summaryrefslogtreecommitdiff
path: root/src/mesa/main
diff options
context:
space:
mode:
authorDavid Nusinow <dnusinow@debian.org>2006-04-07 00:24:21 +0000
committerDavid Nusinow <dnusinow@debian.org>2006-04-07 00:24:21 +0000
commitccb68495e02ae47d4f8868498d0e577299307288 (patch)
tree0fb9386bc5d2de9ddf0bd10ef3dca77cb73c22de /src/mesa/main
Vendor drop of Mesa 6.5
Diffstat (limited to 'src/mesa/main')
-rw-r--r--src/mesa/main/accum.c112
-rw-r--r--src/mesa/main/accum.h62
-rw-r--r--src/mesa/main/api_arrayelt.c767
-rw-r--r--src/mesa/main/api_arrayelt.h37
-rw-r--r--src/mesa/main/api_eval.h42
-rw-r--r--src/mesa/main/api_loopback.c1647
-rw-r--r--src/mesa/main/api_loopback.h37
-rw-r--r--src/mesa/main/api_noop.c964
-rw-r--r--src/mesa/main/api_noop.h147
-rw-r--r--src/mesa/main/api_validate.c238
-rw-r--r--src/mesa/main/api_validate.h49
-rw-r--r--src/mesa/main/attrib.c1331
-rw-r--r--src/mesa/main/attrib.h68
-rw-r--r--src/mesa/main/blend.c582
-rw-r--r--src/mesa/main/blend.h78
-rw-r--r--src/mesa/main/bufferobj.c943
-rw-r--r--src/mesa/main/bufferobj.h124
-rw-r--r--src/mesa/main/buffers.c753
-rw-r--r--src/mesa/main/buffers.h81
-rw-r--r--src/mesa/main/clip.c160
-rw-r--r--src/mesa/main/clip.h49
-rw-r--r--src/mesa/main/colormac.h227
-rw-r--r--src/mesa/main/colortab.c1445
-rw-r--r--src/mesa/main/colortab.h110
-rw-r--r--src/mesa/main/config.h317
-rw-r--r--src/mesa/main/context.c1789
-rw-r--r--src/mesa/main/context.h340
-rw-r--r--src/mesa/main/convolve.c1527
-rw-r--r--src/mesa/main/convolve.h114
-rw-r--r--src/mesa/main/dd.h1072
-rw-r--r--src/mesa/main/debug.c227
-rw-r--r--src/mesa/main/debug.h60
-rw-r--r--src/mesa/main/depth.c188
-rw-r--r--src/mesa/main/depth.h62
-rw-r--r--src/mesa/main/depthstencil.c655
-rw-r--r--src/mesa/main/depthstencil.h56
-rw-r--r--src/mesa/main/descrip.mms213
-rw-r--r--src/mesa/main/dispatch.c95
-rw-r--r--src/mesa/main/dlist.c8551
-rw-r--r--src/mesa/main/dlist.h98
-rw-r--r--src/mesa/main/drawpix.c435
-rw-r--r--src/mesa/main/drawpix.h55
-rw-r--r--src/mesa/main/enable.c1426
-rw-r--r--src/mesa/main/enable.h57
-rw-r--r--src/mesa/main/enums.c4584
-rw-r--r--src/mesa/main/enums.h55
-rw-r--r--src/mesa/main/eval.c962
-rw-r--r--src/mesa/main/eval.h128
-rw-r--r--src/mesa/main/execmem.c131
-rw-r--r--src/mesa/main/extensions.c517
-rw-r--r--src/mesa/main/extensions.h84
-rw-r--r--src/mesa/main/fbobject.c1644
-rw-r--r--src/mesa/main/fbobject.h134
-rw-r--r--src/mesa/main/feedback.c541
-rw-r--r--src/mesa/main/feedback.h82
-rw-r--r--src/mesa/main/fog.c188
-rw-r--r--src/mesa/main/fog.h66
-rw-r--r--src/mesa/main/framebuffer.c766
-rw-r--r--src/mesa/main/framebuffer.h73
-rw-r--r--src/mesa/main/get.c5545
-rw-r--r--src/mesa/main/get.h59
-rw-r--r--src/mesa/main/getstring.c261
-rw-r--r--src/mesa/main/glheader.h258
-rw-r--r--src/mesa/main/hash.c451
-rw-r--r--src/mesa/main/hash.h59
-rw-r--r--src/mesa/main/hint.c153
-rw-r--r--src/mesa/main/hint.h57
-rw-r--r--src/mesa/main/histogram.c1187
-rw-r--r--src/mesa/main/histogram.h89
-rw-r--r--src/mesa/main/image.c4355
-rw-r--r--src/mesa/main/image.h225
-rw-r--r--src/mesa/main/imports.c1329
-rw-r--r--src/mesa/main/imports.h763
-rw-r--r--src/mesa/main/light.c1375
-rw-r--r--src/mesa/main/light.h145
-rw-r--r--src/mesa/main/lines.c134
-rw-r--r--src/mesa/main/lines.h48
-rw-r--r--src/mesa/main/macros.h658
-rw-r--r--src/mesa/main/matrix.c929
-rw-r--r--src/mesa/main/matrix.h131
-rw-r--r--src/mesa/main/mm.c220
-rw-r--r--src/mesa/main/mm.h92
-rw-r--r--src/mesa/main/mtypes.h2947
-rw-r--r--src/mesa/main/occlude.c524
-rw-r--r--src/mesa/main/occlude.h70
-rw-r--r--src/mesa/main/pixel.c2129
-rw-r--r--src/mesa/main/pixel.h158
-rw-r--r--src/mesa/main/points.c294
-rw-r--r--src/mesa/main/points.h60
-rw-r--r--src/mesa/main/polygon.c383
-rw-r--r--src/mesa/main/polygon.h69
-rw-r--r--src/mesa/main/rastpos.c1001
-rw-r--r--src/mesa/main/rastpos.h193
-rw-r--r--src/mesa/main/renderbuffer.c2073
-rw-r--r--src/mesa/main/renderbuffer.h103
-rw-r--r--src/mesa/main/simple_list.h197
-rw-r--r--src/mesa/main/state.c1060
-rw-r--r--src/mesa/main/state.h43
-rw-r--r--src/mesa/main/stencil.c552
-rw-r--r--src/mesa/main/stencil.h77
-rw-r--r--src/mesa/main/texcompress.c254
-rw-r--r--src/mesa/main/texcompress.h65
-rw-r--r--src/mesa/main/texcompress_fxt1.c1708
-rw-r--r--src/mesa/main/texcompress_s3tc.c563
-rw-r--r--src/mesa/main/texenvprogram.c1197
-rw-r--r--src/mesa/main/texenvprogram.h40
-rw-r--r--src/mesa/main/texformat.c1397
-rw-r--r--src/mesa/main/texformat.h230
-rw-r--r--src/mesa/main/texformat_tmp.h1291
-rw-r--r--src/mesa/main/teximage.c3451
-rw-r--r--src/mesa/main/teximage.h242
-rw-r--r--src/mesa/main/texobj.c1052
-rw-r--r--src/mesa/main/texobj.h98
-rw-r--r--src/mesa/main/texrender.c363
-rw-r--r--src/mesa/main/texrender.h15
-rw-r--r--src/mesa/main/texstate.c3135
-rw-r--r--src/mesa/main/texstate.h152
-rw-r--r--src/mesa/main/texstore.c4253
-rw-r--r--src/mesa/main/texstore.h262
-rw-r--r--src/mesa/main/varray.c994
-rw-r--r--src/mesa/main/varray.h160
-rw-r--r--src/mesa/main/version.h52
-rw-r--r--src/mesa/main/vsnprintf.c165
-rw-r--r--src/mesa/main/vtxfmt.c185
-rw-r--r--src/mesa/main/vtxfmt.h43
-rw-r--r--src/mesa/main/vtxfmt_tmp.h537
126 files changed, 89705 insertions, 0 deletions
diff --git a/src/mesa/main/accum.c b/src/mesa/main/accum.c
new file mode 100644
index 00000000000..a6e422640cf
--- /dev/null
+++ b/src/mesa/main/accum.c
@@ -0,0 +1,112 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "glheader.h"
+#include "accum.h"
+#include "context.h"
+#include "imports.h"
+#include "macros.h"
+#include "state.h"
+#include "mtypes.h"
+
+
+void GLAPIENTRY
+_mesa_ClearAccum( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha )
+{
+ GLfloat tmp[4];
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ tmp[0] = CLAMP( red, -1.0F, 1.0F );
+ tmp[1] = CLAMP( green, -1.0F, 1.0F );
+ tmp[2] = CLAMP( blue, -1.0F, 1.0F );
+ tmp[3] = CLAMP( alpha, -1.0F, 1.0F );
+
+ if (TEST_EQ_4V(tmp, ctx->Accum.ClearColor))
+ return;
+
+ FLUSH_VERTICES(ctx, _NEW_ACCUM);
+ COPY_4FV( ctx->Accum.ClearColor, tmp );
+}
+
+
+void GLAPIENTRY
+_mesa_Accum( GLenum op, GLfloat value )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ switch (op) {
+ case GL_ADD:
+ case GL_MULT:
+ case GL_ACCUM:
+ case GL_LOAD:
+ case GL_RETURN:
+ /* OK */
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glAccum(op)");
+ return;
+ }
+
+ if (ctx->DrawBuffer->Visual.haveAccumBuffer == 0) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glAccum(no accum buffer)");
+ return;
+ }
+
+ if (ctx->DrawBuffer != ctx->ReadBuffer) {
+ /* See GLX_SGI_make_current_read or WGL_ARB_make_current_read,
+ * or GL_EXT_framebuffer_blit.
+ */
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glAccum(different read/draw buffers)");
+ return;
+ }
+
+ if (ctx->NewState)
+ _mesa_update_state(ctx);
+
+ if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
+ "glAccum(incomplete framebuffer)");
+ return;
+ }
+
+ if (ctx->RenderMode == GL_RENDER) {
+ GLint x = ctx->DrawBuffer->_Xmin;
+ GLint y = ctx->DrawBuffer->_Ymin;
+ GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
+ GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
+ ctx->Driver.Accum(ctx, op, value, x, y, width, height);
+ }
+}
+
+
+
+void
+_mesa_init_accum( GLcontext *ctx )
+{
+ /* Accumulate buffer group */
+ ASSIGN_4V( ctx->Accum.ClearColor, 0.0, 0.0, 0.0, 0.0 );
+}
diff --git a/src/mesa/main/accum.h b/src/mesa/main/accum.h
new file mode 100644
index 00000000000..ce92688a5b9
--- /dev/null
+++ b/src/mesa/main/accum.h
@@ -0,0 +1,62 @@
+/**
+ * \file accum.h
+ * Accumulation buffer operations.
+ *
+ * \if subset
+ * (No-op)
+ *
+ * \endif
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.5
+ *
+ * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+#ifndef ACCUM_H
+#define ACCUM_H
+
+
+#include "mtypes.h"
+
+#if _HAVE_FULL_GL
+
+extern void GLAPIENTRY
+_mesa_Accum( GLenum op, GLfloat value );
+
+
+extern void GLAPIENTRY
+_mesa_ClearAccum( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha );
+
+extern void
+_mesa_init_accum( GLcontext *ctx );
+
+#else
+
+/** No-op */
+#define _mesa_init_accum( c ) ((void)0)
+
+#endif
+
+#endif
diff --git a/src/mesa/main/api_arrayelt.c b/src/mesa/main/api_arrayelt.c
new file mode 100644
index 00000000000..e905f164025
--- /dev/null
+++ b/src/mesa/main/api_arrayelt.c
@@ -0,0 +1,767 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* Author:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#include "glheader.h"
+#include "api_arrayelt.h"
+#include "context.h"
+#include "imports.h"
+#include "macros.h"
+#include "glapioffsets.h"
+#include "dispatch.h"
+
+typedef void (GLAPIENTRY *array_func)( const void * );
+
+typedef struct {
+ const struct gl_client_array *array;
+ int offset;
+} AEarray;
+
+typedef void (GLAPIENTRY *attrib_func)( GLuint indx, const void *data );
+
+typedef struct {
+ const struct gl_client_array *array;
+ attrib_func func;
+ GLuint index;
+} AEattrib;
+
+typedef struct {
+ AEarray arrays[32];
+ AEattrib attribs[VERT_ATTRIB_MAX + 1];
+ GLuint NewState;
+} AEcontext;
+
+#define AE_CONTEXT(ctx) ((AEcontext *)(ctx)->aelt_context)
+
+
+/*
+ * Convert GL_BYTE, GL_UNSIGNED_BYTE, .. GL_DOUBLE into an integer
+ * in the range [0, 7]. Luckily these type tokens are sequentially
+ * numbered in gl.h, except for GL_DOUBLE.
+ */
+#define TYPE_IDX(t) ( (t) == GL_DOUBLE ? 7 : (t) & 7 )
+
+static const int ColorFuncs[2][8] = {
+ {
+ _gloffset_Color3bv,
+ _gloffset_Color3ubv,
+ _gloffset_Color3sv,
+ _gloffset_Color3usv,
+ _gloffset_Color3iv,
+ _gloffset_Color3uiv,
+ _gloffset_Color3fv,
+ _gloffset_Color3dv,
+ },
+ {
+ _gloffset_Color4bv,
+ _gloffset_Color4ubv,
+ _gloffset_Color4sv,
+ _gloffset_Color4usv,
+ _gloffset_Color4iv,
+ _gloffset_Color4uiv,
+ _gloffset_Color4fv,
+ _gloffset_Color4dv,
+ },
+};
+
+static const int VertexFuncs[3][8] = {
+ {
+ -1,
+ -1,
+ _gloffset_Vertex2sv,
+ -1,
+ _gloffset_Vertex2iv,
+ -1,
+ _gloffset_Vertex2fv,
+ _gloffset_Vertex2dv,
+ },
+ {
+ -1,
+ -1,
+ _gloffset_Vertex3sv,
+ -1,
+ _gloffset_Vertex3iv,
+ -1,
+ _gloffset_Vertex3fv,
+ _gloffset_Vertex3dv,
+ },
+ {
+ -1,
+ -1,
+ _gloffset_Vertex4sv,
+ -1,
+ _gloffset_Vertex4iv,
+ -1,
+ _gloffset_Vertex4fv,
+ _gloffset_Vertex4dv,
+ },
+};
+
+static const int IndexFuncs[8] = {
+ -1,
+ _gloffset_Indexubv,
+ _gloffset_Indexsv,
+ -1,
+ _gloffset_Indexiv,
+ -1,
+ _gloffset_Indexfv,
+ _gloffset_Indexdv,
+};
+
+static const int NormalFuncs[8] = {
+ _gloffset_Normal3bv,
+ -1,
+ _gloffset_Normal3sv,
+ -1,
+ _gloffset_Normal3iv,
+ -1,
+ _gloffset_Normal3fv,
+ _gloffset_Normal3dv,
+};
+
+/* Note: _gloffset_* for these may not be a compile-time constant. */
+static int SecondaryColorFuncs[8];
+static int FogCoordFuncs[8];
+
+/**********************************************************************/
+
+/* GL_BYTE attributes */
+
+static void GLAPIENTRY VertexAttrib1NbvNV(GLuint index, const GLbyte *v)
+{
+ CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, BYTE_TO_FLOAT(v[0])));
+}
+
+static void GLAPIENTRY VertexAttrib1bvNV(GLuint index, const GLbyte *v)
+{
+ CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, v[0]));
+}
+
+static void GLAPIENTRY VertexAttrib2NbvNV(GLuint index, const GLbyte *v)
+{
+ CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, BYTE_TO_FLOAT(v[0]), BYTE_TO_FLOAT(v[1])));
+}
+
+static void GLAPIENTRY VertexAttrib2bvNV(GLuint index, const GLbyte *v)
+{
+ CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, v[0], v[1]));
+}
+
+static void GLAPIENTRY VertexAttrib3NbvNV(GLuint index, const GLbyte *v)
+{
+ CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, BYTE_TO_FLOAT(v[0]),
+ BYTE_TO_FLOAT(v[1]),
+ BYTE_TO_FLOAT(v[2])));
+}
+
+static void GLAPIENTRY VertexAttrib3bvNV(GLuint index, const GLbyte *v)
+{
+ CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, v[0], v[1], v[2]));
+}
+
+static void GLAPIENTRY VertexAttrib4NbvNV(GLuint index, const GLbyte *v)
+{
+ CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, BYTE_TO_FLOAT(v[0]),
+ BYTE_TO_FLOAT(v[1]),
+ BYTE_TO_FLOAT(v[2]),
+ BYTE_TO_FLOAT(v[3])));
+}
+
+static void GLAPIENTRY VertexAttrib4bvNV(GLuint index, const GLbyte *v)
+{
+ CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, v[0], v[1], v[2], v[3]));
+}
+
+/* GL_UNSIGNED_BYTE attributes */
+
+static void GLAPIENTRY VertexAttrib1NubvNV(GLuint index, const GLubyte *v)
+{
+ CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, UBYTE_TO_FLOAT(v[0])));
+}
+
+static void GLAPIENTRY VertexAttrib1ubvNV(GLuint index, const GLubyte *v)
+{
+ CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, v[0]));
+}
+
+static void GLAPIENTRY VertexAttrib2NubvNV(GLuint index, const GLubyte *v)
+{
+ CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, UBYTE_TO_FLOAT(v[0]),
+ UBYTE_TO_FLOAT(v[1])));
+}
+
+static void GLAPIENTRY VertexAttrib2ubvNV(GLuint index, const GLubyte *v)
+{
+ CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, v[0], v[1]));
+}
+
+static void GLAPIENTRY VertexAttrib3NubvNV(GLuint index, const GLubyte *v)
+{
+ CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, UBYTE_TO_FLOAT(v[0]),
+ UBYTE_TO_FLOAT(v[1]),
+ UBYTE_TO_FLOAT(v[2])));
+}
+static void GLAPIENTRY VertexAttrib3ubvNV(GLuint index, const GLubyte *v)
+{
+ CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, v[0], v[1], v[2]));
+}
+
+static void GLAPIENTRY VertexAttrib4NubvNV(GLuint index, const GLubyte *v)
+{
+ CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, UBYTE_TO_FLOAT(v[0]),
+ UBYTE_TO_FLOAT(v[1]),
+ UBYTE_TO_FLOAT(v[2]),
+ UBYTE_TO_FLOAT(v[3])));
+}
+
+static void GLAPIENTRY VertexAttrib4ubvNV(GLuint index, const GLubyte *v)
+{
+ CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, v[0], v[1], v[2], v[3]));
+}
+
+/* GL_SHORT attributes */
+
+static void GLAPIENTRY VertexAttrib1NsvNV(GLuint index, const GLshort *v)
+{
+ CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, SHORT_TO_FLOAT(v[0])));
+}
+
+static void GLAPIENTRY VertexAttrib1svNV(GLuint index, const GLshort *v)
+{
+ CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, v[0]));
+}
+
+static void GLAPIENTRY VertexAttrib2NsvNV(GLuint index, const GLshort *v)
+{
+ CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, SHORT_TO_FLOAT(v[0]),
+ SHORT_TO_FLOAT(v[1])));
+}
+
+static void GLAPIENTRY VertexAttrib2svNV(GLuint index, const GLshort *v)
+{
+ CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, v[0], v[1]));
+}
+
+static void GLAPIENTRY VertexAttrib3NsvNV(GLuint index, const GLshort *v)
+{
+ CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, SHORT_TO_FLOAT(v[0]),
+ SHORT_TO_FLOAT(v[1]),
+ SHORT_TO_FLOAT(v[2])));
+}
+
+static void GLAPIENTRY VertexAttrib3svNV(GLuint index, const GLshort *v)
+{
+ CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, v[0], v[1], v[2]));
+}
+
+static void GLAPIENTRY VertexAttrib4NsvNV(GLuint index, const GLshort *v)
+{
+ CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, SHORT_TO_FLOAT(v[0]),
+ SHORT_TO_FLOAT(v[1]),
+ SHORT_TO_FLOAT(v[2]),
+ SHORT_TO_FLOAT(v[3])));
+}
+
+static void GLAPIENTRY VertexAttrib4svNV(GLuint index, const GLshort *v)
+{
+ CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, v[0], v[1], v[2], v[3]));
+}
+
+/* GL_UNSIGNED_SHORT attributes */
+
+static void GLAPIENTRY VertexAttrib1NusvNV(GLuint index, const GLushort *v)
+{
+ CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, USHORT_TO_FLOAT(v[0])));
+}
+
+static void GLAPIENTRY VertexAttrib1usvNV(GLuint index, const GLushort *v)
+{
+ CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, v[0]));
+}
+
+static void GLAPIENTRY VertexAttrib2NusvNV(GLuint index, const GLushort *v)
+{
+ CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, USHORT_TO_FLOAT(v[0]),
+ USHORT_TO_FLOAT(v[1])));
+}
+
+static void GLAPIENTRY VertexAttrib2usvNV(GLuint index, const GLushort *v)
+{
+ CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, v[0], v[1]));
+}
+
+static void GLAPIENTRY VertexAttrib3NusvNV(GLuint index, const GLushort *v)
+{
+ CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, USHORT_TO_FLOAT(v[0]),
+ USHORT_TO_FLOAT(v[1]),
+ USHORT_TO_FLOAT(v[2])));
+}
+
+static void GLAPIENTRY VertexAttrib3usvNV(GLuint index, const GLushort *v)
+{
+ CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, v[0], v[1], v[2]));
+}
+
+static void GLAPIENTRY VertexAttrib4NusvNV(GLuint index, const GLushort *v)
+{
+ CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, USHORT_TO_FLOAT(v[0]),
+ USHORT_TO_FLOAT(v[1]),
+ USHORT_TO_FLOAT(v[2]),
+ USHORT_TO_FLOAT(v[3])));
+}
+
+static void GLAPIENTRY VertexAttrib4usvNV(GLuint index, const GLushort *v)
+{
+ CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, v[0], v[1], v[2], v[3]));
+}
+
+/* GL_INT attributes */
+
+static void GLAPIENTRY VertexAttrib1NivNV(GLuint index, const GLint *v)
+{
+ CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, INT_TO_FLOAT(v[0])));
+}
+
+static void GLAPIENTRY VertexAttrib1ivNV(GLuint index, const GLint *v)
+{
+ CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, v[0]));
+}
+
+static void GLAPIENTRY VertexAttrib2NivNV(GLuint index, const GLint *v)
+{
+ CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, INT_TO_FLOAT(v[0]),
+ INT_TO_FLOAT(v[1])));
+}
+
+static void GLAPIENTRY VertexAttrib2ivNV(GLuint index, const GLint *v)
+{
+ CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, v[0], v[1]));
+}
+
+static void GLAPIENTRY VertexAttrib3NivNV(GLuint index, const GLint *v)
+{
+ CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, INT_TO_FLOAT(v[0]),
+ INT_TO_FLOAT(v[1]),
+ INT_TO_FLOAT(v[2])));
+}
+
+static void GLAPIENTRY VertexAttrib3ivNV(GLuint index, const GLint *v)
+{
+ CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, v[0], v[1], v[2]));
+}
+
+static void GLAPIENTRY VertexAttrib4NivNV(GLuint index, const GLint *v)
+{
+ CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, INT_TO_FLOAT(v[0]),
+ INT_TO_FLOAT(v[1]),
+ INT_TO_FLOAT(v[2]),
+ INT_TO_FLOAT(v[3])));
+}
+
+static void GLAPIENTRY VertexAttrib4ivNV(GLuint index, const GLint *v)
+{
+ CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, v[0], v[1], v[2], v[3]));
+}
+
+/* GL_UNSIGNED_INT attributes */
+
+static void GLAPIENTRY VertexAttrib1NuivNV(GLuint index, const GLuint *v)
+{
+ CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, UINT_TO_FLOAT(v[0])));
+}
+
+static void GLAPIENTRY VertexAttrib1uivNV(GLuint index, const GLuint *v)
+{
+ CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, v[0]));
+}
+
+static void GLAPIENTRY VertexAttrib2NuivNV(GLuint index, const GLuint *v)
+{
+ CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, UINT_TO_FLOAT(v[0]),
+ UINT_TO_FLOAT(v[1])));
+}
+
+static void GLAPIENTRY VertexAttrib2uivNV(GLuint index, const GLuint *v)
+{
+ CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, v[0], v[1]));
+}
+
+static void GLAPIENTRY VertexAttrib3NuivNV(GLuint index, const GLuint *v)
+{
+ CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, UINT_TO_FLOAT(v[0]),
+ UINT_TO_FLOAT(v[1]),
+ UINT_TO_FLOAT(v[2])));
+}
+
+static void GLAPIENTRY VertexAttrib3uivNV(GLuint index, const GLuint *v)
+{
+ CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, v[0], v[1], v[2]));
+}
+
+static void GLAPIENTRY VertexAttrib4NuivNV(GLuint index, const GLuint *v)
+{
+ CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, UINT_TO_FLOAT(v[0]),
+ UINT_TO_FLOAT(v[1]),
+ UINT_TO_FLOAT(v[2]),
+ UINT_TO_FLOAT(v[3])));
+}
+
+static void GLAPIENTRY VertexAttrib4uivNV(GLuint index, const GLuint *v)
+{
+ CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, v[0], v[1], v[2], v[3]));
+}
+
+/* GL_FLOAT attributes */
+
+static void GLAPIENTRY VertexAttrib1fvNV(GLuint index, const GLfloat *v)
+{
+ CALL_VertexAttrib1fvNV(GET_DISPATCH(), (index, v));
+}
+
+static void GLAPIENTRY VertexAttrib2fvNV(GLuint index, const GLfloat *v)
+{
+ CALL_VertexAttrib2fvNV(GET_DISPATCH(), (index, v));
+}
+
+static void GLAPIENTRY VertexAttrib3fvNV(GLuint index, const GLfloat *v)
+{
+ CALL_VertexAttrib3fvNV(GET_DISPATCH(), (index, v));
+}
+
+static void GLAPIENTRY VertexAttrib4fvNV(GLuint index, const GLfloat *v)
+{
+ CALL_VertexAttrib4fvNV(GET_DISPATCH(), (index, v));
+}
+
+/* GL_DOUBLE attributes */
+
+static void GLAPIENTRY VertexAttrib1dvNV(GLuint index, const GLdouble *v)
+{
+ CALL_VertexAttrib1dvNV(GET_DISPATCH(), (index, v));
+}
+
+static void GLAPIENTRY VertexAttrib2dvNV(GLuint index, const GLdouble *v)
+{
+ CALL_VertexAttrib2dvNV(GET_DISPATCH(), (index, v));
+}
+
+static void GLAPIENTRY VertexAttrib3dvNV(GLuint index, const GLdouble *v)
+{
+ CALL_VertexAttrib3dvNV(GET_DISPATCH(), (index, v));
+}
+
+static void GLAPIENTRY VertexAttrib4dvNV(GLuint index, const GLdouble *v)
+{
+ CALL_VertexAttrib4dvNV(GET_DISPATCH(), (index, v));
+}
+
+
+/*
+ * Array [size][type] of VertexAttrib functions
+ */
+static attrib_func AttribFuncsNV[2][4][8] = {
+ {
+ /* non-normalized */
+ {
+ /* size 1 */
+ (attrib_func) VertexAttrib1bvNV,
+ (attrib_func) VertexAttrib1ubvNV,
+ (attrib_func) VertexAttrib1svNV,
+ (attrib_func) VertexAttrib1usvNV,
+ (attrib_func) VertexAttrib1ivNV,
+ (attrib_func) VertexAttrib1uivNV,
+ (attrib_func) VertexAttrib1fvNV,
+ (attrib_func) VertexAttrib1dvNV
+ },
+ {
+ /* size 2 */
+ (attrib_func) VertexAttrib2bvNV,
+ (attrib_func) VertexAttrib2ubvNV,
+ (attrib_func) VertexAttrib2svNV,
+ (attrib_func) VertexAttrib2usvNV,
+ (attrib_func) VertexAttrib2ivNV,
+ (attrib_func) VertexAttrib2uivNV,
+ (attrib_func) VertexAttrib2fvNV,
+ (attrib_func) VertexAttrib2dvNV
+ },
+ {
+ /* size 3 */
+ (attrib_func) VertexAttrib3bvNV,
+ (attrib_func) VertexAttrib3ubvNV,
+ (attrib_func) VertexAttrib3svNV,
+ (attrib_func) VertexAttrib3usvNV,
+ (attrib_func) VertexAttrib3ivNV,
+ (attrib_func) VertexAttrib3uivNV,
+ (attrib_func) VertexAttrib3fvNV,
+ (attrib_func) VertexAttrib3dvNV
+ },
+ {
+ /* size 4 */
+ (attrib_func) VertexAttrib4bvNV,
+ (attrib_func) VertexAttrib4ubvNV,
+ (attrib_func) VertexAttrib4svNV,
+ (attrib_func) VertexAttrib4usvNV,
+ (attrib_func) VertexAttrib4ivNV,
+ (attrib_func) VertexAttrib4uivNV,
+ (attrib_func) VertexAttrib4fvNV,
+ (attrib_func) VertexAttrib4dvNV
+ }
+ },
+ {
+ /* normalized (except for float/double) */
+ {
+ /* size 1 */
+ (attrib_func) VertexAttrib1NbvNV,
+ (attrib_func) VertexAttrib1NubvNV,
+ (attrib_func) VertexAttrib1NsvNV,
+ (attrib_func) VertexAttrib1NusvNV,
+ (attrib_func) VertexAttrib1NivNV,
+ (attrib_func) VertexAttrib1NuivNV,
+ (attrib_func) VertexAttrib1fvNV,
+ (attrib_func) VertexAttrib1dvNV
+ },
+ {
+ /* size 2 */
+ (attrib_func) VertexAttrib2NbvNV,
+ (attrib_func) VertexAttrib2NubvNV,
+ (attrib_func) VertexAttrib2NsvNV,
+ (attrib_func) VertexAttrib2NusvNV,
+ (attrib_func) VertexAttrib2NivNV,
+ (attrib_func) VertexAttrib2NuivNV,
+ (attrib_func) VertexAttrib2fvNV,
+ (attrib_func) VertexAttrib2dvNV
+ },
+ {
+ /* size 3 */
+ (attrib_func) VertexAttrib3NbvNV,
+ (attrib_func) VertexAttrib3NubvNV,
+ (attrib_func) VertexAttrib3NsvNV,
+ (attrib_func) VertexAttrib3NusvNV,
+ (attrib_func) VertexAttrib3NivNV,
+ (attrib_func) VertexAttrib3NuivNV,
+ (attrib_func) VertexAttrib3fvNV,
+ (attrib_func) VertexAttrib3dvNV
+ },
+ {
+ /* size 4 */
+ (attrib_func) VertexAttrib4NbvNV,
+ (attrib_func) VertexAttrib4NubvNV,
+ (attrib_func) VertexAttrib4NsvNV,
+ (attrib_func) VertexAttrib4NusvNV,
+ (attrib_func) VertexAttrib4NivNV,
+ (attrib_func) VertexAttrib4NuivNV,
+ (attrib_func) VertexAttrib4fvNV,
+ (attrib_func) VertexAttrib4dvNV
+ }
+ }
+};
+
+/**********************************************************************/
+
+
+GLboolean _ae_create_context( GLcontext *ctx )
+{
+ if (ctx->aelt_context)
+ return GL_TRUE;
+
+ /* These _gloffset_* values may not be compile-time constants */
+ SecondaryColorFuncs[0] = _gloffset_SecondaryColor3bvEXT;
+ SecondaryColorFuncs[1] = _gloffset_SecondaryColor3ubvEXT;
+ SecondaryColorFuncs[2] = _gloffset_SecondaryColor3svEXT;
+ SecondaryColorFuncs[3] = _gloffset_SecondaryColor3usvEXT;
+ SecondaryColorFuncs[4] = _gloffset_SecondaryColor3ivEXT;
+ SecondaryColorFuncs[5] = _gloffset_SecondaryColor3uivEXT;
+ SecondaryColorFuncs[6] = _gloffset_SecondaryColor3fvEXT;
+ SecondaryColorFuncs[7] = _gloffset_SecondaryColor3dvEXT;
+
+ FogCoordFuncs[0] = -1;
+ FogCoordFuncs[1] = -1;
+ FogCoordFuncs[2] = -1;
+ FogCoordFuncs[3] = -1;
+ FogCoordFuncs[4] = -1;
+ FogCoordFuncs[5] = -1;
+ FogCoordFuncs[6] = _gloffset_FogCoordfvEXT;
+ FogCoordFuncs[7] = _gloffset_FogCoorddvEXT;
+
+ ctx->aelt_context = MALLOC( sizeof(AEcontext) );
+ if (!ctx->aelt_context)
+ return GL_FALSE;
+
+ AE_CONTEXT(ctx)->NewState = ~0;
+ return GL_TRUE;
+}
+
+
+void _ae_destroy_context( GLcontext *ctx )
+{
+ if ( AE_CONTEXT( ctx ) ) {
+ FREE( ctx->aelt_context );
+ ctx->aelt_context = NULL;
+ }
+}
+
+
+/**
+ * Make a list of per-vertex functions to call for each glArrayElement call.
+ * These functions access the array data (i.e. glVertex, glColor, glNormal,
+ * etc).
+ * Note: this may be called during display list construction.
+ */
+static void _ae_update_state( GLcontext *ctx )
+{
+ AEcontext *actx = AE_CONTEXT(ctx);
+ AEarray *aa = actx->arrays;
+ AEattrib *at = actx->attribs;
+ GLuint i;
+
+ /* conventional vertex arrays */
+ if (ctx->Array.Index.Enabled) {
+ aa->array = &ctx->Array.Index;
+ aa->offset = IndexFuncs[TYPE_IDX(aa->array->Type)];
+ aa++;
+ }
+ if (ctx->Array.EdgeFlag.Enabled) {
+ aa->array = &ctx->Array.EdgeFlag;
+ aa->offset = _gloffset_EdgeFlagv;
+ aa++;
+ }
+ if (ctx->Array.Normal.Enabled) {
+ aa->array = &ctx->Array.Normal;
+ aa->offset = NormalFuncs[TYPE_IDX(aa->array->Type)];
+ aa++;
+ }
+ if (ctx->Array.Color.Enabled) {
+ aa->array = &ctx->Array.Color;
+ aa->offset = ColorFuncs[aa->array->Size-3][TYPE_IDX(aa->array->Type)];
+ aa++;
+ }
+ if (ctx->Array.SecondaryColor.Enabled) {
+ aa->array = &ctx->Array.SecondaryColor;
+ aa->offset = SecondaryColorFuncs[TYPE_IDX(aa->array->Type)];
+ aa++;
+ }
+ if (ctx->Array.FogCoord.Enabled) {
+ aa->array = &ctx->Array.FogCoord;
+ aa->offset = FogCoordFuncs[TYPE_IDX(aa->array->Type)];
+ aa++;
+ }
+ for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
+ if (ctx->Array.TexCoord[i].Enabled) {
+ /* NOTE: we use generic glVertexAttrib functions here.
+ * If we ever de-alias conventional/generic vertex attribs this
+ * will have to change.
+ */
+ struct gl_client_array *attribArray = &ctx->Array.TexCoord[i];
+ at->array = attribArray;
+ at->func = AttribFuncsNV[at->array->Normalized][at->array->Size-1][TYPE_IDX(at->array->Type)];
+ at->index = VERT_ATTRIB_TEX0 + i;
+ at++;
+ }
+ }
+
+ /* generic vertex attribute arrays */
+ for (i = 1; i < VERT_ATTRIB_MAX; i++) { /* skip zero! */
+ if (ctx->Array.VertexAttrib[i].Enabled) {
+ struct gl_client_array *attribArray = &ctx->Array.VertexAttrib[i];
+ at->array = attribArray;
+ /* Note: we can't grab the _glapi_Dispatch->VertexAttrib1fvNV
+ * function pointer here (for float arrays) since the pointer may
+ * change from one execution of _ae_loopback_array_elt() to
+ * the next. Doing so caused UT to break.
+ */
+ at->func = AttribFuncsNV[at->array->Normalized][at->array->Size-1][TYPE_IDX(at->array->Type)];
+ at->index = i;
+ at++;
+ }
+ }
+
+ /* finally, vertex position */
+ if (ctx->Array.VertexAttrib[0].Enabled) {
+ /* Use glVertex(v) instead of glVertexAttrib(0, v) to be sure it's
+ * issued as the last (proviking) attribute).
+ */
+ aa->array = &ctx->Array.VertexAttrib[0];
+ assert(aa->array->Size >= 2); /* XXX fix someday? */
+ aa->offset = VertexFuncs[aa->array->Size-2][TYPE_IDX(aa->array->Type)];
+ aa++;
+ }
+ else if (ctx->Array.Vertex.Enabled) {
+ aa->array = &ctx->Array.Vertex;
+ aa->offset = VertexFuncs[aa->array->Size-2][TYPE_IDX(aa->array->Type)];
+ aa++;
+ }
+
+ ASSERT(at - actx->attribs <= VERT_ATTRIB_MAX);
+ ASSERT(aa - actx->arrays < 32);
+ at->func = NULL; /* terminate the list */
+ aa->offset = -1; /* terminate the list */
+
+ actx->NewState = 0;
+}
+
+
+/**
+ * Called via glArrayElement() and glDrawArrays().
+ * Issue the glNormal, glVertex, glColor, glVertexAttrib, etc functions
+ * for all enabled vertex arrays (for elt-th element).
+ * Note: this may be called during display list construction.
+ */
+void GLAPIENTRY _ae_loopback_array_elt( GLint elt )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ const AEcontext *actx = AE_CONTEXT(ctx);
+ const AEarray *aa;
+ const AEattrib *at;
+ const struct _glapi_table * const disp = GET_DISPATCH();
+
+
+ if (actx->NewState)
+ _ae_update_state( ctx );
+
+ /* generic attributes */
+ for (at = actx->attribs; at->func; at++) {
+ const GLubyte *src
+ = ADD_POINTERS(at->array->BufferObj->Data, at->array->Ptr)
+ + elt * at->array->StrideB;
+ at->func( at->index, src );
+ }
+
+ /* conventional arrays */
+ for (aa = actx->arrays; aa->offset != -1 ; aa++) {
+ const GLubyte *src
+ = ADD_POINTERS(aa->array->BufferObj->Data, aa->array->Ptr)
+ + elt * aa->array->StrideB;
+ CALL_by_offset( disp, (array_func), aa->offset,
+ ((const void *) src) );
+ }
+}
+
+
+void _ae_invalidate_state( GLcontext *ctx, GLuint new_state )
+{
+ AE_CONTEXT(ctx)->NewState |= new_state;
+}
diff --git a/src/mesa/main/api_arrayelt.h b/src/mesa/main/api_arrayelt.h
new file mode 100644
index 00000000000..1c0af9f3ea8
--- /dev/null
+++ b/src/mesa/main/api_arrayelt.h
@@ -0,0 +1,37 @@
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.5
+ *
+ * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef API_ARRAYELT_H
+#define API_ARRAYELT_H
+
+#include "mtypes.h"
+
+extern GLboolean _ae_create_context( GLcontext *ctx );
+extern void _ae_destroy_context( GLcontext *ctx );
+extern void _ae_invalidate_state( GLcontext *ctx, GLuint new_state );
+extern void GLAPIENTRY _ae_loopback_array_elt( GLint elt );
+
+#endif
diff --git a/src/mesa/main/api_eval.h b/src/mesa/main/api_eval.h
new file mode 100644
index 00000000000..d6cb38c9f8c
--- /dev/null
+++ b/src/mesa/main/api_eval.h
@@ -0,0 +1,42 @@
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.5
+ *
+ * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef API_EVAL_H
+#define API_EVAL_H
+
+#include "mtypes.h"
+
+extern void _mesa_EvalPoint1( GLint i );
+extern void _mesa_EvalPoint2( GLint i, GLint j );
+extern void _mesa_EvalCoord1f( GLfloat u );
+extern void _mesa_EvalCoord2f( GLfloat u, GLfloat v );
+extern void _mesa_EvalCoord1fv( const GLfloat *u );
+extern void _mesa_EvalCoord2fv( const GLfloat *u );
+
+#endif
+
+
+
diff --git a/src/mesa/main/api_loopback.c b/src/mesa/main/api_loopback.c
new file mode 100644
index 00000000000..db30059e61d
--- /dev/null
+++ b/src/mesa/main/api_loopback.c
@@ -0,0 +1,1647 @@
+/**
+ * \file api_loopback.c
+ *
+ * \author Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.3
+ *
+ * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include "glheader.h"
+#include "glapi.h"
+#include "glapitable.h"
+#include "macros.h"
+#include "colormac.h"
+#include "api_loopback.h"
+#include "glthread.h"
+#include "mtypes.h"
+#include "dispatch.h"
+
+/* KW: A set of functions to convert unusual Color/Normal/Vertex/etc
+ * calls to a smaller set of driver-provided formats. Currently just
+ * go back to dispatch to find these (eg. call glNormal3f directly),
+ * hence 'loopback'.
+ *
+ * The driver must supply all of the remaining entry points, which are
+ * listed in dd.h. The easiest way for a driver to do this is to
+ * install the supplied software t&l module.
+ */
+#define COLORF(r,g,b,a) CALL_Color4f(GET_DISPATCH(), (r,g,b,a))
+#define VERTEX2(x,y) CALL_Vertex2f(GET_DISPATCH(), (x,y))
+#define VERTEX3(x,y,z) CALL_Vertex3f(GET_DISPATCH(), (x,y,z))
+#define VERTEX4(x,y,z,w) CALL_Vertex4f(GET_DISPATCH(), (x,y,z,w))
+#define NORMAL(x,y,z) CALL_Normal3f(GET_DISPATCH(), (x,y,z))
+#define TEXCOORD1(s) CALL_TexCoord1f(GET_DISPATCH(), (s))
+#define TEXCOORD2(s,t) CALL_TexCoord2f(GET_DISPATCH(), (s,t))
+#define TEXCOORD3(s,t,u) CALL_TexCoord3f(GET_DISPATCH(), (s,t,u))
+#define TEXCOORD4(s,t,u,v) CALL_TexCoord4f(GET_DISPATCH(), (s,t,u,v))
+#define INDEX(c) CALL_Indexf(GET_DISPATCH(), (c))
+#define MULTI_TEXCOORD1(z,s) CALL_MultiTexCoord1fARB(GET_DISPATCH(), (z,s))
+#define MULTI_TEXCOORD2(z,s,t) CALL_MultiTexCoord2fARB(GET_DISPATCH(), (z,s,t))
+#define MULTI_TEXCOORD3(z,s,t,u) CALL_MultiTexCoord3fARB(GET_DISPATCH(), (z,s,t,u))
+#define MULTI_TEXCOORD4(z,s,t,u,v) CALL_MultiTexCoord4fARB(GET_DISPATCH(), (z,s,t,u,v))
+#define EVALCOORD1(x) CALL_EvalCoord1f(GET_DISPATCH(), (x))
+#define EVALCOORD2(x,y) CALL_EvalCoord2f(GET_DISPATCH(), (x,y))
+#define MATERIALFV(a,b,c) CALL_Materialfv(GET_DISPATCH(), (a,b,c))
+#define RECTF(a,b,c,d) CALL_Rectf(GET_DISPATCH(), (a,b,c,d))
+
+#define ATTRIB1NV(index,x) CALL_VertexAttrib1fNV(GET_DISPATCH(), (index,x))
+#define ATTRIB2NV(index,x,y) CALL_VertexAttrib2fNV(GET_DISPATCH(), (index,x,y))
+#define ATTRIB3NV(index,x,y,z) CALL_VertexAttrib3fNV(GET_DISPATCH(), (index,x,y,z))
+#define ATTRIB4NV(index,x,y,z,w) CALL_VertexAttrib4fNV(GET_DISPATCH(), (index,x,y,z,w))
+#define ATTRIB1ARB(index,x) CALL_VertexAttrib1fARB(GET_DISPATCH(), (index,x))
+#define ATTRIB2ARB(index,x,y) CALL_VertexAttrib2fARB(GET_DISPATCH(), (index,x,y))
+#define ATTRIB3ARB(index,x,y,z) CALL_VertexAttrib3fARB(GET_DISPATCH(), (index,x,y,z))
+#define ATTRIB4ARB(index,x,y,z,w) CALL_VertexAttrib4fARB(GET_DISPATCH(), (index,x,y,z,w))
+#define FOGCOORDF(x) CALL_FogCoordfEXT(GET_DISPATCH(), (x))
+#define SECONDARYCOLORF(a,b,c) CALL_SecondaryColor3fEXT(GET_DISPATCH(), (a,b,c))
+
+static void GLAPIENTRY
+loopback_Color3b_f( GLbyte red, GLbyte green, GLbyte blue )
+{
+ COLORF( BYTE_TO_FLOAT(red),
+ BYTE_TO_FLOAT(green),
+ BYTE_TO_FLOAT(blue),
+ 1.0 );
+}
+
+static void GLAPIENTRY
+loopback_Color3d_f( GLdouble red, GLdouble green, GLdouble blue )
+{
+ COLORF( (GLfloat) red, (GLfloat) green, (GLfloat) blue, 1.0 );
+}
+
+static void GLAPIENTRY
+loopback_Color3i_f( GLint red, GLint green, GLint blue )
+{
+ COLORF( INT_TO_FLOAT(red), INT_TO_FLOAT(green),
+ INT_TO_FLOAT(blue), 1.0);
+}
+
+static void GLAPIENTRY
+loopback_Color3s_f( GLshort red, GLshort green, GLshort blue )
+{
+ COLORF( SHORT_TO_FLOAT(red), SHORT_TO_FLOAT(green),
+ SHORT_TO_FLOAT(blue), 1.0);
+}
+
+static void GLAPIENTRY
+loopback_Color3ui_f( GLuint red, GLuint green, GLuint blue )
+{
+ COLORF( UINT_TO_FLOAT(red), UINT_TO_FLOAT(green),
+ UINT_TO_FLOAT(blue), 1.0 );
+}
+
+static void GLAPIENTRY
+loopback_Color3us_f( GLushort red, GLushort green, GLushort blue )
+{
+ COLORF( USHORT_TO_FLOAT(red), USHORT_TO_FLOAT(green),
+ USHORT_TO_FLOAT(blue), 1.0 );
+}
+
+static void GLAPIENTRY
+loopback_Color3ub_f( GLubyte red, GLubyte green, GLubyte blue )
+{
+ COLORF( UBYTE_TO_FLOAT(red), UBYTE_TO_FLOAT(green),
+ UBYTE_TO_FLOAT(blue), 1.0 );
+}
+
+
+static void GLAPIENTRY
+loopback_Color3bv_f( const GLbyte *v )
+{
+ COLORF( BYTE_TO_FLOAT(v[0]), BYTE_TO_FLOAT(v[1]),
+ BYTE_TO_FLOAT(v[2]), 1.0 );
+}
+
+static void GLAPIENTRY
+loopback_Color3dv_f( const GLdouble *v )
+{
+ COLORF( (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0 );
+}
+
+static void GLAPIENTRY
+loopback_Color3iv_f( const GLint *v )
+{
+ COLORF( INT_TO_FLOAT(v[0]), INT_TO_FLOAT(v[1]),
+ INT_TO_FLOAT(v[2]), INT_TO_FLOAT(v[3]) );
+}
+
+static void GLAPIENTRY
+loopback_Color3sv_f( const GLshort *v )
+{
+ COLORF( SHORT_TO_FLOAT(v[0]), SHORT_TO_FLOAT(v[1]),
+ SHORT_TO_FLOAT(v[2]), 1.0 );
+}
+
+static void GLAPIENTRY
+loopback_Color3uiv_f( const GLuint *v )
+{
+ COLORF( UINT_TO_FLOAT(v[0]), UINT_TO_FLOAT(v[1]),
+ UINT_TO_FLOAT(v[2]), 1.0 );
+}
+
+static void GLAPIENTRY
+loopback_Color3usv_f( const GLushort *v )
+{
+ COLORF( USHORT_TO_FLOAT(v[0]), USHORT_TO_FLOAT(v[1]),
+ USHORT_TO_FLOAT(v[2]), 1.0 );
+}
+
+static void GLAPIENTRY
+loopback_Color3ubv_f( const GLubyte *v )
+{
+ COLORF( UBYTE_TO_FLOAT(v[0]), UBYTE_TO_FLOAT(v[1]),
+ UBYTE_TO_FLOAT(v[2]), 1.0 );
+}
+
+
+static void GLAPIENTRY
+loopback_Color4b_f( GLbyte red, GLbyte green, GLbyte blue,
+ GLbyte alpha )
+{
+ COLORF( BYTE_TO_FLOAT(red), BYTE_TO_FLOAT(green),
+ BYTE_TO_FLOAT(blue), BYTE_TO_FLOAT(alpha) );
+}
+
+static void GLAPIENTRY
+loopback_Color4d_f( GLdouble red, GLdouble green, GLdouble blue,
+ GLdouble alpha )
+{
+ COLORF( (GLfloat) red, (GLfloat) green, (GLfloat) blue, (GLfloat) alpha );
+}
+
+static void GLAPIENTRY
+loopback_Color4i_f( GLint red, GLint green, GLint blue, GLint alpha )
+{
+ COLORF( INT_TO_FLOAT(red), INT_TO_FLOAT(green),
+ INT_TO_FLOAT(blue), INT_TO_FLOAT(alpha) );
+}
+
+static void GLAPIENTRY
+loopback_Color4s_f( GLshort red, GLshort green, GLshort blue,
+ GLshort alpha )
+{
+ COLORF( SHORT_TO_FLOAT(red), SHORT_TO_FLOAT(green),
+ SHORT_TO_FLOAT(blue), SHORT_TO_FLOAT(alpha) );
+}
+
+static void GLAPIENTRY
+loopback_Color4ui_f( GLuint red, GLuint green, GLuint blue, GLuint alpha )
+{
+ COLORF( UINT_TO_FLOAT(red), UINT_TO_FLOAT(green),
+ UINT_TO_FLOAT(blue), UINT_TO_FLOAT(alpha) );
+}
+
+static void GLAPIENTRY
+loopback_Color4us_f( GLushort red, GLushort green, GLushort blue, GLushort alpha )
+{
+ COLORF( USHORT_TO_FLOAT(red), USHORT_TO_FLOAT(green),
+ USHORT_TO_FLOAT(blue), USHORT_TO_FLOAT(alpha) );
+}
+
+static void GLAPIENTRY
+loopback_Color4ub_f( GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha )
+{
+ COLORF( UBYTE_TO_FLOAT(red), UBYTE_TO_FLOAT(green),
+ UBYTE_TO_FLOAT(blue), UBYTE_TO_FLOAT(alpha) );
+}
+
+
+static void GLAPIENTRY
+loopback_Color4iv_f( const GLint *v )
+{
+ COLORF( INT_TO_FLOAT(v[0]), INT_TO_FLOAT(v[1]),
+ INT_TO_FLOAT(v[2]), INT_TO_FLOAT(v[3]) );
+}
+
+
+static void GLAPIENTRY
+loopback_Color4bv_f( const GLbyte *v )
+{
+ COLORF( BYTE_TO_FLOAT(v[0]), BYTE_TO_FLOAT(v[1]),
+ BYTE_TO_FLOAT(v[2]), BYTE_TO_FLOAT(v[3]) );
+}
+
+static void GLAPIENTRY
+loopback_Color4dv_f( const GLdouble *v )
+{
+ COLORF( (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3] );
+}
+
+
+static void GLAPIENTRY
+loopback_Color4sv_f( const GLshort *v)
+{
+ COLORF( SHORT_TO_FLOAT(v[0]), SHORT_TO_FLOAT(v[1]),
+ SHORT_TO_FLOAT(v[2]), SHORT_TO_FLOAT(v[3]) );
+}
+
+
+static void GLAPIENTRY
+loopback_Color4uiv_f( const GLuint *v)
+{
+ COLORF( UINT_TO_FLOAT(v[0]), UINT_TO_FLOAT(v[1]),
+ UINT_TO_FLOAT(v[2]), UINT_TO_FLOAT(v[3]) );
+}
+
+static void GLAPIENTRY
+loopback_Color4usv_f( const GLushort *v)
+{
+ COLORF( USHORT_TO_FLOAT(v[0]), USHORT_TO_FLOAT(v[1]),
+ USHORT_TO_FLOAT(v[2]), USHORT_TO_FLOAT(v[3]) );
+}
+
+static void GLAPIENTRY
+loopback_Color4ubv_f( const GLubyte *v)
+{
+ COLORF( UBYTE_TO_FLOAT(v[0]), UBYTE_TO_FLOAT(v[1]),
+ UBYTE_TO_FLOAT(v[2]), UBYTE_TO_FLOAT(v[3]) );
+}
+
+static void GLAPIENTRY
+loopback_FogCoorddEXT( GLdouble d )
+{
+ FOGCOORDF( (GLfloat) d );
+}
+
+static void GLAPIENTRY
+loopback_FogCoorddvEXT( const GLdouble *v )
+{
+ FOGCOORDF( (GLfloat) *v );
+}
+
+
+static void GLAPIENTRY
+loopback_Indexd( GLdouble c )
+{
+ INDEX( (GLfloat) c );
+}
+
+static void GLAPIENTRY
+loopback_Indexi( GLint c )
+{
+ INDEX( (GLfloat) c );
+}
+
+static void GLAPIENTRY
+loopback_Indexs( GLshort c )
+{
+ INDEX( (GLfloat) c );
+}
+
+static void GLAPIENTRY
+loopback_Indexub( GLubyte c )
+{
+ INDEX( (GLfloat) c );
+}
+
+static void GLAPIENTRY
+loopback_Indexdv( const GLdouble *c )
+{
+ INDEX( (GLfloat) *c );
+}
+
+static void GLAPIENTRY
+loopback_Indexiv( const GLint *c )
+{
+ INDEX( (GLfloat) *c );
+}
+
+static void GLAPIENTRY
+loopback_Indexsv( const GLshort *c )
+{
+ INDEX( (GLfloat) *c );
+}
+
+static void GLAPIENTRY
+loopback_Indexubv( const GLubyte *c )
+{
+ INDEX( (GLfloat) *c );
+}
+
+static void GLAPIENTRY
+loopback_Normal3b( GLbyte nx, GLbyte ny, GLbyte nz )
+{
+ NORMAL( BYTE_TO_FLOAT(nx), BYTE_TO_FLOAT(ny), BYTE_TO_FLOAT(nz) );
+}
+
+static void GLAPIENTRY
+loopback_Normal3d( GLdouble nx, GLdouble ny, GLdouble nz )
+{
+ NORMAL((GLfloat) nx, (GLfloat) ny, (GLfloat) nz);
+}
+
+static void GLAPIENTRY
+loopback_Normal3i( GLint nx, GLint ny, GLint nz )
+{
+ NORMAL( INT_TO_FLOAT(nx), INT_TO_FLOAT(ny), INT_TO_FLOAT(nz) );
+}
+
+static void GLAPIENTRY
+loopback_Normal3s( GLshort nx, GLshort ny, GLshort nz )
+{
+ NORMAL( SHORT_TO_FLOAT(nx), SHORT_TO_FLOAT(ny), SHORT_TO_FLOAT(nz) );
+}
+
+static void GLAPIENTRY
+loopback_Normal3bv( const GLbyte *v )
+{
+ NORMAL( BYTE_TO_FLOAT(v[0]), BYTE_TO_FLOAT(v[1]), BYTE_TO_FLOAT(v[2]) );
+}
+
+static void GLAPIENTRY
+loopback_Normal3dv( const GLdouble *v )
+{
+ NORMAL( (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2] );
+}
+
+static void GLAPIENTRY
+loopback_Normal3iv( const GLint *v )
+{
+ NORMAL( INT_TO_FLOAT(v[0]), INT_TO_FLOAT(v[1]), INT_TO_FLOAT(v[2]) );
+}
+
+static void GLAPIENTRY
+loopback_Normal3sv( const GLshort *v )
+{
+ NORMAL( SHORT_TO_FLOAT(v[0]), SHORT_TO_FLOAT(v[1]), SHORT_TO_FLOAT(v[2]) );
+}
+
+static void GLAPIENTRY
+loopback_TexCoord1d( GLdouble s )
+{
+ TEXCOORD1((GLfloat) s);
+}
+
+static void GLAPIENTRY
+loopback_TexCoord1i( GLint s )
+{
+ TEXCOORD1((GLfloat) s);
+}
+
+static void GLAPIENTRY
+loopback_TexCoord1s( GLshort s )
+{
+ TEXCOORD1((GLfloat) s);
+}
+
+static void GLAPIENTRY
+loopback_TexCoord2d( GLdouble s, GLdouble t )
+{
+ TEXCOORD2((GLfloat) s,(GLfloat) t);
+}
+
+static void GLAPIENTRY
+loopback_TexCoord2s( GLshort s, GLshort t )
+{
+ TEXCOORD2((GLfloat) s,(GLfloat) t);
+}
+
+static void GLAPIENTRY
+loopback_TexCoord2i( GLint s, GLint t )
+{
+ TEXCOORD2((GLfloat) s,(GLfloat) t);
+}
+
+static void GLAPIENTRY
+loopback_TexCoord3d( GLdouble s, GLdouble t, GLdouble r )
+{
+ TEXCOORD3((GLfloat) s,(GLfloat) t,(GLfloat) r);
+}
+
+static void GLAPIENTRY
+loopback_TexCoord3i( GLint s, GLint t, GLint r )
+{
+ TEXCOORD3((GLfloat) s,(GLfloat) t,(GLfloat) r);
+}
+
+static void GLAPIENTRY
+loopback_TexCoord3s( GLshort s, GLshort t, GLshort r )
+{
+ TEXCOORD3((GLfloat) s,(GLfloat) t,(GLfloat) r);
+}
+
+static void GLAPIENTRY
+loopback_TexCoord4d( GLdouble s, GLdouble t, GLdouble r, GLdouble q )
+{
+ TEXCOORD4((GLfloat) s,(GLfloat) t,(GLfloat) r,(GLfloat) q);
+}
+
+static void GLAPIENTRY
+loopback_TexCoord4i( GLint s, GLint t, GLint r, GLint q )
+{
+ TEXCOORD4((GLfloat) s,(GLfloat) t,(GLfloat) r,(GLfloat) q);
+}
+
+static void GLAPIENTRY
+loopback_TexCoord4s( GLshort s, GLshort t, GLshort r, GLshort q )
+{
+ TEXCOORD4((GLfloat) s,(GLfloat) t,(GLfloat) r,(GLfloat) q);
+}
+
+static void GLAPIENTRY
+loopback_TexCoord1dv( const GLdouble *v )
+{
+ TEXCOORD1((GLfloat) v[0]);
+}
+
+static void GLAPIENTRY
+loopback_TexCoord1iv( const GLint *v )
+{
+ TEXCOORD1((GLfloat) v[0]);
+}
+
+static void GLAPIENTRY
+loopback_TexCoord1sv( const GLshort *v )
+{
+ TEXCOORD1((GLfloat) v[0]);
+}
+
+static void GLAPIENTRY
+loopback_TexCoord2dv( const GLdouble *v )
+{
+ TEXCOORD2((GLfloat) v[0],(GLfloat) v[1]);
+}
+
+static void GLAPIENTRY
+loopback_TexCoord2iv( const GLint *v )
+{
+ TEXCOORD2((GLfloat) v[0],(GLfloat) v[1]);
+}
+
+static void GLAPIENTRY
+loopback_TexCoord2sv( const GLshort *v )
+{
+ TEXCOORD2((GLfloat) v[0],(GLfloat) v[1]);
+}
+
+static void GLAPIENTRY
+loopback_TexCoord3dv( const GLdouble *v )
+{
+ TEXCOORD2((GLfloat) v[0],(GLfloat) v[1]);
+}
+
+static void GLAPIENTRY
+loopback_TexCoord3iv( const GLint *v )
+{
+ TEXCOORD3((GLfloat) v[0],(GLfloat) v[1],(GLfloat) v[2]);
+}
+
+static void GLAPIENTRY
+loopback_TexCoord3sv( const GLshort *v )
+{
+ TEXCOORD3((GLfloat) v[0],(GLfloat) v[1],(GLfloat) v[2]);
+}
+
+static void GLAPIENTRY
+loopback_TexCoord4dv( const GLdouble *v )
+{
+ TEXCOORD4((GLfloat) v[0],(GLfloat) v[1],(GLfloat) v[2],(GLfloat) v[3]);
+}
+
+static void GLAPIENTRY
+loopback_TexCoord4iv( const GLint *v )
+{
+ TEXCOORD4((GLfloat) v[0],(GLfloat) v[1],(GLfloat) v[2],(GLfloat) v[3]);
+}
+
+static void GLAPIENTRY
+loopback_TexCoord4sv( const GLshort *v )
+{
+ TEXCOORD4((GLfloat) v[0],(GLfloat) v[1],(GLfloat) v[2],(GLfloat) v[3]);
+}
+
+static void GLAPIENTRY
+loopback_Vertex2d( GLdouble x, GLdouble y )
+{
+ VERTEX2( (GLfloat) x, (GLfloat) y );
+}
+
+static void GLAPIENTRY
+loopback_Vertex2i( GLint x, GLint y )
+{
+ VERTEX2( (GLfloat) x, (GLfloat) y );
+}
+
+static void GLAPIENTRY
+loopback_Vertex2s( GLshort x, GLshort y )
+{
+ VERTEX2( (GLfloat) x, (GLfloat) y );
+}
+
+static void GLAPIENTRY
+loopback_Vertex3d( GLdouble x, GLdouble y, GLdouble z )
+{
+ VERTEX3( (GLfloat) x, (GLfloat) y, (GLfloat) z );
+}
+
+static void GLAPIENTRY
+loopback_Vertex3i( GLint x, GLint y, GLint z )
+{
+ VERTEX3( (GLfloat) x, (GLfloat) y, (GLfloat) z );
+}
+
+static void GLAPIENTRY
+loopback_Vertex3s( GLshort x, GLshort y, GLshort z )
+{
+ VERTEX3( (GLfloat) x, (GLfloat) y, (GLfloat) z );
+}
+
+static void GLAPIENTRY
+loopback_Vertex4d( GLdouble x, GLdouble y, GLdouble z, GLdouble w )
+{
+ VERTEX4( (GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w );
+}
+
+static void GLAPIENTRY
+loopback_Vertex4i( GLint x, GLint y, GLint z, GLint w )
+{
+ VERTEX4( (GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w );
+}
+
+static void GLAPIENTRY
+loopback_Vertex4s( GLshort x, GLshort y, GLshort z, GLshort w )
+{
+ VERTEX4( (GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w );
+}
+
+static void GLAPIENTRY
+loopback_Vertex2dv( const GLdouble *v )
+{
+ VERTEX2( (GLfloat) v[0], (GLfloat) v[1] );
+}
+
+static void GLAPIENTRY
+loopback_Vertex2iv( const GLint *v )
+{
+ VERTEX2( (GLfloat) v[0], (GLfloat) v[1] );
+}
+
+static void GLAPIENTRY
+loopback_Vertex2sv( const GLshort *v )
+{
+ VERTEX2( (GLfloat) v[0], (GLfloat) v[1] );
+}
+
+static void GLAPIENTRY
+loopback_Vertex3dv( const GLdouble *v )
+{
+ VERTEX3( (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2] );
+}
+
+static void GLAPIENTRY
+loopback_Vertex3iv( const GLint *v )
+{
+ VERTEX3( (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2] );
+}
+
+static void GLAPIENTRY
+loopback_Vertex3sv( const GLshort *v )
+{
+ VERTEX3( (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2] );
+}
+
+static void GLAPIENTRY
+loopback_Vertex4dv( const GLdouble *v )
+{
+ VERTEX4( (GLfloat) v[0], (GLfloat) v[1],
+ (GLfloat) v[2], (GLfloat) v[3] );
+}
+
+static void GLAPIENTRY
+loopback_Vertex4iv( const GLint *v )
+{
+ VERTEX4( (GLfloat) v[0], (GLfloat) v[1],
+ (GLfloat) v[2], (GLfloat) v[3] );
+}
+
+static void GLAPIENTRY
+loopback_Vertex4sv( const GLshort *v )
+{
+ VERTEX4( (GLfloat) v[0], (GLfloat) v[1],
+ (GLfloat) v[2], (GLfloat) v[3] );
+}
+
+static void GLAPIENTRY
+loopback_MultiTexCoord1dARB(GLenum target, GLdouble s)
+{
+ MULTI_TEXCOORD1( target, (GLfloat) s );
+}
+
+static void GLAPIENTRY
+loopback_MultiTexCoord1dvARB(GLenum target, const GLdouble *v)
+{
+ MULTI_TEXCOORD1( target, (GLfloat) v[0] );
+}
+
+static void GLAPIENTRY
+loopback_MultiTexCoord1iARB(GLenum target, GLint s)
+{
+ MULTI_TEXCOORD1( target, (GLfloat) s );
+}
+
+static void GLAPIENTRY
+loopback_MultiTexCoord1ivARB(GLenum target, const GLint *v)
+{
+ MULTI_TEXCOORD1( target, (GLfloat) v[0] );
+}
+
+static void GLAPIENTRY
+loopback_MultiTexCoord1sARB(GLenum target, GLshort s)
+{
+ MULTI_TEXCOORD1( target, (GLfloat) s );
+}
+
+static void GLAPIENTRY
+loopback_MultiTexCoord1svARB(GLenum target, const GLshort *v)
+{
+ MULTI_TEXCOORD1( target, (GLfloat) v[0] );
+}
+
+static void GLAPIENTRY
+loopback_MultiTexCoord2dARB(GLenum target, GLdouble s, GLdouble t)
+{
+ MULTI_TEXCOORD2( target, (GLfloat) s, (GLfloat) t );
+}
+
+static void GLAPIENTRY
+loopback_MultiTexCoord2dvARB(GLenum target, const GLdouble *v)
+{
+ MULTI_TEXCOORD2( target, (GLfloat) v[0], (GLfloat) v[1] );
+}
+
+static void GLAPIENTRY
+loopback_MultiTexCoord2iARB(GLenum target, GLint s, GLint t)
+{
+ MULTI_TEXCOORD2( target, (GLfloat) s, (GLfloat) t );
+}
+
+static void GLAPIENTRY
+loopback_MultiTexCoord2ivARB(GLenum target, const GLint *v)
+{
+ MULTI_TEXCOORD2( target, (GLfloat) v[0], (GLfloat) v[1] );
+}
+
+static void GLAPIENTRY
+loopback_MultiTexCoord2sARB(GLenum target, GLshort s, GLshort t)
+{
+ MULTI_TEXCOORD2( target, (GLfloat) s, (GLfloat) t );
+}
+
+static void GLAPIENTRY
+loopback_MultiTexCoord2svARB(GLenum target, const GLshort *v)
+{
+ MULTI_TEXCOORD2( target, (GLfloat) v[0], (GLfloat) v[1] );
+}
+
+static void GLAPIENTRY
+loopback_MultiTexCoord3dARB(GLenum target, GLdouble s, GLdouble t, GLdouble r)
+{
+ MULTI_TEXCOORD3( target, (GLfloat) s, (GLfloat) t, (GLfloat) r );
+}
+
+static void GLAPIENTRY
+loopback_MultiTexCoord3dvARB(GLenum target, const GLdouble *v)
+{
+ MULTI_TEXCOORD3( target, (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2] );
+}
+
+static void GLAPIENTRY
+loopback_MultiTexCoord3iARB(GLenum target, GLint s, GLint t, GLint r)
+{
+ MULTI_TEXCOORD3( target, (GLfloat) s, (GLfloat) t, (GLfloat) r );
+}
+
+static void GLAPIENTRY
+loopback_MultiTexCoord3ivARB(GLenum target, const GLint *v)
+{
+ MULTI_TEXCOORD3( target, (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2] );
+}
+
+static void GLAPIENTRY
+loopback_MultiTexCoord3sARB(GLenum target, GLshort s, GLshort t, GLshort r)
+{
+ MULTI_TEXCOORD3( target, (GLfloat) s, (GLfloat) t, (GLfloat) r );
+}
+
+static void GLAPIENTRY
+loopback_MultiTexCoord3svARB(GLenum target, const GLshort *v)
+{
+ MULTI_TEXCOORD3( target, (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2] );
+}
+
+static void GLAPIENTRY
+loopback_MultiTexCoord4dARB(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q)
+{
+ MULTI_TEXCOORD4( target, (GLfloat) s, (GLfloat) t,
+ (GLfloat) r, (GLfloat) q );
+}
+
+static void GLAPIENTRY
+loopback_MultiTexCoord4dvARB(GLenum target, const GLdouble *v)
+{
+ MULTI_TEXCOORD4( target, (GLfloat) v[0], (GLfloat) v[1],
+ (GLfloat) v[2], (GLfloat) v[3] );
+}
+
+static void GLAPIENTRY
+loopback_MultiTexCoord4iARB(GLenum target, GLint s, GLint t, GLint r, GLint q)
+{
+ MULTI_TEXCOORD4( target, (GLfloat) s, (GLfloat) t,
+ (GLfloat) r, (GLfloat) q );
+}
+
+static void GLAPIENTRY
+loopback_MultiTexCoord4ivARB(GLenum target, const GLint *v)
+{
+ MULTI_TEXCOORD4( target, (GLfloat) v[0], (GLfloat) v[1],
+ (GLfloat) v[2], (GLfloat) v[3] );
+}
+
+static void GLAPIENTRY
+loopback_MultiTexCoord4sARB(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q)
+{
+ MULTI_TEXCOORD4( target, (GLfloat) s, (GLfloat) t,
+ (GLfloat) r, (GLfloat) q );
+}
+
+static void GLAPIENTRY
+loopback_MultiTexCoord4svARB(GLenum target, const GLshort *v)
+{
+ MULTI_TEXCOORD4( target, (GLfloat) v[0], (GLfloat) v[1],
+ (GLfloat) v[2], (GLfloat) v[3] );
+}
+
+static void GLAPIENTRY
+loopback_EvalCoord2dv( const GLdouble *u )
+{
+ EVALCOORD2( (GLfloat) u[0], (GLfloat) u[1] );
+}
+
+static void GLAPIENTRY
+loopback_EvalCoord2fv( const GLfloat *u )
+{
+ EVALCOORD2( u[0], u[1] );
+}
+
+static void GLAPIENTRY
+loopback_EvalCoord2d( GLdouble u, GLdouble v )
+{
+ EVALCOORD2( (GLfloat) u, (GLfloat) v );
+}
+
+static void GLAPIENTRY
+loopback_EvalCoord1dv( const GLdouble *u )
+{
+ EVALCOORD1( (GLfloat) *u );
+}
+
+static void GLAPIENTRY
+loopback_EvalCoord1fv( const GLfloat *u )
+{
+ EVALCOORD1( (GLfloat) *u );
+}
+
+static void GLAPIENTRY
+loopback_EvalCoord1d( GLdouble u )
+{
+ EVALCOORD1( (GLfloat) u );
+}
+
+static void GLAPIENTRY
+loopback_Materialf( GLenum face, GLenum pname, GLfloat param )
+{
+ GLfloat fparam[4];
+ fparam[0] = param;
+ MATERIALFV( face, pname, fparam );
+}
+
+static void GLAPIENTRY
+loopback_Materiali(GLenum face, GLenum pname, GLint param )
+{
+ GLfloat p = (GLfloat) param;
+ MATERIALFV(face, pname, &p);
+}
+
+static void GLAPIENTRY
+loopback_Materialiv(GLenum face, GLenum pname, const GLint *params )
+{
+ GLfloat fparam[4];
+ switch (pname) {
+ case GL_AMBIENT:
+ case GL_DIFFUSE:
+ case GL_SPECULAR:
+ case GL_EMISSION:
+ case GL_AMBIENT_AND_DIFFUSE:
+ fparam[0] = INT_TO_FLOAT( params[0] );
+ fparam[1] = INT_TO_FLOAT( params[1] );
+ fparam[2] = INT_TO_FLOAT( params[2] );
+ fparam[3] = INT_TO_FLOAT( params[3] );
+ break;
+ case GL_SHININESS:
+ fparam[0] = (GLfloat) params[0];
+ break;
+ case GL_COLOR_INDEXES:
+ fparam[0] = (GLfloat) params[0];
+ fparam[1] = (GLfloat) params[1];
+ fparam[2] = (GLfloat) params[2];
+ break;
+ default:
+ ;
+ }
+ MATERIALFV(face, pname, fparam);
+}
+
+
+static void GLAPIENTRY
+loopback_Rectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2)
+{
+ RECTF((GLfloat) x1, (GLfloat) y1, (GLfloat) x2, (GLfloat) y2);
+}
+
+static void GLAPIENTRY
+loopback_Rectdv(const GLdouble *v1, const GLdouble *v2)
+{
+ RECTF((GLfloat) v1[0], (GLfloat) v1[1], (GLfloat) v2[0], (GLfloat) v2[1]);
+}
+
+static void GLAPIENTRY
+loopback_Rectfv(const GLfloat *v1, const GLfloat *v2)
+{
+ RECTF(v1[0], v1[1], v2[0], v2[1]);
+}
+
+static void GLAPIENTRY
+loopback_Recti(GLint x1, GLint y1, GLint x2, GLint y2)
+{
+ RECTF((GLfloat) x1, (GLfloat) y1, (GLfloat) x2, (GLfloat) y2);
+}
+
+static void GLAPIENTRY
+loopback_Rectiv(const GLint *v1, const GLint *v2)
+{
+ RECTF((GLfloat) v1[0], (GLfloat) v1[1], (GLfloat) v2[0], (GLfloat) v2[1]);
+}
+
+static void GLAPIENTRY
+loopback_Rects(GLshort x1, GLshort y1, GLshort x2, GLshort y2)
+{
+ RECTF((GLfloat) x1, (GLfloat) y1, (GLfloat) x2, (GLfloat) y2);
+}
+
+static void GLAPIENTRY
+loopback_Rectsv(const GLshort *v1, const GLshort *v2)
+{
+ RECTF((GLfloat) v1[0], (GLfloat) v1[1], (GLfloat) v2[0], (GLfloat) v2[1]);
+}
+
+static void GLAPIENTRY
+loopback_SecondaryColor3bEXT_f( GLbyte red, GLbyte green, GLbyte blue )
+{
+ SECONDARYCOLORF( BYTE_TO_FLOAT(red),
+ BYTE_TO_FLOAT(green),
+ BYTE_TO_FLOAT(blue) );
+}
+
+static void GLAPIENTRY
+loopback_SecondaryColor3dEXT_f( GLdouble red, GLdouble green, GLdouble blue )
+{
+ SECONDARYCOLORF( (GLfloat) red, (GLfloat) green, (GLfloat) blue );
+}
+
+static void GLAPIENTRY
+loopback_SecondaryColor3iEXT_f( GLint red, GLint green, GLint blue )
+{
+ SECONDARYCOLORF( INT_TO_FLOAT(red),
+ INT_TO_FLOAT(green),
+ INT_TO_FLOAT(blue));
+}
+
+static void GLAPIENTRY
+loopback_SecondaryColor3sEXT_f( GLshort red, GLshort green, GLshort blue )
+{
+ SECONDARYCOLORF(SHORT_TO_FLOAT(red),
+ SHORT_TO_FLOAT(green),
+ SHORT_TO_FLOAT(blue));
+}
+
+static void GLAPIENTRY
+loopback_SecondaryColor3uiEXT_f( GLuint red, GLuint green, GLuint blue )
+{
+ SECONDARYCOLORF(UINT_TO_FLOAT(red),
+ UINT_TO_FLOAT(green),
+ UINT_TO_FLOAT(blue));
+}
+
+static void GLAPIENTRY
+loopback_SecondaryColor3usEXT_f( GLushort red, GLushort green, GLushort blue )
+{
+ SECONDARYCOLORF(USHORT_TO_FLOAT(red),
+ USHORT_TO_FLOAT(green),
+ USHORT_TO_FLOAT(blue));
+}
+
+static void GLAPIENTRY
+loopback_SecondaryColor3ubEXT_f( GLubyte red, GLubyte green, GLubyte blue )
+{
+ SECONDARYCOLORF(UBYTE_TO_FLOAT(red),
+ UBYTE_TO_FLOAT(green),
+ UBYTE_TO_FLOAT(blue));
+}
+
+static void GLAPIENTRY
+loopback_SecondaryColor3bvEXT_f( const GLbyte *v )
+{
+ SECONDARYCOLORF(BYTE_TO_FLOAT(v[0]),
+ BYTE_TO_FLOAT(v[1]),
+ BYTE_TO_FLOAT(v[2]));
+}
+
+static void GLAPIENTRY
+loopback_SecondaryColor3dvEXT_f( const GLdouble *v )
+{
+ SECONDARYCOLORF( (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2] );
+}
+static void GLAPIENTRY
+loopback_SecondaryColor3ivEXT_f( const GLint *v )
+{
+ SECONDARYCOLORF(INT_TO_FLOAT(v[0]),
+ INT_TO_FLOAT(v[1]),
+ INT_TO_FLOAT(v[2]));
+}
+
+static void GLAPIENTRY
+loopback_SecondaryColor3svEXT_f( const GLshort *v )
+{
+ SECONDARYCOLORF(SHORT_TO_FLOAT(v[0]),
+ SHORT_TO_FLOAT(v[1]),
+ SHORT_TO_FLOAT(v[2]));
+}
+
+static void GLAPIENTRY
+loopback_SecondaryColor3uivEXT_f( const GLuint *v )
+{
+ SECONDARYCOLORF(UINT_TO_FLOAT(v[0]),
+ UINT_TO_FLOAT(v[1]),
+ UINT_TO_FLOAT(v[2]));
+}
+
+static void GLAPIENTRY
+loopback_SecondaryColor3usvEXT_f( const GLushort *v )
+{
+ SECONDARYCOLORF(USHORT_TO_FLOAT(v[0]),
+ USHORT_TO_FLOAT(v[1]),
+ USHORT_TO_FLOAT(v[2]));
+}
+
+static void GLAPIENTRY
+loopback_SecondaryColor3ubvEXT_f( const GLubyte *v )
+{
+ SECONDARYCOLORF(UBYTE_TO_FLOAT(v[0]),
+ UBYTE_TO_FLOAT(v[1]),
+ UBYTE_TO_FLOAT(v[2]));
+}
+
+
+/*
+ * GL_NV_vertex_program:
+ * Always loop-back to one of the VertexAttrib[1234]f[v]NV functions.
+ */
+
+static void GLAPIENTRY
+loopback_VertexAttrib1sNV(GLuint index, GLshort x)
+{
+ ATTRIB1NV(index, (GLfloat) x);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib1dNV(GLuint index, GLdouble x)
+{
+ ATTRIB1NV(index, (GLfloat) x);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib2sNV(GLuint index, GLshort x, GLshort y)
+{
+ ATTRIB2NV(index, (GLfloat) x, y);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib2dNV(GLuint index, GLdouble x, GLdouble y)
+{
+ ATTRIB2NV(index, (GLfloat) x, (GLfloat) y);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib3sNV(GLuint index, GLshort x, GLshort y, GLshort z)
+{
+ ATTRIB3NV(index, (GLfloat) x, (GLfloat) y, (GLfloat) z);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib3dNV(GLuint index, GLdouble x, GLdouble y, GLdouble z)
+{
+ ATTRIB4NV(index, (GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib4sNV(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w)
+{
+ ATTRIB4NV(index, (GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib4dNV(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w)
+{
+ ATTRIB4NV(index, (GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib4ubNV(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w)
+{
+ ATTRIB4NV(index, UBYTE_TO_FLOAT(x), UBYTE_TO_FLOAT(y),
+ UBYTE_TO_FLOAT(z), UBYTE_TO_FLOAT(w));
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib1svNV(GLuint index, const GLshort *v)
+{
+ ATTRIB1NV(index, (GLfloat) v[0]);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib1dvNV(GLuint index, const GLdouble *v)
+{
+ ATTRIB1NV(index, (GLfloat) v[0]);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib2svNV(GLuint index, const GLshort *v)
+{
+ ATTRIB2NV(index, (GLfloat) v[0], (GLfloat) v[1]);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib2dvNV(GLuint index, const GLdouble *v)
+{
+ ATTRIB2NV(index, (GLfloat) v[0], (GLfloat) v[1]);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib3svNV(GLuint index, const GLshort *v)
+{
+ ATTRIB3NV(index, (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2]);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib3dvNV(GLuint index, const GLdouble *v)
+{
+ ATTRIB3NV(index, (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2]);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib4svNV(GLuint index, const GLshort *v)
+{
+ ATTRIB4NV(index, (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2],
+ (GLfloat)v[3]);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib4dvNV(GLuint index, const GLdouble *v)
+{
+ ATTRIB4NV(index, (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib4ubvNV(GLuint index, const GLubyte *v)
+{
+ ATTRIB4NV(index, UBYTE_TO_FLOAT(v[0]), UBYTE_TO_FLOAT(v[1]),
+ UBYTE_TO_FLOAT(v[2]), UBYTE_TO_FLOAT(v[3]));
+}
+
+
+static void GLAPIENTRY
+loopback_VertexAttribs1svNV(GLuint index, GLsizei n, const GLshort *v)
+{
+ GLint i;
+ for (i = n - 1; i >= 0; i--)
+ loopback_VertexAttrib1svNV(index + i, v + i);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttribs1fvNV(GLuint index, GLsizei n, const GLfloat *v)
+{
+ GLint i;
+ for (i = n - 1; i >= 0; i--)
+ ATTRIB1NV(index + i, v[i]);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttribs1dvNV(GLuint index, GLsizei n, const GLdouble *v)
+{
+ GLint i;
+ for (i = n - 1; i >= 0; i--)
+ loopback_VertexAttrib1dvNV(index + i, v + i);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttribs2svNV(GLuint index, GLsizei n, const GLshort *v)
+{
+ GLint i;
+ for (i = n - 1; i >= 0; i--)
+ loopback_VertexAttrib2svNV(index + i, v + 2 * i);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttribs2fvNV(GLuint index, GLsizei n, const GLfloat *v)
+{
+ GLint i;
+ for (i = n - 1; i >= 0; i--)
+ ATTRIB2NV(index + i, v[2 * i], v[2 * i + 1]);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttribs2dvNV(GLuint index, GLsizei n, const GLdouble *v)
+{
+ GLint i;
+ for (i = n - 1; i >= 0; i--)
+ loopback_VertexAttrib2dvNV(index + i, v + 2 * i);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttribs3svNV(GLuint index, GLsizei n, const GLshort *v)
+{
+ GLint i;
+ for (i = n - 1; i >= 0; i--)
+ loopback_VertexAttrib3svNV(index + i, v + 3 * i);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttribs3fvNV(GLuint index, GLsizei n, const GLfloat *v)
+{
+ GLint i;
+ for (i = n - 1; i >= 0; i--)
+ ATTRIB3NV(index + i, v[3 * i], v[3 * i + 1], v[3 * i + 2]);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttribs3dvNV(GLuint index, GLsizei n, const GLdouble *v)
+{
+ GLint i;
+ for (i = n - 1; i >= 0; i--)
+ loopback_VertexAttrib3dvNV(index + i, v + 3 * i);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttribs4svNV(GLuint index, GLsizei n, const GLshort *v)
+{
+ GLint i;
+ for (i = n - 1; i >= 0; i--)
+ loopback_VertexAttrib4svNV(index + i, v + 4 * i);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttribs4fvNV(GLuint index, GLsizei n, const GLfloat *v)
+{
+ GLint i;
+ for (i = n - 1; i >= 0; i--)
+ ATTRIB4NV(index + i, v[4 * i], v[4 * i + 1], v[4 * i + 2], v[4 * i + 3]);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttribs4dvNV(GLuint index, GLsizei n, const GLdouble *v)
+{
+ GLint i;
+ for (i = n - 1; i >= 0; i--)
+ loopback_VertexAttrib4dvNV(index + i, v + 4 * i);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttribs4ubvNV(GLuint index, GLsizei n, const GLubyte *v)
+{
+ GLint i;
+ for (i = n - 1; i >= 0; i--)
+ loopback_VertexAttrib4ubvNV(index + i, v + 4 * i);
+}
+
+
+/*
+ * GL_ARB_vertex_program
+ * Always loop-back to one of the VertexAttrib[1234]f[v]ARB functions.
+ */
+
+static void GLAPIENTRY
+loopback_VertexAttrib1sARB(GLuint index, GLshort x)
+{
+ ATTRIB1ARB(index, (GLfloat) x);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib1dARB(GLuint index, GLdouble x)
+{
+ ATTRIB1ARB(index, (GLfloat) x);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib2sARB(GLuint index, GLshort x, GLshort y)
+{
+ ATTRIB2ARB(index, (GLfloat) x, y);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib2dARB(GLuint index, GLdouble x, GLdouble y)
+{
+ ATTRIB2ARB(index, (GLfloat) x, (GLfloat) y);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib3sARB(GLuint index, GLshort x, GLshort y, GLshort z)
+{
+ ATTRIB3ARB(index, (GLfloat) x, (GLfloat) y, (GLfloat) z);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib3dARB(GLuint index, GLdouble x, GLdouble y, GLdouble z)
+{
+ ATTRIB4ARB(index, (GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib4sARB(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w)
+{
+ ATTRIB4ARB(index, (GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib4dARB(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w)
+{
+ ATTRIB4ARB(index, (GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib1svARB(GLuint index, const GLshort *v)
+{
+ ATTRIB1ARB(index, (GLfloat) v[0]);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib1dvARB(GLuint index, const GLdouble *v)
+{
+ ATTRIB1ARB(index, (GLfloat) v[0]);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib2svARB(GLuint index, const GLshort *v)
+{
+ ATTRIB2ARB(index, (GLfloat) v[0], (GLfloat) v[1]);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib2dvARB(GLuint index, const GLdouble *v)
+{
+ ATTRIB2ARB(index, (GLfloat) v[0], (GLfloat) v[1]);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib3svARB(GLuint index, const GLshort *v)
+{
+ ATTRIB3ARB(index, (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2]);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib3dvARB(GLuint index, const GLdouble *v)
+{
+ ATTRIB3ARB(index, (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2]);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib4svARB(GLuint index, const GLshort *v)
+{
+ ATTRIB4ARB(index, (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2],
+ (GLfloat)v[3]);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib4dvARB(GLuint index, const GLdouble *v)
+{
+ ATTRIB4ARB(index, (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib4bvARB(GLuint index, const GLbyte * v)
+{
+ ATTRIB4ARB(index, (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib4ivARB(GLuint index, const GLint * v)
+{
+ ATTRIB4ARB(index, (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib4ubvARB(GLuint index, const GLubyte * v)
+{
+ ATTRIB4ARB(index, (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib4usvARB(GLuint index, const GLushort * v)
+{
+ ATTRIB4ARB(index, (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib4uivARB(GLuint index, const GLuint * v)
+{
+ ATTRIB4ARB(index, (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]);
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib4NbvARB(GLuint index, const GLbyte * v)
+{
+ ATTRIB4ARB(index, BYTE_TO_FLOAT(v[0]), BYTE_TO_FLOAT(v[1]),
+ BYTE_TO_FLOAT(v[2]), BYTE_TO_FLOAT(v[3]));
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib4NsvARB(GLuint index, const GLshort * v)
+{
+ ATTRIB4ARB(index, SHORT_TO_FLOAT(v[0]), SHORT_TO_FLOAT(v[1]),
+ SHORT_TO_FLOAT(v[2]), SHORT_TO_FLOAT(v[3]));
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib4NivARB(GLuint index, const GLint * v)
+{
+ ATTRIB4ARB(index, INT_TO_FLOAT(v[0]), INT_TO_FLOAT(v[1]),
+ INT_TO_FLOAT(v[2]), INT_TO_FLOAT(v[3]));
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib4NubARB(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w)
+{
+ ATTRIB4ARB(index, UBYTE_TO_FLOAT(x), UBYTE_TO_FLOAT(y),
+ UBYTE_TO_FLOAT(z), UBYTE_TO_FLOAT(w));
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib4NubvARB(GLuint index, const GLubyte * v)
+{
+ ATTRIB4ARB(index, UBYTE_TO_FLOAT(v[0]), UBYTE_TO_FLOAT(v[1]),
+ UBYTE_TO_FLOAT(v[2]), UBYTE_TO_FLOAT(v[3]));
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib4NusvARB(GLuint index, const GLushort * v)
+{
+ ATTRIB4ARB(index, USHORT_TO_FLOAT(v[0]), USHORT_TO_FLOAT(v[1]),
+ USHORT_TO_FLOAT(v[2]), USHORT_TO_FLOAT(v[3]));
+}
+
+static void GLAPIENTRY
+loopback_VertexAttrib4NuivARB(GLuint index, const GLuint * v)
+{
+ ATTRIB4ARB(index, UINT_TO_FLOAT(v[0]), UINT_TO_FLOAT(v[1]),
+ UINT_TO_FLOAT(v[2]), UINT_TO_FLOAT(v[3]));
+}
+
+
+
+
+/*
+ * This code never registers handlers for any of the entry points
+ * listed in vtxfmt.h.
+ */
+void
+_mesa_loopback_init_api_table( struct _glapi_table *dest )
+{
+ SET_Color3b(dest, loopback_Color3b_f);
+ SET_Color3d(dest, loopback_Color3d_f);
+ SET_Color3i(dest, loopback_Color3i_f);
+ SET_Color3s(dest, loopback_Color3s_f);
+ SET_Color3ui(dest, loopback_Color3ui_f);
+ SET_Color3us(dest, loopback_Color3us_f);
+ SET_Color3ub(dest, loopback_Color3ub_f);
+ SET_Color4b(dest, loopback_Color4b_f);
+ SET_Color4d(dest, loopback_Color4d_f);
+ SET_Color4i(dest, loopback_Color4i_f);
+ SET_Color4s(dest, loopback_Color4s_f);
+ SET_Color4ui(dest, loopback_Color4ui_f);
+ SET_Color4us(dest, loopback_Color4us_f);
+ SET_Color4ub(dest, loopback_Color4ub_f);
+ SET_Color3bv(dest, loopback_Color3bv_f);
+ SET_Color3dv(dest, loopback_Color3dv_f);
+ SET_Color3iv(dest, loopback_Color3iv_f);
+ SET_Color3sv(dest, loopback_Color3sv_f);
+ SET_Color3uiv(dest, loopback_Color3uiv_f);
+ SET_Color3usv(dest, loopback_Color3usv_f);
+ SET_Color3ubv(dest, loopback_Color3ubv_f);
+ SET_Color4bv(dest, loopback_Color4bv_f);
+ SET_Color4dv(dest, loopback_Color4dv_f);
+ SET_Color4iv(dest, loopback_Color4iv_f);
+ SET_Color4sv(dest, loopback_Color4sv_f);
+ SET_Color4uiv(dest, loopback_Color4uiv_f);
+ SET_Color4usv(dest, loopback_Color4usv_f);
+ SET_Color4ubv(dest, loopback_Color4ubv_f);
+
+ SET_SecondaryColor3bEXT(dest, loopback_SecondaryColor3bEXT_f);
+ SET_SecondaryColor3dEXT(dest, loopback_SecondaryColor3dEXT_f);
+ SET_SecondaryColor3iEXT(dest, loopback_SecondaryColor3iEXT_f);
+ SET_SecondaryColor3sEXT(dest, loopback_SecondaryColor3sEXT_f);
+ SET_SecondaryColor3uiEXT(dest, loopback_SecondaryColor3uiEXT_f);
+ SET_SecondaryColor3usEXT(dest, loopback_SecondaryColor3usEXT_f);
+ SET_SecondaryColor3ubEXT(dest, loopback_SecondaryColor3ubEXT_f);
+ SET_SecondaryColor3bvEXT(dest, loopback_SecondaryColor3bvEXT_f);
+ SET_SecondaryColor3dvEXT(dest, loopback_SecondaryColor3dvEXT_f);
+ SET_SecondaryColor3ivEXT(dest, loopback_SecondaryColor3ivEXT_f);
+ SET_SecondaryColor3svEXT(dest, loopback_SecondaryColor3svEXT_f);
+ SET_SecondaryColor3uivEXT(dest, loopback_SecondaryColor3uivEXT_f);
+ SET_SecondaryColor3usvEXT(dest, loopback_SecondaryColor3usvEXT_f);
+ SET_SecondaryColor3ubvEXT(dest, loopback_SecondaryColor3ubvEXT_f);
+
+ SET_Indexd(dest, loopback_Indexd);
+ SET_Indexi(dest, loopback_Indexi);
+ SET_Indexs(dest, loopback_Indexs);
+ SET_Indexub(dest, loopback_Indexub);
+ SET_Indexdv(dest, loopback_Indexdv);
+ SET_Indexiv(dest, loopback_Indexiv);
+ SET_Indexsv(dest, loopback_Indexsv);
+ SET_Indexubv(dest, loopback_Indexubv);
+ SET_Normal3b(dest, loopback_Normal3b);
+ SET_Normal3d(dest, loopback_Normal3d);
+ SET_Normal3i(dest, loopback_Normal3i);
+ SET_Normal3s(dest, loopback_Normal3s);
+ SET_Normal3bv(dest, loopback_Normal3bv);
+ SET_Normal3dv(dest, loopback_Normal3dv);
+ SET_Normal3iv(dest, loopback_Normal3iv);
+ SET_Normal3sv(dest, loopback_Normal3sv);
+ SET_TexCoord1d(dest, loopback_TexCoord1d);
+ SET_TexCoord1i(dest, loopback_TexCoord1i);
+ SET_TexCoord1s(dest, loopback_TexCoord1s);
+ SET_TexCoord2d(dest, loopback_TexCoord2d);
+ SET_TexCoord2s(dest, loopback_TexCoord2s);
+ SET_TexCoord2i(dest, loopback_TexCoord2i);
+ SET_TexCoord3d(dest, loopback_TexCoord3d);
+ SET_TexCoord3i(dest, loopback_TexCoord3i);
+ SET_TexCoord3s(dest, loopback_TexCoord3s);
+ SET_TexCoord4d(dest, loopback_TexCoord4d);
+ SET_TexCoord4i(dest, loopback_TexCoord4i);
+ SET_TexCoord4s(dest, loopback_TexCoord4s);
+ SET_TexCoord1dv(dest, loopback_TexCoord1dv);
+ SET_TexCoord1iv(dest, loopback_TexCoord1iv);
+ SET_TexCoord1sv(dest, loopback_TexCoord1sv);
+ SET_TexCoord2dv(dest, loopback_TexCoord2dv);
+ SET_TexCoord2iv(dest, loopback_TexCoord2iv);
+ SET_TexCoord2sv(dest, loopback_TexCoord2sv);
+ SET_TexCoord3dv(dest, loopback_TexCoord3dv);
+ SET_TexCoord3iv(dest, loopback_TexCoord3iv);
+ SET_TexCoord3sv(dest, loopback_TexCoord3sv);
+ SET_TexCoord4dv(dest, loopback_TexCoord4dv);
+ SET_TexCoord4iv(dest, loopback_TexCoord4iv);
+ SET_TexCoord4sv(dest, loopback_TexCoord4sv);
+ SET_Vertex2d(dest, loopback_Vertex2d);
+ SET_Vertex2i(dest, loopback_Vertex2i);
+ SET_Vertex2s(dest, loopback_Vertex2s);
+ SET_Vertex3d(dest, loopback_Vertex3d);
+ SET_Vertex3i(dest, loopback_Vertex3i);
+ SET_Vertex3s(dest, loopback_Vertex3s);
+ SET_Vertex4d(dest, loopback_Vertex4d);
+ SET_Vertex4i(dest, loopback_Vertex4i);
+ SET_Vertex4s(dest, loopback_Vertex4s);
+ SET_Vertex2dv(dest, loopback_Vertex2dv);
+ SET_Vertex2iv(dest, loopback_Vertex2iv);
+ SET_Vertex2sv(dest, loopback_Vertex2sv);
+ SET_Vertex3dv(dest, loopback_Vertex3dv);
+ SET_Vertex3iv(dest, loopback_Vertex3iv);
+ SET_Vertex3sv(dest, loopback_Vertex3sv);
+ SET_Vertex4dv(dest, loopback_Vertex4dv);
+ SET_Vertex4iv(dest, loopback_Vertex4iv);
+ SET_Vertex4sv(dest, loopback_Vertex4sv);
+ SET_MultiTexCoord1dARB(dest, loopback_MultiTexCoord1dARB);
+ SET_MultiTexCoord1dvARB(dest, loopback_MultiTexCoord1dvARB);
+ SET_MultiTexCoord1iARB(dest, loopback_MultiTexCoord1iARB);
+ SET_MultiTexCoord1ivARB(dest, loopback_MultiTexCoord1ivARB);
+ SET_MultiTexCoord1sARB(dest, loopback_MultiTexCoord1sARB);
+ SET_MultiTexCoord1svARB(dest, loopback_MultiTexCoord1svARB);
+ SET_MultiTexCoord2dARB(dest, loopback_MultiTexCoord2dARB);
+ SET_MultiTexCoord2dvARB(dest, loopback_MultiTexCoord2dvARB);
+ SET_MultiTexCoord2iARB(dest, loopback_MultiTexCoord2iARB);
+ SET_MultiTexCoord2ivARB(dest, loopback_MultiTexCoord2ivARB);
+ SET_MultiTexCoord2sARB(dest, loopback_MultiTexCoord2sARB);
+ SET_MultiTexCoord2svARB(dest, loopback_MultiTexCoord2svARB);
+ SET_MultiTexCoord3dARB(dest, loopback_MultiTexCoord3dARB);
+ SET_MultiTexCoord3dvARB(dest, loopback_MultiTexCoord3dvARB);
+ SET_MultiTexCoord3iARB(dest, loopback_MultiTexCoord3iARB);
+ SET_MultiTexCoord3ivARB(dest, loopback_MultiTexCoord3ivARB);
+ SET_MultiTexCoord3sARB(dest, loopback_MultiTexCoord3sARB);
+ SET_MultiTexCoord3svARB(dest, loopback_MultiTexCoord3svARB);
+ SET_MultiTexCoord4dARB(dest, loopback_MultiTexCoord4dARB);
+ SET_MultiTexCoord4dvARB(dest, loopback_MultiTexCoord4dvARB);
+ SET_MultiTexCoord4iARB(dest, loopback_MultiTexCoord4iARB);
+ SET_MultiTexCoord4ivARB(dest, loopback_MultiTexCoord4ivARB);
+ SET_MultiTexCoord4sARB(dest, loopback_MultiTexCoord4sARB);
+ SET_MultiTexCoord4svARB(dest, loopback_MultiTexCoord4svARB);
+ SET_EvalCoord2dv(dest, loopback_EvalCoord2dv);
+ SET_EvalCoord2fv(dest, loopback_EvalCoord2fv);
+ SET_EvalCoord2d(dest, loopback_EvalCoord2d);
+ SET_EvalCoord1dv(dest, loopback_EvalCoord1dv);
+ SET_EvalCoord1fv(dest, loopback_EvalCoord1fv);
+ SET_EvalCoord1d(dest, loopback_EvalCoord1d);
+ SET_Materialf(dest, loopback_Materialf);
+ SET_Materiali(dest, loopback_Materiali);
+ SET_Materialiv(dest, loopback_Materialiv);
+ SET_Rectd(dest, loopback_Rectd);
+ SET_Rectdv(dest, loopback_Rectdv);
+ SET_Rectfv(dest, loopback_Rectfv);
+ SET_Recti(dest, loopback_Recti);
+ SET_Rectiv(dest, loopback_Rectiv);
+ SET_Rects(dest, loopback_Rects);
+ SET_Rectsv(dest, loopback_Rectsv);
+ SET_FogCoorddEXT(dest, loopback_FogCoorddEXT);
+ SET_FogCoorddvEXT(dest, loopback_FogCoorddvEXT);
+
+ SET_VertexAttrib1sNV(dest, loopback_VertexAttrib1sNV);
+ SET_VertexAttrib1dNV(dest, loopback_VertexAttrib1dNV);
+ SET_VertexAttrib2sNV(dest, loopback_VertexAttrib2sNV);
+ SET_VertexAttrib2dNV(dest, loopback_VertexAttrib2dNV);
+ SET_VertexAttrib3sNV(dest, loopback_VertexAttrib3sNV);
+ SET_VertexAttrib3dNV(dest, loopback_VertexAttrib3dNV);
+ SET_VertexAttrib4sNV(dest, loopback_VertexAttrib4sNV);
+ SET_VertexAttrib4dNV(dest, loopback_VertexAttrib4dNV);
+ SET_VertexAttrib4ubNV(dest, loopback_VertexAttrib4ubNV);
+ SET_VertexAttrib1svNV(dest, loopback_VertexAttrib1svNV);
+ SET_VertexAttrib1dvNV(dest, loopback_VertexAttrib1dvNV);
+ SET_VertexAttrib2svNV(dest, loopback_VertexAttrib2svNV);
+ SET_VertexAttrib2dvNV(dest, loopback_VertexAttrib2dvNV);
+ SET_VertexAttrib3svNV(dest, loopback_VertexAttrib3svNV);
+ SET_VertexAttrib3dvNV(dest, loopback_VertexAttrib3dvNV);
+ SET_VertexAttrib4svNV(dest, loopback_VertexAttrib4svNV);
+ SET_VertexAttrib4dvNV(dest, loopback_VertexAttrib4dvNV);
+ SET_VertexAttrib4ubvNV(dest, loopback_VertexAttrib4ubvNV);
+ SET_VertexAttribs1svNV(dest, loopback_VertexAttribs1svNV);
+ SET_VertexAttribs1fvNV(dest, loopback_VertexAttribs1fvNV);
+ SET_VertexAttribs1dvNV(dest, loopback_VertexAttribs1dvNV);
+ SET_VertexAttribs2svNV(dest, loopback_VertexAttribs2svNV);
+ SET_VertexAttribs2fvNV(dest, loopback_VertexAttribs2fvNV);
+ SET_VertexAttribs2dvNV(dest, loopback_VertexAttribs2dvNV);
+ SET_VertexAttribs3svNV(dest, loopback_VertexAttribs3svNV);
+ SET_VertexAttribs3fvNV(dest, loopback_VertexAttribs3fvNV);
+ SET_VertexAttribs3dvNV(dest, loopback_VertexAttribs3dvNV);
+ SET_VertexAttribs4svNV(dest, loopback_VertexAttribs4svNV);
+ SET_VertexAttribs4fvNV(dest, loopback_VertexAttribs4fvNV);
+ SET_VertexAttribs4dvNV(dest, loopback_VertexAttribs4dvNV);
+ SET_VertexAttribs4ubvNV(dest, loopback_VertexAttribs4ubvNV);
+
+ SET_VertexAttrib1sARB(dest, loopback_VertexAttrib1sARB);
+ SET_VertexAttrib1dARB(dest, loopback_VertexAttrib1dARB);
+ SET_VertexAttrib2sARB(dest, loopback_VertexAttrib2sARB);
+ SET_VertexAttrib2dARB(dest, loopback_VertexAttrib2dARB);
+ SET_VertexAttrib3sARB(dest, loopback_VertexAttrib3sARB);
+ SET_VertexAttrib3dARB(dest, loopback_VertexAttrib3dARB);
+ SET_VertexAttrib4sARB(dest, loopback_VertexAttrib4sARB);
+ SET_VertexAttrib4dARB(dest, loopback_VertexAttrib4dARB);
+ SET_VertexAttrib1svARB(dest, loopback_VertexAttrib1svARB);
+ SET_VertexAttrib1dvARB(dest, loopback_VertexAttrib1dvARB);
+ SET_VertexAttrib2svARB(dest, loopback_VertexAttrib2svARB);
+ SET_VertexAttrib2dvARB(dest, loopback_VertexAttrib2dvARB);
+ SET_VertexAttrib3svARB(dest, loopback_VertexAttrib3svARB);
+ SET_VertexAttrib3dvARB(dest, loopback_VertexAttrib3dvARB);
+ SET_VertexAttrib4svARB(dest, loopback_VertexAttrib4svARB);
+ SET_VertexAttrib4dvARB(dest, loopback_VertexAttrib4dvARB);
+ SET_VertexAttrib4NubARB(dest, loopback_VertexAttrib4NubARB);
+ SET_VertexAttrib4NubvARB(dest, loopback_VertexAttrib4NubvARB);
+ SET_VertexAttrib4bvARB(dest, loopback_VertexAttrib4bvARB);
+ SET_VertexAttrib4ivARB(dest, loopback_VertexAttrib4ivARB);
+ SET_VertexAttrib4ubvARB(dest, loopback_VertexAttrib4ubvARB);
+ SET_VertexAttrib4usvARB(dest, loopback_VertexAttrib4usvARB);
+ SET_VertexAttrib4uivARB(dest, loopback_VertexAttrib4uivARB);
+ SET_VertexAttrib4NbvARB(dest, loopback_VertexAttrib4NbvARB);
+ SET_VertexAttrib4NsvARB(dest, loopback_VertexAttrib4NsvARB);
+ SET_VertexAttrib4NivARB(dest, loopback_VertexAttrib4NivARB);
+ SET_VertexAttrib4NusvARB(dest, loopback_VertexAttrib4NusvARB);
+ SET_VertexAttrib4NuivARB(dest, loopback_VertexAttrib4NuivARB);
+}
diff --git a/src/mesa/main/api_loopback.h b/src/mesa/main/api_loopback.h
new file mode 100644
index 00000000000..6f85bbc1d92
--- /dev/null
+++ b/src/mesa/main/api_loopback.h
@@ -0,0 +1,37 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.5
+ *
+ * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+#ifndef API_LOOPBACK_H
+#define API_LOOPBACK_H
+
+#include "glheader.h"
+
+
+struct _glapi_table;
+
+extern void _mesa_loopback_init_api_table( struct _glapi_table *dest );
+
+#endif
diff --git a/src/mesa/main/api_noop.c b/src/mesa/main/api_noop.c
new file mode 100644
index 00000000000..af7e1f9ac70
--- /dev/null
+++ b/src/mesa/main/api_noop.c
@@ -0,0 +1,964 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include "glheader.h"
+#include "api_noop.h"
+#include "api_validate.h"
+#include "api_arrayelt.h"
+#include "context.h"
+#include "colormac.h"
+#include "light.h"
+#include "macros.h"
+#include "mtypes.h"
+#include "dlist.h"
+#include "dispatch.h"
+
+
+/* In states where certain vertex components are required for t&l or
+ * rasterization, we still need to keep track of the current values.
+ * These functions provide this service by keeping uptodate the
+ * 'ctx->Current' struct for all data elements not included in the
+ * currently enabled hardware vertex.
+ * I.e. these functions would typically be used when outside of glBegin/End.
+ */
+
+
+void GLAPIENTRY _mesa_noop_EdgeFlag( GLboolean b )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Current.EdgeFlag = b;
+}
+
+void GLAPIENTRY _mesa_noop_EdgeFlagv( const GLboolean *b )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Current.EdgeFlag = *b;
+}
+
+void GLAPIENTRY _mesa_noop_Indexf( GLfloat f )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Current.Index = f;
+}
+
+void GLAPIENTRY _mesa_noop_Indexfv( const GLfloat *v )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Current.Index = *v;
+}
+
+void GLAPIENTRY _mesa_noop_FogCoordfEXT( GLfloat a )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_FOG];
+ dest[0] = a;
+ dest[1] = 0.0;
+ dest[2] = 0.0;
+ dest[3] = 1.0;
+}
+
+void GLAPIENTRY _mesa_noop_FogCoordfvEXT( const GLfloat *v )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_FOG];
+ dest[0] = v[0];
+ dest[1] = 0.0;
+ dest[2] = 0.0;
+ dest[3] = 1.0;
+}
+
+void GLAPIENTRY _mesa_noop_Normal3f( GLfloat a, GLfloat b, GLfloat c )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_NORMAL];
+ dest[0] = a;
+ dest[1] = b;
+ dest[2] = c;
+ dest[3] = 1.0;
+}
+
+void GLAPIENTRY _mesa_noop_Normal3fv( const GLfloat *v )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_NORMAL];
+ dest[0] = v[0];
+ dest[1] = v[1];
+ dest[2] = v[2];
+ dest[3] = 1.0;
+}
+
+void GLAPIENTRY _mesa_noop_Color4f( GLfloat a, GLfloat b, GLfloat c, GLfloat d )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLfloat *color = ctx->Current.Attrib[VERT_ATTRIB_COLOR0];
+ color[0] = a;
+ color[1] = b;
+ color[2] = c;
+ color[3] = d;
+}
+
+void GLAPIENTRY _mesa_noop_Color4fv( const GLfloat *v )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLfloat *color = ctx->Current.Attrib[VERT_ATTRIB_COLOR0];
+ color[0] = v[0];
+ color[1] = v[1];
+ color[2] = v[2];
+ color[3] = v[3];
+}
+
+void GLAPIENTRY _mesa_noop_Color3f( GLfloat a, GLfloat b, GLfloat c )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLfloat *color = ctx->Current.Attrib[VERT_ATTRIB_COLOR0];
+ color[0] = a;
+ color[1] = b;
+ color[2] = c;
+ color[3] = 1.0;
+}
+
+void GLAPIENTRY _mesa_noop_Color3fv( const GLfloat *v )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLfloat *color = ctx->Current.Attrib[VERT_ATTRIB_COLOR0];
+ color[0] = v[0];
+ color[1] = v[1];
+ color[2] = v[2];
+ color[3] = 1.0;
+}
+
+void GLAPIENTRY _mesa_noop_MultiTexCoord1fARB( GLenum target, GLfloat a )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLuint unit = target - GL_TEXTURE0_ARB;
+
+ /* unit is unsigned -- cannot be less than zero.
+ */
+ if (unit < MAX_TEXTURE_COORD_UNITS)
+ {
+ GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit];
+ dest[0] = a;
+ dest[1] = 0;
+ dest[2] = 0;
+ dest[3] = 1;
+ }
+}
+
+void GLAPIENTRY _mesa_noop_MultiTexCoord1fvARB( GLenum target, const GLfloat *v )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLuint unit = target - GL_TEXTURE0_ARB;
+
+ /* unit is unsigned -- cannot be less than zero.
+ */
+ if (unit < MAX_TEXTURE_COORD_UNITS)
+ {
+ GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit];
+ dest[0] = v[0];
+ dest[1] = 0;
+ dest[2] = 0;
+ dest[3] = 1;
+ }
+}
+
+void GLAPIENTRY _mesa_noop_MultiTexCoord2fARB( GLenum target, GLfloat a, GLfloat b )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLuint unit = target - GL_TEXTURE0_ARB;
+
+ /* unit is unsigned -- cannot be less than zero.
+ */
+ if (unit < MAX_TEXTURE_COORD_UNITS)
+ {
+ GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit];
+ dest[0] = a;
+ dest[1] = b;
+ dest[2] = 0;
+ dest[3] = 1;
+ }
+}
+
+void GLAPIENTRY _mesa_noop_MultiTexCoord2fvARB( GLenum target, const GLfloat *v )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLuint unit = target - GL_TEXTURE0_ARB;
+
+ /* unit is unsigned -- cannot be less than zero.
+ */
+ if (unit < MAX_TEXTURE_COORD_UNITS)
+ {
+ GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit];
+ dest[0] = v[0];
+ dest[1] = v[1];
+ dest[2] = 0;
+ dest[3] = 1;
+ }
+}
+
+void GLAPIENTRY _mesa_noop_MultiTexCoord3fARB( GLenum target, GLfloat a, GLfloat b, GLfloat c)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLuint unit = target - GL_TEXTURE0_ARB;
+
+ /* unit is unsigned -- cannot be less than zero.
+ */
+ if (unit < MAX_TEXTURE_COORD_UNITS)
+ {
+ GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit];
+ dest[0] = a;
+ dest[1] = b;
+ dest[2] = c;
+ dest[3] = 1;
+ }
+}
+
+void GLAPIENTRY _mesa_noop_MultiTexCoord3fvARB( GLenum target, const GLfloat *v )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLuint unit = target - GL_TEXTURE0_ARB;
+
+ /* unit is unsigned -- cannot be less than zero.
+ */
+ if (unit < MAX_TEXTURE_COORD_UNITS)
+ {
+ GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit];
+ dest[0] = v[0];
+ dest[1] = v[1];
+ dest[2] = v[2];
+ dest[3] = 1;
+ }
+}
+
+void GLAPIENTRY _mesa_noop_MultiTexCoord4fARB( GLenum target, GLfloat a, GLfloat b,
+ GLfloat c, GLfloat d )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLuint unit = target - GL_TEXTURE0_ARB;
+
+ /* unit is unsigned -- cannot be less than zero.
+ */
+ if (unit < MAX_TEXTURE_COORD_UNITS)
+ {
+ GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit];
+ dest[0] = a;
+ dest[1] = b;
+ dest[2] = c;
+ dest[3] = d;
+ }
+}
+
+void GLAPIENTRY _mesa_noop_MultiTexCoord4fvARB( GLenum target, const GLfloat *v )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLuint unit = target - GL_TEXTURE0_ARB;
+
+ /* unit is unsigned -- cannot be less than zero.
+ */
+ if (unit < MAX_TEXTURE_COORD_UNITS)
+ {
+ GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit];
+ dest[0] = v[0];
+ dest[1] = v[1];
+ dest[2] = v[2];
+ dest[3] = v[3];
+ }
+}
+
+void GLAPIENTRY _mesa_noop_SecondaryColor3fEXT( GLfloat a, GLfloat b, GLfloat c )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLfloat *color = ctx->Current.Attrib[VERT_ATTRIB_COLOR1];
+ color[0] = a;
+ color[1] = b;
+ color[2] = c;
+ color[3] = 1.0;
+}
+
+void GLAPIENTRY _mesa_noop_SecondaryColor3fvEXT( const GLfloat *v )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLfloat *color = ctx->Current.Attrib[VERT_ATTRIB_COLOR1];
+ color[0] = v[0];
+ color[1] = v[1];
+ color[2] = v[2];
+ color[3] = 1.0;
+}
+
+void GLAPIENTRY _mesa_noop_TexCoord1f( GLfloat a )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0];
+ dest[0] = a;
+ dest[1] = 0;
+ dest[2] = 0;
+ dest[3] = 1;
+}
+
+void GLAPIENTRY _mesa_noop_TexCoord1fv( const GLfloat *v )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0];
+ dest[0] = v[0];
+ dest[1] = 0;
+ dest[2] = 0;
+ dest[3] = 1;
+}
+
+void GLAPIENTRY _mesa_noop_TexCoord2f( GLfloat a, GLfloat b )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0];
+ dest[0] = a;
+ dest[1] = b;
+ dest[2] = 0;
+ dest[3] = 1;
+}
+
+void GLAPIENTRY _mesa_noop_TexCoord2fv( const GLfloat *v )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0];
+ dest[0] = v[0];
+ dest[1] = v[1];
+ dest[2] = 0;
+ dest[3] = 1;
+}
+
+void GLAPIENTRY _mesa_noop_TexCoord3f( GLfloat a, GLfloat b, GLfloat c )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0];
+ dest[0] = a;
+ dest[1] = b;
+ dest[2] = c;
+ dest[3] = 1;
+}
+
+void GLAPIENTRY _mesa_noop_TexCoord3fv( const GLfloat *v )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0];
+ dest[0] = v[0];
+ dest[1] = v[1];
+ dest[2] = v[2];
+ dest[3] = 1;
+}
+
+void GLAPIENTRY _mesa_noop_TexCoord4f( GLfloat a, GLfloat b, GLfloat c, GLfloat d )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0];
+ dest[0] = a;
+ dest[1] = b;
+ dest[2] = c;
+ dest[3] = d;
+}
+
+void GLAPIENTRY _mesa_noop_TexCoord4fv( const GLfloat *v )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0];
+ dest[0] = v[0];
+ dest[1] = v[1];
+ dest[2] = v[2];
+ dest[3] = v[3];
+}
+
+
+
+void GLAPIENTRY _mesa_noop_VertexAttrib1fNV( GLuint index, GLfloat x )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ if (index < VERT_ATTRIB_MAX) {
+ ASSIGN_4V(ctx->Current.Attrib[index], x, 0, 0, 1);
+ }
+ else
+ _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttrib1fNV" );
+}
+
+void GLAPIENTRY _mesa_noop_VertexAttrib1fvNV( GLuint index, const GLfloat *v )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ if (index < VERT_ATTRIB_MAX) {
+ ASSIGN_4V(ctx->Current.Attrib[index], v[0], 0, 0, 1);
+ }
+ else
+ _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttrib1fvNV" );
+}
+
+void GLAPIENTRY _mesa_noop_VertexAttrib2fNV( GLuint index, GLfloat x, GLfloat y )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ if (index < VERT_ATTRIB_MAX) {
+ ASSIGN_4V(ctx->Current.Attrib[index], x, y, 0, 1);
+ }
+ else
+ _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttrib2fNV" );
+}
+
+void GLAPIENTRY _mesa_noop_VertexAttrib2fvNV( GLuint index, const GLfloat *v )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ if (index < VERT_ATTRIB_MAX) {
+ ASSIGN_4V(ctx->Current.Attrib[index], v[0], v[1], 0, 1);
+ }
+ else
+ _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttrib2fvNV" );
+}
+
+void GLAPIENTRY _mesa_noop_VertexAttrib3fNV( GLuint index, GLfloat x,
+ GLfloat y, GLfloat z )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ if (index < VERT_ATTRIB_MAX) {
+ ASSIGN_4V(ctx->Current.Attrib[index], x, y, z, 1);
+ }
+ else
+ _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttrib3fNV" );
+}
+
+void GLAPIENTRY _mesa_noop_VertexAttrib3fvNV( GLuint index, const GLfloat *v )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ if (index < VERT_ATTRIB_MAX) {
+ ASSIGN_4V(ctx->Current.Attrib[index], v[0], v[1], v[2], 1);
+ }
+ else
+ _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttrib3fvNV" );
+}
+
+void GLAPIENTRY _mesa_noop_VertexAttrib4fNV( GLuint index, GLfloat x,
+ GLfloat y, GLfloat z, GLfloat w )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ if (index < VERT_ATTRIB_MAX) {
+ ASSIGN_4V(ctx->Current.Attrib[index], x, y, z, w);
+ }
+ else
+ _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttrib4fNV" );
+}
+
+void GLAPIENTRY _mesa_noop_VertexAttrib4fvNV( GLuint index, const GLfloat *v )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ if (index < VERT_ATTRIB_MAX) {
+ ASSIGN_4V(ctx->Current.Attrib[index], v[0], v[1], v[2], v[3]);
+ }
+ else
+ _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttrib4fvNV" );
+}
+
+
+/*
+ * XXX Un-alias attribs here
+ */
+
+void GLAPIENTRY _mesa_noop_VertexAttrib1fARB( GLuint index, GLfloat x )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ if (index < VERT_ATTRIB_MAX) {
+ ASSIGN_4V(ctx->Current.Attrib[index], x, 0, 0, 1);
+ }
+ else
+ _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttrib1fARB" );
+}
+
+void GLAPIENTRY _mesa_noop_VertexAttrib1fvARB( GLuint index, const GLfloat *v )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ if (index < VERT_ATTRIB_MAX) {
+ ASSIGN_4V(ctx->Current.Attrib[index], v[0], 0, 0, 1);
+ }
+ else
+ _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttrib1fvARB" );
+}
+
+void GLAPIENTRY _mesa_noop_VertexAttrib2fARB( GLuint index, GLfloat x, GLfloat y )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ if (index < VERT_ATTRIB_MAX) {
+ ASSIGN_4V(ctx->Current.Attrib[index], x, y, 0, 1);
+ }
+ else
+ _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttrib2fARB" );
+}
+
+void GLAPIENTRY _mesa_noop_VertexAttrib2fvARB( GLuint index, const GLfloat *v )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ if (index < VERT_ATTRIB_MAX) {
+ ASSIGN_4V(ctx->Current.Attrib[index], v[0], v[1], 0, 1);
+ }
+ else
+ _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttrib2fvARB" );
+}
+
+void GLAPIENTRY _mesa_noop_VertexAttrib3fARB( GLuint index, GLfloat x,
+ GLfloat y, GLfloat z )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ if (index < VERT_ATTRIB_MAX) {
+ ASSIGN_4V(ctx->Current.Attrib[index], x, y, z, 1);
+ }
+ else
+ _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttrib3fARB" );
+}
+
+void GLAPIENTRY _mesa_noop_VertexAttrib3fvARB( GLuint index, const GLfloat *v )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ if (index < VERT_ATTRIB_MAX) {
+ ASSIGN_4V(ctx->Current.Attrib[index], v[0], v[1], v[2], 1);
+ }
+ else
+ _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttrib3fvARB" );
+}
+
+void GLAPIENTRY _mesa_noop_VertexAttrib4fARB( GLuint index, GLfloat x,
+ GLfloat y, GLfloat z, GLfloat w )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ if (index < VERT_ATTRIB_MAX) {
+ ASSIGN_4V(ctx->Current.Attrib[index], x, y, z, w);
+ }
+ else
+ _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttrib4fARB" );
+}
+
+void GLAPIENTRY _mesa_noop_VertexAttrib4fvARB( GLuint index, const GLfloat *v )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ if (index < VERT_ATTRIB_MAX) {
+ ASSIGN_4V(ctx->Current.Attrib[index], v[0], v[1], v[2], v[3]);
+ }
+ else
+ _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttrib4fvARB" );
+}
+
+
+
+/* Material
+ */
+void GLAPIENTRY _mesa_noop_Materialfv( GLenum face, GLenum pname, const GLfloat *params )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint i, nr;
+ struct gl_material *mat = &ctx->Light.Material;
+ GLuint bitmask = _mesa_material_bitmask( ctx, face, pname, ~0,
+ "_mesa_noop_Materialfv" );
+
+ if (ctx->Light.ColorMaterialEnabled)
+ bitmask &= ~ctx->Light.ColorMaterialBitmask;
+
+ if (bitmask == 0)
+ return;
+
+ switch (pname) {
+ case GL_SHININESS: nr = 1; break;
+ case GL_COLOR_INDEXES: nr = 3; break;
+ default: nr = 4 ; break;
+ }
+
+ for (i = 0 ; i < MAT_ATTRIB_MAX ; i++)
+ if (bitmask & (1<<i))
+ COPY_SZ_4V( mat->Attrib[i], nr, params );
+
+ _mesa_update_material( ctx, bitmask );
+}
+
+/* These really are noops outside begin/end:
+ */
+void GLAPIENTRY _mesa_noop_Vertex2fv( const GLfloat *v )
+{
+ (void) v;
+}
+
+void GLAPIENTRY _mesa_noop_Vertex3fv( const GLfloat *v )
+{
+ (void) v;
+}
+
+void GLAPIENTRY _mesa_noop_Vertex4fv( const GLfloat *v )
+{
+ (void) v;
+}
+
+void GLAPIENTRY _mesa_noop_Vertex2f( GLfloat a, GLfloat b )
+{
+ (void) a; (void) b;
+}
+
+void GLAPIENTRY _mesa_noop_Vertex3f( GLfloat a, GLfloat b, GLfloat c )
+{
+ (void) a; (void) b; (void) c;
+}
+
+void GLAPIENTRY _mesa_noop_Vertex4f( GLfloat a, GLfloat b, GLfloat c, GLfloat d )
+{
+ (void) a; (void) b; (void) c; (void) d;
+}
+
+/* Similarly, these have no effect outside begin/end:
+ */
+void GLAPIENTRY _mesa_noop_EvalCoord1f( GLfloat a )
+{
+ (void) a;
+}
+
+void GLAPIENTRY _mesa_noop_EvalCoord1fv( const GLfloat *v )
+{
+ (void) v;
+}
+
+void GLAPIENTRY _mesa_noop_EvalCoord2f( GLfloat a, GLfloat b )
+{
+ (void) a; (void) b;
+}
+
+void GLAPIENTRY _mesa_noop_EvalCoord2fv( const GLfloat *v )
+{
+ (void) v;
+}
+
+void GLAPIENTRY _mesa_noop_EvalPoint1( GLint a )
+{
+ (void) a;
+}
+
+void GLAPIENTRY _mesa_noop_EvalPoint2( GLint a, GLint b )
+{
+ (void) a; (void) b;
+}
+
+
+/* Begin -- call into driver, should result in the vtxfmt being
+ * swapped out:
+ */
+void GLAPIENTRY _mesa_noop_Begin( GLenum mode )
+{
+ (void) mode;
+}
+
+
+/* End -- just raise an error
+ */
+void GLAPIENTRY _mesa_noop_End( void )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ _mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" );
+}
+
+
+/* Execute a glRectf() function. This is not suitable for GL_COMPILE
+ * modes (as the test for outside begin/end is not compiled),
+ * but may be useful for drivers in circumstances which exclude
+ * display list interactions.
+ *
+ * (None of the functions in this file are suitable for GL_COMPILE
+ * modes).
+ */
+void GLAPIENTRY _mesa_noop_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 )
+{
+ {
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+ }
+
+ CALL_Begin(GET_DISPATCH(), (GL_QUADS));
+ CALL_Vertex2f(GET_DISPATCH(), (x1, y1));
+ CALL_Vertex2f(GET_DISPATCH(), (x2, y1));
+ CALL_Vertex2f(GET_DISPATCH(), (x2, y2));
+ CALL_Vertex2f(GET_DISPATCH(), (x1, y2));
+ CALL_End(GET_DISPATCH(), ());
+}
+
+
+/* Some very basic support for arrays. Drivers without explicit array
+ * support can hook these in, but still need to supply an array-elt
+ * implementation.
+ */
+void GLAPIENTRY _mesa_noop_DrawArrays(GLenum mode, GLint start, GLsizei count)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint i;
+
+ if (!_mesa_validate_DrawArrays( ctx, mode, start, count ))
+ return;
+
+ CALL_Begin(GET_DISPATCH(), (mode));
+ for (i = 0; i < count; i++)
+ CALL_ArrayElement(GET_DISPATCH(), (start + i));
+ CALL_End(GET_DISPATCH(), ());
+}
+
+
+void GLAPIENTRY _mesa_noop_DrawElements(GLenum mode, GLsizei count, GLenum type,
+ const GLvoid *indices)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint i;
+
+ if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices ))
+ return;
+
+ CALL_Begin(GET_DISPATCH(), (mode));
+
+ switch (type) {
+ case GL_UNSIGNED_BYTE:
+ for (i = 0 ; i < count ; i++)
+ CALL_ArrayElement(GET_DISPATCH(), ( ((GLubyte *)indices)[i] ));
+ break;
+ case GL_UNSIGNED_SHORT:
+ for (i = 0 ; i < count ; i++)
+ CALL_ArrayElement(GET_DISPATCH(), ( ((GLushort *)indices)[i] ));
+ break;
+ case GL_UNSIGNED_INT:
+ for (i = 0 ; i < count ; i++)
+ CALL_ArrayElement(GET_DISPATCH(), ( ((GLuint *)indices)[i] ));
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" );
+ break;
+ }
+
+ CALL_End(GET_DISPATCH(), ());
+}
+
+void GLAPIENTRY _mesa_noop_DrawRangeElements(GLenum mode,
+ GLuint start, GLuint end,
+ GLsizei count, GLenum type,
+ const GLvoid *indices)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (_mesa_validate_DrawRangeElements( ctx, mode,
+ start, end,
+ count, type, indices ))
+ CALL_DrawElements(GET_DISPATCH(), (mode, count, type, indices));
+}
+
+/*
+ * Eval Mesh
+ */
+
+/* KW: If are compiling, we don't know whether eval will produce a
+ * vertex when it is run in the future. If this is pure immediate
+ * mode, eval is a noop if neither vertex map is enabled.
+ *
+ * Thus we need to have a check in the display list code or
+ * elsewhere for eval(1,2) vertices in the case where
+ * map(1,2)_vertex is disabled, and to purge those vertices from
+ * the vb.
+ */
+void GLAPIENTRY _mesa_noop_EvalMesh1( GLenum mode, GLint i1, GLint i2 )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint i;
+ GLfloat u, du;
+ GLenum prim;
+
+ switch (mode) {
+ case GL_POINT:
+ prim = GL_POINTS;
+ break;
+ case GL_LINE:
+ prim = GL_LINE_STRIP;
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glEvalMesh1(mode)" );
+ return;
+ }
+
+ /* No effect if vertex maps disabled.
+ */
+ if (!ctx->Eval.Map1Vertex4 &&
+ !ctx->Eval.Map1Vertex3 &&
+ !(ctx->VertexProgram._Enabled && ctx->Eval.Map1Attrib[VERT_ATTRIB_POS]))
+ return;
+
+ du = ctx->Eval.MapGrid1du;
+ u = ctx->Eval.MapGrid1u1 + i1 * du;
+
+ CALL_Begin(GET_DISPATCH(), (prim));
+ for (i=i1;i<=i2;i++,u+=du) {
+ CALL_EvalCoord1f(GET_DISPATCH(), (u));
+ }
+ CALL_End(GET_DISPATCH(), ());
+}
+
+
+
+void GLAPIENTRY _mesa_noop_EvalMesh2( GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLfloat u, du, v, dv, v1, u1;
+ GLint i, j;
+
+ switch (mode) {
+ case GL_POINT:
+ case GL_LINE:
+ case GL_FILL:
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glEvalMesh2(mode)" );
+ return;
+ }
+
+ /* No effect if vertex maps disabled.
+ */
+ if (!ctx->Eval.Map2Vertex4 &&
+ !ctx->Eval.Map2Vertex3 &&
+ !(ctx->VertexProgram._Enabled && ctx->Eval.Map2Attrib[VERT_ATTRIB_POS]))
+ return;
+
+ du = ctx->Eval.MapGrid2du;
+ dv = ctx->Eval.MapGrid2dv;
+ v1 = ctx->Eval.MapGrid2v1 + j1 * dv;
+ u1 = ctx->Eval.MapGrid2u1 + i1 * du;
+
+ switch (mode) {
+ case GL_POINT:
+ CALL_Begin(GET_DISPATCH(), (GL_POINTS));
+ for (v=v1,j=j1;j<=j2;j++,v+=dv) {
+ for (u=u1,i=i1;i<=i2;i++,u+=du) {
+ CALL_EvalCoord2f(GET_DISPATCH(), (u, v));
+ }
+ }
+ CALL_End(GET_DISPATCH(), ());
+ break;
+ case GL_LINE:
+ for (v=v1,j=j1;j<=j2;j++,v+=dv) {
+ CALL_Begin(GET_DISPATCH(), (GL_LINE_STRIP));
+ for (u=u1,i=i1;i<=i2;i++,u+=du) {
+ CALL_EvalCoord2f(GET_DISPATCH(), (u, v));
+ }
+ CALL_End(GET_DISPATCH(), ());
+ }
+ for (u=u1,i=i1;i<=i2;i++,u+=du) {
+ CALL_Begin(GET_DISPATCH(), (GL_LINE_STRIP));
+ for (v=v1,j=j1;j<=j2;j++,v+=dv) {
+ CALL_EvalCoord2f(GET_DISPATCH(), (u, v));
+ }
+ CALL_End(GET_DISPATCH(), ());
+ }
+ break;
+ case GL_FILL:
+ for (v=v1,j=j1;j<j2;j++,v+=dv) {
+ CALL_Begin(GET_DISPATCH(), (GL_TRIANGLE_STRIP));
+ for (u=u1,i=i1;i<=i2;i++,u+=du) {
+ CALL_EvalCoord2f(GET_DISPATCH(), (u, v));
+ CALL_EvalCoord2f(GET_DISPATCH(), (u, v+dv));
+ }
+ CALL_End(GET_DISPATCH(), ());
+ }
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glEvalMesh2(mode)" );
+ return;
+ }
+}
+
+
+
+/* Build a vertexformat full of things to use outside begin/end pairs.
+ *
+ * TODO -- build a whole dispatch table for this purpose, and likewise
+ * for inside begin/end.
+ */
+void _mesa_noop_vtxfmt_init( GLvertexformat *vfmt )
+{
+ vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */
+ vfmt->Begin = _mesa_noop_Begin;
+ vfmt->CallList = _mesa_CallList;
+ vfmt->CallLists = _mesa_CallLists;
+ vfmt->Color3f = _mesa_noop_Color3f;
+ vfmt->Color3fv = _mesa_noop_Color3fv;
+ vfmt->Color4f = _mesa_noop_Color4f;
+ vfmt->Color4fv = _mesa_noop_Color4fv;
+ vfmt->EdgeFlag = _mesa_noop_EdgeFlag;
+ vfmt->EdgeFlagv = _mesa_noop_EdgeFlagv;
+ vfmt->End = _mesa_noop_End;
+ vfmt->EvalCoord1f = _mesa_noop_EvalCoord1f;
+ vfmt->EvalCoord1fv = _mesa_noop_EvalCoord1fv;
+ vfmt->EvalCoord2f = _mesa_noop_EvalCoord2f;
+ vfmt->EvalCoord2fv = _mesa_noop_EvalCoord2fv;
+ vfmt->EvalPoint1 = _mesa_noop_EvalPoint1;
+ vfmt->EvalPoint2 = _mesa_noop_EvalPoint2;
+ vfmt->FogCoordfEXT = _mesa_noop_FogCoordfEXT;
+ vfmt->FogCoordfvEXT = _mesa_noop_FogCoordfvEXT;
+ vfmt->Indexf = _mesa_noop_Indexf;
+ vfmt->Indexfv = _mesa_noop_Indexfv;
+ vfmt->Materialfv = _mesa_noop_Materialfv;
+ vfmt->MultiTexCoord1fARB = _mesa_noop_MultiTexCoord1fARB;
+ vfmt->MultiTexCoord1fvARB = _mesa_noop_MultiTexCoord1fvARB;
+ vfmt->MultiTexCoord2fARB = _mesa_noop_MultiTexCoord2fARB;
+ vfmt->MultiTexCoord2fvARB = _mesa_noop_MultiTexCoord2fvARB;
+ vfmt->MultiTexCoord3fARB = _mesa_noop_MultiTexCoord3fARB;
+ vfmt->MultiTexCoord3fvARB = _mesa_noop_MultiTexCoord3fvARB;
+ vfmt->MultiTexCoord4fARB = _mesa_noop_MultiTexCoord4fARB;
+ vfmt->MultiTexCoord4fvARB = _mesa_noop_MultiTexCoord4fvARB;
+ vfmt->Normal3f = _mesa_noop_Normal3f;
+ vfmt->Normal3fv = _mesa_noop_Normal3fv;
+ vfmt->SecondaryColor3fEXT = _mesa_noop_SecondaryColor3fEXT;
+ vfmt->SecondaryColor3fvEXT = _mesa_noop_SecondaryColor3fvEXT;
+ vfmt->TexCoord1f = _mesa_noop_TexCoord1f;
+ vfmt->TexCoord1fv = _mesa_noop_TexCoord1fv;
+ vfmt->TexCoord2f = _mesa_noop_TexCoord2f;
+ vfmt->TexCoord2fv = _mesa_noop_TexCoord2fv;
+ vfmt->TexCoord3f = _mesa_noop_TexCoord3f;
+ vfmt->TexCoord3fv = _mesa_noop_TexCoord3fv;
+ vfmt->TexCoord4f = _mesa_noop_TexCoord4f;
+ vfmt->TexCoord4fv = _mesa_noop_TexCoord4fv;
+ vfmt->Vertex2f = _mesa_noop_Vertex2f;
+ vfmt->Vertex2fv = _mesa_noop_Vertex2fv;
+ vfmt->Vertex3f = _mesa_noop_Vertex3f;
+ vfmt->Vertex3fv = _mesa_noop_Vertex3fv;
+ vfmt->Vertex4f = _mesa_noop_Vertex4f;
+ vfmt->Vertex4fv = _mesa_noop_Vertex4fv;
+ vfmt->VertexAttrib1fNV = _mesa_noop_VertexAttrib1fNV;
+ vfmt->VertexAttrib1fvNV = _mesa_noop_VertexAttrib1fvNV;
+ vfmt->VertexAttrib2fNV = _mesa_noop_VertexAttrib2fNV;
+ vfmt->VertexAttrib2fvNV = _mesa_noop_VertexAttrib2fvNV;
+ vfmt->VertexAttrib3fNV = _mesa_noop_VertexAttrib3fNV;
+ vfmt->VertexAttrib3fvNV = _mesa_noop_VertexAttrib3fvNV;
+ vfmt->VertexAttrib4fNV = _mesa_noop_VertexAttrib4fNV;
+ vfmt->VertexAttrib4fvNV = _mesa_noop_VertexAttrib4fvNV;
+ vfmt->VertexAttrib1fARB = _mesa_noop_VertexAttrib1fARB;
+ vfmt->VertexAttrib1fvARB = _mesa_noop_VertexAttrib1fvARB;
+ vfmt->VertexAttrib2fARB = _mesa_noop_VertexAttrib2fARB;
+ vfmt->VertexAttrib2fvARB = _mesa_noop_VertexAttrib2fvARB;
+ vfmt->VertexAttrib3fARB = _mesa_noop_VertexAttrib3fARB;
+ vfmt->VertexAttrib3fvARB = _mesa_noop_VertexAttrib3fvARB;
+ vfmt->VertexAttrib4fARB = _mesa_noop_VertexAttrib4fARB;
+ vfmt->VertexAttrib4fvARB = _mesa_noop_VertexAttrib4fvARB;
+
+ vfmt->Rectf = _mesa_noop_Rectf;
+
+ vfmt->DrawArrays = _mesa_noop_DrawArrays;
+ vfmt->DrawElements = _mesa_noop_DrawElements;
+ vfmt->DrawRangeElements = _mesa_noop_DrawRangeElements;
+ vfmt->EvalMesh1 = _mesa_noop_EvalMesh1;
+ vfmt->EvalMesh2 = _mesa_noop_EvalMesh2;
+}
diff --git a/src/mesa/main/api_noop.h b/src/mesa/main/api_noop.h
new file mode 100644
index 00000000000..56d930e3b04
--- /dev/null
+++ b/src/mesa/main/api_noop.h
@@ -0,0 +1,147 @@
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 4.1
+ *
+ * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _API_NOOP_H
+#define _API_NOOP_H
+
+
+#include "glheader.h"
+#include "mtypes.h"
+#include "context.h"
+
+/* In states where certain vertex components are required for t&l or
+ * rasterization, we still need to keep track of the current values.
+ * These functions provide this service by keeping uptodate the
+ * 'ctx->Current' struct for all data elements not included in the
+ * currently enabled hardware vertex.
+ *
+ */
+extern void GLAPIENTRY _mesa_noop_EdgeFlag( GLboolean b );
+extern void GLAPIENTRY _mesa_noop_EdgeFlagv( const GLboolean *b );
+
+extern void GLAPIENTRY _mesa_noop_FogCoordfEXT( GLfloat a );
+extern void GLAPIENTRY _mesa_noop_FogCoordfvEXT( const GLfloat *v );
+
+extern void GLAPIENTRY _mesa_noop_Indexf( GLfloat i );
+extern void GLAPIENTRY _mesa_noop_Indexfv( const GLfloat *v );
+
+extern void GLAPIENTRY _mesa_noop_Normal3f( GLfloat a, GLfloat b, GLfloat c );
+extern void GLAPIENTRY _mesa_noop_Normal3fv( const GLfloat *v );
+
+extern void GLAPIENTRY _mesa_noop_Materialfv( GLenum face, GLenum pname, const GLfloat *param );
+
+extern void _mesa_noop_Color4ub( GLubyte a, GLubyte b, GLubyte c, GLubyte d );
+extern void _mesa_noop_Color4ubv( const GLubyte *v );
+extern void GLAPIENTRY _mesa_noop_Color4f( GLfloat a, GLfloat b, GLfloat c, GLfloat d );
+extern void GLAPIENTRY _mesa_noop_Color4fv( const GLfloat *v );
+extern void _mesa_noop_Color3ub( GLubyte a, GLubyte b, GLubyte c );
+extern void _mesa_noop_Color3ubv( const GLubyte *v );
+extern void GLAPIENTRY _mesa_noop_Color3f( GLfloat a, GLfloat b, GLfloat c );
+extern void GLAPIENTRY _mesa_noop_Color3fv( const GLfloat *v );
+
+extern void GLAPIENTRY _mesa_noop_MultiTexCoord1fARB( GLenum target, GLfloat a );
+extern void GLAPIENTRY _mesa_noop_MultiTexCoord1fvARB( GLenum target, const GLfloat *v );
+extern void GLAPIENTRY _mesa_noop_MultiTexCoord2fARB( GLenum target, GLfloat a, GLfloat b );
+extern void GLAPIENTRY _mesa_noop_MultiTexCoord2fvARB( GLenum target, const GLfloat *v );
+extern void GLAPIENTRY _mesa_noop_MultiTexCoord3fARB( GLenum target, GLfloat a, GLfloat b, GLfloat c);
+extern void GLAPIENTRY _mesa_noop_MultiTexCoord3fvARB( GLenum target, const GLfloat *v );
+extern void GLAPIENTRY _mesa_noop_MultiTexCoord4fARB( GLenum target, GLfloat a, GLfloat b, GLfloat c, GLfloat d );
+extern void GLAPIENTRY _mesa_noop_MultiTexCoord4fvARB( GLenum target, const GLfloat *v );
+
+extern void GLAPIENTRY _mesa_noop_SecondaryColor3ubEXT( GLubyte a, GLubyte b, GLubyte c );
+extern void GLAPIENTRY _mesa_noop_SecondaryColor3ubvEXT( const GLubyte *v );
+extern void GLAPIENTRY _mesa_noop_SecondaryColor3fEXT( GLfloat a, GLfloat b, GLfloat c );
+extern void GLAPIENTRY _mesa_noop_SecondaryColor3fvEXT( const GLfloat *v );
+
+extern void GLAPIENTRY _mesa_noop_TexCoord1f( GLfloat a );
+extern void GLAPIENTRY _mesa_noop_TexCoord1fv( const GLfloat *v );
+extern void GLAPIENTRY _mesa_noop_TexCoord2f( GLfloat a, GLfloat b );
+extern void GLAPIENTRY _mesa_noop_TexCoord2fv( const GLfloat *v );
+extern void GLAPIENTRY _mesa_noop_TexCoord3f( GLfloat a, GLfloat b, GLfloat c );
+extern void GLAPIENTRY _mesa_noop_TexCoord3fv( const GLfloat *v );
+extern void GLAPIENTRY _mesa_noop_TexCoord4f( GLfloat a, GLfloat b, GLfloat c, GLfloat d );
+extern void GLAPIENTRY _mesa_noop_TexCoord4fv( const GLfloat *v );
+
+extern void GLAPIENTRY _mesa_noop_Vertex2f( GLfloat a, GLfloat b );
+extern void GLAPIENTRY _mesa_noop_Vertex2fv( const GLfloat *v );
+extern void GLAPIENTRY _mesa_noop_Vertex3f( GLfloat a, GLfloat b, GLfloat c );
+extern void GLAPIENTRY _mesa_noop_Vertex3fv( const GLfloat *v );
+extern void GLAPIENTRY _mesa_noop_Vertex4f( GLfloat a, GLfloat b, GLfloat c, GLfloat d );
+extern void GLAPIENTRY _mesa_noop_Vertex4fv( const GLfloat *v );
+
+extern void GLAPIENTRY _mesa_noop_VertexAttrib1fNV( GLuint index, GLfloat x );
+extern void GLAPIENTRY _mesa_noop_VertexAttrib1fvNV( GLuint index, const GLfloat *v );
+extern void GLAPIENTRY _mesa_noop_VertexAttrib2fNV( GLuint index, GLfloat x, GLfloat y );
+extern void GLAPIENTRY _mesa_noop_VertexAttrib2fvNV( GLuint index, const GLfloat *v );
+extern void GLAPIENTRY _mesa_noop_VertexAttrib3fNV( GLuint index, GLfloat x, GLfloat y, GLfloat z );
+extern void GLAPIENTRY _mesa_noop_VertexAttrib3fvNV( GLuint index, const GLfloat *v );
+extern void GLAPIENTRY _mesa_noop_VertexAttrib4fNV( GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w );
+
+extern void GLAPIENTRY _mesa_noop_VertexAttrib4fvNV( GLuint index, const GLfloat *v );
+extern void GLAPIENTRY _mesa_noop_VertexAttrib1fARB( GLuint index, GLfloat x );
+extern void GLAPIENTRY _mesa_noop_VertexAttrib1fvARB( GLuint index, const GLfloat *v );
+extern void GLAPIENTRY _mesa_noop_VertexAttrib2fARB( GLuint index, GLfloat x, GLfloat y );
+extern void GLAPIENTRY _mesa_noop_VertexAttrib2fvARB( GLuint index, const GLfloat *v );
+extern void GLAPIENTRY _mesa_noop_VertexAttrib3fARB( GLuint index, GLfloat x, GLfloat y, GLfloat z );
+extern void GLAPIENTRY _mesa_noop_VertexAttrib3fvARB( GLuint index, const GLfloat *v );
+extern void GLAPIENTRY _mesa_noop_VertexAttrib4fARB( GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w );
+extern void GLAPIENTRY _mesa_noop_VertexAttrib4fvARB( GLuint index, const GLfloat *v );
+
+
+extern void GLAPIENTRY _mesa_noop_End( void );
+extern void GLAPIENTRY _mesa_noop_Begin( GLenum mode );
+extern void GLAPIENTRY _mesa_noop_EvalPoint2( GLint a, GLint b );
+extern void GLAPIENTRY _mesa_noop_EvalPoint1( GLint a );
+extern void GLAPIENTRY _mesa_noop_EvalCoord2fv( const GLfloat *v );
+extern void GLAPIENTRY _mesa_noop_EvalCoord2f( GLfloat a, GLfloat b );
+extern void GLAPIENTRY _mesa_noop_EvalCoord1fv( const GLfloat *v );
+extern void GLAPIENTRY _mesa_noop_EvalCoord1f( GLfloat a );
+
+extern void _mesa_noop_vtxfmt_init( GLvertexformat *vfmt );
+
+extern void GLAPIENTRY _mesa_noop_EvalMesh2( GLenum mode, GLint i1, GLint i2,
+ GLint j1, GLint j2 );
+
+extern void GLAPIENTRY _mesa_noop_EvalMesh1( GLenum mode, GLint i1, GLint i2 );
+
+
+/* Not strictly a noop -- translate Rectf down to Begin/End and
+ * vertices. Closer to the loopback operations, but doesn't meet the
+ * criteria for inclusion there (cannot be used in the Save table).
+ */
+extern void GLAPIENTRY _mesa_noop_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 );
+
+
+extern void GLAPIENTRY _mesa_noop_DrawArrays(GLenum mode, GLint start, GLsizei count);
+extern void GLAPIENTRY _mesa_noop_DrawElements(GLenum mode, GLsizei count, GLenum type,
+ const GLvoid *indices);
+extern void GLAPIENTRY _mesa_noop_DrawRangeElements(GLenum mode,
+ GLuint start, GLuint end,
+ GLsizei count, GLenum type,
+ const GLvoid *indices);
+
+
+
+#endif
diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c
new file mode 100644
index 00000000000..d1c8f42e747
--- /dev/null
+++ b/src/mesa/main/api_validate.c
@@ -0,0 +1,238 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.1
+ *
+ * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "glheader.h"
+#include "api_validate.h"
+#include "context.h"
+#include "imports.h"
+#include "mtypes.h"
+#include "state.h"
+
+
+GLboolean
+_mesa_validate_DrawElements(GLcontext *ctx,
+ GLenum mode, GLsizei count, GLenum type,
+ const GLvoid *indices)
+{
+ ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
+
+ if (count <= 0) {
+ if (count < 0)
+ _mesa_error(ctx, GL_INVALID_VALUE, "glDrawElements(count)" );
+ return GL_FALSE;
+ }
+
+ if (mode > GL_POLYGON) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glDrawElements(mode)" );
+ return GL_FALSE;
+ }
+
+ if (type != GL_UNSIGNED_INT &&
+ type != GL_UNSIGNED_BYTE &&
+ type != GL_UNSIGNED_SHORT)
+ {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glDrawElements(type)" );
+ return GL_FALSE;
+ }
+
+ if (ctx->NewState)
+ _mesa_update_state(ctx);
+
+ /* Always need vertex positions */
+ if (!ctx->Array.Vertex.Enabled
+ && !(ctx->VertexProgram._Enabled && ctx->Array.VertexAttrib[0].Enabled))
+ return GL_FALSE;
+
+ /* Vertex buffer object tests */
+ if (ctx->Array.ElementArrayBufferObj->Name) {
+ GLuint indexBytes;
+
+ /* use indices in the buffer object */
+ if (!ctx->Array.ElementArrayBufferObj->Data) {
+ _mesa_warning(ctx, "DrawElements with empty vertex elements buffer!");
+ return GL_FALSE;
+ }
+
+ /* make sure count doesn't go outside buffer bounds */
+ if (type == GL_UNSIGNED_INT) {
+ indexBytes = count * sizeof(GLuint);
+ }
+ else if (type == GL_UNSIGNED_BYTE) {
+ indexBytes = count * sizeof(GLubyte);
+ }
+ else {
+ ASSERT(type == GL_UNSIGNED_SHORT);
+ indexBytes = count * sizeof(GLushort);
+ }
+
+ if ((GLubyte *) indices + indexBytes >
+ ctx->Array.ElementArrayBufferObj->Data +
+ ctx->Array.ElementArrayBufferObj->Size) {
+ _mesa_warning(ctx, "glDrawElements index out of buffer bounds");
+ return GL_FALSE;
+ }
+
+ /* Actual address is the sum of pointers. Indices may be used below. */
+ if (ctx->Const.CheckArrayBounds) {
+ indices = (const GLvoid *)
+ ADD_POINTERS(ctx->Array.ElementArrayBufferObj->Data,
+ (const GLubyte *) indices);
+ }
+ }
+
+ if (ctx->Const.CheckArrayBounds) {
+ /* find max array index */
+ GLuint max = 0;
+ GLint i;
+ if (type == GL_UNSIGNED_INT) {
+ for (i = 0; i < count; i++)
+ if (((GLuint *) indices)[i] > max)
+ max = ((GLuint *) indices)[i];
+ }
+ else if (type == GL_UNSIGNED_SHORT) {
+ for (i = 0; i < count; i++)
+ if (((GLushort *) indices)[i] > max)
+ max = ((GLushort *) indices)[i];
+ }
+ else {
+ ASSERT(type == GL_UNSIGNED_BYTE);
+ for (i = 0; i < count; i++)
+ if (((GLubyte *) indices)[i] > max)
+ max = ((GLubyte *) indices)[i];
+ }
+ if (max >= ctx->Array._MaxElement) {
+ /* the max element is out of bounds of one or more enabled arrays */
+ return GL_FALSE;
+ }
+ }
+
+ return GL_TRUE;
+}
+
+
+GLboolean
+_mesa_validate_DrawRangeElements(GLcontext *ctx, GLenum mode,
+ GLuint start, GLuint end,
+ GLsizei count, GLenum type,
+ const GLvoid *indices)
+{
+ ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
+
+ if (count <= 0) {
+ if (count < 0)
+ _mesa_error(ctx, GL_INVALID_VALUE, "glDrawRangeElements(count)" );
+ return GL_FALSE;
+ }
+
+ if (mode > GL_POLYGON) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glDrawRangeElements(mode)" );
+ return GL_FALSE;
+ }
+
+ if (end < start) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glDrawRangeElements(end<start)");
+ return GL_FALSE;
+ }
+
+ if (type != GL_UNSIGNED_INT &&
+ type != GL_UNSIGNED_BYTE &&
+ type != GL_UNSIGNED_SHORT) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glDrawRangeElements(type)" );
+ return GL_FALSE;
+ }
+
+ if (ctx->NewState)
+ _mesa_update_state(ctx);
+
+ /* Always need vertex positions */
+ if (!ctx->Array.Vertex.Enabled
+ && !(ctx->VertexProgram._Enabled && ctx->Array.VertexAttrib[0].Enabled))
+ return GL_FALSE;
+
+ if (ctx->Const.CheckArrayBounds) {
+ /* Find max array index.
+ * We don't trust the user's start and end values.
+ */
+ GLuint max = 0;
+ GLint i;
+ if (type == GL_UNSIGNED_INT) {
+ for (i = 0; i < count; i++)
+ if (((GLuint *) indices)[i] > max)
+ max = ((GLuint *) indices)[i];
+ }
+ else if (type == GL_UNSIGNED_SHORT) {
+ for (i = 0; i < count; i++)
+ if (((GLushort *) indices)[i] > max)
+ max = ((GLushort *) indices)[i];
+ }
+ else {
+ ASSERT(type == GL_UNSIGNED_BYTE);
+ for (i = 0; i < count; i++)
+ if (((GLubyte *) indices)[i] > max)
+ max = ((GLubyte *) indices)[i];
+ }
+ if (max >= ctx->Array._MaxElement) {
+ /* the max element is out of bounds of one or more enabled arrays */
+ return GL_FALSE;
+ }
+ }
+
+ return GL_TRUE;
+}
+
+
+/**
+ * Called from the tnl module to error check the function parameters and
+ * verify that we really can draw something.
+ */
+GLboolean
+_mesa_validate_DrawArrays(GLcontext *ctx,
+ GLenum mode, GLint start, GLsizei count)
+{
+ ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
+
+ if (count < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glDrawArrays(count)" );
+ return GL_FALSE;
+ }
+
+ if (mode > GL_POLYGON) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glDrawArrays(mode)" );
+ return GL_FALSE;
+ }
+
+ if (ctx->NewState)
+ _mesa_update_state(ctx);
+
+ /* Always need vertex positions */
+ if (!ctx->Array.Vertex.Enabled && !ctx->Array.VertexAttrib[0].Enabled)
+ return GL_FALSE;
+
+ if (ctx->Const.CheckArrayBounds) {
+ if (start + count > (GLint) ctx->Array._MaxElement)
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
diff --git a/src/mesa/main/api_validate.h b/src/mesa/main/api_validate.h
new file mode 100644
index 00000000000..10f0c34e663
--- /dev/null
+++ b/src/mesa/main/api_validate.h
@@ -0,0 +1,49 @@
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.5
+ *
+ * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef API_VALIDATE_H
+#define API_VALIDATE_H
+
+
+#include "mtypes.h"
+
+extern GLboolean
+_mesa_validate_DrawArrays(GLcontext *ctx,
+ GLenum mode, GLint start, GLsizei count);
+
+extern GLboolean
+_mesa_validate_DrawElements(GLcontext *ctx,
+ GLenum mode, GLsizei count, GLenum type,
+ const GLvoid *indices);
+
+extern GLboolean
+_mesa_validate_DrawRangeElements(GLcontext *ctx, GLenum mode,
+ GLuint start, GLuint end,
+ GLsizei count, GLenum type,
+ const GLvoid *indices);
+
+
+#endif
diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c
new file mode 100644
index 00000000000..2eef7294691
--- /dev/null
+++ b/src/mesa/main/attrib.c
@@ -0,0 +1,1331 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "glheader.h"
+#include "imports.h"
+#include "accum.h"
+#include "attrib.h"
+#include "blend.h"
+#include "buffers.h"
+#include "bufferobj.h"
+#include "colormac.h"
+#include "colortab.h"
+#include "context.h"
+#include "depth.h"
+#include "enable.h"
+#include "enums.h"
+#include "fog.h"
+#include "hint.h"
+#include "light.h"
+#include "lines.h"
+#include "matrix.h"
+#include "points.h"
+#include "polygon.h"
+#include "simple_list.h"
+#include "stencil.h"
+#include "texobj.h"
+#include "texstate.h"
+#include "mtypes.h"
+#include "math/m_xform.h"
+
+
+/**
+ * Allocate a new attribute state node. These nodes have a
+ * "kind" value and a pointer to a struct of state data.
+ */
+static struct gl_attrib_node *
+new_attrib_node( GLbitfield kind )
+{
+ struct gl_attrib_node *an = MALLOC_STRUCT(gl_attrib_node);
+ if (an) {
+ an->kind = kind;
+ }
+ return an;
+}
+
+
+void GLAPIENTRY
+_mesa_PushAttrib(GLbitfield mask)
+{
+ struct gl_attrib_node *newnode;
+ struct gl_attrib_node *head;
+
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx, "glPushAttrib %x\n", (int) mask);
+
+ if (ctx->AttribStackDepth >= MAX_ATTRIB_STACK_DEPTH) {
+ _mesa_error( ctx, GL_STACK_OVERFLOW, "glPushAttrib" );
+ return;
+ }
+
+ /* Build linked list of attribute nodes which save all attribute */
+ /* groups specified by the mask. */
+ head = NULL;
+
+ if (mask & GL_ACCUM_BUFFER_BIT) {
+ struct gl_accum_attrib *attr;
+ attr = MALLOC_STRUCT( gl_accum_attrib );
+ MEMCPY( attr, &ctx->Accum, sizeof(struct gl_accum_attrib) );
+ newnode = new_attrib_node( GL_ACCUM_BUFFER_BIT );
+ newnode->data = attr;
+ newnode->next = head;
+ head = newnode;
+ }
+
+ if (mask & GL_COLOR_BUFFER_BIT) {
+ struct gl_colorbuffer_attrib *attr;
+ attr = MALLOC_STRUCT( gl_colorbuffer_attrib );
+ MEMCPY( attr, &ctx->Color, sizeof(struct gl_colorbuffer_attrib) );
+ newnode = new_attrib_node( GL_COLOR_BUFFER_BIT );
+ newnode->data = attr;
+ newnode->next = head;
+ head = newnode;
+ }
+
+ if (mask & GL_CURRENT_BIT) {
+ struct gl_current_attrib *attr;
+ FLUSH_CURRENT( ctx, 0 );
+ attr = MALLOC_STRUCT( gl_current_attrib );
+ MEMCPY( attr, &ctx->Current, sizeof(struct gl_current_attrib) );
+ newnode = new_attrib_node( GL_CURRENT_BIT );
+ newnode->data = attr;
+ newnode->next = head;
+ head = newnode;
+ }
+
+ if (mask & GL_DEPTH_BUFFER_BIT) {
+ struct gl_depthbuffer_attrib *attr;
+ attr = MALLOC_STRUCT( gl_depthbuffer_attrib );
+ MEMCPY( attr, &ctx->Depth, sizeof(struct gl_depthbuffer_attrib) );
+ newnode = new_attrib_node( GL_DEPTH_BUFFER_BIT );
+ newnode->data = attr;
+ newnode->next = head;
+ head = newnode;
+ }
+
+ if (mask & GL_ENABLE_BIT) {
+ struct gl_enable_attrib *attr;
+ GLuint i;
+ attr = MALLOC_STRUCT( gl_enable_attrib );
+ /* Copy enable flags from all other attributes into the enable struct. */
+ attr->AlphaTest = ctx->Color.AlphaEnabled;
+ attr->AutoNormal = ctx->Eval.AutoNormal;
+ attr->Blend = ctx->Color.BlendEnabled;
+ attr->ClipPlanes = ctx->Transform.ClipPlanesEnabled;
+ attr->ColorMaterial = ctx->Light.ColorMaterialEnabled;
+ attr->ColorTable = ctx->Pixel.ColorTableEnabled;
+ attr->PostColorMatrixColorTable = ctx->Pixel.PostColorMatrixColorTableEnabled;
+ attr->PostConvolutionColorTable = ctx->Pixel.PostConvolutionColorTableEnabled;
+ attr->Convolution1D = ctx->Pixel.Convolution1DEnabled;
+ attr->Convolution2D = ctx->Pixel.Convolution2DEnabled;
+ attr->Separable2D = ctx->Pixel.Separable2DEnabled;
+ attr->CullFace = ctx->Polygon.CullFlag;
+ attr->DepthTest = ctx->Depth.Test;
+ attr->Dither = ctx->Color.DitherFlag;
+ attr->Fog = ctx->Fog.Enabled;
+ for (i = 0; i < ctx->Const.MaxLights; i++) {
+ attr->Light[i] = ctx->Light.Light[i].Enabled;
+ }
+ attr->Lighting = ctx->Light.Enabled;
+ attr->LineSmooth = ctx->Line.SmoothFlag;
+ attr->LineStipple = ctx->Line.StippleFlag;
+ attr->Histogram = ctx->Pixel.HistogramEnabled;
+ attr->MinMax = ctx->Pixel.MinMaxEnabled;
+ attr->IndexLogicOp = ctx->Color.IndexLogicOpEnabled;
+ attr->ColorLogicOp = ctx->Color.ColorLogicOpEnabled;
+ attr->Map1Color4 = ctx->Eval.Map1Color4;
+ attr->Map1Index = ctx->Eval.Map1Index;
+ attr->Map1Normal = ctx->Eval.Map1Normal;
+ attr->Map1TextureCoord1 = ctx->Eval.Map1TextureCoord1;
+ attr->Map1TextureCoord2 = ctx->Eval.Map1TextureCoord2;
+ attr->Map1TextureCoord3 = ctx->Eval.Map1TextureCoord3;
+ attr->Map1TextureCoord4 = ctx->Eval.Map1TextureCoord4;
+ attr->Map1Vertex3 = ctx->Eval.Map1Vertex3;
+ attr->Map1Vertex4 = ctx->Eval.Map1Vertex4;
+ MEMCPY(attr->Map1Attrib, ctx->Eval.Map1Attrib, sizeof(ctx->Eval.Map1Attrib));
+ attr->Map2Color4 = ctx->Eval.Map2Color4;
+ attr->Map2Index = ctx->Eval.Map2Index;
+ attr->Map2Normal = ctx->Eval.Map2Normal;
+ attr->Map2TextureCoord1 = ctx->Eval.Map2TextureCoord1;
+ attr->Map2TextureCoord2 = ctx->Eval.Map2TextureCoord2;
+ attr->Map2TextureCoord3 = ctx->Eval.Map2TextureCoord3;
+ attr->Map2TextureCoord4 = ctx->Eval.Map2TextureCoord4;
+ attr->Map2Vertex3 = ctx->Eval.Map2Vertex3;
+ attr->Map2Vertex4 = ctx->Eval.Map2Vertex4;
+ MEMCPY(attr->Map2Attrib, ctx->Eval.Map2Attrib, sizeof(ctx->Eval.Map2Attrib));
+ attr->Normalize = ctx->Transform.Normalize;
+ attr->RasterPositionUnclipped = ctx->Transform.RasterPositionUnclipped;
+ attr->PointSmooth = ctx->Point.SmoothFlag;
+ attr->PointSprite = ctx->Point.PointSprite;
+ attr->PolygonOffsetPoint = ctx->Polygon.OffsetPoint;
+ attr->PolygonOffsetLine = ctx->Polygon.OffsetLine;
+ attr->PolygonOffsetFill = ctx->Polygon.OffsetFill;
+ attr->PolygonSmooth = ctx->Polygon.SmoothFlag;
+ attr->PolygonStipple = ctx->Polygon.StippleFlag;
+ attr->RescaleNormals = ctx->Transform.RescaleNormals;
+ attr->Scissor = ctx->Scissor.Enabled;
+ attr->Stencil = ctx->Stencil.Enabled;
+ attr->StencilTwoSide = ctx->Stencil.TestTwoSide;
+ attr->MultisampleEnabled = ctx->Multisample.Enabled;
+ attr->SampleAlphaToCoverage = ctx->Multisample.SampleAlphaToCoverage;
+ attr->SampleAlphaToOne = ctx->Multisample.SampleAlphaToOne;
+ attr->SampleCoverage = ctx->Multisample.SampleCoverage;
+ attr->SampleCoverageInvert = ctx->Multisample.SampleCoverageInvert;
+ for (i=0; i<MAX_TEXTURE_UNITS; i++) {
+ attr->Texture[i] = ctx->Texture.Unit[i].Enabled;
+ attr->TexGen[i] = ctx->Texture.Unit[i].TexGenEnabled;
+ attr->TextureColorTable[i] = ctx->Texture.Unit[i].ColorTableEnabled;
+ }
+ /* GL_NV_vertex_program */
+ attr->VertexProgram = ctx->VertexProgram.Enabled;
+ attr->VertexProgramPointSize = ctx->VertexProgram.PointSizeEnabled;
+ attr->VertexProgramTwoSide = ctx->VertexProgram.TwoSideEnabled;
+ newnode = new_attrib_node( GL_ENABLE_BIT );
+ newnode->data = attr;
+ newnode->next = head;
+ head = newnode;
+ }
+
+ if (mask & GL_EVAL_BIT) {
+ struct gl_eval_attrib *attr;
+ attr = MALLOC_STRUCT( gl_eval_attrib );
+ MEMCPY( attr, &ctx->Eval, sizeof(struct gl_eval_attrib) );
+ newnode = new_attrib_node( GL_EVAL_BIT );
+ newnode->data = attr;
+ newnode->next = head;
+ head = newnode;
+ }
+
+ if (mask & GL_FOG_BIT) {
+ struct gl_fog_attrib *attr;
+ attr = MALLOC_STRUCT( gl_fog_attrib );
+ MEMCPY( attr, &ctx->Fog, sizeof(struct gl_fog_attrib) );
+ newnode = new_attrib_node( GL_FOG_BIT );
+ newnode->data = attr;
+ newnode->next = head;
+ head = newnode;
+ }
+
+ if (mask & GL_HINT_BIT) {
+ struct gl_hint_attrib *attr;
+ attr = MALLOC_STRUCT( gl_hint_attrib );
+ MEMCPY( attr, &ctx->Hint, sizeof(struct gl_hint_attrib) );
+ newnode = new_attrib_node( GL_HINT_BIT );
+ newnode->data = attr;
+ newnode->next = head;
+ head = newnode;
+ }
+
+ if (mask & GL_LIGHTING_BIT) {
+ struct gl_light_attrib *attr;
+ FLUSH_CURRENT(ctx, 0); /* flush material changes */
+ attr = MALLOC_STRUCT( gl_light_attrib );
+ MEMCPY( attr, &ctx->Light, sizeof(struct gl_light_attrib) );
+ newnode = new_attrib_node( GL_LIGHTING_BIT );
+ newnode->data = attr;
+ newnode->next = head;
+ head = newnode;
+ }
+
+ if (mask & GL_LINE_BIT) {
+ struct gl_line_attrib *attr;
+ attr = MALLOC_STRUCT( gl_line_attrib );
+ MEMCPY( attr, &ctx->Line, sizeof(struct gl_line_attrib) );
+ newnode = new_attrib_node( GL_LINE_BIT );
+ newnode->data = attr;
+ newnode->next = head;
+ head = newnode;
+ }
+
+ if (mask & GL_LIST_BIT) {
+ struct gl_list_attrib *attr;
+ attr = MALLOC_STRUCT( gl_list_attrib );
+ MEMCPY( attr, &ctx->List, sizeof(struct gl_list_attrib) );
+ newnode = new_attrib_node( GL_LIST_BIT );
+ newnode->data = attr;
+ newnode->next = head;
+ head = newnode;
+ }
+
+ if (mask & GL_PIXEL_MODE_BIT) {
+ struct gl_pixel_attrib *attr;
+ attr = MALLOC_STRUCT( gl_pixel_attrib );
+ MEMCPY( attr, &ctx->Pixel, sizeof(struct gl_pixel_attrib) );
+ newnode = new_attrib_node( GL_PIXEL_MODE_BIT );
+ newnode->data = attr;
+ newnode->next = head;
+ head = newnode;
+ }
+
+ if (mask & GL_POINT_BIT) {
+ struct gl_point_attrib *attr;
+ attr = MALLOC_STRUCT( gl_point_attrib );
+ MEMCPY( attr, &ctx->Point, sizeof(struct gl_point_attrib) );
+ newnode = new_attrib_node( GL_POINT_BIT );
+ newnode->data = attr;
+ newnode->next = head;
+ head = newnode;
+ }
+
+ if (mask & GL_POLYGON_BIT) {
+ struct gl_polygon_attrib *attr;
+ attr = MALLOC_STRUCT( gl_polygon_attrib );
+ MEMCPY( attr, &ctx->Polygon, sizeof(struct gl_polygon_attrib) );
+ newnode = new_attrib_node( GL_POLYGON_BIT );
+ newnode->data = attr;
+ newnode->next = head;
+ head = newnode;
+ }
+
+ if (mask & GL_POLYGON_STIPPLE_BIT) {
+ GLuint *stipple;
+ stipple = (GLuint *) MALLOC( 32*sizeof(GLuint) );
+ MEMCPY( stipple, ctx->PolygonStipple, 32*sizeof(GLuint) );
+ newnode = new_attrib_node( GL_POLYGON_STIPPLE_BIT );
+ newnode->data = stipple;
+ newnode->next = head;
+ head = newnode;
+ }
+
+ if (mask & GL_SCISSOR_BIT) {
+ struct gl_scissor_attrib *attr;
+ attr = MALLOC_STRUCT( gl_scissor_attrib );
+ MEMCPY( attr, &ctx->Scissor, sizeof(struct gl_scissor_attrib) );
+ newnode = new_attrib_node( GL_SCISSOR_BIT );
+ newnode->data = attr;
+ newnode->next = head;
+ head = newnode;
+ }
+
+ if (mask & GL_STENCIL_BUFFER_BIT) {
+ struct gl_stencil_attrib *attr;
+ attr = MALLOC_STRUCT( gl_stencil_attrib );
+ MEMCPY( attr, &ctx->Stencil, sizeof(struct gl_stencil_attrib) );
+ newnode = new_attrib_node( GL_STENCIL_BUFFER_BIT );
+ newnode->data = attr;
+ newnode->next = head;
+ head = newnode;
+ }
+
+ if (mask & GL_TEXTURE_BIT) {
+ struct gl_texture_attrib *attr;
+ GLuint u;
+ /* Bump the texture object reference counts so that they don't
+ * inadvertantly get deleted.
+ */
+ for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
+ ctx->Texture.Unit[u].Current1D->RefCount++;
+ ctx->Texture.Unit[u].Current2D->RefCount++;
+ ctx->Texture.Unit[u].Current3D->RefCount++;
+ ctx->Texture.Unit[u].CurrentCubeMap->RefCount++;
+ ctx->Texture.Unit[u].CurrentRect->RefCount++;
+ }
+ attr = MALLOC_STRUCT( gl_texture_attrib );
+ MEMCPY( attr, &ctx->Texture, sizeof(struct gl_texture_attrib) );
+ /* copy state of the currently bound texture objects */
+ for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
+ _mesa_copy_texture_object(&attr->Unit[u].Saved1D,
+ attr->Unit[u].Current1D);
+ _mesa_copy_texture_object(&attr->Unit[u].Saved2D,
+ attr->Unit[u].Current2D);
+ _mesa_copy_texture_object(&attr->Unit[u].Saved3D,
+ attr->Unit[u].Current3D);
+ _mesa_copy_texture_object(&attr->Unit[u].SavedCubeMap,
+ attr->Unit[u].CurrentCubeMap);
+ _mesa_copy_texture_object(&attr->Unit[u].SavedRect,
+ attr->Unit[u].CurrentRect);
+ }
+ newnode = new_attrib_node( GL_TEXTURE_BIT );
+ newnode->data = attr;
+ newnode->next = head;
+ head = newnode;
+ }
+
+ if (mask & GL_TRANSFORM_BIT) {
+ struct gl_transform_attrib *attr;
+ attr = MALLOC_STRUCT( gl_transform_attrib );
+ MEMCPY( attr, &ctx->Transform, sizeof(struct gl_transform_attrib) );
+ newnode = new_attrib_node( GL_TRANSFORM_BIT );
+ newnode->data = attr;
+ newnode->next = head;
+ head = newnode;
+ }
+
+ if (mask & GL_VIEWPORT_BIT) {
+ struct gl_viewport_attrib *attr;
+ attr = MALLOC_STRUCT( gl_viewport_attrib );
+ MEMCPY( attr, &ctx->Viewport, sizeof(struct gl_viewport_attrib) );
+ newnode = new_attrib_node( GL_VIEWPORT_BIT );
+ newnode->data = attr;
+ newnode->next = head;
+ head = newnode;
+ }
+
+ /* GL_ARB_multisample */
+ if (mask & GL_MULTISAMPLE_BIT_ARB) {
+ struct gl_multisample_attrib *attr;
+ attr = MALLOC_STRUCT( gl_multisample_attrib );
+ MEMCPY( attr, &ctx->Multisample, sizeof(struct gl_multisample_attrib) );
+ newnode = new_attrib_node( GL_MULTISAMPLE_BIT_ARB );
+ newnode->data = attr;
+ newnode->next = head;
+ head = newnode;
+ }
+
+ ctx->AttribStack[ctx->AttribStackDepth] = head;
+ ctx->AttribStackDepth++;
+}
+
+
+
+static void
+pop_enable_group(GLcontext *ctx, const struct gl_enable_attrib *enable)
+{
+ GLuint i;
+
+#define TEST_AND_UPDATE(VALUE, NEWVALUE, ENUM) \
+ if ((VALUE) != (NEWVALUE)) { \
+ _mesa_set_enable( ctx, ENUM, (NEWVALUE) ); \
+ }
+
+ TEST_AND_UPDATE(ctx->Color.AlphaEnabled, enable->AlphaTest, GL_ALPHA_TEST);
+ TEST_AND_UPDATE(ctx->Color.BlendEnabled, enable->Blend, GL_BLEND);
+
+ for (i=0;i<MAX_CLIP_PLANES;i++) {
+ const GLuint mask = 1 << i;
+ if ((ctx->Transform.ClipPlanesEnabled & mask) != (enable->ClipPlanes & mask))
+ _mesa_set_enable(ctx, (GLenum) (GL_CLIP_PLANE0 + i),
+ (GLboolean) ((enable->ClipPlanes & mask) ? GL_TRUE : GL_FALSE));
+ }
+
+ TEST_AND_UPDATE(ctx->Light.ColorMaterialEnabled, enable->ColorMaterial,
+ GL_COLOR_MATERIAL);
+ TEST_AND_UPDATE(ctx->Pixel.ColorTableEnabled, enable->ColorTable,
+ GL_COLOR_TABLE);
+ TEST_AND_UPDATE(ctx->Pixel.PostColorMatrixColorTableEnabled,
+ enable->PostColorMatrixColorTable,
+ GL_POST_COLOR_MATRIX_COLOR_TABLE);
+ TEST_AND_UPDATE(ctx->Pixel.PostConvolutionColorTableEnabled,
+ enable->PostConvolutionColorTable,
+ GL_POST_CONVOLUTION_COLOR_TABLE);
+ TEST_AND_UPDATE(ctx->Polygon.CullFlag, enable->CullFace, GL_CULL_FACE);
+ TEST_AND_UPDATE(ctx->Depth.Test, enable->DepthTest, GL_DEPTH_TEST);
+ TEST_AND_UPDATE(ctx->Color.DitherFlag, enable->Dither, GL_DITHER);
+ TEST_AND_UPDATE(ctx->Pixel.Convolution1DEnabled, enable->Convolution1D,
+ GL_CONVOLUTION_1D);
+ TEST_AND_UPDATE(ctx->Pixel.Convolution2DEnabled, enable->Convolution2D,
+ GL_CONVOLUTION_2D);
+ TEST_AND_UPDATE(ctx->Pixel.Separable2DEnabled, enable->Separable2D,
+ GL_SEPARABLE_2D);
+ TEST_AND_UPDATE(ctx->Fog.Enabled, enable->Fog, GL_FOG);
+ TEST_AND_UPDATE(ctx->Light.Enabled, enable->Lighting, GL_LIGHTING);
+ TEST_AND_UPDATE(ctx->Line.SmoothFlag, enable->LineSmooth, GL_LINE_SMOOTH);
+ TEST_AND_UPDATE(ctx->Line.StippleFlag, enable->LineStipple,
+ GL_LINE_STIPPLE);
+ TEST_AND_UPDATE(ctx->Color.IndexLogicOpEnabled, enable->IndexLogicOp,
+ GL_INDEX_LOGIC_OP);
+ TEST_AND_UPDATE(ctx->Color.ColorLogicOpEnabled, enable->ColorLogicOp,
+ GL_COLOR_LOGIC_OP);
+
+ TEST_AND_UPDATE(ctx->Eval.Map1Color4, enable->Map1Color4, GL_MAP1_COLOR_4);
+ TEST_AND_UPDATE(ctx->Eval.Map1Index, enable->Map1Index, GL_MAP1_INDEX);
+ TEST_AND_UPDATE(ctx->Eval.Map1Normal, enable->Map1Normal, GL_MAP1_NORMAL);
+ TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord1, enable->Map1TextureCoord1,
+ GL_MAP1_TEXTURE_COORD_1);
+ TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord2, enable->Map1TextureCoord2,
+ GL_MAP1_TEXTURE_COORD_2);
+ TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord3, enable->Map1TextureCoord3,
+ GL_MAP1_TEXTURE_COORD_3);
+ TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord4, enable->Map1TextureCoord4,
+ GL_MAP1_TEXTURE_COORD_4);
+ TEST_AND_UPDATE(ctx->Eval.Map1Vertex3, enable->Map1Vertex3,
+ GL_MAP1_VERTEX_3);
+ TEST_AND_UPDATE(ctx->Eval.Map1Vertex4, enable->Map1Vertex4,
+ GL_MAP1_VERTEX_4);
+ for (i = 0; i < 16; i++) {
+ TEST_AND_UPDATE(ctx->Eval.Map1Attrib[i], enable->Map1Attrib[i],
+ GL_MAP1_VERTEX_ATTRIB0_4_NV + i);
+ }
+
+ TEST_AND_UPDATE(ctx->Eval.Map2Color4, enable->Map2Color4, GL_MAP2_COLOR_4);
+ TEST_AND_UPDATE(ctx->Eval.Map2Index, enable->Map2Index, GL_MAP2_INDEX);
+ TEST_AND_UPDATE(ctx->Eval.Map2Normal, enable->Map2Normal, GL_MAP2_NORMAL);
+ TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord1, enable->Map2TextureCoord1,
+ GL_MAP2_TEXTURE_COORD_1);
+ TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord2, enable->Map2TextureCoord2,
+ GL_MAP2_TEXTURE_COORD_2);
+ TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord3, enable->Map2TextureCoord3,
+ GL_MAP2_TEXTURE_COORD_3);
+ TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord4, enable->Map2TextureCoord4,
+ GL_MAP2_TEXTURE_COORD_4);
+ TEST_AND_UPDATE(ctx->Eval.Map2Vertex3, enable->Map2Vertex3,
+ GL_MAP2_VERTEX_3);
+ TEST_AND_UPDATE(ctx->Eval.Map2Vertex4, enable->Map2Vertex4,
+ GL_MAP2_VERTEX_4);
+ for (i = 0; i < 16; i++) {
+ TEST_AND_UPDATE(ctx->Eval.Map2Attrib[i], enable->Map2Attrib[i],
+ GL_MAP2_VERTEX_ATTRIB0_4_NV + i);
+ }
+
+ TEST_AND_UPDATE(ctx->Eval.AutoNormal, enable->AutoNormal, GL_AUTO_NORMAL);
+ TEST_AND_UPDATE(ctx->Transform.Normalize, enable->Normalize, GL_NORMALIZE);
+ TEST_AND_UPDATE(ctx->Transform.RescaleNormals, enable->RescaleNormals,
+ GL_RESCALE_NORMAL_EXT);
+ TEST_AND_UPDATE(ctx->Transform.RasterPositionUnclipped,
+ enable->RasterPositionUnclipped,
+ GL_RASTER_POSITION_UNCLIPPED_IBM);
+ TEST_AND_UPDATE(ctx->Point.SmoothFlag, enable->PointSmooth,
+ GL_POINT_SMOOTH);
+ if (ctx->Extensions.NV_point_sprite || ctx->Extensions.ARB_point_sprite) {
+ TEST_AND_UPDATE(ctx->Point.PointSprite, enable->PointSprite,
+ GL_POINT_SPRITE_NV);
+ }
+ TEST_AND_UPDATE(ctx->Polygon.OffsetPoint, enable->PolygonOffsetPoint,
+ GL_POLYGON_OFFSET_POINT);
+ TEST_AND_UPDATE(ctx->Polygon.OffsetLine, enable->PolygonOffsetLine,
+ GL_POLYGON_OFFSET_LINE);
+ TEST_AND_UPDATE(ctx->Polygon.OffsetFill, enable->PolygonOffsetFill,
+ GL_POLYGON_OFFSET_FILL);
+ TEST_AND_UPDATE(ctx->Polygon.SmoothFlag, enable->PolygonSmooth,
+ GL_POLYGON_SMOOTH);
+ TEST_AND_UPDATE(ctx->Polygon.StippleFlag, enable->PolygonStipple,
+ GL_POLYGON_STIPPLE);
+ TEST_AND_UPDATE(ctx->Scissor.Enabled, enable->Scissor, GL_SCISSOR_TEST);
+ TEST_AND_UPDATE(ctx->Stencil.Enabled, enable->Stencil, GL_STENCIL_TEST);
+ if (ctx->Extensions.EXT_stencil_two_side) {
+ TEST_AND_UPDATE(ctx->Stencil.TestTwoSide, enable->StencilTwoSide, GL_STENCIL_TEST_TWO_SIDE_EXT);
+ }
+ TEST_AND_UPDATE(ctx->Multisample.Enabled, enable->MultisampleEnabled,
+ GL_MULTISAMPLE_ARB);
+ TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToCoverage,
+ enable->SampleAlphaToCoverage,
+ GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);
+ TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToOne,
+ enable->SampleAlphaToOne,
+ GL_SAMPLE_ALPHA_TO_ONE_ARB);
+ TEST_AND_UPDATE(ctx->Multisample.SampleCoverage,
+ enable->SampleCoverage,
+ GL_SAMPLE_COVERAGE_ARB);
+ TEST_AND_UPDATE(ctx->Multisample.SampleCoverageInvert,
+ enable->SampleCoverageInvert,
+ GL_SAMPLE_COVERAGE_INVERT_ARB);
+ /* GL_ARB_vertex_program, GL_NV_vertex_program */
+ TEST_AND_UPDATE(ctx->VertexProgram.Enabled,
+ enable->VertexProgram,
+ GL_VERTEX_PROGRAM_ARB);
+ TEST_AND_UPDATE(ctx->VertexProgram.PointSizeEnabled,
+ enable->VertexProgramPointSize,
+ GL_VERTEX_PROGRAM_POINT_SIZE_ARB);
+ TEST_AND_UPDATE(ctx->VertexProgram.TwoSideEnabled,
+ enable->VertexProgramTwoSide,
+ GL_VERTEX_PROGRAM_TWO_SIDE_ARB);
+
+#undef TEST_AND_UPDATE
+
+ /* texture unit enables */
+ for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
+ if (ctx->Texture.Unit[i].Enabled != enable->Texture[i]) {
+ ctx->Texture.Unit[i].Enabled = enable->Texture[i];
+ if (ctx->Driver.Enable) {
+ if (ctx->Driver.ActiveTexture) {
+ (*ctx->Driver.ActiveTexture)(ctx, i);
+ }
+ (*ctx->Driver.Enable)( ctx, GL_TEXTURE_1D,
+ (GLboolean) (enable->Texture[i] & TEXTURE_1D_BIT) );
+ (*ctx->Driver.Enable)( ctx, GL_TEXTURE_2D,
+ (GLboolean) (enable->Texture[i] & TEXTURE_2D_BIT) );
+ (*ctx->Driver.Enable)( ctx, GL_TEXTURE_3D,
+ (GLboolean) (enable->Texture[i] & TEXTURE_3D_BIT) );
+ if (ctx->Extensions.ARB_texture_cube_map)
+ (*ctx->Driver.Enable)( ctx, GL_TEXTURE_CUBE_MAP_ARB,
+ (GLboolean) (enable->Texture[i] & TEXTURE_CUBE_BIT) );
+ if (ctx->Extensions.NV_texture_rectangle)
+ (*ctx->Driver.Enable)( ctx, GL_TEXTURE_RECTANGLE_NV,
+ (GLboolean) (enable->Texture[i] & TEXTURE_RECT_BIT) );
+ }
+ }
+
+ if (ctx->Texture.Unit[i].TexGenEnabled != enable->TexGen[i]) {
+ ctx->Texture.Unit[i].TexGenEnabled = enable->TexGen[i];
+ if (ctx->Driver.Enable) {
+ if (ctx->Driver.ActiveTexture) {
+ (*ctx->Driver.ActiveTexture)(ctx, i);
+ }
+ if (enable->TexGen[i] & S_BIT)
+ (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_S, GL_TRUE);
+ else
+ (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_S, GL_FALSE);
+ if (enable->TexGen[i] & T_BIT)
+ (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_T, GL_TRUE);
+ else
+ (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_T, GL_FALSE);
+ if (enable->TexGen[i] & R_BIT)
+ (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_R, GL_TRUE);
+ else
+ (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_R, GL_FALSE);
+ if (enable->TexGen[i] & Q_BIT)
+ (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_Q, GL_TRUE);
+ else
+ (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_Q, GL_FALSE);
+ }
+ }
+
+ /* GL_SGI_texture_color_table */
+ ctx->Texture.Unit[i].ColorTableEnabled = enable->TextureColorTable[i];
+ }
+
+ if (ctx->Driver.ActiveTexture) {
+ (*ctx->Driver.ActiveTexture)(ctx, ctx->Texture.CurrentUnit);
+ }
+}
+
+
+static void
+pop_texture_group(GLcontext *ctx, const struct gl_texture_attrib *texAttrib)
+{
+ GLuint u;
+
+ for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
+ const struct gl_texture_unit *unit = &texAttrib->Unit[u];
+ GLuint i;
+
+ _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + u);
+ _mesa_set_enable(ctx, GL_TEXTURE_1D,
+ (unit->Enabled & TEXTURE_1D_BIT) ? GL_TRUE : GL_FALSE);
+ _mesa_set_enable(ctx, GL_TEXTURE_2D,
+ (unit->Enabled & TEXTURE_2D_BIT) ? GL_TRUE : GL_FALSE);
+ _mesa_set_enable(ctx, GL_TEXTURE_3D,
+ (unit->Enabled & TEXTURE_3D_BIT) ? GL_TRUE : GL_FALSE);
+ if (ctx->Extensions.ARB_texture_cube_map) {
+ _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP_ARB,
+ (unit->Enabled & TEXTURE_CUBE_BIT) ? GL_TRUE : GL_FALSE);
+ }
+ if (ctx->Extensions.NV_texture_rectangle) {
+ _mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE_NV,
+ (unit->Enabled & TEXTURE_RECT_BIT) ? GL_TRUE : GL_FALSE);
+ }
+ if (ctx->Extensions.SGI_texture_color_table) {
+ _mesa_set_enable(ctx, GL_TEXTURE_COLOR_TABLE_SGI,
+ unit->ColorTableEnabled);
+ }
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->EnvMode);
+ _mesa_TexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, unit->EnvColor);
+ _mesa_TexGeni(GL_S, GL_TEXTURE_GEN_MODE, unit->GenModeS);
+ _mesa_TexGeni(GL_T, GL_TEXTURE_GEN_MODE, unit->GenModeT);
+ _mesa_TexGeni(GL_R, GL_TEXTURE_GEN_MODE, unit->GenModeR);
+ _mesa_TexGeni(GL_Q, GL_TEXTURE_GEN_MODE, unit->GenModeQ);
+ _mesa_TexGenfv(GL_S, GL_OBJECT_PLANE, unit->ObjectPlaneS);
+ _mesa_TexGenfv(GL_T, GL_OBJECT_PLANE, unit->ObjectPlaneT);
+ _mesa_TexGenfv(GL_R, GL_OBJECT_PLANE, unit->ObjectPlaneR);
+ _mesa_TexGenfv(GL_Q, GL_OBJECT_PLANE, unit->ObjectPlaneQ);
+ /* Eye plane done differently to avoid re-transformation */
+ {
+ struct gl_texture_unit *destUnit = &ctx->Texture.Unit[u];
+ COPY_4FV(destUnit->EyePlaneS, unit->EyePlaneS);
+ COPY_4FV(destUnit->EyePlaneT, unit->EyePlaneT);
+ COPY_4FV(destUnit->EyePlaneR, unit->EyePlaneR);
+ COPY_4FV(destUnit->EyePlaneQ, unit->EyePlaneQ);
+ if (ctx->Driver.TexGen) {
+ ctx->Driver.TexGen(ctx, GL_S, GL_EYE_PLANE, unit->EyePlaneS);
+ ctx->Driver.TexGen(ctx, GL_T, GL_EYE_PLANE, unit->EyePlaneT);
+ ctx->Driver.TexGen(ctx, GL_R, GL_EYE_PLANE, unit->EyePlaneR);
+ ctx->Driver.TexGen(ctx, GL_Q, GL_EYE_PLANE, unit->EyePlaneQ);
+ }
+ }
+ _mesa_set_enable(ctx, GL_TEXTURE_GEN_S,
+ ((unit->TexGenEnabled & S_BIT) ? GL_TRUE : GL_FALSE));
+ _mesa_set_enable(ctx, GL_TEXTURE_GEN_T,
+ ((unit->TexGenEnabled & T_BIT) ? GL_TRUE : GL_FALSE));
+ _mesa_set_enable(ctx, GL_TEXTURE_GEN_R,
+ ((unit->TexGenEnabled & R_BIT) ? GL_TRUE : GL_FALSE));
+ _mesa_set_enable(ctx, GL_TEXTURE_GEN_Q,
+ ((unit->TexGenEnabled & Q_BIT) ? GL_TRUE : GL_FALSE));
+ if (ctx->Extensions.EXT_texture_lod_bias) {
+ _mesa_TexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
+ GL_TEXTURE_LOD_BIAS_EXT, unit->LodBias);
+ }
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB,
+ unit->Combine.ModeRGB);
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA,
+ unit->Combine.ModeA);
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB,
+ unit->Combine.SourceRGB[0]);
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB,
+ unit->Combine.SourceRGB[1]);
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB,
+ unit->Combine.SourceRGB[2]);
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA,
+ unit->Combine.SourceA[0]);
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA,
+ unit->Combine.SourceA[1]);
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA,
+ unit->Combine.SourceA[2]);
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB,
+ unit->Combine.OperandRGB[0]);
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB,
+ unit->Combine.OperandRGB[1]);
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB,
+ unit->Combine.OperandRGB[2]);
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA,
+ unit->Combine.OperandA[0]);
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA,
+ unit->Combine.OperandA[1]);
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA,
+ unit->Combine.OperandA[2]);
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE,
+ 1 << unit->Combine.ScaleShiftRGB);
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE,
+ 1 << unit->Combine.ScaleShiftA);
+ }
+
+ /* Restore texture object state */
+ for (i = 0; i < NUM_TEXTURE_TARGETS; i++) {
+ GLenum target = 0;
+ const struct gl_texture_object *obj = NULL;
+ GLfloat bordColor[4];
+
+ switch (i) {
+ case 0:
+ target = GL_TEXTURE_1D;
+ obj = &unit->Saved1D;
+ break;
+ case 1:
+ target = GL_TEXTURE_2D;
+ obj = &unit->Saved2D;
+ break;
+ case 2:
+ target = GL_TEXTURE_3D;
+ obj = &unit->Saved3D;
+ break;
+ case 3:
+ if (!ctx->Extensions.ARB_texture_cube_map)
+ continue;
+ target = GL_TEXTURE_CUBE_MAP_ARB;
+ obj = &unit->SavedCubeMap;
+ break;
+ case 4:
+ if (!ctx->Extensions.NV_texture_rectangle)
+ continue;
+ target = GL_TEXTURE_RECTANGLE_NV;
+ obj = &unit->SavedRect;
+ break;
+ default:
+ ; /* silence warnings */
+ }
+
+ _mesa_BindTexture(target, obj->Name);
+
+ bordColor[0] = CHAN_TO_FLOAT(obj->BorderColor[0]);
+ bordColor[1] = CHAN_TO_FLOAT(obj->BorderColor[1]);
+ bordColor[2] = CHAN_TO_FLOAT(obj->BorderColor[2]);
+ bordColor[3] = CHAN_TO_FLOAT(obj->BorderColor[3]);
+
+ _mesa_TexParameterf(target, GL_TEXTURE_PRIORITY, obj->Priority);
+ _mesa_TexParameterfv(target, GL_TEXTURE_BORDER_COLOR, bordColor);
+ _mesa_TexParameteri(target, GL_TEXTURE_WRAP_S, obj->WrapS);
+ _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, obj->WrapT);
+ _mesa_TexParameteri(target, GL_TEXTURE_WRAP_R, obj->WrapR);
+ _mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, obj->MinFilter);
+ _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, obj->MagFilter);
+ _mesa_TexParameterf(target, GL_TEXTURE_MIN_LOD, obj->MinLod);
+ _mesa_TexParameterf(target, GL_TEXTURE_MAX_LOD, obj->MaxLod);
+ _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, obj->BaseLevel);
+ _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, obj->MaxLevel);
+ if (ctx->Extensions.EXT_texture_filter_anisotropic) {
+ _mesa_TexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT,
+ obj->MaxAnisotropy);
+ }
+ if (ctx->Extensions.SGIX_shadow) {
+ _mesa_TexParameteri(target, GL_TEXTURE_COMPARE_SGIX,
+ obj->CompareFlag);
+ _mesa_TexParameteri(target, GL_TEXTURE_COMPARE_OPERATOR_SGIX,
+ obj->CompareOperator);
+ }
+ if (ctx->Extensions.SGIX_shadow_ambient) {
+ _mesa_TexParameterf(target, GL_SHADOW_AMBIENT_SGIX,
+ obj->ShadowAmbient);
+ }
+
+ }
+ }
+ _mesa_ActiveTextureARB(GL_TEXTURE0_ARB
+ + texAttrib->CurrentUnit);
+
+ /* "un-bump" the texture object reference counts. We did that so they
+ * wouldn't inadvertantly get deleted while they were still referenced
+ * inside the attribute state stack.
+ */
+ for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
+ ctx->Texture.Unit[u].Current1D->RefCount--;
+ ctx->Texture.Unit[u].Current2D->RefCount--;
+ ctx->Texture.Unit[u].Current3D->RefCount--;
+ ctx->Texture.Unit[u].CurrentCubeMap->RefCount--;
+ ctx->Texture.Unit[u].CurrentRect->RefCount--;
+ }
+}
+
+
+/*
+ * This function is kind of long just because we have to call a lot
+ * of device driver functions to update device driver state.
+ *
+ * XXX As it is now, most of the pop-code calls immediate-mode Mesa functions
+ * in order to restore GL state. This isn't terribly efficient but it
+ * ensures that dirty flags and any derived state gets updated correctly.
+ * We could at least check if the value to restore equals the current value
+ * and then skip the Mesa call.
+ */
+void GLAPIENTRY
+_mesa_PopAttrib(void)
+{
+ struct gl_attrib_node *attr, *next;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (ctx->AttribStackDepth == 0) {
+ _mesa_error( ctx, GL_STACK_UNDERFLOW, "glPopAttrib" );
+ return;
+ }
+
+ ctx->AttribStackDepth--;
+ attr = ctx->AttribStack[ctx->AttribStackDepth];
+
+ while (attr) {
+
+ if (MESA_VERBOSE & VERBOSE_API) {
+ _mesa_debug(ctx, "glPopAttrib %s\n",
+ _mesa_lookup_enum_by_nr(attr->kind));
+ }
+
+ switch (attr->kind) {
+ case GL_ACCUM_BUFFER_BIT:
+ {
+ const struct gl_accum_attrib *accum;
+ accum = (const struct gl_accum_attrib *) attr->data;
+ _mesa_ClearAccum(accum->ClearColor[0],
+ accum->ClearColor[1],
+ accum->ClearColor[2],
+ accum->ClearColor[3]);
+ }
+ break;
+ case GL_COLOR_BUFFER_BIT:
+ {
+ const struct gl_colorbuffer_attrib *color;
+ color = (const struct gl_colorbuffer_attrib *) attr->data;
+ _mesa_ClearIndex((GLfloat) color->ClearIndex);
+ _mesa_ClearColor(color->ClearColor[0],
+ color->ClearColor[1],
+ color->ClearColor[2],
+ color->ClearColor[3]);
+ _mesa_IndexMask(color->IndexMask);
+ _mesa_ColorMask((GLboolean) (color->ColorMask[0] != 0),
+ (GLboolean) (color->ColorMask[1] != 0),
+ (GLboolean) (color->ColorMask[2] != 0),
+ (GLboolean) (color->ColorMask[3] != 0));
+ _mesa_drawbuffers(ctx, ctx->Const.MaxDrawBuffers,
+ color->DrawBuffer, NULL);
+ _mesa_set_enable(ctx, GL_ALPHA_TEST, color->AlphaEnabled);
+ _mesa_AlphaFunc(color->AlphaFunc, color->AlphaRef);
+ _mesa_set_enable(ctx, GL_BLEND, color->BlendEnabled);
+ _mesa_BlendFuncSeparateEXT(color->BlendSrcRGB,
+ color->BlendDstRGB,
+ color->BlendSrcA,
+ color->BlendDstA);
+ /* This special case is because glBlendEquationSeparateEXT
+ * cannot take GL_LOGIC_OP as a parameter.
+ */
+ if ( color->BlendEquationRGB == color->BlendEquationA ) {
+ _mesa_BlendEquation(color->BlendEquationRGB);
+ }
+ else {
+ _mesa_BlendEquationSeparateEXT(color->BlendEquationRGB,
+ color->BlendEquationA);
+ }
+ _mesa_BlendColor(color->BlendColor[0],
+ color->BlendColor[1],
+ color->BlendColor[2],
+ color->BlendColor[3]);
+ _mesa_LogicOp(color->LogicOp);
+ _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP,
+ color->ColorLogicOpEnabled);
+ _mesa_set_enable(ctx, GL_INDEX_LOGIC_OP,
+ color->IndexLogicOpEnabled);
+ _mesa_set_enable(ctx, GL_DITHER, color->DitherFlag);
+ }
+ break;
+ case GL_CURRENT_BIT:
+ FLUSH_CURRENT( ctx, 0 );
+ MEMCPY( &ctx->Current, attr->data,
+ sizeof(struct gl_current_attrib) );
+ break;
+ case GL_DEPTH_BUFFER_BIT:
+ {
+ const struct gl_depthbuffer_attrib *depth;
+ depth = (const struct gl_depthbuffer_attrib *) attr->data;
+ _mesa_DepthFunc(depth->Func);
+ _mesa_ClearDepth(depth->Clear);
+ _mesa_set_enable(ctx, GL_DEPTH_TEST, depth->Test);
+ _mesa_DepthMask(depth->Mask);
+ }
+ break;
+ case GL_ENABLE_BIT:
+ {
+ const struct gl_enable_attrib *enable;
+ enable = (const struct gl_enable_attrib *) attr->data;
+ pop_enable_group(ctx, enable);
+ ctx->NewState |= _NEW_ALL;
+ }
+ break;
+ case GL_EVAL_BIT:
+ MEMCPY( &ctx->Eval, attr->data, sizeof(struct gl_eval_attrib) );
+ ctx->NewState |= _NEW_EVAL;
+ break;
+ case GL_FOG_BIT:
+ {
+ const struct gl_fog_attrib *fog;
+ fog = (const struct gl_fog_attrib *) attr->data;
+ _mesa_set_enable(ctx, GL_FOG, fog->Enabled);
+ _mesa_Fogfv(GL_FOG_COLOR, fog->Color);
+ _mesa_Fogf(GL_FOG_DENSITY, fog->Density);
+ _mesa_Fogf(GL_FOG_START, fog->Start);
+ _mesa_Fogf(GL_FOG_END, fog->End);
+ _mesa_Fogf(GL_FOG_INDEX, fog->Index);
+ _mesa_Fogi(GL_FOG_MODE, fog->Mode);
+ }
+ break;
+ case GL_HINT_BIT:
+ {
+ const struct gl_hint_attrib *hint;
+ hint = (const struct gl_hint_attrib *) attr->data;
+ _mesa_Hint(GL_PERSPECTIVE_CORRECTION_HINT,
+ hint->PerspectiveCorrection );
+ _mesa_Hint(GL_POINT_SMOOTH_HINT, hint->PointSmooth);
+ _mesa_Hint(GL_LINE_SMOOTH_HINT, hint->LineSmooth);
+ _mesa_Hint(GL_POLYGON_SMOOTH_HINT, hint->PolygonSmooth);
+ _mesa_Hint(GL_FOG_HINT, hint->Fog);
+ _mesa_Hint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT,
+ hint->ClipVolumeClipping);
+ if (ctx->Extensions.ARB_texture_compression)
+ _mesa_Hint(GL_TEXTURE_COMPRESSION_HINT_ARB,
+ hint->TextureCompression);
+ }
+ break;
+ case GL_LIGHTING_BIT:
+ {
+ GLuint i;
+ const struct gl_light_attrib *light;
+ light = (const struct gl_light_attrib *) attr->data;
+ /* lighting enable */
+ _mesa_set_enable(ctx, GL_LIGHTING, light->Enabled);
+ /* per-light state */
+ if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top))
+ _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
+
+ for (i = 0; i < ctx->Const.MaxLights; i++) {
+ const struct gl_light *l = &light->Light[i];
+ _mesa_set_enable(ctx, GL_LIGHT0 + i, l->Enabled);
+ _mesa_light(ctx, i, GL_AMBIENT, l->Ambient);
+ _mesa_light(ctx, i, GL_DIFFUSE, l->Diffuse);
+ _mesa_light(ctx, i, GL_SPECULAR, l->Specular );
+ _mesa_light(ctx, i, GL_POSITION, l->EyePosition);
+ _mesa_light(ctx, i, GL_SPOT_DIRECTION, l->EyeDirection);
+ _mesa_light(ctx, i, GL_SPOT_EXPONENT, &l->SpotExponent);
+ _mesa_light(ctx, i, GL_SPOT_CUTOFF, &l->SpotCutoff);
+ _mesa_light(ctx, i, GL_CONSTANT_ATTENUATION,
+ &l->ConstantAttenuation);
+ _mesa_light(ctx, i, GL_LINEAR_ATTENUATION,
+ &l->LinearAttenuation);
+ _mesa_light(ctx, i, GL_QUADRATIC_ATTENUATION,
+ &l->QuadraticAttenuation);
+ }
+ /* light model */
+ _mesa_LightModelfv(GL_LIGHT_MODEL_AMBIENT,
+ light->Model.Ambient);
+ _mesa_LightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER,
+ (GLfloat) light->Model.LocalViewer);
+ _mesa_LightModelf(GL_LIGHT_MODEL_TWO_SIDE,
+ (GLfloat) light->Model.TwoSide);
+ _mesa_LightModelf(GL_LIGHT_MODEL_COLOR_CONTROL,
+ (GLfloat) light->Model.ColorControl);
+ /* materials */
+ MEMCPY(&ctx->Light.Material, &light->Material,
+ sizeof(struct gl_material));
+ /* shade model */
+ _mesa_ShadeModel(light->ShadeModel);
+ /* color material */
+ _mesa_ColorMaterial(light->ColorMaterialFace,
+ light->ColorMaterialMode);
+ _mesa_set_enable(ctx, GL_COLOR_MATERIAL,
+ light->ColorMaterialEnabled);
+ }
+ break;
+ case GL_LINE_BIT:
+ {
+ const struct gl_line_attrib *line;
+ line = (const struct gl_line_attrib *) attr->data;
+ _mesa_set_enable(ctx, GL_LINE_SMOOTH, line->SmoothFlag);
+ _mesa_set_enable(ctx, GL_LINE_STIPPLE, line->StippleFlag);
+ _mesa_LineStipple(line->StippleFactor, line->StipplePattern);
+ _mesa_LineWidth(line->Width);
+ }
+ break;
+ case GL_LIST_BIT:
+ MEMCPY( &ctx->List, attr->data, sizeof(struct gl_list_attrib) );
+ break;
+ case GL_PIXEL_MODE_BIT:
+ MEMCPY( &ctx->Pixel, attr->data, sizeof(struct gl_pixel_attrib) );
+ /* XXX what other pixel state needs to be set by function calls? */
+ _mesa_ReadBuffer(ctx->Pixel.ReadBuffer);
+ ctx->NewState |= _NEW_PIXEL;
+ break;
+ case GL_POINT_BIT:
+ {
+ const struct gl_point_attrib *point;
+ point = (const struct gl_point_attrib *) attr->data;
+ _mesa_PointSize(point->Size);
+ _mesa_set_enable(ctx, GL_POINT_SMOOTH, point->SmoothFlag);
+ if (ctx->Extensions.EXT_point_parameters) {
+ _mesa_PointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT,
+ point->Params);
+ _mesa_PointParameterfEXT(GL_POINT_SIZE_MIN_EXT,
+ point->MinSize);
+ _mesa_PointParameterfEXT(GL_POINT_SIZE_MAX_EXT,
+ point->MaxSize);
+ _mesa_PointParameterfEXT(GL_POINT_FADE_THRESHOLD_SIZE_EXT,
+ point->Threshold);
+ }
+ if (ctx->Extensions.NV_point_sprite
+ || ctx->Extensions.ARB_point_sprite) {
+ GLuint u;
+ for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
+ _mesa_TexEnvi(GL_POINT_SPRITE_NV, GL_COORD_REPLACE_NV,
+ (GLint) point->CoordReplace[u]);
+ }
+ _mesa_set_enable(ctx, GL_POINT_SPRITE_NV,point->PointSprite);
+ _mesa_PointParameteriNV(GL_POINT_SPRITE_R_MODE_NV,
+ ctx->Point.SpriteRMode);
+ _mesa_PointParameterfEXT(GL_POINT_SPRITE_COORD_ORIGIN,
+ (GLfloat)ctx->Point.SpriteOrigin);
+ }
+ }
+ break;
+ case GL_POLYGON_BIT:
+ {
+ const struct gl_polygon_attrib *polygon;
+ polygon = (const struct gl_polygon_attrib *) attr->data;
+ _mesa_CullFace(polygon->CullFaceMode);
+ _mesa_FrontFace(polygon->FrontFace);
+ _mesa_PolygonMode(GL_FRONT, polygon->FrontMode);
+ _mesa_PolygonMode(GL_BACK, polygon->BackMode);
+ _mesa_PolygonOffset(polygon->OffsetFactor,
+ polygon->OffsetUnits);
+ _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, polygon->SmoothFlag);
+ _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, polygon->StippleFlag);
+ _mesa_set_enable(ctx, GL_CULL_FACE, polygon->CullFlag);
+ _mesa_set_enable(ctx, GL_POLYGON_OFFSET_POINT,
+ polygon->OffsetPoint);
+ _mesa_set_enable(ctx, GL_POLYGON_OFFSET_LINE,
+ polygon->OffsetLine);
+ _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL,
+ polygon->OffsetFill);
+ }
+ break;
+ case GL_POLYGON_STIPPLE_BIT:
+ MEMCPY( ctx->PolygonStipple, attr->data, 32*sizeof(GLuint) );
+ ctx->NewState |= _NEW_POLYGONSTIPPLE;
+ if (ctx->Driver.PolygonStipple)
+ ctx->Driver.PolygonStipple( ctx, (const GLubyte *) attr->data );
+ break;
+ case GL_SCISSOR_BIT:
+ {
+ const struct gl_scissor_attrib *scissor;
+ scissor = (const struct gl_scissor_attrib *) attr->data;
+ _mesa_Scissor(scissor->X, scissor->Y,
+ scissor->Width, scissor->Height);
+ _mesa_set_enable(ctx, GL_SCISSOR_TEST, scissor->Enabled);
+ }
+ break;
+ case GL_STENCIL_BUFFER_BIT:
+ {
+ const struct gl_stencil_attrib *stencil;
+ stencil = (const struct gl_stencil_attrib *) attr->data;
+ _mesa_set_enable(ctx, GL_STENCIL_TEST, stencil->Enabled);
+ _mesa_ClearStencil(stencil->Clear);
+ if (ctx->Extensions.EXT_stencil_two_side) {
+ _mesa_set_enable(ctx, GL_STENCIL_TEST_TWO_SIDE_EXT,
+ stencil->TestTwoSide);
+ _mesa_ActiveStencilFaceEXT(stencil->ActiveFace
+ ? GL_BACK : GL_FRONT);
+ }
+ /* front state */
+ _mesa_StencilFuncSeparate(GL_FRONT,
+ stencil->Function[0],
+ stencil->Ref[0],
+ stencil->ValueMask[0]);
+ _mesa_StencilMaskSeparate(GL_FRONT, stencil->WriteMask[0]);
+ _mesa_StencilOpSeparate(GL_FRONT, stencil->FailFunc[0],
+ stencil->ZFailFunc[0],
+ stencil->ZPassFunc[0]);
+ /* back state */
+ _mesa_StencilFuncSeparate(GL_BACK,
+ stencil->Function[1],
+ stencil->Ref[1],
+ stencil->ValueMask[1]);
+ _mesa_StencilMaskSeparate(GL_BACK, stencil->WriteMask[1]);
+ _mesa_StencilOpSeparate(GL_BACK, stencil->FailFunc[1],
+ stencil->ZFailFunc[1],
+ stencil->ZPassFunc[1]);
+ }
+ break;
+ case GL_TRANSFORM_BIT:
+ {
+ GLuint i;
+ const struct gl_transform_attrib *xform;
+ xform = (const struct gl_transform_attrib *) attr->data;
+ _mesa_MatrixMode(xform->MatrixMode);
+ if (_math_matrix_is_dirty(ctx->ProjectionMatrixStack.Top))
+ _math_matrix_analyse( ctx->ProjectionMatrixStack.Top );
+
+ /* restore clip planes */
+ for (i = 0; i < MAX_CLIP_PLANES; i++) {
+ const GLuint mask = 1 << 1;
+ const GLfloat *eyePlane = xform->EyeUserPlane[i];
+ COPY_4V(ctx->Transform.EyeUserPlane[i], eyePlane);
+ if (xform->ClipPlanesEnabled & mask) {
+ _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_TRUE);
+ }
+ else {
+ _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_FALSE);
+ }
+ if (ctx->Driver.ClipPlane)
+ ctx->Driver.ClipPlane( ctx, GL_CLIP_PLANE0 + i, eyePlane );
+ }
+
+ /* normalize/rescale */
+ if (xform->Normalize != ctx->Transform.Normalize)
+ _mesa_set_enable(ctx, GL_NORMALIZE,ctx->Transform.Normalize);
+ if (xform->RescaleNormals != ctx->Transform.RescaleNormals)
+ _mesa_set_enable(ctx, GL_RESCALE_NORMAL_EXT,
+ ctx->Transform.RescaleNormals);
+ }
+ break;
+ case GL_TEXTURE_BIT:
+ /* Take care of texture object reference counters */
+ {
+ const struct gl_texture_attrib *texture;
+ texture = (const struct gl_texture_attrib *) attr->data;
+ pop_texture_group(ctx, texture);
+ ctx->NewState |= _NEW_TEXTURE;
+ }
+ break;
+ case GL_VIEWPORT_BIT:
+ {
+ const struct gl_viewport_attrib *vp;
+ vp = (const struct gl_viewport_attrib *) attr->data;
+ _mesa_Viewport(vp->X, vp->Y, vp->Width, vp->Height);
+ _mesa_DepthRange(vp->Near, vp->Far);
+ }
+ break;
+ case GL_MULTISAMPLE_BIT_ARB:
+ {
+ const struct gl_multisample_attrib *ms;
+ ms = (const struct gl_multisample_attrib *) attr->data;
+ _mesa_SampleCoverageARB(ms->SampleCoverageValue,
+ ms->SampleCoverageInvert);
+ }
+ break;
+
+ default:
+ _mesa_problem( ctx, "Bad attrib flag in PopAttrib");
+ break;
+ }
+
+ next = attr->next;
+ FREE( attr->data );
+ FREE( attr );
+ attr = next;
+ }
+}
+
+
+/**
+ * Helper for incrementing/decrementing vertex buffer object reference
+ * counts when pushing/popping the GL_CLIENT_VERTEX_ARRAY_BIT attribute group.
+ */
+static void
+adjust_buffer_object_ref_counts(struct gl_array_attrib *array, GLint step)
+{
+ GLuint i;
+ array->Vertex.BufferObj->RefCount += step;
+ array->Normal.BufferObj->RefCount += step;
+ array->Color.BufferObj->RefCount += step;
+ array->SecondaryColor.BufferObj->RefCount += step;
+ array->FogCoord.BufferObj->RefCount += step;
+ array->Index.BufferObj->RefCount += step;
+ array->EdgeFlag.BufferObj->RefCount += step;
+ for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++)
+ array->TexCoord[i].BufferObj->RefCount += step;
+ for (i = 0; i < VERT_ATTRIB_MAX; i++)
+ array->VertexAttrib[i].BufferObj->RefCount += step;
+
+ array->ArrayBufferObj->RefCount += step;
+ array->ElementArrayBufferObj->RefCount += step;
+}
+
+
+#define GL_CLIENT_PACK_BIT (1<<20)
+#define GL_CLIENT_UNPACK_BIT (1<<21)
+
+
+void GLAPIENTRY
+_mesa_PushClientAttrib(GLbitfield mask)
+{
+ struct gl_attrib_node *newnode;
+ struct gl_attrib_node *head;
+
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (ctx->ClientAttribStackDepth >= MAX_CLIENT_ATTRIB_STACK_DEPTH) {
+ _mesa_error( ctx, GL_STACK_OVERFLOW, "glPushClientAttrib" );
+ return;
+ }
+
+ /* Build linked list of attribute nodes which save all attribute */
+ /* groups specified by the mask. */
+ head = NULL;
+
+ if (mask & GL_CLIENT_PIXEL_STORE_BIT) {
+ struct gl_pixelstore_attrib *attr;
+#if FEATURE_EXT_pixel_buffer_object
+ ctx->Pack.BufferObj->RefCount++;
+ ctx->Unpack.BufferObj->RefCount++;
+#endif
+ /* packing attribs */
+ attr = MALLOC_STRUCT( gl_pixelstore_attrib );
+ MEMCPY( attr, &ctx->Pack, sizeof(struct gl_pixelstore_attrib) );
+ newnode = new_attrib_node( GL_CLIENT_PACK_BIT );
+ newnode->data = attr;
+ newnode->next = head;
+ head = newnode;
+ /* unpacking attribs */
+ attr = MALLOC_STRUCT( gl_pixelstore_attrib );
+ MEMCPY( attr, &ctx->Unpack, sizeof(struct gl_pixelstore_attrib) );
+ newnode = new_attrib_node( GL_CLIENT_UNPACK_BIT );
+ newnode->data = attr;
+ newnode->next = head;
+ head = newnode;
+ }
+ if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) {
+ struct gl_array_attrib *attr;
+ attr = MALLOC_STRUCT( gl_array_attrib );
+ MEMCPY( attr, &ctx->Array, sizeof(struct gl_array_attrib) );
+ newnode = new_attrib_node( GL_CLIENT_VERTEX_ARRAY_BIT );
+ newnode->data = attr;
+ newnode->next = head;
+ head = newnode;
+ /* bump reference counts on buffer objects */
+ adjust_buffer_object_ref_counts(&ctx->Array, 1);
+ }
+
+ ctx->ClientAttribStack[ctx->ClientAttribStackDepth] = head;
+ ctx->ClientAttribStackDepth++;
+}
+
+
+
+
+void GLAPIENTRY
+_mesa_PopClientAttrib(void)
+{
+ struct gl_attrib_node *attr, *next;
+
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (ctx->ClientAttribStackDepth == 0) {
+ _mesa_error( ctx, GL_STACK_UNDERFLOW, "glPopClientAttrib" );
+ return;
+ }
+
+ ctx->ClientAttribStackDepth--;
+ attr = ctx->ClientAttribStack[ctx->ClientAttribStackDepth];
+
+ while (attr) {
+ switch (attr->kind) {
+ case GL_CLIENT_PACK_BIT:
+#if FEATURE_EXT_pixel_buffer_object
+ ctx->Pack.BufferObj->RefCount--;
+ if (ctx->Pack.BufferObj->RefCount <= 0) {
+ _mesa_remove_buffer_object( ctx, ctx->Pack.BufferObj );
+ (*ctx->Driver.DeleteBuffer)( ctx, ctx->Pack.BufferObj );
+ }
+#endif
+ MEMCPY( &ctx->Pack, attr->data,
+ sizeof(struct gl_pixelstore_attrib) );
+ ctx->NewState |= _NEW_PACKUNPACK;
+ break;
+ case GL_CLIENT_UNPACK_BIT:
+#if FEATURE_EXT_pixel_buffer_object
+ ctx->Unpack.BufferObj->RefCount--;
+ if (ctx->Unpack.BufferObj->RefCount <= 0) {
+ _mesa_remove_buffer_object( ctx, ctx->Unpack.BufferObj );
+ (*ctx->Driver.DeleteBuffer)( ctx, ctx->Unpack.BufferObj );
+ }
+#endif
+ MEMCPY( &ctx->Unpack, attr->data,
+ sizeof(struct gl_pixelstore_attrib) );
+ ctx->NewState |= _NEW_PACKUNPACK;
+ break;
+ case GL_CLIENT_VERTEX_ARRAY_BIT:
+ adjust_buffer_object_ref_counts(&ctx->Array, -1);
+ MEMCPY( &ctx->Array, attr->data,
+ sizeof(struct gl_array_attrib) );
+ /* decrement reference counts on buffer objects */
+ ctx->NewState |= _NEW_ARRAY;
+ break;
+ default:
+ _mesa_problem( ctx, "Bad attrib flag in PopClientAttrib");
+ break;
+ }
+
+ next = attr->next;
+ FREE( attr->data );
+ FREE( attr );
+ attr = next;
+ }
+}
+
+
+void _mesa_init_attrib( GLcontext *ctx )
+{
+ /* Renderer and client attribute stacks */
+ ctx->AttribStackDepth = 0;
+ ctx->ClientAttribStackDepth = 0;
+}
diff --git a/src/mesa/main/attrib.h b/src/mesa/main/attrib.h
new file mode 100644
index 00000000000..09d75196b23
--- /dev/null
+++ b/src/mesa/main/attrib.h
@@ -0,0 +1,68 @@
+/**
+ * \file attrib.h
+ * Attribute stacks.
+ *
+ * \if subset
+ * (No-op)
+ *
+ * \endif
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 5.1
+ *
+ * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+#ifndef ATTRIB_H
+#define ATTRIB_H
+
+
+#include "mtypes.h"
+
+
+#if _HAVE_FULL_GL
+
+extern void GLAPIENTRY
+_mesa_PushAttrib( GLbitfield mask );
+
+extern void GLAPIENTRY
+_mesa_PopAttrib( void );
+
+extern void GLAPIENTRY
+_mesa_PushClientAttrib( GLbitfield mask );
+
+extern void GLAPIENTRY
+_mesa_PopClientAttrib( void );
+
+extern void
+_mesa_init_attrib( GLcontext *ctx );
+
+#else
+
+/** No-op */
+#define _mesa_init_attrib( c ) ((void)0)
+
+#endif
+
+#endif
diff --git a/src/mesa/main/blend.c b/src/mesa/main/blend.c
new file mode 100644
index 00000000000..aebc70421ab
--- /dev/null
+++ b/src/mesa/main/blend.c
@@ -0,0 +1,582 @@
+/**
+ * \file blend.c
+ * Blending operations.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.1
+ *
+ * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+#include "glheader.h"
+#include "blend.h"
+#include "colormac.h"
+#include "context.h"
+#include "enums.h"
+#include "macros.h"
+#include "mtypes.h"
+
+
+/**
+ * Specify the blending operation.
+ *
+ * \param sfactor source factor operator.
+ * \param dfactor destination factor operator.
+ *
+ * \sa glBlendFunc, glBlendFuncSeparateEXT
+ *
+ * Swizzles the inputs and calls \c glBlendFuncSeparateEXT. This is done
+ * using the \c CurrentDispatch table in the context, so this same function
+ * can be used while compiling display lists. Therefore, there is no need
+ * for the display list code to save and restore this function.
+ */
+void GLAPIENTRY
+_mesa_BlendFunc( GLenum sfactor, GLenum dfactor )
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ (*ctx->CurrentDispatch->BlendFuncSeparateEXT)( sfactor, dfactor,
+ sfactor, dfactor );
+}
+
+
+/**
+ * Process GL_EXT_blend_func_separate().
+ *
+ * \param sfactorRGB RGB source factor operator.
+ * \param dfactorRGB RGB destination factor operator.
+ * \param sfactorA alpha source factor operator.
+ * \param dfactorA alpha destination factor operator.
+ *
+ * Verifies the parameters and updates gl_colorbuffer_attrib.
+ * On a change, flush the vertices and notify the driver via
+ * dd_function_table::BlendFuncSeparate.
+ */
+void GLAPIENTRY
+_mesa_BlendFuncSeparateEXT( GLenum sfactorRGB, GLenum dfactorRGB,
+ GLenum sfactorA, GLenum dfactorA )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glBlendFuncSeparate %s %s %s %s\n",
+ _mesa_lookup_enum_by_nr(sfactorRGB),
+ _mesa_lookup_enum_by_nr(dfactorRGB),
+ _mesa_lookup_enum_by_nr(sfactorA),
+ _mesa_lookup_enum_by_nr(dfactorA));
+
+ switch (sfactorRGB) {
+ case GL_SRC_COLOR:
+ case GL_ONE_MINUS_SRC_COLOR:
+ if (!ctx->Extensions.NV_blend_square) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (sfactorRGB)");
+ return;
+ }
+ /* fall-through */
+ case GL_ZERO:
+ case GL_ONE:
+ case GL_DST_COLOR:
+ case GL_ONE_MINUS_DST_COLOR:
+ case GL_SRC_ALPHA:
+ case GL_ONE_MINUS_SRC_ALPHA:
+ case GL_DST_ALPHA:
+ case GL_ONE_MINUS_DST_ALPHA:
+ case GL_SRC_ALPHA_SATURATE:
+ case GL_CONSTANT_COLOR:
+ case GL_ONE_MINUS_CONSTANT_COLOR:
+ case GL_CONSTANT_ALPHA:
+ case GL_ONE_MINUS_CONSTANT_ALPHA:
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (sfactorRGB)");
+ return;
+ }
+
+ switch (dfactorRGB) {
+ case GL_DST_COLOR:
+ case GL_ONE_MINUS_DST_COLOR:
+ if (!ctx->Extensions.NV_blend_square) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (dfactorRGB)");
+ return;
+ }
+ /* fall-through */
+ case GL_ZERO:
+ case GL_ONE:
+ case GL_SRC_COLOR:
+ case GL_ONE_MINUS_SRC_COLOR:
+ case GL_SRC_ALPHA:
+ case GL_ONE_MINUS_SRC_ALPHA:
+ case GL_DST_ALPHA:
+ case GL_ONE_MINUS_DST_ALPHA:
+ case GL_CONSTANT_COLOR:
+ case GL_ONE_MINUS_CONSTANT_COLOR:
+ case GL_CONSTANT_ALPHA:
+ case GL_ONE_MINUS_CONSTANT_ALPHA:
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (dfactorRGB)");
+ return;
+ }
+
+ switch (sfactorA) {
+ case GL_SRC_COLOR:
+ case GL_ONE_MINUS_SRC_COLOR:
+ if (!ctx->Extensions.NV_blend_square) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (sfactorA)");
+ return;
+ }
+ /* fall-through */
+ case GL_ZERO:
+ case GL_ONE:
+ case GL_DST_COLOR:
+ case GL_ONE_MINUS_DST_COLOR:
+ case GL_SRC_ALPHA:
+ case GL_ONE_MINUS_SRC_ALPHA:
+ case GL_DST_ALPHA:
+ case GL_ONE_MINUS_DST_ALPHA:
+ case GL_SRC_ALPHA_SATURATE:
+ case GL_CONSTANT_COLOR:
+ case GL_ONE_MINUS_CONSTANT_COLOR:
+ case GL_CONSTANT_ALPHA:
+ case GL_ONE_MINUS_CONSTANT_ALPHA:
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (sfactorA)");
+ return;
+ }
+
+ switch (dfactorA) {
+ case GL_DST_COLOR:
+ case GL_ONE_MINUS_DST_COLOR:
+ if (!ctx->Extensions.NV_blend_square) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (dfactorA)");
+ return;
+ }
+ /* fall-through */
+ case GL_ZERO:
+ case GL_ONE:
+ case GL_SRC_COLOR:
+ case GL_ONE_MINUS_SRC_COLOR:
+ case GL_SRC_ALPHA:
+ case GL_ONE_MINUS_SRC_ALPHA:
+ case GL_DST_ALPHA:
+ case GL_ONE_MINUS_DST_ALPHA:
+ case GL_CONSTANT_COLOR:
+ case GL_ONE_MINUS_CONSTANT_COLOR:
+ case GL_CONSTANT_ALPHA:
+ case GL_ONE_MINUS_CONSTANT_ALPHA:
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (dfactorA)" );
+ return;
+ }
+
+ if (ctx->Color.BlendSrcRGB == sfactorRGB &&
+ ctx->Color.BlendDstRGB == dfactorRGB &&
+ ctx->Color.BlendSrcA == sfactorA &&
+ ctx->Color.BlendDstA == dfactorA)
+ return;
+
+ FLUSH_VERTICES(ctx, _NEW_COLOR);
+
+ ctx->Color.BlendSrcRGB = sfactorRGB;
+ ctx->Color.BlendDstRGB = dfactorRGB;
+ ctx->Color.BlendSrcA = sfactorA;
+ ctx->Color.BlendDstA = dfactorA;
+
+ if (ctx->Driver.BlendFuncSeparate) {
+ (*ctx->Driver.BlendFuncSeparate)( ctx, sfactorRGB, dfactorRGB,
+ sfactorA, dfactorA );
+ }
+}
+
+
+#if _HAVE_FULL_GL
+
+static GLboolean
+_mesa_validate_blend_equation( GLcontext *ctx,
+ GLenum mode, GLboolean is_separate )
+{
+ switch (mode) {
+ case GL_FUNC_ADD:
+ break;
+ case GL_MIN:
+ case GL_MAX:
+ if (!ctx->Extensions.EXT_blend_minmax &&
+ !ctx->Extensions.ARB_imaging) {
+ return GL_FALSE;
+ }
+ break;
+ /* glBlendEquationSeparate cannot take GL_LOGIC_OP as a parameter.
+ */
+ case GL_LOGIC_OP:
+ if (!ctx->Extensions.EXT_blend_logic_op || is_separate) {
+ return GL_FALSE;
+ }
+ break;
+ case GL_FUNC_SUBTRACT:
+ case GL_FUNC_REVERSE_SUBTRACT:
+ if (!ctx->Extensions.EXT_blend_subtract &&
+ !ctx->Extensions.ARB_imaging) {
+ return GL_FALSE;
+ }
+ break;
+ default:
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+
+/* This is really an extension function! */
+void GLAPIENTRY
+_mesa_BlendEquation( GLenum mode )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glBlendEquation %s\n",
+ _mesa_lookup_enum_by_nr(mode));
+
+ if ( ! _mesa_validate_blend_equation( ctx, mode, GL_FALSE ) ) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquation");
+ return;
+ }
+
+ if ( (ctx->Color.BlendEquationRGB == mode) &&
+ (ctx->Color.BlendEquationA == mode) )
+ return;
+
+ FLUSH_VERTICES(ctx, _NEW_COLOR);
+ ctx->Color.BlendEquationRGB = mode;
+ ctx->Color.BlendEquationA = mode;
+
+ /* This is needed to support 1.1's RGB logic ops AND
+ * 1.0's blending logicops.
+ */
+ ctx->Color._LogicOpEnabled = (ctx->Color.ColorLogicOpEnabled ||
+ (ctx->Color.BlendEnabled &&
+ mode == GL_LOGIC_OP));
+
+ if (ctx->Driver.BlendEquationSeparate)
+ (*ctx->Driver.BlendEquationSeparate)( ctx, mode, mode );
+}
+
+
+void GLAPIENTRY
+_mesa_BlendEquationSeparateEXT( GLenum modeRGB, GLenum modeA )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glBlendEquationSeparateEXT %s %s\n",
+ _mesa_lookup_enum_by_nr(modeRGB),
+ _mesa_lookup_enum_by_nr(modeA));
+
+ if ( (modeRGB != modeA) && !ctx->Extensions.EXT_blend_equation_separate ) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glBlendEquationSeparateEXT not supported by driver");
+ return;
+ }
+
+ if ( ! _mesa_validate_blend_equation( ctx, modeRGB, GL_TRUE ) ) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquationSeparateEXT(modeRGB)");
+ return;
+ }
+
+ if ( ! _mesa_validate_blend_equation( ctx, modeA, GL_TRUE ) ) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquationSeparateEXT(modeA)");
+ return;
+ }
+
+
+ if ( (ctx->Color.BlendEquationRGB == modeRGB) &&
+ (ctx->Color.BlendEquationA == modeA) )
+ return;
+
+ FLUSH_VERTICES(ctx, _NEW_COLOR);
+ ctx->Color.BlendEquationRGB = modeRGB;
+ ctx->Color.BlendEquationA = modeA;
+
+ /* This is needed to support 1.1's RGB logic ops AND
+ * 1.0's blending logicops. This test is simplified over glBlendEquation
+ * because modeRGB cannot be GL_LOGIC_OP.
+ */
+ ctx->Color._LogicOpEnabled = (ctx->Color.ColorLogicOpEnabled);
+
+ if (ctx->Driver.BlendEquationSeparate)
+ (*ctx->Driver.BlendEquationSeparate)( ctx, modeRGB, modeA );
+}
+#endif
+
+
+/**
+ * Set the blending color.
+ *
+ * \param red red color component.
+ * \param green green color component.
+ * \param blue blue color component.
+ * \param alpha alpha color component.
+ *
+ * \sa glBlendColor().
+ *
+ * Clamps the parameters and updates gl_colorbuffer_attrib::BlendColor. On a
+ * change, flushes the vertices and notifies the driver via
+ * dd_function_table::BlendColor callback.
+ */
+void GLAPIENTRY
+_mesa_BlendColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha )
+{
+ GLfloat tmp[4];
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ tmp[0] = CLAMP( red, 0.0F, 1.0F );
+ tmp[1] = CLAMP( green, 0.0F, 1.0F );
+ tmp[2] = CLAMP( blue, 0.0F, 1.0F );
+ tmp[3] = CLAMP( alpha, 0.0F, 1.0F );
+
+ if (TEST_EQ_4V(tmp, ctx->Color.BlendColor))
+ return;
+
+ FLUSH_VERTICES(ctx, _NEW_COLOR);
+ COPY_4FV( ctx->Color.BlendColor, tmp );
+
+ if (ctx->Driver.BlendColor)
+ (*ctx->Driver.BlendColor)(ctx, tmp);
+}
+
+
+/**
+ * Specify the alpha test function.
+ *
+ * \param func alpha comparison function.
+ * \param ref reference value.
+ *
+ * Verifies the parameters and updates gl_colorbuffer_attrib.
+ * On a change, flushes the vertices and notifies the driver via
+ * dd_function_table::AlphaFunc callback.
+ */
+void GLAPIENTRY
+_mesa_AlphaFunc( GLenum func, GLclampf ref )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ switch (func) {
+ case GL_NEVER:
+ case GL_LESS:
+ case GL_EQUAL:
+ case GL_LEQUAL:
+ case GL_GREATER:
+ case GL_NOTEQUAL:
+ case GL_GEQUAL:
+ case GL_ALWAYS:
+ ref = CLAMP(ref, 0.0F, 1.0F);
+
+ if (ctx->Color.AlphaFunc == func && ctx->Color.AlphaRef == ref)
+ return; /* no change */
+
+ FLUSH_VERTICES(ctx, _NEW_COLOR);
+ ctx->Color.AlphaFunc = func;
+ ctx->Color.AlphaRef = ref;
+
+ if (ctx->Driver.AlphaFunc)
+ ctx->Driver.AlphaFunc(ctx, func, ref);
+ return;
+
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glAlphaFunc(func)" );
+ return;
+ }
+}
+
+
+/**
+ * Specify a logic pixel operation for color index rendering.
+ *
+ * \param opcode operation.
+ *
+ * Verifies that \p opcode is a valid enum and updates
+gl_colorbuffer_attrib::LogicOp.
+ * On a change, flushes the vertices and notifies the driver via the
+ * dd_function_table::LogicOpcode callback.
+ */
+void GLAPIENTRY
+_mesa_LogicOp( GLenum opcode )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ switch (opcode) {
+ case GL_CLEAR:
+ case GL_SET:
+ case GL_COPY:
+ case GL_COPY_INVERTED:
+ case GL_NOOP:
+ case GL_INVERT:
+ case GL_AND:
+ case GL_NAND:
+ case GL_OR:
+ case GL_NOR:
+ case GL_XOR:
+ case GL_EQUIV:
+ case GL_AND_REVERSE:
+ case GL_AND_INVERTED:
+ case GL_OR_REVERSE:
+ case GL_OR_INVERTED:
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glLogicOp" );
+ return;
+ }
+
+ if (ctx->Color.LogicOp == opcode)
+ return;
+
+ FLUSH_VERTICES(ctx, _NEW_COLOR);
+ ctx->Color.LogicOp = opcode;
+
+ if (ctx->Driver.LogicOpcode)
+ ctx->Driver.LogicOpcode( ctx, opcode );
+}
+
+#if _HAVE_FULL_GL
+void GLAPIENTRY
+_mesa_IndexMask( GLuint mask )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (ctx->Color.IndexMask == mask)
+ return;
+
+ FLUSH_VERTICES(ctx, _NEW_COLOR);
+ ctx->Color.IndexMask = mask;
+
+ if (ctx->Driver.IndexMask)
+ ctx->Driver.IndexMask( ctx, mask );
+}
+#endif
+
+
+/**
+ * Enable or disable writing of frame buffer color components.
+ *
+ * \param red whether to mask writing of the red color component.
+ * \param green whether to mask writing of the green color component.
+ * \param blue whether to mask writing of the blue color component.
+ * \param alpha whether to mask writing of the alpha color component.
+ *
+ * \sa glColorMask().
+ *
+ * Sets the appropriate value of gl_colorbuffer_attrib::ColorMask. On a
+ * change, flushes the vertices and notifies the driver via the
+ * dd_function_table::ColorMask callback.
+ */
+void GLAPIENTRY
+_mesa_ColorMask( GLboolean red, GLboolean green,
+ GLboolean blue, GLboolean alpha )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLubyte tmp[4];
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx, "glColorMask %d %d %d %d\n", red, green, blue, alpha);
+
+ /* Shouldn't have any information about channel depth in core mesa
+ * -- should probably store these as the native booleans:
+ */
+ tmp[RCOMP] = red ? 0xff : 0x0;
+ tmp[GCOMP] = green ? 0xff : 0x0;
+ tmp[BCOMP] = blue ? 0xff : 0x0;
+ tmp[ACOMP] = alpha ? 0xff : 0x0;
+
+ if (TEST_EQ_4UBV(tmp, ctx->Color.ColorMask))
+ return;
+
+ FLUSH_VERTICES(ctx, _NEW_COLOR);
+ COPY_4UBV(ctx->Color.ColorMask, tmp);
+
+ if (ctx->Driver.ColorMask)
+ ctx->Driver.ColorMask( ctx, red, green, blue, alpha );
+}
+
+
+/**********************************************************************/
+/** \name Initialization */
+/*@{*/
+
+/**
+ * Initialization of the context's Color attribute group.
+ *
+ * \param ctx GL context.
+ *
+ * Initializes the related fields in the context color attribute group,
+ * __GLcontextRec::Color.
+ */
+void _mesa_init_color( GLcontext * ctx )
+{
+ /* Color buffer group */
+ ctx->Color.IndexMask = ~0u;
+ ctx->Color.ColorMask[0] = 0xff;
+ ctx->Color.ColorMask[1] = 0xff;
+ ctx->Color.ColorMask[2] = 0xff;
+ ctx->Color.ColorMask[3] = 0xff;
+ ctx->Color.ClearIndex = 0;
+ ASSIGN_4V( ctx->Color.ClearColor, 0, 0, 0, 0 );
+ ctx->Color.AlphaEnabled = GL_FALSE;
+ ctx->Color.AlphaFunc = GL_ALWAYS;
+ ctx->Color.AlphaRef = 0;
+ ctx->Color.BlendEnabled = GL_FALSE;
+ ctx->Color.BlendSrcRGB = GL_ONE;
+ ctx->Color.BlendDstRGB = GL_ZERO;
+ ctx->Color.BlendSrcA = GL_ONE;
+ ctx->Color.BlendDstA = GL_ZERO;
+ ctx->Color.BlendEquationRGB = GL_FUNC_ADD;
+ ctx->Color.BlendEquationA = GL_FUNC_ADD;
+ ASSIGN_4V( ctx->Color.BlendColor, 0.0, 0.0, 0.0, 0.0 );
+ ctx->Color.IndexLogicOpEnabled = GL_FALSE;
+ ctx->Color.ColorLogicOpEnabled = GL_FALSE;
+ ctx->Color._LogicOpEnabled = GL_FALSE;
+ ctx->Color.LogicOp = GL_COPY;
+ ctx->Color.DitherFlag = GL_TRUE;
+
+ if (ctx->Visual.doubleBufferMode) {
+ ctx->Color.DrawBuffer[0] = GL_BACK;
+ }
+ else {
+ ctx->Color.DrawBuffer[0] = GL_FRONT;
+ }
+
+ ctx->Color.ClampFragmentColor = GL_FIXED_ONLY_ARB;
+ ctx->Color.ClampReadColor = GL_FIXED_ONLY_ARB;
+}
+
+/*@}*/
diff --git a/src/mesa/main/blend.h b/src/mesa/main/blend.h
new file mode 100644
index 00000000000..d6c03d903f4
--- /dev/null
+++ b/src/mesa/main/blend.h
@@ -0,0 +1,78 @@
+/**
+ * \file blend.h
+ * Blending functions operations.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.5
+ *
+ * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+#ifndef BLEND_H
+#define BLEND_H
+
+
+#include "mtypes.h"
+
+
+extern void GLAPIENTRY
+_mesa_BlendFunc( GLenum sfactor, GLenum dfactor );
+
+
+extern void GLAPIENTRY
+_mesa_BlendFuncSeparateEXT( GLenum sfactorRGB, GLenum dfactorRGB,
+ GLenum sfactorA, GLenum dfactorA );
+
+
+extern void GLAPIENTRY
+_mesa_BlendEquation( GLenum mode );
+
+
+extern void GLAPIENTRY
+_mesa_BlendEquationSeparateEXT( GLenum modeRGB, GLenum modeA );
+
+
+extern void GLAPIENTRY
+_mesa_BlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+
+
+extern void GLAPIENTRY
+_mesa_AlphaFunc( GLenum func, GLclampf ref );
+
+
+extern void GLAPIENTRY
+_mesa_LogicOp( GLenum opcode );
+
+
+extern void GLAPIENTRY
+_mesa_IndexMask( GLuint mask );
+
+extern void GLAPIENTRY
+_mesa_ColorMask( GLboolean red, GLboolean green,
+ GLboolean blue, GLboolean alpha );
+
+extern void
+_mesa_init_color( GLcontext * ctx );
+
+#endif
diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c
new file mode 100644
index 00000000000..03aec367c43
--- /dev/null
+++ b/src/mesa/main/bufferobj.c
@@ -0,0 +1,943 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.3
+ *
+ * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/**
+ * \file bufferobj.c
+ * \brief Functions for the GL_ARB_vertex_buffer_object extension.
+ * \author Brian Paul, Ian Romanick
+ */
+
+
+#include "glheader.h"
+#include "hash.h"
+#include "imports.h"
+#include "image.h"
+#include "context.h"
+#include "bufferobj.h"
+
+
+/**
+ * Get the buffer object bound to the specified target in a GL context.
+ *
+ * \param ctx GL context
+ * \param target Buffer object target to be retrieved. Currently this must
+ * be either \c GL_ARRAY_BUFFER or \c GL_ELEMENT_ARRAY_BUFFER.
+ * \param str Name of caller for logging errors.
+ * \return A pointer to the buffer object bound to \c target in the
+ * specified context or \c NULL if \c target is invalid or no
+ * buffer object is bound.
+ */
+static INLINE struct gl_buffer_object *
+buffer_object_get_target( GLcontext *ctx, GLenum target, const char * str )
+{
+ struct gl_buffer_object * bufObj = NULL;
+
+ switch (target) {
+ case GL_ARRAY_BUFFER_ARB:
+ bufObj = ctx->Array.ArrayBufferObj;
+ break;
+ case GL_ELEMENT_ARRAY_BUFFER_ARB:
+ bufObj = ctx->Array.ElementArrayBufferObj;
+ break;
+ case GL_PIXEL_PACK_BUFFER_EXT:
+ bufObj = ctx->Pack.BufferObj;
+ break;
+ case GL_PIXEL_UNPACK_BUFFER_EXT:
+ bufObj = ctx->Unpack.BufferObj;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "gl%s(target)", str);
+ return NULL;
+ }
+
+ if (bufObj->Name == 0)
+ return NULL;
+
+ return bufObj;
+}
+
+
+/**
+ * Tests the subdata range parameters and sets the GL error code for
+ * \c glBufferSubDataARB and \c glGetBufferSubDataARB.
+ *
+ * \param ctx GL context.
+ * \param target Buffer object target on which to operate.
+ * \param offset Offset of the first byte of the subdata range.
+ * \param size Size, in bytes, of the subdata range.
+ * \param str Name of caller for logging errors.
+ * \return A pointer to the buffer object bound to \c target in the
+ * specified context or \c NULL if any of the parameter or state
+ * conditions for \c glBufferSubDataARB or \c glGetBufferSubDataARB
+ * are invalid.
+ *
+ * \sa glBufferSubDataARB, glGetBufferSubDataARB
+ */
+static struct gl_buffer_object *
+buffer_object_subdata_range_good( GLcontext * ctx, GLenum target,
+ GLintptrARB offset, GLsizeiptrARB size,
+ const char * str )
+{
+ struct gl_buffer_object *bufObj;
+
+ if (size < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(size < 0)", str);
+ return NULL;
+ }
+
+ if (offset < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(offset < 0)", str);
+ return NULL;
+ }
+
+ bufObj = buffer_object_get_target( ctx, target, str );
+ if (!bufObj || bufObj->Name == 0) {
+ return NULL;
+ }
+
+ if ((GLuint) (offset + size) > bufObj->Size) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "%s(size + offset > buffer size)", str);
+ return NULL;
+ }
+
+ if (bufObj->Pointer) {
+ /* Buffer is currently mapped */
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s", str);
+ return NULL;
+ }
+
+ return bufObj;
+}
+
+
+/**
+ * Allocate and initialize a new buffer object.
+ *
+ * This function is intended to be called via
+ * \c dd_function_table::NewBufferObject.
+ */
+struct gl_buffer_object *
+_mesa_new_buffer_object( GLcontext *ctx, GLuint name, GLenum target )
+{
+ struct gl_buffer_object *obj;
+
+ (void) ctx;
+
+ obj = MALLOC_STRUCT(gl_buffer_object);
+ _mesa_initialize_buffer_object(obj, name, target);
+ return obj;
+}
+
+
+/**
+ * Delete a buffer object.
+ *
+ * This function is intended to be called via
+ * \c dd_function_table::DeleteBuffer.
+ */
+void
+_mesa_delete_buffer_object( GLcontext *ctx, struct gl_buffer_object *bufObj )
+{
+ (void) ctx;
+
+ if (bufObj->Data)
+ _mesa_free(bufObj->Data);
+ _mesa_free(bufObj);
+}
+
+
+/**
+ * Initialize a buffer object to default values.
+ */
+void
+_mesa_initialize_buffer_object( struct gl_buffer_object *obj,
+ GLuint name, GLenum target )
+{
+ (void) target;
+
+ _mesa_bzero(obj, sizeof(struct gl_buffer_object));
+ obj->RefCount = 1;
+ obj->Name = name;
+ obj->Usage = GL_STATIC_DRAW_ARB;
+ obj->Access = GL_READ_WRITE_ARB;
+}
+
+
+/**
+ * Add the given buffer object to the buffer object pool.
+ */
+void
+_mesa_save_buffer_object( GLcontext *ctx, struct gl_buffer_object *obj )
+{
+ if (obj->Name > 0) {
+ /* insert into hash table */
+ _mesa_HashInsert(ctx->Shared->BufferObjects, obj->Name, obj);
+ }
+}
+
+
+/**
+ * Remove the given buffer object from the buffer object pool.
+ * Do not deallocate the buffer object though.
+ */
+void
+_mesa_remove_buffer_object( GLcontext *ctx, struct gl_buffer_object *bufObj )
+{
+ if (bufObj->Name > 0) {
+ /* remove from hash table */
+ _mesa_HashRemove(ctx->Shared->BufferObjects, bufObj->Name);
+ }
+}
+
+
+/**
+ * Allocate space for and store data in a buffer object. Any data that was
+ * previously stored in the buffer object is lost. If \c data is \c NULL,
+ * memory will be allocated, but no copy will occur.
+ *
+ * This function is intended to be called via
+ * \c dd_function_table::BufferData. This function need not set GL error
+ * codes. The input parameters will have been tested before calling.
+ *
+ * \param ctx GL context.
+ * \param target Buffer object target on which to operate.
+ * \param size Size, in bytes, of the new data store.
+ * \param data Pointer to the data to store in the buffer object. This
+ * pointer may be \c NULL.
+ * \param usage Hints about how the data will be used.
+ * \param bufObj Object to be used.
+ *
+ * \sa glBufferDataARB, dd_function_table::BufferData.
+ */
+void
+_mesa_buffer_data( GLcontext *ctx, GLenum target, GLsizeiptrARB size,
+ const GLvoid * data, GLenum usage,
+ struct gl_buffer_object * bufObj )
+{
+ void * new_data;
+
+ (void) ctx; (void) target;
+
+ new_data = _mesa_realloc( bufObj->Data, bufObj->Size, size );
+ if (new_data) {
+ bufObj->Data = (GLubyte *) new_data;
+ bufObj->Size = size;
+ bufObj->Usage = usage;
+
+ if (data) {
+ _mesa_memcpy( bufObj->Data, data, size );
+ }
+ }
+}
+
+
+/**
+ * Replace data in a subrange of buffer object. If the data range
+ * specified by \c size + \c offset extends beyond the end of the buffer or
+ * if \c data is \c NULL, no copy is performed.
+ *
+ * This function is intended to be called by
+ * \c dd_function_table::BufferSubData. This function need not set GL error
+ * codes. The input parameters will have been tested before calling.
+ *
+ * \param ctx GL context.
+ * \param target Buffer object target on which to operate.
+ * \param offset Offset of the first byte to be modified.
+ * \param size Size, in bytes, of the data range.
+ * \param data Pointer to the data to store in the buffer object.
+ * \param bufObj Object to be used.
+ *
+ * \sa glBufferSubDataARB, dd_function_table::BufferSubData.
+ */
+void
+_mesa_buffer_subdata( GLcontext *ctx, GLenum target, GLintptrARB offset,
+ GLsizeiptrARB size, const GLvoid * data,
+ struct gl_buffer_object * bufObj )
+{
+ (void) ctx; (void) target;
+
+ if (bufObj->Data && ((GLuint) (size + offset) <= bufObj->Size)) {
+ _mesa_memcpy( (GLubyte *) bufObj->Data + offset, data, size );
+ }
+}
+
+
+/**
+ * Retrieve data from a subrange of buffer object. If the data range
+ * specified by \c size + \c offset extends beyond the end of the buffer or
+ * if \c data is \c NULL, no copy is performed.
+ *
+ * This function is intended to be called by
+ * \c dd_function_table::BufferGetSubData. This function need not set GL error
+ * codes. The input parameters will have been tested before calling.
+ *
+ * \param ctx GL context.
+ * \param target Buffer object target on which to operate.
+ * \param offset Offset of the first byte to be modified.
+ * \param size Size, in bytes, of the data range.
+ * \param data Pointer to the data to store in the buffer object.
+ * \param bufObj Object to be used.
+ *
+ * \sa glBufferGetSubDataARB, dd_function_table::GetBufferSubData.
+ */
+void
+_mesa_buffer_get_subdata( GLcontext *ctx, GLenum target, GLintptrARB offset,
+ GLsizeiptrARB size, GLvoid * data,
+ struct gl_buffer_object * bufObj )
+{
+ (void) ctx; (void) target;
+
+ if (bufObj->Data && ((GLsizeiptrARB) (size + offset) <= bufObj->Size)) {
+ _mesa_memcpy( data, (GLubyte *) bufObj->Data + offset, size );
+ }
+}
+
+
+/**
+ * Fallback function called via ctx->Driver.MapBuffer().
+ * Hardware drivers that really implement buffer objects should never use
+ * function.
+ *
+ * The input parameters will have been already tested for errors.
+ *
+ * \param ctx GL context.
+ * \param target Buffer object target on which to operate.
+ * \param access Information about how the buffer will be accessed.
+ * \param bufObj Object to be mapped.
+ * \return A pointer to the object's internal data store that can be accessed
+ * by the processor
+ *
+ * \sa glMapBufferARB, dd_function_table::MapBuffer
+ */
+void *
+_mesa_buffer_map( GLcontext *ctx, GLenum target, GLenum access,
+ struct gl_buffer_object *bufObj )
+{
+ (void) ctx;
+ (void) target;
+ (void) access;
+ ASSERT(!bufObj->OnCard);
+ /* Just return a direct pointer to the data */
+ if (bufObj->Pointer) {
+ /* already mapped! */
+ return NULL;
+ }
+ bufObj->Pointer = bufObj->Data;
+ return bufObj->Pointer;
+}
+
+
+/**
+ * Fallback function called via ctx->Driver.MapBuffer().
+ * Hardware drivers that really implement buffer objects should never use
+ * function.
+ *
+ * The input parameters will have been already tested for errors.
+ *
+ * \sa glUnmapBufferARB, dd_function_table::UnmapBuffer
+ */
+GLboolean
+_mesa_buffer_unmap( GLcontext *ctx, GLenum target,
+ struct gl_buffer_object *bufObj )
+{
+ (void) ctx;
+ (void) target;
+ ASSERT(!bufObj->OnCard);
+ /* XXX we might assert here that bufObj->Pointer is non-null */
+ bufObj->Pointer = NULL;
+ return GL_TRUE;
+}
+
+
+/**
+ * Initialize the state associated with buffer objects
+ */
+void
+_mesa_init_buffer_objects( GLcontext *ctx )
+{
+ GLuint i;
+
+ /* Allocate the default buffer object and set refcount so high that
+ * it never gets deleted.
+ */
+ ctx->Array.NullBufferObj = _mesa_new_buffer_object(ctx, 0, 0);
+ if (ctx->Array.NullBufferObj)
+ ctx->Array.NullBufferObj->RefCount = 1000;
+
+ ctx->Array.ArrayBufferObj = ctx->Array.NullBufferObj;
+ ctx->Array.ElementArrayBufferObj = ctx->Array.NullBufferObj;
+
+ /* Vertex array buffers */
+ ctx->Array.Vertex.BufferObj = ctx->Array.NullBufferObj;
+ ctx->Array.Normal.BufferObj = ctx->Array.NullBufferObj;
+ ctx->Array.Color.BufferObj = ctx->Array.NullBufferObj;
+ ctx->Array.SecondaryColor.BufferObj = ctx->Array.NullBufferObj;
+ ctx->Array.FogCoord.BufferObj = ctx->Array.NullBufferObj;
+ ctx->Array.Index.BufferObj = ctx->Array.NullBufferObj;
+ for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
+ ctx->Array.TexCoord[i].BufferObj = ctx->Array.NullBufferObj;
+ }
+ ctx->Array.EdgeFlag.BufferObj = ctx->Array.NullBufferObj;
+ for (i = 0; i < VERT_ATTRIB_MAX; i++) {
+ ctx->Array.VertexAttrib[i].BufferObj = ctx->Array.NullBufferObj;
+ }
+}
+
+
+/**
+ * When we're about to read pixel data out of a PBO (via glDrawPixels,
+ * glTexImage, etc) or write data into a PBO (via glReadPixels,
+ * glGetTexImage, etc) we call this function to check that we're not
+ * going to read out of bounds.
+ *
+ * XXX This would also be a convenient time to check that the PBO isn't
+ * currently mapped. Whoever calls this function should check for that.
+ * Remember, we can't use a PBO when it's mapped!
+ *
+ * \param width width of image to read/write
+ * \param height height of image to read/write
+ * \param depth depth of image to read/write
+ * \param format format of image to read/write
+ * \param type datatype of image to read/write
+ * \param ptr the user-provided pointer/offset
+ * \return GL_TRUE if the PBO access is OK, GL_FALSE if the access would
+ * go out of bounds.
+ */
+GLboolean
+_mesa_validate_pbo_access(GLuint dimensions,
+ const struct gl_pixelstore_attrib *pack,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type, const GLvoid *ptr)
+{
+ GLvoid *start, *end;
+ const GLubyte *sizeAddr; /* buffer size, cast to a pointer */
+
+ ASSERT(pack->BufferObj->Name != 0);
+
+ if (pack->BufferObj->Size == 0)
+ /* no buffer! */
+ return GL_FALSE;
+
+ /* get address of first pixel we'll read */
+ start = _mesa_image_address(dimensions, pack, ptr, width, height,
+ format, type, 0, 0, 0);
+
+ /* get address just past the last pixel we'll read */
+ end = _mesa_image_address(dimensions, pack, ptr, width, height,
+ format, type, depth-1, height-1, width);
+
+
+ sizeAddr = ((const GLubyte *) 0) + pack->BufferObj->Size;
+
+ if ((const GLubyte *) start > sizeAddr) {
+ /* This will catch negative values / wrap-around */
+ return GL_FALSE;
+ }
+ if ((const GLubyte *) end > sizeAddr) {
+ /* Image read goes beyond end of buffer */
+ return GL_FALSE;
+ }
+
+ /* OK! */
+ return GL_TRUE;
+}
+
+
+
+
+/**********************************************************************/
+/* API Functions */
+/**********************************************************************/
+
+void GLAPIENTRY
+_mesa_BindBufferARB(GLenum target, GLuint buffer)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_buffer_object *oldBufObj;
+ struct gl_buffer_object *newBufObj = NULL;
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ oldBufObj = buffer_object_get_target( ctx, target, "BindBufferARB" );
+ if (oldBufObj && oldBufObj->Name == buffer)
+ return; /* rebinding the same buffer object- no change */
+
+ /*
+ * Get pointer to new buffer object (newBufObj)
+ */
+ if (buffer == 0) {
+ /* The spec says there's not a buffer object named 0, but we use
+ * one internally because it simplifies things.
+ */
+ newBufObj = ctx->Array.NullBufferObj;
+ }
+ else {
+ /* non-default buffer object */
+ const struct _mesa_HashTable *hash = ctx->Shared->BufferObjects;
+ newBufObj = (struct gl_buffer_object *) _mesa_HashLookup(hash, buffer);
+ if (!newBufObj) {
+ /* if this is a new buffer object id, allocate a buffer object now */
+ newBufObj = (*ctx->Driver.NewBufferObject)(ctx, buffer, target);
+ if (!newBufObj) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindBufferARB");
+ return;
+ }
+ _mesa_save_buffer_object(ctx, newBufObj);
+ }
+ newBufObj->RefCount++;
+ }
+
+ switch (target) {
+ case GL_ARRAY_BUFFER_ARB:
+ ctx->Array.ArrayBufferObj = newBufObj;
+ break;
+ case GL_ELEMENT_ARRAY_BUFFER_ARB:
+ ctx->Array.ElementArrayBufferObj = newBufObj;
+ break;
+ case GL_PIXEL_PACK_BUFFER_EXT:
+ ctx->Pack.BufferObj = newBufObj;
+ break;
+ case GL_PIXEL_UNPACK_BUFFER_EXT:
+ ctx->Unpack.BufferObj = newBufObj;
+ break;
+ default:
+ _mesa_problem(ctx, "Bad target in _mesa_BindBufferARB");
+ return;
+ }
+
+ /* Pass BindBuffer call to device driver */
+ if (ctx->Driver.BindBuffer && newBufObj)
+ (*ctx->Driver.BindBuffer)( ctx, target, newBufObj );
+
+ if (oldBufObj) {
+ oldBufObj->RefCount--;
+ assert(oldBufObj->RefCount >= 0);
+ if (oldBufObj->RefCount == 0) {
+ assert(oldBufObj->Name != 0);
+ ASSERT(ctx->Driver.DeleteBuffer);
+ ctx->Driver.DeleteBuffer( ctx, oldBufObj );
+ }
+ }
+}
+
+
+/**
+ * Delete a set of buffer objects.
+ *
+ * \param n Number of buffer objects to delete.
+ * \param ids Array of \c n buffer object IDs.
+ */
+void GLAPIENTRY
+_mesa_DeleteBuffersARB(GLsizei n, const GLuint *ids)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLsizei i;
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (n < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteBuffersARB(n)");
+ return;
+ }
+
+ _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
+
+ for (i = 0; i < n; i++) {
+ if (ids[i] != 0) {
+ struct gl_buffer_object *bufObj = (struct gl_buffer_object *)
+ _mesa_HashLookup(ctx->Shared->BufferObjects, ids[i]);
+ if (bufObj) {
+ /* unbind any vertex pointers bound to this buffer */
+ GLuint j;
+
+ ASSERT(bufObj->Name == ids[i]);
+
+ if (ctx->Array.Vertex.BufferObj == bufObj) {
+ bufObj->RefCount--;
+ ctx->Array.Vertex.BufferObj = ctx->Array.NullBufferObj;
+ ctx->Array.NullBufferObj->RefCount++;
+ }
+ if (ctx->Array.Normal.BufferObj == bufObj) {
+ bufObj->RefCount--;
+ ctx->Array.Normal.BufferObj = ctx->Array.NullBufferObj;
+ ctx->Array.NullBufferObj->RefCount++;
+ }
+ if (ctx->Array.Color.BufferObj == bufObj) {
+ bufObj->RefCount--;
+ ctx->Array.Color.BufferObj = ctx->Array.NullBufferObj;
+ ctx->Array.NullBufferObj->RefCount++;
+ }
+ if (ctx->Array.SecondaryColor.BufferObj == bufObj) {
+ bufObj->RefCount--;
+ ctx->Array.SecondaryColor.BufferObj = ctx->Array.NullBufferObj;
+ ctx->Array.NullBufferObj->RefCount++;
+ }
+ if (ctx->Array.FogCoord.BufferObj == bufObj) {
+ bufObj->RefCount--;
+ ctx->Array.FogCoord.BufferObj = ctx->Array.NullBufferObj;
+ ctx->Array.NullBufferObj->RefCount++;
+ }
+ if (ctx->Array.Index.BufferObj == bufObj) {
+ bufObj->RefCount--;
+ ctx->Array.Index.BufferObj = ctx->Array.NullBufferObj;
+ ctx->Array.NullBufferObj->RefCount++;
+ }
+ if (ctx->Array.EdgeFlag.BufferObj == bufObj) {
+ bufObj->RefCount--;
+ ctx->Array.EdgeFlag.BufferObj = ctx->Array.NullBufferObj;
+ ctx->Array.NullBufferObj->RefCount++;
+ }
+ for (j = 0; j < MAX_TEXTURE_UNITS; j++) {
+ if (ctx->Array.TexCoord[j].BufferObj == bufObj) {
+ bufObj->RefCount--;
+ ctx->Array.TexCoord[j].BufferObj = ctx->Array.NullBufferObj;
+ ctx->Array.NullBufferObj->RefCount++;
+ }
+ }
+ for (j = 0; j < VERT_ATTRIB_MAX; j++) {
+ if (ctx->Array.VertexAttrib[j].BufferObj == bufObj) {
+ bufObj->RefCount--;
+ ctx->Array.VertexAttrib[j].BufferObj = ctx->Array.NullBufferObj;
+ ctx->Array.NullBufferObj->RefCount++;
+ }
+ }
+
+ if (ctx->Array.ArrayBufferObj == bufObj) {
+ _mesa_BindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
+ }
+ if (ctx->Array.ElementArrayBufferObj == bufObj) {
+ _mesa_BindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, 0 );
+ }
+
+ if (ctx->Pack.BufferObj == bufObj) {
+ _mesa_BindBufferARB( GL_PIXEL_PACK_BUFFER_EXT, 0 );
+ }
+ if (ctx->Unpack.BufferObj == bufObj) {
+ _mesa_BindBufferARB( GL_PIXEL_UNPACK_BUFFER_EXT, 0 );
+ }
+
+ /* The ID is immediately freed for re-use */
+ _mesa_remove_buffer_object(ctx, bufObj);
+ bufObj->RefCount--;
+ if (bufObj->RefCount <= 0) {
+ ASSERT(ctx->Array.ArrayBufferObj != bufObj);
+ ASSERT(ctx->Array.ElementArrayBufferObj != bufObj);
+ ASSERT(ctx->Array.Vertex.BufferObj != bufObj);
+ ASSERT(ctx->Driver.DeleteBuffer);
+ ctx->Driver.DeleteBuffer(ctx, bufObj);
+ }
+ }
+ }
+ }
+
+ _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+}
+
+
+/**
+ * Generate a set of unique buffer object IDs and store them in \c buffer.
+ *
+ * \param n Number of IDs to generate.
+ * \param buffer Array of \c n locations to store the IDs.
+ */
+void GLAPIENTRY
+_mesa_GenBuffersARB(GLsizei n, GLuint *buffer)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLuint first;
+ GLint i;
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (n < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glGenBuffersARB");
+ return;
+ }
+
+ if (!buffer) {
+ return;
+ }
+
+ /*
+ * This must be atomic (generation and allocation of buffer object IDs)
+ */
+ _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
+
+ first = _mesa_HashFindFreeKeyBlock(ctx->Shared->BufferObjects, n);
+
+ /* Allocate new, empty buffer objects and return identifiers */
+ for (i = 0; i < n; i++) {
+ struct gl_buffer_object *bufObj;
+ GLuint name = first + i;
+ GLenum target = 0;
+ bufObj = (*ctx->Driver.NewBufferObject)( ctx, name, target );
+ if (!bufObj) {
+ _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenBuffersARB");
+ return;
+ }
+ _mesa_save_buffer_object(ctx, bufObj);
+ buffer[i] = first + i;
+ }
+
+ _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+}
+
+
+/**
+ * Determine if ID is the name of a buffer object.
+ *
+ * \param id ID of the potential buffer object.
+ * \return \c GL_TRUE if \c id is the name of a buffer object,
+ * \c GL_FALSE otherwise.
+ */
+GLboolean GLAPIENTRY
+_mesa_IsBufferARB(GLuint id)
+{
+ struct gl_buffer_object * bufObj;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
+
+ if (id == 0)
+ return GL_FALSE;
+
+ _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
+ bufObj = (struct gl_buffer_object *) _mesa_HashLookup(ctx->Shared->BufferObjects, id);
+ _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+
+ return bufObj ? GL_TRUE : GL_FALSE;
+}
+
+
+void GLAPIENTRY
+_mesa_BufferDataARB(GLenum target, GLsizeiptrARB size,
+ const GLvoid * data, GLenum usage)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_buffer_object *bufObj;
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (size < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glBufferDataARB(size < 0)");
+ return;
+ }
+
+ switch (usage) {
+ case GL_STREAM_DRAW_ARB:
+ case GL_STREAM_READ_ARB:
+ case GL_STREAM_COPY_ARB:
+ case GL_STATIC_DRAW_ARB:
+ case GL_STATIC_READ_ARB:
+ case GL_STATIC_COPY_ARB:
+ case GL_DYNAMIC_DRAW_ARB:
+ case GL_DYNAMIC_READ_ARB:
+ case GL_DYNAMIC_COPY_ARB:
+ /* OK */
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glBufferDataARB(usage)");
+ return;
+ }
+
+ bufObj = buffer_object_get_target( ctx, target, "BufferDataARB" );
+ if (!bufObj || bufObj->Name ==0) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glBufferDataARB" );
+ return;
+ }
+
+ if (bufObj->Pointer) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glBufferDataARB(buffer is mapped)" );
+ return;
+ }
+
+ ASSERT(ctx->Driver.BufferData);
+
+ /* Give the buffer object to the driver! <data> may be null! */
+ (*ctx->Driver.BufferData)( ctx, target, size, data, usage, bufObj );
+}
+
+
+void GLAPIENTRY
+_mesa_BufferSubDataARB(GLenum target, GLintptrARB offset,
+ GLsizeiptrARB size, const GLvoid * data)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_buffer_object *bufObj;
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ bufObj = buffer_object_subdata_range_good( ctx, target, offset, size,
+ "BufferSubDataARB" );
+ if (!bufObj) {
+ /* error already recorded */
+ return;
+ }
+
+ ASSERT(ctx->Driver.BufferSubData);
+ (*ctx->Driver.BufferSubData)( ctx, target, offset, size, data, bufObj );
+}
+
+
+void GLAPIENTRY
+_mesa_GetBufferSubDataARB(GLenum target, GLintptrARB offset,
+ GLsizeiptrARB size, void * data)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_buffer_object *bufObj;
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ bufObj = buffer_object_subdata_range_good( ctx, target, offset, size,
+ "GetBufferSubDataARB" );
+ if (!bufObj) {
+ /* error already recorded */
+ return;
+ }
+
+ ASSERT(ctx->Driver.GetBufferSubData);
+ (*ctx->Driver.GetBufferSubData)( ctx, target, offset, size, data, bufObj );
+}
+
+
+void * GLAPIENTRY
+_mesa_MapBufferARB(GLenum target, GLenum access)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_buffer_object * bufObj;
+ ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, NULL);
+
+ switch (access) {
+ case GL_READ_ONLY_ARB:
+ case GL_WRITE_ONLY_ARB:
+ case GL_READ_WRITE_ARB:
+ /* OK */
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glMapBufferARB(access)");
+ return NULL;
+ }
+
+ bufObj = buffer_object_get_target( ctx, target, "MapBufferARB" );
+ if (!bufObj || bufObj->Name == 0) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glMapBufferARB" );
+ return NULL;
+ }
+
+ if (bufObj->Pointer) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glMapBufferARB(already mapped)");
+ return NULL;
+ }
+
+ ASSERT(ctx->Driver.MapBuffer);
+ bufObj->Pointer = (*ctx->Driver.MapBuffer)( ctx, target, access, bufObj );
+ if (!bufObj->Pointer) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMapBufferARB(access)");
+ }
+
+ bufObj->Access = access;
+
+ return bufObj->Pointer;
+}
+
+
+GLboolean GLAPIENTRY
+_mesa_UnmapBufferARB(GLenum target)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_buffer_object *bufObj;
+ GLboolean status = GL_TRUE;
+ ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
+
+ bufObj = buffer_object_get_target( ctx, target, "UnmapBufferARB" );
+ if (!bufObj || bufObj->Name == 0) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glUnmapBufferARB" );
+ return GL_FALSE;
+ }
+
+ if (!bufObj->Pointer) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glUnmapBufferARB");
+ return GL_FALSE;
+ }
+
+ if (ctx->Driver.UnmapBuffer) {
+ status = (*ctx->Driver.UnmapBuffer)( ctx, target, bufObj );
+ }
+
+ bufObj->Access = GL_READ_WRITE_ARB; /* initial value, OK? */
+ bufObj->Pointer = NULL;
+
+ return status;
+}
+
+
+void GLAPIENTRY
+_mesa_GetBufferParameterivARB(GLenum target, GLenum pname, GLint *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_buffer_object *bufObj;
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ bufObj = buffer_object_get_target( ctx, target, "GetBufferParameterivARB" );
+ if (!bufObj || bufObj->Name == 0) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "GetBufferParameterivARB" );
+ return;
+ }
+
+ switch (pname) {
+ case GL_BUFFER_SIZE_ARB:
+ *params = (GLint) bufObj->Size;
+ break;
+ case GL_BUFFER_USAGE_ARB:
+ *params = bufObj->Usage;
+ break;
+ case GL_BUFFER_ACCESS_ARB:
+ *params = bufObj->Access;
+ break;
+ case GL_BUFFER_MAPPED_ARB:
+ *params = (bufObj->Pointer != NULL);
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetBufferParameterivARB(pname)");
+ return;
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_GetBufferPointervARB(GLenum target, GLenum pname, GLvoid **params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_buffer_object * bufObj;
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (pname != GL_BUFFER_MAP_POINTER_ARB) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetBufferPointervARB(pname)");
+ return;
+ }
+
+ bufObj = buffer_object_get_target( ctx, target, "GetBufferPointervARB" );
+ if (!bufObj || bufObj->Name == 0) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetBufferPointervARB" );
+ return;
+ }
+
+ *params = bufObj->Pointer;
+}
diff --git a/src/mesa/main/bufferobj.h b/src/mesa/main/bufferobj.h
new file mode 100644
index 00000000000..bc1005332ca
--- /dev/null
+++ b/src/mesa/main/bufferobj.h
@@ -0,0 +1,124 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.3
+ *
+ * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+#ifndef BUFFEROBJ_H
+#define BUFFEROBJ_H
+
+
+#include "context.h"
+
+
+/*
+ * Internal functions
+ */
+
+extern void
+_mesa_init_buffer_objects( GLcontext *ctx );
+
+extern struct gl_buffer_object *
+_mesa_new_buffer_object( GLcontext *ctx, GLuint name, GLenum target );
+
+extern void
+_mesa_delete_buffer_object( GLcontext *ctx, struct gl_buffer_object *bufObj );
+
+extern void
+_mesa_initialize_buffer_object( struct gl_buffer_object *obj,
+ GLuint name, GLenum target );
+
+extern void
+_mesa_save_buffer_object( GLcontext *ctx, struct gl_buffer_object *obj );
+
+extern void
+_mesa_remove_buffer_object( GLcontext *ctx, struct gl_buffer_object *bufObj );
+
+extern void
+_mesa_buffer_data( GLcontext *ctx, GLenum target, GLsizeiptrARB size,
+ const GLvoid * data, GLenum usage,
+ struct gl_buffer_object * bufObj );
+
+extern void
+_mesa_buffer_subdata( GLcontext *ctx, GLenum target, GLintptrARB offset,
+ GLsizeiptrARB size, const GLvoid * data,
+ struct gl_buffer_object * bufObj );
+
+extern void
+_mesa_buffer_get_subdata( GLcontext *ctx, GLenum target, GLintptrARB offset,
+ GLsizeiptrARB size, GLvoid * data,
+ struct gl_buffer_object * bufObj );
+
+extern void *
+_mesa_buffer_map( GLcontext *ctx, GLenum target, GLenum access,
+ struct gl_buffer_object * bufObj );
+
+extern GLboolean
+_mesa_buffer_unmap( GLcontext *ctx, GLenum target,
+ struct gl_buffer_object * bufObj );
+
+extern GLboolean
+_mesa_validate_pbo_access(GLuint dimensions,
+ const struct gl_pixelstore_attrib *pack,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type, const GLvoid *ptr);
+
+
+/*
+ * API functions
+ */
+
+extern void GLAPIENTRY
+_mesa_BindBufferARB(GLenum target, GLuint buffer);
+
+extern void GLAPIENTRY
+_mesa_DeleteBuffersARB(GLsizei n, const GLuint * buffer);
+
+extern void GLAPIENTRY
+_mesa_GenBuffersARB(GLsizei n, GLuint * buffer);
+
+extern GLboolean GLAPIENTRY
+_mesa_IsBufferARB(GLuint buffer);
+
+extern void GLAPIENTRY
+_mesa_BufferDataARB(GLenum target, GLsizeiptrARB size, const GLvoid * data, GLenum usage);
+
+extern void GLAPIENTRY
+_mesa_BufferSubDataARB(GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid * data);
+
+extern void GLAPIENTRY
+_mesa_GetBufferSubDataARB(GLenum target, GLintptrARB offset, GLsizeiptrARB size, void * data);
+
+extern void * GLAPIENTRY
+_mesa_MapBufferARB(GLenum target, GLenum access);
+
+extern GLboolean GLAPIENTRY
+_mesa_UnmapBufferARB(GLenum target);
+
+extern void GLAPIENTRY
+_mesa_GetBufferParameterivARB(GLenum target, GLenum pname, GLint *params);
+
+extern void GLAPIENTRY
+_mesa_GetBufferPointervARB(GLenum target, GLenum pname, GLvoid **params);
+
+#endif
diff --git a/src/mesa/main/buffers.c b/src/mesa/main/buffers.c
new file mode 100644
index 00000000000..0d5d838ca0c
--- /dev/null
+++ b/src/mesa/main/buffers.c
@@ -0,0 +1,753 @@
+/**
+ * \file buffers.c
+ * Frame buffer management.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include "glheader.h"
+#include "buffers.h"
+#include "colormac.h"
+#include "context.h"
+#include "enums.h"
+#include "fbobject.h"
+#include "state.h"
+
+
+#define BAD_MASK ~0u
+
+
+#if _HAVE_FULL_GL
+void GLAPIENTRY
+_mesa_ClearIndex( GLfloat c )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (ctx->Color.ClearIndex == (GLuint) c)
+ return;
+
+ FLUSH_VERTICES(ctx, _NEW_COLOR);
+ ctx->Color.ClearIndex = (GLuint) c;
+
+ if (!ctx->Visual.rgbMode && ctx->Driver.ClearIndex) {
+ /* it's OK to call glClearIndex in RGBA mode but it should be a NOP */
+ (*ctx->Driver.ClearIndex)( ctx, ctx->Color.ClearIndex );
+ }
+}
+#endif
+
+
+/**
+ * Specify the clear values for the color buffers.
+ *
+ * \param red red color component.
+ * \param green green color component.
+ * \param blue blue color component.
+ * \param alpha alpha component.
+ *
+ * \sa glClearColor().
+ *
+ * Clamps the parameters and updates gl_colorbuffer_attrib::ClearColor. On a
+ * change, flushes the vertices and notifies the driver via the
+ * dd_function_table::ClearColor callback.
+ */
+void GLAPIENTRY
+_mesa_ClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha )
+{
+ GLfloat tmp[4];
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ tmp[0] = CLAMP(red, 0.0F, 1.0F);
+ tmp[1] = CLAMP(green, 0.0F, 1.0F);
+ tmp[2] = CLAMP(blue, 0.0F, 1.0F);
+ tmp[3] = CLAMP(alpha, 0.0F, 1.0F);
+
+ if (TEST_EQ_4V(tmp, ctx->Color.ClearColor))
+ return; /* no change */
+
+ FLUSH_VERTICES(ctx, _NEW_COLOR);
+ COPY_4V(ctx->Color.ClearColor, tmp);
+
+ if (ctx->Visual.rgbMode && ctx->Driver.ClearColor) {
+ /* it's OK to call glClearColor in CI mode but it should be a NOP */
+ (*ctx->Driver.ClearColor)(ctx, ctx->Color.ClearColor);
+ }
+}
+
+
+/**
+ * Clear buffers.
+ *
+ * \param mask bit-mask indicating the buffers to be cleared.
+ *
+ * Flushes the vertices and verifies the parameter. If __GLcontextRec::NewState
+ * is set then calls _mesa_update_state() to update gl_frame_buffer::_Xmin,
+ * etc. If the rasterization mode is set to GL_RENDER then requests the driver
+ * to clear the buffers, via the dd_function_table::Clear callback.
+ */
+void GLAPIENTRY
+_mesa_Clear( GLbitfield mask )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx, "glClear 0x%x\n", mask);
+
+ if (mask & ~(GL_COLOR_BUFFER_BIT |
+ GL_DEPTH_BUFFER_BIT |
+ GL_STENCIL_BUFFER_BIT |
+ GL_ACCUM_BUFFER_BIT)) {
+ /* invalid bit set */
+ _mesa_error( ctx, GL_INVALID_VALUE, "glClear(0x%x)", mask);
+ return;
+ }
+
+ if (ctx->NewState) {
+ _mesa_update_state( ctx ); /* update _Xmin, etc */
+ }
+
+ if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
+ "glClear(incomplete framebuffer)");
+ return;
+ }
+
+ if (ctx->RenderMode == GL_RENDER) {
+ const GLint x = ctx->DrawBuffer->_Xmin;
+ const GLint y = ctx->DrawBuffer->_Ymin;
+ const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
+ const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
+ GLbitfield bufferMask;
+
+ /* don't clear depth buffer if depth writing disabled */
+ if (!ctx->Depth.Mask)
+ mask &= ~GL_DEPTH_BUFFER_BIT;
+
+ /* Build the bitmask to send to device driver's Clear function.
+ * Note that the GL_COLOR_BUFFER_BIT flag will expand to 0, 1, 2 or 4
+ * of the BUFFER_BIT_FRONT/BACK_LEFT/RIGHT flags, or one of the
+ * BUFFER_BIT_COLORn flags.
+ */
+ bufferMask = 0;
+ if (mask & GL_COLOR_BUFFER_BIT) {
+ bufferMask |= ctx->DrawBuffer->_ColorDrawBufferMask[0];
+ }
+
+ if ((mask & GL_DEPTH_BUFFER_BIT)
+ && ctx->DrawBuffer->Visual.haveDepthBuffer) {
+ bufferMask |= BUFFER_BIT_DEPTH;
+ }
+
+ if ((mask & GL_STENCIL_BUFFER_BIT)
+ && ctx->DrawBuffer->Visual.haveStencilBuffer) {
+ bufferMask |= BUFFER_BIT_STENCIL;
+ }
+
+ if ((mask & GL_ACCUM_BUFFER_BIT)
+ && ctx->DrawBuffer->Visual.haveAccumBuffer) {
+ bufferMask |= BUFFER_BIT_ACCUM;
+ }
+
+ ASSERT(ctx->Driver.Clear);
+ ctx->Driver.Clear( ctx, bufferMask, (GLboolean) !ctx->Scissor.Enabled,
+ x, y, width, height );
+ }
+}
+
+
+
+/**
+ * Return bitmask of BUFFER_BIT_* flags indicating which color buffers are
+ * available to the rendering context.
+ * This depends on the framebuffer we're writing to. For window system
+ * framebuffers we look at the framebuffer's visual. But for user-
+ * create framebuffers we look at the number of supported color attachments.
+ */
+static GLbitfield
+supported_buffer_bitmask(const GLcontext *ctx, GLuint framebufferID)
+{
+ GLbitfield mask = 0x0;
+ GLint i;
+
+ if (framebufferID > 0) {
+ /* A user-created renderbuffer */
+ ASSERT(ctx->Extensions.EXT_framebuffer_object);
+ for (i = 0; i < ctx->Const.MaxColorAttachments; i++) {
+ mask |= (BUFFER_BIT_COLOR0 << i);
+ }
+ }
+ else {
+ /* A window system renderbuffer */
+ mask = BUFFER_BIT_FRONT_LEFT; /* always have this */
+ if (ctx->Visual.stereoMode) {
+ mask |= BUFFER_BIT_FRONT_RIGHT;
+ if (ctx->Visual.doubleBufferMode) {
+ mask |= BUFFER_BIT_BACK_LEFT | BUFFER_BIT_BACK_RIGHT;
+ }
+ }
+ else if (ctx->Visual.doubleBufferMode) {
+ mask |= BUFFER_BIT_BACK_LEFT;
+ }
+
+ for (i = 0; i < ctx->Visual.numAuxBuffers; i++) {
+ mask |= (BUFFER_BIT_AUX0 << i);
+ }
+ }
+
+ return mask;
+}
+
+
+/**
+ * Helper routine used by glDrawBuffer and glDrawBuffersARB.
+ * Given a GLenum naming one or more color buffers (such as
+ * GL_FRONT_AND_BACK), return the corresponding bitmask of BUFFER_BIT_* flags.
+ */
+static GLbitfield
+draw_buffer_enum_to_bitmask(GLenum buffer)
+{
+ switch (buffer) {
+ case GL_NONE:
+ return 0;
+ case GL_FRONT:
+ return BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_FRONT_RIGHT;
+ case GL_BACK:
+ return BUFFER_BIT_BACK_LEFT | BUFFER_BIT_BACK_RIGHT;
+ case GL_RIGHT:
+ return BUFFER_BIT_FRONT_RIGHT | BUFFER_BIT_BACK_RIGHT;
+ case GL_FRONT_RIGHT:
+ return BUFFER_BIT_FRONT_RIGHT;
+ case GL_BACK_RIGHT:
+ return BUFFER_BIT_BACK_RIGHT;
+ case GL_BACK_LEFT:
+ return BUFFER_BIT_BACK_LEFT;
+ case GL_FRONT_AND_BACK:
+ return BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT
+ | BUFFER_BIT_FRONT_RIGHT | BUFFER_BIT_BACK_RIGHT;
+ case GL_LEFT:
+ return BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT;
+ case GL_FRONT_LEFT:
+ return BUFFER_BIT_FRONT_LEFT;
+ case GL_AUX0:
+ return BUFFER_BIT_AUX0;
+ case GL_AUX1:
+ return BUFFER_BIT_AUX1;
+ case GL_AUX2:
+ return BUFFER_BIT_AUX2;
+ case GL_AUX3:
+ return BUFFER_BIT_AUX3;
+ case GL_COLOR_ATTACHMENT0_EXT:
+ return BUFFER_BIT_COLOR0;
+ case GL_COLOR_ATTACHMENT1_EXT:
+ return BUFFER_BIT_COLOR1;
+ case GL_COLOR_ATTACHMENT2_EXT:
+ return BUFFER_BIT_COLOR2;
+ case GL_COLOR_ATTACHMENT3_EXT:
+ return BUFFER_BIT_COLOR3;
+ default:
+ /* error */
+ return BAD_MASK;
+ }
+}
+
+
+/**
+ * Helper routine used by glReadBuffer.
+ * Given a GLenum naming a color buffer, return the index of the corresponding
+ * renderbuffer (a BUFFER_* value).
+ * return -1 for an invalid buffer.
+ */
+static GLint
+read_buffer_enum_to_index(GLenum buffer)
+{
+ switch (buffer) {
+ case GL_FRONT:
+ return BUFFER_FRONT_LEFT;
+ case GL_BACK:
+ return BUFFER_BACK_LEFT;
+ case GL_RIGHT:
+ return BUFFER_FRONT_RIGHT;
+ case GL_FRONT_RIGHT:
+ return BUFFER_FRONT_RIGHT;
+ case GL_BACK_RIGHT:
+ return BUFFER_BACK_RIGHT;
+ case GL_BACK_LEFT:
+ return BUFFER_BACK_LEFT;
+ case GL_LEFT:
+ return BUFFER_FRONT_LEFT;
+ case GL_FRONT_LEFT:
+ return BUFFER_FRONT_LEFT;
+ case GL_AUX0:
+ return BUFFER_AUX0;
+ case GL_AUX1:
+ return BUFFER_AUX1;
+ case GL_AUX2:
+ return BUFFER_AUX2;
+ case GL_AUX3:
+ return BUFFER_AUX3;
+ case GL_COLOR_ATTACHMENT0_EXT:
+ return BUFFER_COLOR0;
+ case GL_COLOR_ATTACHMENT1_EXT:
+ return BUFFER_COLOR1;
+ case GL_COLOR_ATTACHMENT2_EXT:
+ return BUFFER_COLOR2;
+ case GL_COLOR_ATTACHMENT3_EXT:
+ return BUFFER_COLOR3;
+ default:
+ /* error */
+ return -1;
+ }
+}
+
+
+/**
+ * Called by glDrawBuffer().
+ * Specify which renderbuffer(s) to draw into for the first color output.
+ * <buffer> can name zero, one, two or four renderbuffers!
+ * \sa _mesa_DrawBuffersARB
+ *
+ * \param buffer buffer token such as GL_LEFT or GL_FRONT_AND_BACK, etc.
+ */
+void GLAPIENTRY
+_mesa_DrawBuffer(GLenum buffer)
+{
+ GLuint bufferID;
+ GLbitfield destMask;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* too complex... */
+
+ if (MESA_VERBOSE & VERBOSE_API) {
+ _mesa_debug(ctx, "glDrawBuffer %s\n", _mesa_lookup_enum_by_nr(buffer));
+ }
+
+ bufferID = ctx->DrawBuffer->Name;
+
+ if (buffer == GL_NONE) {
+ destMask = 0x0;
+ }
+ else {
+ const GLbitfield supportedMask = supported_buffer_bitmask(ctx, bufferID);
+ destMask = draw_buffer_enum_to_bitmask(buffer);
+ if (destMask == BAD_MASK) {
+ /* totally bogus buffer */
+ _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffer(buffer)");
+ return;
+ }
+ destMask &= supportedMask;
+ if (destMask == 0x0) {
+ /* none of the named color buffers exist! */
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffer(buffer)");
+ return;
+ }
+ }
+
+ /* if we get here, there's no error so set new state */
+ _mesa_drawbuffers(ctx, 1, &buffer, &destMask);
+}
+
+
+/**
+ * Called by glDrawBuffersARB; specifies the destination color renderbuffers
+ * for N fragment program color outputs.
+ * \sa _mesa_DrawBuffer
+ * \param n number of outputs
+ * \param buffers array [n] of renderbuffer names. Unlike glDrawBuffer, the
+ * names cannot specify more than one buffer. For example,
+ * GL_FRONT_AND_BACK is illegal.
+ */
+void GLAPIENTRY
+_mesa_DrawBuffersARB(GLsizei n, const GLenum *buffers)
+{
+ GLint output;
+ GLuint bufferID;
+ GLbitfield usedBufferMask, supportedMask;
+ GLbitfield destMask[MAX_DRAW_BUFFERS];
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (!ctx->Extensions.ARB_draw_buffers) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffersARB");
+ return;
+ }
+ if (n < 1 || n > (GLsizei) ctx->Const.MaxDrawBuffers) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glDrawBuffersARB(n)");
+ return;
+ }
+
+ bufferID = ctx->DrawBuffer->Name;
+
+ supportedMask = supported_buffer_bitmask(ctx, bufferID);
+ usedBufferMask = 0x0;
+
+ /* complicated error checking... */
+ for (output = 0; output < n; output++) {
+ if (buffers[output] == GL_NONE) {
+ destMask[output] = 0x0;
+ }
+ else {
+ destMask[output] = draw_buffer_enum_to_bitmask(buffers[output]);
+ if (destMask[output] == BAD_MASK
+ || _mesa_bitcount(destMask[output]) > 1) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffersARB(buffer)");
+ return;
+ }
+ destMask[output] &= supportedMask;
+ if (destMask[output] == 0) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glDrawBuffersARB(unsupported buffer)");
+ return;
+ }
+ if (destMask[output] & usedBufferMask) {
+ /* can't specify a dest buffer more than once! */
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glDrawBuffersARB(duplicated buffer)");
+ return;
+ }
+
+ /* update bitmask */
+ usedBufferMask |= destMask[output];
+ }
+ }
+
+ /* OK, if we get here, there were no errors so set the new state */
+ _mesa_drawbuffers(ctx, n, buffers, destMask);
+}
+
+
+/**
+ * Set color output state. Traditionally, there was only one color
+ * output, but fragment programs can now have several distinct color
+ * outputs (see GL_ARB_draw_buffers). This function sets the state
+ * for one such color output.
+ * \param ctx current context
+ * \param output which fragment program output
+ * \param buffer buffer to write to (like GL_LEFT)
+ * \param destMask BUFFER_* bitmask
+ * (like BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT).
+ */
+static void
+set_color_output(GLcontext *ctx, GLuint output, GLenum buffer,
+ GLbitfield destMask)
+{
+ struct gl_framebuffer *fb = ctx->DrawBuffer;
+
+ ASSERT(output < ctx->Const.MaxDrawBuffers);
+
+ fb->ColorDrawBuffer[output] = buffer;
+ fb->_ColorDrawBufferMask[output] = destMask;
+
+ if (fb->Name == 0) {
+ /* Set traditional state var */
+ ctx->Color.DrawBuffer[output] = buffer;
+ }
+
+ /* not really needed, will be set later */
+ fb->_NumColorDrawBuffers[output] = 0;
+}
+
+
+/**
+ * Helper routine used by _mesa_DrawBuffer, _mesa_DrawBuffersARB and
+ * _mesa_PopAttrib to set drawbuffer state.
+ * All error checking will have been done prior to calling this function
+ * so nothing should go wrong at this point.
+ * \param ctx current context
+ * \param n number of color outputs to set
+ * \param buffers array[n] of colorbuffer names, like GL_LEFT.
+ * \param destMask array[n] of BUFFER_* bitmasks which correspond to the
+ * colorbuffer names. (i.e. GL_FRONT_AND_BACK =>
+ * BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT).
+ */
+void
+_mesa_drawbuffers(GLcontext *ctx, GLsizei n, const GLenum *buffers,
+ const GLbitfield *destMask)
+{
+ GLbitfield mask[MAX_DRAW_BUFFERS];
+ GLint output;
+
+ if (!destMask) {
+ /* compute destMask values now */
+ const GLuint bufferID = ctx->DrawBuffer->Name;
+ const GLbitfield supportedMask = supported_buffer_bitmask(ctx, bufferID);
+ for (output = 0; output < n; output++) {
+ mask[output] = draw_buffer_enum_to_bitmask(buffers[output]);
+ ASSERT(mask[output] != BAD_MASK);
+ mask[output] &= supportedMask;
+ }
+ destMask = mask;
+ }
+
+ for (output = 0; output < n; output++) {
+ set_color_output(ctx, output, buffers[output], destMask[output]);
+ }
+
+ /* set remaining color outputs to NONE */
+ for (output = n; output < ctx->Const.MaxDrawBuffers; output++) {
+ set_color_output(ctx, output, GL_NONE, 0x0);
+ }
+
+ ctx->NewState |= _NEW_COLOR;
+
+ /*
+ * Call device driver function.
+ */
+ if (ctx->Driver.DrawBuffers)
+ ctx->Driver.DrawBuffers(ctx, n, buffers);
+ else if (ctx->Driver.DrawBuffer)
+ ctx->Driver.DrawBuffer(ctx, buffers[0]);
+}
+
+
+
+/**
+ * Called by glReadBuffer to set the source renderbuffer for reading pixels.
+ * \param mode color buffer such as GL_FRONT, GL_BACK, etc.
+ */
+void GLAPIENTRY
+_mesa_ReadBuffer(GLenum buffer)
+{
+ struct gl_framebuffer *fb;
+ GLbitfield supportedMask;
+ GLint srcBuffer;
+ GLuint bufferID;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ fb = ctx->ReadBuffer;
+ bufferID = fb->Name;
+
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx, "glReadBuffer %s\n", _mesa_lookup_enum_by_nr(buffer));
+
+ if (bufferID > 0 && buffer == GL_NONE) {
+ /* This is legal for user-created framebuffer objects */
+ srcBuffer = -1;
+ }
+ else {
+ /* general case / window-system framebuffer */
+ srcBuffer = read_buffer_enum_to_index(buffer);
+ if (srcBuffer == -1) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glReadBuffer(buffer=0x%x)", buffer);
+ return;
+ }
+ supportedMask = supported_buffer_bitmask(ctx, bufferID);
+ if (((1 << srcBuffer) & supportedMask) == 0) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glReadBuffer(buffer=0x%x)", buffer);
+ return;
+ }
+ }
+
+ if (bufferID == 0) {
+ ctx->Pixel.ReadBuffer = buffer;
+ }
+ fb->ColorReadBuffer = buffer;
+ fb->_ColorReadBufferIndex = srcBuffer;
+
+ ctx->NewState |= _NEW_PIXEL;
+
+ /*
+ * Call device driver function.
+ */
+ if (ctx->Driver.ReadBuffer)
+ (*ctx->Driver.ReadBuffer)(ctx, buffer);
+}
+
+
+#if _HAVE_FULL_GL
+
+/**
+ * GL_MESA_resize_buffers extension.
+ *
+ * When this function is called, we'll ask the window system how large
+ * the current window is. If it's a new size, we'll call the driver's
+ * ResizeBuffers function. The driver will then resize its color buffers
+ * as needed, and maybe call the swrast's routine for reallocating
+ * swrast-managed depth/stencil/accum/etc buffers.
+ * \note This function should only be called through the GL API, not
+ * from device drivers (as was done in the past).
+ */
+void GLAPIENTRY
+_mesa_ResizeBuffersMESA( void )
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx );
+
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx, "glResizeBuffersMESA\n");
+
+ if (ctx->WinSysDrawBuffer) {
+ GLuint newWidth, newHeight;
+ GLframebuffer *buffer = ctx->WinSysDrawBuffer;
+
+ assert(buffer->Name == 0);
+
+ /* ask device driver for size of output buffer */
+ ctx->Driver.GetBufferSize( buffer, &newWidth, &newHeight );
+
+ /* see if size of device driver's color buffer (window) has changed */
+ if (buffer->Width != newWidth || buffer->Height != newHeight) {
+ if (ctx->Driver.ResizeBuffers)
+ ctx->Driver.ResizeBuffers(ctx, buffer, newWidth, newHeight );
+ }
+ }
+
+ if (ctx->WinSysReadBuffer
+ && ctx->WinSysReadBuffer != ctx->WinSysDrawBuffer) {
+ GLuint newWidth, newHeight;
+ GLframebuffer *buffer = ctx->WinSysReadBuffer;
+
+ assert(buffer->Name == 0);
+
+ /* ask device driver for size of read buffer */
+ ctx->Driver.GetBufferSize( buffer, &newWidth, &newHeight );
+
+ /* see if size of device driver's color buffer (window) has changed */
+ if (buffer->Width != newWidth || buffer->Height != newHeight) {
+ if (ctx->Driver.ResizeBuffers)
+ ctx->Driver.ResizeBuffers(ctx, buffer, newWidth, newHeight );
+ }
+ }
+
+ ctx->NewState |= _NEW_BUFFERS; /* to update scissor / window bounds */
+}
+
+
+/*
+ * XXX move somewhere else someday?
+ */
+void GLAPIENTRY
+_mesa_SampleCoverageARB(GLclampf value, GLboolean invert)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (!ctx->Extensions.ARB_multisample) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleCoverageARB");
+ return;
+ }
+
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx );
+ ctx->Multisample.SampleCoverageValue = (GLfloat) CLAMP(value, 0.0, 1.0);
+ ctx->Multisample.SampleCoverageInvert = invert;
+ ctx->NewState |= _NEW_MULTISAMPLE;
+}
+
+#endif /* _HAVE_FULL_GL */
+
+
+
+/**
+ * Define the scissor box.
+ *
+ * \param x, y coordinates of the scissor box lower-left corner.
+ * \param width width of the scissor box.
+ * \param height height of the scissor box.
+ *
+ * \sa glScissor().
+ *
+ * Verifies the parameters and updates __GLcontextRec::Scissor. On a
+ * change flushes the vertices and notifies the driver via
+ * the dd_function_table::Scissor callback.
+ */
+void
+_mesa_set_scissor(GLcontext *ctx,
+ GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ if (x == ctx->Scissor.X &&
+ y == ctx->Scissor.Y &&
+ width == ctx->Scissor.Width &&
+ height == ctx->Scissor.Height)
+ return;
+
+ FLUSH_VERTICES(ctx, _NEW_SCISSOR);
+ ctx->Scissor.X = x;
+ ctx->Scissor.Y = y;
+ ctx->Scissor.Width = width;
+ ctx->Scissor.Height = height;
+
+ if (ctx->Driver.Scissor)
+ ctx->Driver.Scissor( ctx, x, y, width, height );
+}
+
+
+void GLAPIENTRY
+_mesa_Scissor( GLint x, GLint y, GLsizei width, GLsizei height )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (width < 0 || height < 0) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glScissor" );
+ return;
+ }
+
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx, "glScissor %d %d %d %d\n", x, y, width, height);
+
+ _mesa_set_scissor(ctx, x, y, width, height);
+}
+
+
+
+/**********************************************************************/
+/** \name Initialization */
+/*@{*/
+
+/**
+ * Initialize the context's scissor state.
+ * \param ctx the GL context.
+ */
+void
+_mesa_init_scissor(GLcontext *ctx)
+{
+ /* Scissor group */
+ ctx->Scissor.Enabled = GL_FALSE;
+ ctx->Scissor.X = 0;
+ ctx->Scissor.Y = 0;
+ ctx->Scissor.Width = 0;
+ ctx->Scissor.Height = 0;
+}
+
+
+/**
+ * Initialize the context's multisample state.
+ * \param ctx the GL context.
+ */
+void
+_mesa_init_multisample(GLcontext *ctx)
+{
+ ctx->Multisample.Enabled = GL_FALSE;
+ ctx->Multisample.SampleAlphaToCoverage = GL_FALSE;
+ ctx->Multisample.SampleAlphaToOne = GL_FALSE;
+ ctx->Multisample.SampleCoverage = GL_FALSE;
+ ctx->Multisample.SampleCoverageValue = 1.0;
+ ctx->Multisample.SampleCoverageInvert = GL_FALSE;
+}
+
+/*@}*/
diff --git a/src/mesa/main/buffers.h b/src/mesa/main/buffers.h
new file mode 100644
index 00000000000..77e9f81560e
--- /dev/null
+++ b/src/mesa/main/buffers.h
@@ -0,0 +1,81 @@
+/**
+ * \file buffers.h
+ * Frame buffer management functions declarations.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+#ifndef BUFFERS_H
+#define BUFFERS_H
+
+
+#include "mtypes.h"
+
+
+extern void GLAPIENTRY
+_mesa_ClearIndex( GLfloat c );
+
+extern void GLAPIENTRY
+_mesa_ClearColor( GLclampf red, GLclampf green,
+ GLclampf blue, GLclampf alpha );
+
+extern void GLAPIENTRY
+_mesa_Clear( GLbitfield mask );
+
+extern void GLAPIENTRY
+_mesa_DrawBuffer( GLenum mode );
+
+extern void GLAPIENTRY
+_mesa_DrawBuffersARB(GLsizei n, const GLenum *buffers);
+
+extern void
+_mesa_drawbuffers(GLcontext *ctx, GLsizei n, const GLenum *buffers,
+ const GLbitfield *destMask);
+
+extern void GLAPIENTRY
+_mesa_ReadBuffer( GLenum mode );
+
+extern void GLAPIENTRY
+_mesa_ResizeBuffersMESA( void );
+
+extern void GLAPIENTRY
+_mesa_Scissor( GLint x, GLint y, GLsizei width, GLsizei height );
+
+extern void GLAPIENTRY
+_mesa_SampleCoverageARB(GLclampf value, GLboolean invert);
+
+extern void
+_mesa_init_scissor(GLcontext *ctx);
+
+extern void
+_mesa_init_multisample(GLcontext *ctx);
+
+extern void
+_mesa_set_scissor(GLcontext *ctx,
+ GLint x, GLint y, GLsizei width, GLsizei height);
+
+#endif
diff --git a/src/mesa/main/clip.c b/src/mesa/main/clip.c
new file mode 100644
index 00000000000..43ef55ee3b5
--- /dev/null
+++ b/src/mesa/main/clip.c
@@ -0,0 +1,160 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.3
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include "glheader.h"
+#include "clip.h"
+#include "context.h"
+#include "macros.h"
+#include "mtypes.h"
+
+#include "math/m_xform.h"
+#include "math/m_matrix.h"
+
+
+
+/**********************************************************************/
+/* Get/Set User clip-planes. */
+/**********************************************************************/
+
+
+
+void GLAPIENTRY
+_mesa_ClipPlane( GLenum plane, const GLdouble *eq )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint p;
+ GLfloat equation[4];
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ p = (GLint) plane - (GLint) GL_CLIP_PLANE0;
+ if (p < 0 || p >= (GLint) ctx->Const.MaxClipPlanes) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glClipPlane" );
+ return;
+ }
+
+ equation[0] = (GLfloat) eq[0];
+ equation[1] = (GLfloat) eq[1];
+ equation[2] = (GLfloat) eq[2];
+ equation[3] = (GLfloat) eq[3];
+
+ /*
+ * The equation is transformed by the transpose of the inverse of the
+ * current modelview matrix and stored in the resulting eye coordinates.
+ *
+ * KW: Eqn is then transformed to the current clip space, where user
+ * clipping now takes place. The clip-space equations are recalculated
+ * whenever the projection matrix changes.
+ */
+ if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top))
+ _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
+
+ _mesa_transform_vector( equation, equation,
+ ctx->ModelviewMatrixStack.Top->inv );
+
+ if (TEST_EQ_4V(ctx->Transform.EyeUserPlane[p], equation))
+ return;
+
+ FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
+ COPY_4FV(ctx->Transform.EyeUserPlane[p], equation);
+
+ /* Update derived state. This state also depends on the projection
+ * matrix, and is recalculated on changes to the projection matrix by
+ * code in _mesa_update_state().
+ */
+ if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
+ if (_math_matrix_is_dirty(ctx->ProjectionMatrixStack.Top))
+ _math_matrix_analyse( ctx->ProjectionMatrixStack.Top );
+
+ _mesa_transform_vector( ctx->Transform._ClipUserPlane[p],
+ ctx->Transform.EyeUserPlane[p],
+ ctx->ProjectionMatrixStack.Top->inv );
+ }
+
+ if (ctx->Driver.ClipPlane)
+ ctx->Driver.ClipPlane( ctx, plane, equation );
+}
+
+
+void GLAPIENTRY
+_mesa_GetClipPlane( GLenum plane, GLdouble *equation )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint p;
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ p = (GLint) (plane - GL_CLIP_PLANE0);
+ if (p < 0 || p >= (GLint) ctx->Const.MaxClipPlanes) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetClipPlane" );
+ return;
+ }
+
+ equation[0] = (GLdouble) ctx->Transform.EyeUserPlane[p][0];
+ equation[1] = (GLdouble) ctx->Transform.EyeUserPlane[p][1];
+ equation[2] = (GLdouble) ctx->Transform.EyeUserPlane[p][2];
+ equation[3] = (GLdouble) ctx->Transform.EyeUserPlane[p][3];
+}
+
+void GLAPIENTRY
+_mesa_CullParameterfvEXT (GLenum cap, GLfloat *v)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ switch (cap) {
+ case GL_CULL_VERTEX_EYE_POSITION_EXT:
+ FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
+ COPY_4FV(ctx->Transform.CullEyePos, v);
+
+ _mesa_transform_vector( ctx->Transform.CullObjPos,
+ ctx->Transform.CullEyePos,
+ ctx->ModelviewMatrixStack.Top->inv );
+ break;
+
+ case GL_CULL_VERTEX_OBJECT_POSITION_EXT:
+ FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
+ COPY_4FV(ctx->Transform.CullObjPos, v);
+
+ _mesa_transform_vector( ctx->Transform.CullEyePos,
+ ctx->Transform.CullObjPos,
+ ctx->ModelviewMatrixStack.Top->m );
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glCullParameterfvEXT" );
+ }
+}
+
+void GLAPIENTRY
+_mesa_CullParameterdvEXT (GLenum cap, GLdouble *v)
+{
+ GLfloat f[4];
+
+ f[0] = (GLfloat)v[0];
+ f[1] = (GLfloat)v[1];
+ f[2] = (GLfloat)v[2];
+ f[3] = (GLfloat)v[3];
+
+ _mesa_CullParameterfvEXT(cap, f);
+}
+
diff --git a/src/mesa/main/clip.h b/src/mesa/main/clip.h
new file mode 100644
index 00000000000..d53afb45bdf
--- /dev/null
+++ b/src/mesa/main/clip.h
@@ -0,0 +1,49 @@
+/**
+ * \file clip.h
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.5
+ *
+ * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+#ifndef CLIP_H
+#define CLIP_H
+
+#include "mtypes.h"
+
+extern void GLAPIENTRY
+_mesa_ClipPlane( GLenum plane, const GLdouble *equation );
+
+extern void GLAPIENTRY
+_mesa_GetClipPlane( GLenum plane, GLdouble *equation );
+
+extern void GLAPIENTRY
+_mesa_CullParameterfvEXT (GLenum cap, GLfloat *v);
+
+extern void GLAPIENTRY
+_mesa_CullParameterdvEXT (GLenum cap, GLdouble *v);
+
+
+#endif
diff --git a/src/mesa/main/colormac.h b/src/mesa/main/colormac.h
new file mode 100644
index 00000000000..a19521fc85b
--- /dev/null
+++ b/src/mesa/main/colormac.h
@@ -0,0 +1,227 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.1
+ *
+ * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/**
+ * \file colormac.h
+ * Color-related macros
+ */
+
+
+#ifndef COLORMAC_H
+#define COLORMAC_H
+
+
+#include "imports.h"
+#include "config.h"
+#include "macros.h"
+
+
+/** \def BYTE_TO_CHAN
+ * Convert from GLbyte to GLchan */
+
+/** \def UBYTE_TO_CHAN
+ * Convert from GLubyte to GLchan */
+
+/** \def SHORT_TO_CHAN
+ * Convert from GLshort to GLchan */
+
+/** \def USHORT_TO_CHAN
+ * Convert from GLushort to GLchan */
+
+/** \def INT_TO_CHAN
+ * Convert from GLint to GLchan */
+
+/** \def UINT_TO_CHAN
+ * Convert from GLuint to GLchan */
+
+/** \def CHAN_TO_UBYTE
+ * Convert from GLchan to GLubyte */
+
+/** \def CHAN_TO_FLOAT
+ * Convert from GLchan to GLfloat */
+
+/** \def CLAMPED_FLOAT_TO_CHAN
+ * Convert from GLclampf to GLchan */
+
+/** \def UNCLAMPED_FLOAT_TO_CHAN
+ * Convert from GLfloat to GLchan */
+
+/** \def COPY_CHAN4
+ * Copy a GLchan[4] array */
+
+/** \def CHAN_PRODUCT
+ * Scaled product (usually approximated) between two GLchan arguments */
+
+#if CHAN_BITS == 8
+
+#define BYTE_TO_CHAN(b) ((b) < 0 ? 0 : (GLchan) (b))
+#define UBYTE_TO_CHAN(b) (b)
+#define SHORT_TO_CHAN(s) ((s) < 0 ? 0 : (GLchan) ((s) >> 7))
+#define USHORT_TO_CHAN(s) ((GLchan) ((s) >> 8))
+#define INT_TO_CHAN(i) ((i) < 0 ? 0 : (GLchan) ((i) >> 23))
+#define UINT_TO_CHAN(i) ((GLchan) ((i) >> 24))
+
+#define CHAN_TO_UBYTE(c) (c)
+#define CHAN_TO_FLOAT(c) UBYTE_TO_FLOAT(c)
+
+#define CLAMPED_FLOAT_TO_CHAN(c, f) CLAMPED_FLOAT_TO_UBYTE(c, f)
+#define UNCLAMPED_FLOAT_TO_CHAN(c, f) UNCLAMPED_FLOAT_TO_UBYTE(c, f)
+
+#define COPY_CHAN4(DST, SRC) COPY_4UBV(DST, SRC)
+
+#define CHAN_PRODUCT(a, b) ((GLubyte) (((GLint)(a) * ((GLint)(b) + 1)) >> 8))
+
+#elif CHAN_BITS == 16
+
+#define BYTE_TO_CHAN(b) ((b) < 0 ? 0 : (((GLchan) (b)) * 516))
+#define UBYTE_TO_CHAN(b) ((((GLchan) (b)) << 8) | ((GLchan) (b)))
+#define SHORT_TO_CHAN(s) ((s) < 0 ? 0 : (GLchan) (s))
+#define USHORT_TO_CHAN(s) (s)
+#define INT_TO_CHAN(i) ((i) < 0 ? 0 : (GLchan) ((i) >> 15))
+#define UINT_TO_CHAN(i) ((GLchan) ((i) >> 16))
+
+#define CHAN_TO_UBYTE(c) ((c) >> 8)
+#define CHAN_TO_FLOAT(c) ((GLfloat) ((c) * (1.0 / CHAN_MAXF)))
+
+#define CLAMPED_FLOAT_TO_CHAN(c, f) CLAMPED_FLOAT_TO_USHORT(c, f)
+#define UNCLAMPED_FLOAT_TO_CHAN(c, f) UNCLAMPED_FLOAT_TO_USHORT(c, f)
+
+#define COPY_CHAN4(DST, SRC) COPY_4V(DST, SRC)
+
+#define CHAN_PRODUCT(a, b) ((GLchan) ((((GLuint) (a)) * ((GLuint) (b))) / 65535))
+
+#elif CHAN_BITS == 32
+
+/* XXX floating-point color channels not fully thought-out */
+#define BYTE_TO_CHAN(b) ((GLfloat) ((b) * (1.0F / 127.0F)))
+#define UBYTE_TO_CHAN(b) ((GLfloat) ((b) * (1.0F / 255.0F)))
+#define SHORT_TO_CHAN(s) ((GLfloat) ((s) * (1.0F / 32767.0F)))
+#define USHORT_TO_CHAN(s) ((GLfloat) ((s) * (1.0F / 65535.0F)))
+#define INT_TO_CHAN(i) ((GLfloat) ((i) * (1.0F / 2147483647.0F)))
+#define UINT_TO_CHAN(i) ((GLfloat) ((i) * (1.0F / 4294967295.0F)))
+
+#define CHAN_TO_UBYTE(c) FLOAT_TO_UBYTE(c)
+#define CHAN_TO_FLOAT(c) (c)
+
+#define CLAMPED_FLOAT_TO_CHAN(c, f) c = (f)
+#define UNCLAMPED_FLOAT_TO_CHAN(c, f) c = (f)
+
+#define COPY_CHAN4(DST, SRC) COPY_4V(DST, SRC)
+
+#define CHAN_PRODUCT(a, b) ((a) * (b))
+
+#else
+
+#error unexpected CHAN_BITS size
+
+#endif
+
+
+/**
+ * Convert 3 channels at once.
+ *
+ * \param dst pointer to destination GLchan[3] array.
+ * \param f pointer to source GLfloat[3] array.
+ *
+ * \sa #UNCLAMPED_FLOAT_TO_CHAN.
+ */
+#define UNCLAMPED_FLOAT_TO_RGB_CHAN(dst, f) \
+do { \
+ UNCLAMPED_FLOAT_TO_CHAN(dst[0], f[0]); \
+ UNCLAMPED_FLOAT_TO_CHAN(dst[1], f[1]); \
+ UNCLAMPED_FLOAT_TO_CHAN(dst[2], f[2]); \
+} while (0)
+
+
+/**
+ * Convert 4 channels at once.
+ *
+ * \param dst pointer to destination GLchan[4] array.
+ * \param f pointer to source GLfloat[4] array.
+ *
+ * \sa #UNCLAMPED_FLOAT_TO_CHAN.
+ */
+#define UNCLAMPED_FLOAT_TO_RGBA_CHAN(dst, f) \
+do { \
+ UNCLAMPED_FLOAT_TO_CHAN(dst[0], f[0]); \
+ UNCLAMPED_FLOAT_TO_CHAN(dst[1], f[1]); \
+ UNCLAMPED_FLOAT_TO_CHAN(dst[2], f[2]); \
+ UNCLAMPED_FLOAT_TO_CHAN(dst[3], f[3]); \
+} while (0)
+
+
+
+/**
+ * \name Generic color packing macros. All inputs should be GLubytes.
+ *
+ * \todo We may move these into texstore.h at some point.
+ */
+/*@{*/
+
+#define PACK_COLOR_8888( R, G, B, A ) \
+ (((R) << 24) | ((G) << 16) | ((B) << 8) | (A))
+
+#define PACK_COLOR_8888_REV( R, G, B, A ) \
+ (((A) << 24) | ((B) << 16) | ((G) << 8) | (R))
+
+#define PACK_COLOR_888( R, G, B ) \
+ (((R) << 16) | ((G) << 8) | (B))
+
+#define PACK_COLOR_565( R, G, B ) \
+ ((((R) & 0xf8) << 8) | (((G) & 0xfc) << 3) | (((B) & 0xf8) >> 3))
+
+#define PACK_COLOR_565_REV( R, G, B ) \
+ (((R) & 0xf8) | ((G) & 0xe0) >> 5 | (((G) & 0x1c) << 11) | (((B) & 0xf8) << 5))
+
+#define PACK_COLOR_1555( A, B, G, R ) \
+ ((((B) & 0xf8) << 7) | (((G) & 0xf8) << 2) | (((R) & 0xf8) >> 3) | \
+ ((A) ? 0x8000 : 0))
+
+#define PACK_COLOR_1555_REV( A, B, G, R ) \
+ ((((B) & 0xf8) >> 1) | (((G) & 0xc0) >> 6) | (((G) & 0x38) << 10) | (((R) & 0xf8) << 5) | \
+ ((A) ? 0x80 : 0))
+
+#define PACK_COLOR_4444( R, G, B, A ) \
+ ((((R) & 0xf0) << 8) | (((G) & 0xf0) << 4) | ((B) & 0xf0) | ((A) >> 4))
+
+#define PACK_COLOR_4444_REV( R, G, B, A ) \
+ ((((B) & 0xf0) << 8) | (((A) & 0xf0) << 4) | ((R) & 0xf0) | ((G) >> 4))
+
+#define PACK_COLOR_88( L, A ) \
+ (((L) << 8) | (A))
+
+#define PACK_COLOR_88_REV( L, A ) \
+ (((A) << 8) | (L))
+
+#define PACK_COLOR_332( R, G, B ) \
+ (((R) & 0xe0) | (((G) & 0xe0) >> 3) | (((B) & 0xc0) >> 6))
+
+#define PACK_COLOR_233( B, G, R ) \
+ (((B) & 0xc0) | (((G) & 0xe0) >> 2) | (((R) & 0xe0) >> 5))
+
+/*@}*/
+
+
+#endif /* COLORMAC_H */
diff --git a/src/mesa/main/colortab.c b/src/mesa/main/colortab.c
new file mode 100644
index 00000000000..e2f95cf7f9b
--- /dev/null
+++ b/src/mesa/main/colortab.c
@@ -0,0 +1,1445 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include "glheader.h"
+#include "bufferobj.h"
+#include "colortab.h"
+#include "context.h"
+#include "image.h"
+#include "macros.h"
+#include "state.h"
+
+
+/*
+ * Given an internalFormat token passed to glColorTable,
+ * return the corresponding base format.
+ * Return -1 if invalid token.
+ */
+static GLint
+base_colortab_format( GLenum format )
+{
+ switch (format) {
+ case GL_ALPHA:
+ case GL_ALPHA4:
+ case GL_ALPHA8:
+ case GL_ALPHA12:
+ case GL_ALPHA16:
+ return GL_ALPHA;
+ case GL_LUMINANCE:
+ case GL_LUMINANCE4:
+ case GL_LUMINANCE8:
+ case GL_LUMINANCE12:
+ case GL_LUMINANCE16:
+ return GL_LUMINANCE;
+ case GL_LUMINANCE_ALPHA:
+ case GL_LUMINANCE4_ALPHA4:
+ case GL_LUMINANCE6_ALPHA2:
+ case GL_LUMINANCE8_ALPHA8:
+ case GL_LUMINANCE12_ALPHA4:
+ case GL_LUMINANCE12_ALPHA12:
+ case GL_LUMINANCE16_ALPHA16:
+ return GL_LUMINANCE_ALPHA;
+ case GL_INTENSITY:
+ case GL_INTENSITY4:
+ case GL_INTENSITY8:
+ case GL_INTENSITY12:
+ case GL_INTENSITY16:
+ return GL_INTENSITY;
+ case GL_RGB:
+ case GL_R3_G3_B2:
+ case GL_RGB4:
+ case GL_RGB5:
+ case GL_RGB8:
+ case GL_RGB10:
+ case GL_RGB12:
+ case GL_RGB16:
+ return GL_RGB;
+ case GL_RGBA:
+ case GL_RGBA2:
+ case GL_RGBA4:
+ case GL_RGB5_A1:
+ case GL_RGBA8:
+ case GL_RGB10_A2:
+ case GL_RGBA12:
+ case GL_RGBA16:
+ return GL_RGBA;
+ default:
+ return -1; /* error */
+ }
+}
+
+
+
+/*
+ * Examine table's format and set the component sizes accordingly.
+ */
+static void
+set_component_sizes( struct gl_color_table *table )
+{
+ GLubyte sz;
+
+ switch (table->Type) {
+ case GL_UNSIGNED_BYTE:
+ sz = 8 * sizeof(GLubyte);
+ break;
+ case GL_UNSIGNED_SHORT:
+ sz = 8 * sizeof(GLushort);
+ break;
+ case GL_FLOAT:
+ /* Don't actually return 32 here since that causes the conformance
+ * tests to blow up. Conform thinks the component is an integer,
+ * not a float.
+ */
+ sz = 8; /** 8 * sizeof(GLfloat); **/
+ break;
+ default:
+ _mesa_problem(NULL, "bad color table type in set_component_sizes 0x%x", table->Type);
+ return;
+ }
+
+ switch (table->_BaseFormat) {
+ case GL_ALPHA:
+ table->RedSize = 0;
+ table->GreenSize = 0;
+ table->BlueSize = 0;
+ table->AlphaSize = sz;
+ table->IntensitySize = 0;
+ table->LuminanceSize = 0;
+ break;
+ case GL_LUMINANCE:
+ table->RedSize = 0;
+ table->GreenSize = 0;
+ table->BlueSize = 0;
+ table->AlphaSize = 0;
+ table->IntensitySize = 0;
+ table->LuminanceSize = sz;
+ break;
+ case GL_LUMINANCE_ALPHA:
+ table->RedSize = 0;
+ table->GreenSize = 0;
+ table->BlueSize = 0;
+ table->AlphaSize = sz;
+ table->IntensitySize = 0;
+ table->LuminanceSize = sz;
+ break;
+ case GL_INTENSITY:
+ table->RedSize = 0;
+ table->GreenSize = 0;
+ table->BlueSize = 0;
+ table->AlphaSize = 0;
+ table->IntensitySize = sz;
+ table->LuminanceSize = 0;
+ break;
+ case GL_RGB:
+ table->RedSize = sz;
+ table->GreenSize = sz;
+ table->BlueSize = sz;
+ table->AlphaSize = 0;
+ table->IntensitySize = 0;
+ table->LuminanceSize = 0;
+ break;
+ case GL_RGBA:
+ table->RedSize = sz;
+ table->GreenSize = sz;
+ table->BlueSize = sz;
+ table->AlphaSize = sz;
+ table->IntensitySize = 0;
+ table->LuminanceSize = 0;
+ break;
+ default:
+ _mesa_problem(NULL, "unexpected format in set_component_sizes");
+ }
+}
+
+
+
+/**
+ * Update/replace all or part of a color table. Helper function
+ * used by _mesa_ColorTable() and _mesa_ColorSubTable().
+ * The table->Table buffer should already be allocated.
+ * \param start first entry to update
+ * \param count number of entries to update
+ * \param format format of user-provided table data
+ * \param type datatype of user-provided table data
+ * \param data user-provided table data
+ * \param [rgba]Scale - RGBA scale factors
+ * \param [rgba]Bias - RGBA bias factors
+ */
+static void
+store_colortable_entries(GLcontext *ctx, struct gl_color_table *table,
+ GLsizei start, GLsizei count,
+ GLenum format, GLenum type, const GLvoid *data,
+ GLfloat rScale, GLfloat rBias,
+ GLfloat gScale, GLfloat gBias,
+ GLfloat bScale, GLfloat bBias,
+ GLfloat aScale, GLfloat aBias)
+{
+ if (ctx->Unpack.BufferObj->Name) {
+ /* Get/unpack the color table data from a PBO */
+ GLubyte *buf;
+ if (!_mesa_validate_pbo_access(1, &ctx->Unpack, count, 1, 1,
+ format, type, data)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glColor[Sub]Table(bad PBO access)");
+ return;
+ }
+ buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+ GL_READ_ONLY_ARB,
+ ctx->Unpack.BufferObj);
+ if (!buf) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glColor[Sub]Table(PBO mapped)");
+ return;
+ }
+ data = ADD_POINTERS(buf, data);
+ }
+
+
+ if (table->Type == GL_FLOAT) {
+ /* convert user-provided data to GLfloat values */
+ GLfloat tempTab[MAX_COLOR_TABLE_SIZE * 4];
+ GLfloat *tableF;
+ GLint i;
+
+ _mesa_unpack_color_span_float(ctx,
+ count, /* number of pixels */
+ table->_BaseFormat, /* dest format */
+ tempTab, /* dest address */
+ format, type, /* src format/type */
+ data, /* src data */
+ &ctx->Unpack,
+ IMAGE_CLAMP_BIT); /* transfer ops */
+
+ /* the destination */
+ tableF = (GLfloat *) table->Table;
+
+ /* Apply scale & bias & clamp now */
+ switch (table->_BaseFormat) {
+ case GL_INTENSITY:
+ for (i = 0; i < count; i++) {
+ GLuint j = start + i;
+ tableF[j] = CLAMP(tempTab[i] * rScale + rBias, 0.0F, 1.0F);
+ }
+ break;
+ case GL_LUMINANCE:
+ for (i = 0; i < count; i++) {
+ GLuint j = start + i;
+ tableF[j] = CLAMP(tempTab[i] * rScale + rBias, 0.0F, 1.0F);
+ }
+ break;
+ case GL_ALPHA:
+ for (i = 0; i < count; i++) {
+ GLuint j = start + i;
+ tableF[j] = CLAMP(tempTab[i] * aScale + aBias, 0.0F, 1.0F);
+ }
+ break;
+ case GL_LUMINANCE_ALPHA:
+ for (i = 0; i < count; i++) {
+ GLuint j = start + i;
+ tableF[j*2+0] = CLAMP(tempTab[i*2+0] * rScale + rBias, 0.0F, 1.0F);
+ tableF[j*2+1] = CLAMP(tempTab[i*2+1] * aScale + aBias, 0.0F, 1.0F);
+ }
+ break;
+ case GL_RGB:
+ for (i = 0; i < count; i++) {
+ GLuint j = start + i;
+ tableF[j*3+0] = CLAMP(tempTab[i*3+0] * rScale + rBias, 0.0F, 1.0F);
+ tableF[j*3+1] = CLAMP(tempTab[i*3+1] * gScale + gBias, 0.0F, 1.0F);
+ tableF[j*3+2] = CLAMP(tempTab[i*3+2] * bScale + bBias, 0.0F, 1.0F);
+ }
+ break;
+ case GL_RGBA:
+ for (i = 0; i < count; i++) {
+ GLuint j = start + i;
+ tableF[j*4+0] = CLAMP(tempTab[i*4+0] * rScale + rBias, 0.0F, 1.0F);
+ tableF[j*4+1] = CLAMP(tempTab[i*4+1] * gScale + gBias, 0.0F, 1.0F);
+ tableF[j*4+2] = CLAMP(tempTab[i*4+2] * bScale + bBias, 0.0F, 1.0F);
+ tableF[j*4+3] = CLAMP(tempTab[i*4+3] * aScale + aBias, 0.0F, 1.0F);
+ }
+ break;
+ default:
+ _mesa_problem(ctx, "Bad format in store_colortable_entries");
+ return;
+ }
+ }
+ else {
+ /* non-float (GLchan) */
+ const GLint comps = _mesa_components_in_format(table->_BaseFormat);
+ GLchan *dest = (GLchan *) table->Table + start * comps;
+ _mesa_unpack_color_span_chan(ctx, count, /* number of entries */
+ table->_BaseFormat, /* dest format */
+ dest, /* dest address */
+ format, type, data, /* src data */
+ &ctx->Unpack,
+ 0); /* transfer ops */
+ }
+
+ if (ctx->Unpack.BufferObj->Name) {
+ ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+ ctx->Unpack.BufferObj);
+ }
+}
+
+
+
+void GLAPIENTRY
+_mesa_ColorTable( GLenum target, GLenum internalFormat,
+ GLsizei width, GLenum format, GLenum type,
+ const GLvoid *data )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ struct gl_texture_object *texObj = NULL;
+ struct gl_color_table *table = NULL;
+ GLboolean proxy = GL_FALSE;
+ GLint baseFormat;
+ GLfloat rScale = 1.0, gScale = 1.0, bScale = 1.0, aScale = 1.0;
+ GLfloat rBias = 0.0, gBias = 0.0, bBias = 0.0, aBias = 0.0;
+ GLenum tableType = CHAN_TYPE;
+ GLint comps;
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* too complex */
+
+ switch (target) {
+ case GL_TEXTURE_1D:
+ texObj = texUnit->Current1D;
+ table = &texObj->Palette;
+ break;
+ case GL_TEXTURE_2D:
+ texObj = texUnit->Current2D;
+ table = &texObj->Palette;
+ break;
+ case GL_TEXTURE_3D:
+ texObj = texUnit->Current3D;
+ table = &texObj->Palette;
+ break;
+ case GL_TEXTURE_CUBE_MAP_ARB:
+ if (!ctx->Extensions.ARB_texture_cube_map) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)");
+ return;
+ }
+ texObj = texUnit->CurrentCubeMap;
+ table = &texObj->Palette;
+ break;
+ case GL_PROXY_TEXTURE_1D:
+ texObj = ctx->Texture.Proxy1D;
+ table = &texObj->Palette;
+ proxy = GL_TRUE;
+ break;
+ case GL_PROXY_TEXTURE_2D:
+ texObj = ctx->Texture.Proxy2D;
+ table = &texObj->Palette;
+ proxy = GL_TRUE;
+ break;
+ case GL_PROXY_TEXTURE_3D:
+ texObj = ctx->Texture.Proxy3D;
+ table = &texObj->Palette;
+ proxy = GL_TRUE;
+ break;
+ case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
+ if (!ctx->Extensions.ARB_texture_cube_map) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)");
+ return;
+ }
+ texObj = ctx->Texture.ProxyCubeMap;
+ table = &texObj->Palette;
+ break;
+ case GL_SHARED_TEXTURE_PALETTE_EXT:
+ table = &ctx->Texture.Palette;
+ tableType = GL_FLOAT;
+ break;
+ case GL_COLOR_TABLE:
+ table = &ctx->ColorTable;
+ tableType = GL_FLOAT;
+ rScale = ctx->Pixel.ColorTableScale[0];
+ gScale = ctx->Pixel.ColorTableScale[1];
+ bScale = ctx->Pixel.ColorTableScale[2];
+ aScale = ctx->Pixel.ColorTableScale[3];
+ rBias = ctx->Pixel.ColorTableBias[0];
+ gBias = ctx->Pixel.ColorTableBias[1];
+ bBias = ctx->Pixel.ColorTableBias[2];
+ aBias = ctx->Pixel.ColorTableBias[3];
+ break;
+ case GL_PROXY_COLOR_TABLE:
+ table = &ctx->ProxyColorTable;
+ proxy = GL_TRUE;
+ break;
+ case GL_TEXTURE_COLOR_TABLE_SGI:
+ if (!ctx->Extensions.SGI_texture_color_table) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)");
+ return;
+ }
+ table = &(texUnit->ColorTable);
+ tableType = GL_FLOAT;
+ rScale = ctx->Pixel.TextureColorTableScale[0];
+ gScale = ctx->Pixel.TextureColorTableScale[1];
+ bScale = ctx->Pixel.TextureColorTableScale[2];
+ aScale = ctx->Pixel.TextureColorTableScale[3];
+ rBias = ctx->Pixel.TextureColorTableBias[0];
+ gBias = ctx->Pixel.TextureColorTableBias[1];
+ bBias = ctx->Pixel.TextureColorTableBias[2];
+ aBias = ctx->Pixel.TextureColorTableBias[3];
+ break;
+ case GL_PROXY_TEXTURE_COLOR_TABLE_SGI:
+ if (!ctx->Extensions.SGI_texture_color_table) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)");
+ return;
+ }
+ table = &(texUnit->ProxyColorTable);
+ tableType = GL_FLOAT;
+ proxy = GL_TRUE;
+ break;
+ case GL_POST_CONVOLUTION_COLOR_TABLE:
+ table = &ctx->PostConvolutionColorTable;
+ tableType = GL_FLOAT;
+ rScale = ctx->Pixel.PCCTscale[0];
+ gScale = ctx->Pixel.PCCTscale[1];
+ bScale = ctx->Pixel.PCCTscale[2];
+ aScale = ctx->Pixel.PCCTscale[3];
+ rBias = ctx->Pixel.PCCTbias[0];
+ gBias = ctx->Pixel.PCCTbias[1];
+ bBias = ctx->Pixel.PCCTbias[2];
+ aBias = ctx->Pixel.PCCTbias[3];
+ break;
+ case GL_PROXY_POST_CONVOLUTION_COLOR_TABLE:
+ table = &ctx->ProxyPostConvolutionColorTable;
+ tableType = GL_FLOAT;
+ proxy = GL_TRUE;
+ break;
+ case GL_POST_COLOR_MATRIX_COLOR_TABLE:
+ table = &ctx->PostColorMatrixColorTable;
+ tableType = GL_FLOAT;
+ rScale = ctx->Pixel.PCMCTscale[0];
+ gScale = ctx->Pixel.PCMCTscale[1];
+ bScale = ctx->Pixel.PCMCTscale[2];
+ aScale = ctx->Pixel.PCMCTscale[3];
+ rBias = ctx->Pixel.PCMCTbias[0];
+ gBias = ctx->Pixel.PCMCTbias[1];
+ bBias = ctx->Pixel.PCMCTbias[2];
+ aBias = ctx->Pixel.PCMCTbias[3];
+ break;
+ case GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE:
+ table = &ctx->ProxyPostColorMatrixColorTable;
+ tableType = GL_FLOAT;
+ proxy = GL_TRUE;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)");
+ return;
+ }
+
+ assert(table);
+
+ if (!_mesa_is_legal_format_and_type(ctx, format, type) ||
+ format == GL_INTENSITY) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glColorTable(format or type)");
+ return;
+ }
+
+ baseFormat = base_colortab_format(internalFormat);
+ if (baseFormat < 0) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(internalFormat)");
+ return;
+ }
+
+ if (width < 0 || (width != 0 && _mesa_bitcount(width) != 1)) {
+ /* error */
+ if (proxy) {
+ table->Size = 0;
+ table->InternalFormat = (GLenum) 0;
+ table->_BaseFormat = (GLenum) 0;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glColorTable(width=%d)", width);
+ }
+ return;
+ }
+
+ if (width > (GLsizei) ctx->Const.MaxColorTableSize) {
+ if (proxy) {
+ table->Size = 0;
+ table->InternalFormat = (GLenum) 0;
+ table->_BaseFormat = (GLenum) 0;
+ }
+ else {
+ _mesa_error(ctx, GL_TABLE_TOO_LARGE, "glColorTable(width)");
+ }
+ return;
+ }
+
+ table->Size = width;
+ table->InternalFormat = internalFormat;
+ table->_BaseFormat = (GLenum) baseFormat;
+ table->Type = (tableType == GL_FLOAT) ? GL_FLOAT : CHAN_TYPE;
+
+ comps = _mesa_components_in_format(table->_BaseFormat);
+ assert(comps > 0); /* error should have been caught sooner */
+
+ if (!proxy) {
+ /* free old table, if any */
+ if (table->Table) {
+ FREE(table->Table);
+ table->Table = NULL;
+ }
+
+ if (width > 0) {
+ if (table->Type == GL_FLOAT) {
+ table->Table = MALLOC(comps * width * sizeof(GLfloat));
+ }
+ else {
+ table->Table = MALLOC(comps * width * sizeof(GLchan));
+ }
+
+ if (!table->Table) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glColorTable");
+ return;
+ }
+
+ store_colortable_entries(ctx, table,
+ 0, width, /* start, count */
+ format, type, data,
+ rScale, rBias,
+ gScale, gBias,
+ bScale, bBias,
+ aScale, aBias);
+ }
+ } /* proxy */
+
+ /* do this after the table's Type and Format are set */
+ set_component_sizes(table);
+
+ if (texObj || target == GL_SHARED_TEXTURE_PALETTE_EXT) {
+ /* texture object palette, texObj==NULL means the shared palette */
+ if (ctx->Driver.UpdateTexturePalette) {
+ (*ctx->Driver.UpdateTexturePalette)( ctx, texObj );
+ }
+ }
+
+ ctx->NewState |= _NEW_PIXEL;
+}
+
+
+
+void GLAPIENTRY
+_mesa_ColorSubTable( GLenum target, GLsizei start,
+ GLsizei count, GLenum format, GLenum type,
+ const GLvoid *data )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ struct gl_texture_object *texObj = NULL;
+ struct gl_color_table *table = NULL;
+ GLfloat rScale = 1.0, gScale = 1.0, bScale = 1.0, aScale = 1.0;
+ GLfloat rBias = 0.0, gBias = 0.0, bBias = 0.0, aBias = 0.0;
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ switch (target) {
+ case GL_TEXTURE_1D:
+ texObj = texUnit->Current1D;
+ table = &texObj->Palette;
+ break;
+ case GL_TEXTURE_2D:
+ texObj = texUnit->Current2D;
+ table = &texObj->Palette;
+ break;
+ case GL_TEXTURE_3D:
+ texObj = texUnit->Current3D;
+ table = &texObj->Palette;
+ break;
+ case GL_TEXTURE_CUBE_MAP_ARB:
+ if (!ctx->Extensions.ARB_texture_cube_map) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glColorSubTable(target)");
+ return;
+ }
+ texObj = texUnit->CurrentCubeMap;
+ table = &texObj->Palette;
+ break;
+ case GL_SHARED_TEXTURE_PALETTE_EXT:
+ table = &ctx->Texture.Palette;
+ break;
+ case GL_COLOR_TABLE:
+ table = &ctx->ColorTable;
+ rScale = ctx->Pixel.ColorTableScale[0];
+ gScale = ctx->Pixel.ColorTableScale[1];
+ bScale = ctx->Pixel.ColorTableScale[2];
+ aScale = ctx->Pixel.ColorTableScale[3];
+ rBias = ctx->Pixel.ColorTableBias[0];
+ gBias = ctx->Pixel.ColorTableBias[1];
+ bBias = ctx->Pixel.ColorTableBias[2];
+ aBias = ctx->Pixel.ColorTableBias[3];
+ break;
+ case GL_TEXTURE_COLOR_TABLE_SGI:
+ if (!ctx->Extensions.SGI_texture_color_table) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glColorSubTable(target)");
+ return;
+ }
+ table = &(texUnit->ColorTable);
+ rScale = ctx->Pixel.TextureColorTableScale[0];
+ gScale = ctx->Pixel.TextureColorTableScale[1];
+ bScale = ctx->Pixel.TextureColorTableScale[2];
+ aScale = ctx->Pixel.TextureColorTableScale[3];
+ rBias = ctx->Pixel.TextureColorTableBias[0];
+ gBias = ctx->Pixel.TextureColorTableBias[1];
+ bBias = ctx->Pixel.TextureColorTableBias[2];
+ aBias = ctx->Pixel.TextureColorTableBias[3];
+ break;
+ case GL_POST_CONVOLUTION_COLOR_TABLE:
+ table = &ctx->PostConvolutionColorTable;
+ rScale = ctx->Pixel.PCCTscale[0];
+ gScale = ctx->Pixel.PCCTscale[1];
+ bScale = ctx->Pixel.PCCTscale[2];
+ aScale = ctx->Pixel.PCCTscale[3];
+ rBias = ctx->Pixel.PCCTbias[0];
+ gBias = ctx->Pixel.PCCTbias[1];
+ bBias = ctx->Pixel.PCCTbias[2];
+ aBias = ctx->Pixel.PCCTbias[3];
+ break;
+ case GL_POST_COLOR_MATRIX_COLOR_TABLE:
+ table = &ctx->PostColorMatrixColorTable;
+ rScale = ctx->Pixel.PCMCTscale[0];
+ gScale = ctx->Pixel.PCMCTscale[1];
+ bScale = ctx->Pixel.PCMCTscale[2];
+ aScale = ctx->Pixel.PCMCTscale[3];
+ rBias = ctx->Pixel.PCMCTbias[0];
+ gBias = ctx->Pixel.PCMCTbias[1];
+ bBias = ctx->Pixel.PCMCTbias[2];
+ aBias = ctx->Pixel.PCMCTbias[3];
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glColorSubTable(target)");
+ return;
+ }
+
+ assert(table);
+
+ if (!_mesa_is_legal_format_and_type(ctx, format, type) ||
+ format == GL_INTENSITY) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glColorSubTable(format or type)");
+ return;
+ }
+
+ if (count < 1) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glColorSubTable(count)");
+ return;
+ }
+
+ /* error should have been caught sooner */
+ assert(_mesa_components_in_format(table->_BaseFormat) > 0);
+
+ if (start + count > (GLint) table->Size) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glColorSubTable(count)");
+ return;
+ }
+
+ if (!table->Table) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glColorSubTable");
+ return;
+ }
+
+ store_colortable_entries(ctx, table, start, count,
+ format, type, data,
+ rScale, rBias,
+ gScale, gBias,
+ bScale, bBias,
+ aScale, aBias);
+
+ if (texObj || target == GL_SHARED_TEXTURE_PALETTE_EXT) {
+ /* per-texture object palette */
+ if (ctx->Driver.UpdateTexturePalette) {
+ (*ctx->Driver.UpdateTexturePalette)( ctx, texObj );
+ }
+ }
+
+ ctx->NewState |= _NEW_PIXEL;
+}
+
+
+
+void GLAPIENTRY
+_mesa_CopyColorTable(GLenum target, GLenum internalformat,
+ GLint x, GLint y, GLsizei width)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ /* Select buffer to read from */
+ ctx->Driver.CopyColorTable( ctx, target, internalformat, x, y, width );
+}
+
+
+
+void GLAPIENTRY
+_mesa_CopyColorSubTable(GLenum target, GLsizei start,
+ GLint x, GLint y, GLsizei width)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ ctx->Driver.CopyColorSubTable( ctx, target, start, x, y, width );
+}
+
+
+
+void GLAPIENTRY
+_mesa_GetColorTable( GLenum target, GLenum format,
+ GLenum type, GLvoid *data )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ struct gl_color_table *table = NULL;
+ GLchan rgba[MAX_COLOR_TABLE_SIZE][4];
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (ctx->NewState) {
+ _mesa_update_state(ctx);
+ }
+
+ switch (target) {
+ case GL_TEXTURE_1D:
+ table = &texUnit->Current1D->Palette;
+ break;
+ case GL_TEXTURE_2D:
+ table = &texUnit->Current2D->Palette;
+ break;
+ case GL_TEXTURE_3D:
+ table = &texUnit->Current3D->Palette;
+ break;
+ case GL_TEXTURE_CUBE_MAP_ARB:
+ if (!ctx->Extensions.ARB_texture_cube_map) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTable(target)");
+ return;
+ }
+ table = &texUnit->CurrentCubeMap->Palette;
+ break;
+ case GL_SHARED_TEXTURE_PALETTE_EXT:
+ table = &ctx->Texture.Palette;
+ break;
+ case GL_COLOR_TABLE:
+ table = &ctx->ColorTable;
+ break;
+ case GL_TEXTURE_COLOR_TABLE_SGI:
+ if (!ctx->Extensions.SGI_texture_color_table) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTable(target)");
+ return;
+ }
+ table = &(texUnit->ColorTable);
+ break;
+ case GL_POST_CONVOLUTION_COLOR_TABLE:
+ table = &ctx->PostConvolutionColorTable;
+ break;
+ case GL_POST_COLOR_MATRIX_COLOR_TABLE:
+ table = &ctx->PostColorMatrixColorTable;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTable(target)");
+ return;
+ }
+
+ ASSERT(table);
+
+ switch (table->_BaseFormat) {
+ case GL_ALPHA:
+ if (table->Type == GL_FLOAT) {
+ const GLfloat *tableF = (const GLfloat *) table->Table;
+ GLuint i;
+ for (i = 0; i < table->Size; i++) {
+ rgba[i][RCOMP] = 0;
+ rgba[i][GCOMP] = 0;
+ rgba[i][BCOMP] = 0;
+ rgba[i][ACOMP] = IROUND_POS(tableF[i] * CHAN_MAXF);
+ }
+ }
+ else {
+ const GLchan *tableUB = (const GLchan *) table->Table;
+ GLuint i;
+ for (i = 0; i < table->Size; i++) {
+ rgba[i][RCOMP] = 0;
+ rgba[i][GCOMP] = 0;
+ rgba[i][BCOMP] = 0;
+ rgba[i][ACOMP] = tableUB[i];
+ }
+ }
+ break;
+ case GL_LUMINANCE:
+ if (table->Type == GL_FLOAT) {
+ const GLfloat *tableF = (const GLfloat *) table->Table;
+ GLuint i;
+ for (i = 0; i < table->Size; i++) {
+ rgba[i][RCOMP] = IROUND_POS(tableF[i] * CHAN_MAXF);
+ rgba[i][GCOMP] = IROUND_POS(tableF[i] * CHAN_MAXF);
+ rgba[i][BCOMP] = IROUND_POS(tableF[i] * CHAN_MAXF);
+ rgba[i][ACOMP] = CHAN_MAX;
+ }
+ }
+ else {
+ const GLchan *tableUB = (const GLchan *) table->Table;
+ GLuint i;
+ for (i = 0; i < table->Size; i++) {
+ rgba[i][RCOMP] = tableUB[i];
+ rgba[i][GCOMP] = tableUB[i];
+ rgba[i][BCOMP] = tableUB[i];
+ rgba[i][ACOMP] = CHAN_MAX;
+ }
+ }
+ break;
+ case GL_LUMINANCE_ALPHA:
+ if (table->Type == GL_FLOAT) {
+ const GLfloat *tableF = (const GLfloat *) table->Table;
+ GLuint i;
+ for (i = 0; i < table->Size; i++) {
+ rgba[i][RCOMP] = IROUND_POS(tableF[i*2+0] * CHAN_MAXF);
+ rgba[i][GCOMP] = IROUND_POS(tableF[i*2+0] * CHAN_MAXF);
+ rgba[i][BCOMP] = IROUND_POS(tableF[i*2+0] * CHAN_MAXF);
+ rgba[i][ACOMP] = IROUND_POS(tableF[i*2+1] * CHAN_MAXF);
+ }
+ }
+ else {
+ const GLchan *tableUB = (const GLchan *) table->Table;
+ GLuint i;
+ for (i = 0; i < table->Size; i++) {
+ rgba[i][RCOMP] = tableUB[i*2+0];
+ rgba[i][GCOMP] = tableUB[i*2+0];
+ rgba[i][BCOMP] = tableUB[i*2+0];
+ rgba[i][ACOMP] = tableUB[i*2+1];
+ }
+ }
+ break;
+ case GL_INTENSITY:
+ if (table->Type == GL_FLOAT) {
+ const GLfloat *tableF = (const GLfloat *) table->Table;
+ GLuint i;
+ for (i = 0; i < table->Size; i++) {
+ rgba[i][RCOMP] = IROUND_POS(tableF[i] * CHAN_MAXF);
+ rgba[i][GCOMP] = IROUND_POS(tableF[i] * CHAN_MAXF);
+ rgba[i][BCOMP] = IROUND_POS(tableF[i] * CHAN_MAXF);
+ rgba[i][ACOMP] = IROUND_POS(tableF[i] * CHAN_MAXF);
+ }
+ }
+ else {
+ const GLchan *tableUB = (const GLchan *) table->Table;
+ GLuint i;
+ for (i = 0; i < table->Size; i++) {
+ rgba[i][RCOMP] = tableUB[i];
+ rgba[i][GCOMP] = tableUB[i];
+ rgba[i][BCOMP] = tableUB[i];
+ rgba[i][ACOMP] = tableUB[i];
+ }
+ }
+ break;
+ case GL_RGB:
+ if (table->Type == GL_FLOAT) {
+ const GLfloat *tableF = (const GLfloat *) table->Table;
+ GLuint i;
+ for (i = 0; i < table->Size; i++) {
+ rgba[i][RCOMP] = IROUND_POS(tableF[i*3+0] * CHAN_MAXF);
+ rgba[i][GCOMP] = IROUND_POS(tableF[i*3+1] * CHAN_MAXF);
+ rgba[i][BCOMP] = IROUND_POS(tableF[i*3+2] * CHAN_MAXF);
+ rgba[i][ACOMP] = CHAN_MAX;
+ }
+ }
+ else {
+ const GLchan *tableUB = (const GLchan *) table->Table;
+ GLuint i;
+ for (i = 0; i < table->Size; i++) {
+ rgba[i][RCOMP] = tableUB[i*3+0];
+ rgba[i][GCOMP] = tableUB[i*3+1];
+ rgba[i][BCOMP] = tableUB[i*3+2];
+ rgba[i][ACOMP] = CHAN_MAX;
+ }
+ }
+ break;
+ case GL_RGBA:
+ if (table->Type == GL_FLOAT) {
+ const GLfloat *tableF = (const GLfloat *) table->Table;
+ GLuint i;
+ for (i = 0; i < table->Size; i++) {
+ rgba[i][RCOMP] = IROUND_POS(tableF[i*4+0] * CHAN_MAXF);
+ rgba[i][GCOMP] = IROUND_POS(tableF[i*4+1] * CHAN_MAXF);
+ rgba[i][BCOMP] = IROUND_POS(tableF[i*4+2] * CHAN_MAXF);
+ rgba[i][ACOMP] = IROUND_POS(tableF[i*4+3] * CHAN_MAXF);
+ }
+ }
+ else {
+ const GLchan *tableUB = (const GLchan *) table->Table;
+ GLuint i;
+ for (i = 0; i < table->Size; i++) {
+ rgba[i][RCOMP] = tableUB[i*4+0];
+ rgba[i][GCOMP] = tableUB[i*4+1];
+ rgba[i][BCOMP] = tableUB[i*4+2];
+ rgba[i][ACOMP] = tableUB[i*4+3];
+ }
+ }
+ break;
+ default:
+ _mesa_problem(ctx, "bad table format in glGetColorTable");
+ return;
+ }
+
+ if (ctx->Pack.BufferObj->Name) {
+ /* pack color table into PBO */
+ GLubyte *buf;
+ if (!_mesa_validate_pbo_access(1, &ctx->Pack, table->Size, 1, 1,
+ format, type, data)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetColorTable(invalid PBO access)");
+ return;
+ }
+ buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
+ GL_WRITE_ONLY_ARB,
+ ctx->Pack.BufferObj);
+ if (!buf) {
+ /* buffer is already mapped - that's an error */
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetColorTable(PBO is mapped)");
+ return;
+ }
+ data = ADD_POINTERS(buf, data);
+ }
+
+ _mesa_pack_rgba_span_chan(ctx, table->Size, (const GLchan (*)[4]) rgba,
+ format, type, data, &ctx->Pack, GL_FALSE);
+
+ if (ctx->Pack.BufferObj->Name) {
+ ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
+ ctx->Pack.BufferObj);
+ }
+}
+
+
+
+void GLAPIENTRY
+_mesa_ColorTableParameterfv(GLenum target, GLenum pname, const GLfloat *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ switch (target) {
+ case GL_COLOR_TABLE_SGI:
+ if (pname == GL_COLOR_TABLE_SCALE_SGI) {
+ ctx->Pixel.ColorTableScale[0] = params[0];
+ ctx->Pixel.ColorTableScale[1] = params[1];
+ ctx->Pixel.ColorTableScale[2] = params[2];
+ ctx->Pixel.ColorTableScale[3] = params[3];
+ }
+ else if (pname == GL_COLOR_TABLE_BIAS_SGI) {
+ ctx->Pixel.ColorTableBias[0] = params[0];
+ ctx->Pixel.ColorTableBias[1] = params[1];
+ ctx->Pixel.ColorTableBias[2] = params[2];
+ ctx->Pixel.ColorTableBias[3] = params[3];
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameterfv(pname)");
+ return;
+ }
+ break;
+ case GL_TEXTURE_COLOR_TABLE_SGI:
+ if (!ctx->Extensions.SGI_texture_color_table) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameter(target)");
+ return;
+ }
+ if (pname == GL_COLOR_TABLE_SCALE_SGI) {
+ ctx->Pixel.TextureColorTableScale[0] = params[0];
+ ctx->Pixel.TextureColorTableScale[1] = params[1];
+ ctx->Pixel.TextureColorTableScale[2] = params[2];
+ ctx->Pixel.TextureColorTableScale[3] = params[3];
+ }
+ else if (pname == GL_COLOR_TABLE_BIAS_SGI) {
+ ctx->Pixel.TextureColorTableBias[0] = params[0];
+ ctx->Pixel.TextureColorTableBias[1] = params[1];
+ ctx->Pixel.TextureColorTableBias[2] = params[2];
+ ctx->Pixel.TextureColorTableBias[3] = params[3];
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameterfv(pname)");
+ return;
+ }
+ break;
+ case GL_POST_CONVOLUTION_COLOR_TABLE_SGI:
+ if (pname == GL_COLOR_TABLE_SCALE_SGI) {
+ ctx->Pixel.PCCTscale[0] = params[0];
+ ctx->Pixel.PCCTscale[1] = params[1];
+ ctx->Pixel.PCCTscale[2] = params[2];
+ ctx->Pixel.PCCTscale[3] = params[3];
+ }
+ else if (pname == GL_COLOR_TABLE_BIAS_SGI) {
+ ctx->Pixel.PCCTbias[0] = params[0];
+ ctx->Pixel.PCCTbias[1] = params[1];
+ ctx->Pixel.PCCTbias[2] = params[2];
+ ctx->Pixel.PCCTbias[3] = params[3];
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameterfv(pname)");
+ return;
+ }
+ break;
+ case GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI:
+ if (pname == GL_COLOR_TABLE_SCALE_SGI) {
+ ctx->Pixel.PCMCTscale[0] = params[0];
+ ctx->Pixel.PCMCTscale[1] = params[1];
+ ctx->Pixel.PCMCTscale[2] = params[2];
+ ctx->Pixel.PCMCTscale[3] = params[3];
+ }
+ else if (pname == GL_COLOR_TABLE_BIAS_SGI) {
+ ctx->Pixel.PCMCTbias[0] = params[0];
+ ctx->Pixel.PCMCTbias[1] = params[1];
+ ctx->Pixel.PCMCTbias[2] = params[2];
+ ctx->Pixel.PCMCTbias[3] = params[3];
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameterfv(pname)");
+ return;
+ }
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameter(target)");
+ return;
+ }
+
+ ctx->NewState |= _NEW_PIXEL;
+}
+
+
+
+void GLAPIENTRY
+_mesa_ColorTableParameteriv(GLenum target, GLenum pname, const GLint *params)
+{
+ GLfloat fparams[4];
+ if (pname == GL_COLOR_TABLE_SGI ||
+ pname == GL_TEXTURE_COLOR_TABLE_SGI ||
+ pname == GL_POST_CONVOLUTION_COLOR_TABLE_SGI ||
+ pname == GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI) {
+ /* four values */
+ fparams[0] = (GLfloat) params[0];
+ fparams[1] = (GLfloat) params[1];
+ fparams[2] = (GLfloat) params[2];
+ fparams[3] = (GLfloat) params[3];
+ }
+ else {
+ /* one values */
+ fparams[0] = (GLfloat) params[0];
+ }
+ _mesa_ColorTableParameterfv(target, pname, fparams);
+}
+
+
+
+void GLAPIENTRY
+_mesa_GetColorTableParameterfv( GLenum target, GLenum pname, GLfloat *params )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ struct gl_color_table *table = NULL;
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ switch (target) {
+ case GL_TEXTURE_1D:
+ table = &texUnit->Current1D->Palette;
+ break;
+ case GL_TEXTURE_2D:
+ table = &texUnit->Current2D->Palette;
+ break;
+ case GL_TEXTURE_3D:
+ table = &texUnit->Current3D->Palette;
+ break;
+ case GL_TEXTURE_CUBE_MAP_ARB:
+ if (!ctx->Extensions.ARB_texture_cube_map) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetColorTableParameterfv(target)");
+ return;
+ }
+ table = &texUnit->CurrentCubeMap->Palette;
+ break;
+ case GL_PROXY_TEXTURE_1D:
+ table = &ctx->Texture.Proxy1D->Palette;
+ break;
+ case GL_PROXY_TEXTURE_2D:
+ table = &ctx->Texture.Proxy2D->Palette;
+ break;
+ case GL_PROXY_TEXTURE_3D:
+ table = &ctx->Texture.Proxy3D->Palette;
+ break;
+ case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
+ if (!ctx->Extensions.ARB_texture_cube_map) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetColorTableParameterfv(target)");
+ return;
+ }
+ table = &ctx->Texture.ProxyCubeMap->Palette;
+ break;
+ case GL_SHARED_TEXTURE_PALETTE_EXT:
+ table = &ctx->Texture.Palette;
+ break;
+ case GL_COLOR_TABLE:
+ table = &ctx->ColorTable;
+ if (pname == GL_COLOR_TABLE_SCALE_SGI) {
+ params[0] = ctx->Pixel.ColorTableScale[0];
+ params[1] = ctx->Pixel.ColorTableScale[1];
+ params[2] = ctx->Pixel.ColorTableScale[2];
+ params[3] = ctx->Pixel.ColorTableScale[3];
+ return;
+ }
+ else if (pname == GL_COLOR_TABLE_BIAS_SGI) {
+ params[0] = ctx->Pixel.ColorTableBias[0];
+ params[1] = ctx->Pixel.ColorTableBias[1];
+ params[2] = ctx->Pixel.ColorTableBias[2];
+ params[3] = ctx->Pixel.ColorTableBias[3];
+ return;
+ }
+ break;
+ case GL_PROXY_COLOR_TABLE:
+ table = &ctx->ProxyColorTable;
+ break;
+ case GL_TEXTURE_COLOR_TABLE_SGI:
+ if (!ctx->Extensions.SGI_texture_color_table) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameter(target)");
+ return;
+ }
+ table = &(texUnit->ColorTable);
+ if (pname == GL_COLOR_TABLE_SCALE_SGI) {
+ params[0] = ctx->Pixel.TextureColorTableScale[0];
+ params[1] = ctx->Pixel.TextureColorTableScale[1];
+ params[2] = ctx->Pixel.TextureColorTableScale[2];
+ params[3] = ctx->Pixel.TextureColorTableScale[3];
+ return;
+ }
+ else if (pname == GL_COLOR_TABLE_BIAS_SGI) {
+ params[0] = ctx->Pixel.TextureColorTableBias[0];
+ params[1] = ctx->Pixel.TextureColorTableBias[1];
+ params[2] = ctx->Pixel.TextureColorTableBias[2];
+ params[3] = ctx->Pixel.TextureColorTableBias[3];
+ return;
+ }
+ break;
+ case GL_PROXY_TEXTURE_COLOR_TABLE_SGI:
+ if (!ctx->Extensions.SGI_texture_color_table) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameter(target)");
+ return;
+ }
+ table = &(texUnit->ProxyColorTable);
+ break;
+ case GL_POST_CONVOLUTION_COLOR_TABLE:
+ table = &ctx->PostConvolutionColorTable;
+ if (pname == GL_COLOR_TABLE_SCALE_SGI) {
+ params[0] = ctx->Pixel.PCCTscale[0];
+ params[1] = ctx->Pixel.PCCTscale[1];
+ params[2] = ctx->Pixel.PCCTscale[2];
+ params[3] = ctx->Pixel.PCCTscale[3];
+ return;
+ }
+ else if (pname == GL_COLOR_TABLE_BIAS_SGI) {
+ params[0] = ctx->Pixel.PCCTbias[0];
+ params[1] = ctx->Pixel.PCCTbias[1];
+ params[2] = ctx->Pixel.PCCTbias[2];
+ params[3] = ctx->Pixel.PCCTbias[3];
+ return;
+ }
+ break;
+ case GL_PROXY_POST_CONVOLUTION_COLOR_TABLE:
+ table = &ctx->ProxyPostConvolutionColorTable;
+ break;
+ case GL_POST_COLOR_MATRIX_COLOR_TABLE:
+ table = &ctx->PostColorMatrixColorTable;
+ if (pname == GL_COLOR_TABLE_SCALE_SGI) {
+ params[0] = ctx->Pixel.PCMCTscale[0];
+ params[1] = ctx->Pixel.PCMCTscale[1];
+ params[2] = ctx->Pixel.PCMCTscale[2];
+ params[3] = ctx->Pixel.PCMCTscale[3];
+ return;
+ }
+ else if (pname == GL_COLOR_TABLE_BIAS_SGI) {
+ params[0] = ctx->Pixel.PCMCTbias[0];
+ params[1] = ctx->Pixel.PCMCTbias[1];
+ params[2] = ctx->Pixel.PCMCTbias[2];
+ params[3] = ctx->Pixel.PCMCTbias[3];
+ return;
+ }
+ break;
+ case GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE:
+ table = &ctx->ProxyPostColorMatrixColorTable;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameterfv(target)");
+ return;
+ }
+
+ assert(table);
+
+ switch (pname) {
+ case GL_COLOR_TABLE_FORMAT:
+ *params = (GLfloat) table->InternalFormat;
+ break;
+ case GL_COLOR_TABLE_WIDTH:
+ *params = (GLfloat) table->Size;
+ break;
+ case GL_COLOR_TABLE_RED_SIZE:
+ *params = (GLfloat) table->RedSize;
+ break;
+ case GL_COLOR_TABLE_GREEN_SIZE:
+ *params = (GLfloat) table->GreenSize;
+ break;
+ case GL_COLOR_TABLE_BLUE_SIZE:
+ *params = (GLfloat) table->BlueSize;
+ break;
+ case GL_COLOR_TABLE_ALPHA_SIZE:
+ *params = (GLfloat) table->AlphaSize;
+ break;
+ case GL_COLOR_TABLE_LUMINANCE_SIZE:
+ *params = (GLfloat) table->LuminanceSize;
+ break;
+ case GL_COLOR_TABLE_INTENSITY_SIZE:
+ *params = (GLfloat) table->IntensitySize;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameterfv(pname)" );
+ return;
+ }
+}
+
+
+
+void GLAPIENTRY
+_mesa_GetColorTableParameteriv( GLenum target, GLenum pname, GLint *params )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ struct gl_color_table *table = NULL;
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ switch (target) {
+ case GL_TEXTURE_1D:
+ table = &texUnit->Current1D->Palette;
+ break;
+ case GL_TEXTURE_2D:
+ table = &texUnit->Current2D->Palette;
+ break;
+ case GL_TEXTURE_3D:
+ table = &texUnit->Current3D->Palette;
+ break;
+ case GL_TEXTURE_CUBE_MAP_ARB:
+ if (!ctx->Extensions.ARB_texture_cube_map) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetColorTableParameteriv(target)");
+ return;
+ }
+ table = &texUnit->CurrentCubeMap->Palette;
+ break;
+ case GL_PROXY_TEXTURE_1D:
+ table = &ctx->Texture.Proxy1D->Palette;
+ break;
+ case GL_PROXY_TEXTURE_2D:
+ table = &ctx->Texture.Proxy2D->Palette;
+ break;
+ case GL_PROXY_TEXTURE_3D:
+ table = &ctx->Texture.Proxy3D->Palette;
+ break;
+ case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
+ if (!ctx->Extensions.ARB_texture_cube_map) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetColorTableParameteriv(target)");
+ return;
+ }
+ table = &ctx->Texture.ProxyCubeMap->Palette;
+ break;
+ case GL_SHARED_TEXTURE_PALETTE_EXT:
+ table = &ctx->Texture.Palette;
+ break;
+ case GL_COLOR_TABLE:
+ table = &ctx->ColorTable;
+ if (pname == GL_COLOR_TABLE_SCALE_SGI) {
+ params[0] = (GLint) ctx->Pixel.ColorTableScale[0];
+ params[1] = (GLint) ctx->Pixel.ColorTableScale[1];
+ params[2] = (GLint) ctx->Pixel.ColorTableScale[2];
+ params[3] = (GLint) ctx->Pixel.ColorTableScale[3];
+ return;
+ }
+ else if (pname == GL_COLOR_TABLE_BIAS_SGI) {
+ params[0] = (GLint) ctx->Pixel.ColorTableBias[0];
+ params[1] = (GLint) ctx->Pixel.ColorTableBias[1];
+ params[2] = (GLint) ctx->Pixel.ColorTableBias[2];
+ params[3] = (GLint) ctx->Pixel.ColorTableBias[3];
+ return;
+ }
+ break;
+ case GL_PROXY_COLOR_TABLE:
+ table = &ctx->ProxyColorTable;
+ break;
+ case GL_TEXTURE_COLOR_TABLE_SGI:
+ if (!ctx->Extensions.SGI_texture_color_table) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameter(target)");
+ return;
+ }
+ table = &(texUnit->ColorTable);
+ if (pname == GL_COLOR_TABLE_SCALE_SGI) {
+ params[0] = (GLint) ctx->Pixel.TextureColorTableScale[0];
+ params[1] = (GLint) ctx->Pixel.TextureColorTableScale[1];
+ params[2] = (GLint) ctx->Pixel.TextureColorTableScale[2];
+ params[3] = (GLint) ctx->Pixel.TextureColorTableScale[3];
+ return;
+ }
+ else if (pname == GL_COLOR_TABLE_BIAS_SGI) {
+ params[0] = (GLint) ctx->Pixel.TextureColorTableBias[0];
+ params[1] = (GLint) ctx->Pixel.TextureColorTableBias[1];
+ params[2] = (GLint) ctx->Pixel.TextureColorTableBias[2];
+ params[3] = (GLint) ctx->Pixel.TextureColorTableBias[3];
+ return;
+ }
+ break;
+ case GL_PROXY_TEXTURE_COLOR_TABLE_SGI:
+ if (!ctx->Extensions.SGI_texture_color_table) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameter(target)");
+ return;
+ }
+ table = &(texUnit->ProxyColorTable);
+ break;
+ case GL_POST_CONVOLUTION_COLOR_TABLE:
+ table = &ctx->PostConvolutionColorTable;
+ if (pname == GL_COLOR_TABLE_SCALE_SGI) {
+ params[0] = (GLint) ctx->Pixel.PCCTscale[0];
+ params[1] = (GLint) ctx->Pixel.PCCTscale[1];
+ params[2] = (GLint) ctx->Pixel.PCCTscale[2];
+ params[3] = (GLint) ctx->Pixel.PCCTscale[3];
+ return;
+ }
+ else if (pname == GL_COLOR_TABLE_BIAS_SGI) {
+ params[0] = (GLint) ctx->Pixel.PCCTbias[0];
+ params[1] = (GLint) ctx->Pixel.PCCTbias[1];
+ params[2] = (GLint) ctx->Pixel.PCCTbias[2];
+ params[3] = (GLint) ctx->Pixel.PCCTbias[3];
+ return;
+ }
+ break;
+ case GL_PROXY_POST_CONVOLUTION_COLOR_TABLE:
+ table = &ctx->ProxyPostConvolutionColorTable;
+ break;
+ case GL_POST_COLOR_MATRIX_COLOR_TABLE:
+ table = &ctx->PostColorMatrixColorTable;
+ if (pname == GL_COLOR_TABLE_SCALE_SGI) {
+ params[0] = (GLint) ctx->Pixel.PCMCTscale[0];
+ params[1] = (GLint) ctx->Pixel.PCMCTscale[1];
+ params[2] = (GLint) ctx->Pixel.PCMCTscale[2];
+ params[3] = (GLint) ctx->Pixel.PCMCTscale[3];
+ return;
+ }
+ else if (pname == GL_COLOR_TABLE_BIAS_SGI) {
+ params[0] = (GLint) ctx->Pixel.PCMCTbias[0];
+ params[1] = (GLint) ctx->Pixel.PCMCTbias[1];
+ params[2] = (GLint) ctx->Pixel.PCMCTbias[2];
+ params[3] = (GLint) ctx->Pixel.PCMCTbias[3];
+ return;
+ }
+ break;
+ case GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE:
+ table = &ctx->ProxyPostColorMatrixColorTable;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameteriv(target)");
+ return;
+ }
+
+ assert(table);
+
+ switch (pname) {
+ case GL_COLOR_TABLE_FORMAT:
+ *params = table->InternalFormat;
+ break;
+ case GL_COLOR_TABLE_WIDTH:
+ *params = table->Size;
+ break;
+ case GL_COLOR_TABLE_RED_SIZE:
+ *params = table->RedSize;
+ break;
+ case GL_COLOR_TABLE_GREEN_SIZE:
+ *params = table->GreenSize;
+ break;
+ case GL_COLOR_TABLE_BLUE_SIZE:
+ *params = table->BlueSize;
+ break;
+ case GL_COLOR_TABLE_ALPHA_SIZE:
+ *params = table->AlphaSize;
+ break;
+ case GL_COLOR_TABLE_LUMINANCE_SIZE:
+ *params = table->LuminanceSize;
+ break;
+ case GL_COLOR_TABLE_INTENSITY_SIZE:
+ *params = table->IntensitySize;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameteriv(pname)" );
+ return;
+ }
+}
+
+/**********************************************************************/
+/***** Initialization *****/
+/**********************************************************************/
+
+
+void
+_mesa_init_colortable( struct gl_color_table *p )
+{
+ p->Type = CHAN_TYPE;
+ p->Table = NULL;
+ p->Size = 0;
+ p->InternalFormat = GL_RGBA;
+}
+
+
+
+void
+_mesa_free_colortable_data( struct gl_color_table *p )
+{
+ if (p->Table) {
+ FREE(p->Table);
+ p->Table = NULL;
+ }
+}
+
+
+/*
+ * Initialize all colortables for a context.
+ */
+void _mesa_init_colortables( GLcontext * ctx )
+{
+ /* Color tables */
+ _mesa_init_colortable(&ctx->ColorTable);
+ _mesa_init_colortable(&ctx->ProxyColorTable);
+ _mesa_init_colortable(&ctx->PostConvolutionColorTable);
+ _mesa_init_colortable(&ctx->ProxyPostConvolutionColorTable);
+ _mesa_init_colortable(&ctx->PostColorMatrixColorTable);
+ _mesa_init_colortable(&ctx->ProxyPostColorMatrixColorTable);
+}
+
+
+/*
+ * Free all colortable data for a context
+ */
+void _mesa_free_colortables_data( GLcontext *ctx )
+{
+ _mesa_free_colortable_data(&ctx->ColorTable);
+ _mesa_free_colortable_data(&ctx->ProxyColorTable);
+ _mesa_free_colortable_data(&ctx->PostConvolutionColorTable);
+ _mesa_free_colortable_data(&ctx->ProxyPostConvolutionColorTable);
+ _mesa_free_colortable_data(&ctx->PostColorMatrixColorTable);
+ _mesa_free_colortable_data(&ctx->ProxyPostColorMatrixColorTable);
+}
diff --git a/src/mesa/main/colortab.h b/src/mesa/main/colortab.h
new file mode 100644
index 00000000000..4bd16210a0b
--- /dev/null
+++ b/src/mesa/main/colortab.h
@@ -0,0 +1,110 @@
+/**
+ * \file colortab.h
+ * Color tables.
+ *
+ * \if subset
+ * (No-op)
+ *
+ * \endif
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.5
+ *
+ * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef COLORTAB_H
+#define COLORTAB_H
+
+
+#include "mtypes.h"
+
+#if _HAVE_FULL_GL
+
+extern void GLAPIENTRY
+_mesa_ColorTable( GLenum target, GLenum internalformat,
+ GLsizei width, GLenum format, GLenum type,
+ const GLvoid *table );
+
+extern void GLAPIENTRY
+_mesa_ColorSubTable( GLenum target, GLsizei start,
+ GLsizei count, GLenum format, GLenum type,
+ const GLvoid *table );
+
+extern void GLAPIENTRY
+_mesa_CopyColorSubTable(GLenum target, GLsizei start,
+ GLint x, GLint y, GLsizei width);
+
+extern void GLAPIENTRY
+_mesa_CopyColorTable(GLenum target, GLenum internalformat,
+ GLint x, GLint y, GLsizei width);
+
+extern void GLAPIENTRY
+_mesa_GetColorTable( GLenum target, GLenum format,
+ GLenum type, GLvoid *table );
+
+extern void GLAPIENTRY
+_mesa_ColorTableParameterfv(GLenum target, GLenum pname,
+ const GLfloat *params);
+
+extern void GLAPIENTRY
+_mesa_ColorTableParameteriv(GLenum target, GLenum pname,
+ const GLint *params);
+
+extern void GLAPIENTRY
+_mesa_GetColorTableParameterfv( GLenum target, GLenum pname, GLfloat *params );
+
+extern void GLAPIENTRY
+_mesa_GetColorTableParameteriv( GLenum target, GLenum pname, GLint *params );
+
+
+
+extern void
+_mesa_init_colortable( struct gl_color_table *table );
+
+extern void
+_mesa_free_colortable_data( struct gl_color_table *table );
+
+extern void
+_mesa_init_colortables( GLcontext *ctx );
+
+extern void
+_mesa_free_colortables_data( GLcontext *ctx );
+
+#else
+
+/** No-op */
+#define _mesa_init_colortable( p ) ((void) 0)
+
+/** No-op */
+#define _mesa_free_colortable_data( p ) ((void) 0)
+
+/** No-op */
+#define _mesa_init_colortables( p ) ((void)0)
+
+/** No-op */
+#define _mesa_free_colortables_data( p ) ((void)0)
+
+#endif
+
+#endif
diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h
new file mode 100644
index 00000000000..a10542de22e
--- /dev/null
+++ b/src/mesa/main/config.h
@@ -0,0 +1,317 @@
+/**
+ * \file config.h
+ * Tunable configuration parameters.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.3
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef CONFIG_H
+#define CONFIG_H
+
+/**
+ * \name OpenGL implementation limits
+ */
+/*@{*/
+
+/** Maximum modelview matrix stack depth */
+#define MAX_MODELVIEW_STACK_DEPTH 32
+
+/** Maximum projection matrix stack depth */
+#define MAX_PROJECTION_STACK_DEPTH 32
+
+/** Maximum texture matrix stack depth */
+#define MAX_TEXTURE_STACK_DEPTH 10
+
+/** Maximum color matrix stack depth */
+#define MAX_COLOR_STACK_DEPTH 4
+
+/** Maximum attribute stack depth */
+#define MAX_ATTRIB_STACK_DEPTH 16
+
+/** Maximum client attribute stack depth */
+#define MAX_CLIENT_ATTRIB_STACK_DEPTH 16
+
+/** Maximum recursion depth of display list calls */
+#define MAX_LIST_NESTING 64
+
+/** Maximum number of lights */
+#define MAX_LIGHTS 8
+
+/** Maximum user-defined clipping planes */
+#define MAX_CLIP_PLANES 6
+
+/** Maximum pixel map lookup table size */
+#define MAX_PIXEL_MAP_TABLE 256
+
+/** Maximum number of auxillary color buffers */
+#define MAX_AUX_BUFFERS 4
+
+/** Maximum order (degree) of curves */
+#ifdef AMIGA
+# define MAX_EVAL_ORDER 12
+#else
+# define MAX_EVAL_ORDER 30
+#endif
+
+/** Maximum Name stack depth */
+#define MAX_NAME_STACK_DEPTH 64
+
+/** Minimum point size */
+#define MIN_POINT_SIZE 1.0
+/** Maximum point size */
+#define MAX_POINT_SIZE 20.0
+/** Point size granularity */
+#define POINT_SIZE_GRANULARITY 0.1
+
+/** Minimum line width */
+#define MIN_LINE_WIDTH 1.0
+/** Maximum line width */
+#define MAX_LINE_WIDTH 10.0
+/** Line width granularity */
+#define LINE_WIDTH_GRANULARITY 0.1
+
+/** Max texture palette / color table size */
+#define MAX_COLOR_TABLE_SIZE 256
+
+/** Number of 1D/2D texture mipmap levels */
+#define MAX_TEXTURE_LEVELS 12
+
+/** Number of 3D texture mipmap levels */
+#define MAX_3D_TEXTURE_LEVELS 9
+
+/** Number of cube texture mipmap levels - GL_ARB_texture_cube_map */
+#define MAX_CUBE_TEXTURE_LEVELS 12
+
+/** Maximum rectangular texture size - GL_NV_texture_rectangle */
+#define MAX_TEXTURE_RECT_SIZE 2048
+
+/** Number of texture units - GL_ARB_multitexture */
+#define MAX_TEXTURE_UNITS 8
+
+/*@}*/
+
+
+/**
+ * \name Separate numbers of texture coordinates and texture image units.
+ *
+ * These values will eventually replace most instances of MAX_TEXTURE_UNITS.
+ * We should always have MAX_TEXTURE_COORD_UNITS <= MAX_TEXTURE_IMAGE_UNITS.
+ * And, GL_MAX_TEXTURE_UNITS <= MAX_TEXTURE_COORD_UNITS.
+ */
+/*@{*/
+#define MAX_TEXTURE_COORD_UNITS 8
+#define MAX_TEXTURE_IMAGE_UNITS 8
+/*@}*/
+
+/**
+ * Maximum viewport/image width. Must accomodate all texture sizes too.
+ */
+#define MAX_WIDTH 4096
+/** Maximum viewport/image height */
+#define MAX_HEIGHT 4096
+
+/** Maxmimum size for CVA. May be overridden by the drivers. */
+#define MAX_ARRAY_LOCK_SIZE 3000
+
+/** Subpixel precision for antialiasing, window coordinate snapping */
+#define SUB_PIXEL_BITS 4
+
+/** Size of histogram tables */
+#define HISTOGRAM_TABLE_SIZE 256
+
+/** Max convolution filter width */
+#define MAX_CONVOLUTION_WIDTH 9
+/** Max convolution filter height */
+#define MAX_CONVOLUTION_HEIGHT 9
+
+/** For GL_ARB_texture_compression */
+#define MAX_COMPRESSED_TEXTURE_FORMATS 25
+
+/** For GL_EXT_texture_filter_anisotropic */
+#define MAX_TEXTURE_MAX_ANISOTROPY 16.0
+
+/** For GL_EXT_texture_lod_bias (typically MAX_TEXTURE_LEVELS - 1) */
+#define MAX_TEXTURE_LOD_BIAS 11.0
+
+/** For GL_NV_vertex_program */
+/*@{*/
+#define MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS 128
+#define MAX_NV_VERTEX_PROGRAM_TEMPS 12
+#define MAX_NV_VERTEX_PROGRAM_PARAMS 128 /* KW: power of two */
+#define MAX_NV_VERTEX_PROGRAM_INPUTS 16
+#define MAX_NV_VERTEX_PROGRAM_OUTPUTS 15
+/*@}*/
+
+/** For GL_NV_fragment_program */
+/*@{*/
+#define MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS 128
+#define MAX_NV_FRAGMENT_PROGRAM_TEMPS 96
+#define MAX_NV_FRAGMENT_PROGRAM_PARAMS 64
+#define MAX_NV_FRAGMENT_PROGRAM_INPUTS 12
+#define MAX_NV_FRAGMENT_PROGRAM_OUTPUTS 3
+#define MAX_NV_FRAGMENT_PROGRAM_WRITE_ONLYS 2
+/*@}*/
+
+/** For GL_ARB_vertex_program */
+/*@{*/
+#define MAX_VERTEX_PROGRAM_ADDRESS_REGS 1
+#define MAX_VERTEX_PROGRAM_ATTRIBS 16
+/*@}*/
+
+/** For GL_ARB_fragment_program */
+/*@{*/
+#define MAX_FRAGMENT_PROGRAM_ADDRESS_REGS 0
+#define MAX_FRAGMENT_PROGRAM_ALU_INSTRUCTIONS 48
+#define MAX_FRAGMENT_PROGRAM_TEX_INSTRUCTIONS 24
+#define MAX_FRAGMENT_PROGRAM_TEX_INDIRECTIONS 4
+/*@}*/
+
+/** For any program target/extension */
+/*@{*/
+#define MAX_PROGRAM_LOCAL_PARAMS 128 /* KW: power of two */
+#define MAX_PROGRAM_MATRICES 8
+#define MAX_PROGRAM_MATRIX_STACK_DEPTH 4
+/*@}*/
+
+/** For GL_ARB_fragment_shader */
+/*@{*/
+#define MAX_FRAGMENT_UNIFORM_COMPONENTS 64
+/*@}*/
+
+/** For GL_ARB_vertex_shader */
+/*@{*/
+#define MAX_VERTEX_UNIFORM_COMPONENTS 512
+#define MAX_VARYING_FLOATS 32
+#define MAX_VERTEX_TEXTURE_IMAGE_UNITS 0
+#define MAX_COMBINED_TEXTURE_IMAGE_UNITS (MAX_TEXTURE_IMAGE_UNITS + MAX_VERTEX_TEXTURE_IMAGE_UNITS)
+/*@}*/
+
+
+/** For GL_ARB_draw_buffers */
+/*@{*/
+#define MAX_DRAW_BUFFERS 1
+/*@}*/
+
+
+/** For GL_EXT_framebuffer_object */
+/*@{*/
+#define MAX_COLOR_ATTACHMENTS 8
+/*@}*/
+
+
+
+/**
+ * \name Mesa-specific parameters
+ */
+/*@{*/
+
+
+/**
+ * If non-zero use GLdouble for walking triangle edges, for better accuracy.
+ */
+#define TRIANGLE_WALK_DOUBLE 0
+
+
+/**
+ * Bits per depth buffer value.
+ *
+ * Any reasonable value up to 31 will work. 32 doesn't work because of integer
+ * overflow problems in the rasterizer code.
+ */
+#ifndef DEFAULT_SOFTWARE_DEPTH_BITS
+#define DEFAULT_SOFTWARE_DEPTH_BITS 16
+#endif
+/** Depth buffer data type */
+#if DEFAULT_SOFTWARE_DEPTH_BITS <= 16
+#define DEFAULT_SOFTWARE_DEPTH_TYPE GLushort
+#else
+#define DEFAULT_SOFTWARE_DEPTH_TYPE GLuint
+#endif
+
+
+/**
+ * Bits per stencil value: 8
+ */
+#define STENCIL_BITS 8
+
+
+/**
+ * Bits per color channel: 8, 16 or 32
+ */
+#ifndef CHAN_BITS
+#define CHAN_BITS 8
+#endif
+
+
+/*
+ * Color channel component order
+ *
+ * \note Changes will almost certainly cause problems at this time.
+ */
+#define RCOMP 0
+#define GCOMP 1
+#define BCOMP 2
+#define ACOMP 3
+
+
+/*
+ * Enable/disable features (blocks of code) by setting FEATURE_xyz to 0 or 1.
+ */
+#ifndef _HAVE_FULL_GL
+#define _HAVE_FULL_GL 1
+#endif
+
+#define FEATURE_ARB_vertex_buffer_object _HAVE_FULL_GL
+#define FEATURE_ARB_vertex_program _HAVE_FULL_GL
+#define FEATURE_ARB_fragment_program _HAVE_FULL_GL
+#define FEATURE_ARB_occlusion_query _HAVE_FULL_GL
+#define FEATURE_EXT_pixel_buffer_object _HAVE_FULL_GL
+#define FEATURE_MESA_program_debug _HAVE_FULL_GL
+#define FEATURE_NV_fence _HAVE_FULL_GL
+#define FEATURE_NV_fragment_program _HAVE_FULL_GL
+#define FEATURE_NV_vertex_program _HAVE_FULL_GL
+#define FEATURE_userclip _HAVE_FULL_GL
+#define FEATURE_texgen _HAVE_FULL_GL
+#define FEATURE_windowpos _HAVE_FULL_GL
+#define FEATURE_ARB_vertex_shader _HAVE_FULL_GL
+#define FEATURE_ARB_fragment_shader _HAVE_FULL_GL
+#define FEATURE_ARB_shader_objects (FEATURE_ARB_vertex_shader || FEATURE_ARB_fragment_shader)
+#define FEATURE_ARB_shading_language_100 FEATURE_ARB_shader_objects
+#define FEATURE_ATI_fragment_shader _HAVE_FULL_GL
+#define FEATURE_EXT_framebuffer_object _HAVE_FULL_GL
+#define FEATURE_EXT_framebuffer_blit _HAVE_FULL_GL
+/*@}*/
+
+
+/**
+ * Maximum number of temporary vertices required for clipping.
+ *
+ * Used in array_cache and tnl modules.
+ */
+#define MAX_CLIPPED_VERTICES ((2 * (6 + MAX_CLIP_PLANES))+1)
+
+
+#endif /* CONFIG_H */
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
new file mode 100644
index 00000000000..92dcdfd4ffc
--- /dev/null
+++ b/src/mesa/main/context.c
@@ -0,0 +1,1789 @@
+/**
+ * \file context.c
+ * Mesa context/visual/framebuffer management functions.
+ * \author Brian Paul
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/**
+ * \mainpage Mesa Main Module
+ *
+ * \section MainIntroduction Introduction
+ *
+ * The Mesa Main module consists of all the files in the main/ directory.
+ * Among the features of this module are:
+ * <UL>
+ * <LI> Structures to represent most GL state </LI>
+ * <LI> State set/get functions </LI>
+ * <LI> Display lists </LI>
+ * <LI> Texture unit, object and image handling </LI>
+ * <LI> Matrix and attribute stacks </LI>
+ * </UL>
+ *
+ * Other modules are responsible for API dispatch, vertex transformation,
+ * point/line/triangle setup, rasterization, vertex array caching,
+ * vertex/fragment programs/shaders, etc.
+ *
+ *
+ * \section AboutDoxygen About Doxygen
+ *
+ * If you're viewing this information as Doxygen-generated HTML you'll
+ * see the documentation index at the top of this page.
+ *
+ * The first line lists the Mesa source code modules.
+ * The second line lists the indexes available for viewing the documentation
+ * for each module.
+ *
+ * Selecting the <b>Main page</b> link will display a summary of the module
+ * (this page).
+ *
+ * Selecting <b>Data Structures</b> will list all C structures.
+ *
+ * Selecting the <b>File List</b> link will list all the source files in
+ * the module.
+ * Selecting a filename will show a list of all functions defined in that file.
+ *
+ * Selecting the <b>Data Fields</b> link will display a list of all
+ * documented structure members.
+ *
+ * Selecting the <b>Globals</b> link will display a list
+ * of all functions, structures, global variables and macros in the module.
+ *
+ */
+
+
+#include "glheader.h"
+#include "imports.h"
+#include "accum.h"
+#include "attrib.h"
+#include "blend.h"
+#include "buffers.h"
+#include "bufferobj.h"
+#include "colortab.h"
+#include "context.h"
+#include "debug.h"
+#include "depth.h"
+#include "dlist.h"
+#include "eval.h"
+#include "enums.h"
+#include "extensions.h"
+#include "fbobject.h"
+#include "feedback.h"
+#include "fog.h"
+#include "get.h"
+#include "glthread.h"
+#include "glapioffsets.h"
+#include "histogram.h"
+#include "hint.h"
+#include "hash.h"
+#include "atifragshader.h"
+#include "light.h"
+#include "lines.h"
+#include "macros.h"
+#include "matrix.h"
+#include "occlude.h"
+#include "pixel.h"
+#include "points.h"
+#include "polygon.h"
+#if FEATURE_NV_vertex_program || FEATURE_NV_fragment_program
+#include "program.h"
+#endif
+#include "rastpos.h"
+#include "simple_list.h"
+#include "state.h"
+#include "stencil.h"
+#include "texcompress.h"
+#include "teximage.h"
+#include "texobj.h"
+#include "texstate.h"
+#include "mtypes.h"
+#include "varray.h"
+#include "version.h"
+#include "vtxfmt.h"
+#if _HAVE_FULL_GL
+#include "math/m_translate.h"
+#include "math/m_matrix.h"
+#include "math/m_xform.h"
+#include "math/mathmod.h"
+#endif
+#include "shaderobjects.h"
+
+#ifdef USE_SPARC_ASM
+#include "sparc/sparc.h"
+#endif
+
+#ifndef MESA_VERBOSE
+int MESA_VERBOSE = 0;
+#endif
+
+#ifndef MESA_DEBUG_FLAGS
+int MESA_DEBUG_FLAGS = 0;
+#endif
+
+
+/* ubyte -> float conversion */
+GLfloat _mesa_ubyte_to_float_color_tab[256];
+
+static void
+free_shared_state( GLcontext *ctx, struct gl_shared_state *ss );
+
+
+/**********************************************************************/
+/** \name OpenGL SI-style interface (new in Mesa 3.5)
+ *
+ * \if subset
+ * \note Most of these functions are never called in the Mesa subset.
+ * \endif
+ */
+/*@{*/
+
+/**
+ * Destroy context callback.
+ *
+ * \param gc context.
+ * \return GL_TRUE on success, or GL_FALSE on failure.
+ *
+ * \ifnot subset
+ * Called by window system/device driver (via __GLexports::destroyCurrent) when
+ * the rendering context is to be destroyed.
+ * \endif
+ *
+ * Frees the context data and the context structure.
+ */
+GLboolean
+_mesa_destroyContext(__GLcontext *gc)
+{
+ if (gc) {
+ _mesa_free_context_data(gc);
+ _mesa_free(gc);
+ }
+ return GL_TRUE;
+}
+
+/**
+ * Unbind context callback.
+ *
+ * \param gc context.
+ * \return GL_TRUE on success, or GL_FALSE on failure.
+ *
+ * \ifnot subset
+ * Called by window system/device driver (via __GLexports::loseCurrent)
+ * when the rendering context is made non-current.
+ * \endif
+ *
+ * No-op
+ */
+GLboolean
+_mesa_loseCurrent(__GLcontext *gc)
+{
+ /* XXX unbind context from thread */
+ (void) gc;
+ return GL_TRUE;
+}
+
+/**
+ * Bind context callback.
+ *
+ * \param gc context.
+ * \return GL_TRUE on success, or GL_FALSE on failure.
+ *
+ * \ifnot subset
+ * Called by window system/device driver (via __GLexports::makeCurrent)
+ * when the rendering context is made current.
+ * \endif
+ *
+ * No-op
+ */
+GLboolean
+_mesa_makeCurrent(__GLcontext *gc)
+{
+ /* XXX bind context to thread */
+ (void) gc;
+ return GL_TRUE;
+}
+
+/**
+ * Share context callback.
+ *
+ * \param gc context.
+ * \param gcShare shared context.
+ * \return GL_TRUE on success, or GL_FALSE on failure.
+ *
+ * \ifnot subset
+ * Called by window system/device driver (via __GLexports::shareContext)
+ * \endif
+ *
+ * Update the shared context reference count, gl_shared_state::RefCount.
+ */
+GLboolean
+_mesa_shareContext(__GLcontext *gc, __GLcontext *gcShare)
+{
+ if (gc && gcShare && gc->Shared && gcShare->Shared) {
+ gc->Shared->RefCount--;
+ if (gc->Shared->RefCount == 0) {
+ free_shared_state(gc, gc->Shared);
+ }
+ gc->Shared = gcShare->Shared;
+ gc->Shared->RefCount++;
+ return GL_TRUE;
+ }
+ else {
+ return GL_FALSE;
+ }
+}
+
+
+#if _HAVE_FULL_GL
+/**
+ * Copy context callback.
+ */
+GLboolean
+_mesa_copyContext(__GLcontext *dst, const __GLcontext *src, GLuint mask)
+{
+ if (dst && src) {
+ _mesa_copy_context( src, dst, mask );
+ return GL_TRUE;
+ }
+ else {
+ return GL_FALSE;
+ }
+}
+#endif
+
+/** No-op */
+GLboolean
+_mesa_forceCurrent(__GLcontext *gc)
+{
+ (void) gc;
+ return GL_TRUE;
+}
+
+/**
+ * Windows/buffer resizing notification callback.
+ *
+ * \param gc GL context.
+ * \return GL_TRUE on success, or GL_FALSE on failure.
+ */
+GLboolean
+_mesa_notifyResize(__GLcontext *gc)
+{
+ GLint x, y;
+ GLuint width, height;
+ __GLdrawablePrivate *d = gc->imports.getDrawablePrivate(gc);
+ if (!d || !d->getDrawableSize)
+ return GL_FALSE;
+ d->getDrawableSize( d, &x, &y, &width, &height );
+ /* update viewport, resize software buffers, etc. */
+ return GL_TRUE;
+}
+
+/**
+ * Window/buffer destruction notification callback.
+ *
+ * \param gc GL context.
+ *
+ * Called when the context's window/buffer is going to be destroyed.
+ *
+ * No-op
+ */
+void
+_mesa_notifyDestroy(__GLcontext *gc)
+{
+ /* Unbind from it. */
+ (void) gc;
+}
+
+/**
+ * Swap buffers notification callback.
+ *
+ * \param gc GL context.
+ *
+ * Called by window system just before swapping buffers.
+ * We have to finish any pending rendering.
+ */
+void
+_mesa_notifySwapBuffers(__GLcontext *gc)
+{
+ FLUSH_VERTICES( gc, 0 );
+}
+
+/** No-op */
+struct __GLdispatchStateRec *
+_mesa_dispatchExec(__GLcontext *gc)
+{
+ (void) gc;
+ return NULL;
+}
+
+/** No-op */
+void
+_mesa_beginDispatchOverride(__GLcontext *gc)
+{
+ (void) gc;
+}
+
+/** No-op */
+void
+_mesa_endDispatchOverride(__GLcontext *gc)
+{
+ (void) gc;
+}
+
+/**
+ * \ifnot subset
+ * Setup the exports.
+ *
+ * The window system will call these functions when it needs Mesa to do
+ * something.
+ *
+ * \note Device drivers should override these functions! For example,
+ * the Xlib driver should plug in the XMesa*-style functions into this
+ * structure. The XMesa-style functions should then call the _mesa_*
+ * version of these functions. This is an approximation to OO design
+ * (inheritance and virtual functions).
+ * \endif
+ *
+ * \if subset
+ * No-op.
+ *
+ * \endif
+ */
+static void
+_mesa_init_default_exports(__GLexports *exports)
+{
+#if _HAVE_FULL_GL
+ exports->destroyContext = _mesa_destroyContext;
+ exports->loseCurrent = _mesa_loseCurrent;
+ exports->makeCurrent = _mesa_makeCurrent;
+ exports->shareContext = _mesa_shareContext;
+ exports->copyContext = _mesa_copyContext;
+ exports->forceCurrent = _mesa_forceCurrent;
+ exports->notifyResize = _mesa_notifyResize;
+ exports->notifyDestroy = _mesa_notifyDestroy;
+ exports->notifySwapBuffers = _mesa_notifySwapBuffers;
+ exports->dispatchExec = _mesa_dispatchExec;
+ exports->beginDispatchOverride = _mesa_beginDispatchOverride;
+ exports->endDispatchOverride = _mesa_endDispatchOverride;
+#else
+ (void) exports;
+#endif
+}
+
+/**
+ * Exported OpenGL SI interface.
+ */
+__GLcontext *
+__glCoreCreateContext(__GLimports *imports, __GLcontextModes *modes)
+{
+ GLcontext *ctx;
+
+ ctx = (GLcontext *) (*imports->calloc)(NULL, 1, sizeof(GLcontext));
+ if (ctx == NULL) {
+ return NULL;
+ }
+
+ /* XXX doesn't work at this time */
+ _mesa_initialize_context(ctx, modes, NULL, NULL, NULL);
+ ctx->imports = *imports;
+
+ return ctx;
+}
+
+/**
+ * Exported OpenGL SI interface.
+ */
+void
+__glCoreNopDispatch(void)
+{
+#if 0
+ /* SI */
+ __gl_dispatch = __glNopDispatchState;
+#else
+ /* Mesa */
+ _glapi_set_dispatch(NULL);
+#endif
+}
+
+/*@}*/
+
+
+/**********************************************************************/
+/** \name GL Visual allocation/destruction */
+/**********************************************************************/
+/*@{*/
+
+/**
+ * Allocates a GLvisual structure and initializes it via
+ * _mesa_initialize_visual().
+ *
+ * \param rgbFlag GL_TRUE for RGB(A) mode, GL_FALSE for Color Index mode.
+ * \param dbFlag double buffering
+ * \param stereoFlag stereo buffer
+ * \param depthBits requested bits per depth buffer value. Any value in [0, 32]
+ * is acceptable but the actual depth type will be GLushort or GLuint as
+ * needed.
+ * \param stencilBits requested minimum bits per stencil buffer value
+ * \param accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits number of bits per color component in accum buffer.
+ * \param indexBits number of bits per pixel if \p rgbFlag is GL_FALSE
+ * \param redBits number of bits per color component in frame buffer for RGB(A)
+ * mode. We always use 8 in core Mesa though.
+ * \param greenBits same as above.
+ * \param blueBits same as above.
+ * \param alphaBits same as above.
+ * \param numSamples not really used.
+ *
+ * \return pointer to new GLvisual or NULL if requested parameters can't be
+ * met.
+ *
+ * \note Need to add params for level and numAuxBuffers (at least)
+ */
+GLvisual *
+_mesa_create_visual( GLboolean rgbFlag,
+ GLboolean dbFlag,
+ GLboolean stereoFlag,
+ GLint redBits,
+ GLint greenBits,
+ GLint blueBits,
+ GLint alphaBits,
+ GLint indexBits,
+ GLint depthBits,
+ GLint stencilBits,
+ GLint accumRedBits,
+ GLint accumGreenBits,
+ GLint accumBlueBits,
+ GLint accumAlphaBits,
+ GLint numSamples )
+{
+ GLvisual *vis = (GLvisual *) CALLOC( sizeof(GLvisual) );
+ if (vis) {
+ if (!_mesa_initialize_visual(vis, rgbFlag, dbFlag, stereoFlag,
+ redBits, greenBits, blueBits, alphaBits,
+ indexBits, depthBits, stencilBits,
+ accumRedBits, accumGreenBits,
+ accumBlueBits, accumAlphaBits,
+ numSamples)) {
+ FREE(vis);
+ return NULL;
+ }
+ }
+ return vis;
+}
+
+/**
+ * Makes some sanity checks and fills in the fields of the
+ * GLvisual object with the given parameters. If the caller needs
+ * to set additional fields, he should just probably init the whole GLvisual
+ * object himself.
+ * \return GL_TRUE on success, or GL_FALSE on failure.
+ *
+ * \sa _mesa_create_visual() above for the parameter description.
+ */
+GLboolean
+_mesa_initialize_visual( GLvisual *vis,
+ GLboolean rgbFlag,
+ GLboolean dbFlag,
+ GLboolean stereoFlag,
+ GLint redBits,
+ GLint greenBits,
+ GLint blueBits,
+ GLint alphaBits,
+ GLint indexBits,
+ GLint depthBits,
+ GLint stencilBits,
+ GLint accumRedBits,
+ GLint accumGreenBits,
+ GLint accumBlueBits,
+ GLint accumAlphaBits,
+ GLint numSamples )
+{
+ assert(vis);
+
+ if (depthBits < 0 || depthBits > 32) {
+ return GL_FALSE;
+ }
+ if (stencilBits < 0 || stencilBits > STENCIL_BITS) {
+ return GL_FALSE;
+ }
+ assert(accumRedBits >= 0);
+ assert(accumGreenBits >= 0);
+ assert(accumBlueBits >= 0);
+ assert(accumAlphaBits >= 0);
+
+ vis->rgbMode = rgbFlag;
+ vis->doubleBufferMode = dbFlag;
+ vis->stereoMode = stereoFlag;
+
+ vis->redBits = redBits;
+ vis->greenBits = greenBits;
+ vis->blueBits = blueBits;
+ vis->alphaBits = alphaBits;
+ vis->rgbBits = redBits + greenBits + blueBits;
+
+ vis->indexBits = indexBits;
+ vis->depthBits = depthBits;
+ vis->stencilBits = stencilBits;
+
+ vis->accumRedBits = accumRedBits;
+ vis->accumGreenBits = accumGreenBits;
+ vis->accumBlueBits = accumBlueBits;
+ vis->accumAlphaBits = accumAlphaBits;
+
+ vis->haveAccumBuffer = accumRedBits > 0;
+ vis->haveDepthBuffer = depthBits > 0;
+ vis->haveStencilBuffer = stencilBits > 0;
+
+ vis->numAuxBuffers = 0;
+ vis->level = 0;
+ vis->pixmapMode = 0;
+ vis->sampleBuffers = numSamples > 0 ? 1 : 0;
+ vis->samples = numSamples;
+
+ return GL_TRUE;
+}
+
+
+/**
+ * Destroy a visual and free its memory.
+ *
+ * \param vis visual.
+ *
+ * Frees the visual structure.
+ */
+void
+_mesa_destroy_visual( GLvisual *vis )
+{
+ FREE(vis);
+}
+
+/*@}*/
+
+
+/**********************************************************************/
+/** \name Context allocation, initialization, destroying
+ *
+ * The purpose of the most initialization functions here is to provide the
+ * default state values according to the OpenGL specification.
+ */
+/**********************************************************************/
+/*@{*/
+
+/**
+ * One-time initialization mutex lock.
+ *
+ * \sa Used by one_time_init().
+ */
+_glthread_DECLARE_STATIC_MUTEX(OneTimeLock);
+
+/**
+ * Calls all the various one-time-init functions in Mesa.
+ *
+ * While holding a global mutex lock, calls several initialization functions,
+ * and sets the glapi callbacks if the \c MESA_DEBUG environment variable is
+ * defined.
+ *
+ * \sa _math_init().
+ */
+static void
+one_time_init( GLcontext *ctx )
+{
+ static GLboolean alreadyCalled = GL_FALSE;
+ (void) ctx;
+ _glthread_LOCK_MUTEX(OneTimeLock);
+ if (!alreadyCalled) {
+ GLuint i;
+
+ /* do some implementation tests */
+ assert( sizeof(GLbyte) == 1 );
+ assert( sizeof(GLubyte) == 1 );
+ assert( sizeof(GLshort) == 2 );
+ assert( sizeof(GLushort) == 2 );
+ assert( sizeof(GLint) == 4 );
+ assert( sizeof(GLuint) == 4 );
+
+#if _HAVE_FULL_GL
+ _math_init();
+
+ for (i = 0; i < 256; i++) {
+ _mesa_ubyte_to_float_color_tab[i] = (float) i / 255.0F;
+ }
+#endif
+
+#ifdef USE_SPARC_ASM
+ _mesa_init_sparc_glapi_relocs();
+#endif
+ if (_mesa_getenv("MESA_DEBUG")) {
+ _glapi_noop_enable_warnings(GL_TRUE);
+ _glapi_set_warning_func( (_glapi_warning_func) _mesa_warning );
+ }
+ else {
+ _glapi_noop_enable_warnings(GL_FALSE);
+ }
+
+#if defined(DEBUG) && defined(__DATE__) && defined(__TIME__)
+ _mesa_debug(ctx, "Mesa %s DEBUG build %s %s\n",
+ MESA_VERSION_STRING, __DATE__, __TIME__);
+#endif
+
+ alreadyCalled = GL_TRUE;
+ }
+ _glthread_UNLOCK_MUTEX(OneTimeLock);
+}
+
+
+/**
+ * Allocate and initialize a shared context state structure.
+ * Initializes the display list, texture objects and vertex programs hash
+ * tables, allocates the texture objects. If it runs out of memory, frees
+ * everything already allocated before returning NULL.
+ *
+ * \return pointer to a gl_shared_state structure on success, or NULL on
+ * failure.
+ */
+static GLboolean
+alloc_shared_state( GLcontext *ctx )
+{
+ struct gl_shared_state *ss = CALLOC_STRUCT(gl_shared_state);
+ if (!ss)
+ return GL_FALSE;
+
+ ctx->Shared = ss;
+
+ _glthread_INIT_MUTEX(ss->Mutex);
+
+ ss->DisplayList = _mesa_NewHashTable();
+ ss->TexObjects = _mesa_NewHashTable();
+#if FEATURE_NV_vertex_program || FEATURE_NV_fragment_program
+ ss->Programs = _mesa_NewHashTable();
+#endif
+
+#if FEATURE_ARB_vertex_program
+ ss->DefaultVertexProgram = ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0);
+ if (!ss->DefaultVertexProgram)
+ goto cleanup;
+#endif
+#if FEATURE_ARB_fragment_program
+ ss->DefaultFragmentProgram = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
+ if (!ss->DefaultFragmentProgram)
+ goto cleanup;
+#endif
+#if FEATURE_ATI_fragment_shader
+ ss->ATIShaders = _mesa_NewHashTable();
+ ss->DefaultFragmentShader = _mesa_new_ati_fragment_shader(ctx, 0);
+ if (!ss->DefaultFragmentShader)
+ goto cleanup;
+#endif
+
+ ss->BufferObjects = _mesa_NewHashTable();
+
+ ss->GL2Objects = _mesa_NewHashTable ();
+
+ ss->Default1D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D);
+ if (!ss->Default1D)
+ goto cleanup;
+
+ ss->Default2D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_2D);
+ if (!ss->Default2D)
+ goto cleanup;
+
+ ss->Default3D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_3D);
+ if (!ss->Default3D)
+ goto cleanup;
+
+ ss->DefaultCubeMap = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_CUBE_MAP_ARB);
+ if (!ss->DefaultCubeMap)
+ goto cleanup;
+
+ ss->DefaultRect = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_RECTANGLE_NV);
+ if (!ss->DefaultRect)
+ goto cleanup;
+
+ /* Effectively bind the default textures to all texture units */
+ ss->Default1D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
+ ss->Default2D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
+ ss->Default3D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
+ ss->DefaultCubeMap->RefCount += MAX_TEXTURE_IMAGE_UNITS;
+ ss->DefaultRect->RefCount += MAX_TEXTURE_IMAGE_UNITS;
+
+#if FEATURE_EXT_framebuffer_object
+ ss->FrameBuffers = _mesa_NewHashTable();
+ if (!ss->FrameBuffers)
+ goto cleanup;
+ ss->RenderBuffers = _mesa_NewHashTable();
+ if (!ss->RenderBuffers)
+ goto cleanup;
+#endif
+
+
+ return GL_TRUE;
+
+ cleanup:
+ /* Ran out of memory at some point. Free everything and return NULL */
+ if (ss->DisplayList)
+ _mesa_DeleteHashTable(ss->DisplayList);
+ if (ss->TexObjects)
+ _mesa_DeleteHashTable(ss->TexObjects);
+#if FEATURE_NV_vertex_program
+ if (ss->Programs)
+ _mesa_DeleteHashTable(ss->Programs);
+#endif
+#if FEATURE_ARB_vertex_program
+ if (ss->DefaultVertexProgram)
+ ctx->Driver.DeleteProgram(ctx, ss->DefaultVertexProgram);
+#endif
+#if FEATURE_ARB_fragment_program
+ if (ss->DefaultFragmentProgram)
+ ctx->Driver.DeleteProgram(ctx, ss->DefaultFragmentProgram);
+#endif
+#if FEATURE_ATI_fragment_shader
+ if (ss->DefaultFragmentShader)
+ _mesa_delete_ati_fragment_shader(ctx, ss->DefaultFragmentShader);
+#endif
+#if FEATURE_ARB_vertex_buffer_object
+ if (ss->BufferObjects)
+ _mesa_DeleteHashTable(ss->BufferObjects);
+#endif
+
+ if (ss->GL2Objects)
+ _mesa_DeleteHashTable (ss->GL2Objects);
+
+#if FEATURE_EXT_framebuffer_object
+ if (ss->FrameBuffers)
+ _mesa_DeleteHashTable(ss->FrameBuffers);
+ if (ss->RenderBuffers)
+ _mesa_DeleteHashTable(ss->RenderBuffers);
+#endif
+
+ if (ss->Default1D)
+ (*ctx->Driver.DeleteTexture)(ctx, ss->Default1D);
+ if (ss->Default2D)
+ (*ctx->Driver.DeleteTexture)(ctx, ss->Default2D);
+ if (ss->Default3D)
+ (*ctx->Driver.DeleteTexture)(ctx, ss->Default3D);
+ if (ss->DefaultCubeMap)
+ (*ctx->Driver.DeleteTexture)(ctx, ss->DefaultCubeMap);
+ if (ss->DefaultRect)
+ (*ctx->Driver.DeleteTexture)(ctx, ss->DefaultRect);
+ if (ss)
+ _mesa_free(ss);
+ return GL_FALSE;
+}
+
+/**
+ * Deallocate a shared state context and all children structures.
+ *
+ * \param ctx GL context.
+ * \param ss shared state pointer.
+ *
+ * Frees the display lists, the texture objects (calling the driver texture
+ * deletion callback to free its private data) and the vertex programs, as well
+ * as their hash tables.
+ *
+ * \sa alloc_shared_state().
+ */
+static void
+free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
+{
+ /* Free display lists */
+ while (1) {
+ GLuint list = _mesa_HashFirstEntry(ss->DisplayList);
+ if (list) {
+ _mesa_destroy_list(ctx, list);
+ }
+ else {
+ break;
+ }
+ }
+ _mesa_DeleteHashTable(ss->DisplayList);
+
+ /* Free texture objects */
+ ASSERT(ctx->Driver.DeleteTexture);
+ /* the default textures */
+ (*ctx->Driver.DeleteTexture)(ctx, ss->Default1D);
+ (*ctx->Driver.DeleteTexture)(ctx, ss->Default2D);
+ (*ctx->Driver.DeleteTexture)(ctx, ss->Default3D);
+ (*ctx->Driver.DeleteTexture)(ctx, ss->DefaultCubeMap);
+ (*ctx->Driver.DeleteTexture)(ctx, ss->DefaultRect);
+ /* all other textures */
+ while (1) {
+ GLuint texName = _mesa_HashFirstEntry(ss->TexObjects);
+ if (texName) {
+ struct gl_texture_object *texObj = (struct gl_texture_object *)
+ _mesa_HashLookup(ss->TexObjects, texName);
+ ASSERT(texObj);
+ (*ctx->Driver.DeleteTexture)(ctx, texObj);
+ _mesa_HashRemove(ss->TexObjects, texName);
+ }
+ else {
+ break;
+ }
+ }
+ _mesa_DeleteHashTable(ss->TexObjects);
+
+#if defined(FEATURE_NV_vertex_program) || defined(FEATURE_NV_fragment_program)
+ /* Free vertex/fragment programs */
+ while (1) {
+ GLuint prog = _mesa_HashFirstEntry(ss->Programs);
+ if (prog) {
+ struct program *p = (struct program *) _mesa_HashLookup(ss->Programs,
+ prog);
+ ASSERT(p);
+ ctx->Driver.DeleteProgram(ctx, p);
+ _mesa_HashRemove(ss->Programs, prog);
+ }
+ else {
+ break;
+ }
+ }
+ _mesa_DeleteHashTable(ss->Programs);
+#endif
+#if FEATURE_ARB_vertex_program
+ _mesa_delete_program(ctx, ss->DefaultVertexProgram);
+#endif
+#if FEATURE_ARB_fragment_program
+ _mesa_delete_program(ctx, ss->DefaultFragmentProgram);
+#endif
+
+#if FEATURE_ATI_fragment_shader
+ /* Free ATI fragment shaders */
+ while (1) {
+ GLuint prog = _mesa_HashFirstEntry(ss->ATIShaders);
+ if (prog) {
+ struct ati_fragment_shader *s = (struct ati_fragment_shader *)
+ _mesa_HashLookup(ss->ATIShaders, prog);
+ ASSERT(s);
+ _mesa_delete_ati_fragment_shader(ctx, s);
+ _mesa_HashRemove(ss->ATIShaders, prog);
+ }
+ else {
+ break;
+ }
+ }
+ _mesa_DeleteHashTable(ss->ATIShaders);
+ _mesa_delete_ati_fragment_shader(ctx, ss->DefaultFragmentShader);
+#endif
+
+#if FEATURE_ARB_vertex_buffer_object
+ _mesa_DeleteHashTable(ss->BufferObjects);
+#endif
+
+#if FEATURE_ARB_shader_objects
+ _mesa_DeleteHashTable (ss->GL2Objects);
+#endif
+
+#if FEATURE_EXT_framebuffer_object
+ _mesa_DeleteHashTable(ss->FrameBuffers);
+ _mesa_DeleteHashTable(ss->RenderBuffers);
+#endif
+
+ _glthread_DESTROY_MUTEX(ss->Mutex);
+
+ FREE(ss);
+}
+
+
+/**
+ * Initialize fields of gl_current_attrib (aka ctx->Current.*)
+ */
+static void
+_mesa_init_current( GLcontext *ctx )
+{
+ GLuint i;
+
+ /* Current group */
+ for (i = 0; i < VERT_ATTRIB_MAX; i++) {
+ ASSIGN_4V( ctx->Current.Attrib[i], 0.0, 0.0, 0.0, 1.0 );
+ }
+ /* special cases: */
+ ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_WEIGHT], 1.0, 0.0, 0.0, 1.0 );
+ ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_NORMAL], 0.0, 0.0, 1.0, 1.0 );
+ ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR0], 1.0, 1.0, 1.0, 1.0 );
+ ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR1], 0.0, 0.0, 0.0, 1.0 );
+ ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_FOG], 0.0, 0.0, 0.0, 0.0 );
+
+ ctx->Current.Index = 1;
+ ctx->Current.EdgeFlag = GL_TRUE;
+}
+
+
+/**
+ * Init vertex/fragment program native limits from logical limits.
+ */
+static void
+init_natives(struct gl_program_constants *prog)
+{
+ prog->MaxNativeInstructions = prog->MaxInstructions;
+ prog->MaxNativeAluInstructions = prog->MaxAluInstructions;
+ prog->MaxNativeTexInstructions = prog->MaxTexInstructions;
+ prog->MaxNativeTexIndirections = prog->MaxTexIndirections;
+ prog->MaxNativeAttribs = prog->MaxAttribs;
+ prog->MaxNativeTemps = prog->MaxTemps;
+ prog->MaxNativeAddressRegs = prog->MaxAddressRegs;
+ prog->MaxNativeParameters = prog->MaxParameters;
+}
+
+
+/**
+ * Initialize fields of gl_constants (aka ctx->Const.*).
+ * Use defaults from config.h. The device drivers will often override
+ * some of these values (such as number of texture units).
+ */
+static void
+_mesa_init_constants( GLcontext *ctx )
+{
+ assert(ctx);
+
+ assert(MAX_TEXTURE_LEVELS >= MAX_3D_TEXTURE_LEVELS);
+ assert(MAX_TEXTURE_LEVELS >= MAX_CUBE_TEXTURE_LEVELS);
+
+ /* Constants, may be overriden (usually only reduced) by device drivers */
+ ctx->Const.MaxTextureLevels = MAX_TEXTURE_LEVELS;
+ ctx->Const.Max3DTextureLevels = MAX_3D_TEXTURE_LEVELS;
+ ctx->Const.MaxCubeTextureLevels = MAX_CUBE_TEXTURE_LEVELS;
+ ctx->Const.MaxTextureRectSize = MAX_TEXTURE_RECT_SIZE;
+ ctx->Const.MaxTextureUnits = MAX_TEXTURE_UNITS;
+ ctx->Const.MaxTextureCoordUnits = MAX_TEXTURE_COORD_UNITS;
+ ctx->Const.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
+ ctx->Const.MaxTextureMaxAnisotropy = MAX_TEXTURE_MAX_ANISOTROPY;
+ ctx->Const.MaxTextureLodBias = MAX_TEXTURE_LOD_BIAS;
+ ctx->Const.MaxArrayLockSize = MAX_ARRAY_LOCK_SIZE;
+ ctx->Const.SubPixelBits = SUB_PIXEL_BITS;
+ ctx->Const.MinPointSize = MIN_POINT_SIZE;
+ ctx->Const.MaxPointSize = MAX_POINT_SIZE;
+ ctx->Const.MinPointSizeAA = MIN_POINT_SIZE;
+ ctx->Const.MaxPointSizeAA = MAX_POINT_SIZE;
+ ctx->Const.PointSizeGranularity = (GLfloat) POINT_SIZE_GRANULARITY;
+ ctx->Const.MinLineWidth = MIN_LINE_WIDTH;
+ ctx->Const.MaxLineWidth = MAX_LINE_WIDTH;
+ ctx->Const.MinLineWidthAA = MIN_LINE_WIDTH;
+ ctx->Const.MaxLineWidthAA = MAX_LINE_WIDTH;
+ ctx->Const.LineWidthGranularity = (GLfloat) LINE_WIDTH_GRANULARITY;
+ ctx->Const.MaxColorTableSize = MAX_COLOR_TABLE_SIZE;
+ ctx->Const.MaxConvolutionWidth = MAX_CONVOLUTION_WIDTH;
+ ctx->Const.MaxConvolutionHeight = MAX_CONVOLUTION_HEIGHT;
+ ctx->Const.MaxClipPlanes = MAX_CLIP_PLANES;
+ ctx->Const.MaxLights = MAX_LIGHTS;
+ ctx->Const.MaxShininess = 128.0;
+ ctx->Const.MaxSpotExponent = 128.0;
+ ctx->Const.MaxViewportWidth = MAX_WIDTH;
+ ctx->Const.MaxViewportHeight = MAX_HEIGHT;
+#if FEATURE_ARB_vertex_program
+ ctx->Const.VertexProgram.MaxInstructions = MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS;
+ ctx->Const.VertexProgram.MaxAluInstructions = 0;
+ ctx->Const.VertexProgram.MaxTexInstructions = 0;
+ ctx->Const.VertexProgram.MaxTexIndirections = 0;
+ ctx->Const.VertexProgram.MaxAttribs = MAX_NV_VERTEX_PROGRAM_INPUTS;
+ ctx->Const.VertexProgram.MaxTemps = MAX_NV_VERTEX_PROGRAM_TEMPS;
+ ctx->Const.VertexProgram.MaxParameters = MAX_NV_VERTEX_PROGRAM_PARAMS;
+ ctx->Const.VertexProgram.MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS;
+ ctx->Const.VertexProgram.MaxEnvParams = MAX_NV_VERTEX_PROGRAM_PARAMS;
+ ctx->Const.VertexProgram.MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS;
+ init_natives(&ctx->Const.VertexProgram);
+#endif
+#if FEATURE_ARB_fragment_program
+ ctx->Const.FragmentProgram.MaxInstructions = MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS;
+ ctx->Const.FragmentProgram.MaxAluInstructions = MAX_FRAGMENT_PROGRAM_ALU_INSTRUCTIONS;
+ ctx->Const.FragmentProgram.MaxTexInstructions = MAX_FRAGMENT_PROGRAM_TEX_INSTRUCTIONS;
+ ctx->Const.FragmentProgram.MaxTexIndirections = MAX_FRAGMENT_PROGRAM_TEX_INDIRECTIONS;
+ ctx->Const.FragmentProgram.MaxAttribs = MAX_NV_FRAGMENT_PROGRAM_INPUTS;
+ ctx->Const.FragmentProgram.MaxTemps = MAX_NV_FRAGMENT_PROGRAM_TEMPS;
+ ctx->Const.FragmentProgram.MaxParameters = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
+ ctx->Const.FragmentProgram.MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS;
+ ctx->Const.FragmentProgram.MaxEnvParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
+ ctx->Const.FragmentProgram.MaxAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS;
+ init_natives(&ctx->Const.FragmentProgram);
+#endif
+ ctx->Const.MaxProgramMatrices = MAX_PROGRAM_MATRICES;
+ ctx->Const.MaxProgramMatrixStackDepth = MAX_PROGRAM_MATRIX_STACK_DEPTH;
+
+ /* If we're running in the X server, do bounds checking to prevent
+ * segfaults and server crashes!
+ */
+#if defined(XFree86LOADER) && defined(IN_MODULE)
+ ctx->Const.CheckArrayBounds = GL_TRUE;
+#else
+ ctx->Const.CheckArrayBounds = GL_FALSE;
+#endif
+
+ /* GL_ARB_draw_buffers */
+ ctx->Const.MaxDrawBuffers = MAX_DRAW_BUFFERS;
+
+ /* GL_OES_read_format */
+ ctx->Const.ColorReadFormat = GL_RGBA;
+ ctx->Const.ColorReadType = GL_UNSIGNED_BYTE;
+
+#if FEATURE_EXT_framebuffer_object
+ ctx->Const.MaxColorAttachments = MAX_COLOR_ATTACHMENTS;
+ ctx->Const.MaxRenderbufferSize = MAX_WIDTH;
+#endif
+
+ /* sanity checks */
+ ASSERT(ctx->Const.MaxTextureUnits == MAX2(ctx->Const.MaxTextureImageUnits, ctx->Const.MaxTextureCoordUnits));
+ ASSERT(ctx->Const.FragmentProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS);
+ ASSERT(ctx->Const.VertexProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS);
+}
+
+
+/**
+ * Initialize the attribute groups in a GL context.
+ *
+ * \param ctx GL context.
+ *
+ * Initializes all the attributes, calling the respective <tt>init*</tt>
+ * functions for the more complex data structures.
+ */
+static GLboolean
+init_attrib_groups( GLcontext *ctx )
+{
+ assert(ctx);
+
+ /* Constants */
+ _mesa_init_constants( ctx );
+
+ /* Extensions */
+ _mesa_init_extensions( ctx );
+
+ /* Attribute Groups */
+ _mesa_init_accum( ctx );
+ _mesa_init_attrib( ctx );
+ _mesa_init_buffer_objects( ctx );
+ _mesa_init_color( ctx );
+ _mesa_init_colortables( ctx );
+ _mesa_init_current( ctx );
+ _mesa_init_depth( ctx );
+ _mesa_init_debug( ctx );
+ _mesa_init_display_list( ctx );
+ _mesa_init_eval( ctx );
+ _mesa_init_feedback( ctx );
+ _mesa_init_fog( ctx );
+ _mesa_init_histogram( ctx );
+ _mesa_init_hint( ctx );
+ _mesa_init_line( ctx );
+ _mesa_init_lighting( ctx );
+ _mesa_init_matrix( ctx );
+ _mesa_init_multisample( ctx );
+ _mesa_init_pixel( ctx );
+ _mesa_init_point( ctx );
+ _mesa_init_polygon( ctx );
+ _mesa_init_program( ctx );
+ _mesa_init_query( ctx );
+ _mesa_init_rastpos( ctx );
+ _mesa_init_scissor( ctx );
+ _mesa_init_shaderobjects (ctx);
+ _mesa_init_stencil( ctx );
+ _mesa_init_transform( ctx );
+ _mesa_init_varray( ctx );
+ _mesa_init_viewport( ctx );
+
+ if (!_mesa_init_texture( ctx ))
+ return GL_FALSE;
+
+ _mesa_init_texture_s3tc( ctx );
+ _mesa_init_texture_fxt1( ctx );
+
+ /* Miscellaneous */
+ ctx->NewState = _NEW_ALL;
+ ctx->ErrorValue = (GLenum) GL_NO_ERROR;
+ ctx->_Facing = 0;
+
+ return GL_TRUE;
+}
+
+
+/**
+ * This is the default function we plug into all dispatch table slots
+ * This helps prevents a segfault when someone calls a GL function without
+ * first checking if the extension's supported.
+ */
+static int
+generic_nop(void)
+{
+ _mesa_problem(NULL, "User called no-op dispatch function (an unsupported extension function?)");
+ return 0;
+}
+
+
+/**
+ * Allocate and initialize a new dispatch table.
+ */
+static struct _glapi_table *
+alloc_dispatch_table(void)
+{
+ /* Find the larger of Mesa's dispatch table and libGL's dispatch table.
+ * In practice, this'll be the same for stand-alone Mesa. But for DRI
+ * Mesa we do this to accomodate different versions of libGL and various
+ * DRI drivers.
+ */
+ GLint numEntries = MAX2(_glapi_get_dispatch_table_size(),
+ sizeof(struct _glapi_table) / sizeof(_glapi_proc));
+ struct _glapi_table *table =
+ (struct _glapi_table *) _mesa_malloc(numEntries * sizeof(_glapi_proc));
+ if (table) {
+ _glapi_proc *entry = (_glapi_proc *) table;
+ GLint i;
+ for (i = 0; i < numEntries; i++) {
+ entry[i] = (_glapi_proc) generic_nop;
+ }
+ }
+ return table;
+}
+
+
+/**
+ * Initialize a GLcontext struct (rendering context).
+ *
+ * This includes allocating all the other structs and arrays which hang off of
+ * the context by pointers.
+ * Note that the driver needs to pass in its dd_function_table here since
+ * we need to at least call driverFunctions->NewTextureObject to create the
+ * default texture objects.
+ *
+ * Called by _mesa_create_context().
+ *
+ * Performs the imports and exports callback tables initialization, and
+ * miscellaneous one-time initializations. If no shared context is supplied one
+ * is allocated, and increase its reference count. Setups the GL API dispatch
+ * tables. Initialize the TNL module. Sets the maximum Z buffer depth.
+ * Finally queries the \c MESA_DEBUG and \c MESA_VERBOSE environment variables
+ * for debug flags.
+ *
+ * \param ctx the context to initialize
+ * \param visual describes the visual attributes for this context
+ * \param share_list points to context to share textures, display lists,
+ * etc with, or NULL
+ * \param driverFunctions table of device driver functions for this context
+ * to use
+ * \param driverContext pointer to driver-specific context data
+ */
+GLboolean
+_mesa_initialize_context( GLcontext *ctx,
+ const GLvisual *visual,
+ GLcontext *share_list,
+ const struct dd_function_table *driverFunctions,
+ void *driverContext )
+{
+ ASSERT(driverContext);
+ assert(driverFunctions->NewTextureObject);
+ assert(driverFunctions->FreeTexImageData);
+
+ /* If the driver wants core Mesa to use special imports, it'll have to
+ * override these defaults.
+ */
+ _mesa_init_default_imports( &(ctx->imports), driverContext );
+
+ /* initialize the exports (Mesa functions called by the window system) */
+ _mesa_init_default_exports( &(ctx->exports) );
+
+ /* misc one-time initializations */
+ one_time_init(ctx);
+
+ ctx->Visual = *visual;
+ ctx->DrawBuffer = NULL;
+ ctx->ReadBuffer = NULL;
+ ctx->WinSysDrawBuffer = NULL;
+ ctx->WinSysReadBuffer = NULL;
+
+ /* Plug in driver functions and context pointer here.
+ * This is important because when we call alloc_shared_state() below
+ * we'll call ctx->Driver.NewTextureObject() to create the default
+ * textures.
+ */
+ ctx->Driver = *driverFunctions;
+ ctx->DriverCtx = driverContext;
+
+ if (share_list) {
+ /* share state with another context */
+ ctx->Shared = share_list->Shared;
+ }
+ else {
+ /* allocate new, unshared state */
+ if (!alloc_shared_state( ctx )) {
+ return GL_FALSE;
+ }
+ }
+ _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
+ ctx->Shared->RefCount++;
+ _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+
+ if (!init_attrib_groups( ctx )) {
+ free_shared_state(ctx, ctx->Shared);
+ return GL_FALSE;
+ }
+
+ /* setup the API dispatch tables */
+ ctx->Exec = alloc_dispatch_table();
+ ctx->Save = alloc_dispatch_table();
+ if (!ctx->Exec || !ctx->Save) {
+ free_shared_state(ctx, ctx->Shared);
+ if (ctx->Exec)
+ _mesa_free(ctx->Exec);
+ }
+ _mesa_init_exec_table(ctx->Exec);
+ ctx->CurrentDispatch = ctx->Exec;
+#if _HAVE_FULL_GL
+ _mesa_init_dlist_table(ctx->Save);
+ _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
+ /* Neutral tnl module stuff */
+ _mesa_init_exec_vtxfmt( ctx );
+ ctx->TnlModule.Current = NULL;
+ ctx->TnlModule.SwapCount = 0;
+#endif
+
+ ctx->_MaintainTexEnvProgram = (_mesa_getenv("MESA_TEX_PROG") != NULL);
+ ctx->_UseTexEnvProgram = ctx->_MaintainTexEnvProgram;
+
+ ctx->_MaintainTnlProgram = (_mesa_getenv("MESA_TNL_PROG") != NULL);
+ if (ctx->_MaintainTnlProgram)
+ ctx->_MaintainTexEnvProgram = 1; /* this is required... */
+
+ ctx->FirstTimeCurrent = GL_TRUE;
+
+ return GL_TRUE;
+}
+
+
+/**
+ * Allocate and initialize a GLcontext structure.
+ * Note that the driver needs to pass in its dd_function_table here since
+ * we need to at least call driverFunctions->NewTextureObject to initialize
+ * the rendering context.
+ *
+ * \param visual a GLvisual pointer (we copy the struct contents)
+ * \param share_list another context to share display lists with or NULL
+ * \param driverFunctions points to the dd_function_table into which the
+ * driver has plugged in all its special functions.
+ * \param driverCtx points to the device driver's private context state
+ *
+ * \return pointer to a new __GLcontextRec or NULL if error.
+ */
+GLcontext *
+_mesa_create_context( const GLvisual *visual,
+ GLcontext *share_list,
+ const struct dd_function_table *driverFunctions,
+ void *driverContext )
+
+{
+ GLcontext *ctx;
+
+ ASSERT(visual);
+ ASSERT(driverContext);
+
+ ctx = (GLcontext *) _mesa_calloc(sizeof(GLcontext));
+ if (!ctx)
+ return NULL;
+
+ if (_mesa_initialize_context(ctx, visual, share_list,
+ driverFunctions, driverContext)) {
+ return ctx;
+ }
+ else {
+ _mesa_free(ctx);
+ return NULL;
+ }
+}
+
+
+/**
+ * Free the data associated with the given context.
+ *
+ * But doesn't free the GLcontext struct itself.
+ *
+ * \sa _mesa_initialize_context() and init_attrib_groups().
+ */
+void
+_mesa_free_context_data( GLcontext *ctx )
+{
+ /* if we're destroying the current context, unbind it first */
+ if (ctx == _mesa_get_current_context()) {
+ _mesa_make_current(NULL, NULL, NULL);
+ }
+
+ _mesa_free_lighting_data( ctx );
+ _mesa_free_eval_data( ctx );
+ _mesa_free_texture_data( ctx );
+ _mesa_free_matrix_data( ctx );
+ _mesa_free_viewport_data( ctx );
+ _mesa_free_colortables_data( ctx );
+ _mesa_free_program_data(ctx);
+ _mesa_free_query_data(ctx);
+
+#if FEATURE_ARB_vertex_buffer_object
+ _mesa_delete_buffer_object(ctx, ctx->Array.NullBufferObj);
+#endif
+
+ /* free dispatch tables */
+ _mesa_free(ctx->Exec);
+ _mesa_free(ctx->Save);
+
+ /* Shared context state (display lists, textures, etc) */
+ _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
+ ctx->Shared->RefCount--;
+ assert(ctx->Shared->RefCount >= 0);
+ _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+ if (ctx->Shared->RefCount == 0) {
+ /* free shared state */
+ free_shared_state( ctx, ctx->Shared );
+ }
+
+ if (ctx->Extensions.String)
+ FREE((void *) ctx->Extensions.String);
+}
+
+
+/**
+ * Destroy a GLcontext structure.
+ *
+ * \param ctx GL context.
+ *
+ * Calls _mesa_free_context_data() and frees the GLcontext structure itself.
+ */
+void
+_mesa_destroy_context( GLcontext *ctx )
+{
+ if (ctx) {
+ _mesa_free_context_data(ctx);
+ FREE( (void *) ctx );
+ }
+}
+
+
+#if _HAVE_FULL_GL
+/**
+ * Copy attribute groups from one context to another.
+ *
+ * \param src source context
+ * \param dst destination context
+ * \param mask bitwise OR of GL_*_BIT flags
+ *
+ * According to the bits specified in \p mask, copies the corresponding
+ * attributes from \p src into \p dst. For many of the attributes a simple \c
+ * memcpy is not enough due to the existence of internal pointers in their data
+ * structures.
+ */
+void
+_mesa_copy_context( const GLcontext *src, GLcontext *dst, GLuint mask )
+{
+ if (mask & GL_ACCUM_BUFFER_BIT) {
+ /* OK to memcpy */
+ dst->Accum = src->Accum;
+ }
+ if (mask & GL_COLOR_BUFFER_BIT) {
+ /* OK to memcpy */
+ dst->Color = src->Color;
+ }
+ if (mask & GL_CURRENT_BIT) {
+ /* OK to memcpy */
+ dst->Current = src->Current;
+ }
+ if (mask & GL_DEPTH_BUFFER_BIT) {
+ /* OK to memcpy */
+ dst->Depth = src->Depth;
+ }
+ if (mask & GL_ENABLE_BIT) {
+ /* no op */
+ }
+ if (mask & GL_EVAL_BIT) {
+ /* OK to memcpy */
+ dst->Eval = src->Eval;
+ }
+ if (mask & GL_FOG_BIT) {
+ /* OK to memcpy */
+ dst->Fog = src->Fog;
+ }
+ if (mask & GL_HINT_BIT) {
+ /* OK to memcpy */
+ dst->Hint = src->Hint;
+ }
+ if (mask & GL_LIGHTING_BIT) {
+ GLuint i;
+ /* begin with memcpy */
+ dst->Light = src->Light;
+ /* fixup linked lists to prevent pointer insanity */
+ make_empty_list( &(dst->Light.EnabledList) );
+ for (i = 0; i < MAX_LIGHTS; i++) {
+ if (dst->Light.Light[i].Enabled) {
+ insert_at_tail(&(dst->Light.EnabledList), &(dst->Light.Light[i]));
+ }
+ }
+ }
+ if (mask & GL_LINE_BIT) {
+ /* OK to memcpy */
+ dst->Line = src->Line;
+ }
+ if (mask & GL_LIST_BIT) {
+ /* OK to memcpy */
+ dst->List = src->List;
+ }
+ if (mask & GL_PIXEL_MODE_BIT) {
+ /* OK to memcpy */
+ dst->Pixel = src->Pixel;
+ }
+ if (mask & GL_POINT_BIT) {
+ /* OK to memcpy */
+ dst->Point = src->Point;
+ }
+ if (mask & GL_POLYGON_BIT) {
+ /* OK to memcpy */
+ dst->Polygon = src->Polygon;
+ }
+ if (mask & GL_POLYGON_STIPPLE_BIT) {
+ /* Use loop instead of MEMCPY due to problem with Portland Group's
+ * C compiler. Reported by John Stone.
+ */
+ GLuint i;
+ for (i = 0; i < 32; i++) {
+ dst->PolygonStipple[i] = src->PolygonStipple[i];
+ }
+ }
+ if (mask & GL_SCISSOR_BIT) {
+ /* OK to memcpy */
+ dst->Scissor = src->Scissor;
+ }
+ if (mask & GL_STENCIL_BUFFER_BIT) {
+ /* OK to memcpy */
+ dst->Stencil = src->Stencil;
+ }
+ if (mask & GL_TEXTURE_BIT) {
+ /* Cannot memcpy because of pointers */
+ _mesa_copy_texture_state(src, dst);
+ }
+ if (mask & GL_TRANSFORM_BIT) {
+ /* OK to memcpy */
+ dst->Transform = src->Transform;
+ }
+ if (mask & GL_VIEWPORT_BIT) {
+ /* Cannot use memcpy, because of pointers in GLmatrix _WindowMap */
+ dst->Viewport.X = src->Viewport.X;
+ dst->Viewport.Y = src->Viewport.Y;
+ dst->Viewport.Width = src->Viewport.Width;
+ dst->Viewport.Height = src->Viewport.Height;
+ dst->Viewport.Near = src->Viewport.Near;
+ dst->Viewport.Far = src->Viewport.Far;
+ _math_matrix_copy(&dst->Viewport._WindowMap, &src->Viewport._WindowMap);
+ }
+
+ /* XXX FIXME: Call callbacks?
+ */
+ dst->NewState = _NEW_ALL;
+}
+#endif
+
+
+/**
+ * Check if the given context can render into the given framebuffer
+ * by checking visual attributes.
+ *
+ * XXX this may go away someday because we're moving toward more freedom
+ * in binding contexts to drawables with different visual attributes.
+ * The GL_EXT_f_b_o extension is prompting some of that.
+ *
+ * \return GL_TRUE if compatible, GL_FALSE otherwise.
+ */
+static GLboolean
+check_compatible(const GLcontext *ctx, const GLframebuffer *buffer)
+{
+ const GLvisual *ctxvis = &ctx->Visual;
+ const GLvisual *bufvis = &buffer->Visual;
+
+ if (ctxvis == bufvis)
+ return GL_TRUE;
+
+ if (ctxvis->rgbMode != bufvis->rgbMode)
+ return GL_FALSE;
+#if 0
+ /* disabling this fixes the fgl_glxgears pbuffer demo */
+ if (ctxvis->doubleBufferMode && !bufvis->doubleBufferMode)
+ return GL_FALSE;
+#endif
+ if (ctxvis->stereoMode && !bufvis->stereoMode)
+ return GL_FALSE;
+ if (ctxvis->haveAccumBuffer && !bufvis->haveAccumBuffer)
+ return GL_FALSE;
+ if (ctxvis->haveDepthBuffer && !bufvis->haveDepthBuffer)
+ return GL_FALSE;
+ if (ctxvis->haveStencilBuffer && !bufvis->haveStencilBuffer)
+ return GL_FALSE;
+ if (ctxvis->redMask && ctxvis->redMask != bufvis->redMask)
+ return GL_FALSE;
+ if (ctxvis->greenMask && ctxvis->greenMask != bufvis->greenMask)
+ return GL_FALSE;
+ if (ctxvis->blueMask && ctxvis->blueMask != bufvis->blueMask)
+ return GL_FALSE;
+ if (ctxvis->depthBits && ctxvis->depthBits != bufvis->depthBits)
+ return GL_FALSE;
+ if (ctxvis->stencilBits && ctxvis->stencilBits != bufvis->stencilBits)
+ return GL_FALSE;
+
+ return GL_TRUE;
+}
+
+
+/**
+ * Do one-time initialization for the given framebuffer. Specifically,
+ * ask the driver for the window's current size and update the framebuffer
+ * object to match.
+ * Really, the device driver should totally take care of this.
+ */
+static void
+initialize_framebuffer_size(GLcontext *ctx, GLframebuffer *fb)
+{
+ GLuint width, height;
+ ASSERT(ctx->Driver.GetBufferSize);
+ ctx->Driver.GetBufferSize(fb, &width, &height);
+ if (ctx->Driver.ResizeBuffers)
+ ctx->Driver.ResizeBuffers(ctx, fb, width, height);
+ fb->Initialized = GL_TRUE;
+}
+
+
+/**
+ * Bind the given context to the given drawBuffer and readBuffer and
+ * make it the current context for the calling thread.
+ * We'll render into the drawBuffer and read pixels from the
+ * readBuffer (i.e. glRead/CopyPixels, glCopyTexImage, etc).
+ *
+ * We check that the context's and framebuffer's visuals are compatible
+ * and return immediately if they're not.
+ *
+ * \param newCtx the new GL context. If NULL then there will be no current GL
+ * context.
+ * \param drawBuffer the drawing framebuffer
+ * \param readBuffer the reading framebuffer
+ */
+void
+_mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer,
+ GLframebuffer *readBuffer )
+{
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(newCtx, "_mesa_make_current()\n");
+
+ /* Check that the context's and framebuffer's visuals are compatible.
+ */
+ if (newCtx && drawBuffer && newCtx->WinSysDrawBuffer != drawBuffer) {
+ if (!check_compatible(newCtx, drawBuffer)) {
+ _mesa_warning(newCtx,
+ "MakeCurrent: incompatible visuals for context and drawbuffer");
+ return;
+ }
+ }
+ if (newCtx && readBuffer && newCtx->WinSysReadBuffer != readBuffer) {
+ if (!check_compatible(newCtx, readBuffer)) {
+ _mesa_warning(newCtx,
+ "MakeCurrent: incompatible visuals for context and readbuffer");
+ return;
+ }
+ }
+
+ /* We used to call _glapi_check_multithread() here. Now do it in drivers */
+ _glapi_set_context((void *) newCtx);
+ ASSERT(_mesa_get_current_context() == newCtx);
+
+ if (!newCtx) {
+ _glapi_set_dispatch(NULL); /* none current */
+ }
+ else {
+ _glapi_set_dispatch(newCtx->CurrentDispatch);
+
+ if (drawBuffer && readBuffer) {
+ /* TODO: check if newCtx and buffer's visual match??? */
+
+ ASSERT(drawBuffer->Name == 0);
+ ASSERT(readBuffer->Name == 0);
+ newCtx->WinSysDrawBuffer = drawBuffer;
+ newCtx->WinSysReadBuffer = readBuffer;
+
+ /*
+ * Only set the context's Draw/ReadBuffer fields if they're NULL
+ * or not bound to a user-created FBO.
+ */
+ if (!newCtx->DrawBuffer || newCtx->DrawBuffer->Name == 0) {
+ newCtx->DrawBuffer = drawBuffer;
+ }
+ if (!newCtx->ReadBuffer || newCtx->ReadBuffer->Name == 0) {
+ newCtx->ReadBuffer = readBuffer;
+ }
+
+ newCtx->NewState |= _NEW_BUFFERS;
+
+#if _HAVE_FULL_GL
+ if (!drawBuffer->Initialized) {
+ initialize_framebuffer_size(newCtx, drawBuffer);
+ }
+ if (readBuffer != drawBuffer && !readBuffer->Initialized) {
+ initialize_framebuffer_size(newCtx, readBuffer);
+ }
+#endif
+ if (newCtx->FirstTimeCurrent) {
+ /* set initial viewport and scissor size now */
+ _mesa_set_viewport(newCtx, 0, 0,
+ drawBuffer->Width, drawBuffer->Height);
+ _mesa_set_scissor(newCtx, 0, 0,
+ drawBuffer->Width, drawBuffer->Height );
+ }
+ }
+
+ /* We can use this to help debug user's problems. Tell them to set
+ * the MESA_INFO env variable before running their app. Then the
+ * first time each context is made current we'll print some useful
+ * information.
+ */
+ if (newCtx->FirstTimeCurrent) {
+ if (_mesa_getenv("MESA_INFO")) {
+ _mesa_print_info();
+ }
+ newCtx->FirstTimeCurrent = GL_FALSE;
+ }
+ }
+}
+
+
+/**
+ * Make context 'ctx' share the display lists, textures and programs
+ * that are associated with 'ctxToShare'.
+ * Any display lists, textures or programs associated with 'ctx' will
+ * be deleted if nobody else is sharing them.
+ */
+GLboolean
+_mesa_share_state(GLcontext *ctx, GLcontext *ctxToShare)
+{
+ if (ctx && ctxToShare && ctx->Shared && ctxToShare->Shared) {
+ ctx->Shared->RefCount--;
+ if (ctx->Shared->RefCount == 0) {
+ free_shared_state(ctx, ctx->Shared);
+ }
+ ctx->Shared = ctxToShare->Shared;
+ ctx->Shared->RefCount++;
+ return GL_TRUE;
+ }
+ else {
+ return GL_FALSE;
+ }
+}
+
+
+
+/**
+ * Get current context for the calling thread.
+ *
+ * \return pointer to the current GL context.
+ *
+ * Calls _glapi_get_context(). This isn't the fastest way to get the current
+ * context. If you need speed, see the #GET_CURRENT_CONTEXT macro in context.h.
+ */
+GLcontext *
+_mesa_get_current_context( void )
+{
+ return (GLcontext *) _glapi_get_context();
+}
+
+/**
+ * Get context's current API dispatch table.
+ *
+ * It'll either be the immediate-mode execute dispatcher or the display list
+ * compile dispatcher.
+ *
+ * \param ctx GL context.
+ *
+ * \return pointer to dispatch_table.
+ *
+ * Simply returns __GLcontextRec::CurrentDispatch.
+ */
+struct _glapi_table *
+_mesa_get_dispatch(GLcontext *ctx)
+{
+ return ctx->CurrentDispatch;
+}
+
+/*@}*/
+
+
+/**********************************************************************/
+/** \name Miscellaneous functions */
+/**********************************************************************/
+/*@{*/
+
+/**
+ * Record an error.
+ *
+ * \param ctx GL context.
+ * \param error error code.
+ *
+ * Records the given error code and call the driver's dd_function_table::Error
+ * function if defined.
+ *
+ * \sa
+ * This is called via _mesa_error().
+ */
+void
+_mesa_record_error( GLcontext *ctx, GLenum error )
+{
+ if (!ctx)
+ return;
+
+ if (ctx->ErrorValue == GL_NO_ERROR) {
+ ctx->ErrorValue = error;
+ }
+
+ /* Call device driver's error handler, if any. This is used on the Mac. */
+ if (ctx->Driver.Error) {
+ (*ctx->Driver.Error)( ctx );
+ }
+}
+
+/**
+ * Execute glFinish().
+ *
+ * Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the
+ * dd_function_table::Finish driver callback, if not NULL.
+ */
+void GLAPIENTRY
+_mesa_Finish( void )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+ if (ctx->Driver.Finish) {
+ (*ctx->Driver.Finish)( ctx );
+ }
+}
+
+/**
+ * Execute glFlush().
+ *
+ * Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the
+ * dd_function_table::Flush driver callback, if not NULL.
+ */
+void GLAPIENTRY
+_mesa_Flush( void )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+ if (ctx->Driver.Flush) {
+ (*ctx->Driver.Flush)( ctx );
+ }
+}
+
+
+/*@}*/
diff --git a/src/mesa/main/context.h b/src/mesa/main/context.h
new file mode 100644
index 00000000000..9c6ef520792
--- /dev/null
+++ b/src/mesa/main/context.h
@@ -0,0 +1,340 @@
+/**
+ * \file context.h
+ * Mesa context/visual/framebuffer management functions.
+ *
+ * There are three Mesa data types which are meant to be used by device
+ * drivers:
+ * - GLcontext: this contains the Mesa rendering state
+ * - GLvisual: this describes the color buffer (RGB vs. ci), whether or not
+ * there's a depth buffer, stencil buffer, etc.
+ * - GLframebuffer: contains pointers to the depth buffer, stencil buffer,
+ * accum buffer and alpha buffers.
+ *
+ * These types should be encapsulated by corresponding device driver
+ * data types. See xmesa.h and xmesaP.h for an example.
+ *
+ * In OOP terms, GLcontext, GLvisual, and GLframebuffer are base classes
+ * which the device driver must derive from.
+ *
+ * The following functions create and destroy these data types.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.1
+ *
+ * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef CONTEXT_H
+#define CONTEXT_H
+
+
+#include "glapi.h"
+#include "imports.h"
+#include "mtypes.h"
+
+
+/**********************************************************************/
+/** \name Create/destroy a GLvisual. */
+/*@{*/
+
+extern GLvisual *
+_mesa_create_visual( GLboolean rgbFlag,
+ GLboolean dbFlag,
+ GLboolean stereoFlag,
+ GLint redBits,
+ GLint greenBits,
+ GLint blueBits,
+ GLint alphaBits,
+ GLint indexBits,
+ GLint depthBits,
+ GLint stencilBits,
+ GLint accumRedBits,
+ GLint accumGreenBits,
+ GLint accumBlueBits,
+ GLint accumAlphaBits,
+ GLint numSamples );
+
+extern GLboolean
+_mesa_initialize_visual( GLvisual *v,
+ GLboolean rgbFlag,
+ GLboolean dbFlag,
+ GLboolean stereoFlag,
+ GLint redBits,
+ GLint greenBits,
+ GLint blueBits,
+ GLint alphaBits,
+ GLint indexBits,
+ GLint depthBits,
+ GLint stencilBits,
+ GLint accumRedBits,
+ GLint accumGreenBits,
+ GLint accumBlueBits,
+ GLint accumAlphaBits,
+ GLint numSamples );
+
+extern void
+_mesa_destroy_visual( GLvisual *vis );
+
+/*@}*/
+
+
+/**********************************************************************/
+/** \name Create/destroy a GLcontext. */
+/*@{*/
+
+extern GLcontext *
+_mesa_create_context( const GLvisual *visual,
+ GLcontext *share_list,
+ const struct dd_function_table *driverFunctions,
+ void *driverContext );
+
+extern GLboolean
+_mesa_initialize_context( GLcontext *ctx,
+ const GLvisual *visual,
+ GLcontext *share_list,
+ const struct dd_function_table *driverFunctions,
+ void *driverContext );
+
+extern void
+_mesa_free_context_data( GLcontext *ctx );
+
+extern void
+_mesa_destroy_context( GLcontext *ctx );
+
+
+extern void
+_mesa_copy_context(const GLcontext *src, GLcontext *dst, GLuint mask);
+
+
+extern void
+_mesa_make_current( GLcontext *ctx, GLframebuffer *drawBuffer,
+ GLframebuffer *readBuffer );
+
+extern GLboolean
+_mesa_share_state(GLcontext *ctx, GLcontext *ctxToShare);
+
+extern GLcontext *
+_mesa_get_current_context(void);
+
+/*@}*/
+
+
+/**********************************************************************/
+/** \name OpenGL SI-style export functions. */
+/*@{*/
+
+extern GLboolean
+_mesa_destroyContext(__GLcontext *gc);
+
+extern GLboolean
+_mesa_loseCurrent(__GLcontext *gc);
+
+extern GLboolean
+_mesa_makeCurrent(__GLcontext *gc);
+
+extern GLboolean
+_mesa_shareContext(__GLcontext *gc, __GLcontext *gcShare);
+
+extern GLboolean
+_mesa_copyContext(__GLcontext *dst, const __GLcontext *src, GLuint mask);
+
+extern GLboolean
+_mesa_forceCurrent(__GLcontext *gc);
+
+extern GLboolean
+_mesa_notifyResize(__GLcontext *gc);
+
+extern void
+_mesa_notifyDestroy(__GLcontext *gc);
+
+extern void
+_mesa_notifySwapBuffers(__GLcontext *gc);
+
+extern struct __GLdispatchStateRec *
+_mesa_dispatchExec(__GLcontext *gc);
+
+extern void
+_mesa_beginDispatchOverride(__GLcontext *gc);
+
+extern void
+_mesa_endDispatchOverride(__GLcontext *gc);
+
+/*@}*/
+
+
+extern struct _glapi_table *
+_mesa_get_dispatch(GLcontext *ctx);
+
+
+
+/**********************************************************************/
+/** \name Miscellaneous */
+/*@{*/
+
+extern void
+_mesa_record_error( GLcontext *ctx, GLenum error );
+
+
+extern void GLAPIENTRY
+_mesa_Finish( void );
+
+extern void GLAPIENTRY
+_mesa_Flush( void );
+
+/*@}*/
+
+
+
+/**********************************************************************/
+/** \name Macros for contexts/flushing. */
+/*@{*/
+
+
+/**
+ * Flush vertices.
+ *
+ * \param ctx GL context.
+ * \param newstate new state.
+ *
+ * Checks if dd_function_table::NeedFlush is marked to flush stored vertices,
+ * and calls dd_function_table::FlushVertices if so. Marks
+ * __GLcontextRec::NewState with \p newstate.
+ */
+#define FLUSH_VERTICES(ctx, newstate) \
+do { \
+ if (MESA_VERBOSE & VERBOSE_STATE) \
+ _mesa_debug(ctx, "FLUSH_VERTICES in %s\n", MESA_FUNCTION);\
+ if (ctx->Driver.NeedFlush & FLUSH_STORED_VERTICES) \
+ ctx->Driver.FlushVertices(ctx, FLUSH_STORED_VERTICES); \
+ ctx->NewState |= newstate; \
+} while (0)
+
+/**
+ * Flush current state.
+ *
+ * \param ctx GL context.
+ * \param newstate new state.
+ *
+ * Checks if dd_function_table::NeedFlush is marked to flush current state,
+ * and calls dd_function_table::FlushVertices if so. Marks
+ * __GLcontextRec::NewState with \p newstate.
+ */
+#define FLUSH_CURRENT(ctx, newstate) \
+do { \
+ if (MESA_VERBOSE & VERBOSE_STATE) \
+ _mesa_debug(ctx, "FLUSH_CURRENT in %s\n", MESA_FUNCTION); \
+ if (ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT) \
+ ctx->Driver.FlushVertices(ctx, FLUSH_UPDATE_CURRENT); \
+ ctx->NewState |= newstate; \
+} while (0)
+
+/**
+ * Macro to assert that the API call was made outside the
+ * glBegin()/glEnd() pair, with return value.
+ *
+ * \param ctx GL context.
+ * \param retval value to return value in case the assertion fails.
+ */
+#define ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, retval) \
+do { \
+ if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) { \
+ _mesa_error( ctx, GL_INVALID_OPERATION, "begin/end" ); \
+ return retval; \
+ } \
+} while (0)
+
+/**
+ * Macro to assert that the API call was made outside the
+ * glBegin()/glEnd() pair.
+ *
+ * \param ctx GL context.
+ */
+#define ASSERT_OUTSIDE_BEGIN_END(ctx) \
+do { \
+ if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) { \
+ _mesa_error( ctx, GL_INVALID_OPERATION, "begin/end" ); \
+ return; \
+ } \
+} while (0)
+
+/**
+ * Macro to assert that the API call was made outside the
+ * glBegin()/glEnd() pair and flush the vertices.
+ *
+ * \param ctx GL context.
+ */
+#define ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx) \
+do { \
+ ASSERT_OUTSIDE_BEGIN_END(ctx); \
+ FLUSH_VERTICES(ctx, 0); \
+} while (0)
+
+/**
+ * Macro to assert that the API call was made outside the
+ * glBegin()/glEnd() pair and flush the vertices, with return value.
+ *
+ * \param ctx GL context.
+ * \param retval value to return value in case the assertion fails.
+ */
+#define ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx, retval) \
+do { \
+ ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, retval); \
+ FLUSH_VERTICES(ctx, 0); \
+} while (0)
+
+
+/*@}*/
+
+
+
+/**
+ * Macros to help evaluate current state conditions
+ */
+
+/*@{*/
+
+/**
+ * Is the secondary color needed?
+ */
+#define NEED_SECONDARY_COLOR(CTX) \
+ (((CTX)->Light.Enabled && \
+ (CTX)->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) \
+ || (CTX)->Fog.ColorSumEnabled \
+ || ((CTX)->VertexProgram._Enabled && \
+ ((CTX)->VertexProgram.Current->Base.InputsRead & VERT_BIT_COLOR1)) \
+ || ((CTX)->FragmentProgram._Enabled && \
+ ((CTX)->FragmentProgram.Current->Base.InputsRead & FRAG_BIT_COL1)) \
+ )
+
+
+/**
+ * Is two-sided lighting in effect?
+ */
+#define NEED_TWO_SIDED_LIGHTING(CTX) \
+ (ctx->Light.Enabled && ctx->Light.Model.TwoSide)
+
+
+/*@}*/
+
+
+#endif
diff --git a/src/mesa/main/convolve.c b/src/mesa/main/convolve.c
new file mode 100644
index 00000000000..6b97c7f56cd
--- /dev/null
+++ b/src/mesa/main/convolve.c
@@ -0,0 +1,1527 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.3
+ *
+ * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/*
+ * Image convolution functions.
+ *
+ * Notes: filter kernel elements are indexed by <n> and <m> as in
+ * the GL spec.
+ */
+
+
+#include "glheader.h"
+#include "bufferobj.h"
+#include "colormac.h"
+#include "convolve.h"
+#include "context.h"
+#include "image.h"
+#include "mtypes.h"
+#include "pixel.h"
+#include "state.h"
+
+
+/*
+ * Given an internalFormat token passed to glConvolutionFilter
+ * or glSeparableFilter, return the corresponding base format.
+ * Return -1 if invalid token.
+ */
+static GLint
+base_filter_format( GLenum format )
+{
+ switch (format) {
+ case GL_ALPHA:
+ case GL_ALPHA4:
+ case GL_ALPHA8:
+ case GL_ALPHA12:
+ case GL_ALPHA16:
+ return GL_ALPHA;
+ case GL_LUMINANCE:
+ case GL_LUMINANCE4:
+ case GL_LUMINANCE8:
+ case GL_LUMINANCE12:
+ case GL_LUMINANCE16:
+ return GL_LUMINANCE;
+ case GL_LUMINANCE_ALPHA:
+ case GL_LUMINANCE4_ALPHA4:
+ case GL_LUMINANCE6_ALPHA2:
+ case GL_LUMINANCE8_ALPHA8:
+ case GL_LUMINANCE12_ALPHA4:
+ case GL_LUMINANCE12_ALPHA12:
+ case GL_LUMINANCE16_ALPHA16:
+ return GL_LUMINANCE_ALPHA;
+ case GL_INTENSITY:
+ case GL_INTENSITY4:
+ case GL_INTENSITY8:
+ case GL_INTENSITY12:
+ case GL_INTENSITY16:
+ return GL_INTENSITY;
+ case GL_RGB:
+ case GL_R3_G3_B2:
+ case GL_RGB4:
+ case GL_RGB5:
+ case GL_RGB8:
+ case GL_RGB10:
+ case GL_RGB12:
+ case GL_RGB16:
+ return GL_RGB;
+ case 4:
+ case GL_RGBA:
+ case GL_RGBA2:
+ case GL_RGBA4:
+ case GL_RGB5_A1:
+ case GL_RGBA8:
+ case GL_RGB10_A2:
+ case GL_RGBA12:
+ case GL_RGBA16:
+ return GL_RGBA;
+ default:
+ return -1; /* error */
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_ConvolutionFilter1D(GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *image)
+{
+ GLint baseFormat;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (target != GL_CONVOLUTION_1D) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter1D(target)");
+ return;
+ }
+
+ baseFormat = base_filter_format(internalFormat);
+ if (baseFormat < 0 || baseFormat == GL_COLOR_INDEX) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter1D(internalFormat)");
+ return;
+ }
+
+ if (width < 0 || width > MAX_CONVOLUTION_WIDTH) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glConvolutionFilter1D(width)");
+ return;
+ }
+
+ if (!_mesa_is_legal_format_and_type(ctx, format, type)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glConvolutionFilter1D(format or type)");
+ return;
+ }
+
+ if (format == GL_COLOR_INDEX ||
+ format == GL_STENCIL_INDEX ||
+ format == GL_DEPTH_COMPONENT ||
+ format == GL_INTENSITY ||
+ type == GL_BITMAP) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter1D(format or type)");
+ return;
+ }
+
+ ctx->Convolution1D.Format = format;
+ ctx->Convolution1D.InternalFormat = internalFormat;
+ ctx->Convolution1D.Width = width;
+ ctx->Convolution1D.Height = 1;
+
+ if (ctx->Unpack.BufferObj->Name) {
+ /* unpack filter from PBO */
+ GLubyte *buf;
+ if (!_mesa_validate_pbo_access(1, &ctx->Unpack, width, 1, 1,
+ format, type, image)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glConvolutionFilter1D(invalid PBO access)");
+ return;
+ }
+ buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+ GL_READ_ONLY_ARB,
+ ctx->Unpack.BufferObj);
+ if (!buf) {
+ /* buffer is already mapped - that's an error */
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glConvolutionFilter1D(PBO is mapped)");
+ return;
+ }
+ image = ADD_POINTERS(buf, image);
+ }
+ else if (!image) {
+ return;
+ }
+
+ _mesa_unpack_color_span_float(ctx, width, GL_RGBA,
+ ctx->Convolution1D.Filter,
+ format, type, image, &ctx->Unpack,
+ 0); /* transferOps */
+
+ if (ctx->Unpack.BufferObj->Name) {
+ ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+ ctx->Unpack.BufferObj);
+ }
+
+ _mesa_scale_and_bias_rgba(width,
+ (GLfloat (*)[4]) ctx->Convolution1D.Filter,
+ ctx->Pixel.ConvolutionFilterScale[0][0],
+ ctx->Pixel.ConvolutionFilterScale[0][1],
+ ctx->Pixel.ConvolutionFilterScale[0][2],
+ ctx->Pixel.ConvolutionFilterScale[0][3],
+ ctx->Pixel.ConvolutionFilterBias[0][0],
+ ctx->Pixel.ConvolutionFilterBias[0][1],
+ ctx->Pixel.ConvolutionFilterBias[0][2],
+ ctx->Pixel.ConvolutionFilterBias[0][3]);
+
+ ctx->NewState |= _NEW_PIXEL;
+}
+
+
+void GLAPIENTRY
+_mesa_ConvolutionFilter2D(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image)
+{
+ GLint baseFormat;
+ GLint i;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (target != GL_CONVOLUTION_2D) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter2D(target)");
+ return;
+ }
+
+ baseFormat = base_filter_format(internalFormat);
+ if (baseFormat < 0 || baseFormat == GL_COLOR_INDEX) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter2D(internalFormat)");
+ return;
+ }
+
+ if (width < 0 || width > MAX_CONVOLUTION_WIDTH) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glConvolutionFilter2D(width)");
+ return;
+ }
+ if (height < 0 || height > MAX_CONVOLUTION_HEIGHT) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glConvolutionFilter2D(height)");
+ return;
+ }
+
+ if (!_mesa_is_legal_format_and_type(ctx, format, type)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glConvolutionFilter2D(format or type)");
+ return;
+ }
+ if (format == GL_COLOR_INDEX ||
+ format == GL_STENCIL_INDEX ||
+ format == GL_DEPTH_COMPONENT ||
+ format == GL_INTENSITY ||
+ type == GL_BITMAP) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter2D(format or type)");
+ return;
+ }
+
+ /* this should have been caught earlier */
+ assert(_mesa_components_in_format(format));
+
+ ctx->Convolution2D.Format = format;
+ ctx->Convolution2D.InternalFormat = internalFormat;
+ ctx->Convolution2D.Width = width;
+ ctx->Convolution2D.Height = height;
+
+ if (ctx->Unpack.BufferObj->Name) {
+ /* unpack filter from PBO */
+ GLubyte *buf;
+ if (!_mesa_validate_pbo_access(2, &ctx->Unpack, width, height, 1,
+ format, type, image)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glConvolutionFilter2D(invalid PBO access)");
+ return;
+ }
+ buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+ GL_READ_ONLY_ARB,
+ ctx->Unpack.BufferObj);
+ if (!buf) {
+ /* buffer is already mapped - that's an error */
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glConvolutionFilter2D(PBO is mapped)");
+ return;
+ }
+ image = ADD_POINTERS(buf, image);
+ }
+ else if (!image) {
+ return;
+ }
+
+ /* Unpack filter image. We always store filters in RGBA format. */
+ for (i = 0; i < height; i++) {
+ const GLvoid *src = _mesa_image_address2d(&ctx->Unpack, image, width,
+ height, format, type, i, 0);
+ GLfloat *dst = ctx->Convolution2D.Filter + i * width * 4;
+ _mesa_unpack_color_span_float(ctx, width, GL_RGBA, dst,
+ format, type, src, &ctx->Unpack,
+ 0); /* transferOps */
+ }
+
+ if (ctx->Unpack.BufferObj->Name) {
+ ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+ ctx->Unpack.BufferObj);
+ }
+
+ _mesa_scale_and_bias_rgba(width * height,
+ (GLfloat (*)[4]) ctx->Convolution2D.Filter,
+ ctx->Pixel.ConvolutionFilterScale[1][0],
+ ctx->Pixel.ConvolutionFilterScale[1][1],
+ ctx->Pixel.ConvolutionFilterScale[1][2],
+ ctx->Pixel.ConvolutionFilterScale[1][3],
+ ctx->Pixel.ConvolutionFilterBias[1][0],
+ ctx->Pixel.ConvolutionFilterBias[1][1],
+ ctx->Pixel.ConvolutionFilterBias[1][2],
+ ctx->Pixel.ConvolutionFilterBias[1][3]);
+
+ ctx->NewState |= _NEW_PIXEL;
+}
+
+
+void GLAPIENTRY
+_mesa_ConvolutionParameterf(GLenum target, GLenum pname, GLfloat param)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLuint c;
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ switch (target) {
+ case GL_CONVOLUTION_1D:
+ c = 0;
+ break;
+ case GL_CONVOLUTION_2D:
+ c = 1;
+ break;
+ case GL_SEPARABLE_2D:
+ c = 2;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterf(target)");
+ return;
+ }
+
+ switch (pname) {
+ case GL_CONVOLUTION_BORDER_MODE:
+ if (param == (GLfloat) GL_REDUCE ||
+ param == (GLfloat) GL_CONSTANT_BORDER ||
+ param == (GLfloat) GL_REPLICATE_BORDER) {
+ ctx->Pixel.ConvolutionBorderMode[c] = (GLenum) param;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterf(params)");
+ return;
+ }
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterf(pname)");
+ return;
+ }
+
+ ctx->NewState |= _NEW_PIXEL;
+}
+
+
+void GLAPIENTRY
+_mesa_ConvolutionParameterfv(GLenum target, GLenum pname, const GLfloat *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLuint c;
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ switch (target) {
+ case GL_CONVOLUTION_1D:
+ c = 0;
+ break;
+ case GL_CONVOLUTION_2D:
+ c = 1;
+ break;
+ case GL_SEPARABLE_2D:
+ c = 2;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterfv(target)");
+ return;
+ }
+
+ switch (pname) {
+ case GL_CONVOLUTION_BORDER_COLOR:
+ COPY_4V(ctx->Pixel.ConvolutionBorderColor[c], params);
+ break;
+ case GL_CONVOLUTION_BORDER_MODE:
+ if (params[0] == (GLfloat) GL_REDUCE ||
+ params[0] == (GLfloat) GL_CONSTANT_BORDER ||
+ params[0] == (GLfloat) GL_REPLICATE_BORDER) {
+ ctx->Pixel.ConvolutionBorderMode[c] = (GLenum) params[0];
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterfv(params)");
+ return;
+ }
+ break;
+ case GL_CONVOLUTION_FILTER_SCALE:
+ COPY_4V(ctx->Pixel.ConvolutionFilterScale[c], params);
+ break;
+ case GL_CONVOLUTION_FILTER_BIAS:
+ COPY_4V(ctx->Pixel.ConvolutionFilterBias[c], params);
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterfv(pname)");
+ return;
+ }
+
+ ctx->NewState |= _NEW_PIXEL;
+}
+
+
+void GLAPIENTRY
+_mesa_ConvolutionParameteri(GLenum target, GLenum pname, GLint param)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLuint c;
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ switch (target) {
+ case GL_CONVOLUTION_1D:
+ c = 0;
+ break;
+ case GL_CONVOLUTION_2D:
+ c = 1;
+ break;
+ case GL_SEPARABLE_2D:
+ c = 2;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteri(target)");
+ return;
+ }
+
+ switch (pname) {
+ case GL_CONVOLUTION_BORDER_MODE:
+ if (param == (GLint) GL_REDUCE ||
+ param == (GLint) GL_CONSTANT_BORDER ||
+ param == (GLint) GL_REPLICATE_BORDER) {
+ ctx->Pixel.ConvolutionBorderMode[c] = (GLenum) param;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteri(params)");
+ return;
+ }
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteri(pname)");
+ return;
+ }
+
+ ctx->NewState |= _NEW_PIXEL;
+}
+
+
+void GLAPIENTRY
+_mesa_ConvolutionParameteriv(GLenum target, GLenum pname, const GLint *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLuint c;
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ switch (target) {
+ case GL_CONVOLUTION_1D:
+ c = 0;
+ break;
+ case GL_CONVOLUTION_2D:
+ c = 1;
+ break;
+ case GL_SEPARABLE_2D:
+ c = 2;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteriv(target)");
+ return;
+ }
+
+ switch (pname) {
+ case GL_CONVOLUTION_BORDER_COLOR:
+ ctx->Pixel.ConvolutionBorderColor[c][0] = INT_TO_FLOAT(params[0]);
+ ctx->Pixel.ConvolutionBorderColor[c][1] = INT_TO_FLOAT(params[1]);
+ ctx->Pixel.ConvolutionBorderColor[c][2] = INT_TO_FLOAT(params[2]);
+ ctx->Pixel.ConvolutionBorderColor[c][3] = INT_TO_FLOAT(params[3]);
+ break;
+ case GL_CONVOLUTION_BORDER_MODE:
+ if (params[0] == (GLint) GL_REDUCE ||
+ params[0] == (GLint) GL_CONSTANT_BORDER ||
+ params[0] == (GLint) GL_REPLICATE_BORDER) {
+ ctx->Pixel.ConvolutionBorderMode[c] = (GLenum) params[0];
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteriv(params)");
+ return;
+ }
+ break;
+ case GL_CONVOLUTION_FILTER_SCALE:
+ /* COPY_4V(ctx->Pixel.ConvolutionFilterScale[c], params); */
+ /* need cast to prevent compiler warnings */
+ ctx->Pixel.ConvolutionFilterScale[c][0] = (GLfloat) params[0];
+ ctx->Pixel.ConvolutionFilterScale[c][1] = (GLfloat) params[1];
+ ctx->Pixel.ConvolutionFilterScale[c][2] = (GLfloat) params[2];
+ ctx->Pixel.ConvolutionFilterScale[c][3] = (GLfloat) params[3];
+ break;
+ case GL_CONVOLUTION_FILTER_BIAS:
+ /* COPY_4V(ctx->Pixel.ConvolutionFilterBias[c], params); */
+ /* need cast to prevent compiler warnings */
+ ctx->Pixel.ConvolutionFilterBias[c][0] = (GLfloat) params[0];
+ ctx->Pixel.ConvolutionFilterBias[c][1] = (GLfloat) params[1];
+ ctx->Pixel.ConvolutionFilterBias[c][2] = (GLfloat) params[2];
+ ctx->Pixel.ConvolutionFilterBias[c][3] = (GLfloat) params[3];
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteriv(pname)");
+ return;
+ }
+
+ ctx->NewState |= _NEW_PIXEL;
+}
+
+
+void GLAPIENTRY
+_mesa_CopyConvolutionFilter1D(GLenum target, GLenum internalFormat, GLint x, GLint y, GLsizei width)
+{
+ GLint baseFormat;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (target != GL_CONVOLUTION_1D) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glCopyConvolutionFilter1D(target)");
+ return;
+ }
+
+ baseFormat = base_filter_format(internalFormat);
+ if (baseFormat < 0 || baseFormat == GL_COLOR_INDEX) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glCopyConvolutionFilter1D(internalFormat)");
+ return;
+ }
+
+ if (width < 0 || width > MAX_CONVOLUTION_WIDTH) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glCopyConvolutionFilter1D(width)");
+ return;
+ }
+
+ ctx->Driver.CopyConvolutionFilter1D( ctx, target,
+ internalFormat, x, y, width);
+}
+
+
+void GLAPIENTRY
+_mesa_CopyConvolutionFilter2D(GLenum target, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ GLint baseFormat;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (target != GL_CONVOLUTION_2D) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glCopyConvolutionFilter2D(target)");
+ return;
+ }
+
+ baseFormat = base_filter_format(internalFormat);
+ if (baseFormat < 0 || baseFormat == GL_COLOR_INDEX) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glCopyConvolutionFilter2D(internalFormat)");
+ return;
+ }
+
+ if (width < 0 || width > MAX_CONVOLUTION_WIDTH) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glCopyConvolutionFilter2D(width)");
+ return;
+ }
+ if (height < 0 || height > MAX_CONVOLUTION_HEIGHT) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glCopyConvolutionFilter2D(height)");
+ return;
+ }
+
+ ctx->Driver.CopyConvolutionFilter2D( ctx, target, internalFormat, x, y,
+ width, height );
+}
+
+
+void GLAPIENTRY
+_mesa_GetConvolutionFilter(GLenum target, GLenum format, GLenum type, GLvoid *image)
+{
+ const struct gl_convolution_attrib *filter;
+ GLuint row;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (ctx->NewState) {
+ _mesa_update_state(ctx);
+ }
+
+ if (!_mesa_is_legal_format_and_type(ctx, format, type)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetConvolutionFilter(format or type)");
+ return;
+ }
+
+ if (format == GL_COLOR_INDEX ||
+ format == GL_STENCIL_INDEX ||
+ format == GL_DEPTH_COMPONENT ||
+ format == GL_INTENSITY ||
+ type == GL_BITMAP) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetConvolutionFilter(format or type)");
+ return;
+ }
+
+ switch (target) {
+ case GL_CONVOLUTION_1D:
+ filter = &(ctx->Convolution1D);
+ break;
+ case GL_CONVOLUTION_2D:
+ filter = &(ctx->Convolution2D);
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetConvolutionFilter(target)");
+ return;
+ }
+
+ if (ctx->Pack.BufferObj->Name) {
+ /* Pack the filter into a PBO */
+ GLubyte *buf;
+ if (!_mesa_validate_pbo_access(2, &ctx->Pack,
+ filter->Width, filter->Height,
+ 1, format, type, image)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetConvolutionFilter(invalid PBO access)");
+ return;
+ }
+ buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
+ GL_WRITE_ONLY_ARB,
+ ctx->Pack.BufferObj);
+ if (!buf) {
+ /* buffer is already mapped - that's an error */
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetConvolutionFilter(PBO is mapped)");
+ return;
+ }
+ image = ADD_POINTERS(image, buf);
+ }
+
+ for (row = 0; row < filter->Height; row++) {
+ GLvoid *dst = _mesa_image_address2d(&ctx->Pack, image, filter->Width,
+ filter->Height, format, type,
+ row, 0);
+ const GLfloat *src = filter->Filter + row * filter->Width * 4;
+ _mesa_pack_rgba_span_float(ctx, filter->Width,
+ (const GLfloat (*)[4]) src,
+ format, type, dst, &ctx->Pack, 0);
+ }
+
+ if (ctx->Pack.BufferObj->Name) {
+ ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
+ ctx->Pack.BufferObj);
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_GetConvolutionParameterfv(GLenum target, GLenum pname, GLfloat *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ const struct gl_convolution_attrib *conv;
+ GLuint c;
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ switch (target) {
+ case GL_CONVOLUTION_1D:
+ c = 0;
+ conv = &ctx->Convolution1D;
+ break;
+ case GL_CONVOLUTION_2D:
+ c = 1;
+ conv = &ctx->Convolution2D;
+ break;
+ case GL_SEPARABLE_2D:
+ c = 2;
+ conv = &ctx->Separable2D;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetConvolutionParameterfv(target)");
+ return;
+ }
+
+ switch (pname) {
+ case GL_CONVOLUTION_BORDER_COLOR:
+ COPY_4V(params, ctx->Pixel.ConvolutionBorderColor[c]);
+ break;
+ case GL_CONVOLUTION_BORDER_MODE:
+ *params = (GLfloat) ctx->Pixel.ConvolutionBorderMode[c];
+ break;
+ case GL_CONVOLUTION_FILTER_SCALE:
+ COPY_4V(params, ctx->Pixel.ConvolutionFilterScale[c]);
+ break;
+ case GL_CONVOLUTION_FILTER_BIAS:
+ COPY_4V(params, ctx->Pixel.ConvolutionFilterBias[c]);
+ break;
+ case GL_CONVOLUTION_FORMAT:
+ *params = (GLfloat) conv->Format;
+ break;
+ case GL_CONVOLUTION_WIDTH:
+ *params = (GLfloat) conv->Width;
+ break;
+ case GL_CONVOLUTION_HEIGHT:
+ *params = (GLfloat) conv->Height;
+ break;
+ case GL_MAX_CONVOLUTION_WIDTH:
+ *params = (GLfloat) ctx->Const.MaxConvolutionWidth;
+ break;
+ case GL_MAX_CONVOLUTION_HEIGHT:
+ *params = (GLfloat) ctx->Const.MaxConvolutionHeight;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetConvolutionParameterfv(pname)");
+ return;
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_GetConvolutionParameteriv(GLenum target, GLenum pname, GLint *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ const struct gl_convolution_attrib *conv;
+ GLuint c;
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ switch (target) {
+ case GL_CONVOLUTION_1D:
+ c = 0;
+ conv = &ctx->Convolution1D;
+ break;
+ case GL_CONVOLUTION_2D:
+ c = 1;
+ conv = &ctx->Convolution2D;
+ break;
+ case GL_SEPARABLE_2D:
+ c = 2;
+ conv = &ctx->Separable2D;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetConvolutionParameteriv(target)");
+ return;
+ }
+
+ switch (pname) {
+ case GL_CONVOLUTION_BORDER_COLOR:
+ params[0] = FLOAT_TO_INT(ctx->Pixel.ConvolutionBorderColor[c][0]);
+ params[1] = FLOAT_TO_INT(ctx->Pixel.ConvolutionBorderColor[c][1]);
+ params[2] = FLOAT_TO_INT(ctx->Pixel.ConvolutionBorderColor[c][2]);
+ params[3] = FLOAT_TO_INT(ctx->Pixel.ConvolutionBorderColor[c][3]);
+ break;
+ case GL_CONVOLUTION_BORDER_MODE:
+ *params = (GLint) ctx->Pixel.ConvolutionBorderMode[c];
+ break;
+ case GL_CONVOLUTION_FILTER_SCALE:
+ params[0] = (GLint) ctx->Pixel.ConvolutionFilterScale[c][0];
+ params[1] = (GLint) ctx->Pixel.ConvolutionFilterScale[c][1];
+ params[2] = (GLint) ctx->Pixel.ConvolutionFilterScale[c][2];
+ params[3] = (GLint) ctx->Pixel.ConvolutionFilterScale[c][3];
+ break;
+ case GL_CONVOLUTION_FILTER_BIAS:
+ params[0] = (GLint) ctx->Pixel.ConvolutionFilterBias[c][0];
+ params[1] = (GLint) ctx->Pixel.ConvolutionFilterBias[c][1];
+ params[2] = (GLint) ctx->Pixel.ConvolutionFilterBias[c][2];
+ params[3] = (GLint) ctx->Pixel.ConvolutionFilterBias[c][3];
+ break;
+ case GL_CONVOLUTION_FORMAT:
+ *params = (GLint) conv->Format;
+ break;
+ case GL_CONVOLUTION_WIDTH:
+ *params = (GLint) conv->Width;
+ break;
+ case GL_CONVOLUTION_HEIGHT:
+ *params = (GLint) conv->Height;
+ break;
+ case GL_MAX_CONVOLUTION_WIDTH:
+ *params = (GLint) ctx->Const.MaxConvolutionWidth;
+ break;
+ case GL_MAX_CONVOLUTION_HEIGHT:
+ *params = (GLint) ctx->Const.MaxConvolutionHeight;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetConvolutionParameteriv(pname)");
+ return;
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_GetSeparableFilter(GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span)
+{
+ const GLint colStart = MAX_CONVOLUTION_WIDTH * 4;
+ const struct gl_convolution_attrib *filter;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (ctx->NewState) {
+ _mesa_update_state(ctx);
+ }
+
+ if (target != GL_SEPARABLE_2D) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetSeparableFilter(target)");
+ return;
+ }
+
+ if (!_mesa_is_legal_format_and_type(ctx, format, type)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetConvolutionFilter(format or type)");
+ return;
+ }
+
+ if (format == GL_COLOR_INDEX ||
+ format == GL_STENCIL_INDEX ||
+ format == GL_DEPTH_COMPONENT ||
+ format == GL_INTENSITY ||
+ type == GL_BITMAP) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetConvolutionFilter(format or type)");
+ return;
+ }
+
+ filter = &ctx->Separable2D;
+
+ if (ctx->Pack.BufferObj->Name) {
+ /* Pack filter into PBO */
+ GLubyte *buf;
+ if (!_mesa_validate_pbo_access(1, &ctx->Pack, filter->Width, 1, 1,
+ format, type, row)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetSeparableFilter(invalid PBO access, width)");
+ return;
+ }
+ if (!_mesa_validate_pbo_access(1, &ctx->Pack, filter->Height, 1, 1,
+ format, type, column)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetSeparableFilter(invalid PBO access, height)");
+ return;
+ }
+ buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
+ GL_WRITE_ONLY_ARB,
+ ctx->Pack.BufferObj);
+ if (!buf) {
+ /* buffer is already mapped - that's an error */
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetSeparableFilter(PBO is mapped)");
+ return;
+ }
+ row = ADD_POINTERS(buf, row);
+ column = ADD_POINTERS(buf, column);
+ }
+
+ /* Row filter */
+ if (row) {
+ GLvoid *dst = _mesa_image_address1d(&ctx->Pack, row, filter->Width,
+ format, type, 0);
+ _mesa_pack_rgba_span_float(ctx, filter->Width,
+ (const GLfloat (*)[4]) filter->Filter,
+ format, type, dst, &ctx->Pack, 0);
+ }
+
+ /* Column filter */
+ if (column) {
+ GLvoid *dst = _mesa_image_address1d(&ctx->Pack, column, filter->Height,
+ format, type, 0);
+ const GLfloat *src = filter->Filter + colStart;
+ _mesa_pack_rgba_span_float(ctx, filter->Height,
+ (const GLfloat (*)[4]) src,
+ format, type, dst, &ctx->Pack, 0);
+ }
+
+ (void) span; /* unused at this time */
+
+ if (ctx->Pack.BufferObj->Name) {
+ /* Pack filter into PBO */
+ ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+ ctx->Unpack.BufferObj);
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_SeparableFilter2D(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column)
+{
+ const GLint colStart = MAX_CONVOLUTION_WIDTH * 4;
+ GLint baseFormat;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (target != GL_SEPARABLE_2D) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glSeparableFilter2D(target)");
+ return;
+ }
+
+ baseFormat = base_filter_format(internalFormat);
+ if (baseFormat < 0 || baseFormat == GL_COLOR_INDEX) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glSeparableFilter2D(internalFormat)");
+ return;
+ }
+
+ if (width < 0 || width > MAX_CONVOLUTION_WIDTH) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glSeparableFilter2D(width)");
+ return;
+ }
+ if (height < 0 || height > MAX_CONVOLUTION_HEIGHT) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glSeparableFilter2D(height)");
+ return;
+ }
+
+ if (!_mesa_is_legal_format_and_type(ctx, format, type)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glSeparableFilter2D(format or type)");
+ return;
+ }
+
+ if (format == GL_COLOR_INDEX ||
+ format == GL_STENCIL_INDEX ||
+ format == GL_DEPTH_COMPONENT ||
+ format == GL_INTENSITY ||
+ type == GL_BITMAP) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glSeparableFilter2D(format or type)");
+ return;
+ }
+
+ ctx->Separable2D.Format = format;
+ ctx->Separable2D.InternalFormat = internalFormat;
+ ctx->Separable2D.Width = width;
+ ctx->Separable2D.Height = height;
+
+ if (ctx->Unpack.BufferObj->Name) {
+ /* unpack filter from PBO */
+ GLubyte *buf;
+ if (!_mesa_validate_pbo_access(1, &ctx->Unpack, width, 1, 1,
+ format, type, row)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glSeparableFilter2D(invalid PBO access, width)");
+ return;
+ }
+ if (!_mesa_validate_pbo_access(1, &ctx->Unpack, height, 1, 1,
+ format, type, column)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glSeparableFilter2D(invalid PBO access, height)");
+ return;
+ }
+ buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+ GL_READ_ONLY_ARB,
+ ctx->Unpack.BufferObj);
+ if (!buf) {
+ /* buffer is already mapped - that's an error */
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glSeparableFilter2D(PBO is mapped)");
+ return;
+ }
+ row = ADD_POINTERS(buf, row);
+ column = ADD_POINTERS(buf, column);
+ }
+
+ /* unpack row filter */
+ if (row) {
+ _mesa_unpack_color_span_float(ctx, width, GL_RGBA,
+ ctx->Separable2D.Filter,
+ format, type, row, &ctx->Unpack,
+ 0); /* transferOps */
+
+ _mesa_scale_and_bias_rgba(width,
+ (GLfloat (*)[4]) ctx->Separable2D.Filter,
+ ctx->Pixel.ConvolutionFilterScale[2][0],
+ ctx->Pixel.ConvolutionFilterScale[2][1],
+ ctx->Pixel.ConvolutionFilterScale[2][2],
+ ctx->Pixel.ConvolutionFilterScale[2][3],
+ ctx->Pixel.ConvolutionFilterBias[2][0],
+ ctx->Pixel.ConvolutionFilterBias[2][1],
+ ctx->Pixel.ConvolutionFilterBias[2][2],
+ ctx->Pixel.ConvolutionFilterBias[2][3]);
+ }
+
+ /* unpack column filter */
+ if (column) {
+ _mesa_unpack_color_span_float(ctx, height, GL_RGBA,
+ &ctx->Separable2D.Filter[colStart],
+ format, type, column, &ctx->Unpack,
+ 0); /* transferOps */
+
+ _mesa_scale_and_bias_rgba(height,
+ (GLfloat (*)[4]) (ctx->Separable2D.Filter + colStart),
+ ctx->Pixel.ConvolutionFilterScale[2][0],
+ ctx->Pixel.ConvolutionFilterScale[2][1],
+ ctx->Pixel.ConvolutionFilterScale[2][2],
+ ctx->Pixel.ConvolutionFilterScale[2][3],
+ ctx->Pixel.ConvolutionFilterBias[2][0],
+ ctx->Pixel.ConvolutionFilterBias[2][1],
+ ctx->Pixel.ConvolutionFilterBias[2][2],
+ ctx->Pixel.ConvolutionFilterBias[2][3]);
+ }
+
+ if (ctx->Unpack.BufferObj->Name) {
+ ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+ ctx->Unpack.BufferObj);
+ }
+
+ ctx->NewState |= _NEW_PIXEL;
+}
+
+
+/**********************************************************************/
+/*** image convolution functions ***/
+/**********************************************************************/
+
+static void
+convolve_1d_reduce(GLint srcWidth, const GLfloat src[][4],
+ GLint filterWidth, const GLfloat filter[][4],
+ GLfloat dest[][4])
+{
+ GLint dstWidth;
+ GLint i, n;
+
+ if (filterWidth >= 1)
+ dstWidth = srcWidth - (filterWidth - 1);
+ else
+ dstWidth = srcWidth;
+
+ if (dstWidth <= 0)
+ return; /* null result */
+
+ for (i = 0; i < dstWidth; i++) {
+ GLfloat sumR = 0.0;
+ GLfloat sumG = 0.0;
+ GLfloat sumB = 0.0;
+ GLfloat sumA = 0.0;
+ for (n = 0; n < filterWidth; n++) {
+ sumR += src[i + n][RCOMP] * filter[n][RCOMP];
+ sumG += src[i + n][GCOMP] * filter[n][GCOMP];
+ sumB += src[i + n][BCOMP] * filter[n][BCOMP];
+ sumA += src[i + n][ACOMP] * filter[n][ACOMP];
+ }
+ dest[i][RCOMP] = sumR;
+ dest[i][GCOMP] = sumG;
+ dest[i][BCOMP] = sumB;
+ dest[i][ACOMP] = sumA;
+ }
+}
+
+
+static void
+convolve_1d_constant(GLint srcWidth, const GLfloat src[][4],
+ GLint filterWidth, const GLfloat filter[][4],
+ GLfloat dest[][4],
+ const GLfloat borderColor[4])
+{
+ const GLint halfFilterWidth = filterWidth / 2;
+ GLint i, n;
+
+ for (i = 0; i < srcWidth; i++) {
+ GLfloat sumR = 0.0;
+ GLfloat sumG = 0.0;
+ GLfloat sumB = 0.0;
+ GLfloat sumA = 0.0;
+ for (n = 0; n < filterWidth; n++) {
+ if (i + n < halfFilterWidth || i + n - halfFilterWidth >= srcWidth) {
+ sumR += borderColor[RCOMP] * filter[n][RCOMP];
+ sumG += borderColor[GCOMP] * filter[n][GCOMP];
+ sumB += borderColor[BCOMP] * filter[n][BCOMP];
+ sumA += borderColor[ACOMP] * filter[n][ACOMP];
+ }
+ else {
+ sumR += src[i + n - halfFilterWidth][RCOMP] * filter[n][RCOMP];
+ sumG += src[i + n - halfFilterWidth][GCOMP] * filter[n][GCOMP];
+ sumB += src[i + n - halfFilterWidth][BCOMP] * filter[n][BCOMP];
+ sumA += src[i + n - halfFilterWidth][ACOMP] * filter[n][ACOMP];
+ }
+ }
+ dest[i][RCOMP] = sumR;
+ dest[i][GCOMP] = sumG;
+ dest[i][BCOMP] = sumB;
+ dest[i][ACOMP] = sumA;
+ }
+}
+
+
+static void
+convolve_1d_replicate(GLint srcWidth, const GLfloat src[][4],
+ GLint filterWidth, const GLfloat filter[][4],
+ GLfloat dest[][4])
+{
+ const GLint halfFilterWidth = filterWidth / 2;
+ GLint i, n;
+
+ for (i = 0; i < srcWidth; i++) {
+ GLfloat sumR = 0.0;
+ GLfloat sumG = 0.0;
+ GLfloat sumB = 0.0;
+ GLfloat sumA = 0.0;
+ for (n = 0; n < filterWidth; n++) {
+ if (i + n < halfFilterWidth) {
+ sumR += src[0][RCOMP] * filter[n][RCOMP];
+ sumG += src[0][GCOMP] * filter[n][GCOMP];
+ sumB += src[0][BCOMP] * filter[n][BCOMP];
+ sumA += src[0][ACOMP] * filter[n][ACOMP];
+ }
+ else if (i + n - halfFilterWidth >= srcWidth) {
+ sumR += src[srcWidth - 1][RCOMP] * filter[n][RCOMP];
+ sumG += src[srcWidth - 1][GCOMP] * filter[n][GCOMP];
+ sumB += src[srcWidth - 1][BCOMP] * filter[n][BCOMP];
+ sumA += src[srcWidth - 1][ACOMP] * filter[n][ACOMP];
+ }
+ else {
+ sumR += src[i + n - halfFilterWidth][RCOMP] * filter[n][RCOMP];
+ sumG += src[i + n - halfFilterWidth][GCOMP] * filter[n][GCOMP];
+ sumB += src[i + n - halfFilterWidth][BCOMP] * filter[n][BCOMP];
+ sumA += src[i + n - halfFilterWidth][ACOMP] * filter[n][ACOMP];
+ }
+ }
+ dest[i][RCOMP] = sumR;
+ dest[i][GCOMP] = sumG;
+ dest[i][BCOMP] = sumB;
+ dest[i][ACOMP] = sumA;
+ }
+}
+
+
+static void
+convolve_2d_reduce(GLint srcWidth, GLint srcHeight,
+ const GLfloat src[][4],
+ GLint filterWidth, GLint filterHeight,
+ const GLfloat filter[][4],
+ GLfloat dest[][4])
+{
+ GLint dstWidth, dstHeight;
+ GLint i, j, n, m;
+
+ if (filterWidth >= 1)
+ dstWidth = srcWidth - (filterWidth - 1);
+ else
+ dstWidth = srcWidth;
+
+ if (filterHeight >= 1)
+ dstHeight = srcHeight - (filterHeight - 1);
+ else
+ dstHeight = srcHeight;
+
+ if (dstWidth <= 0 || dstHeight <= 0)
+ return;
+
+ for (j = 0; j < dstHeight; j++) {
+ for (i = 0; i < dstWidth; i++) {
+ GLfloat sumR = 0.0;
+ GLfloat sumG = 0.0;
+ GLfloat sumB = 0.0;
+ GLfloat sumA = 0.0;
+ for (m = 0; m < filterHeight; m++) {
+ for (n = 0; n < filterWidth; n++) {
+ const GLint k = (j + m) * srcWidth + i + n;
+ const GLint f = m * filterWidth + n;
+ sumR += src[k][RCOMP] * filter[f][RCOMP];
+ sumG += src[k][GCOMP] * filter[f][GCOMP];
+ sumB += src[k][BCOMP] * filter[f][BCOMP];
+ sumA += src[k][ACOMP] * filter[f][ACOMP];
+ }
+ }
+ dest[j * dstWidth + i][RCOMP] = sumR;
+ dest[j * dstWidth + i][GCOMP] = sumG;
+ dest[j * dstWidth + i][BCOMP] = sumB;
+ dest[j * dstWidth + i][ACOMP] = sumA;
+ }
+ }
+}
+
+
+static void
+convolve_2d_constant(GLint srcWidth, GLint srcHeight,
+ const GLfloat src[][4],
+ GLint filterWidth, GLint filterHeight,
+ const GLfloat filter[][4],
+ GLfloat dest[][4],
+ const GLfloat borderColor[4])
+{
+ const GLint halfFilterWidth = filterWidth / 2;
+ const GLint halfFilterHeight = filterHeight / 2;
+ GLint i, j, n, m;
+
+ for (j = 0; j < srcHeight; j++) {
+ for (i = 0; i < srcWidth; i++) {
+ GLfloat sumR = 0.0;
+ GLfloat sumG = 0.0;
+ GLfloat sumB = 0.0;
+ GLfloat sumA = 0.0;
+ for (m = 0; m < filterHeight; m++) {
+ for (n = 0; n < filterWidth; n++) {
+ const GLint f = m * filterWidth + n;
+ const GLint is = i + n - halfFilterWidth;
+ const GLint js = j + m - halfFilterHeight;
+ if (is < 0 || is >= srcWidth ||
+ js < 0 || js >= srcHeight) {
+ sumR += borderColor[RCOMP] * filter[f][RCOMP];
+ sumG += borderColor[GCOMP] * filter[f][GCOMP];
+ sumB += borderColor[BCOMP] * filter[f][BCOMP];
+ sumA += borderColor[ACOMP] * filter[f][ACOMP];
+ }
+ else {
+ const GLint k = js * srcWidth + is;
+ sumR += src[k][RCOMP] * filter[f][RCOMP];
+ sumG += src[k][GCOMP] * filter[f][GCOMP];
+ sumB += src[k][BCOMP] * filter[f][BCOMP];
+ sumA += src[k][ACOMP] * filter[f][ACOMP];
+ }
+ }
+ }
+ dest[j * srcWidth + i][RCOMP] = sumR;
+ dest[j * srcWidth + i][GCOMP] = sumG;
+ dest[j * srcWidth + i][BCOMP] = sumB;
+ dest[j * srcWidth + i][ACOMP] = sumA;
+ }
+ }
+}
+
+
+static void
+convolve_2d_replicate(GLint srcWidth, GLint srcHeight,
+ const GLfloat src[][4],
+ GLint filterWidth, GLint filterHeight,
+ const GLfloat filter[][4],
+ GLfloat dest[][4])
+{
+ const GLint halfFilterWidth = filterWidth / 2;
+ const GLint halfFilterHeight = filterHeight / 2;
+ GLint i, j, n, m;
+
+ for (j = 0; j < srcHeight; j++) {
+ for (i = 0; i < srcWidth; i++) {
+ GLfloat sumR = 0.0;
+ GLfloat sumG = 0.0;
+ GLfloat sumB = 0.0;
+ GLfloat sumA = 0.0;
+ for (m = 0; m < filterHeight; m++) {
+ for (n = 0; n < filterWidth; n++) {
+ const GLint f = m * filterWidth + n;
+ GLint is = i + n - halfFilterWidth;
+ GLint js = j + m - halfFilterHeight;
+ GLint k;
+ if (is < 0)
+ is = 0;
+ else if (is >= srcWidth)
+ is = srcWidth - 1;
+ if (js < 0)
+ js = 0;
+ else if (js >= srcHeight)
+ js = srcHeight - 1;
+ k = js * srcWidth + is;
+ sumR += src[k][RCOMP] * filter[f][RCOMP];
+ sumG += src[k][GCOMP] * filter[f][GCOMP];
+ sumB += src[k][BCOMP] * filter[f][BCOMP];
+ sumA += src[k][ACOMP] * filter[f][ACOMP];
+ }
+ }
+ dest[j * srcWidth + i][RCOMP] = sumR;
+ dest[j * srcWidth + i][GCOMP] = sumG;
+ dest[j * srcWidth + i][BCOMP] = sumB;
+ dest[j * srcWidth + i][ACOMP] = sumA;
+ }
+ }
+}
+
+
+static void
+convolve_sep_reduce(GLint srcWidth, GLint srcHeight,
+ const GLfloat src[][4],
+ GLint filterWidth, GLint filterHeight,
+ const GLfloat rowFilt[][4],
+ const GLfloat colFilt[][4],
+ GLfloat dest[][4])
+{
+ GLint dstWidth, dstHeight;
+ GLint i, j, n, m;
+
+ if (filterWidth >= 1)
+ dstWidth = srcWidth - (filterWidth - 1);
+ else
+ dstWidth = srcWidth;
+
+ if (filterHeight >= 1)
+ dstHeight = srcHeight - (filterHeight - 1);
+ else
+ dstHeight = srcHeight;
+
+ if (dstWidth <= 0 || dstHeight <= 0)
+ return;
+
+ for (j = 0; j < dstHeight; j++) {
+ for (i = 0; i < dstWidth; i++) {
+ GLfloat sumR = 0.0;
+ GLfloat sumG = 0.0;
+ GLfloat sumB = 0.0;
+ GLfloat sumA = 0.0;
+ for (m = 0; m < filterHeight; m++) {
+ for (n = 0; n < filterWidth; n++) {
+ GLint k = (j + m) * srcWidth + i + n;
+ sumR += src[k][RCOMP] * rowFilt[n][RCOMP] * colFilt[m][RCOMP];
+ sumG += src[k][GCOMP] * rowFilt[n][GCOMP] * colFilt[m][GCOMP];
+ sumB += src[k][BCOMP] * rowFilt[n][BCOMP] * colFilt[m][BCOMP];
+ sumA += src[k][ACOMP] * rowFilt[n][ACOMP] * colFilt[m][ACOMP];
+ }
+ }
+ dest[j * dstWidth + i][RCOMP] = sumR;
+ dest[j * dstWidth + i][GCOMP] = sumG;
+ dest[j * dstWidth + i][BCOMP] = sumB;
+ dest[j * dstWidth + i][ACOMP] = sumA;
+ }
+ }
+}
+
+
+static void
+convolve_sep_constant(GLint srcWidth, GLint srcHeight,
+ const GLfloat src[][4],
+ GLint filterWidth, GLint filterHeight,
+ const GLfloat rowFilt[][4],
+ const GLfloat colFilt[][4],
+ GLfloat dest[][4],
+ const GLfloat borderColor[4])
+{
+ const GLint halfFilterWidth = filterWidth / 2;
+ const GLint halfFilterHeight = filterHeight / 2;
+ GLint i, j, n, m;
+
+ for (j = 0; j < srcHeight; j++) {
+ for (i = 0; i < srcWidth; i++) {
+ GLfloat sumR = 0.0;
+ GLfloat sumG = 0.0;
+ GLfloat sumB = 0.0;
+ GLfloat sumA = 0.0;
+ for (m = 0; m < filterHeight; m++) {
+ for (n = 0; n < filterWidth; n++) {
+ const GLint is = i + n - halfFilterWidth;
+ const GLint js = j + m - halfFilterHeight;
+ if (is < 0 || is >= srcWidth ||
+ js < 0 || js >= srcHeight) {
+ sumR += borderColor[RCOMP] * rowFilt[n][RCOMP] * colFilt[m][RCOMP];
+ sumG += borderColor[GCOMP] * rowFilt[n][GCOMP] * colFilt[m][GCOMP];
+ sumB += borderColor[BCOMP] * rowFilt[n][BCOMP] * colFilt[m][BCOMP];
+ sumA += borderColor[ACOMP] * rowFilt[n][ACOMP] * colFilt[m][ACOMP];
+ }
+ else {
+ GLint k = js * srcWidth + is;
+ sumR += src[k][RCOMP] * rowFilt[n][RCOMP] * colFilt[m][RCOMP];
+ sumG += src[k][GCOMP] * rowFilt[n][GCOMP] * colFilt[m][GCOMP];
+ sumB += src[k][BCOMP] * rowFilt[n][BCOMP] * colFilt[m][BCOMP];
+ sumA += src[k][ACOMP] * rowFilt[n][ACOMP] * colFilt[m][ACOMP];
+ }
+
+ }
+ }
+ dest[j * srcWidth + i][RCOMP] = sumR;
+ dest[j * srcWidth + i][GCOMP] = sumG;
+ dest[j * srcWidth + i][BCOMP] = sumB;
+ dest[j * srcWidth + i][ACOMP] = sumA;
+ }
+ }
+}
+
+
+static void
+convolve_sep_replicate(GLint srcWidth, GLint srcHeight,
+ const GLfloat src[][4],
+ GLint filterWidth, GLint filterHeight,
+ const GLfloat rowFilt[][4],
+ const GLfloat colFilt[][4],
+ GLfloat dest[][4])
+{
+ const GLint halfFilterWidth = filterWidth / 2;
+ const GLint halfFilterHeight = filterHeight / 2;
+ GLint i, j, n, m;
+
+ for (j = 0; j < srcHeight; j++) {
+ for (i = 0; i < srcWidth; i++) {
+ GLfloat sumR = 0.0;
+ GLfloat sumG = 0.0;
+ GLfloat sumB = 0.0;
+ GLfloat sumA = 0.0;
+ for (m = 0; m < filterHeight; m++) {
+ for (n = 0; n < filterWidth; n++) {
+ GLint is = i + n - halfFilterWidth;
+ GLint js = j + m - halfFilterHeight;
+ GLint k;
+ if (is < 0)
+ is = 0;
+ else if (is >= srcWidth)
+ is = srcWidth - 1;
+ if (js < 0)
+ js = 0;
+ else if (js >= srcHeight)
+ js = srcHeight - 1;
+ k = js * srcWidth + is;
+ sumR += src[k][RCOMP] * rowFilt[n][RCOMP] * colFilt[m][RCOMP];
+ sumG += src[k][GCOMP] * rowFilt[n][GCOMP] * colFilt[m][GCOMP];
+ sumB += src[k][BCOMP] * rowFilt[n][BCOMP] * colFilt[m][BCOMP];
+ sumA += src[k][ACOMP] * rowFilt[n][ACOMP] * colFilt[m][ACOMP];
+ }
+ }
+ dest[j * srcWidth + i][RCOMP] = sumR;
+ dest[j * srcWidth + i][GCOMP] = sumG;
+ dest[j * srcWidth + i][BCOMP] = sumB;
+ dest[j * srcWidth + i][ACOMP] = sumA;
+ }
+ }
+}
+
+
+
+void
+_mesa_convolve_1d_image(const GLcontext *ctx, GLsizei *width,
+ const GLfloat *srcImage, GLfloat *dstImage)
+{
+ switch (ctx->Pixel.ConvolutionBorderMode[0]) {
+ case GL_REDUCE:
+ convolve_1d_reduce(*width, (const GLfloat (*)[4]) srcImage,
+ ctx->Convolution1D.Width,
+ (const GLfloat (*)[4]) ctx->Convolution1D.Filter,
+ (GLfloat (*)[4]) dstImage);
+ *width = *width - (MAX2(ctx->Convolution1D.Width, 1) - 1);
+ break;
+ case GL_CONSTANT_BORDER:
+ convolve_1d_constant(*width, (const GLfloat (*)[4]) srcImage,
+ ctx->Convolution1D.Width,
+ (const GLfloat (*)[4]) ctx->Convolution1D.Filter,
+ (GLfloat (*)[4]) dstImage,
+ ctx->Pixel.ConvolutionBorderColor[0]);
+ break;
+ case GL_REPLICATE_BORDER:
+ convolve_1d_replicate(*width, (const GLfloat (*)[4]) srcImage,
+ ctx->Convolution1D.Width,
+ (const GLfloat (*)[4]) ctx->Convolution1D.Filter,
+ (GLfloat (*)[4]) dstImage);
+ break;
+ default:
+ ;
+ }
+}
+
+
+void
+_mesa_convolve_2d_image(const GLcontext *ctx, GLsizei *width, GLsizei *height,
+ const GLfloat *srcImage, GLfloat *dstImage)
+{
+ switch (ctx->Pixel.ConvolutionBorderMode[1]) {
+ case GL_REDUCE:
+ convolve_2d_reduce(*width, *height,
+ (const GLfloat (*)[4]) srcImage,
+ ctx->Convolution2D.Width,
+ ctx->Convolution2D.Height,
+ (const GLfloat (*)[4]) ctx->Convolution2D.Filter,
+ (GLfloat (*)[4]) dstImage);
+ *width = *width - (MAX2(ctx->Convolution2D.Width, 1) - 1);
+ *height = *height - (MAX2(ctx->Convolution2D.Height, 1) - 1);
+ break;
+ case GL_CONSTANT_BORDER:
+ convolve_2d_constant(*width, *height,
+ (const GLfloat (*)[4]) srcImage,
+ ctx->Convolution2D.Width,
+ ctx->Convolution2D.Height,
+ (const GLfloat (*)[4]) ctx->Convolution2D.Filter,
+ (GLfloat (*)[4]) dstImage,
+ ctx->Pixel.ConvolutionBorderColor[1]);
+ break;
+ case GL_REPLICATE_BORDER:
+ convolve_2d_replicate(*width, *height,
+ (const GLfloat (*)[4]) srcImage,
+ ctx->Convolution2D.Width,
+ ctx->Convolution2D.Height,
+ (const GLfloat (*)[4])ctx->Convolution2D.Filter,
+ (GLfloat (*)[4]) dstImage);
+ break;
+ default:
+ ;
+ }
+}
+
+
+void
+_mesa_convolve_sep_image(const GLcontext *ctx,
+ GLsizei *width, GLsizei *height,
+ const GLfloat *srcImage, GLfloat *dstImage)
+{
+ const GLfloat *rowFilter = ctx->Separable2D.Filter;
+ const GLfloat *colFilter = rowFilter + 4 * MAX_CONVOLUTION_WIDTH;
+
+ switch (ctx->Pixel.ConvolutionBorderMode[2]) {
+ case GL_REDUCE:
+ convolve_sep_reduce(*width, *height,
+ (const GLfloat (*)[4]) srcImage,
+ ctx->Separable2D.Width,
+ ctx->Separable2D.Height,
+ (const GLfloat (*)[4]) rowFilter,
+ (const GLfloat (*)[4]) colFilter,
+ (GLfloat (*)[4]) dstImage);
+ *width = *width - (MAX2(ctx->Separable2D.Width, 1) - 1);
+ *height = *height - (MAX2(ctx->Separable2D.Height, 1) - 1);
+ break;
+ case GL_CONSTANT_BORDER:
+ convolve_sep_constant(*width, *height,
+ (const GLfloat (*)[4]) srcImage,
+ ctx->Separable2D.Width,
+ ctx->Separable2D.Height,
+ (const GLfloat (*)[4]) rowFilter,
+ (const GLfloat (*)[4]) colFilter,
+ (GLfloat (*)[4]) dstImage,
+ ctx->Pixel.ConvolutionBorderColor[2]);
+ break;
+ case GL_REPLICATE_BORDER:
+ convolve_sep_replicate(*width, *height,
+ (const GLfloat (*)[4]) srcImage,
+ ctx->Separable2D.Width,
+ ctx->Separable2D.Height,
+ (const GLfloat (*)[4]) rowFilter,
+ (const GLfloat (*)[4]) colFilter,
+ (GLfloat (*)[4]) dstImage);
+ break;
+ default:
+ ;
+ }
+}
+
+
+
+/*
+ * This function computes an image's size after convolution.
+ * If the convolution border mode is GL_REDUCE, the post-convolution
+ * image will be smaller than the original.
+ */
+void
+_mesa_adjust_image_for_convolution(const GLcontext *ctx, GLuint dimensions,
+ GLsizei *width, GLsizei *height)
+{
+ if (ctx->Pixel.Convolution1DEnabled
+ && dimensions == 1
+ && ctx->Pixel.ConvolutionBorderMode[0] == GL_REDUCE) {
+ *width = *width - (MAX2(ctx->Convolution1D.Width, 1) - 1);
+ }
+ else if (ctx->Pixel.Convolution2DEnabled
+ && dimensions > 1
+ && ctx->Pixel.ConvolutionBorderMode[1] == GL_REDUCE) {
+ *width = *width - (MAX2(ctx->Convolution2D.Width, 1) - 1);
+ *height = *height - (MAX2(ctx->Convolution2D.Height, 1) - 1);
+ }
+ else if (ctx->Pixel.Separable2DEnabled
+ && dimensions > 1
+ && ctx->Pixel.ConvolutionBorderMode[2] == GL_REDUCE) {
+ *width = *width - (MAX2(ctx->Separable2D.Width, 1) - 1);
+ *height = *height - (MAX2(ctx->Separable2D.Height, 1) - 1);
+ }
+}
diff --git a/src/mesa/main/convolve.h b/src/mesa/main/convolve.h
new file mode 100644
index 00000000000..4505cdae01e
--- /dev/null
+++ b/src/mesa/main/convolve.h
@@ -0,0 +1,114 @@
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.5
+ *
+ * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef CONVOLVE_H
+#define CONVOLVE_H
+
+
+#include "mtypes.h"
+
+
+#if _HAVE_FULL_GL
+extern void GLAPIENTRY
+_mesa_ConvolutionFilter1D(GLenum target, GLenum internalformat, GLsizei width,
+ GLenum format, GLenum type, const GLvoid *image);
+
+extern void GLAPIENTRY
+_mesa_ConvolutionFilter2D(GLenum target, GLenum internalformat, GLsizei width,
+ GLsizei height, GLenum format, GLenum type,
+ const GLvoid *image);
+
+extern void GLAPIENTRY
+_mesa_ConvolutionParameterf(GLenum target, GLenum pname, GLfloat params);
+
+extern void GLAPIENTRY
+_mesa_ConvolutionParameterfv(GLenum target, GLenum pname,
+ const GLfloat *params);
+
+extern void GLAPIENTRY
+_mesa_ConvolutionParameteri(GLenum target, GLenum pname, GLint params);
+
+extern void GLAPIENTRY
+_mesa_ConvolutionParameteriv(GLenum target, GLenum pname, const GLint *params);
+
+extern void GLAPIENTRY
+_mesa_CopyConvolutionFilter1D(GLenum target, GLenum internalformat,
+ GLint x, GLint y, GLsizei width);
+
+extern void GLAPIENTRY
+_mesa_CopyConvolutionFilter2D(GLenum target, GLenum internalformat,
+ GLint x, GLint y, GLsizei width, GLsizei height);
+
+extern void GLAPIENTRY
+_mesa_GetConvolutionFilter(GLenum target, GLenum format, GLenum type,
+ GLvoid *image);
+
+extern void GLAPIENTRY
+_mesa_GetConvolutionParameterfv(GLenum target, GLenum pname, GLfloat *params);
+
+extern void GLAPIENTRY
+_mesa_GetConvolutionParameteriv(GLenum target, GLenum pname, GLint *params);
+
+extern void GLAPIENTRY
+_mesa_GetSeparableFilter(GLenum target, GLenum format, GLenum type,
+ GLvoid *row, GLvoid *column, GLvoid *span);
+
+extern void GLAPIENTRY
+_mesa_SeparableFilter2D(GLenum target, GLenum internalformat,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const GLvoid *row, const GLvoid *column);
+
+
+
+extern void
+_mesa_convolve_1d_image(const GLcontext *ctx, GLsizei *width,
+ const GLfloat *srcImage, GLfloat *dstImage);
+
+
+extern void
+_mesa_convolve_2d_image(const GLcontext *ctx, GLsizei *width, GLsizei *height,
+ const GLfloat *srcImage, GLfloat *dstImage);
+
+
+extern void
+_mesa_convolve_sep_image(const GLcontext *ctx,
+ GLsizei *width, GLsizei *height,
+ const GLfloat *srcImage, GLfloat *dstImage);
+
+
+extern void
+_mesa_adjust_image_for_convolution(const GLcontext *ctx, GLuint dimensions,
+ GLsizei *width, GLsizei *height);
+
+#else
+#define _mesa_adjust_image_for_convolution(c, d, w, h) ((void)0)
+#define _mesa_convolve_1d_image(c,w,s,d) ((void)0)
+#define _mesa_convolve_2d_image(c,w,h,s,d) ((void)0)
+#define _mesa_convolve_sep_image(c,w,h,s,d) ((void)0)
+#endif
+
+#endif
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
new file mode 100644
index 00000000000..4f1a962731d
--- /dev/null
+++ b/src/mesa/main/dd.h
@@ -0,0 +1,1072 @@
+/**
+ * \file dd.h
+ * Device driver interfaces.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef DD_INCLUDED
+#define DD_INCLUDED
+
+/* THIS FILE ONLY INCLUDED BY mtypes.h !!!!! */
+
+struct gl_pixelstore_attrib;
+struct mesa_display_list;
+
+/**
+ * Device driver function table.
+ * Core Mesa uses these function pointers to call into device drivers.
+ * Most of these functions directly correspond to OpenGL state commands.
+ * Core Mesa will call these functions after error checking has been done
+ * so that the drivers don't have to worry about error testing.
+ *
+ * Vertex transformation/clipping/lighting is patched into the T&L module.
+ * Rasterization functions are patched into the swrast module.
+ *
+ * Note: when new functions are added here, the drivers/common/driverfuncs.c
+ * file should be updated too!!!
+ */
+struct dd_function_table {
+ /**
+ * Return a string as needed by glGetString().
+ *
+ * Only the GL_RENDERER token must be implemented. Otherwise, NULL can be
+ * returned.
+ */
+ const GLubyte * (*GetString)( GLcontext *ctx, GLenum name );
+
+ /**
+ * Notify the driver after Mesa has made some internal state changes.
+ *
+ * This is in addition to any state change callbacks Mesa may already have
+ * made.
+ */
+ void (*UpdateState)( GLcontext *ctx, GLbitfield new_state );
+
+ /**
+ * Get the width and height of the named buffer/window.
+ *
+ * Mesa uses this to determine when the driver's window size has changed.
+ */
+ void (*GetBufferSize)( GLframebuffer *buffer,
+ GLuint *width, GLuint *height );
+
+ /**
+ * Resize the given framebuffer to the given size.
+ */
+ void (*ResizeBuffers)( GLcontext *ctx, GLframebuffer *fb,
+ GLuint width, GLuint height);
+
+ /**
+ * Called whenever an error is generated.
+ *
+ * __GLcontextRec::ErrorValue contains the error value.
+ */
+ void (*Error)( GLcontext *ctx );
+
+ /**
+ * This is called whenever glFinish() is called.
+ */
+ void (*Finish)( GLcontext *ctx );
+
+ /**
+ * This is called whenever glFlush() is called.
+ */
+ void (*Flush)( GLcontext *ctx );
+
+ /**
+ * Clear the color/depth/stencil/accum buffer(s).
+ *
+ * \param mask a bitmask of the DD_*_BIT values defined above that indicates
+ * which buffers need to be cleared.
+ * \param all if true then clear the whole buffer, else clear only the
+ * region defined by <tt>(x, y, width, height)</tt>.
+ *
+ * This function must obey the glColorMask(), glIndexMask() and
+ * glStencilMask() settings!
+ * Software Mesa can do masked clears if the device driver can't.
+ */
+ void (*Clear)( GLcontext *ctx, GLbitfield mask, GLboolean all,
+ GLint x, GLint y, GLint width, GLint height );
+
+
+ /**
+ * \name For hardware accumulation buffer
+ */
+ /*@{*/
+ /**
+ * Execute glAccum command within the given scissor region.
+ */
+ void (*Accum)( GLcontext *ctx, GLenum op, GLfloat value,
+ GLint xpos, GLint ypos, GLint width, GLint height );
+ /*@}*/
+
+
+ /**
+ * \name glDraw(), glRead(), glCopyPixels() and glBitmap() functions
+ */
+ /*@{*/
+
+ /**
+ * This is called by glDrawPixels().
+ *
+ * \p unpack describes how to unpack the source image data.
+ */
+ void (*DrawPixels)( GLcontext *ctx,
+ GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const struct gl_pixelstore_attrib *unpack,
+ const GLvoid *pixels );
+
+ /**
+ * Called by glReadPixels().
+ */
+ void (*ReadPixels)( GLcontext *ctx,
+ GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const struct gl_pixelstore_attrib *unpack,
+ GLvoid *dest );
+
+ /**
+ * Do a glCopyPixels().
+ *
+ * This function must respect all rasterization state, glPixelTransfer(),
+ * glPixelZoom(), etc.
+ */
+ void (*CopyPixels)( GLcontext *ctx, GLint srcx, GLint srcy,
+ GLsizei width, GLsizei height,
+ GLint dstx, GLint dsty, GLenum type );
+
+ /**
+ * This is called by glBitmap().
+ *
+ * Works the same as dd_function_table::DrawPixels, above.
+ */
+ void (*Bitmap)( GLcontext *ctx,
+ GLint x, GLint y, GLsizei width, GLsizei height,
+ const struct gl_pixelstore_attrib *unpack,
+ const GLubyte *bitmap );
+ /*@}*/
+
+
+ /**
+ * \name Texture image functions
+ */
+ /*@{*/
+
+ /**
+ * Choose texture format.
+ *
+ * This is called by the \c _mesa_store_tex[sub]image[123]d() fallback
+ * functions. The driver should examine \p internalFormat and return a
+ * pointer to an appropriate gl_texture_format.
+ */
+ const struct gl_texture_format *(*ChooseTextureFormat)( GLcontext *ctx,
+ GLint internalFormat, GLenum srcFormat, GLenum srcType );
+
+ /**
+ * Called by glTexImage1D().
+ *
+ * \param target user specified.
+ * \param format user specified.
+ * \param type user specified.
+ * \param pixels user specified.
+ * \param packing indicates the image packing of pixels.
+ * \param texObj is the target texture object.
+ * \param texImage is the target texture image. It will have the texture \p
+ * width, \p height, \p depth, \p border and \p internalFormat information.
+ *
+ * \p retainInternalCopy is returned by this function and indicates whether
+ * core Mesa should keep an internal copy of the texture image.
+ *
+ * Drivers should call a fallback routine from texstore.c if needed.
+ */
+ void (*TexImage1D)( GLcontext *ctx, GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint border,
+ GLenum format, GLenum type, const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage );
+
+ /**
+ * Called by glTexImage2D().
+ *
+ * \sa dd_function_table::TexImage1D.
+ */
+ void (*TexImage2D)( GLcontext *ctx, GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint height, GLint border,
+ GLenum format, GLenum type, const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage );
+
+ /**
+ * Called by glTexImage3D().
+ *
+ * \sa dd_function_table::TexImage1D.
+ */
+ void (*TexImage3D)( GLcontext *ctx, GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint height, GLint depth, GLint border,
+ GLenum format, GLenum type, const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage );
+
+ /**
+ * Called by glTexSubImage1D().
+ *
+ * \param target user specified.
+ * \param level user specified.
+ * \param xoffset user specified.
+ * \param yoffset user specified.
+ * \param zoffset user specified.
+ * \param width user specified.
+ * \param height user specified.
+ * \param depth user specified.
+ * \param format user specified.
+ * \param type user specified.
+ * \param pixels user specified.
+ * \param packing indicates the image packing of pixels.
+ * \param texObj is the target texture object.
+ * \param texImage is the target texture image. It will have the texture \p
+ * width, \p height, \p border and \p internalFormat information.
+ *
+ * The driver should use a fallback routine from texstore.c if needed.
+ */
+ void (*TexSubImage1D)( GLcontext *ctx, GLenum target, GLint level,
+ GLint xoffset, GLsizei width,
+ GLenum format, GLenum type,
+ const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage );
+
+ /**
+ * Called by glTexSubImage2D().
+ *
+ * \sa dd_function_table::TexSubImage1D.
+ */
+ void (*TexSubImage2D)( GLcontext *ctx, GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage );
+
+ /**
+ * Called by glTexSubImage3D().
+ *
+ * \sa dd_function_table::TexSubImage1D.
+ */
+ void (*TexSubImage3D)( GLcontext *ctx, GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLint depth,
+ GLenum format, GLenum type,
+ const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage );
+
+ /**
+ * Called by glGetTexImage().
+ */
+ void (*GetTexImage)( GLcontext *ctx, GLenum target, GLint level,
+ GLenum format, GLenum type, GLvoid *pixels,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage );
+
+ /**
+ * Called by glCopyTexImage1D().
+ *
+ * Drivers should use a fallback routine from texstore.c if needed.
+ */
+ void (*CopyTexImage1D)( GLcontext *ctx, GLenum target, GLint level,
+ GLenum internalFormat, GLint x, GLint y,
+ GLsizei width, GLint border );
+
+ /**
+ * Called by glCopyTexImage2D().
+ *
+ * Drivers should use a fallback routine from texstore.c if needed.
+ */
+ void (*CopyTexImage2D)( GLcontext *ctx, GLenum target, GLint level,
+ GLenum internalFormat, GLint x, GLint y,
+ GLsizei width, GLsizei height, GLint border );
+
+ /**
+ * Called by glCopyTexSubImage1D().
+ *
+ * Drivers should use a fallback routine from texstore.c if needed.
+ */
+ void (*CopyTexSubImage1D)( GLcontext *ctx, GLenum target, GLint level,
+ GLint xoffset,
+ GLint x, GLint y, GLsizei width );
+ /**
+ * Called by glCopyTexSubImage2D().
+ *
+ * Drivers should use a fallback routine from texstore.c if needed.
+ */
+ void (*CopyTexSubImage2D)( GLcontext *ctx, GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLint x, GLint y,
+ GLsizei width, GLsizei height );
+ /**
+ * Called by glCopyTexSubImage3D().
+ *
+ * Drivers should use a fallback routine from texstore.c if needed.
+ */
+ void (*CopyTexSubImage3D)( GLcontext *ctx, GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLint x, GLint y,
+ GLsizei width, GLsizei height );
+
+ /**
+ * Called by glTexImage[123]D when user specifies a proxy texture
+ * target.
+ *
+ * \return GL_TRUE if the proxy test passes, or GL_FALSE if the test fails.
+ */
+ GLboolean (*TestProxyTexImage)(GLcontext *ctx, GLenum target,
+ GLint level, GLint internalFormat,
+ GLenum format, GLenum type,
+ GLint width, GLint height,
+ GLint depth, GLint border);
+ /*@}*/
+
+
+ /**
+ * \name Compressed texture functions
+ */
+ /*@{*/
+
+ /**
+ * Called by glCompressedTexImage1D().
+ *
+ * \param target user specified.
+ * \param format user specified.
+ * \param type user specified.
+ * \param pixels user specified.
+ * \param packing indicates the image packing of pixels.
+ * \param texObj is the target texture object.
+ * \param texImage is the target texture image. It will have the texture \p
+ * width, \p height, \p depth, \p border and \p internalFormat information.
+ *
+ * \a retainInternalCopy is returned by this function and indicates whether
+ * core Mesa should keep an internal copy of the texture image.
+ */
+ void (*CompressedTexImage1D)( GLcontext *ctx, GLenum target,
+ GLint level, GLint internalFormat,
+ GLsizei width, GLint border,
+ GLsizei imageSize, const GLvoid *data,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage );
+ /**
+ * Called by glCompressedTexImage2D().
+ *
+ * \sa dd_function_table::CompressedTexImage1D.
+ */
+ void (*CompressedTexImage2D)( GLcontext *ctx, GLenum target,
+ GLint level, GLint internalFormat,
+ GLsizei width, GLsizei height, GLint border,
+ GLsizei imageSize, const GLvoid *data,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage );
+ /**
+ * Called by glCompressedTexImage3D().
+ *
+ * \sa dd_function_table::CompressedTexImage3D.
+ */
+ void (*CompressedTexImage3D)( GLcontext *ctx, GLenum target,
+ GLint level, GLint internalFormat,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLint border,
+ GLsizei imageSize, const GLvoid *data,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage );
+
+ /**
+ * Called by glCompressedTexSubImage1D().
+ *
+ * \param target user specified.
+ * \param level user specified.
+ * \param xoffset user specified.
+ * \param yoffset user specified.
+ * \param zoffset user specified.
+ * \param width user specified.
+ * \param height user specified.
+ * \param depth user specified.
+ * \param imageSize user specified.
+ * \param data user specified.
+ * \param texObj is the target texture object.
+ * \param texImage is the target texture image. It will have the texture \p
+ * width, \p height, \p depth, \p border and \p internalFormat information.
+ */
+ void (*CompressedTexSubImage1D)(GLcontext *ctx, GLenum target, GLint level,
+ GLint xoffset, GLsizei width,
+ GLenum format,
+ GLsizei imageSize, const GLvoid *data,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage);
+ /**
+ * Called by glCompressedTexSubImage2D().
+ *
+ * \sa dd_function_table::CompressedTexImage3D.
+ */
+ void (*CompressedTexSubImage2D)(GLcontext *ctx, GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLint height,
+ GLenum format,
+ GLsizei imageSize, const GLvoid *data,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage);
+ /**
+ * Called by glCompressedTexSubImage3D().
+ *
+ * \sa dd_function_table::CompressedTexImage3D.
+ */
+ void (*CompressedTexSubImage3D)(GLcontext *ctx, GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLint height, GLint depth,
+ GLenum format,
+ GLsizei imageSize, const GLvoid *data,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage);
+
+
+ /**
+ * Called by glGetCompressedTexImage.
+ */
+ void (*GetCompressedTexImage)(GLcontext *ctx, GLenum target, GLint level,
+ GLvoid *img,
+ const struct gl_texture_object *texObj,
+ const struct gl_texture_image *texImage);
+
+ /**
+ * Called to query number of bytes of storage needed to store the
+ * specified compressed texture.
+ */
+ GLuint (*CompressedTextureSize)( GLcontext *ctx, GLsizei width,
+ GLsizei height, GLsizei depth,
+ GLenum format );
+ /*@}*/
+
+ /**
+ * \name Texture object functions
+ */
+ /*@{*/
+
+ /**
+ * Called by glBindTexture().
+ */
+ void (*BindTexture)( GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj );
+
+ /**
+ * Called to allocate a new texture object.
+ * A new gl_texture_object should be returned. The driver should
+ * attach to it any device-specific info it needs.
+ */
+ struct gl_texture_object * (*NewTextureObject)( GLcontext *ctx, GLuint name,
+ GLenum target );
+ /**
+ * Called when a texture object is about to be deallocated.
+ *
+ * Driver should delete the gl_texture_object object and anything
+ * hanging off of it.
+ */
+ void (*DeleteTexture)( GLcontext *ctx, struct gl_texture_object *tObj );
+
+ /**
+ * Called to allocate a new texture image object.
+ */
+ struct gl_texture_image * (*NewTextureImage)( GLcontext *ctx );
+
+ /**
+ * Called to free tImage->Data.
+ */
+ void (*FreeTexImageData)( GLcontext *ctx, struct gl_texture_image *tImage );
+
+ /**
+ * Note: no context argument. This function doesn't initially look
+ * like it belongs here, except that the driver is the only entity
+ * that knows for sure how the texture memory is allocated - via
+ * the above callbacks. There is then an argument that the driver
+ * knows what memcpy paths might be fast. Typically this is invoked with
+ *
+ * to -- a pointer into texture memory allocated by NewTextureImage() above.
+ * from -- a pointer into client memory or a mesa temporary.
+ * sz -- nr bytes to copy.
+ */
+ void* (*TextureMemCpy)( void *to, const void *from, size_t sz );
+
+ /**
+ * Called by glAreTextureResident().
+ */
+ GLboolean (*IsTextureResident)( GLcontext *ctx,
+ struct gl_texture_object *t );
+
+ /**
+ * Called by glPrioritizeTextures().
+ */
+ void (*PrioritizeTexture)( GLcontext *ctx, struct gl_texture_object *t,
+ GLclampf priority );
+
+ /**
+ * Called by glActiveTextureARB() to set current texture unit.
+ */
+ void (*ActiveTexture)( GLcontext *ctx, GLuint texUnitNumber );
+
+ /**
+ * Called when the texture's color lookup table is changed.
+ *
+ * If \p tObj is NULL then the shared texture palette
+ * gl_texture_object::Palette is to be updated.
+ */
+ void (*UpdateTexturePalette)( GLcontext *ctx,
+ struct gl_texture_object *tObj );
+ /*@}*/
+
+
+ /**
+ * \name Imaging functionality
+ */
+ /*@{*/
+ void (*CopyColorTable)( GLcontext *ctx,
+ GLenum target, GLenum internalformat,
+ GLint x, GLint y, GLsizei width );
+
+ void (*CopyColorSubTable)( GLcontext *ctx,
+ GLenum target, GLsizei start,
+ GLint x, GLint y, GLsizei width );
+
+ void (*CopyConvolutionFilter1D)( GLcontext *ctx, GLenum target,
+ GLenum internalFormat,
+ GLint x, GLint y, GLsizei width );
+
+ void (*CopyConvolutionFilter2D)( GLcontext *ctx, GLenum target,
+ GLenum internalFormat,
+ GLint x, GLint y,
+ GLsizei width, GLsizei height );
+ /*@}*/
+
+
+ /**
+ * \name Vertex/fragment program functions
+ */
+ /*@{*/
+ /** Bind a vertex/fragment program */
+ void (*BindProgram)(GLcontext *ctx, GLenum target, struct program *prog);
+ /** Allocate a new program */
+ struct program * (*NewProgram)(GLcontext *ctx, GLenum target, GLuint id);
+ /** Delete a program */
+ void (*DeleteProgram)(GLcontext *ctx, struct program *prog);
+ /** Notify driver that a program string has been specified. */
+ void (*ProgramStringNotify)(GLcontext *ctx, GLenum target,
+ struct program *prog);
+
+
+
+ /** Query if program can be loaded onto hardware */
+ GLboolean (*IsProgramNative)(GLcontext *ctx, GLenum target,
+ struct program *prog);
+
+ /*@}*/
+
+
+ /**
+ * \name State-changing functions.
+ *
+ * \note drawing functions are above.
+ *
+ * These functions are called by their corresponding OpenGL API functions.
+ * They are \e also called by the gl_PopAttrib() function!!!
+ * May add more functions like these to the device driver in the future.
+ */
+ /*@{*/
+ /** Specify the alpha test function */
+ void (*AlphaFunc)(GLcontext *ctx, GLenum func, GLfloat ref);
+ /** Set the blend color */
+ void (*BlendColor)(GLcontext *ctx, const GLfloat color[4]);
+ /** Set the blend equation */
+ void (*BlendEquationSeparate)(GLcontext *ctx, GLenum modeRGB, GLenum modeA);
+ /** Specify pixel arithmetic */
+ void (*BlendFuncSeparate)(GLcontext *ctx,
+ GLenum sfactorRGB, GLenum dfactorRGB,
+ GLenum sfactorA, GLenum dfactorA);
+ /** Specify clear values for the color buffers */
+ void (*ClearColor)(GLcontext *ctx, const GLfloat color[4]);
+ /** Specify the clear value for the depth buffer */
+ void (*ClearDepth)(GLcontext *ctx, GLclampd d);
+ /** Specify the clear value for the color index buffers */
+ void (*ClearIndex)(GLcontext *ctx, GLuint index);
+ /** Specify the clear value for the stencil buffer */
+ void (*ClearStencil)(GLcontext *ctx, GLint s);
+ /** Specify a plane against which all geometry is clipped */
+ void (*ClipPlane)(GLcontext *ctx, GLenum plane, const GLfloat *equation );
+ /** Enable and disable writing of frame buffer color components */
+ void (*ColorMask)(GLcontext *ctx, GLboolean rmask, GLboolean gmask,
+ GLboolean bmask, GLboolean amask );
+ /** Cause a material color to track the current color */
+ void (*ColorMaterial)(GLcontext *ctx, GLenum face, GLenum mode);
+ /** Specify whether front- or back-facing facets can be culled */
+ void (*CullFace)(GLcontext *ctx, GLenum mode);
+ /** Define front- and back-facing polygons */
+ void (*FrontFace)(GLcontext *ctx, GLenum mode);
+ /** Specify the value used for depth buffer comparisons */
+ void (*DepthFunc)(GLcontext *ctx, GLenum func);
+ /** Enable or disable writing into the depth buffer */
+ void (*DepthMask)(GLcontext *ctx, GLboolean flag);
+ /** Specify mapping of depth values from NDC to window coordinates */
+ void (*DepthRange)(GLcontext *ctx, GLclampd nearval, GLclampd farval);
+ /** Specify the current buffer for writing */
+ void (*DrawBuffer)( GLcontext *ctx, GLenum buffer );
+ /** Specify the buffers for writing for fragment programs*/
+ void (*DrawBuffers)( GLcontext *ctx, GLsizei n, const GLenum *buffers );
+ /** Enable or disable server-side gl capabilities */
+ void (*Enable)(GLcontext *ctx, GLenum cap, GLboolean state);
+ /** Specify fog parameters */
+ void (*Fogfv)(GLcontext *ctx, GLenum pname, const GLfloat *params);
+ /** Specify implementation-specific hints */
+ void (*Hint)(GLcontext *ctx, GLenum target, GLenum mode);
+ /** Control the writing of individual bits in the color index buffers */
+ void (*IndexMask)(GLcontext *ctx, GLuint mask);
+ /** Set light source parameters.
+ * Note: for GL_POSITION and GL_SPOT_DIRECTION, params will have already
+ * been transformed to eye-space.
+ */
+ void (*Lightfv)(GLcontext *ctx, GLenum light,
+ GLenum pname, const GLfloat *params );
+ /** Set the lighting model parameters */
+ void (*LightModelfv)(GLcontext *ctx, GLenum pname, const GLfloat *params);
+ /** Specify the line stipple pattern */
+ void (*LineStipple)(GLcontext *ctx, GLint factor, GLushort pattern );
+ /** Specify the width of rasterized lines */
+ void (*LineWidth)(GLcontext *ctx, GLfloat width);
+ /** Specify a logical pixel operation for color index rendering */
+ void (*LogicOpcode)(GLcontext *ctx, GLenum opcode);
+ void (*PointParameterfv)(GLcontext *ctx, GLenum pname,
+ const GLfloat *params);
+ /** Specify the diameter of rasterized points */
+ void (*PointSize)(GLcontext *ctx, GLfloat size);
+ /** Select a polygon rasterization mode */
+ void (*PolygonMode)(GLcontext *ctx, GLenum face, GLenum mode);
+ /** Set the scale and units used to calculate depth values */
+ void (*PolygonOffset)(GLcontext *ctx, GLfloat factor, GLfloat units);
+ /** Set the polygon stippling pattern */
+ void (*PolygonStipple)(GLcontext *ctx, const GLubyte *mask );
+ /* Specifies the current buffer for reading */
+ void (*ReadBuffer)( GLcontext *ctx, GLenum buffer );
+ /** Set rasterization mode */
+ void (*RenderMode)(GLcontext *ctx, GLenum mode );
+ /** Define the scissor box */
+ void (*Scissor)(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h);
+ /** Select flat or smooth shading */
+ void (*ShadeModel)(GLcontext *ctx, GLenum mode);
+ /** OpenGL 2.0 two-sided StencilFunc */
+ void (*StencilFuncSeparate)(GLcontext *ctx, GLenum face, GLenum func,
+ GLint ref, GLuint mask);
+ /** OpenGL 2.0 two-sided StencilMask */
+ void (*StencilMaskSeparate)(GLcontext *ctx, GLenum face, GLuint mask);
+ /** OpenGL 2.0 two-sided StencilOp */
+ void (*StencilOpSeparate)(GLcontext *ctx, GLenum face, GLenum fail,
+ GLenum zfail, GLenum zpass);
+ /** Control the generation of texture coordinates */
+ void (*TexGen)(GLcontext *ctx, GLenum coord, GLenum pname,
+ const GLfloat *params);
+ /** Set texture environment parameters */
+ void (*TexEnv)(GLcontext *ctx, GLenum target, GLenum pname,
+ const GLfloat *param);
+ /** Set texture parameters */
+ void (*TexParameter)(GLcontext *ctx, GLenum target,
+ struct gl_texture_object *texObj,
+ GLenum pname, const GLfloat *params);
+ void (*TextureMatrix)(GLcontext *ctx, GLuint unit, const GLmatrix *mat);
+ /** Set the viewport */
+ void (*Viewport)(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h);
+ /*@}*/
+
+
+ /**
+ * \name Vertex array functions
+ *
+ * Called by the corresponding OpenGL functions.
+ */
+ /*@{*/
+ void (*VertexPointer)(GLcontext *ctx, GLint size, GLenum type,
+ GLsizei stride, const GLvoid *ptr);
+ void (*NormalPointer)(GLcontext *ctx, GLenum type,
+ GLsizei stride, const GLvoid *ptr);
+ void (*ColorPointer)(GLcontext *ctx, GLint size, GLenum type,
+ GLsizei stride, const GLvoid *ptr);
+ void (*FogCoordPointer)(GLcontext *ctx, GLenum type,
+ GLsizei stride, const GLvoid *ptr);
+ void (*IndexPointer)(GLcontext *ctx, GLenum type,
+ GLsizei stride, const GLvoid *ptr);
+ void (*SecondaryColorPointer)(GLcontext *ctx, GLint size, GLenum type,
+ GLsizei stride, const GLvoid *ptr);
+ void (*TexCoordPointer)(GLcontext *ctx, GLint size, GLenum type,
+ GLsizei stride, const GLvoid *ptr);
+ void (*EdgeFlagPointer)(GLcontext *ctx, GLsizei stride, const GLvoid *ptr);
+ void (*VertexAttribPointer)(GLcontext *ctx, GLuint index, GLint size,
+ GLenum type, GLsizei stride, const GLvoid *ptr);
+ void (*LockArraysEXT)( GLcontext *ctx, GLint first, GLsizei count );
+ void (*UnlockArraysEXT)( GLcontext *ctx );
+ /*@}*/
+
+
+ /**
+ * \name State-query functions
+ *
+ * Return GL_TRUE if query was completed, GL_FALSE otherwise.
+ */
+ /*@{*/
+ /** Return the value or values of a selected parameter */
+ GLboolean (*GetBooleanv)(GLcontext *ctx, GLenum pname, GLboolean *result);
+ /** Return the value or values of a selected parameter */
+ GLboolean (*GetDoublev)(GLcontext *ctx, GLenum pname, GLdouble *result);
+ /** Return the value or values of a selected parameter */
+ GLboolean (*GetFloatv)(GLcontext *ctx, GLenum pname, GLfloat *result);
+ /** Return the value or values of a selected parameter */
+ GLboolean (*GetIntegerv)(GLcontext *ctx, GLenum pname, GLint *result);
+ /** Return the value or values of a selected parameter */
+ GLboolean (*GetPointerv)(GLcontext *ctx, GLenum pname, GLvoid **result);
+ /*@}*/
+
+
+ /**
+ * \name Vertex/pixel buffer object functions
+ */
+#if FEATURE_ARB_vertex_buffer_object
+ /*@{*/
+ void (*BindBuffer)( GLcontext *ctx, GLenum target,
+ struct gl_buffer_object *obj );
+
+ struct gl_buffer_object * (*NewBufferObject)( GLcontext *ctx, GLuint buffer,
+ GLenum target );
+
+ void (*DeleteBuffer)( GLcontext *ctx, struct gl_buffer_object *obj );
+
+ void (*BufferData)( GLcontext *ctx, GLenum target, GLsizeiptrARB size,
+ const GLvoid *data, GLenum usage,
+ struct gl_buffer_object *obj );
+
+ void (*BufferSubData)( GLcontext *ctx, GLenum target, GLintptrARB offset,
+ GLsizeiptrARB size, const GLvoid *data,
+ struct gl_buffer_object *obj );
+
+ void (*GetBufferSubData)( GLcontext *ctx, GLenum target,
+ GLintptrARB offset, GLsizeiptrARB size,
+ GLvoid *data, struct gl_buffer_object *obj );
+
+ void * (*MapBuffer)( GLcontext *ctx, GLenum target, GLenum access,
+ struct gl_buffer_object *obj );
+
+ GLboolean (*UnmapBuffer)( GLcontext *ctx, GLenum target,
+ struct gl_buffer_object *obj );
+ /*@}*/
+#endif
+
+ /**
+ * \name Functions for GL_EXT_framebuffer_object
+ */
+#if FEATURE_EXT_framebuffer_object
+ /*@{*/
+ struct gl_framebuffer * (*NewFramebuffer)(GLcontext *ctx, GLuint name);
+ struct gl_renderbuffer * (*NewRenderbuffer)(GLcontext *ctx, GLuint name);
+ void (*BindFramebuffer)(GLcontext *ctx, GLenum target,
+ struct gl_framebuffer *fb);
+ void (*FramebufferRenderbuffer)(GLcontext *ctx,
+ struct gl_framebuffer *fb,
+ GLenum attachment,
+ struct gl_renderbuffer *rb);
+ void (*RenderTexture)(GLcontext *ctx,
+ struct gl_framebuffer *fb,
+ struct gl_renderbuffer_attachment *att);
+ void (*FinishRenderTexture)(GLcontext *ctx,
+ struct gl_renderbuffer_attachment *att);
+ /*@}*/
+#endif
+#if FEATURE_EXT_framebuffer_blit
+ void (*BlitFramebuffer)(GLcontext *ctx,
+ GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter);
+#endif
+
+ /**
+ * \name Query objects
+ */
+ /*@{*/
+ struct gl_query_object * (*NewQueryObject)(GLcontext *ctx, GLuint id);
+ void (*BeginQuery)(GLcontext *ctx, GLenum target,
+ struct gl_query_object *q);
+ void (*EndQuery)(GLcontext *ctx, GLenum target, struct gl_query_object *q);
+ /*@}*/
+
+
+ /**
+ * \name Support for multiple T&L engines
+ */
+ /*@{*/
+
+ /**
+ * Bitmask of state changes that require the current T&L module to be
+ * validated, using ValidateTnlModule() below.
+ */
+ GLuint NeedValidate;
+
+ /**
+ * Validate the current T&L module.
+ *
+ * This is called directly after UpdateState() when a state change that has
+ * occurred matches the dd_function_table::NeedValidate bitmask above. This
+ * ensures all computed values are up to date, thus allowing the driver to
+ * decide if the current T&L module needs to be swapped out.
+ *
+ * This must be non-NULL if a driver installs a custom T&L module and sets
+ * the dd_function_table::NeedValidate bitmask, but may be NULL otherwise.
+ */
+ void (*ValidateTnlModule)( GLcontext *ctx, GLuint new_state );
+
+
+#define PRIM_OUTSIDE_BEGIN_END GL_POLYGON+1
+#define PRIM_INSIDE_UNKNOWN_PRIM GL_POLYGON+2
+#define PRIM_UNKNOWN GL_POLYGON+3
+
+ /**
+ * Set by the driver-supplied T&L engine.
+ *
+ * Set to PRIM_OUTSIDE_BEGIN_END when outside glBegin()/glEnd().
+ */
+ GLuint CurrentExecPrimitive;
+
+ /**
+ * Current state of an in-progress compilation.
+ *
+ * May take on any of the additional values PRIM_OUTSIDE_BEGIN_END,
+ * PRIM_INSIDE_UNKNOWN_PRIM or PRIM_UNKNOWN defined above.
+ */
+ GLuint CurrentSavePrimitive;
+
+
+#define FLUSH_STORED_VERTICES 0x1
+#define FLUSH_UPDATE_CURRENT 0x2
+ /**
+ * Set by the driver-supplied T&L engine whenever vertices are buffered
+ * between glBegin()/glEnd() objects or __GLcontextRec::Current is not
+ * updated.
+ *
+ * The dd_function_table::FlushVertices call below may be used to resolve
+ * these conditions.
+ */
+ GLuint NeedFlush;
+ GLuint SaveNeedFlush;
+
+ /**
+ * If inside glBegin()/glEnd(), it should ASSERT(0). Otherwise, if
+ * FLUSH_STORED_VERTICES bit in \p flags is set flushes any buffered
+ * vertices, if FLUSH_UPDATE_CURRENT bit is set updates
+ * __GLcontextRec::Current and gl_light_attrib::Material
+ *
+ * Note that the default T&L engine never clears the
+ * FLUSH_UPDATE_CURRENT bit, even after performing the update.
+ */
+ void (*FlushVertices)( GLcontext *ctx, GLuint flags );
+ void (*SaveFlushVertices)( GLcontext *ctx );
+
+ /**
+ * Give the driver the opportunity to hook in its own vtxfmt for
+ * compiling optimized display lists. This is called on each valid
+ * glBegin() during list compilation.
+ */
+ GLboolean (*NotifySaveBegin)( GLcontext *ctx, GLenum mode );
+
+ /**
+ * Notify driver that the special derived value _NeedEyeCoords has
+ * changed.
+ */
+ void (*LightingSpaceChange)( GLcontext *ctx );
+
+ /**
+ * Called by glNewList().
+ *
+ * Let the T&L component know what is going on with display lists
+ * in time to make changes to dispatch tables, etc.
+ */
+ void (*NewList)( GLcontext *ctx, GLuint list, GLenum mode );
+ /**
+ * Called by glEndList().
+ *
+ * \sa dd_function_table::NewList.
+ */
+ void (*EndList)( GLcontext *ctx );
+
+ /**
+ * Called by glCallList(s).
+ *
+ * Notify the T&L component before and after calling a display list.
+ */
+ void (*BeginCallList)( GLcontext *ctx,
+ struct mesa_display_list *dlist );
+ /**
+ * Called by glEndCallList().
+ *
+ * \sa dd_function_table::BeginCallList.
+ */
+ void (*EndCallList)( GLcontext *ctx );
+
+};
+
+
+/**
+ * Transform/Clip/Lighting interface
+ *
+ * Drivers present a reduced set of the functions possible in
+ * glBegin()/glEnd() objects. Core mesa provides translation stubs for the
+ * remaining functions to map down to these entry points.
+ *
+ * These are the initial values to be installed into dispatch by
+ * mesa. If the T&L driver wants to modify the dispatch table
+ * while installed, it must do so itself. It would be possible for
+ * the vertexformat to install it's own initial values for these
+ * functions, but this way there is an obvious list of what is
+ * expected of the driver.
+ *
+ * If the driver wants to hook in entry points other than those
+ * listed, it must restore them to their original values in
+ * the disable() callback, below.
+ */
+typedef struct {
+ /**
+ * \name Vertex
+ */
+ /*@{*/
+ void (GLAPIENTRYP ArrayElement)( GLint ); /* NOTE */
+ void (GLAPIENTRYP Color3f)( GLfloat, GLfloat, GLfloat );
+ void (GLAPIENTRYP Color3fv)( const GLfloat * );
+ void (GLAPIENTRYP Color4f)( GLfloat, GLfloat, GLfloat, GLfloat );
+ void (GLAPIENTRYP Color4fv)( const GLfloat * );
+ void (GLAPIENTRYP EdgeFlag)( GLboolean );
+ void (GLAPIENTRYP EdgeFlagv)( const GLboolean * );
+ void (GLAPIENTRYP EvalCoord1f)( GLfloat ); /* NOTE */
+ void (GLAPIENTRYP EvalCoord1fv)( const GLfloat * ); /* NOTE */
+ void (GLAPIENTRYP EvalCoord2f)( GLfloat, GLfloat ); /* NOTE */
+ void (GLAPIENTRYP EvalCoord2fv)( const GLfloat * ); /* NOTE */
+ void (GLAPIENTRYP EvalPoint1)( GLint ); /* NOTE */
+ void (GLAPIENTRYP EvalPoint2)( GLint, GLint ); /* NOTE */
+ void (GLAPIENTRYP FogCoordfEXT)( GLfloat );
+ void (GLAPIENTRYP FogCoordfvEXT)( const GLfloat * );
+ void (GLAPIENTRYP Indexf)( GLfloat );
+ void (GLAPIENTRYP Indexfv)( const GLfloat * );
+ void (GLAPIENTRYP Materialfv)( GLenum face, GLenum pname, const GLfloat * ); /* NOTE */
+ void (GLAPIENTRYP MultiTexCoord1fARB)( GLenum, GLfloat );
+ void (GLAPIENTRYP MultiTexCoord1fvARB)( GLenum, const GLfloat * );
+ void (GLAPIENTRYP MultiTexCoord2fARB)( GLenum, GLfloat, GLfloat );
+ void (GLAPIENTRYP MultiTexCoord2fvARB)( GLenum, const GLfloat * );
+ void (GLAPIENTRYP MultiTexCoord3fARB)( GLenum, GLfloat, GLfloat, GLfloat );
+ void (GLAPIENTRYP MultiTexCoord3fvARB)( GLenum, const GLfloat * );
+ void (GLAPIENTRYP MultiTexCoord4fARB)( GLenum, GLfloat, GLfloat, GLfloat, GLfloat );
+ void (GLAPIENTRYP MultiTexCoord4fvARB)( GLenum, const GLfloat * );
+ void (GLAPIENTRYP Normal3f)( GLfloat, GLfloat, GLfloat );
+ void (GLAPIENTRYP Normal3fv)( const GLfloat * );
+ void (GLAPIENTRYP SecondaryColor3fEXT)( GLfloat, GLfloat, GLfloat );
+ void (GLAPIENTRYP SecondaryColor3fvEXT)( const GLfloat * );
+ void (GLAPIENTRYP TexCoord1f)( GLfloat );
+ void (GLAPIENTRYP TexCoord1fv)( const GLfloat * );
+ void (GLAPIENTRYP TexCoord2f)( GLfloat, GLfloat );
+ void (GLAPIENTRYP TexCoord2fv)( const GLfloat * );
+ void (GLAPIENTRYP TexCoord3f)( GLfloat, GLfloat, GLfloat );
+ void (GLAPIENTRYP TexCoord3fv)( const GLfloat * );
+ void (GLAPIENTRYP TexCoord4f)( GLfloat, GLfloat, GLfloat, GLfloat );
+ void (GLAPIENTRYP TexCoord4fv)( const GLfloat * );
+ void (GLAPIENTRYP Vertex2f)( GLfloat, GLfloat );
+ void (GLAPIENTRYP Vertex2fv)( const GLfloat * );
+ void (GLAPIENTRYP Vertex3f)( GLfloat, GLfloat, GLfloat );
+ void (GLAPIENTRYP Vertex3fv)( const GLfloat * );
+ void (GLAPIENTRYP Vertex4f)( GLfloat, GLfloat, GLfloat, GLfloat );
+ void (GLAPIENTRYP Vertex4fv)( const GLfloat * );
+ void (GLAPIENTRYP CallList)( GLuint ); /* NOTE */
+ void (GLAPIENTRYP CallLists)( GLsizei, GLenum, const GLvoid * ); /* NOTE */
+ void (GLAPIENTRYP Begin)( GLenum );
+ void (GLAPIENTRYP End)( void );
+ void (GLAPIENTRYP VertexAttrib1fNV)( GLuint index, GLfloat x );
+ void (GLAPIENTRYP VertexAttrib1fvNV)( GLuint index, const GLfloat *v );
+ void (GLAPIENTRYP VertexAttrib2fNV)( GLuint index, GLfloat x, GLfloat y );
+ void (GLAPIENTRYP VertexAttrib2fvNV)( GLuint index, const GLfloat *v );
+ void (GLAPIENTRYP VertexAttrib3fNV)( GLuint index, GLfloat x, GLfloat y, GLfloat z );
+ void (GLAPIENTRYP VertexAttrib3fvNV)( GLuint index, const GLfloat *v );
+ void (GLAPIENTRYP VertexAttrib4fNV)( GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w );
+ void (GLAPIENTRYP VertexAttrib4fvNV)( GLuint index, const GLfloat *v );
+ void (GLAPIENTRYP VertexAttrib1fARB)( GLuint index, GLfloat x );
+ void (GLAPIENTRYP VertexAttrib1fvARB)( GLuint index, const GLfloat *v );
+ void (GLAPIENTRYP VertexAttrib2fARB)( GLuint index, GLfloat x, GLfloat y );
+ void (GLAPIENTRYP VertexAttrib2fvARB)( GLuint index, const GLfloat *v );
+ void (GLAPIENTRYP VertexAttrib3fARB)( GLuint index, GLfloat x, GLfloat y, GLfloat z );
+ void (GLAPIENTRYP VertexAttrib3fvARB)( GLuint index, const GLfloat *v );
+ void (GLAPIENTRYP VertexAttrib4fARB)( GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w );
+ void (GLAPIENTRYP VertexAttrib4fvARB)( GLuint index, const GLfloat *v );
+ /*@}*/
+
+ /*
+ */
+ void (GLAPIENTRYP Rectf)( GLfloat, GLfloat, GLfloat, GLfloat );
+
+ /**
+ * \name Array
+ */
+ /*@{*/
+ void (GLAPIENTRYP DrawArrays)( GLenum mode, GLint start, GLsizei count );
+ void (GLAPIENTRYP DrawElements)( GLenum mode, GLsizei count, GLenum type,
+ const GLvoid *indices );
+ void (GLAPIENTRYP DrawRangeElements)( GLenum mode, GLuint start,
+ GLuint end, GLsizei count,
+ GLenum type, const GLvoid *indices );
+ /*@}*/
+
+ /**
+ * \name Eval
+ *
+ * If you don't support eval, fallback to the default vertex format
+ * on receiving an eval call and use the pipeline mechanism to
+ * provide partial T&L acceleration.
+ *
+ * Mesa will provide a set of helper functions to do eval within
+ * accelerated vertex formats, eventually...
+ */
+ /*@{*/
+ void (GLAPIENTRYP EvalMesh1)( GLenum mode, GLint i1, GLint i2 );
+ void (GLAPIENTRYP EvalMesh2)( GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 );
+ /*@}*/
+
+} GLvertexformat;
+
+
+#endif /* DD_INCLUDED */
diff --git a/src/mesa/main/debug.c b/src/mesa/main/debug.c
new file mode 100644
index 00000000000..98ca65b96a9
--- /dev/null
+++ b/src/mesa/main/debug.c
@@ -0,0 +1,227 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "mtypes.h"
+#include "context.h"
+#include "imports.h"
+#include "debug.h"
+#include "get.h"
+
+/**
+ * Primitive names
+ */
+const char *_mesa_prim_name[GL_POLYGON+4] = {
+ "GL_POINTS",
+ "GL_LINES",
+ "GL_LINE_LOOP",
+ "GL_LINE_STRIP",
+ "GL_TRIANGLES",
+ "GL_TRIANGLE_STRIP",
+ "GL_TRIANGLE_FAN",
+ "GL_QUADS",
+ "GL_QUAD_STRIP",
+ "GL_POLYGON",
+ "outside begin/end",
+ "inside unkown primitive",
+ "unknown state"
+};
+
+void
+_mesa_print_state( const char *msg, GLuint state )
+{
+ _mesa_debug(NULL,
+ "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
+ msg,
+ state,
+ (state & _NEW_MODELVIEW) ? "ctx->ModelView, " : "",
+ (state & _NEW_PROJECTION) ? "ctx->Projection, " : "",
+ (state & _NEW_TEXTURE_MATRIX) ? "ctx->TextureMatrix, " : "",
+ (state & _NEW_COLOR_MATRIX) ? "ctx->ColorMatrix, " : "",
+ (state & _NEW_ACCUM) ? "ctx->Accum, " : "",
+ (state & _NEW_COLOR) ? "ctx->Color, " : "",
+ (state & _NEW_DEPTH) ? "ctx->Depth, " : "",
+ (state & _NEW_EVAL) ? "ctx->Eval/EvalMap, " : "",
+ (state & _NEW_FOG) ? "ctx->Fog, " : "",
+ (state & _NEW_HINT) ? "ctx->Hint, " : "",
+ (state & _NEW_LIGHT) ? "ctx->Light, " : "",
+ (state & _NEW_LINE) ? "ctx->Line, " : "",
+ (state & _NEW_PIXEL) ? "ctx->Pixel, " : "",
+ (state & _NEW_POINT) ? "ctx->Point, " : "",
+ (state & _NEW_POLYGON) ? "ctx->Polygon, " : "",
+ (state & _NEW_POLYGONSTIPPLE) ? "ctx->PolygonStipple, " : "",
+ (state & _NEW_SCISSOR) ? "ctx->Scissor, " : "",
+ (state & _NEW_TEXTURE) ? "ctx->Texture, " : "",
+ (state & _NEW_TRANSFORM) ? "ctx->Transform, " : "",
+ (state & _NEW_VIEWPORT) ? "ctx->Viewport, " : "",
+ (state & _NEW_PACKUNPACK) ? "ctx->Pack/Unpack, " : "",
+ (state & _NEW_ARRAY) ? "ctx->Array, " : "",
+ (state & _NEW_RENDERMODE) ? "ctx->RenderMode, " : "",
+ (state & _NEW_BUFFERS) ? "ctx->Visual, ctx->DrawBuffer,, " : "");
+}
+
+
+
+void
+_mesa_print_tri_caps( const char *name, GLuint flags )
+{
+ _mesa_debug(NULL,
+ "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
+ name,
+ flags,
+ (flags & DD_FLATSHADE) ? "flat-shade, " : "",
+ (flags & DD_SEPARATE_SPECULAR) ? "separate-specular, " : "",
+ (flags & DD_TRI_LIGHT_TWOSIDE) ? "tri-light-twoside, " : "",
+ (flags & DD_TRI_TWOSTENCIL) ? "tri-twostencil, " : "",
+ (flags & DD_TRI_UNFILLED) ? "tri-unfilled, " : "",
+ (flags & DD_TRI_STIPPLE) ? "tri-stipple, " : "",
+ (flags & DD_TRI_OFFSET) ? "tri-offset, " : "",
+ (flags & DD_TRI_SMOOTH) ? "tri-smooth, " : "",
+ (flags & DD_LINE_SMOOTH) ? "line-smooth, " : "",
+ (flags & DD_LINE_STIPPLE) ? "line-stipple, " : "",
+ (flags & DD_LINE_WIDTH) ? "line-wide, " : "",
+ (flags & DD_POINT_SMOOTH) ? "point-smooth, " : "",
+ (flags & DD_POINT_SIZE) ? "point-size, " : "",
+ (flags & DD_POINT_ATTEN) ? "point-atten, " : "",
+ (flags & DD_TRI_CULL_FRONT_BACK) ? "cull-all, " : ""
+ );
+}
+
+
+/**
+ * Print information about this Mesa version and build options.
+ */
+void _mesa_print_info( void )
+{
+ _mesa_debug(NULL, "Mesa GL_VERSION = %s\n",
+ (char *) _mesa_GetString(GL_VERSION));
+ _mesa_debug(NULL, "Mesa GL_RENDERER = %s\n",
+ (char *) _mesa_GetString(GL_RENDERER));
+ _mesa_debug(NULL, "Mesa GL_VENDOR = %s\n",
+ (char *) _mesa_GetString(GL_VENDOR));
+ _mesa_debug(NULL, "Mesa GL_EXTENSIONS = %s\n",
+ (char *) _mesa_GetString(GL_EXTENSIONS));
+#if defined(THREADS)
+ _mesa_debug(NULL, "Mesa thread-safe: YES\n");
+#else
+ _mesa_debug(NULL, "Mesa thread-safe: NO\n");
+#endif
+#if defined(USE_X86_ASM)
+ _mesa_debug(NULL, "Mesa x86-optimized: YES\n");
+#else
+ _mesa_debug(NULL, "Mesa x86-optimized: NO\n");
+#endif
+#if defined(USE_SPARC_ASM)
+ _mesa_debug(NULL, "Mesa sparc-optimized: YES\n");
+#else
+ _mesa_debug(NULL, "Mesa sparc-optimized: NO\n");
+#endif
+}
+
+
+/**
+ * Set the debugging flags.
+ *
+ * \param debug debug string
+ *
+ * If compiled with debugging support then search for keywords in \p debug and
+ * enables the verbose debug output of the respective feature.
+ */
+static void add_debug_flags( const char *debug )
+{
+#ifdef DEBUG
+ if (_mesa_strstr(debug, "varray"))
+ MESA_VERBOSE |= VERBOSE_VARRAY;
+
+ if (_mesa_strstr(debug, "tex"))
+ MESA_VERBOSE |= VERBOSE_TEXTURE;
+
+ if (_mesa_strstr(debug, "imm"))
+ MESA_VERBOSE |= VERBOSE_IMMEDIATE;
+
+ if (_mesa_strstr(debug, "pipe"))
+ MESA_VERBOSE |= VERBOSE_PIPELINE;
+
+ if (_mesa_strstr(debug, "driver"))
+ MESA_VERBOSE |= VERBOSE_DRIVER;
+
+ if (_mesa_strstr(debug, "state"))
+ MESA_VERBOSE |= VERBOSE_STATE;
+
+ if (_mesa_strstr(debug, "api"))
+ MESA_VERBOSE |= VERBOSE_API;
+
+ if (_mesa_strstr(debug, "list"))
+ MESA_VERBOSE |= VERBOSE_DISPLAY_LIST;
+
+ if (_mesa_strstr(debug, "lighting"))
+ MESA_VERBOSE |= VERBOSE_LIGHTING;
+
+ if (_mesa_strstr(debug, "disassem"))
+ MESA_VERBOSE |= VERBOSE_DISASSEM;
+
+ /* Debug flag:
+ */
+ if (_mesa_strstr(debug, "flush"))
+ MESA_DEBUG_FLAGS |= DEBUG_ALWAYS_FLUSH;
+
+#if defined(_FPU_GETCW) && defined(_FPU_SETCW)
+ if (_mesa_strstr(debug, "fpexceptions")) {
+ /* raise FP exceptions */
+ fpu_control_t mask;
+ _FPU_GETCW(mask);
+ mask &= ~(_FPU_MASK_IM | _FPU_MASK_DM | _FPU_MASK_ZM
+ | _FPU_MASK_OM | _FPU_MASK_UM);
+ _FPU_SETCW(mask);
+ }
+#endif
+
+#else
+ (void) debug;
+#endif
+}
+
+
+void
+_mesa_init_debug( GLcontext *ctx )
+{
+ char *c;
+
+ /* Dither disable */
+ ctx->NoDither = _mesa_getenv("MESA_NO_DITHER") ? GL_TRUE : GL_FALSE;
+ if (ctx->NoDither) {
+ if (_mesa_getenv("MESA_DEBUG")) {
+ _mesa_debug(ctx, "MESA_NO_DITHER set - dithering disabled\n");
+ }
+ ctx->Color.DitherFlag = GL_FALSE;
+ }
+
+ c = _mesa_getenv("MESA_DEBUG");
+ if (c)
+ add_debug_flags(c);
+
+ c = _mesa_getenv("MESA_VERBOSE");
+ if (c)
+ add_debug_flags(c);
+}
+
diff --git a/src/mesa/main/debug.h b/src/mesa/main/debug.h
new file mode 100644
index 00000000000..94d99c384bd
--- /dev/null
+++ b/src/mesa/main/debug.h
@@ -0,0 +1,60 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.1
+ *
+ * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file debug.h
+ * Debugging functions.
+ *
+ * \if subset
+ * (No-op)
+ *
+ * \endif
+ */
+
+
+#ifndef _DEBUG_H
+#define _DEBUG_H
+
+#if _HAVE_FULL_GL
+
+extern void _mesa_print_tri_caps( const char *name, GLuint flags );
+extern void _mesa_print_enable_flags( const char *msg, GLuint flags );
+extern void _mesa_print_state( const char *msg, GLuint state );
+extern void _mesa_print_info( void );
+extern void _mesa_init_debug( GLcontext *ctx );
+
+#else
+
+/** No-op */
+#define _mesa_print_state( m, s ) ((void)0)
+
+/** No-op */
+#define _mesa_print_info() ((void)0)
+
+/** No-op */
+#define _mesa_init_debug( c ) ((void)0)
+
+#endif
+
+#endif
diff --git a/src/mesa/main/depth.c b/src/mesa/main/depth.c
new file mode 100644
index 00000000000..f5511ce2fbf
--- /dev/null
+++ b/src/mesa/main/depth.c
@@ -0,0 +1,188 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include "glheader.h"
+#include "imports.h"
+#include "context.h"
+#include "depth.h"
+#include "enums.h"
+#include "hash.h"
+#include "macros.h"
+#include "mtypes.h"
+
+
+/**********************************************************************/
+/***** API Functions *****/
+/**********************************************************************/
+
+
+
+void GLAPIENTRY
+_mesa_ClearDepth( GLclampd depth )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ depth = CLAMP( depth, 0.0, 1.0 );
+
+ if (ctx->Depth.Clear == depth)
+ return;
+
+ FLUSH_VERTICES(ctx, _NEW_DEPTH);
+ ctx->Depth.Clear = depth;
+ if (ctx->Driver.ClearDepth)
+ (*ctx->Driver.ClearDepth)( ctx, ctx->Depth.Clear );
+}
+
+
+
+void GLAPIENTRY
+_mesa_DepthFunc( GLenum func )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glDepthFunc %s\n", _mesa_lookup_enum_by_nr(func));
+
+ switch (func) {
+ case GL_LESS: /* (default) pass if incoming z < stored z */
+ case GL_GEQUAL:
+ case GL_LEQUAL:
+ case GL_GREATER:
+ case GL_NOTEQUAL:
+ case GL_EQUAL:
+ case GL_ALWAYS:
+ case GL_NEVER:
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glDepth.Func" );
+ return;
+ }
+
+ if (ctx->Depth.Func == func)
+ return;
+
+ FLUSH_VERTICES(ctx, _NEW_DEPTH);
+ ctx->Depth.Func = func;
+
+ if (ctx->Driver.DepthFunc)
+ ctx->Driver.DepthFunc( ctx, func );
+}
+
+
+
+void GLAPIENTRY
+_mesa_DepthMask( GLboolean flag )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glDepthMask %d\n", flag);
+
+ /*
+ * GL_TRUE indicates depth buffer writing is enabled (default)
+ * GL_FALSE indicates depth buffer writing is disabled
+ */
+ if (ctx->Depth.Mask == flag)
+ return;
+
+ FLUSH_VERTICES(ctx, _NEW_DEPTH);
+ ctx->Depth.Mask = flag;
+
+ if (ctx->Driver.DepthMask)
+ ctx->Driver.DepthMask( ctx, flag );
+}
+
+
+
+/**
+ * Specified by the GL_EXT_depth_bounds_test extension.
+ */
+void GLAPIENTRY
+_mesa_DepthBoundsEXT( GLclampd zmin, GLclampd zmax )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (zmin > zmax) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glDepthBoundsEXT(zmin > zmax)");
+ return;
+ }
+
+ zmin = CLAMP(zmin, 0.0, 1.0);
+ zmax = CLAMP(zmax, 0.0, 1.0);
+
+ if (ctx->Depth.BoundsMin == zmin && ctx->Depth.BoundsMax == zmax)
+ return;
+
+ FLUSH_VERTICES(ctx, _NEW_DEPTH);
+ ctx->Depth.BoundsMin = (GLfloat) zmin;
+ ctx->Depth.BoundsMax = (GLfloat) zmax;
+}
+
+
+/**********************************************************************/
+/***** Initialization *****/
+/**********************************************************************/
+
+
+/**
+ * Initialize the depth buffer attribute group in the given context.
+ */
+void _mesa_init_depth( GLcontext * ctx )
+{
+ /* Depth buffer group */
+ ctx->Depth.Test = GL_FALSE;
+ ctx->Depth.Clear = 1.0;
+ ctx->Depth.Func = GL_LESS;
+ ctx->Depth.Mask = GL_TRUE;
+
+ /* XXX this is now per-framebuffer state */
+#if 00
+ /* Z buffer stuff */
+ if (ctx->Visual.depthBits == 0) {
+ /* Special case. Even if we don't have a depth buffer we need
+ * good values for DepthMax for Z vertex transformation purposes
+ * and for per-fragment fog computation.
+ */
+ ctx->DepthMax = (1 << 16) - 1;
+ ctx->DepthMaxF = (GLfloat) ctx->DepthMax;
+ }
+ else if (ctx->Visual.depthBits < 32) {
+ ctx->DepthMax = (1 << ctx->Visual.depthBits) - 1;
+ ctx->DepthMaxF = (GLfloat) ctx->DepthMax;
+ }
+ else {
+ /* Special case since shift values greater than or equal to the
+ * number of bits in the left hand expression's type are undefined.
+ */
+ ctx->DepthMax = 0xffffffff;
+ ctx->DepthMaxF = (GLfloat) ctx->DepthMax;
+ }
+ ctx->MRD = 1.0; /* Minimum resolvable depth value, for polygon offset */
+#endif
+}
diff --git a/src/mesa/main/depth.h b/src/mesa/main/depth.h
new file mode 100644
index 00000000000..dcc0b4637a7
--- /dev/null
+++ b/src/mesa/main/depth.h
@@ -0,0 +1,62 @@
+/**
+ * \file depth.h
+ * Depth buffer operations.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.3
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef DEPTH_H
+#define DEPTH_H
+
+
+#include "mtypes.h"
+
+
+#if _HAVE_FULL_GL
+
+extern void GLAPIENTRY
+_mesa_ClearDepth( GLclampd depth );
+
+extern void GLAPIENTRY
+_mesa_DepthFunc( GLenum func );
+
+extern void GLAPIENTRY
+_mesa_DepthMask( GLboolean flag );
+
+extern void GLAPIENTRY
+_mesa_DepthBoundsEXT( GLclampd zmin, GLclampd zmax );
+
+extern void
+_mesa_init_depth( GLcontext * ctx );
+
+#else
+
+/** No-op */
+#define _mesa_init_depth( c ) ((void)0)
+
+#endif
+
+#endif
diff --git a/src/mesa/main/depthstencil.c b/src/mesa/main/depthstencil.c
new file mode 100644
index 00000000000..09524bba02e
--- /dev/null
+++ b/src/mesa/main/depthstencil.c
@@ -0,0 +1,655 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "glheader.h"
+#include "imports.h"
+#include "context.h"
+#include "fbobject.h"
+#include "mtypes.h"
+#include "depthstencil.h"
+#include "renderbuffer.h"
+
+
+/**
+ * Adaptor/wrappers for GL_DEPTH_STENCIL renderbuffers.
+ *
+ * The problem with a GL_DEPTH_STENCIL renderbuffer is that sometimes we
+ * want to treat it as a stencil buffer, other times we want to treat it
+ * as a depth/z buffer and still other times when we want to treat it as
+ * a combined Z+stencil buffer! That implies we need three different sets
+ * of Get/Put functions.
+ *
+ * We solve this by wrapping the Z24_S8 renderbuffer with depth and stencil
+ * adaptors, each with the right kind of depth/stencil Get/Put functions.
+ */
+
+
+static void *
+nop_get_pointer(GLcontext *ctx, struct gl_renderbuffer *rb, GLint x, GLint y)
+{
+ return NULL;
+}
+
+
+/**
+ * Delete a depth or stencil wrapper renderbuffer.
+ */
+static void
+delete_wrapper(struct gl_renderbuffer *rb)
+{
+ struct gl_renderbuffer *dsrb = rb->Wrapped;
+ ASSERT(dsrb);
+ ASSERT(rb->_ActualFormat == GL_DEPTH_COMPONENT24 ||
+ rb->_ActualFormat == GL_STENCIL_INDEX8_EXT);
+ /* decrement refcount on the wrapped buffer and delete it if necessary */
+ dsrb->RefCount--;
+ if (dsrb->RefCount <= 0) {
+ dsrb->Delete(dsrb);
+ }
+ _mesa_free(rb);
+}
+
+
+/**
+ * Realloc storage for wrapper.
+ */
+static GLboolean
+alloc_wrapper_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
+ GLenum internalFormat, GLuint width, GLuint height)
+{
+ /* just pass this on to the wrapped renderbuffer */
+ struct gl_renderbuffer *dsrb = rb->Wrapped;
+ GLboolean retVal;
+
+ ASSERT(dsrb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT);
+
+ retVal = dsrb->AllocStorage(ctx, dsrb, dsrb->InternalFormat, width, height);
+ if (retVal) {
+ rb->Width = width;
+ rb->Height = height;
+ }
+ return retVal;
+}
+
+
+
+
+/*======================================================================
+ * Depth wrapper around depth/stencil renderbuffer
+ */
+
+static void
+get_row_z24(GLcontext *ctx, struct gl_renderbuffer *z24rb, GLuint count,
+ GLint x, GLint y, void *values)
+{
+ struct gl_renderbuffer *dsrb = z24rb->Wrapped;
+ GLuint temp[MAX_WIDTH], i;
+ GLuint *dst = (GLuint *) values;
+ const GLuint *src = (const GLuint *) dsrb->GetPointer(ctx, dsrb, x, y);
+ ASSERT(z24rb->DataType == GL_UNSIGNED_INT);
+ ASSERT(dsrb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT);
+ ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
+ if (!src) {
+ dsrb->GetRow(ctx, dsrb, count, x, y, temp);
+ src = temp;
+ }
+ for (i = 0; i < count; i++) {
+ dst[i] = src[i] >> 8;
+ }
+}
+
+static void
+get_values_z24(GLcontext *ctx, struct gl_renderbuffer *z24rb, GLuint count,
+ const GLint x[], const GLint y[], void *values)
+{
+ struct gl_renderbuffer *dsrb = z24rb->Wrapped;
+ GLuint temp[MAX_WIDTH], i;
+ GLuint *dst = (GLuint *) values;
+ ASSERT(z24rb->DataType == GL_UNSIGNED_INT);
+ ASSERT(dsrb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT);
+ ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
+ ASSERT(count <= MAX_WIDTH);
+ /* don't bother trying direct access */
+ dsrb->GetValues(ctx, dsrb, count, x, y, temp);
+ for (i = 0; i < count; i++) {
+ dst[i] = temp[i] >> 8;
+ }
+}
+
+static void
+put_row_z24(GLcontext *ctx, struct gl_renderbuffer *z24rb, GLuint count,
+ GLint x, GLint y, const void *values, const GLubyte *mask)
+{
+ struct gl_renderbuffer *dsrb = z24rb->Wrapped;
+ const GLuint *src = (const GLuint *) values;
+ GLuint *dst = (GLuint *) dsrb->GetPointer(ctx, dsrb, x, y);
+ ASSERT(z24rb->DataType == GL_UNSIGNED_INT);
+ ASSERT(dsrb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT);
+ ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
+ if (dst) {
+ /* direct access */
+ GLuint i;
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ dst[i] = (src[i] << 8) | (dst[i] & 0xff);
+ }
+ }
+ }
+ else {
+ /* get, modify, put */
+ GLuint temp[MAX_WIDTH], i;
+ dsrb->GetRow(ctx, dsrb, count, x, y, temp);
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ temp[i] = (src[i] << 8) | (temp[i] & 0xff);
+ }
+ }
+ dsrb->PutRow(ctx, dsrb, count, x, y, temp, mask);
+ }
+}
+
+static void
+put_mono_row_z24(GLcontext *ctx, struct gl_renderbuffer *z24rb, GLuint count,
+ GLint x, GLint y, const void *value, const GLubyte *mask)
+{
+ struct gl_renderbuffer *dsrb = z24rb->Wrapped;
+ const GLuint shiftedVal = *((GLuint *) value) << 8;
+ GLuint *dst = (GLuint *) dsrb->GetPointer(ctx, dsrb, x, y);
+ ASSERT(z24rb->DataType == GL_UNSIGNED_INT);
+ ASSERT(dsrb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT);
+ ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
+ if (dst) {
+ /* direct access */
+ GLuint i;
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ dst[i] = shiftedVal | (dst[i] & 0xff);
+ }
+ }
+ }
+ else {
+ /* get, modify, put */
+ GLuint temp[MAX_WIDTH], i;
+ dsrb->GetRow(ctx, dsrb, count, x, y, temp);
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ temp[i] = shiftedVal | (temp[i] & 0xff);
+ }
+ }
+ dsrb->PutRow(ctx, dsrb, count, x, y, temp, mask);
+ }
+}
+
+static void
+put_values_z24(GLcontext *ctx, struct gl_renderbuffer *z24rb, GLuint count,
+ const GLint x[], const GLint y[],
+ const void *values, const GLubyte *mask)
+{
+ struct gl_renderbuffer *dsrb = z24rb->Wrapped;
+ const GLubyte *src = (const GLubyte *) values;
+ ASSERT(z24rb->DataType == GL_UNSIGNED_INT);
+ ASSERT(dsrb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT);
+ ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
+ if (dsrb->GetPointer(ctx, dsrb, 0, 0)) {
+ /* direct access */
+ GLuint i;
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ GLuint *dst = (GLuint *) dsrb->GetPointer(ctx, dsrb, x[i], y[i]);
+ *dst = (src[i] << 8) | (*dst & 0xff);
+ }
+ }
+ }
+ else {
+ /* get, modify, put */
+ GLuint temp[MAX_WIDTH], i;
+ dsrb->GetValues(ctx, dsrb, count, x, y, temp);
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ temp[i] = (src[i] << 8) | (temp[i] & 0xff);
+ }
+ }
+ dsrb->PutValues(ctx, dsrb, count, x, y, temp, mask);
+ }
+}
+
+static void
+put_mono_values_z24(GLcontext *ctx, struct gl_renderbuffer *z24rb,
+ GLuint count, const GLint x[], const GLint y[],
+ const void *value, const GLubyte *mask)
+{
+ struct gl_renderbuffer *dsrb = z24rb->Wrapped;
+ GLuint temp[MAX_WIDTH], i;
+ const GLuint shiftedVal = *((GLuint *) value) << 8;
+ /* get, modify, put */
+ dsrb->GetValues(ctx, dsrb, count, x, y, temp);
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ temp[i] = shiftedVal | (temp[i] & 0xff);
+ }
+ }
+ dsrb->PutValues(ctx, dsrb, count, x, y, temp, mask);
+}
+
+
+/**
+ * Wrap the given GL_DEPTH_STENCIL renderbuffer so that it acts like
+ * a depth renderbuffer.
+ * \return new depth renderbuffer
+ */
+struct gl_renderbuffer *
+_mesa_new_z24_renderbuffer_wrapper(GLcontext *ctx,
+ struct gl_renderbuffer *dsrb)
+{
+ struct gl_renderbuffer *z24rb;
+
+ ASSERT(dsrb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT);
+ ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
+
+ z24rb = _mesa_new_renderbuffer(ctx, 0);
+ if (!z24rb)
+ return NULL;
+
+ z24rb->Wrapped = dsrb;
+ z24rb->Name = dsrb->Name;
+ z24rb->RefCount = 1;
+ z24rb->Width = dsrb->Width;
+ z24rb->Height = dsrb->Height;
+ z24rb->InternalFormat = GL_DEPTH_COMPONENT24_ARB;
+ z24rb->_ActualFormat = GL_DEPTH_COMPONENT24_ARB;
+ z24rb->_BaseFormat = GL_DEPTH_COMPONENT;
+ z24rb->DataType = GL_UNSIGNED_INT;
+ z24rb->DepthBits = 24;
+ z24rb->Data = NULL;
+ z24rb->Delete = delete_wrapper;
+ z24rb->AllocStorage = alloc_wrapper_storage;
+ z24rb->GetPointer = nop_get_pointer;
+ z24rb->GetRow = get_row_z24;
+ z24rb->GetValues = get_values_z24;
+ z24rb->PutRow = put_row_z24;
+ z24rb->PutRowRGB = NULL;
+ z24rb->PutMonoRow = put_mono_row_z24;
+ z24rb->PutValues = put_values_z24;
+ z24rb->PutMonoValues = put_mono_values_z24;
+
+ return z24rb;
+}
+
+
+/*======================================================================
+ * Stencil wrapper around depth/stencil renderbuffer
+ */
+
+static void
+get_row_s8(GLcontext *ctx, struct gl_renderbuffer *s8rb, GLuint count,
+ GLint x, GLint y, void *values)
+{
+ struct gl_renderbuffer *dsrb = s8rb->Wrapped;
+ GLuint temp[MAX_WIDTH], i;
+ GLubyte *dst = (GLubyte *) values;
+ const GLuint *src = (const GLuint *) dsrb->GetPointer(ctx, dsrb, x, y);
+ ASSERT(s8rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(dsrb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT);
+ ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
+ if (!src) {
+ dsrb->GetRow(ctx, dsrb, count, x, y, temp);
+ src = temp;
+ }
+ for (i = 0; i < count; i++) {
+ dst[i] = src[i] & 0xff;
+ }
+}
+
+static void
+get_values_s8(GLcontext *ctx, struct gl_renderbuffer *s8rb, GLuint count,
+ const GLint x[], const GLint y[], void *values)
+{
+ struct gl_renderbuffer *dsrb = s8rb->Wrapped;
+ GLuint temp[MAX_WIDTH], i;
+ GLubyte *dst = (GLubyte *) values;
+ ASSERT(s8rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(dsrb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT);
+ ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
+ ASSERT(count <= MAX_WIDTH);
+ /* don't bother trying direct access */
+ dsrb->GetValues(ctx, dsrb, count, x, y, temp);
+ for (i = 0; i < count; i++) {
+ dst[i] = temp[i] & 0xff;
+ }
+}
+
+static void
+put_row_s8(GLcontext *ctx, struct gl_renderbuffer *s8rb, GLuint count,
+ GLint x, GLint y, const void *values, const GLubyte *mask)
+{
+ struct gl_renderbuffer *dsrb = s8rb->Wrapped;
+ const GLubyte *src = (const GLubyte *) values;
+ GLuint *dst = (GLuint *) dsrb->GetPointer(ctx, dsrb, x, y);
+ ASSERT(s8rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(dsrb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT);
+ ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
+ if (dst) {
+ /* direct access */
+ GLuint i;
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ dst[i] = (dst[i] & 0xffffff00) | src[i];
+ }
+ }
+ }
+ else {
+ /* get, modify, put */
+ GLuint temp[MAX_WIDTH], i;
+ dsrb->GetRow(ctx, dsrb, count, x, y, temp);
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ temp[i] = (temp[i] & 0xffffff00) | src[i];
+ }
+ }
+ dsrb->PutRow(ctx, dsrb, count, x, y, temp, mask);
+ }
+}
+
+static void
+put_mono_row_s8(GLcontext *ctx, struct gl_renderbuffer *s8rb, GLuint count,
+ GLint x, GLint y, const void *value, const GLubyte *mask)
+{
+ struct gl_renderbuffer *dsrb = s8rb->Wrapped;
+ const GLubyte val = *((GLubyte *) value);
+ GLuint *dst = (GLuint *) dsrb->GetPointer(ctx, dsrb, x, y);
+ ASSERT(s8rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(dsrb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT);
+ ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
+ if (dst) {
+ /* direct access */
+ GLuint i;
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ dst[i] = (dst[i] & 0xffffff00) | val;
+ }
+ }
+ }
+ else {
+ /* get, modify, put */
+ GLuint temp[MAX_WIDTH], i;
+ dsrb->GetRow(ctx, dsrb, count, x, y, temp);
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ temp[i] = (temp[i] & 0xffffff00) | val;
+ }
+ }
+ dsrb->PutRow(ctx, dsrb, count, x, y, temp, mask);
+ }
+}
+
+static void
+put_values_s8(GLcontext *ctx, struct gl_renderbuffer *s8rb, GLuint count,
+ const GLint x[], const GLint y[],
+ const void *values, const GLubyte *mask)
+{
+ struct gl_renderbuffer *dsrb = s8rb->Wrapped;
+ const GLubyte *src = (const GLubyte *) values;
+ ASSERT(s8rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(dsrb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT);
+ ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
+ if (dsrb->GetPointer(ctx, dsrb, 0, 0)) {
+ /* direct access */
+ GLuint i;
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ GLuint *dst = (GLuint *) dsrb->GetPointer(ctx, dsrb, x[i], y[i]);
+ *dst = (*dst & 0xffffff00) | src[i];
+ }
+ }
+ }
+ else {
+ /* get, modify, put */
+ GLuint temp[MAX_WIDTH], i;
+ dsrb->GetValues(ctx, dsrb, count, x, y, temp);
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ temp[i] = (temp[i] & 0xffffff00) | src[i];
+ }
+ }
+ dsrb->PutValues(ctx, dsrb, count, x, y, temp, mask);
+ }
+}
+
+static void
+put_mono_values_s8(GLcontext *ctx, struct gl_renderbuffer *s8rb, GLuint count,
+ const GLint x[], const GLint y[],
+ const void *value, const GLubyte *mask)
+{
+ struct gl_renderbuffer *dsrb = s8rb->Wrapped;
+ GLuint temp[MAX_WIDTH], i;
+ const GLubyte val = *((GLubyte *) value);
+ /* get, modify, put */
+ dsrb->GetValues(ctx, dsrb, count, x, y, temp);
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ temp[i] = (temp[i] & 0xffffff) | val;
+ }
+ }
+ dsrb->PutValues(ctx, dsrb, count, x, y, temp, mask);
+}
+
+
+/**
+ * Wrap the given GL_DEPTH_STENCIL renderbuffer so that it acts like
+ * a stencil renderbuffer.
+ * \return new stencil renderbuffer
+ */
+struct gl_renderbuffer *
+_mesa_new_s8_renderbuffer_wrapper(GLcontext *ctx, struct gl_renderbuffer *dsrb)
+{
+ struct gl_renderbuffer *s8rb;
+
+ ASSERT(dsrb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT);
+ ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
+
+ s8rb = _mesa_new_renderbuffer(ctx, 0);
+ if (!s8rb)
+ return NULL;
+
+ s8rb->Wrapped = dsrb;
+ s8rb->Name = dsrb->Name;
+ s8rb->RefCount = 1;
+ s8rb->Width = dsrb->Width;
+ s8rb->Height = dsrb->Height;
+ s8rb->InternalFormat = GL_STENCIL_INDEX8_EXT;
+ s8rb->_ActualFormat = GL_STENCIL_INDEX8_EXT;
+ s8rb->_BaseFormat = GL_STENCIL_INDEX;
+ s8rb->DataType = GL_UNSIGNED_BYTE;
+ s8rb->StencilBits = 8;
+ s8rb->Data = NULL;
+ s8rb->Delete = delete_wrapper;
+ s8rb->AllocStorage = alloc_wrapper_storage;
+ s8rb->GetPointer = nop_get_pointer;
+ s8rb->GetRow = get_row_s8;
+ s8rb->GetValues = get_values_s8;
+ s8rb->PutRow = put_row_s8;
+ s8rb->PutRowRGB = NULL;
+ s8rb->PutMonoRow = put_mono_row_s8;
+ s8rb->PutValues = put_values_s8;
+ s8rb->PutMonoValues = put_mono_values_s8;
+
+ return s8rb;
+}
+
+
+
+/**
+ ** The following functions are useful for hardware drivers that only
+ ** implement combined depth/stencil buffers.
+ ** The GL_EXT_framebuffer_object extension allows indepedent depth and
+ ** stencil buffers to be used in any combination.
+ ** Therefore, we sometimes have to merge separate depth and stencil
+ ** renderbuffers into a single depth+stencil renderbuffer. And sometimes
+ ** we have to split combined depth+stencil renderbuffers into separate
+ ** renderbuffers.
+ **/
+
+
+/**
+ * Extract stencil values from the combined depth/stencil renderbuffer, storing
+ * the values into a separate stencil renderbuffer.
+ * \param dsRb the source depth/stencil renderbuffer
+ * \param stencilRb the destination stencil renderbuffer
+ * (either 8-bit or 32-bit)
+ */
+void
+_mesa_extract_stencil(GLcontext *ctx,
+ struct gl_renderbuffer *dsRb,
+ struct gl_renderbuffer *stencilRb)
+{
+ GLuint row, width, height;
+
+ ASSERT(dsRb);
+ ASSERT(stencilRb);
+
+ ASSERT(dsRb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT);
+ ASSERT(dsRb->DataType == GL_UNSIGNED_INT_24_8_EXT);
+ ASSERT(stencilRb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT ||
+ stencilRb->_ActualFormat == GL_STENCIL_INDEX8_EXT);
+ ASSERT(dsRb->Width == stencilRb->Width);
+ ASSERT(dsRb->Height == stencilRb->Height);
+
+ width = dsRb->Width;
+ height = dsRb->Height;
+
+ for (row = 0; row < height; row++) {
+ GLuint depthStencil[MAX_WIDTH];
+ dsRb->GetRow(ctx, dsRb, width, 0, row, depthStencil);
+ if (stencilRb->_ActualFormat == GL_STENCIL_INDEX8_EXT) {
+ /* 8bpp stencil */
+ GLubyte stencil[MAX_WIDTH];
+ GLuint i;
+ for (i = 0; i < width; i++) {
+ stencil[i] = depthStencil[i] & 0xff;
+ }
+ stencilRb->PutRow(ctx, stencilRb, width, 0, row, stencil, NULL);
+ }
+ else {
+ /* 32bpp stencil */
+ /* the 24 depth bits will be ignored */
+ ASSERT(stencilRb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT);
+ ASSERT(stencilRb->DataType == GL_UNSIGNED_INT_24_8_EXT);
+ stencilRb->PutRow(ctx, stencilRb, width, 0, row, depthStencil, NULL);
+ }
+ }
+}
+
+
+/**
+ * Copy stencil values from a stencil renderbuffer into a combined
+ * depth/stencil renderbuffer.
+ * \param dsRb the destination depth/stencil renderbuffer
+ * \param stencilRb the source stencil buffer (either 8-bit or 32-bit)
+ */
+void
+_mesa_insert_stencil(GLcontext *ctx,
+ struct gl_renderbuffer *dsRb,
+ struct gl_renderbuffer *stencilRb)
+{
+ GLuint row, width, height;
+
+ ASSERT(dsRb);
+ ASSERT(stencilRb);
+
+ ASSERT(dsRb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT);
+ ASSERT(dsRb->DataType == GL_UNSIGNED_INT_24_8_EXT);
+ ASSERT(stencilRb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT ||
+ stencilRb->_ActualFormat == GL_STENCIL_INDEX8_EXT);
+
+ ASSERT(dsRb->Width == stencilRb->Width);
+ ASSERT(dsRb->Height == stencilRb->Height);
+
+ width = dsRb->Width;
+ height = dsRb->Height;
+
+ for (row = 0; row < height; row++) {
+ GLuint depthStencil[MAX_WIDTH];
+
+ dsRb->GetRow(ctx, dsRb, width, 0, row, depthStencil);
+
+ if (stencilRb->_ActualFormat == GL_STENCIL_INDEX8_EXT) {
+ /* 8bpp stencil */
+ GLubyte stencil[MAX_WIDTH];
+ GLuint i;
+ stencilRb->GetRow(ctx, stencilRb, width, 0, row, stencil);
+ for (i = 0; i < width; i++) {
+ depthStencil[i] = (depthStencil[i] & 0xffffff00) | stencil[i];
+ }
+ }
+ else {
+ /* 32bpp stencil buffer */
+ GLuint stencil[MAX_WIDTH], i;
+ ASSERT(stencilRb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT);
+ ASSERT(stencilRb->DataType == GL_UNSIGNED_INT_24_8_EXT);
+ stencilRb->GetRow(ctx, stencilRb, width, 0, row, stencil);
+ for (i = 0; i < width; i++) {
+ depthStencil[i]
+ = (depthStencil[i] & 0xffffff00) | (stencil[i] & 0xff);
+ }
+ }
+
+ dsRb->PutRow(ctx, dsRb, width, 0, row, depthStencil, NULL);
+ }
+}
+
+
+/**
+ * Convert the stencil buffer from 8bpp to 32bpp depth/stencil.
+ * \param stencilRb the stencil renderbuffer to promote
+ */
+void
+_mesa_promote_stencil(GLcontext *ctx, struct gl_renderbuffer *stencilRb)
+{
+ const GLsizei width = stencilRb->Width;
+ const GLsizei height = stencilRb->Height;
+ GLubyte *data;
+ GLint i, j, k;
+
+ ASSERT(stencilRb->_ActualFormat == GL_STENCIL_INDEX8_EXT);
+ ASSERT(stencilRb->Data);
+
+ data = (GLubyte *) stencilRb->Data;
+ stencilRb->Data = NULL;
+ stencilRb->AllocStorage(ctx, stencilRb, GL_DEPTH24_STENCIL8_EXT,
+ width, height);
+
+ ASSERT(stencilRb->DataType == GL_UNSIGNED_INT_24_8_EXT);
+
+ k = 0;
+ for (i = 0; i < height; i++) {
+ GLuint depthStencil[MAX_WIDTH];
+ for (j = 0; j < width; j++) {
+ depthStencil[j] = data[k++];
+ }
+ stencilRb->PutRow(ctx, stencilRb, width, 0, i, depthStencil, NULL);
+ }
+ _mesa_free(data);
+
+ stencilRb->_BaseFormat = GL_DEPTH_STENCIL_EXT;
+}
diff --git a/src/mesa/main/depthstencil.h b/src/mesa/main/depthstencil.h
new file mode 100644
index 00000000000..3dde081f5a5
--- /dev/null
+++ b/src/mesa/main/depthstencil.h
@@ -0,0 +1,56 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef DEPTHSTENCIL_H
+#define DEPTHSTENCIL_H
+
+
+extern struct gl_renderbuffer *
+_mesa_new_z24_renderbuffer_wrapper(GLcontext *ctx,
+ struct gl_renderbuffer *dsrb);
+
+
+extern struct gl_renderbuffer *
+_mesa_new_s8_renderbuffer_wrapper(GLcontext *ctx,
+ struct gl_renderbuffer *dsrb);
+
+
+extern void
+_mesa_extract_stencil(GLcontext *ctx,
+ struct gl_renderbuffer *dsRb,
+ struct gl_renderbuffer *stencilRb);
+
+
+extern void
+_mesa_insert_stencil(GLcontext *ctx,
+ struct gl_renderbuffer *dsRb,
+ struct gl_renderbuffer *stencilRb);
+
+
+extern void
+_mesa_promote_stencil(GLcontext *ctx, struct gl_renderbuffer *stencilRb);
+
+
+#endif /* DEPTHSTENCIL_H */
diff --git a/src/mesa/main/descrip.mms b/src/mesa/main/descrip.mms
new file mode 100644
index 00000000000..f4221cef903
--- /dev/null
+++ b/src/mesa/main/descrip.mms
@@ -0,0 +1,213 @@
+# Makefile for core library for VMS
+# contributed by Jouk Jansen joukj@hrem.stm.tudelft.nl
+# Last revision : 10 May 2005
+
+.first
+ define gl [---.include.gl]
+ define math [-.math]
+ define shader [-.shader]
+
+.include [---]mms-config.
+
+##### MACROS #####
+
+VPATH = RCS
+
+INCDIR = [---.include],[-.glapi],[-.shader]
+LIBDIR = [---.lib]
+CFLAGS = /include=($(INCDIR),[])/define=(PTHREADS=1)/name=(as_is,short)/float=ieee/ieee=denorm
+
+SOURCES =accum.c \
+ api_arrayelt.c \
+ api_loopback.c \
+ api_noop.c \
+ api_validate.c \
+ attrib.c \
+ blend.c \
+ bufferobj.c \
+ buffers.c \
+ clip.c \
+ colortab.c \
+ context.c \
+ convolve.c \
+ debug.c \
+ depth.c \
+ depthstencil.c \
+ dispatch.c \
+ dlist.c \
+ drawpix.c \
+ enable.c \
+ enums.c \
+ eval.c \
+ execmem.c \
+ extensions.c \
+ fbobject.c \
+ feedback.c \
+ fog.c \
+ framebuffer.c \
+ get.c \
+ getstring.c \
+ hash.c \
+ hint.c \
+ histogram.c \
+ image.c \
+ imports.c \
+ light.c \
+ lines.c \
+ matrix.c \
+ mm.c \
+ occlude.c \
+ pixel.c \
+ points.c \
+ polygon.c \
+ rastpos.c \
+ renderbuffer.c \
+ state.c \
+ stencil.c \
+ texcompress.c \
+ texcompress_fxt1.c \
+ texcompress_s3tc.c \
+ texenvprogram.c \
+ texformat.c \
+ teximage.c \
+ texobj.c \
+ texrender.c \
+ texstate.c \
+ texstore.c \
+ varray.c \
+ vtxfmt.c
+
+OBJECTS=accum.obj,\
+api_arrayelt.obj,\
+api_loopback.obj,\
+api_noop.obj,\
+api_validate.obj,\
+attrib.obj,\
+blend.obj,\
+bufferobj.obj,\
+buffers.obj,\
+clip.obj,\
+colortab.obj,\
+context.obj,\
+convolve.obj,\
+debug.obj,\
+depth.obj,\
+depthstencil.obj,\
+dispatch.obj,\
+dlist.obj,\
+drawpix.obj,\
+enable.obj,\
+enums.obj,\
+eval.obj,\
+execmem.obj,\
+extensions.obj,\
+fbobject.obj,\
+feedback.obj,\
+fog.obj,\
+framebuffer.obj,\
+get.obj,\
+getstring.obj,\
+hash.obj,\
+hint.obj,\
+histogram.obj,\
+image.obj,\
+imports.obj,\
+light.obj,\
+lines.obj,\
+matrix.obj,\
+mm.obj,\
+occlude.obj,\
+pixel.obj,\
+points.obj,\
+polygon.obj,\
+rastpos.obj,\
+renderbuffer.obj,\
+state.obj,\
+stencil.obj,\
+texcompress.obj,\
+texcompress_fxt1.obj,\
+texcompress_s3tc.obj,\
+texenvprogram.obj,\
+texformat.obj,\
+teximage.obj,\
+texobj.obj,\
+texrender.obj,\
+texstate.obj,\
+texstore.obj,\
+varray.obj,\
+vtxfmt.obj
+
+##### RULES #####
+
+VERSION=Mesa V3.4
+
+##### TARGETS #####
+# Make the library
+$(LIBDIR)$(GL_LIB) : $(OBJECTS)
+ @ $(MAKELIB) $(GL_LIB) $(OBJECTS)
+ @ rename $(GL_LIB)* $(LIBDIR)
+
+clean :
+ purge
+ delete *.obj;*
+
+accum.obj : accum.c
+api_arrayelt.obj : api_arrayelt.c
+api_loopback.obj : api_loopback.c
+api_noop.obj : api_noop.c
+api_validate.obj : api_validate.c
+attrib.obj : attrib.c
+blend.obj : blend.c
+bufferobj.obj : bufferobj.c
+buffers.obj : buffers.c
+clip.obj : clip.c
+colortab.obj : colortab.c
+context.obj : context.c
+convolve.obj : convolve.c
+debug.obj : debug.c
+depth.obj : depth.c
+depthstencil.obj : depthstencil.c
+dispatch.obj : dispatch.c
+dlist.obj : dlist.c
+drawpix.obj : drawpix.c
+enable.obj : enable.c
+enums.obj : enums.c
+eval.obj : eval.c
+execmem.obj : execmem.c
+extensions.obj : extensions.c
+fbobject.obj : fbobject.c
+feedback.obj : feedback.c
+fog.obj : fog.c
+framebuffer.obj : framebuffer.c
+get.obj : get.c
+getstring.obj : getstring.c
+hash.obj : hash.c
+hint.obj : hint.c
+histogram.obj : histogram.c
+image.obj : image.c
+imports.obj : imports.c vsnprintf.c
+light.obj : light.c
+lines.obj : lines.c
+matrix.obj : matrix.c
+mm.obj : mm.c
+occlude.obj : occlude.c
+pixel.obj : pixel.c
+points.obj : points.c
+polygon.obj : polygon.c
+rastpos.obj : rastpos.c
+renderbuffer.obj : renderbuffer.c
+state.obj : state.c
+stencil.obj : stencil.c
+texcompress.obj : texcompress.c
+texcompress_fxt1.obj : texcompress_fxt1.c
+ cc$(CFLAGS)/warn=(disable=SHIFTCOUNT) texcompress_fxt1.c
+texcompress_s3tc.obj : texcompress_s3tc.c
+texenvprogram.obj : texenvprogram.c
+texformat.obj : texformat.c
+teximage.obj : teximage.c
+texobj.obj : texobj.c
+texrender.obj : texrender.c
+texstate.obj : texstate.c
+texstore.obj : texstore.c
+varray.obj : varray.c
+vtxfmt.obj : vtxfmt.c
diff --git a/src/mesa/main/dispatch.c b/src/mesa/main/dispatch.c
new file mode 100644
index 00000000000..05c1c36c0d2
--- /dev/null
+++ b/src/mesa/main/dispatch.c
@@ -0,0 +1,95 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.3
+ *
+ * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/**
+ * \file dispatch.c
+ *
+ * This file generates all the gl* function entrypoints. This code is not
+ * used if optimized assembly stubs are available (e.g., using x86/glapi_x86.S
+ * on IA32 or sparc/glapi_sparc.S on SPARC).
+ *
+ * \note
+ * This file is also used to build the client-side libGL that loads DRI-based
+ * device drivers. At build-time it is symlinked to src/glx/x11.
+ *
+ * \author Brian Paul <brian@precisioninsight.com>
+ */
+
+#ifndef GLX_USE_APPLEGL
+
+#include "glheader.h"
+#include "glapi.h"
+#include "glapitable.h"
+#include "glthread.h"
+
+
+#if !(defined(USE_X86_ASM) || defined(USE_X86_64_ASM) || defined(USE_SPARC_ASM))
+
+#if defined(WIN32)
+#define KEYWORD1 GLAPI
+#else
+#define KEYWORD1 PUBLIC
+#endif
+
+#define KEYWORD2 GLAPIENTRY
+
+#if defined(USE_MGL_NAMESPACE)
+#define NAME(func) mgl##func
+#else
+#define NAME(func) gl##func
+#endif
+
+#if 0 /* Use this to log GL calls to stdout (for DEBUG only!) */
+
+#define F stdout
+#define DISPATCH(FUNC, ARGS, MESSAGE) \
+ fprintf MESSAGE; \
+ CALL_ ## FUNC(GET_DISPATCH(), ARGS);
+
+#define RETURN_DISPATCH(FUNC, ARGS, MESSAGE) \
+ fprintf MESSAGE; \
+ return CALL_ ## FUNC(GET_DISPATCH(), ARGS);
+
+#else
+
+#define DISPATCH(FUNC, ARGS, MESSAGE) \
+ CALL_ ## FUNC(GET_DISPATCH(), ARGS);
+
+#define RETURN_DISPATCH(FUNC, ARGS, MESSAGE) \
+ return CALL_ ## FUNC(GET_DISPATCH(), ARGS);
+
+#endif /* logging */
+
+
+#ifndef GLAPIENTRY
+#define GLAPIENTRY
+#endif
+
+#include "dispatch.h"
+#include "glapitemp.h"
+
+#endif /* USE_X86_ASM */
+
+#endif /* !GLX_USE_APPLEGL */
diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c
new file mode 100644
index 00000000000..dba2008ef73
--- /dev/null
+++ b/src/mesa/main/dlist.c
@@ -0,0 +1,8551 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/**
+ * \file dlist.c
+ * Display lists management functions.
+ */
+
+#include "glheader.h"
+#include "imports.h"
+#include "api_arrayelt.h"
+#include "api_loopback.h"
+#include "config.h"
+#if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program
+#include "arbprogram.h"
+#include "program.h"
+#endif
+#include "attrib.h"
+#include "blend.h"
+#include "buffers.h"
+#if FEATURE_ARB_vertex_buffer_object
+#include "bufferobj.h"
+#endif
+#include "clip.h"
+#include "colormac.h"
+#include "colortab.h"
+#include "context.h"
+#include "convolve.h"
+#include "depth.h"
+#include "dlist.h"
+#include "enable.h"
+#include "enums.h"
+#include "eval.h"
+#include "extensions.h"
+#include "feedback.h"
+#include "get.h"
+#include "glapi.h"
+#include "hash.h"
+#include "histogram.h"
+#include "image.h"
+#include "light.h"
+#include "lines.h"
+#include "dlist.h"
+#include "macros.h"
+#include "matrix.h"
+#include "occlude.h"
+#include "pixel.h"
+#include "points.h"
+#include "polygon.h"
+#include "state.h"
+#include "texobj.h"
+#include "teximage.h"
+#include "texstate.h"
+#include "mtypes.h"
+#include "varray.h"
+#if FEATURE_NV_vertex_program || FEATURE_NV_fragment_program
+#include "nvprogram.h"
+#include "program.h"
+#endif
+#if FEATURE_ATI_fragment_shader
+#include "atifragshader.h"
+#endif
+
+#include "math/m_matrix.h"
+#include "math/m_xform.h"
+
+#include "dispatch.h"
+
+
+/**
+ * Flush vertices.
+ *
+ * \param ctx GL context.
+ *
+ * Checks if dd_function_table::SaveNeedFlush is marked to flush
+ * stored (save) vertices, and calls
+ * dd_function_table::SaveFlushVertices if so.
+ */
+#define SAVE_FLUSH_VERTICES(ctx) \
+do { \
+ if (ctx->Driver.SaveNeedFlush) \
+ ctx->Driver.SaveFlushVertices(ctx); \
+} while (0)
+
+
+/**
+ * Macro to assert that the API call was made outside the
+ * glBegin()/glEnd() pair, with return value.
+ *
+ * \param ctx GL context.
+ * \param retval value to return value in case the assertion fails.
+ */
+#define ASSERT_OUTSIDE_SAVE_BEGIN_END_WITH_RETVAL(ctx, retval) \
+do { \
+ if (ctx->Driver.CurrentSavePrimitive <= GL_POLYGON || \
+ ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM) { \
+ _mesa_compile_error( ctx, GL_INVALID_OPERATION, "begin/end" ); \
+ return retval; \
+ } \
+} while (0)
+
+/**
+ * Macro to assert that the API call was made outside the
+ * glBegin()/glEnd() pair.
+ *
+ * \param ctx GL context.
+ */
+#define ASSERT_OUTSIDE_SAVE_BEGIN_END(ctx) \
+do { \
+ if (ctx->Driver.CurrentSavePrimitive <= GL_POLYGON || \
+ ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM) { \
+ _mesa_compile_error( ctx, GL_INVALID_OPERATION, "begin/end" ); \
+ return; \
+ } \
+} while (0)
+
+/**
+ * Macro to assert that the API call was made outside the
+ * glBegin()/glEnd() pair and flush the vertices.
+ *
+ * \param ctx GL context.
+ */
+#define ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx) \
+do { \
+ ASSERT_OUTSIDE_SAVE_BEGIN_END(ctx); \
+ SAVE_FLUSH_VERTICES(ctx); \
+} while (0)
+
+/**
+ * Macro to assert that the API call was made outside the
+ * glBegin()/glEnd() pair and flush the vertices, with return value.
+ *
+ * \param ctx GL context.
+ * \param retval value to return value in case the assertion fails.
+ */
+#define ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx, retval)\
+do { \
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_WITH_RETVAL(ctx, retval); \
+ SAVE_FLUSH_VERTICES(ctx); \
+} while (0)
+
+
+
+/**
+ * Display list opcodes.
+ *
+ * The fact that these identifiers are assigned consecutive
+ * integer values starting at 0 is very important, see InstSize array usage)
+ */
+typedef enum
+{
+ OPCODE_INVALID = -1, /* Force signed enum */
+ OPCODE_ACCUM,
+ OPCODE_ALPHA_FUNC,
+ OPCODE_BIND_TEXTURE,
+ OPCODE_BITMAP,
+ OPCODE_BLEND_COLOR,
+ OPCODE_BLEND_EQUATION,
+ OPCODE_BLEND_EQUATION_SEPARATE,
+ OPCODE_BLEND_FUNC_SEPARATE,
+ OPCODE_CALL_LIST,
+ OPCODE_CALL_LIST_OFFSET,
+ OPCODE_CLEAR,
+ OPCODE_CLEAR_ACCUM,
+ OPCODE_CLEAR_COLOR,
+ OPCODE_CLEAR_DEPTH,
+ OPCODE_CLEAR_INDEX,
+ OPCODE_CLEAR_STENCIL,
+ OPCODE_CLIP_PLANE,
+ OPCODE_COLOR_MASK,
+ OPCODE_COLOR_MATERIAL,
+ OPCODE_COLOR_TABLE,
+ OPCODE_COLOR_TABLE_PARAMETER_FV,
+ OPCODE_COLOR_TABLE_PARAMETER_IV,
+ OPCODE_COLOR_SUB_TABLE,
+ OPCODE_CONVOLUTION_FILTER_1D,
+ OPCODE_CONVOLUTION_FILTER_2D,
+ OPCODE_CONVOLUTION_PARAMETER_I,
+ OPCODE_CONVOLUTION_PARAMETER_IV,
+ OPCODE_CONVOLUTION_PARAMETER_F,
+ OPCODE_CONVOLUTION_PARAMETER_FV,
+ OPCODE_COPY_COLOR_SUB_TABLE,
+ OPCODE_COPY_COLOR_TABLE,
+ OPCODE_COPY_PIXELS,
+ OPCODE_COPY_TEX_IMAGE1D,
+ OPCODE_COPY_TEX_IMAGE2D,
+ OPCODE_COPY_TEX_SUB_IMAGE1D,
+ OPCODE_COPY_TEX_SUB_IMAGE2D,
+ OPCODE_COPY_TEX_SUB_IMAGE3D,
+ OPCODE_CULL_FACE,
+ OPCODE_DEPTH_FUNC,
+ OPCODE_DEPTH_MASK,
+ OPCODE_DEPTH_RANGE,
+ OPCODE_DISABLE,
+ OPCODE_DRAW_BUFFER,
+ OPCODE_DRAW_PIXELS,
+ OPCODE_ENABLE,
+ OPCODE_EVALMESH1,
+ OPCODE_EVALMESH2,
+ OPCODE_FOG,
+ OPCODE_FRONT_FACE,
+ OPCODE_FRUSTUM,
+ OPCODE_HINT,
+ OPCODE_HISTOGRAM,
+ OPCODE_INDEX_MASK,
+ OPCODE_INIT_NAMES,
+ OPCODE_LIGHT,
+ OPCODE_LIGHT_MODEL,
+ OPCODE_LINE_STIPPLE,
+ OPCODE_LINE_WIDTH,
+ OPCODE_LIST_BASE,
+ OPCODE_LOAD_IDENTITY,
+ OPCODE_LOAD_MATRIX,
+ OPCODE_LOAD_NAME,
+ OPCODE_LOGIC_OP,
+ OPCODE_MAP1,
+ OPCODE_MAP2,
+ OPCODE_MAPGRID1,
+ OPCODE_MAPGRID2,
+ OPCODE_MATRIX_MODE,
+ OPCODE_MIN_MAX,
+ OPCODE_MULT_MATRIX,
+ OPCODE_ORTHO,
+ OPCODE_PASSTHROUGH,
+ OPCODE_PIXEL_MAP,
+ OPCODE_PIXEL_TRANSFER,
+ OPCODE_PIXEL_ZOOM,
+ OPCODE_POINT_SIZE,
+ OPCODE_POINT_PARAMETERS,
+ OPCODE_POLYGON_MODE,
+ OPCODE_POLYGON_STIPPLE,
+ OPCODE_POLYGON_OFFSET,
+ OPCODE_POP_ATTRIB,
+ OPCODE_POP_MATRIX,
+ OPCODE_POP_NAME,
+ OPCODE_PRIORITIZE_TEXTURE,
+ OPCODE_PUSH_ATTRIB,
+ OPCODE_PUSH_MATRIX,
+ OPCODE_PUSH_NAME,
+ OPCODE_RASTER_POS,
+ OPCODE_READ_BUFFER,
+ OPCODE_RESET_HISTOGRAM,
+ OPCODE_RESET_MIN_MAX,
+ OPCODE_ROTATE,
+ OPCODE_SCALE,
+ OPCODE_SCISSOR,
+ OPCODE_SELECT_TEXTURE_SGIS,
+ OPCODE_SELECT_TEXTURE_COORD_SET,
+ OPCODE_SHADE_MODEL,
+ OPCODE_STENCIL_FUNC,
+ OPCODE_STENCIL_MASK,
+ OPCODE_STENCIL_OP,
+ OPCODE_TEXENV,
+ OPCODE_TEXGEN,
+ OPCODE_TEXPARAMETER,
+ OPCODE_TEX_IMAGE1D,
+ OPCODE_TEX_IMAGE2D,
+ OPCODE_TEX_IMAGE3D,
+ OPCODE_TEX_SUB_IMAGE1D,
+ OPCODE_TEX_SUB_IMAGE2D,
+ OPCODE_TEX_SUB_IMAGE3D,
+ OPCODE_TRANSLATE,
+ OPCODE_VIEWPORT,
+ OPCODE_WINDOW_POS,
+ /* GL_ARB_multitexture */
+ OPCODE_ACTIVE_TEXTURE,
+ /* GL_ARB_texture_compression */
+ OPCODE_COMPRESSED_TEX_IMAGE_1D,
+ OPCODE_COMPRESSED_TEX_IMAGE_2D,
+ OPCODE_COMPRESSED_TEX_IMAGE_3D,
+ OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D,
+ OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D,
+ OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D,
+ /* GL_ARB_multisample */
+ OPCODE_SAMPLE_COVERAGE,
+ /* GL_ARB_window_pos */
+ OPCODE_WINDOW_POS_ARB,
+ /* GL_NV_vertex_program */
+ OPCODE_BIND_PROGRAM_NV,
+ OPCODE_EXECUTE_PROGRAM_NV,
+ OPCODE_REQUEST_RESIDENT_PROGRAMS_NV,
+ OPCODE_LOAD_PROGRAM_NV,
+ OPCODE_PROGRAM_PARAMETER4F_NV,
+ OPCODE_TRACK_MATRIX_NV,
+ /* GL_NV_fragment_program */
+ OPCODE_PROGRAM_LOCAL_PARAMETER_ARB,
+ OPCODE_PROGRAM_NAMED_PARAMETER_NV,
+ /* GL_EXT_stencil_two_side */
+ OPCODE_ACTIVE_STENCIL_FACE_EXT,
+ /* GL_EXT_depth_bounds_test */
+ OPCODE_DEPTH_BOUNDS_EXT,
+ /* GL_ARB_vertex/fragment_program */
+ OPCODE_PROGRAM_STRING_ARB,
+ OPCODE_PROGRAM_ENV_PARAMETER_ARB,
+ /* GL_ARB_occlusion_query */
+ OPCODE_BEGIN_QUERY_ARB,
+ OPCODE_END_QUERY_ARB,
+ /* GL_ARB_draw_buffers */
+ OPCODE_DRAW_BUFFERS_ARB,
+ /* GL_ATI_fragment_shader */
+ OPCODE_BIND_FRAGMENT_SHADER_ATI,
+ OPCODE_SET_FRAGMENT_SHADER_CONSTANTS_ATI,
+ /* OpenGL 2.0 */
+ OPCODE_STENCIL_FUNC_SEPARATE,
+ OPCODE_STENCIL_OP_SEPARATE,
+ OPCODE_STENCIL_MASK_SEPARATE,
+
+ /* GL_EXT_framebuffer_blit */
+ OPCODE_BLIT_FRAMEBUFFER,
+
+ /* Vertex attributes -- fallback for when optimized display
+ * list build isn't active.
+ */
+ OPCODE_ATTR_1F_NV,
+ OPCODE_ATTR_2F_NV,
+ OPCODE_ATTR_3F_NV,
+ OPCODE_ATTR_4F_NV,
+ OPCODE_ATTR_1F_ARB,
+ OPCODE_ATTR_2F_ARB,
+ OPCODE_ATTR_3F_ARB,
+ OPCODE_ATTR_4F_ARB,
+ OPCODE_MATERIAL,
+ OPCODE_INDEX,
+ OPCODE_EDGEFLAG,
+ OPCODE_BEGIN,
+ OPCODE_END,
+ OPCODE_RECTF,
+ OPCODE_EVAL_C1,
+ OPCODE_EVAL_C2,
+ OPCODE_EVAL_P1,
+ OPCODE_EVAL_P2,
+
+ /* The following three are meta instructions */
+ OPCODE_ERROR, /* raise compiled-in error */
+ OPCODE_CONTINUE,
+ OPCODE_END_OF_LIST,
+ OPCODE_EXT_0
+} OpCode;
+
+
+
+/**
+ * Display list node.
+ *
+ * Display list instructions are stored as sequences of "nodes". Nodes
+ * are allocated in blocks. Each block has BLOCK_SIZE nodes. Blocks
+ * are linked together with a pointer.
+ *
+ * Each instruction in the display list is stored as a sequence of
+ * contiguous nodes in memory.
+ * Each node is the union of a variety of data types.
+ */
+union node
+{
+ OpCode opcode;
+ GLboolean b;
+ GLbitfield bf;
+ GLubyte ub;
+ GLshort s;
+ GLushort us;
+ GLint i;
+ GLuint ui;
+ GLenum e;
+ GLfloat f;
+ GLvoid *data;
+ void *next; /* If prev node's opcode==OPCODE_CONTINUE */
+};
+
+
+/**
+ * How many nodes to allocate at a time.
+ *
+ * \note Reduced now that we hold vertices etc. elsewhere.
+ */
+#define BLOCK_SIZE 256
+
+
+
+/**
+ * Number of nodes of storage needed for each instruction.
+ * Sizes for dynamically allocated opcodes are stored in the context struct.
+ */
+static GLuint InstSize[OPCODE_END_OF_LIST + 1];
+
+void mesa_print_display_list(GLuint list);
+
+
+/**********************************************************************/
+/***** Private *****/
+/**********************************************************************/
+
+
+/**
+ * Make an empty display list. This is used by glGenLists() to
+ * reserve display list IDs.
+ */
+static struct mesa_display_list *
+make_list(GLuint list, GLuint count)
+{
+ struct mesa_display_list *dlist = CALLOC_STRUCT(mesa_display_list);
+ dlist->id = list;
+ dlist->node = (Node *) _mesa_malloc(sizeof(Node) * count);
+ dlist->node[0].opcode = OPCODE_END_OF_LIST;
+ return dlist;
+}
+
+
+
+/**
+ * Destroy all nodes in a display list.
+ * \param list - display list number
+ */
+void
+_mesa_destroy_list(GLcontext *ctx, GLuint list)
+{
+ struct mesa_display_list *dlist;
+ Node *n, *block;
+ GLboolean done;
+
+ if (list == 0)
+ return;
+
+ dlist =
+ (struct mesa_display_list *) _mesa_HashLookup(ctx->Shared->DisplayList,
+ list);
+ if (!dlist)
+ return;
+
+ n = block = dlist->node;
+
+ done = block ? GL_FALSE : GL_TRUE;
+ while (!done) {
+
+ /* check for extension opcodes first */
+
+ GLint i = (GLint) n[0].opcode - (GLint) OPCODE_EXT_0;
+ if (i >= 0 && i < (GLint) ctx->ListExt.NumOpcodes) {
+ ctx->ListExt.Opcode[i].Destroy(ctx, &n[1]);
+ n += ctx->ListExt.Opcode[i].Size;
+ }
+ else {
+ switch (n[0].opcode) {
+ /* for some commands, we need to free malloc'd memory */
+ case OPCODE_MAP1:
+ _mesa_free(n[6].data);
+ n += InstSize[n[0].opcode];
+ break;
+ case OPCODE_MAP2:
+ _mesa_free(n[10].data);
+ n += InstSize[n[0].opcode];
+ break;
+ case OPCODE_DRAW_PIXELS:
+ _mesa_free(n[5].data);
+ n += InstSize[n[0].opcode];
+ break;
+ case OPCODE_BITMAP:
+ _mesa_free(n[7].data);
+ n += InstSize[n[0].opcode];
+ break;
+ case OPCODE_COLOR_TABLE:
+ _mesa_free(n[6].data);
+ n += InstSize[n[0].opcode];
+ break;
+ case OPCODE_COLOR_SUB_TABLE:
+ _mesa_free(n[6].data);
+ n += InstSize[n[0].opcode];
+ break;
+ case OPCODE_CONVOLUTION_FILTER_1D:
+ _mesa_free(n[6].data);
+ n += InstSize[n[0].opcode];
+ break;
+ case OPCODE_CONVOLUTION_FILTER_2D:
+ _mesa_free(n[7].data);
+ n += InstSize[n[0].opcode];
+ break;
+ case OPCODE_POLYGON_STIPPLE:
+ _mesa_free(n[1].data);
+ n += InstSize[n[0].opcode];
+ break;
+ case OPCODE_TEX_IMAGE1D:
+ _mesa_free(n[8].data);
+ n += InstSize[n[0].opcode];
+ break;
+ case OPCODE_TEX_IMAGE2D:
+ _mesa_free(n[9].data);
+ n += InstSize[n[0].opcode];
+ break;
+ case OPCODE_TEX_IMAGE3D:
+ _mesa_free(n[10].data);
+ n += InstSize[n[0].opcode];
+ break;
+ case OPCODE_TEX_SUB_IMAGE1D:
+ _mesa_free(n[7].data);
+ n += InstSize[n[0].opcode];
+ break;
+ case OPCODE_TEX_SUB_IMAGE2D:
+ _mesa_free(n[9].data);
+ n += InstSize[n[0].opcode];
+ break;
+ case OPCODE_TEX_SUB_IMAGE3D:
+ _mesa_free(n[11].data);
+ n += InstSize[n[0].opcode];
+ break;
+ case OPCODE_COMPRESSED_TEX_IMAGE_1D:
+ _mesa_free(n[7].data);
+ n += InstSize[n[0].opcode];
+ break;
+ case OPCODE_COMPRESSED_TEX_IMAGE_2D:
+ _mesa_free(n[8].data);
+ n += InstSize[n[0].opcode];
+ break;
+ case OPCODE_COMPRESSED_TEX_IMAGE_3D:
+ _mesa_free(n[9].data);
+ n += InstSize[n[0].opcode];
+ break;
+ case OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D:
+ _mesa_free(n[7].data);
+ n += InstSize[n[0].opcode];
+ break;
+ case OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D:
+ _mesa_free(n[9].data);
+ n += InstSize[n[0].opcode];
+ break;
+ case OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D:
+ _mesa_free(n[11].data);
+ n += InstSize[n[0].opcode];
+ break;
+#if FEATURE_NV_vertex_program
+ case OPCODE_LOAD_PROGRAM_NV:
+ _mesa_free(n[4].data); /* program string */
+ n += InstSize[n[0].opcode];
+ break;
+ case OPCODE_REQUEST_RESIDENT_PROGRAMS_NV:
+ _mesa_free(n[2].data); /* array of program ids */
+ n += InstSize[n[0].opcode];
+ break;
+#endif
+#if FEATURE_NV_fragment_program
+ case OPCODE_PROGRAM_NAMED_PARAMETER_NV:
+ _mesa_free(n[3].data); /* parameter name */
+ n += InstSize[n[0].opcode];
+ break;
+#endif
+#if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program
+ case OPCODE_PROGRAM_STRING_ARB:
+ _mesa_free(n[4].data); /* program string */
+ n += InstSize[n[0].opcode];
+ break;
+#endif
+ case OPCODE_CONTINUE:
+ n = (Node *) n[1].next;
+ _mesa_free(block);
+ block = n;
+ break;
+ case OPCODE_END_OF_LIST:
+ _mesa_free(block);
+ done = GL_TRUE;
+ break;
+ default:
+ /* Most frequent case */
+ n += InstSize[n[0].opcode];
+ break;
+ }
+ }
+ }
+
+ _mesa_free(dlist);
+ _mesa_HashRemove(ctx->Shared->DisplayList, list);
+}
+
+
+
+/*
+ * Translate the nth element of list from type to GLuint.
+ */
+static GLuint
+translate_id(GLsizei n, GLenum type, const GLvoid * list)
+{
+ GLbyte *bptr;
+ GLubyte *ubptr;
+ GLshort *sptr;
+ GLushort *usptr;
+ GLint *iptr;
+ GLuint *uiptr;
+ GLfloat *fptr;
+
+ switch (type) {
+ case GL_BYTE:
+ bptr = (GLbyte *) list;
+ return (GLuint) *(bptr + n);
+ case GL_UNSIGNED_BYTE:
+ ubptr = (GLubyte *) list;
+ return (GLuint) *(ubptr + n);
+ case GL_SHORT:
+ sptr = (GLshort *) list;
+ return (GLuint) *(sptr + n);
+ case GL_UNSIGNED_SHORT:
+ usptr = (GLushort *) list;
+ return (GLuint) *(usptr + n);
+ case GL_INT:
+ iptr = (GLint *) list;
+ return (GLuint) *(iptr + n);
+ case GL_UNSIGNED_INT:
+ uiptr = (GLuint *) list;
+ return (GLuint) *(uiptr + n);
+ case GL_FLOAT:
+ fptr = (GLfloat *) list;
+ return (GLuint) *(fptr + n);
+ case GL_2_BYTES:
+ ubptr = ((GLubyte *) list) + 2 * n;
+ return (GLuint) *ubptr * 256 + (GLuint) * (ubptr + 1);
+ case GL_3_BYTES:
+ ubptr = ((GLubyte *) list) + 3 * n;
+ return (GLuint) * ubptr * 65536
+ + (GLuint) *(ubptr + 1) * 256 + (GLuint) * (ubptr + 2);
+ case GL_4_BYTES:
+ ubptr = ((GLubyte *) list) + 4 * n;
+ return (GLuint) *ubptr * 16777216
+ + (GLuint) *(ubptr + 1) * 65536
+ + (GLuint) *(ubptr + 2) * 256 + (GLuint) * (ubptr + 3);
+ default:
+ return 0;
+ }
+}
+
+
+
+
+/**********************************************************************/
+/***** Public *****/
+/**********************************************************************/
+
+/**
+ * Wrapper for _mesa_unpack_image() that handles pixel buffer objects.
+ * \todo This won't suffice when the PBO is really in VRAM/GPU memory.
+ */
+static GLvoid *
+unpack_image(GLuint dimensions, GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type, const GLvoid * pixels,
+ const struct gl_pixelstore_attrib *unpack)
+{
+ if (unpack->BufferObj->Name == 0) {
+ /* no PBO */
+ return _mesa_unpack_image(dimensions, width, height, depth, format,
+ type, pixels, unpack);
+ }
+ else
+ if (_mesa_validate_pbo_access
+ (dimensions, unpack, width, height, depth, format, type, pixels)) {
+ const GLubyte *src = ADD_POINTERS(unpack->BufferObj->Data, pixels);
+ return _mesa_unpack_image(dimensions, width, height, depth, format,
+ type, src, unpack);
+ }
+ /* bad access! */
+ return NULL;
+}
+
+
+/**
+ * Allocate space for a display list instruction.
+ * \param opcode the instruction opcode (OPCODE_* value)
+ * \param size instruction size in bytes, not counting opcode.
+ * \return pointer to the usable data area (not including the internal
+ * opcode).
+ */
+void *
+_mesa_alloc_instruction(GLcontext *ctx, GLuint opcode, GLuint bytes)
+{
+ const GLuint numNodes = 1 + (bytes + sizeof(Node) - 1) / sizeof(Node);
+ Node *n;
+
+ if (opcode < (GLuint) OPCODE_EXT_0) {
+ if (InstSize[opcode] == 0) {
+ /* save instruction size now */
+ InstSize[opcode] = numNodes;
+ }
+ else {
+ /* make sure instruction size agrees */
+ ASSERT(numNodes == InstSize[opcode]);
+ }
+ }
+
+ if (ctx->ListState.CurrentPos + numNodes + 2 > BLOCK_SIZE) {
+ /* This block is full. Allocate a new block and chain to it */
+ Node *newblock;
+ n = ctx->ListState.CurrentBlock + ctx->ListState.CurrentPos;
+ n[0].opcode = OPCODE_CONTINUE;
+ newblock = (Node *) _mesa_malloc(sizeof(Node) * BLOCK_SIZE);
+ if (!newblock) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "Building display list");
+ return NULL;
+ }
+ n[1].next = (Node *) newblock;
+ ctx->ListState.CurrentBlock = newblock;
+ ctx->ListState.CurrentPos = 0;
+ }
+
+ n = ctx->ListState.CurrentBlock + ctx->ListState.CurrentPos;
+ ctx->ListState.CurrentPos += numNodes;
+
+ n[0].opcode = (OpCode) opcode;
+
+ return (void *) (n + 1); /* return ptr to node following opcode */
+}
+
+
+/**
+ * This function allows modules and drivers to get their own opcodes
+ * for extending display list functionality.
+ * \param ctx the rendering context
+ * \param size number of bytes for storing the new display list command
+ * \param execute function to execute the new display list command
+ * \param destroy function to destroy the new display list command
+ * \param print function to print the new display list command
+ * \return the new opcode number or -1 if error
+ */
+GLint
+_mesa_alloc_opcode(GLcontext *ctx,
+ GLuint size,
+ void (*execute) (GLcontext *, void *),
+ void (*destroy) (GLcontext *, void *),
+ void (*print) (GLcontext *, void *))
+{
+ if (ctx->ListExt.NumOpcodes < MAX_DLIST_EXT_OPCODES) {
+ const GLuint i = ctx->ListExt.NumOpcodes++;
+ ctx->ListExt.Opcode[i].Size =
+ 1 + (size + sizeof(Node) - 1) / sizeof(Node);
+ ctx->ListExt.Opcode[i].Execute = execute;
+ ctx->ListExt.Opcode[i].Destroy = destroy;
+ ctx->ListExt.Opcode[i].Print = print;
+ return i + OPCODE_EXT_0;
+ }
+ return -1;
+}
+
+
+
+/**
+ * Allocate display list instruction. Returns Node ptr to where the opcode
+ * is stored.
+ * - nParams is the number of function parameters
+ * - return value a pointer to sizeof(Node) before the actual
+ * usable data area.
+ */
+#define ALLOC_INSTRUCTION(CTX, OPCODE, NPARAMS) \
+ ((Node *)_mesa_alloc_instruction(CTX, OPCODE, (NPARAMS)*sizeof(Node)) - 1)
+
+
+
+/*
+ * Display List compilation functions
+ */
+static void GLAPIENTRY
+save_Accum(GLenum op, GLfloat value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_ACCUM, 2);
+ if (n) {
+ n[1].e = op;
+ n[2].f = value;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_Accum(ctx->Exec, (op, value));
+ }
+}
+
+
+static void GLAPIENTRY
+save_AlphaFunc(GLenum func, GLclampf ref)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_ALPHA_FUNC, 2);
+ if (n) {
+ n[1].e = func;
+ n[2].f = (GLfloat) ref;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_AlphaFunc(ctx->Exec, (func, ref));
+ }
+}
+
+
+static void GLAPIENTRY
+save_BindTexture(GLenum target, GLuint texture)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_BIND_TEXTURE, 2);
+ if (n) {
+ n[1].e = target;
+ n[2].ui = texture;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_BindTexture(ctx->Exec, (target, texture));
+ }
+}
+
+
+static void GLAPIENTRY
+save_Bitmap(GLsizei width, GLsizei height,
+ GLfloat xorig, GLfloat yorig,
+ GLfloat xmove, GLfloat ymove, const GLubyte * pixels)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLvoid *image = _mesa_unpack_bitmap(width, height, pixels, &ctx->Unpack);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_BITMAP, 7);
+ if (n) {
+ n[1].i = (GLint) width;
+ n[2].i = (GLint) height;
+ n[3].f = xorig;
+ n[4].f = yorig;
+ n[5].f = xmove;
+ n[6].f = ymove;
+ n[7].data = image;
+ }
+ else if (image) {
+ _mesa_free(image);
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_Bitmap(ctx->Exec, (width, height,
+ xorig, yorig, xmove, ymove, pixels));
+ }
+}
+
+
+static void GLAPIENTRY
+save_BlendEquation(GLenum mode)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_BLEND_EQUATION, 1);
+ if (n) {
+ n[1].e = mode;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_BlendEquation(ctx->Exec, (mode));
+ }
+}
+
+
+static void GLAPIENTRY
+save_BlendEquationSeparateEXT(GLenum modeRGB, GLenum modeA)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_BLEND_EQUATION_SEPARATE, 2);
+ if (n) {
+ n[1].e = modeRGB;
+ n[2].e = modeA;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_BlendEquationSeparateEXT(ctx->Exec, (modeRGB, modeA));
+ }
+}
+
+
+static void GLAPIENTRY
+save_BlendFuncSeparateEXT(GLenum sfactorRGB, GLenum dfactorRGB,
+ GLenum sfactorA, GLenum dfactorA)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_BLEND_FUNC_SEPARATE, 4);
+ if (n) {
+ n[1].e = sfactorRGB;
+ n[2].e = dfactorRGB;
+ n[3].e = sfactorA;
+ n[4].e = dfactorA;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_BlendFuncSeparateEXT(ctx->Exec,
+ (sfactorRGB, dfactorRGB, sfactorA, dfactorA));
+ }
+}
+
+
+static void GLAPIENTRY
+save_BlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_BLEND_COLOR, 4);
+ if (n) {
+ n[1].f = red;
+ n[2].f = green;
+ n[3].f = blue;
+ n[4].f = alpha;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_BlendColor(ctx->Exec, (red, green, blue, alpha));
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_save_CallList(GLuint list)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ SAVE_FLUSH_VERTICES(ctx);
+
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_CALL_LIST, 1);
+ if (n) {
+ n[1].ui = list;
+ }
+
+ /* After this, we don't know what begin/end state we're in:
+ */
+ ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN;
+
+ if (ctx->ExecuteFlag) {
+ CALL_CallList(ctx->Exec, (list));
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_save_CallLists(GLsizei n, GLenum type, const GLvoid * lists)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint i;
+ GLboolean typeErrorFlag;
+
+ SAVE_FLUSH_VERTICES(ctx);
+
+ switch (type) {
+ case GL_BYTE:
+ case GL_UNSIGNED_BYTE:
+ case GL_SHORT:
+ case GL_UNSIGNED_SHORT:
+ case GL_INT:
+ case GL_UNSIGNED_INT:
+ case GL_FLOAT:
+ case GL_2_BYTES:
+ case GL_3_BYTES:
+ case GL_4_BYTES:
+ typeErrorFlag = GL_FALSE;
+ break;
+ default:
+ typeErrorFlag = GL_TRUE;
+ }
+
+ for (i = 0; i < n; i++) {
+ GLuint list = translate_id(i, type, lists);
+ Node *n = ALLOC_INSTRUCTION(ctx, OPCODE_CALL_LIST_OFFSET, 2);
+ if (n) {
+ n[1].ui = list;
+ n[2].b = typeErrorFlag;
+ }
+ }
+
+ /* After this, we don't know what begin/end state we're in:
+ */
+ ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN;
+
+ if (ctx->ExecuteFlag) {
+ CALL_CallLists(ctx->Exec, (n, type, lists));
+ }
+}
+
+
+static void GLAPIENTRY
+save_Clear(GLbitfield mask)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_CLEAR, 1);
+ if (n) {
+ n[1].bf = mask;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_Clear(ctx->Exec, (mask));
+ }
+}
+
+
+static void GLAPIENTRY
+save_ClearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_CLEAR_ACCUM, 4);
+ if (n) {
+ n[1].f = red;
+ n[2].f = green;
+ n[3].f = blue;
+ n[4].f = alpha;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_ClearAccum(ctx->Exec, (red, green, blue, alpha));
+ }
+}
+
+
+static void GLAPIENTRY
+save_ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_CLEAR_COLOR, 4);
+ if (n) {
+ n[1].f = red;
+ n[2].f = green;
+ n[3].f = blue;
+ n[4].f = alpha;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_ClearColor(ctx->Exec, (red, green, blue, alpha));
+ }
+}
+
+
+static void GLAPIENTRY
+save_ClearDepth(GLclampd depth)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_CLEAR_DEPTH, 1);
+ if (n) {
+ n[1].f = (GLfloat) depth;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_ClearDepth(ctx->Exec, (depth));
+ }
+}
+
+
+static void GLAPIENTRY
+save_ClearIndex(GLfloat c)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_CLEAR_INDEX, 1);
+ if (n) {
+ n[1].f = c;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_ClearIndex(ctx->Exec, (c));
+ }
+}
+
+
+static void GLAPIENTRY
+save_ClearStencil(GLint s)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_CLEAR_STENCIL, 1);
+ if (n) {
+ n[1].i = s;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_ClearStencil(ctx->Exec, (s));
+ }
+}
+
+
+static void GLAPIENTRY
+save_ClipPlane(GLenum plane, const GLdouble * equ)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_CLIP_PLANE, 5);
+ if (n) {
+ n[1].e = plane;
+ n[2].f = (GLfloat) equ[0];
+ n[3].f = (GLfloat) equ[1];
+ n[4].f = (GLfloat) equ[2];
+ n[5].f = (GLfloat) equ[3];
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_ClipPlane(ctx->Exec, (plane, equ));
+ }
+}
+
+
+
+static void GLAPIENTRY
+save_ColorMask(GLboolean red, GLboolean green,
+ GLboolean blue, GLboolean alpha)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_COLOR_MASK, 4);
+ if (n) {
+ n[1].b = red;
+ n[2].b = green;
+ n[3].b = blue;
+ n[4].b = alpha;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_ColorMask(ctx->Exec, (red, green, blue, alpha));
+ }
+}
+
+
+static void GLAPIENTRY
+save_ColorMaterial(GLenum face, GLenum mode)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_COLOR_MATERIAL, 2);
+ if (n) {
+ n[1].e = face;
+ n[2].e = mode;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_ColorMaterial(ctx->Exec, (face, mode));
+ }
+}
+
+
+static void GLAPIENTRY
+save_ColorTable(GLenum target, GLenum internalFormat,
+ GLsizei width, GLenum format, GLenum type,
+ const GLvoid * table)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ if (_mesa_is_proxy_texture(target)) {
+ /* execute immediately */
+ CALL_ColorTable(ctx->Exec, (target, internalFormat, width,
+ format, type, table));
+ }
+ else {
+ GLvoid *image = unpack_image(1, width, 1, 1, format, type, table,
+ &ctx->Unpack);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_COLOR_TABLE, 6);
+ if (n) {
+ n[1].e = target;
+ n[2].e = internalFormat;
+ n[3].i = width;
+ n[4].e = format;
+ n[5].e = type;
+ n[6].data = image;
+ }
+ else if (image) {
+ _mesa_free(image);
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_ColorTable(ctx->Exec, (target, internalFormat, width,
+ format, type, table));
+ }
+ }
+}
+
+
+
+static void GLAPIENTRY
+save_ColorTableParameterfv(GLenum target, GLenum pname,
+ const GLfloat *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_COLOR_TABLE_PARAMETER_FV, 6);
+ if (n) {
+ n[1].e = target;
+ n[2].e = pname;
+ n[3].f = params[0];
+ if (pname == GL_COLOR_TABLE_SGI ||
+ pname == GL_POST_CONVOLUTION_COLOR_TABLE_SGI ||
+ pname == GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI ||
+ pname == GL_TEXTURE_COLOR_TABLE_SGI) {
+ n[4].f = params[1];
+ n[5].f = params[2];
+ n[6].f = params[3];
+ }
+ }
+
+ if (ctx->ExecuteFlag) {
+ CALL_ColorTableParameterfv(ctx->Exec, (target, pname, params));
+ }
+}
+
+
+static void GLAPIENTRY
+save_ColorTableParameteriv(GLenum target, GLenum pname, const GLint *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_COLOR_TABLE_PARAMETER_IV, 6);
+ if (n) {
+ n[1].e = target;
+ n[2].e = pname;
+ n[3].i = params[0];
+ if (pname == GL_COLOR_TABLE_SGI ||
+ pname == GL_POST_CONVOLUTION_COLOR_TABLE_SGI ||
+ pname == GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI ||
+ pname == GL_TEXTURE_COLOR_TABLE_SGI) {
+ n[4].i = params[1];
+ n[5].i = params[2];
+ n[6].i = params[3];
+ }
+ }
+
+ if (ctx->ExecuteFlag) {
+ CALL_ColorTableParameteriv(ctx->Exec, (target, pname, params));
+ }
+}
+
+
+
+static void GLAPIENTRY
+save_ColorSubTable(GLenum target, GLsizei start, GLsizei count,
+ GLenum format, GLenum type, const GLvoid * table)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLvoid *image = unpack_image(1, count, 1, 1, format, type, table,
+ &ctx->Unpack);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_COLOR_SUB_TABLE, 6);
+ if (n) {
+ n[1].e = target;
+ n[2].i = start;
+ n[3].i = count;
+ n[4].e = format;
+ n[5].e = type;
+ n[6].data = image;
+ }
+ else if (image) {
+ _mesa_free(image);
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_ColorSubTable(ctx->Exec,
+ (target, start, count, format, type, table));
+ }
+}
+
+
+static void GLAPIENTRY
+save_CopyColorSubTable(GLenum target, GLsizei start,
+ GLint x, GLint y, GLsizei width)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_COPY_COLOR_SUB_TABLE, 5);
+ if (n) {
+ n[1].e = target;
+ n[2].i = start;
+ n[3].i = x;
+ n[4].i = y;
+ n[5].i = width;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_CopyColorSubTable(ctx->Exec, (target, start, x, y, width));
+ }
+}
+
+
+static void GLAPIENTRY
+save_CopyColorTable(GLenum target, GLenum internalformat,
+ GLint x, GLint y, GLsizei width)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_COPY_COLOR_TABLE, 5);
+ if (n) {
+ n[1].e = target;
+ n[2].e = internalformat;
+ n[3].i = x;
+ n[4].i = y;
+ n[5].i = width;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_CopyColorTable(ctx->Exec, (target, internalformat, x, y, width));
+ }
+}
+
+
+static void GLAPIENTRY
+save_ConvolutionFilter1D(GLenum target, GLenum internalFormat, GLsizei width,
+ GLenum format, GLenum type, const GLvoid * filter)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLvoid *image = unpack_image(1, width, 1, 1, format, type, filter,
+ &ctx->Unpack);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_CONVOLUTION_FILTER_1D, 6);
+ if (n) {
+ n[1].e = target;
+ n[2].e = internalFormat;
+ n[3].i = width;
+ n[4].e = format;
+ n[5].e = type;
+ n[6].data = image;
+ }
+ else if (image) {
+ _mesa_free(image);
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_ConvolutionFilter1D(ctx->Exec, (target, internalFormat, width,
+ format, type, filter));
+ }
+}
+
+
+static void GLAPIENTRY
+save_ConvolutionFilter2D(GLenum target, GLenum internalFormat,
+ GLsizei width, GLsizei height, GLenum format,
+ GLenum type, const GLvoid * filter)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLvoid *image = unpack_image(2, width, height, 1, format, type, filter,
+ &ctx->Unpack);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_CONVOLUTION_FILTER_2D, 7);
+ if (n) {
+ n[1].e = target;
+ n[2].e = internalFormat;
+ n[3].i = width;
+ n[4].i = height;
+ n[5].e = format;
+ n[6].e = type;
+ n[7].data = image;
+ }
+ else if (image) {
+ _mesa_free(image);
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_ConvolutionFilter2D(ctx->Exec,
+ (target, internalFormat, width, height, format,
+ type, filter));
+ }
+}
+
+
+static void GLAPIENTRY
+save_ConvolutionParameteri(GLenum target, GLenum pname, GLint param)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_CONVOLUTION_PARAMETER_I, 3);
+ if (n) {
+ n[1].e = target;
+ n[2].e = pname;
+ n[3].i = param;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_ConvolutionParameteri(ctx->Exec, (target, pname, param));
+ }
+}
+
+
+static void GLAPIENTRY
+save_ConvolutionParameteriv(GLenum target, GLenum pname, const GLint *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_CONVOLUTION_PARAMETER_IV, 6);
+ if (n) {
+ n[1].e = target;
+ n[2].e = pname;
+ n[3].i = params[0];
+ if (pname == GL_CONVOLUTION_BORDER_COLOR ||
+ pname == GL_CONVOLUTION_FILTER_SCALE ||
+ pname == GL_CONVOLUTION_FILTER_BIAS) {
+ n[4].i = params[1];
+ n[5].i = params[2];
+ n[6].i = params[3];
+ }
+ else {
+ n[4].i = n[5].i = n[6].i = 0;
+ }
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_ConvolutionParameteriv(ctx->Exec, (target, pname, params));
+ }
+}
+
+
+static void GLAPIENTRY
+save_ConvolutionParameterf(GLenum target, GLenum pname, GLfloat param)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_CONVOLUTION_PARAMETER_F, 3);
+ if (n) {
+ n[1].e = target;
+ n[2].e = pname;
+ n[3].f = param;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_ConvolutionParameterf(ctx->Exec, (target, pname, param));
+ }
+}
+
+
+static void GLAPIENTRY
+save_ConvolutionParameterfv(GLenum target, GLenum pname,
+ const GLfloat *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_CONVOLUTION_PARAMETER_FV, 6);
+ if (n) {
+ n[1].e = target;
+ n[2].e = pname;
+ n[3].f = params[0];
+ if (pname == GL_CONVOLUTION_BORDER_COLOR ||
+ pname == GL_CONVOLUTION_FILTER_SCALE ||
+ pname == GL_CONVOLUTION_FILTER_BIAS) {
+ n[4].f = params[1];
+ n[5].f = params[2];
+ n[6].f = params[3];
+ }
+ else {
+ n[4].f = n[5].f = n[6].f = 0.0F;
+ }
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_ConvolutionParameterfv(ctx->Exec, (target, pname, params));
+ }
+}
+
+
+static void GLAPIENTRY
+save_CopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_COPY_PIXELS, 5);
+ if (n) {
+ n[1].i = x;
+ n[2].i = y;
+ n[3].i = (GLint) width;
+ n[4].i = (GLint) height;
+ n[5].e = type;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_CopyPixels(ctx->Exec, (x, y, width, height, type));
+ }
+}
+
+
+
+static void GLAPIENTRY
+save_CopyTexImage1D(GLenum target, GLint level, GLenum internalformat,
+ GLint x, GLint y, GLsizei width, GLint border)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_COPY_TEX_IMAGE1D, 7);
+ if (n) {
+ n[1].e = target;
+ n[2].i = level;
+ n[3].e = internalformat;
+ n[4].i = x;
+ n[5].i = y;
+ n[6].i = width;
+ n[7].i = border;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_CopyTexImage1D(ctx->Exec, (target, level, internalformat,
+ x, y, width, border));
+ }
+}
+
+
+static void GLAPIENTRY
+save_CopyTexImage2D(GLenum target, GLint level,
+ GLenum internalformat,
+ GLint x, GLint y, GLsizei width,
+ GLsizei height, GLint border)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_COPY_TEX_IMAGE2D, 8);
+ if (n) {
+ n[1].e = target;
+ n[2].i = level;
+ n[3].e = internalformat;
+ n[4].i = x;
+ n[5].i = y;
+ n[6].i = width;
+ n[7].i = height;
+ n[8].i = border;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_CopyTexImage2D(ctx->Exec, (target, level, internalformat,
+ x, y, width, height, border));
+ }
+}
+
+
+
+static void GLAPIENTRY
+save_CopyTexSubImage1D(GLenum target, GLint level,
+ GLint xoffset, GLint x, GLint y, GLsizei width)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_COPY_TEX_SUB_IMAGE1D, 6);
+ if (n) {
+ n[1].e = target;
+ n[2].i = level;
+ n[3].i = xoffset;
+ n[4].i = x;
+ n[5].i = y;
+ n[6].i = width;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_CopyTexSubImage1D(ctx->Exec,
+ (target, level, xoffset, x, y, width));
+ }
+}
+
+
+static void GLAPIENTRY
+save_CopyTexSubImage2D(GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLint x, GLint y, GLsizei width, GLint height)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_COPY_TEX_SUB_IMAGE2D, 8);
+ if (n) {
+ n[1].e = target;
+ n[2].i = level;
+ n[3].i = xoffset;
+ n[4].i = yoffset;
+ n[5].i = x;
+ n[6].i = y;
+ n[7].i = width;
+ n[8].i = height;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_CopyTexSubImage2D(ctx->Exec, (target, level, xoffset, yoffset,
+ x, y, width, height));
+ }
+}
+
+
+static void GLAPIENTRY
+save_CopyTexSubImage3D(GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLint x, GLint y, GLsizei width, GLint height)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_COPY_TEX_SUB_IMAGE3D, 9);
+ if (n) {
+ n[1].e = target;
+ n[2].i = level;
+ n[3].i = xoffset;
+ n[4].i = yoffset;
+ n[5].i = zoffset;
+ n[6].i = x;
+ n[7].i = y;
+ n[8].i = width;
+ n[9].i = height;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_CopyTexSubImage3D(ctx->Exec, (target, level,
+ xoffset, yoffset, zoffset,
+ x, y, width, height));
+ }
+}
+
+
+static void GLAPIENTRY
+save_CullFace(GLenum mode)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_CULL_FACE, 1);
+ if (n) {
+ n[1].e = mode;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_CullFace(ctx->Exec, (mode));
+ }
+}
+
+
+static void GLAPIENTRY
+save_DepthFunc(GLenum func)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_DEPTH_FUNC, 1);
+ if (n) {
+ n[1].e = func;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_DepthFunc(ctx->Exec, (func));
+ }
+}
+
+
+static void GLAPIENTRY
+save_DepthMask(GLboolean mask)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_DEPTH_MASK, 1);
+ if (n) {
+ n[1].b = mask;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_DepthMask(ctx->Exec, (mask));
+ }
+}
+
+
+static void GLAPIENTRY
+save_DepthRange(GLclampd nearval, GLclampd farval)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_DEPTH_RANGE, 2);
+ if (n) {
+ n[1].f = (GLfloat) nearval;
+ n[2].f = (GLfloat) farval;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_DepthRange(ctx->Exec, (nearval, farval));
+ }
+}
+
+
+static void GLAPIENTRY
+save_Disable(GLenum cap)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_DISABLE, 1);
+ if (n) {
+ n[1].e = cap;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_Disable(ctx->Exec, (cap));
+ }
+}
+
+
+static void GLAPIENTRY
+save_DrawBuffer(GLenum mode)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_DRAW_BUFFER, 1);
+ if (n) {
+ n[1].e = mode;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_DrawBuffer(ctx->Exec, (mode));
+ }
+}
+
+
+static void GLAPIENTRY
+save_DrawPixels(GLsizei width, GLsizei height,
+ GLenum format, GLenum type, const GLvoid * pixels)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLvoid *image = unpack_image(2, width, height, 1, format, type,
+ pixels, &ctx->Unpack);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_DRAW_PIXELS, 5);
+ if (n) {
+ n[1].i = width;
+ n[2].i = height;
+ n[3].e = format;
+ n[4].e = type;
+ n[5].data = image;
+ }
+ else if (image) {
+ _mesa_free(image);
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_DrawPixels(ctx->Exec, (width, height, format, type, pixels));
+ }
+}
+
+
+
+static void GLAPIENTRY
+save_Enable(GLenum cap)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_ENABLE, 1);
+ if (n) {
+ n[1].e = cap;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_Enable(ctx->Exec, (cap));
+ }
+}
+
+
+
+static void GLAPIENTRY
+_mesa_save_EvalMesh1(GLenum mode, GLint i1, GLint i2)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_EVALMESH1, 3);
+ if (n) {
+ n[1].e = mode;
+ n[2].i = i1;
+ n[3].i = i2;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_EvalMesh1(ctx->Exec, (mode, i1, i2));
+ }
+}
+
+
+static void GLAPIENTRY
+_mesa_save_EvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_EVALMESH2, 5);
+ if (n) {
+ n[1].e = mode;
+ n[2].i = i1;
+ n[3].i = i2;
+ n[4].i = j1;
+ n[5].i = j2;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_EvalMesh2(ctx->Exec, (mode, i1, i2, j1, j2));
+ }
+}
+
+
+
+
+static void GLAPIENTRY
+save_Fogfv(GLenum pname, const GLfloat *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_FOG, 5);
+ if (n) {
+ n[1].e = pname;
+ n[2].f = params[0];
+ n[3].f = params[1];
+ n[4].f = params[2];
+ n[5].f = params[3];
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_Fogfv(ctx->Exec, (pname, params));
+ }
+}
+
+
+static void GLAPIENTRY
+save_Fogf(GLenum pname, GLfloat param)
+{
+ save_Fogfv(pname, &param);
+}
+
+
+static void GLAPIENTRY
+save_Fogiv(GLenum pname, const GLint *params)
+{
+ GLfloat p[4];
+ switch (pname) {
+ case GL_FOG_MODE:
+ case GL_FOG_DENSITY:
+ case GL_FOG_START:
+ case GL_FOG_END:
+ case GL_FOG_INDEX:
+ p[0] = (GLfloat) *params;
+ break;
+ case GL_FOG_COLOR:
+ p[0] = INT_TO_FLOAT(params[0]);
+ p[1] = INT_TO_FLOAT(params[1]);
+ p[2] = INT_TO_FLOAT(params[2]);
+ p[3] = INT_TO_FLOAT(params[3]);
+ break;
+ default:
+ /* Error will be caught later in gl_Fogfv */
+ ;
+ }
+ save_Fogfv(pname, p);
+}
+
+
+static void GLAPIENTRY
+save_Fogi(GLenum pname, GLint param)
+{
+ save_Fogiv(pname, &param);
+}
+
+
+static void GLAPIENTRY
+save_FrontFace(GLenum mode)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_FRONT_FACE, 1);
+ if (n) {
+ n[1].e = mode;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_FrontFace(ctx->Exec, (mode));
+ }
+}
+
+
+static void GLAPIENTRY
+save_Frustum(GLdouble left, GLdouble right,
+ GLdouble bottom, GLdouble top, GLdouble nearval, GLdouble farval)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_FRUSTUM, 6);
+ if (n) {
+ n[1].f = (GLfloat) left;
+ n[2].f = (GLfloat) right;
+ n[3].f = (GLfloat) bottom;
+ n[4].f = (GLfloat) top;
+ n[5].f = (GLfloat) nearval;
+ n[6].f = (GLfloat) farval;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_Frustum(ctx->Exec, (left, right, bottom, top, nearval, farval));
+ }
+}
+
+
+static void GLAPIENTRY
+save_Hint(GLenum target, GLenum mode)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_HINT, 2);
+ if (n) {
+ n[1].e = target;
+ n[2].e = mode;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_Hint(ctx->Exec, (target, mode));
+ }
+}
+
+
+static void GLAPIENTRY
+save_Histogram(GLenum target, GLsizei width, GLenum internalFormat,
+ GLboolean sink)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_HISTOGRAM, 4);
+ if (n) {
+ n[1].e = target;
+ n[2].i = width;
+ n[3].e = internalFormat;
+ n[4].b = sink;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_Histogram(ctx->Exec, (target, width, internalFormat, sink));
+ }
+}
+
+
+static void GLAPIENTRY
+save_IndexMask(GLuint mask)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_INDEX_MASK, 1);
+ if (n) {
+ n[1].ui = mask;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_IndexMask(ctx->Exec, (mask));
+ }
+}
+
+
+static void GLAPIENTRY
+save_InitNames(void)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ (void) ALLOC_INSTRUCTION(ctx, OPCODE_INIT_NAMES, 0);
+ if (ctx->ExecuteFlag) {
+ CALL_InitNames(ctx->Exec, ());
+ }
+}
+
+
+static void GLAPIENTRY
+save_Lightfv(GLenum light, GLenum pname, const GLfloat *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_LIGHT, 6);
+ if (OPCODE_LIGHT) {
+ GLint i, nParams;
+ n[1].e = light;
+ n[2].e = pname;
+ switch (pname) {
+ case GL_AMBIENT:
+ nParams = 4;
+ break;
+ case GL_DIFFUSE:
+ nParams = 4;
+ break;
+ case GL_SPECULAR:
+ nParams = 4;
+ break;
+ case GL_POSITION:
+ nParams = 4;
+ break;
+ case GL_SPOT_DIRECTION:
+ nParams = 3;
+ break;
+ case GL_SPOT_EXPONENT:
+ nParams = 1;
+ break;
+ case GL_SPOT_CUTOFF:
+ nParams = 1;
+ break;
+ case GL_CONSTANT_ATTENUATION:
+ nParams = 1;
+ break;
+ case GL_LINEAR_ATTENUATION:
+ nParams = 1;
+ break;
+ case GL_QUADRATIC_ATTENUATION:
+ nParams = 1;
+ break;
+ default:
+ nParams = 0;
+ }
+ for (i = 0; i < nParams; i++) {
+ n[3 + i].f = params[i];
+ }
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_Lightfv(ctx->Exec, (light, pname, params));
+ }
+}
+
+
+static void GLAPIENTRY
+save_Lightf(GLenum light, GLenum pname, GLfloat params)
+{
+ save_Lightfv(light, pname, &params);
+}
+
+
+static void GLAPIENTRY
+save_Lightiv(GLenum light, GLenum pname, const GLint *params)
+{
+ GLfloat fparam[4];
+ switch (pname) {
+ case GL_AMBIENT:
+ case GL_DIFFUSE:
+ case GL_SPECULAR:
+ fparam[0] = INT_TO_FLOAT(params[0]);
+ fparam[1] = INT_TO_FLOAT(params[1]);
+ fparam[2] = INT_TO_FLOAT(params[2]);
+ fparam[3] = INT_TO_FLOAT(params[3]);
+ break;
+ case GL_POSITION:
+ fparam[0] = (GLfloat) params[0];
+ fparam[1] = (GLfloat) params[1];
+ fparam[2] = (GLfloat) params[2];
+ fparam[3] = (GLfloat) params[3];
+ break;
+ case GL_SPOT_DIRECTION:
+ fparam[0] = (GLfloat) params[0];
+ fparam[1] = (GLfloat) params[1];
+ fparam[2] = (GLfloat) params[2];
+ break;
+ case GL_SPOT_EXPONENT:
+ case GL_SPOT_CUTOFF:
+ case GL_CONSTANT_ATTENUATION:
+ case GL_LINEAR_ATTENUATION:
+ case GL_QUADRATIC_ATTENUATION:
+ fparam[0] = (GLfloat) params[0];
+ break;
+ default:
+ /* error will be caught later in gl_Lightfv */
+ ;
+ }
+ save_Lightfv(light, pname, fparam);
+}
+
+
+static void GLAPIENTRY
+save_Lighti(GLenum light, GLenum pname, GLint param)
+{
+ save_Lightiv(light, pname, &param);
+}
+
+
+static void GLAPIENTRY
+save_LightModelfv(GLenum pname, const GLfloat *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_LIGHT_MODEL, 5);
+ if (n) {
+ n[1].e = pname;
+ n[2].f = params[0];
+ n[3].f = params[1];
+ n[4].f = params[2];
+ n[5].f = params[3];
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_LightModelfv(ctx->Exec, (pname, params));
+ }
+}
+
+
+static void GLAPIENTRY
+save_LightModelf(GLenum pname, GLfloat param)
+{
+ save_LightModelfv(pname, &param);
+}
+
+
+static void GLAPIENTRY
+save_LightModeliv(GLenum pname, const GLint *params)
+{
+ GLfloat fparam[4];
+ switch (pname) {
+ case GL_LIGHT_MODEL_AMBIENT:
+ fparam[0] = INT_TO_FLOAT(params[0]);
+ fparam[1] = INT_TO_FLOAT(params[1]);
+ fparam[2] = INT_TO_FLOAT(params[2]);
+ fparam[3] = INT_TO_FLOAT(params[3]);
+ break;
+ case GL_LIGHT_MODEL_LOCAL_VIEWER:
+ case GL_LIGHT_MODEL_TWO_SIDE:
+ case GL_LIGHT_MODEL_COLOR_CONTROL:
+ fparam[0] = (GLfloat) params[0];
+ break;
+ default:
+ /* Error will be caught later in gl_LightModelfv */
+ ;
+ }
+ save_LightModelfv(pname, fparam);
+}
+
+
+static void GLAPIENTRY
+save_LightModeli(GLenum pname, GLint param)
+{
+ save_LightModeliv(pname, &param);
+}
+
+
+static void GLAPIENTRY
+save_LineStipple(GLint factor, GLushort pattern)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_LINE_STIPPLE, 2);
+ if (n) {
+ n[1].i = factor;
+ n[2].us = pattern;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_LineStipple(ctx->Exec, (factor, pattern));
+ }
+}
+
+
+static void GLAPIENTRY
+save_LineWidth(GLfloat width)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_LINE_WIDTH, 1);
+ if (n) {
+ n[1].f = width;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_LineWidth(ctx->Exec, (width));
+ }
+}
+
+
+static void GLAPIENTRY
+save_ListBase(GLuint base)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_LIST_BASE, 1);
+ if (n) {
+ n[1].ui = base;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_ListBase(ctx->Exec, (base));
+ }
+}
+
+
+static void GLAPIENTRY
+save_LoadIdentity(void)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ (void) ALLOC_INSTRUCTION(ctx, OPCODE_LOAD_IDENTITY, 0);
+ if (ctx->ExecuteFlag) {
+ CALL_LoadIdentity(ctx->Exec, ());
+ }
+}
+
+
+static void GLAPIENTRY
+save_LoadMatrixf(const GLfloat * m)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_LOAD_MATRIX, 16);
+ if (n) {
+ GLuint i;
+ for (i = 0; i < 16; i++) {
+ n[1 + i].f = m[i];
+ }
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_LoadMatrixf(ctx->Exec, (m));
+ }
+}
+
+
+static void GLAPIENTRY
+save_LoadMatrixd(const GLdouble * m)
+{
+ GLfloat f[16];
+ GLint i;
+ for (i = 0; i < 16; i++) {
+ f[i] = (GLfloat) m[i];
+ }
+ save_LoadMatrixf(f);
+}
+
+
+static void GLAPIENTRY
+save_LoadName(GLuint name)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_LOAD_NAME, 1);
+ if (n) {
+ n[1].ui = name;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_LoadName(ctx->Exec, (name));
+ }
+}
+
+
+static void GLAPIENTRY
+save_LogicOp(GLenum opcode)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_LOGIC_OP, 1);
+ if (n) {
+ n[1].e = opcode;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_LogicOp(ctx->Exec, (opcode));
+ }
+}
+
+
+static void GLAPIENTRY
+save_Map1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride,
+ GLint order, const GLdouble * points)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_MAP1, 6);
+ if (n) {
+ GLfloat *pnts = _mesa_copy_map_points1d(target, stride, order, points);
+ n[1].e = target;
+ n[2].f = (GLfloat) u1;
+ n[3].f = (GLfloat) u2;
+ n[4].i = _mesa_evaluator_components(target); /* stride */
+ n[5].i = order;
+ n[6].data = (void *) pnts;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_Map1d(ctx->Exec, (target, u1, u2, stride, order, points));
+ }
+}
+
+static void GLAPIENTRY
+save_Map1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride,
+ GLint order, const GLfloat * points)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_MAP1, 6);
+ if (n) {
+ GLfloat *pnts = _mesa_copy_map_points1f(target, stride, order, points);
+ n[1].e = target;
+ n[2].f = u1;
+ n[3].f = u2;
+ n[4].i = _mesa_evaluator_components(target); /* stride */
+ n[5].i = order;
+ n[6].data = (void *) pnts;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_Map1f(ctx->Exec, (target, u1, u2, stride, order, points));
+ }
+}
+
+
+static void GLAPIENTRY
+save_Map2d(GLenum target,
+ GLdouble u1, GLdouble u2, GLint ustride, GLint uorder,
+ GLdouble v1, GLdouble v2, GLint vstride, GLint vorder,
+ const GLdouble * points)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_MAP2, 10);
+ if (n) {
+ GLfloat *pnts = _mesa_copy_map_points2d(target, ustride, uorder,
+ vstride, vorder, points);
+ n[1].e = target;
+ n[2].f = (GLfloat) u1;
+ n[3].f = (GLfloat) u2;
+ n[4].f = (GLfloat) v1;
+ n[5].f = (GLfloat) v2;
+ /* XXX verify these strides are correct */
+ n[6].i = _mesa_evaluator_components(target) * vorder; /*ustride */
+ n[7].i = _mesa_evaluator_components(target); /*vstride */
+ n[8].i = uorder;
+ n[9].i = vorder;
+ n[10].data = (void *) pnts;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_Map2d(ctx->Exec, (target,
+ u1, u2, ustride, uorder,
+ v1, v2, vstride, vorder, points));
+ }
+}
+
+
+static void GLAPIENTRY
+save_Map2f(GLenum target,
+ GLfloat u1, GLfloat u2, GLint ustride, GLint uorder,
+ GLfloat v1, GLfloat v2, GLint vstride, GLint vorder,
+ const GLfloat * points)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_MAP2, 10);
+ if (n) {
+ GLfloat *pnts = _mesa_copy_map_points2f(target, ustride, uorder,
+ vstride, vorder, points);
+ n[1].e = target;
+ n[2].f = u1;
+ n[3].f = u2;
+ n[4].f = v1;
+ n[5].f = v2;
+ /* XXX verify these strides are correct */
+ n[6].i = _mesa_evaluator_components(target) * vorder; /*ustride */
+ n[7].i = _mesa_evaluator_components(target); /*vstride */
+ n[8].i = uorder;
+ n[9].i = vorder;
+ n[10].data = (void *) pnts;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_Map2f(ctx->Exec, (target, u1, u2, ustride, uorder,
+ v1, v2, vstride, vorder, points));
+ }
+}
+
+
+static void GLAPIENTRY
+save_MapGrid1f(GLint un, GLfloat u1, GLfloat u2)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_MAPGRID1, 3);
+ if (n) {
+ n[1].i = un;
+ n[2].f = u1;
+ n[3].f = u2;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_MapGrid1f(ctx->Exec, (un, u1, u2));
+ }
+}
+
+
+static void GLAPIENTRY
+save_MapGrid1d(GLint un, GLdouble u1, GLdouble u2)
+{
+ save_MapGrid1f(un, (GLfloat) u1, (GLfloat) u2);
+}
+
+
+static void GLAPIENTRY
+save_MapGrid2f(GLint un, GLfloat u1, GLfloat u2,
+ GLint vn, GLfloat v1, GLfloat v2)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_MAPGRID2, 6);
+ if (n) {
+ n[1].i = un;
+ n[2].f = u1;
+ n[3].f = u2;
+ n[4].i = vn;
+ n[5].f = v1;
+ n[6].f = v2;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_MapGrid2f(ctx->Exec, (un, u1, u2, vn, v1, v2));
+ }
+}
+
+
+
+static void GLAPIENTRY
+save_MapGrid2d(GLint un, GLdouble u1, GLdouble u2,
+ GLint vn, GLdouble v1, GLdouble v2)
+{
+ save_MapGrid2f(un, (GLfloat) u1, (GLfloat) u2,
+ vn, (GLfloat) v1, (GLfloat) v2);
+}
+
+
+static void GLAPIENTRY
+save_MatrixMode(GLenum mode)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_MATRIX_MODE, 1);
+ if (n) {
+ n[1].e = mode;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_MatrixMode(ctx->Exec, (mode));
+ }
+}
+
+
+static void GLAPIENTRY
+save_Minmax(GLenum target, GLenum internalFormat, GLboolean sink)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_MIN_MAX, 3);
+ if (n) {
+ n[1].e = target;
+ n[2].e = internalFormat;
+ n[3].b = sink;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_Minmax(ctx->Exec, (target, internalFormat, sink));
+ }
+}
+
+
+static void GLAPIENTRY
+save_MultMatrixf(const GLfloat * m)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_MULT_MATRIX, 16);
+ if (n) {
+ GLuint i;
+ for (i = 0; i < 16; i++) {
+ n[1 + i].f = m[i];
+ }
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_MultMatrixf(ctx->Exec, (m));
+ }
+}
+
+
+static void GLAPIENTRY
+save_MultMatrixd(const GLdouble * m)
+{
+ GLfloat f[16];
+ GLint i;
+ for (i = 0; i < 16; i++) {
+ f[i] = (GLfloat) m[i];
+ }
+ save_MultMatrixf(f);
+}
+
+
+static void GLAPIENTRY
+save_NewList(GLuint list, GLenum mode)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ /* It's an error to call this function while building a display list */
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glNewList");
+ (void) list;
+ (void) mode;
+}
+
+
+
+static void GLAPIENTRY
+save_Ortho(GLdouble left, GLdouble right,
+ GLdouble bottom, GLdouble top, GLdouble nearval, GLdouble farval)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_ORTHO, 6);
+ if (n) {
+ n[1].f = (GLfloat) left;
+ n[2].f = (GLfloat) right;
+ n[3].f = (GLfloat) bottom;
+ n[4].f = (GLfloat) top;
+ n[5].f = (GLfloat) nearval;
+ n[6].f = (GLfloat) farval;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_Ortho(ctx->Exec, (left, right, bottom, top, nearval, farval));
+ }
+}
+
+
+static void GLAPIENTRY
+save_PixelMapfv(GLenum map, GLint mapsize, const GLfloat *values)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_PIXEL_MAP, 3);
+ if (n) {
+ n[1].e = map;
+ n[2].i = mapsize;
+ n[3].data = (void *) _mesa_malloc(mapsize * sizeof(GLfloat));
+ MEMCPY(n[3].data, (void *) values, mapsize * sizeof(GLfloat));
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_PixelMapfv(ctx->Exec, (map, mapsize, values));
+ }
+}
+
+
+static void GLAPIENTRY
+save_PixelMapuiv(GLenum map, GLint mapsize, const GLuint *values)
+{
+ GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
+ GLint i;
+ if (map == GL_PIXEL_MAP_I_TO_I || map == GL_PIXEL_MAP_S_TO_S) {
+ for (i = 0; i < mapsize; i++) {
+ fvalues[i] = (GLfloat) values[i];
+ }
+ }
+ else {
+ for (i = 0; i < mapsize; i++) {
+ fvalues[i] = UINT_TO_FLOAT(values[i]);
+ }
+ }
+ save_PixelMapfv(map, mapsize, fvalues);
+}
+
+
+static void GLAPIENTRY
+save_PixelMapusv(GLenum map, GLint mapsize, const GLushort *values)
+{
+ GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
+ GLint i;
+ if (map == GL_PIXEL_MAP_I_TO_I || map == GL_PIXEL_MAP_S_TO_S) {
+ for (i = 0; i < mapsize; i++) {
+ fvalues[i] = (GLfloat) values[i];
+ }
+ }
+ else {
+ for (i = 0; i < mapsize; i++) {
+ fvalues[i] = USHORT_TO_FLOAT(values[i]);
+ }
+ }
+ save_PixelMapfv(map, mapsize, fvalues);
+}
+
+
+static void GLAPIENTRY
+save_PixelTransferf(GLenum pname, GLfloat param)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_PIXEL_TRANSFER, 2);
+ if (n) {
+ n[1].e = pname;
+ n[2].f = param;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_PixelTransferf(ctx->Exec, (pname, param));
+ }
+}
+
+
+static void GLAPIENTRY
+save_PixelTransferi(GLenum pname, GLint param)
+{
+ save_PixelTransferf(pname, (GLfloat) param);
+}
+
+
+static void GLAPIENTRY
+save_PixelZoom(GLfloat xfactor, GLfloat yfactor)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_PIXEL_ZOOM, 2);
+ if (n) {
+ n[1].f = xfactor;
+ n[2].f = yfactor;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_PixelZoom(ctx->Exec, (xfactor, yfactor));
+ }
+}
+
+
+static void GLAPIENTRY
+save_PointParameterfvEXT(GLenum pname, const GLfloat *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_POINT_PARAMETERS, 4);
+ if (n) {
+ n[1].e = pname;
+ n[2].f = params[0];
+ n[3].f = params[1];
+ n[4].f = params[2];
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_PointParameterfvEXT(ctx->Exec, (pname, params));
+ }
+}
+
+
+static void GLAPIENTRY
+save_PointParameterfEXT(GLenum pname, GLfloat param)
+{
+ save_PointParameterfvEXT(pname, &param);
+}
+
+static void GLAPIENTRY
+save_PointParameteriNV(GLenum pname, GLint param)
+{
+ GLfloat p = (GLfloat) param;
+ save_PointParameterfvEXT(pname, &p);
+}
+
+static void GLAPIENTRY
+save_PointParameterivNV(GLenum pname, const GLint * param)
+{
+ GLfloat p = (GLfloat) param[0];
+ save_PointParameterfvEXT(pname, &p);
+}
+
+
+static void GLAPIENTRY
+save_PointSize(GLfloat size)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_POINT_SIZE, 1);
+ if (n) {
+ n[1].f = size;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_PointSize(ctx->Exec, (size));
+ }
+}
+
+
+static void GLAPIENTRY
+save_PolygonMode(GLenum face, GLenum mode)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_POLYGON_MODE, 2);
+ if (n) {
+ n[1].e = face;
+ n[2].e = mode;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_PolygonMode(ctx->Exec, (face, mode));
+ }
+}
+
+
+/*
+ * Polygon stipple must have been upacked already!
+ */
+static void GLAPIENTRY
+save_PolygonStipple(const GLubyte * pattern)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_POLYGON_STIPPLE, 1);
+ if (n) {
+ void *data;
+ n[1].data = _mesa_malloc(32 * 4);
+ data = n[1].data; /* This needed for Acorn compiler */
+ MEMCPY(data, pattern, 32 * 4);
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_PolygonStipple(ctx->Exec, ((GLubyte *) pattern));
+ }
+}
+
+
+static void GLAPIENTRY
+save_PolygonOffset(GLfloat factor, GLfloat units)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_POLYGON_OFFSET, 2);
+ if (n) {
+ n[1].f = factor;
+ n[2].f = units;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_PolygonOffset(ctx->Exec, (factor, units));
+ }
+}
+
+
+static void GLAPIENTRY
+save_PolygonOffsetEXT(GLfloat factor, GLfloat bias)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ /* XXX mult by DepthMaxF here??? */
+ save_PolygonOffset(factor, ctx->DrawBuffer->_DepthMaxF * bias);
+}
+
+
+static void GLAPIENTRY
+save_PopAttrib(void)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ (void) ALLOC_INSTRUCTION(ctx, OPCODE_POP_ATTRIB, 0);
+ if (ctx->ExecuteFlag) {
+ CALL_PopAttrib(ctx->Exec, ());
+ }
+}
+
+
+static void GLAPIENTRY
+save_PopMatrix(void)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ (void) ALLOC_INSTRUCTION(ctx, OPCODE_POP_MATRIX, 0);
+ if (ctx->ExecuteFlag) {
+ CALL_PopMatrix(ctx->Exec, ());
+ }
+}
+
+
+static void GLAPIENTRY
+save_PopName(void)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ (void) ALLOC_INSTRUCTION(ctx, OPCODE_POP_NAME, 0);
+ if (ctx->ExecuteFlag) {
+ CALL_PopName(ctx->Exec, ());
+ }
+}
+
+
+static void GLAPIENTRY
+save_PrioritizeTextures(GLsizei num, const GLuint * textures,
+ const GLclampf * priorities)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint i;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
+ for (i = 0; i < num; i++) {
+ Node *n;
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_PRIORITIZE_TEXTURE, 2);
+ if (n) {
+ n[1].ui = textures[i];
+ n[2].f = priorities[i];
+ }
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_PrioritizeTextures(ctx->Exec, (num, textures, priorities));
+ }
+}
+
+
+static void GLAPIENTRY
+save_PushAttrib(GLbitfield mask)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_PUSH_ATTRIB, 1);
+ if (n) {
+ n[1].bf = mask;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_PushAttrib(ctx->Exec, (mask));
+ }
+}
+
+
+static void GLAPIENTRY
+save_PushMatrix(void)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ (void) ALLOC_INSTRUCTION(ctx, OPCODE_PUSH_MATRIX, 0);
+ if (ctx->ExecuteFlag) {
+ CALL_PushMatrix(ctx->Exec, ());
+ }
+}
+
+
+static void GLAPIENTRY
+save_PushName(GLuint name)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_PUSH_NAME, 1);
+ if (n) {
+ n[1].ui = name;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_PushName(ctx->Exec, (name));
+ }
+}
+
+
+static void GLAPIENTRY
+save_RasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_RASTER_POS, 4);
+ if (n) {
+ n[1].f = x;
+ n[2].f = y;
+ n[3].f = z;
+ n[4].f = w;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_RasterPos4f(ctx->Exec, (x, y, z, w));
+ }
+}
+
+static void GLAPIENTRY
+save_RasterPos2d(GLdouble x, GLdouble y)
+{
+ save_RasterPos4f((GLfloat) x, (GLfloat) y, 0.0F, 1.0F);
+}
+
+static void GLAPIENTRY
+save_RasterPos2f(GLfloat x, GLfloat y)
+{
+ save_RasterPos4f(x, y, 0.0F, 1.0F);
+}
+
+static void GLAPIENTRY
+save_RasterPos2i(GLint x, GLint y)
+{
+ save_RasterPos4f((GLfloat) x, (GLfloat) y, 0.0F, 1.0F);
+}
+
+static void GLAPIENTRY
+save_RasterPos2s(GLshort x, GLshort y)
+{
+ save_RasterPos4f(x, y, 0.0F, 1.0F);
+}
+
+static void GLAPIENTRY
+save_RasterPos3d(GLdouble x, GLdouble y, GLdouble z)
+{
+ save_RasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F);
+}
+
+static void GLAPIENTRY
+save_RasterPos3f(GLfloat x, GLfloat y, GLfloat z)
+{
+ save_RasterPos4f(x, y, z, 1.0F);
+}
+
+static void GLAPIENTRY
+save_RasterPos3i(GLint x, GLint y, GLint z)
+{
+ save_RasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F);
+}
+
+static void GLAPIENTRY
+save_RasterPos3s(GLshort x, GLshort y, GLshort z)
+{
+ save_RasterPos4f(x, y, z, 1.0F);
+}
+
+static void GLAPIENTRY
+save_RasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
+{
+ save_RasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
+}
+
+static void GLAPIENTRY
+save_RasterPos4i(GLint x, GLint y, GLint z, GLint w)
+{
+ save_RasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
+}
+
+static void GLAPIENTRY
+save_RasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w)
+{
+ save_RasterPos4f(x, y, z, w);
+}
+
+static void GLAPIENTRY
+save_RasterPos2dv(const GLdouble * v)
+{
+ save_RasterPos4f((GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F);
+}
+
+static void GLAPIENTRY
+save_RasterPos2fv(const GLfloat * v)
+{
+ save_RasterPos4f(v[0], v[1], 0.0F, 1.0F);
+}
+
+static void GLAPIENTRY
+save_RasterPos2iv(const GLint * v)
+{
+ save_RasterPos4f((GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F);
+}
+
+static void GLAPIENTRY
+save_RasterPos2sv(const GLshort * v)
+{
+ save_RasterPos4f(v[0], v[1], 0.0F, 1.0F);
+}
+
+static void GLAPIENTRY
+save_RasterPos3dv(const GLdouble * v)
+{
+ save_RasterPos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F);
+}
+
+static void GLAPIENTRY
+save_RasterPos3fv(const GLfloat * v)
+{
+ save_RasterPos4f(v[0], v[1], v[2], 1.0F);
+}
+
+static void GLAPIENTRY
+save_RasterPos3iv(const GLint * v)
+{
+ save_RasterPos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F);
+}
+
+static void GLAPIENTRY
+save_RasterPos3sv(const GLshort * v)
+{
+ save_RasterPos4f(v[0], v[1], v[2], 1.0F);
+}
+
+static void GLAPIENTRY
+save_RasterPos4dv(const GLdouble * v)
+{
+ save_RasterPos4f((GLfloat) v[0], (GLfloat) v[1],
+ (GLfloat) v[2], (GLfloat) v[3]);
+}
+
+static void GLAPIENTRY
+save_RasterPos4fv(const GLfloat * v)
+{
+ save_RasterPos4f(v[0], v[1], v[2], v[3]);
+}
+
+static void GLAPIENTRY
+save_RasterPos4iv(const GLint * v)
+{
+ save_RasterPos4f((GLfloat) v[0], (GLfloat) v[1],
+ (GLfloat) v[2], (GLfloat) v[3]);
+}
+
+static void GLAPIENTRY
+save_RasterPos4sv(const GLshort * v)
+{
+ save_RasterPos4f(v[0], v[1], v[2], v[3]);
+}
+
+
+static void GLAPIENTRY
+save_PassThrough(GLfloat token)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_PASSTHROUGH, 1);
+ if (n) {
+ n[1].f = token;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_PassThrough(ctx->Exec, (token));
+ }
+}
+
+
+static void GLAPIENTRY
+save_ReadBuffer(GLenum mode)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_READ_BUFFER, 1);
+ if (n) {
+ n[1].e = mode;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_ReadBuffer(ctx->Exec, (mode));
+ }
+}
+
+
+static void GLAPIENTRY
+save_ResetHistogram(GLenum target)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_RESET_HISTOGRAM, 1);
+ if (n) {
+ n[1].e = target;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_ResetHistogram(ctx->Exec, (target));
+ }
+}
+
+
+static void GLAPIENTRY
+save_ResetMinmax(GLenum target)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_RESET_MIN_MAX, 1);
+ if (n) {
+ n[1].e = target;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_ResetMinmax(ctx->Exec, (target));
+ }
+}
+
+
+static void GLAPIENTRY
+save_Rotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_ROTATE, 4);
+ if (n) {
+ n[1].f = angle;
+ n[2].f = x;
+ n[3].f = y;
+ n[4].f = z;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_Rotatef(ctx->Exec, (angle, x, y, z));
+ }
+}
+
+
+static void GLAPIENTRY
+save_Rotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z)
+{
+ save_Rotatef((GLfloat) angle, (GLfloat) x, (GLfloat) y, (GLfloat) z);
+}
+
+
+static void GLAPIENTRY
+save_Scalef(GLfloat x, GLfloat y, GLfloat z)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_SCALE, 3);
+ if (n) {
+ n[1].f = x;
+ n[2].f = y;
+ n[3].f = z;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_Scalef(ctx->Exec, (x, y, z));
+ }
+}
+
+
+static void GLAPIENTRY
+save_Scaled(GLdouble x, GLdouble y, GLdouble z)
+{
+ save_Scalef((GLfloat) x, (GLfloat) y, (GLfloat) z);
+}
+
+
+static void GLAPIENTRY
+save_Scissor(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_SCISSOR, 4);
+ if (n) {
+ n[1].i = x;
+ n[2].i = y;
+ n[3].i = width;
+ n[4].i = height;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_Scissor(ctx->Exec, (x, y, width, height));
+ }
+}
+
+
+static void GLAPIENTRY
+save_ShadeModel(GLenum mode)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_SHADE_MODEL, 1);
+ if (n) {
+ n[1].e = mode;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_ShadeModel(ctx->Exec, (mode));
+ }
+}
+
+
+static void GLAPIENTRY
+save_StencilFunc(GLenum func, GLint ref, GLuint mask)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_STENCIL_FUNC, 3);
+ if (n) {
+ n[1].e = func;
+ n[2].i = ref;
+ n[3].ui = mask;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_StencilFunc(ctx->Exec, (func, ref, mask));
+ }
+}
+
+
+static void GLAPIENTRY
+save_StencilMask(GLuint mask)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_STENCIL_MASK, 1);
+ if (n) {
+ n[1].ui = mask;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_StencilMask(ctx->Exec, (mask));
+ }
+}
+
+
+static void GLAPIENTRY
+save_StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_STENCIL_OP, 3);
+ if (n) {
+ n[1].e = fail;
+ n[2].e = zfail;
+ n[3].e = zpass;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_StencilOp(ctx->Exec, (fail, zfail, zpass));
+ }
+}
+
+
+static void GLAPIENTRY
+save_StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_STENCIL_FUNC_SEPARATE, 4);
+ if (n) {
+ n[1].e = face;
+ n[2].e = func;
+ n[3].i = ref;
+ n[4].ui = mask;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_StencilFuncSeparate(ctx->Exec, (face, func, ref, mask));
+ }
+}
+
+
+static void GLAPIENTRY
+save_StencilMaskSeparate(GLenum face, GLuint mask)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_STENCIL_MASK_SEPARATE, 2);
+ if (n) {
+ n[1].e = face;
+ n[2].ui = mask;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_StencilMaskSeparate(ctx->Exec, (face, mask));
+ }
+}
+
+
+static void GLAPIENTRY
+save_StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_STENCIL_OP_SEPARATE, 4);
+ if (n) {
+ n[1].e = face;
+ n[2].e = fail;
+ n[3].e = zfail;
+ n[4].e = zpass;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_StencilOpSeparate(ctx->Exec, (face, fail, zfail, zpass));
+ }
+}
+
+
+static void GLAPIENTRY
+save_TexEnvfv(GLenum target, GLenum pname, const GLfloat *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_TEXENV, 6);
+ if (n) {
+ n[1].e = target;
+ n[2].e = pname;
+ if (pname == GL_TEXTURE_ENV_COLOR) {
+ n[3].f = params[0];
+ n[4].f = params[1];
+ n[5].f = params[2];
+ n[6].f = params[3];
+ }
+ else {
+ n[3].f = params[0];
+ n[4].f = n[5].f = n[6].f = 0.0F;
+ }
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_TexEnvfv(ctx->Exec, (target, pname, params));
+ }
+}
+
+
+static void GLAPIENTRY
+save_TexEnvf(GLenum target, GLenum pname, GLfloat param)
+{
+ save_TexEnvfv(target, pname, &param);
+}
+
+
+static void GLAPIENTRY
+save_TexEnvi(GLenum target, GLenum pname, GLint param)
+{
+ GLfloat p[4];
+ p[0] = (GLfloat) param;
+ p[1] = p[2] = p[3] = 0.0;
+ save_TexEnvfv(target, pname, p);
+}
+
+
+static void GLAPIENTRY
+save_TexEnviv(GLenum target, GLenum pname, const GLint * param)
+{
+ GLfloat p[4];
+ if (pname == GL_TEXTURE_ENV_COLOR) {
+ p[0] = INT_TO_FLOAT(param[0]);
+ p[1] = INT_TO_FLOAT(param[1]);
+ p[2] = INT_TO_FLOAT(param[2]);
+ p[3] = INT_TO_FLOAT(param[3]);
+ }
+ else {
+ p[0] = (GLfloat) param[0];
+ p[1] = p[2] = p[3] = 0.0F;
+ }
+ save_TexEnvfv(target, pname, p);
+}
+
+
+static void GLAPIENTRY
+save_TexGenfv(GLenum coord, GLenum pname, const GLfloat *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_TEXGEN, 6);
+ if (n) {
+ n[1].e = coord;
+ n[2].e = pname;
+ n[3].f = params[0];
+ n[4].f = params[1];
+ n[5].f = params[2];
+ n[6].f = params[3];
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_TexGenfv(ctx->Exec, (coord, pname, params));
+ }
+}
+
+
+static void GLAPIENTRY
+save_TexGeniv(GLenum coord, GLenum pname, const GLint *params)
+{
+ GLfloat p[4];
+ p[0] = (GLfloat) params[0];
+ p[1] = (GLfloat) params[1];
+ p[2] = (GLfloat) params[2];
+ p[3] = (GLfloat) params[3];
+ save_TexGenfv(coord, pname, p);
+}
+
+
+static void GLAPIENTRY
+save_TexGend(GLenum coord, GLenum pname, GLdouble param)
+{
+ GLfloat p = (GLfloat) param;
+ save_TexGenfv(coord, pname, &p);
+}
+
+
+static void GLAPIENTRY
+save_TexGendv(GLenum coord, GLenum pname, const GLdouble *params)
+{
+ GLfloat p[4];
+ p[0] = (GLfloat) params[0];
+ p[1] = (GLfloat) params[1];
+ p[2] = (GLfloat) params[2];
+ p[3] = (GLfloat) params[3];
+ save_TexGenfv(coord, pname, p);
+}
+
+
+static void GLAPIENTRY
+save_TexGenf(GLenum coord, GLenum pname, GLfloat param)
+{
+ save_TexGenfv(coord, pname, &param);
+}
+
+
+static void GLAPIENTRY
+save_TexGeni(GLenum coord, GLenum pname, GLint param)
+{
+ save_TexGeniv(coord, pname, &param);
+}
+
+
+static void GLAPIENTRY
+save_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_TEXPARAMETER, 6);
+ if (n) {
+ n[1].e = target;
+ n[2].e = pname;
+ n[3].f = params[0];
+ n[4].f = params[1];
+ n[5].f = params[2];
+ n[6].f = params[3];
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_TexParameterfv(ctx->Exec, (target, pname, params));
+ }
+}
+
+
+static void GLAPIENTRY
+save_TexParameterf(GLenum target, GLenum pname, GLfloat param)
+{
+ save_TexParameterfv(target, pname, &param);
+}
+
+
+static void GLAPIENTRY
+save_TexParameteri(GLenum target, GLenum pname, GLint param)
+{
+ GLfloat fparam[4];
+ fparam[0] = (GLfloat) param;
+ fparam[1] = fparam[2] = fparam[3] = 0.0;
+ save_TexParameterfv(target, pname, fparam);
+}
+
+
+static void GLAPIENTRY
+save_TexParameteriv(GLenum target, GLenum pname, const GLint *params)
+{
+ GLfloat fparam[4];
+ fparam[0] = (GLfloat) params[0];
+ fparam[1] = fparam[2] = fparam[3] = 0.0;
+ save_TexParameterfv(target, pname, fparam);
+}
+
+
+static void GLAPIENTRY
+save_TexImage1D(GLenum target,
+ GLint level, GLint components,
+ GLsizei width, GLint border,
+ GLenum format, GLenum type, const GLvoid * pixels)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ if (target == GL_PROXY_TEXTURE_1D) {
+ /* don't compile, execute immediately */
+ CALL_TexImage1D(ctx->Exec, (target, level, components, width,
+ border, format, type, pixels));
+ }
+ else {
+ GLvoid *image = unpack_image(1, width, 1, 1, format, type,
+ pixels, &ctx->Unpack);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_TEX_IMAGE1D, 8);
+ if (n) {
+ n[1].e = target;
+ n[2].i = level;
+ n[3].i = components;
+ n[4].i = (GLint) width;
+ n[5].i = border;
+ n[6].e = format;
+ n[7].e = type;
+ n[8].data = image;
+ }
+ else if (image) {
+ _mesa_free(image);
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_TexImage1D(ctx->Exec, (target, level, components, width,
+ border, format, type, pixels));
+ }
+ }
+}
+
+
+static void GLAPIENTRY
+save_TexImage2D(GLenum target,
+ GLint level, GLint components,
+ GLsizei width, GLsizei height, GLint border,
+ GLenum format, GLenum type, const GLvoid * pixels)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ if (target == GL_PROXY_TEXTURE_2D) {
+ /* don't compile, execute immediately */
+ CALL_TexImage2D(ctx->Exec, (target, level, components, width,
+ height, border, format, type, pixels));
+ }
+ else {
+ GLvoid *image = unpack_image(2, width, height, 1, format, type,
+ pixels, &ctx->Unpack);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_TEX_IMAGE2D, 9);
+ if (n) {
+ n[1].e = target;
+ n[2].i = level;
+ n[3].i = components;
+ n[4].i = (GLint) width;
+ n[5].i = (GLint) height;
+ n[6].i = border;
+ n[7].e = format;
+ n[8].e = type;
+ n[9].data = image;
+ }
+ else if (image) {
+ _mesa_free(image);
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_TexImage2D(ctx->Exec, (target, level, components, width,
+ height, border, format, type, pixels));
+ }
+ }
+}
+
+
+static void GLAPIENTRY
+save_TexImage3D(GLenum target,
+ GLint level, GLint internalFormat,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLint border,
+ GLenum format, GLenum type, const GLvoid * pixels)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ if (target == GL_PROXY_TEXTURE_3D) {
+ /* don't compile, execute immediately */
+ CALL_TexImage3D(ctx->Exec, (target, level, internalFormat, width,
+ height, depth, border, format, type,
+ pixels));
+ }
+ else {
+ Node *n;
+ GLvoid *image = unpack_image(3, width, height, depth, format, type,
+ pixels, &ctx->Unpack);
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_TEX_IMAGE3D, 10);
+ if (n) {
+ n[1].e = target;
+ n[2].i = level;
+ n[3].i = (GLint) internalFormat;
+ n[4].i = (GLint) width;
+ n[5].i = (GLint) height;
+ n[6].i = (GLint) depth;
+ n[7].i = border;
+ n[8].e = format;
+ n[9].e = type;
+ n[10].data = image;
+ }
+ else if (image) {
+ _mesa_free(image);
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_TexImage3D(ctx->Exec, (target, level, internalFormat, width,
+ height, depth, border, format, type,
+ pixels));
+ }
+ }
+}
+
+
+static void GLAPIENTRY
+save_TexSubImage1D(GLenum target, GLint level, GLint xoffset,
+ GLsizei width, GLenum format, GLenum type,
+ const GLvoid * pixels)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ GLvoid *image = unpack_image(1, width, 1, 1, format, type,
+ pixels, &ctx->Unpack);
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_TEX_SUB_IMAGE1D, 7);
+ if (n) {
+ n[1].e = target;
+ n[2].i = level;
+ n[3].i = xoffset;
+ n[4].i = (GLint) width;
+ n[5].e = format;
+ n[6].e = type;
+ n[7].data = image;
+ }
+ else if (image) {
+ _mesa_free(image);
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_TexSubImage1D(ctx->Exec, (target, level, xoffset, width,
+ format, type, pixels));
+ }
+}
+
+
+static void GLAPIENTRY
+save_TexSubImage2D(GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type, const GLvoid * pixels)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ GLvoid *image = unpack_image(2, width, height, 1, format, type,
+ pixels, &ctx->Unpack);
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_TEX_SUB_IMAGE2D, 9);
+ if (n) {
+ n[1].e = target;
+ n[2].i = level;
+ n[3].i = xoffset;
+ n[4].i = yoffset;
+ n[5].i = (GLint) width;
+ n[6].i = (GLint) height;
+ n[7].e = format;
+ n[8].e = type;
+ n[9].data = image;
+ }
+ else if (image) {
+ _mesa_free(image);
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_TexSubImage2D(ctx->Exec, (target, level, xoffset, yoffset,
+ width, height, format, type, pixels));
+ }
+}
+
+
+static void GLAPIENTRY
+save_TexSubImage3D(GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type, const GLvoid * pixels)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ GLvoid *image = unpack_image(3, width, height, depth, format, type,
+ pixels, &ctx->Unpack);
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_TEX_SUB_IMAGE3D, 11);
+ if (n) {
+ n[1].e = target;
+ n[2].i = level;
+ n[3].i = xoffset;
+ n[4].i = yoffset;
+ n[5].i = zoffset;
+ n[6].i = (GLint) width;
+ n[7].i = (GLint) height;
+ n[8].i = (GLint) depth;
+ n[9].e = format;
+ n[10].e = type;
+ n[11].data = image;
+ }
+ else if (image) {
+ _mesa_free(image);
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_TexSubImage3D(ctx->Exec, (target, level,
+ xoffset, yoffset, zoffset,
+ width, height, depth, format, type,
+ pixels));
+ }
+}
+
+
+static void GLAPIENTRY
+save_Translatef(GLfloat x, GLfloat y, GLfloat z)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_TRANSLATE, 3);
+ if (n) {
+ n[1].f = x;
+ n[2].f = y;
+ n[3].f = z;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_Translatef(ctx->Exec, (x, y, z));
+ }
+}
+
+
+static void GLAPIENTRY
+save_Translated(GLdouble x, GLdouble y, GLdouble z)
+{
+ save_Translatef((GLfloat) x, (GLfloat) y, (GLfloat) z);
+}
+
+
+
+static void GLAPIENTRY
+save_Viewport(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_VIEWPORT, 4);
+ if (n) {
+ n[1].i = x;
+ n[2].i = y;
+ n[3].i = (GLint) width;
+ n[4].i = (GLint) height;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_Viewport(ctx->Exec, (x, y, width, height));
+ }
+}
+
+
+static void GLAPIENTRY
+save_WindowPos4fMESA(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_WINDOW_POS, 4);
+ if (n) {
+ n[1].f = x;
+ n[2].f = y;
+ n[3].f = z;
+ n[4].f = w;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_WindowPos4fMESA(ctx->Exec, (x, y, z, w));
+ }
+}
+
+static void GLAPIENTRY
+save_WindowPos2dMESA(GLdouble x, GLdouble y)
+{
+ save_WindowPos4fMESA((GLfloat) x, (GLfloat) y, 0.0F, 1.0F);
+}
+
+static void GLAPIENTRY
+save_WindowPos2fMESA(GLfloat x, GLfloat y)
+{
+ save_WindowPos4fMESA(x, y, 0.0F, 1.0F);
+}
+
+static void GLAPIENTRY
+save_WindowPos2iMESA(GLint x, GLint y)
+{
+ save_WindowPos4fMESA((GLfloat) x, (GLfloat) y, 0.0F, 1.0F);
+}
+
+static void GLAPIENTRY
+save_WindowPos2sMESA(GLshort x, GLshort y)
+{
+ save_WindowPos4fMESA(x, y, 0.0F, 1.0F);
+}
+
+static void GLAPIENTRY
+save_WindowPos3dMESA(GLdouble x, GLdouble y, GLdouble z)
+{
+ save_WindowPos4fMESA((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F);
+}
+
+static void GLAPIENTRY
+save_WindowPos3fMESA(GLfloat x, GLfloat y, GLfloat z)
+{
+ save_WindowPos4fMESA(x, y, z, 1.0F);
+}
+
+static void GLAPIENTRY
+save_WindowPos3iMESA(GLint x, GLint y, GLint z)
+{
+ save_WindowPos4fMESA((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F);
+}
+
+static void GLAPIENTRY
+save_WindowPos3sMESA(GLshort x, GLshort y, GLshort z)
+{
+ save_WindowPos4fMESA(x, y, z, 1.0F);
+}
+
+static void GLAPIENTRY
+save_WindowPos4dMESA(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
+{
+ save_WindowPos4fMESA((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
+}
+
+static void GLAPIENTRY
+save_WindowPos4iMESA(GLint x, GLint y, GLint z, GLint w)
+{
+ save_WindowPos4fMESA((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
+}
+
+static void GLAPIENTRY
+save_WindowPos4sMESA(GLshort x, GLshort y, GLshort z, GLshort w)
+{
+ save_WindowPos4fMESA(x, y, z, w);
+}
+
+static void GLAPIENTRY
+save_WindowPos2dvMESA(const GLdouble * v)
+{
+ save_WindowPos4fMESA((GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F);
+}
+
+static void GLAPIENTRY
+save_WindowPos2fvMESA(const GLfloat * v)
+{
+ save_WindowPos4fMESA(v[0], v[1], 0.0F, 1.0F);
+}
+
+static void GLAPIENTRY
+save_WindowPos2ivMESA(const GLint * v)
+{
+ save_WindowPos4fMESA((GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F);
+}
+
+static void GLAPIENTRY
+save_WindowPos2svMESA(const GLshort * v)
+{
+ save_WindowPos4fMESA(v[0], v[1], 0.0F, 1.0F);
+}
+
+static void GLAPIENTRY
+save_WindowPos3dvMESA(const GLdouble * v)
+{
+ save_WindowPos4fMESA((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F);
+}
+
+static void GLAPIENTRY
+save_WindowPos3fvMESA(const GLfloat * v)
+{
+ save_WindowPos4fMESA(v[0], v[1], v[2], 1.0F);
+}
+
+static void GLAPIENTRY
+save_WindowPos3ivMESA(const GLint * v)
+{
+ save_WindowPos4fMESA((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F);
+}
+
+static void GLAPIENTRY
+save_WindowPos3svMESA(const GLshort * v)
+{
+ save_WindowPos4fMESA(v[0], v[1], v[2], 1.0F);
+}
+
+static void GLAPIENTRY
+save_WindowPos4dvMESA(const GLdouble * v)
+{
+ save_WindowPos4fMESA((GLfloat) v[0], (GLfloat) v[1],
+ (GLfloat) v[2], (GLfloat) v[3]);
+}
+
+static void GLAPIENTRY
+save_WindowPos4fvMESA(const GLfloat * v)
+{
+ save_WindowPos4fMESA(v[0], v[1], v[2], v[3]);
+}
+
+static void GLAPIENTRY
+save_WindowPos4ivMESA(const GLint * v)
+{
+ save_WindowPos4fMESA((GLfloat) v[0], (GLfloat) v[1],
+ (GLfloat) v[2], (GLfloat) v[3]);
+}
+
+static void GLAPIENTRY
+save_WindowPos4svMESA(const GLshort * v)
+{
+ save_WindowPos4fMESA(v[0], v[1], v[2], v[3]);
+}
+
+
+
+/* GL_ARB_multitexture */
+static void GLAPIENTRY
+save_ActiveTextureARB(GLenum target)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_ACTIVE_TEXTURE, 1);
+ if (n) {
+ n[1].e = target;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_ActiveTextureARB(ctx->Exec, (target));
+ }
+}
+
+
+/* GL_ARB_transpose_matrix */
+
+static void GLAPIENTRY
+save_LoadTransposeMatrixdARB(const GLdouble m[16])
+{
+ GLfloat tm[16];
+ _math_transposefd(tm, m);
+ save_LoadMatrixf(tm);
+}
+
+
+static void GLAPIENTRY
+save_LoadTransposeMatrixfARB(const GLfloat m[16])
+{
+ GLfloat tm[16];
+ _math_transposef(tm, m);
+ save_LoadMatrixf(tm);
+}
+
+
+static void GLAPIENTRY
+save_MultTransposeMatrixdARB(const GLdouble m[16])
+{
+ GLfloat tm[16];
+ _math_transposefd(tm, m);
+ save_MultMatrixf(tm);
+}
+
+
+static void GLAPIENTRY
+save_MultTransposeMatrixfARB(const GLfloat m[16])
+{
+ GLfloat tm[16];
+ _math_transposef(tm, m);
+ save_MultMatrixf(tm);
+}
+
+
+/* GL_ARB_texture_compression */
+static void GLAPIENTRY
+save_CompressedTexImage1DARB(GLenum target, GLint level,
+ GLenum internalFormat, GLsizei width,
+ GLint border, GLsizei imageSize,
+ const GLvoid * data)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ if (target == GL_PROXY_TEXTURE_1D) {
+ /* don't compile, execute immediately */
+ CALL_CompressedTexImage1DARB(ctx->Exec, (target, level, internalFormat,
+ width, border, imageSize,
+ data));
+ }
+ else {
+ Node *n;
+ GLvoid *image;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ /* make copy of image */
+ image = _mesa_malloc(imageSize);
+ if (!image) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage1DARB");
+ return;
+ }
+ MEMCPY(image, data, imageSize);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_COMPRESSED_TEX_IMAGE_1D, 7);
+ if (n) {
+ n[1].e = target;
+ n[2].i = level;
+ n[3].e = internalFormat;
+ n[4].i = (GLint) width;
+ n[5].i = border;
+ n[6].i = imageSize;
+ n[7].data = image;
+ }
+ else if (image) {
+ _mesa_free(image);
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_CompressedTexImage1DARB(ctx->Exec,
+ (target, level, internalFormat, width,
+ border, imageSize, data));
+ }
+ }
+}
+
+
+static void GLAPIENTRY
+save_CompressedTexImage2DARB(GLenum target, GLint level,
+ GLenum internalFormat, GLsizei width,
+ GLsizei height, GLint border, GLsizei imageSize,
+ const GLvoid * data)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ if (target == GL_PROXY_TEXTURE_2D) {
+ /* don't compile, execute immediately */
+ CALL_CompressedTexImage2DARB(ctx->Exec, (target, level, internalFormat,
+ width, height, border,
+ imageSize, data));
+ }
+ else {
+ Node *n;
+ GLvoid *image;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ /* make copy of image */
+ image = _mesa_malloc(imageSize);
+ if (!image) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2DARB");
+ return;
+ }
+ MEMCPY(image, data, imageSize);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_COMPRESSED_TEX_IMAGE_2D, 8);
+ if (n) {
+ n[1].e = target;
+ n[2].i = level;
+ n[3].e = internalFormat;
+ n[4].i = (GLint) width;
+ n[5].i = (GLint) height;
+ n[6].i = border;
+ n[7].i = imageSize;
+ n[8].data = image;
+ }
+ else if (image) {
+ _mesa_free(image);
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_CompressedTexImage2DARB(ctx->Exec,
+ (target, level, internalFormat, width,
+ height, border, imageSize, data));
+ }
+ }
+}
+
+
+static void GLAPIENTRY
+save_CompressedTexImage3DARB(GLenum target, GLint level,
+ GLenum internalFormat, GLsizei width,
+ GLsizei height, GLsizei depth, GLint border,
+ GLsizei imageSize, const GLvoid * data)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ if (target == GL_PROXY_TEXTURE_3D) {
+ /* don't compile, execute immediately */
+ CALL_CompressedTexImage3DARB(ctx->Exec, (target, level, internalFormat,
+ width, height, depth, border,
+ imageSize, data));
+ }
+ else {
+ Node *n;
+ GLvoid *image;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ /* make copy of image */
+ image = _mesa_malloc(imageSize);
+ if (!image) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage3DARB");
+ return;
+ }
+ MEMCPY(image, data, imageSize);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_COMPRESSED_TEX_IMAGE_3D, 9);
+ if (n) {
+ n[1].e = target;
+ n[2].i = level;
+ n[3].e = internalFormat;
+ n[4].i = (GLint) width;
+ n[5].i = (GLint) height;
+ n[6].i = (GLint) depth;
+ n[7].i = border;
+ n[8].i = imageSize;
+ n[9].data = image;
+ }
+ else if (image) {
+ _mesa_free(image);
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_CompressedTexImage3DARB(ctx->Exec,
+ (target, level, internalFormat, width,
+ height, depth, border, imageSize,
+ data));
+ }
+ }
+}
+
+
+static void GLAPIENTRY
+save_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
+ GLsizei width, GLenum format,
+ GLsizei imageSize, const GLvoid * data)
+{
+ Node *n;
+ GLvoid *image;
+
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
+ /* make copy of image */
+ image = _mesa_malloc(imageSize);
+ if (!image) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage1DARB");
+ return;
+ }
+ MEMCPY(image, data, imageSize);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D, 7);
+ if (n) {
+ n[1].e = target;
+ n[2].i = level;
+ n[3].i = xoffset;
+ n[4].i = (GLint) width;
+ n[5].e = format;
+ n[6].i = imageSize;
+ n[7].data = image;
+ }
+ else if (image) {
+ _mesa_free(image);
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_CompressedTexSubImage1DARB(ctx->Exec, (target, level, xoffset,
+ width, format, imageSize,
+ data));
+ }
+}
+
+
+static void GLAPIENTRY
+save_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
+ GLint yoffset, GLsizei width, GLsizei height,
+ GLenum format, GLsizei imageSize,
+ const GLvoid * data)
+{
+ Node *n;
+ GLvoid *image;
+
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
+ /* make copy of image */
+ image = _mesa_malloc(imageSize);
+ if (!image) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage2DARB");
+ return;
+ }
+ MEMCPY(image, data, imageSize);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D, 9);
+ if (n) {
+ n[1].e = target;
+ n[2].i = level;
+ n[3].i = xoffset;
+ n[4].i = yoffset;
+ n[5].i = (GLint) width;
+ n[6].i = (GLint) height;
+ n[7].e = format;
+ n[8].i = imageSize;
+ n[9].data = image;
+ }
+ else if (image) {
+ _mesa_free(image);
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_CompressedTexSubImage2DARB(ctx->Exec,
+ (target, level, xoffset, yoffset, width,
+ height, format, imageSize, data));
+ }
+}
+
+
+static void GLAPIENTRY
+save_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
+ GLint yoffset, GLint zoffset, GLsizei width,
+ GLsizei height, GLsizei depth, GLenum format,
+ GLsizei imageSize, const GLvoid * data)
+{
+ Node *n;
+ GLvoid *image;
+
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
+ /* make copy of image */
+ image = _mesa_malloc(imageSize);
+ if (!image) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage3DARB");
+ return;
+ }
+ MEMCPY(image, data, imageSize);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D, 11);
+ if (n) {
+ n[1].e = target;
+ n[2].i = level;
+ n[3].i = xoffset;
+ n[4].i = yoffset;
+ n[5].i = zoffset;
+ n[6].i = (GLint) width;
+ n[7].i = (GLint) height;
+ n[8].i = (GLint) depth;
+ n[9].e = format;
+ n[10].i = imageSize;
+ n[11].data = image;
+ }
+ else if (image) {
+ _mesa_free(image);
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_CompressedTexSubImage3DARB(ctx->Exec,
+ (target, level, xoffset, yoffset,
+ zoffset, width, height, depth, format,
+ imageSize, data));
+ }
+}
+
+
+/* GL_ARB_multisample */
+static void GLAPIENTRY
+save_SampleCoverageARB(GLclampf value, GLboolean invert)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_SAMPLE_COVERAGE, 2);
+ if (n) {
+ n[1].f = value;
+ n[2].b = invert;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_SampleCoverageARB(ctx->Exec, (value, invert));
+ }
+}
+
+
+/*
+ * GL_NV_vertex_program
+ */
+#if FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program
+static void GLAPIENTRY
+save_BindProgramNV(GLenum target, GLuint id)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_BIND_PROGRAM_NV, 2);
+ if (n) {
+ n[1].e = target;
+ n[2].ui = id;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_BindProgramNV(ctx->Exec, (target, id));
+ }
+}
+#endif /* FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program */
+
+#if FEATURE_NV_vertex_program
+static void GLAPIENTRY
+save_ExecuteProgramNV(GLenum target, GLuint id, const GLfloat *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_EXECUTE_PROGRAM_NV, 6);
+ if (n) {
+ n[1].e = target;
+ n[2].ui = id;
+ n[3].f = params[0];
+ n[4].f = params[1];
+ n[5].f = params[2];
+ n[6].f = params[3];
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_ExecuteProgramNV(ctx->Exec, (target, id, params));
+ }
+}
+
+
+static void GLAPIENTRY
+save_ProgramParameter4fNV(GLenum target, GLuint index,
+ GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_PROGRAM_PARAMETER4F_NV, 6);
+ if (n) {
+ n[1].e = target;
+ n[2].ui = index;
+ n[3].f = x;
+ n[4].f = y;
+ n[5].f = z;
+ n[6].f = w;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_ProgramParameter4fNV(ctx->Exec, (target, index, x, y, z, w));
+ }
+}
+
+
+static void GLAPIENTRY
+save_ProgramParameter4fvNV(GLenum target, GLuint index,
+ const GLfloat *params)
+{
+ save_ProgramParameter4fNV(target, index, params[0], params[1],
+ params[2], params[3]);
+}
+
+
+static void GLAPIENTRY
+save_ProgramParameter4dNV(GLenum target, GLuint index,
+ GLdouble x, GLdouble y, GLdouble z, GLdouble w)
+{
+ save_ProgramParameter4fNV(target, index, (GLfloat) x, (GLfloat) y,
+ (GLfloat) z, (GLfloat) w);
+}
+
+
+static void GLAPIENTRY
+save_ProgramParameter4dvNV(GLenum target, GLuint index,
+ const GLdouble *params)
+{
+ save_ProgramParameter4fNV(target, index, (GLfloat) params[0],
+ (GLfloat) params[1], (GLfloat) params[2],
+ (GLfloat) params[3]);
+}
+
+
+static void GLAPIENTRY
+save_ProgramParameters4dvNV(GLenum target, GLuint index,
+ GLuint num, const GLdouble *params)
+{
+ GLuint i;
+ for (i = 0; i < num; i++) {
+ save_ProgramParameter4dvNV(target, index + i, params + 4 * i);
+ }
+}
+
+
+static void GLAPIENTRY
+save_ProgramParameters4fvNV(GLenum target, GLuint index,
+ GLuint num, const GLfloat *params)
+{
+ GLuint i;
+ for (i = 0; i < num; i++) {
+ save_ProgramParameter4fvNV(target, index + i, params + 4 * i);
+ }
+}
+
+
+static void GLAPIENTRY
+save_LoadProgramNV(GLenum target, GLuint id, GLsizei len,
+ const GLubyte * program)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ GLubyte *programCopy;
+
+ programCopy = (GLubyte *) _mesa_malloc(len);
+ if (!programCopy) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
+ return;
+ }
+ _mesa_memcpy(programCopy, program, len);
+
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_LOAD_PROGRAM_NV, 4);
+ if (n) {
+ n[1].e = target;
+ n[2].ui = id;
+ n[3].i = len;
+ n[4].data = programCopy;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_LoadProgramNV(ctx->Exec, (target, id, len, program));
+ }
+}
+
+
+static void GLAPIENTRY
+save_RequestResidentProgramsNV(GLsizei num, const GLuint * ids)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ GLuint *idCopy = (GLuint *) _mesa_malloc(num * sizeof(GLuint));
+ if (!idCopy) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glRequestResidentProgramsNV");
+ return;
+ }
+ _mesa_memcpy(idCopy, ids, num * sizeof(GLuint));
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_TRACK_MATRIX_NV, 2);
+ if (n) {
+ n[1].i = num;
+ n[2].data = idCopy;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_RequestResidentProgramsNV(ctx->Exec, (num, ids));
+ }
+}
+
+
+static void GLAPIENTRY
+save_TrackMatrixNV(GLenum target, GLuint address,
+ GLenum matrix, GLenum transform)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_TRACK_MATRIX_NV, 4);
+ if (n) {
+ n[1].e = target;
+ n[2].ui = address;
+ n[3].e = matrix;
+ n[4].e = transform;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_TrackMatrixNV(ctx->Exec, (target, address, matrix, transform));
+ }
+}
+#endif /* FEATURE_NV_vertex_program */
+
+
+/*
+ * GL_NV_fragment_program
+ */
+#if FEATURE_NV_fragment_program
+static void GLAPIENTRY
+save_ProgramLocalParameter4fARB(GLenum target, GLuint index,
+ GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_PROGRAM_LOCAL_PARAMETER_ARB, 6);
+ if (n) {
+ n[1].e = target;
+ n[2].ui = index;
+ n[3].f = x;
+ n[4].f = y;
+ n[5].f = z;
+ n[6].f = w;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_ProgramLocalParameter4fARB(ctx->Exec, (target, index, x, y, z, w));
+ }
+}
+
+
+static void GLAPIENTRY
+save_ProgramLocalParameter4fvARB(GLenum target, GLuint index,
+ const GLfloat *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_PROGRAM_LOCAL_PARAMETER_ARB, 6);
+ if (n) {
+ n[1].e = target;
+ n[2].ui = index;
+ n[3].f = params[0];
+ n[4].f = params[1];
+ n[5].f = params[2];
+ n[6].f = params[3];
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_ProgramLocalParameter4fvARB(ctx->Exec, (target, index, params));
+ }
+}
+
+
+static void GLAPIENTRY
+save_ProgramLocalParameter4dARB(GLenum target, GLuint index,
+ GLdouble x, GLdouble y,
+ GLdouble z, GLdouble w)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_PROGRAM_LOCAL_PARAMETER_ARB, 6);
+ if (n) {
+ n[1].e = target;
+ n[2].ui = index;
+ n[3].f = (GLfloat) x;
+ n[4].f = (GLfloat) y;
+ n[5].f = (GLfloat) z;
+ n[6].f = (GLfloat) w;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_ProgramLocalParameter4dARB(ctx->Exec, (target, index, x, y, z, w));
+ }
+}
+
+
+static void GLAPIENTRY
+save_ProgramLocalParameter4dvARB(GLenum target, GLuint index,
+ const GLdouble *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_PROGRAM_LOCAL_PARAMETER_ARB, 6);
+ if (n) {
+ n[1].e = target;
+ n[2].ui = index;
+ n[3].f = (GLfloat) params[0];
+ n[4].f = (GLfloat) params[1];
+ n[5].f = (GLfloat) params[2];
+ n[6].f = (GLfloat) params[3];
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_ProgramLocalParameter4dvARB(ctx->Exec, (target, index, params));
+ }
+}
+
+static void GLAPIENTRY
+save_ProgramNamedParameter4fNV(GLuint id, GLsizei len, const GLubyte * name,
+ GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ GLubyte *nameCopy = (GLubyte *) _mesa_malloc(len);
+ if (!nameCopy) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramNamedParameter4fNV");
+ return;
+ }
+ _mesa_memcpy(nameCopy, name, len);
+
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_PROGRAM_NAMED_PARAMETER_NV, 6);
+ if (n) {
+ n[1].ui = id;
+ n[2].i = len;
+ n[3].data = nameCopy;
+ n[4].f = x;
+ n[5].f = y;
+ n[6].f = z;
+ n[7].f = w;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_ProgramNamedParameter4fNV(ctx->Exec, (id, len, name, x, y, z, w));
+ }
+}
+
+
+static void GLAPIENTRY
+save_ProgramNamedParameter4fvNV(GLuint id, GLsizei len, const GLubyte * name,
+ const float v[])
+{
+ save_ProgramNamedParameter4fNV(id, len, name, v[0], v[1], v[2], v[3]);
+}
+
+
+static void GLAPIENTRY
+save_ProgramNamedParameter4dNV(GLuint id, GLsizei len, const GLubyte * name,
+ GLdouble x, GLdouble y, GLdouble z, GLdouble w)
+{
+ save_ProgramNamedParameter4fNV(id, len, name, (GLfloat) x, (GLfloat) y,
+ (GLfloat) z, (GLfloat) w);
+}
+
+
+static void GLAPIENTRY
+save_ProgramNamedParameter4dvNV(GLuint id, GLsizei len, const GLubyte * name,
+ const double v[])
+{
+ save_ProgramNamedParameter4fNV(id, len, name, (GLfloat) v[0],
+ (GLfloat) v[1], (GLfloat) v[2],
+ (GLfloat) v[3]);
+}
+
+#endif /* FEATURE_NV_fragment_program */
+
+
+
+/* GL_EXT_stencil_two_side */
+static void GLAPIENTRY
+save_ActiveStencilFaceEXT(GLenum face)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_ACTIVE_STENCIL_FACE_EXT, 1);
+ if (n) {
+ n[1].e = face;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_ActiveStencilFaceEXT(ctx->Exec, (face));
+ }
+}
+
+
+/* GL_EXT_depth_bounds_test */
+static void GLAPIENTRY
+save_DepthBoundsEXT(GLclampd zmin, GLclampd zmax)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_DEPTH_BOUNDS_EXT, 2);
+ if (n) {
+ n[1].f = (GLfloat) zmin;
+ n[2].f = (GLfloat) zmax;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_DepthBoundsEXT(ctx->Exec, (zmin, zmax));
+ }
+}
+
+
+
+#if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program
+
+static void GLAPIENTRY
+save_ProgramStringARB(GLenum target, GLenum format, GLsizei len,
+ const GLvoid * string)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ GLubyte *programCopy;
+
+ programCopy = (GLubyte *) _mesa_malloc(len);
+ if (!programCopy) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB");
+ return;
+ }
+ _mesa_memcpy(programCopy, string, len);
+
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_PROGRAM_STRING_ARB, 4);
+ if (n) {
+ n[1].e = target;
+ n[2].e = format;
+ n[3].i = len;
+ n[4].data = programCopy;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_ProgramStringARB(ctx->Exec, (target, format, len, string));
+ }
+}
+
+
+static void GLAPIENTRY
+save_ProgramEnvParameter4fARB(GLenum target, GLuint index,
+ GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_PROGRAM_ENV_PARAMETER_ARB, 6);
+ if (n) {
+ n[1].e = target;
+ n[2].ui = index;
+ n[3].f = x;
+ n[4].f = y;
+ n[5].f = z;
+ n[6].f = w;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_ProgramEnvParameter4fARB(ctx->Exec, (target, index, x, y, z, w));
+ }
+}
+
+
+static void GLAPIENTRY
+save_ProgramEnvParameter4fvARB(GLenum target, GLuint index,
+ const GLfloat *params)
+{
+ save_ProgramEnvParameter4fARB(target, index, params[0], params[1],
+ params[2], params[3]);
+}
+
+
+static void GLAPIENTRY
+save_ProgramEnvParameter4dARB(GLenum target, GLuint index,
+ GLdouble x, GLdouble y, GLdouble z, GLdouble w)
+{
+ save_ProgramEnvParameter4fARB(target, index,
+ (GLfloat) x,
+ (GLfloat) y, (GLfloat) z, (GLfloat) w);
+}
+
+
+static void GLAPIENTRY
+save_ProgramEnvParameter4dvARB(GLenum target, GLuint index,
+ const GLdouble *params)
+{
+ save_ProgramEnvParameter4fARB(target, index,
+ (GLfloat) params[0],
+ (GLfloat) params[1],
+ (GLfloat) params[2], (GLfloat) params[3]);
+}
+
+#endif /* FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program */
+
+
+#ifdef FEATURE_ARB_occlusion_query
+
+static void GLAPIENTRY
+save_BeginQueryARB(GLenum target, GLuint id)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_BEGIN_QUERY_ARB, 2);
+ if (n) {
+ n[1].e = target;
+ n[2].ui = id;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_BeginQueryARB(ctx->Exec, (target, id));
+ }
+}
+
+
+static void GLAPIENTRY
+save_EndQueryARB(GLenum target)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_END_QUERY_ARB, 1);
+ if (n) {
+ n[1].e = target;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_EndQueryARB(ctx->Exec, (target));
+ }
+}
+
+#endif /* FEATURE_ARB_occlusion_query */
+
+
+static void GLAPIENTRY
+save_DrawBuffersARB(GLsizei count, const GLenum * buffers)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_DRAW_BUFFERS_ARB, 1 + MAX_DRAW_BUFFERS);
+ if (n) {
+ GLint i;
+ n[1].i = count;
+ if (count > MAX_DRAW_BUFFERS)
+ count = MAX_DRAW_BUFFERS;
+ for (i = 0; i < count; i++) {
+ n[2 + i].e = buffers[i];
+ }
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_DrawBuffersARB(ctx->Exec, (count, buffers));
+ }
+}
+
+#if FEATURE_ATI_fragment_shader
+static void GLAPIENTRY
+save_BindFragmentShaderATI(GLuint id)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_BIND_FRAGMENT_SHADER_ATI, 1);
+ if (n) {
+ n[1].ui = id;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_BindFragmentShaderATI(ctx->Exec, (id));
+ }
+}
+
+static void GLAPIENTRY
+save_SetFragmentShaderConstantATI(GLuint dst, const GLfloat *value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_SET_FRAGMENT_SHADER_CONSTANTS_ATI, 5);
+ if (n) {
+ n[1].ui = dst;
+ n[2].f = value[0];
+ n[3].f = value[1];
+ n[4].f = value[2];
+ n[5].f = value[3];
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_SetFragmentShaderConstantATI(ctx->Exec, (dst, value));
+ }
+}
+#endif
+
+static void
+save_Attr1fNV(GLenum attr, GLfloat x)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ SAVE_FLUSH_VERTICES(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_ATTR_1F_NV, 2);
+ if (n) {
+ n[1].e = attr;
+ n[2].f = x;
+ }
+
+ ASSERT(attr < VERT_ATTRIB_MAX);
+ ctx->ListState.ActiveAttribSize[attr] = 1;
+ ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, 0, 0, 1);
+
+ if (ctx->ExecuteFlag) {
+ CALL_VertexAttrib1fNV(ctx->Exec, (attr, x));
+ }
+}
+
+static void
+save_Attr2fNV(GLenum attr, GLfloat x, GLfloat y)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ SAVE_FLUSH_VERTICES(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_ATTR_2F_NV, 3);
+ if (n) {
+ n[1].e = attr;
+ n[2].f = x;
+ n[3].f = y;
+ }
+
+ ASSERT(attr < VERT_ATTRIB_MAX);
+ ctx->ListState.ActiveAttribSize[attr] = 2;
+ ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, 0, 1);
+
+ if (ctx->ExecuteFlag) {
+ CALL_VertexAttrib2fNV(ctx->Exec, (attr, x, y));
+ }
+}
+
+static void
+save_Attr3fNV(GLenum attr, GLfloat x, GLfloat y, GLfloat z)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ SAVE_FLUSH_VERTICES(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_ATTR_3F_NV, 4);
+ if (n) {
+ n[1].e = attr;
+ n[2].f = x;
+ n[3].f = y;
+ n[4].f = z;
+ }
+
+ ASSERT(attr < VERT_ATTRIB_MAX);
+ ctx->ListState.ActiveAttribSize[attr] = 3;
+ ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, z, 1);
+
+ if (ctx->ExecuteFlag) {
+ CALL_VertexAttrib3fNV(ctx->Exec, (attr, x, y, z));
+ }
+}
+
+static void
+save_Attr4fNV(GLenum attr, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ SAVE_FLUSH_VERTICES(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_ATTR_4F_NV, 5);
+ if (n) {
+ n[1].e = attr;
+ n[2].f = x;
+ n[3].f = y;
+ n[4].f = z;
+ n[5].f = w;
+ }
+
+ ASSERT(attr < VERT_ATTRIB_MAX);
+ ctx->ListState.ActiveAttribSize[attr] = 4;
+ ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, z, w);
+
+ if (ctx->ExecuteFlag) {
+ CALL_VertexAttrib4fNV(ctx->Exec, (attr, x, y, z, w));
+ }
+}
+
+
+static void
+save_Attr1fARB(GLenum attr, GLfloat x)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ SAVE_FLUSH_VERTICES(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_ATTR_1F_ARB, 2);
+ if (n) {
+ n[1].e = attr;
+ n[2].f = x;
+ }
+
+ ASSERT(attr < VERT_ATTRIB_MAX);
+ ctx->ListState.ActiveAttribSize[attr] = 1;
+ ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, 0, 0, 1);
+
+ if (ctx->ExecuteFlag) {
+ CALL_VertexAttrib1fARB(ctx->Exec, (attr, x));
+ }
+}
+
+static void
+save_Attr2fARB(GLenum attr, GLfloat x, GLfloat y)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ SAVE_FLUSH_VERTICES(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_ATTR_2F_ARB, 3);
+ if (n) {
+ n[1].e = attr;
+ n[2].f = x;
+ n[3].f = y;
+ }
+
+ ASSERT(attr < VERT_ATTRIB_MAX);
+ ctx->ListState.ActiveAttribSize[attr] = 2;
+ ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, 0, 1);
+
+ if (ctx->ExecuteFlag) {
+ CALL_VertexAttrib2fARB(ctx->Exec, (attr, x, y));
+ }
+}
+
+static void
+save_Attr3fARB(GLenum attr, GLfloat x, GLfloat y, GLfloat z)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ SAVE_FLUSH_VERTICES(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_ATTR_3F_ARB, 4);
+ if (n) {
+ n[1].e = attr;
+ n[2].f = x;
+ n[3].f = y;
+ n[4].f = z;
+ }
+
+ ASSERT(attr < VERT_ATTRIB_MAX);
+ ctx->ListState.ActiveAttribSize[attr] = 3;
+ ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, z, 1);
+
+ if (ctx->ExecuteFlag) {
+ CALL_VertexAttrib3fARB(ctx->Exec, (attr, x, y, z));
+ }
+}
+
+static void
+save_Attr4fARB(GLenum attr, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ SAVE_FLUSH_VERTICES(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_ATTR_4F_ARB, 5);
+ if (n) {
+ n[1].e = attr;
+ n[2].f = x;
+ n[3].f = y;
+ n[4].f = z;
+ n[5].f = w;
+ }
+
+ ASSERT(attr < VERT_ATTRIB_MAX);
+ ctx->ListState.ActiveAttribSize[attr] = 4;
+ ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, z, w);
+
+ if (ctx->ExecuteFlag) {
+ CALL_VertexAttrib4fARB(ctx->Exec, (attr, x, y, z, w));
+ }
+}
+
+
+static void GLAPIENTRY
+save_EvalCoord1f(GLfloat x)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ SAVE_FLUSH_VERTICES(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_EVAL_C1, 1);
+ if (n) {
+ n[1].f = x;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_EvalCoord1f(ctx->Exec, (x));
+ }
+}
+
+static void GLAPIENTRY
+save_EvalCoord1fv(const GLfloat * v)
+{
+ save_EvalCoord1f(v[0]);
+}
+
+static void GLAPIENTRY
+save_EvalCoord2f(GLfloat x, GLfloat y)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ SAVE_FLUSH_VERTICES(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_EVAL_C2, 2);
+ if (n) {
+ n[1].f = x;
+ n[2].f = y;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_EvalCoord2f(ctx->Exec, (x, y));
+ }
+}
+
+static void GLAPIENTRY
+save_EvalCoord2fv(const GLfloat * v)
+{
+ save_EvalCoord2f(v[0], v[1]);
+}
+
+
+static void GLAPIENTRY
+save_EvalPoint1(GLint x)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ SAVE_FLUSH_VERTICES(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_EVAL_P1, 1);
+ if (n) {
+ n[1].i = x;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_EvalPoint1(ctx->Exec, (x));
+ }
+}
+
+static void GLAPIENTRY
+save_EvalPoint2(GLint x, GLint y)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ SAVE_FLUSH_VERTICES(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_EVAL_P2, 2);
+ if (n) {
+ n[1].i = x;
+ n[2].i = y;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_EvalPoint2(ctx->Exec, (x, y));
+ }
+}
+
+static void GLAPIENTRY
+save_Indexf(GLfloat x)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ SAVE_FLUSH_VERTICES(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_INDEX, 1);
+ if (n) {
+ n[1].f = x;
+ }
+
+ ctx->ListState.ActiveIndex = 1;
+ ctx->ListState.CurrentIndex = x;
+
+ if (ctx->ExecuteFlag) {
+ CALL_Indexi(ctx->Exec, ((GLint) x));
+ }
+}
+
+static void GLAPIENTRY
+save_Indexfv(const GLfloat * v)
+{
+ save_Indexf(v[0]);
+}
+
+static void GLAPIENTRY
+save_EdgeFlag(GLboolean x)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ SAVE_FLUSH_VERTICES(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_EDGEFLAG, 1);
+ if (n) {
+ n[1].b = x;
+ }
+
+ ctx->ListState.ActiveEdgeFlag = 1;
+ ctx->ListState.CurrentEdgeFlag = x;
+
+ if (ctx->ExecuteFlag) {
+ CALL_EdgeFlag(ctx->Exec, (x));
+ }
+}
+
+static void GLAPIENTRY
+save_EdgeFlagv(const GLboolean * v)
+{
+ save_EdgeFlag(v[0]);
+}
+
+static void GLAPIENTRY
+save_Materialfv(GLenum face, GLenum pname, const GLfloat * param)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ int args, i;
+
+ SAVE_FLUSH_VERTICES(ctx);
+
+ switch (face) {
+ case GL_BACK:
+ case GL_FRONT:
+ case GL_FRONT_AND_BACK:
+ break;
+ default:
+ _mesa_compile_error(ctx, GL_INVALID_ENUM, "material(face)");
+ return;
+ }
+
+ switch (pname) {
+ case GL_EMISSION:
+ case GL_AMBIENT:
+ case GL_DIFFUSE:
+ case GL_SPECULAR:
+ case GL_AMBIENT_AND_DIFFUSE:
+ args = 4;
+ break;
+ case GL_SHININESS:
+ args = 1;
+ break;
+ case GL_COLOR_INDEXES:
+ args = 3;
+ break;
+ default:
+ _mesa_compile_error(ctx, GL_INVALID_ENUM, "material(pname)");
+ return;
+ }
+
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_MATERIAL, 6);
+ if (n) {
+ n[1].e = face;
+ n[2].e = pname;
+ for (i = 0; i < args; i++)
+ n[3 + i].f = param[i];
+ }
+
+ {
+ GLuint bitmask = _mesa_material_bitmask(ctx, face, pname, ~0, NULL);
+ for (i = 0; i < MAT_ATTRIB_MAX; i++)
+ if (bitmask & (1 << i)) {
+ ctx->ListState.ActiveMaterialSize[i] = args;
+ COPY_SZ_4V(ctx->ListState.CurrentMaterial[i], args, param);
+ }
+ }
+
+ if (ctx->ExecuteFlag) {
+ CALL_Materialfv(ctx->Exec, (face, pname, param));
+ }
+}
+
+static void GLAPIENTRY
+save_Begin(GLenum mode)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ GLboolean error = GL_FALSE;
+
+ if ( /*mode < GL_POINTS || */ mode > GL_POLYGON) {
+ _mesa_compile_error(ctx, GL_INVALID_ENUM, "Begin (mode)");
+ error = GL_TRUE;
+ }
+ else if (ctx->Driver.CurrentSavePrimitive == PRIM_UNKNOWN) {
+ /* Typically the first begin. This may raise an error on
+ * playback, depending on whether CallList is issued from inside
+ * a begin/end or not.
+ */
+ ctx->Driver.CurrentSavePrimitive = PRIM_INSIDE_UNKNOWN_PRIM;
+ }
+ else if (ctx->Driver.CurrentSavePrimitive == PRIM_OUTSIDE_BEGIN_END) {
+ ctx->Driver.CurrentSavePrimitive = mode;
+ }
+ else {
+ _mesa_compile_error(ctx, GL_INVALID_OPERATION, "recursive begin");
+ error = GL_TRUE;
+ }
+
+ if (!error) {
+ /* Give the driver an opportunity to hook in an optimized
+ * display list compiler.
+ */
+ if (ctx->Driver.NotifySaveBegin(ctx, mode))
+ return;
+
+ SAVE_FLUSH_VERTICES(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_BEGIN, 1);
+ if (n) {
+ n[1].e = mode;
+ }
+ }
+
+ if (ctx->ExecuteFlag) {
+ CALL_Begin(ctx->Exec, (mode));
+ }
+}
+
+static void GLAPIENTRY
+save_End(void)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ SAVE_FLUSH_VERTICES(ctx);
+ (void) ALLOC_INSTRUCTION(ctx, OPCODE_END, 0);
+ ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END;
+ if (ctx->ExecuteFlag) {
+ CALL_End(ctx->Exec, ());
+ }
+}
+
+static void GLAPIENTRY
+save_Rectf(GLfloat a, GLfloat b, GLfloat c, GLfloat d)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ SAVE_FLUSH_VERTICES(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_RECTF, 4);
+ if (n) {
+ n[1].f = a;
+ n[2].f = b;
+ n[3].f = c;
+ n[4].f = d;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_Rectf(ctx->Exec, (a, b, c, d));
+ }
+}
+
+
+static void GLAPIENTRY
+save_Vertex2f(GLfloat x, GLfloat y)
+{
+ save_Attr2fNV(VERT_ATTRIB_POS, x, y);
+}
+
+static void GLAPIENTRY
+save_Vertex2fv(const GLfloat * v)
+{
+ save_Attr2fNV(VERT_ATTRIB_POS, v[0], v[1]);
+}
+
+static void GLAPIENTRY
+save_Vertex3f(GLfloat x, GLfloat y, GLfloat z)
+{
+ save_Attr3fNV(VERT_ATTRIB_POS, x, y, z);
+}
+
+static void GLAPIENTRY
+save_Vertex3fv(const GLfloat * v)
+{
+ save_Attr3fNV(VERT_ATTRIB_POS, v[0], v[1], v[2]);
+}
+
+static void GLAPIENTRY
+save_Vertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ save_Attr4fNV(VERT_ATTRIB_POS, x, y, z, w);
+}
+
+static void GLAPIENTRY
+save_Vertex4fv(const GLfloat * v)
+{
+ save_Attr4fNV(VERT_ATTRIB_POS, v[0], v[1], v[2], v[3]);
+}
+
+static void GLAPIENTRY
+save_TexCoord1f(GLfloat x)
+{
+ save_Attr1fNV(VERT_ATTRIB_TEX0, x);
+}
+
+static void GLAPIENTRY
+save_TexCoord1fv(const GLfloat * v)
+{
+ save_Attr1fNV(VERT_ATTRIB_TEX0, v[0]);
+}
+
+static void GLAPIENTRY
+save_TexCoord2f(GLfloat x, GLfloat y)
+{
+ save_Attr2fNV(VERT_ATTRIB_TEX0, x, y);
+}
+
+static void GLAPIENTRY
+save_TexCoord2fv(const GLfloat * v)
+{
+ save_Attr2fNV(VERT_ATTRIB_TEX0, v[0], v[1]);
+}
+
+static void GLAPIENTRY
+save_TexCoord3f(GLfloat x, GLfloat y, GLfloat z)
+{
+ save_Attr3fNV(VERT_ATTRIB_TEX0, x, y, z);
+}
+
+static void GLAPIENTRY
+save_TexCoord3fv(const GLfloat * v)
+{
+ save_Attr3fNV(VERT_ATTRIB_TEX0, v[0], v[1], v[2]);
+}
+
+static void GLAPIENTRY
+save_TexCoord4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ save_Attr4fNV(VERT_ATTRIB_TEX0, x, y, z, w);
+}
+
+static void GLAPIENTRY
+save_TexCoord4fv(const GLfloat * v)
+{
+ save_Attr4fNV(VERT_ATTRIB_TEX0, v[0], v[1], v[2], v[3]);
+}
+
+static void GLAPIENTRY
+save_Normal3f(GLfloat x, GLfloat y, GLfloat z)
+{
+ save_Attr3fNV(VERT_ATTRIB_NORMAL, x, y, z);
+}
+
+static void GLAPIENTRY
+save_Normal3fv(const GLfloat * v)
+{
+ save_Attr3fNV(VERT_ATTRIB_NORMAL, v[0], v[1], v[2]);
+}
+
+static void GLAPIENTRY
+save_FogCoordfEXT(GLfloat x)
+{
+ save_Attr1fNV(VERT_ATTRIB_FOG, x);
+}
+
+static void GLAPIENTRY
+save_FogCoordfvEXT(const GLfloat * v)
+{
+ save_Attr1fNV(VERT_ATTRIB_FOG, v[0]);
+}
+
+static void GLAPIENTRY
+save_Color3f(GLfloat x, GLfloat y, GLfloat z)
+{
+ save_Attr3fNV(VERT_ATTRIB_COLOR0, x, y, z);
+}
+
+static void GLAPIENTRY
+save_Color3fv(const GLfloat * v)
+{
+ save_Attr3fNV(VERT_ATTRIB_COLOR0, v[0], v[1], v[2]);
+}
+
+static void GLAPIENTRY
+save_Color4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ save_Attr4fNV(VERT_ATTRIB_COLOR0, x, y, z, w);
+}
+
+static void GLAPIENTRY
+save_Color4fv(const GLfloat * v)
+{
+ save_Attr4fNV(VERT_ATTRIB_COLOR0, v[0], v[1], v[2], v[3]);
+}
+
+static void GLAPIENTRY
+save_SecondaryColor3fEXT(GLfloat x, GLfloat y, GLfloat z)
+{
+ save_Attr3fNV(VERT_ATTRIB_COLOR1, x, y, z);
+}
+
+static void GLAPIENTRY
+save_SecondaryColor3fvEXT(const GLfloat * v)
+{
+ save_Attr3fNV(VERT_ATTRIB_COLOR1, v[0], v[1], v[2]);
+}
+
+
+/* Just call the respective ATTR for texcoord
+ */
+static void GLAPIENTRY
+save_MultiTexCoord1f(GLenum target, GLfloat x)
+{
+ GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
+ save_Attr1fNV(attr, x);
+}
+
+static void GLAPIENTRY
+save_MultiTexCoord1fv(GLenum target, const GLfloat * v)
+{
+ GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
+ save_Attr1fNV(attr, v[0]);
+}
+
+static void GLAPIENTRY
+save_MultiTexCoord2f(GLenum target, GLfloat x, GLfloat y)
+{
+ GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
+ save_Attr2fNV(attr, x, y);
+}
+
+static void GLAPIENTRY
+save_MultiTexCoord2fv(GLenum target, const GLfloat * v)
+{
+ GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
+ save_Attr2fNV(attr, v[0], v[1]);
+}
+
+static void GLAPIENTRY
+save_MultiTexCoord3f(GLenum target, GLfloat x, GLfloat y, GLfloat z)
+{
+ GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
+ save_Attr3fNV(attr, x, y, z);
+}
+
+static void GLAPIENTRY
+save_MultiTexCoord3fv(GLenum target, const GLfloat * v)
+{
+ GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
+ save_Attr3fNV(attr, v[0], v[1], v[2]);
+}
+
+static void GLAPIENTRY
+save_MultiTexCoord4f(GLenum target, GLfloat x, GLfloat y,
+ GLfloat z, GLfloat w)
+{
+ GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
+ save_Attr4fNV(attr, x, y, z, w);
+}
+
+static void GLAPIENTRY
+save_MultiTexCoord4fv(GLenum target, const GLfloat * v)
+{
+ GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
+ save_Attr4fNV(attr, v[0], v[1], v[2], v[3]);
+}
+
+
+/**
+ * Record a GL_INVALID_VALUE error when a invalid vertex attribute
+ * index is found.
+ */
+static void
+index_error(void)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ _mesa_error(ctx, GL_INVALID_VALUE, "VertexAttribf(index)");
+}
+
+
+/* First level for NV_vertex_program:
+ *
+ * Check for errors at compile time?.
+ */
+static void GLAPIENTRY
+save_VertexAttrib1fNV(GLuint index, GLfloat x)
+{
+ if (index < VERT_ATTRIB_MAX)
+ save_Attr1fNV(index, x);
+ else
+ index_error();
+}
+
+static void GLAPIENTRY
+save_VertexAttrib1fvNV(GLuint index, const GLfloat * v)
+{
+ if (index < VERT_ATTRIB_MAX)
+ save_Attr1fNV(index, v[0]);
+ else
+ index_error();
+}
+
+static void GLAPIENTRY
+save_VertexAttrib2fNV(GLuint index, GLfloat x, GLfloat y)
+{
+ if (index < VERT_ATTRIB_MAX)
+ save_Attr2fNV(index, x, y);
+ else
+ index_error();
+}
+
+static void GLAPIENTRY
+save_VertexAttrib2fvNV(GLuint index, const GLfloat * v)
+{
+ if (index < VERT_ATTRIB_MAX)
+ save_Attr2fNV(index, v[0], v[1]);
+ else
+ index_error();
+}
+
+static void GLAPIENTRY
+save_VertexAttrib3fNV(GLuint index, GLfloat x, GLfloat y, GLfloat z)
+{
+ if (index < VERT_ATTRIB_MAX)
+ save_Attr3fNV(index, x, y, z);
+ else
+ index_error();
+}
+
+static void GLAPIENTRY
+save_VertexAttrib3fvNV(GLuint index, const GLfloat * v)
+{
+ if (index < VERT_ATTRIB_MAX)
+ save_Attr3fNV(index, v[0], v[1], v[2]);
+ else
+ index_error();
+}
+
+static void GLAPIENTRY
+save_VertexAttrib4fNV(GLuint index, GLfloat x, GLfloat y,
+ GLfloat z, GLfloat w)
+{
+ if (index < VERT_ATTRIB_MAX)
+ save_Attr4fNV(index, x, y, z, w);
+ else
+ index_error();
+}
+
+static void GLAPIENTRY
+save_VertexAttrib4fvNV(GLuint index, const GLfloat * v)
+{
+ if (index < VERT_ATTRIB_MAX)
+ save_Attr4fNV(index, v[0], v[1], v[2], v[3]);
+ else
+ index_error();
+}
+
+
+
+
+static void GLAPIENTRY
+save_VertexAttrib1fARB(GLuint index, GLfloat x)
+{
+ if (index < VERT_ATTRIB_MAX)
+ save_Attr1fARB(index, x);
+ else
+ index_error();
+}
+
+static void GLAPIENTRY
+save_VertexAttrib1fvARB(GLuint index, const GLfloat * v)
+{
+ if (index < VERT_ATTRIB_MAX)
+ save_Attr1fARB(index, v[0]);
+ else
+ index_error();
+}
+
+static void GLAPIENTRY
+save_VertexAttrib2fARB(GLuint index, GLfloat x, GLfloat y)
+{
+ if (index < VERT_ATTRIB_MAX)
+ save_Attr2fARB(index, x, y);
+ else
+ index_error();
+}
+
+static void GLAPIENTRY
+save_VertexAttrib2fvARB(GLuint index, const GLfloat * v)
+{
+ if (index < VERT_ATTRIB_MAX)
+ save_Attr2fARB(index, v[0], v[1]);
+ else
+ index_error();
+}
+
+static void GLAPIENTRY
+save_VertexAttrib3fARB(GLuint index, GLfloat x, GLfloat y, GLfloat z)
+{
+ if (index < VERT_ATTRIB_MAX)
+ save_Attr3fARB(index, x, y, z);
+ else
+ index_error();
+}
+
+static void GLAPIENTRY
+save_VertexAttrib3fvARB(GLuint index, const GLfloat * v)
+{
+ if (index < VERT_ATTRIB_MAX)
+ save_Attr3fARB(index, v[0], v[1], v[2]);
+ else
+ index_error();
+}
+
+static void GLAPIENTRY
+save_VertexAttrib4fARB(GLuint index, GLfloat x, GLfloat y, GLfloat z,
+ GLfloat w)
+{
+ if (index < VERT_ATTRIB_MAX)
+ save_Attr4fARB(index, x, y, z, w);
+ else
+ index_error();
+}
+
+static void GLAPIENTRY
+save_VertexAttrib4fvARB(GLuint index, const GLfloat * v)
+{
+ if (index < VERT_ATTRIB_MAX)
+ save_Attr4fARB(index, v[0], v[1], v[2], v[3]);
+ else
+ index_error();
+}
+
+
+#if FEATURE_EXT_framebuffer_blit
+static void GLAPIENTRY
+save_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_BLIT_FRAMEBUFFER, 10);
+ if (n) {
+ n[1].i = srcX0;
+ n[2].i = srcY0;
+ n[3].i = srcX1;
+ n[4].i = srcY1;
+ n[5].i = dstX0;
+ n[6].i = dstY0;
+ n[7].i = dstX1;
+ n[8].i = dstY1;
+ n[9].i = mask;
+ n[10].e = filter;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_BlitFramebufferEXT(ctx->Exec, (srcX0, srcY0, srcX1, srcY1,
+ dstX0, dstY0, dstX1, dstY1,
+ mask, filter));
+ }
+}
+#endif
+
+
+/**
+ * Save an error-generating command into display list.
+ *
+ * KW: Will appear in the list before the vertex buffer containing the
+ * command that provoked the error. I don't see this as a problem.
+ */
+static void
+save_error(GLcontext *ctx, GLenum error, const char *s)
+{
+ Node *n;
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_ERROR, 2);
+ if (n) {
+ n[1].e = error;
+ n[2].data = (void *) s;
+ }
+}
+
+
+/**
+ * Compile an error into current display list.
+ */
+void
+_mesa_compile_error(GLcontext *ctx, GLenum error, const char *s)
+{
+ if (ctx->CompileFlag)
+ save_error(ctx, error, s);
+ if (ctx->ExecuteFlag)
+ _mesa_error(ctx, error, s);
+}
+
+
+/**
+ * Test if ID names a display list.
+ */
+static GLboolean
+islist(GLcontext *ctx, GLuint list)
+{
+ if (list > 0 && _mesa_HashLookup(ctx->Shared->DisplayList, list)) {
+ return GL_TRUE;
+ }
+ else {
+ return GL_FALSE;
+ }
+}
+
+
+
+/**********************************************************************/
+/* Display list execution */
+/**********************************************************************/
+
+
+/*
+ * Execute a display list. Note that the ListBase offset must have already
+ * been added before calling this function. I.e. the list argument is
+ * the absolute list number, not relative to ListBase.
+ * \param list - display list number
+ */
+static void
+execute_list(GLcontext *ctx, GLuint list)
+{
+ struct mesa_display_list *dlist;
+ Node *n;
+ GLboolean done;
+
+ if (list == 0 || !islist(ctx, list))
+ return;
+
+ if (ctx->ListState.CallDepth == MAX_LIST_NESTING) {
+ /* raise an error? */
+ return;
+ }
+
+
+ dlist =
+ (struct mesa_display_list *) _mesa_HashLookup(ctx->Shared->DisplayList,
+ list);
+ if (!dlist)
+ return;
+
+ ctx->ListState.CallStack[ctx->ListState.CallDepth++] = dlist;
+
+ if (ctx->Driver.BeginCallList)
+ ctx->Driver.BeginCallList(ctx, dlist);
+
+ n = dlist->node;
+
+ done = GL_FALSE;
+ while (!done) {
+ OpCode opcode = n[0].opcode;
+ int i = (int) n[0].opcode - (int) OPCODE_EXT_0;
+
+ if (i >= 0 && i < (GLint) ctx->ListExt.NumOpcodes) {
+ /* this is a driver-extended opcode */
+ ctx->ListExt.Opcode[i].Execute(ctx, &n[1]);
+ n += ctx->ListExt.Opcode[i].Size;
+ }
+ else {
+ switch (opcode) {
+ case OPCODE_ERROR:
+ _mesa_error(ctx, n[1].e, (const char *) n[2].data);
+ break;
+ case OPCODE_ACCUM:
+ CALL_Accum(ctx->Exec, (n[1].e, n[2].f));
+ break;
+ case OPCODE_ALPHA_FUNC:
+ CALL_AlphaFunc(ctx->Exec, (n[1].e, n[2].f));
+ break;
+ case OPCODE_BIND_TEXTURE:
+ CALL_BindTexture(ctx->Exec, (n[1].e, n[2].ui));
+ break;
+ case OPCODE_BITMAP:
+ {
+ const struct gl_pixelstore_attrib save = ctx->Unpack;
+ ctx->Unpack = ctx->DefaultPacking;
+ CALL_Bitmap(ctx->Exec, ((GLsizei) n[1].i, (GLsizei) n[2].i,
+ n[3].f, n[4].f, n[5].f, n[6].f,
+ (const GLubyte *) n[7].data));
+ ctx->Unpack = save; /* restore */
+ }
+ break;
+ case OPCODE_BLEND_COLOR:
+ CALL_BlendColor(ctx->Exec, (n[1].f, n[2].f, n[3].f, n[4].f));
+ break;
+ case OPCODE_BLEND_EQUATION:
+ CALL_BlendEquation(ctx->Exec, (n[1].e));
+ break;
+ case OPCODE_BLEND_EQUATION_SEPARATE:
+ CALL_BlendEquationSeparateEXT(ctx->Exec, (n[1].e, n[2].e));
+ break;
+ case OPCODE_BLEND_FUNC_SEPARATE:
+ CALL_BlendFuncSeparateEXT(ctx->Exec,
+ (n[1].e, n[2].e, n[3].e, n[4].e));
+ break;
+ case OPCODE_CALL_LIST:
+ /* Generated by glCallList(), don't add ListBase */
+ if (ctx->ListState.CallDepth < MAX_LIST_NESTING) {
+ execute_list(ctx, n[1].ui);
+ }
+ break;
+ case OPCODE_CALL_LIST_OFFSET:
+ /* Generated by glCallLists() so we must add ListBase */
+ if (n[2].b) {
+ /* user specified a bad data type at compile time */
+ _mesa_error(ctx, GL_INVALID_ENUM, "glCallLists(type)");
+ }
+ else if (ctx->ListState.CallDepth < MAX_LIST_NESTING) {
+ execute_list(ctx, ctx->List.ListBase + n[1].ui);
+ }
+ break;
+ case OPCODE_CLEAR:
+ CALL_Clear(ctx->Exec, (n[1].bf));
+ break;
+ case OPCODE_CLEAR_COLOR:
+ CALL_ClearColor(ctx->Exec, (n[1].f, n[2].f, n[3].f, n[4].f));
+ break;
+ case OPCODE_CLEAR_ACCUM:
+ CALL_ClearAccum(ctx->Exec, (n[1].f, n[2].f, n[3].f, n[4].f));
+ break;
+ case OPCODE_CLEAR_DEPTH:
+ CALL_ClearDepth(ctx->Exec, ((GLclampd) n[1].f));
+ break;
+ case OPCODE_CLEAR_INDEX:
+ CALL_ClearIndex(ctx->Exec, ((GLfloat) n[1].ui));
+ break;
+ case OPCODE_CLEAR_STENCIL:
+ CALL_ClearStencil(ctx->Exec, (n[1].i));
+ break;
+ case OPCODE_CLIP_PLANE:
+ {
+ GLdouble eq[4];
+ eq[0] = n[2].f;
+ eq[1] = n[3].f;
+ eq[2] = n[4].f;
+ eq[3] = n[5].f;
+ CALL_ClipPlane(ctx->Exec, (n[1].e, eq));
+ }
+ break;
+ case OPCODE_COLOR_MASK:
+ CALL_ColorMask(ctx->Exec, (n[1].b, n[2].b, n[3].b, n[4].b));
+ break;
+ case OPCODE_COLOR_MATERIAL:
+ CALL_ColorMaterial(ctx->Exec, (n[1].e, n[2].e));
+ break;
+ case OPCODE_COLOR_TABLE:
+ {
+ const struct gl_pixelstore_attrib save = ctx->Unpack;
+ ctx->Unpack = ctx->DefaultPacking;
+ CALL_ColorTable(ctx->Exec, (n[1].e, n[2].e, n[3].i, n[4].e,
+ n[5].e, n[6].data));
+ ctx->Unpack = save; /* restore */
+ }
+ break;
+ case OPCODE_COLOR_TABLE_PARAMETER_FV:
+ {
+ GLfloat params[4];
+ params[0] = n[3].f;
+ params[1] = n[4].f;
+ params[2] = n[5].f;
+ params[3] = n[6].f;
+ CALL_ColorTableParameterfv(ctx->Exec,
+ (n[1].e, n[2].e, params));
+ }
+ break;
+ case OPCODE_COLOR_TABLE_PARAMETER_IV:
+ {
+ GLint params[4];
+ params[0] = n[3].i;
+ params[1] = n[4].i;
+ params[2] = n[5].i;
+ params[3] = n[6].i;
+ CALL_ColorTableParameteriv(ctx->Exec,
+ (n[1].e, n[2].e, params));
+ }
+ break;
+ case OPCODE_COLOR_SUB_TABLE:
+ {
+ const struct gl_pixelstore_attrib save = ctx->Unpack;
+ ctx->Unpack = ctx->DefaultPacking;
+ CALL_ColorSubTable(ctx->Exec, (n[1].e, n[2].i, n[3].i,
+ n[4].e, n[5].e, n[6].data));
+ ctx->Unpack = save; /* restore */
+ }
+ break;
+ case OPCODE_CONVOLUTION_FILTER_1D:
+ {
+ const struct gl_pixelstore_attrib save = ctx->Unpack;
+ ctx->Unpack = ctx->DefaultPacking;
+ CALL_ConvolutionFilter1D(ctx->Exec, (n[1].e, n[2].i, n[3].i,
+ n[4].e, n[5].e,
+ n[6].data));
+ ctx->Unpack = save; /* restore */
+ }
+ break;
+ case OPCODE_CONVOLUTION_FILTER_2D:
+ {
+ const struct gl_pixelstore_attrib save = ctx->Unpack;
+ ctx->Unpack = ctx->DefaultPacking;
+ CALL_ConvolutionFilter2D(ctx->Exec, (n[1].e, n[2].i, n[3].i,
+ n[4].i, n[5].e, n[6].e,
+ n[7].data));
+ ctx->Unpack = save; /* restore */
+ }
+ break;
+ case OPCODE_CONVOLUTION_PARAMETER_I:
+ CALL_ConvolutionParameteri(ctx->Exec, (n[1].e, n[2].e, n[3].i));
+ break;
+ case OPCODE_CONVOLUTION_PARAMETER_IV:
+ {
+ GLint params[4];
+ params[0] = n[3].i;
+ params[1] = n[4].i;
+ params[2] = n[5].i;
+ params[3] = n[6].i;
+ CALL_ConvolutionParameteriv(ctx->Exec,
+ (n[1].e, n[2].e, params));
+ }
+ break;
+ case OPCODE_CONVOLUTION_PARAMETER_F:
+ CALL_ConvolutionParameterf(ctx->Exec, (n[1].e, n[2].e, n[3].f));
+ break;
+ case OPCODE_CONVOLUTION_PARAMETER_FV:
+ {
+ GLfloat params[4];
+ params[0] = n[3].f;
+ params[1] = n[4].f;
+ params[2] = n[5].f;
+ params[3] = n[6].f;
+ CALL_ConvolutionParameterfv(ctx->Exec,
+ (n[1].e, n[2].e, params));
+ }
+ break;
+ case OPCODE_COPY_COLOR_SUB_TABLE:
+ CALL_CopyColorSubTable(ctx->Exec, (n[1].e, n[2].i,
+ n[3].i, n[4].i, n[5].i));
+ break;
+ case OPCODE_COPY_COLOR_TABLE:
+ CALL_CopyColorSubTable(ctx->Exec, (n[1].e, n[2].i,
+ n[3].i, n[4].i, n[5].i));
+ break;
+ case OPCODE_COPY_PIXELS:
+ CALL_CopyPixels(ctx->Exec, (n[1].i, n[2].i,
+ (GLsizei) n[3].i, (GLsizei) n[4].i,
+ n[5].e));
+ break;
+ case OPCODE_COPY_TEX_IMAGE1D:
+ CALL_CopyTexImage1D(ctx->Exec, (n[1].e, n[2].i, n[3].e, n[4].i,
+ n[5].i, n[6].i, n[7].i));
+ break;
+ case OPCODE_COPY_TEX_IMAGE2D:
+ CALL_CopyTexImage2D(ctx->Exec, (n[1].e, n[2].i, n[3].e, n[4].i,
+ n[5].i, n[6].i, n[7].i, n[8].i));
+ break;
+ case OPCODE_COPY_TEX_SUB_IMAGE1D:
+ CALL_CopyTexSubImage1D(ctx->Exec, (n[1].e, n[2].i, n[3].i,
+ n[4].i, n[5].i, n[6].i));
+ break;
+ case OPCODE_COPY_TEX_SUB_IMAGE2D:
+ CALL_CopyTexSubImage2D(ctx->Exec, (n[1].e, n[2].i, n[3].i,
+ n[4].i, n[5].i, n[6].i, n[7].i,
+ n[8].i));
+ break;
+ case OPCODE_COPY_TEX_SUB_IMAGE3D:
+ CALL_CopyTexSubImage3D(ctx->Exec, (n[1].e, n[2].i, n[3].i,
+ n[4].i, n[5].i, n[6].i, n[7].i,
+ n[8].i, n[9].i));
+ break;
+ case OPCODE_CULL_FACE:
+ CALL_CullFace(ctx->Exec, (n[1].e));
+ break;
+ case OPCODE_DEPTH_FUNC:
+ CALL_DepthFunc(ctx->Exec, (n[1].e));
+ break;
+ case OPCODE_DEPTH_MASK:
+ CALL_DepthMask(ctx->Exec, (n[1].b));
+ break;
+ case OPCODE_DEPTH_RANGE:
+ CALL_DepthRange(ctx->Exec,
+ ((GLclampd) n[1].f, (GLclampd) n[2].f));
+ break;
+ case OPCODE_DISABLE:
+ CALL_Disable(ctx->Exec, (n[1].e));
+ break;
+ case OPCODE_DRAW_BUFFER:
+ CALL_DrawBuffer(ctx->Exec, (n[1].e));
+ break;
+ case OPCODE_DRAW_PIXELS:
+ {
+ const struct gl_pixelstore_attrib save = ctx->Unpack;
+ ctx->Unpack = ctx->DefaultPacking;
+ CALL_DrawPixels(ctx->Exec, (n[1].i, n[2].i, n[3].e, n[4].e,
+ n[5].data));
+ ctx->Unpack = save; /* restore */
+ }
+ break;
+ case OPCODE_ENABLE:
+ CALL_Enable(ctx->Exec, (n[1].e));
+ break;
+ case OPCODE_EVALMESH1:
+ CALL_EvalMesh1(ctx->Exec, (n[1].e, n[2].i, n[3].i));
+ break;
+ case OPCODE_EVALMESH2:
+ CALL_EvalMesh2(ctx->Exec,
+ (n[1].e, n[2].i, n[3].i, n[4].i, n[5].i));
+ break;
+ case OPCODE_FOG:
+ {
+ GLfloat p[4];
+ p[0] = n[2].f;
+ p[1] = n[3].f;
+ p[2] = n[4].f;
+ p[3] = n[5].f;
+ CALL_Fogfv(ctx->Exec, (n[1].e, p));
+ }
+ break;
+ case OPCODE_FRONT_FACE:
+ CALL_FrontFace(ctx->Exec, (n[1].e));
+ break;
+ case OPCODE_FRUSTUM:
+ CALL_Frustum(ctx->Exec,
+ (n[1].f, n[2].f, n[3].f, n[4].f, n[5].f, n[6].f));
+ break;
+ case OPCODE_HINT:
+ CALL_Hint(ctx->Exec, (n[1].e, n[2].e));
+ break;
+ case OPCODE_HISTOGRAM:
+ CALL_Histogram(ctx->Exec, (n[1].e, n[2].i, n[3].e, n[4].b));
+ break;
+ case OPCODE_INDEX_MASK:
+ CALL_IndexMask(ctx->Exec, (n[1].ui));
+ break;
+ case OPCODE_INIT_NAMES:
+ CALL_InitNames(ctx->Exec, ());
+ break;
+ case OPCODE_LIGHT:
+ {
+ GLfloat p[4];
+ p[0] = n[3].f;
+ p[1] = n[4].f;
+ p[2] = n[5].f;
+ p[3] = n[6].f;
+ CALL_Lightfv(ctx->Exec, (n[1].e, n[2].e, p));
+ }
+ break;
+ case OPCODE_LIGHT_MODEL:
+ {
+ GLfloat p[4];
+ p[0] = n[2].f;
+ p[1] = n[3].f;
+ p[2] = n[4].f;
+ p[3] = n[5].f;
+ CALL_LightModelfv(ctx->Exec, (n[1].e, p));
+ }
+ break;
+ case OPCODE_LINE_STIPPLE:
+ CALL_LineStipple(ctx->Exec, (n[1].i, n[2].us));
+ break;
+ case OPCODE_LINE_WIDTH:
+ CALL_LineWidth(ctx->Exec, (n[1].f));
+ break;
+ case OPCODE_LIST_BASE:
+ CALL_ListBase(ctx->Exec, (n[1].ui));
+ break;
+ case OPCODE_LOAD_IDENTITY:
+ CALL_LoadIdentity(ctx->Exec, ());
+ break;
+ case OPCODE_LOAD_MATRIX:
+ if (sizeof(Node) == sizeof(GLfloat)) {
+ CALL_LoadMatrixf(ctx->Exec, (&n[1].f));
+ }
+ else {
+ GLfloat m[16];
+ GLuint i;
+ for (i = 0; i < 16; i++) {
+ m[i] = n[1 + i].f;
+ }
+ CALL_LoadMatrixf(ctx->Exec, (m));
+ }
+ break;
+ case OPCODE_LOAD_NAME:
+ CALL_LoadName(ctx->Exec, (n[1].ui));
+ break;
+ case OPCODE_LOGIC_OP:
+ CALL_LogicOp(ctx->Exec, (n[1].e));
+ break;
+ case OPCODE_MAP1:
+ {
+ GLenum target = n[1].e;
+ GLint ustride = _mesa_evaluator_components(target);
+ GLint uorder = n[5].i;
+ GLfloat u1 = n[2].f;
+ GLfloat u2 = n[3].f;
+ CALL_Map1f(ctx->Exec, (target, u1, u2, ustride, uorder,
+ (GLfloat *) n[6].data));
+ }
+ break;
+ case OPCODE_MAP2:
+ {
+ GLenum target = n[1].e;
+ GLfloat u1 = n[2].f;
+ GLfloat u2 = n[3].f;
+ GLfloat v1 = n[4].f;
+ GLfloat v2 = n[5].f;
+ GLint ustride = n[6].i;
+ GLint vstride = n[7].i;
+ GLint uorder = n[8].i;
+ GLint vorder = n[9].i;
+ CALL_Map2f(ctx->Exec, (target, u1, u2, ustride, uorder,
+ v1, v2, vstride, vorder,
+ (GLfloat *) n[10].data));
+ }
+ break;
+ case OPCODE_MAPGRID1:
+ CALL_MapGrid1f(ctx->Exec, (n[1].i, n[2].f, n[3].f));
+ break;
+ case OPCODE_MAPGRID2:
+ CALL_MapGrid2f(ctx->Exec,
+ (n[1].i, n[2].f, n[3].f, n[4].i, n[5].f, n[6].f));
+ break;
+ case OPCODE_MATRIX_MODE:
+ CALL_MatrixMode(ctx->Exec, (n[1].e));
+ break;
+ case OPCODE_MIN_MAX:
+ CALL_Minmax(ctx->Exec, (n[1].e, n[2].e, n[3].b));
+ break;
+ case OPCODE_MULT_MATRIX:
+ if (sizeof(Node) == sizeof(GLfloat)) {
+ CALL_MultMatrixf(ctx->Exec, (&n[1].f));
+ }
+ else {
+ GLfloat m[16];
+ GLuint i;
+ for (i = 0; i < 16; i++) {
+ m[i] = n[1 + i].f;
+ }
+ CALL_MultMatrixf(ctx->Exec, (m));
+ }
+ break;
+ case OPCODE_ORTHO:
+ CALL_Ortho(ctx->Exec,
+ (n[1].f, n[2].f, n[3].f, n[4].f, n[5].f, n[6].f));
+ break;
+ case OPCODE_PASSTHROUGH:
+ CALL_PassThrough(ctx->Exec, (n[1].f));
+ break;
+ case OPCODE_PIXEL_MAP:
+ CALL_PixelMapfv(ctx->Exec,
+ (n[1].e, n[2].i, (GLfloat *) n[3].data));
+ break;
+ case OPCODE_PIXEL_TRANSFER:
+ CALL_PixelTransferf(ctx->Exec, (n[1].e, n[2].f));
+ break;
+ case OPCODE_PIXEL_ZOOM:
+ CALL_PixelZoom(ctx->Exec, (n[1].f, n[2].f));
+ break;
+ case OPCODE_POINT_SIZE:
+ CALL_PointSize(ctx->Exec, (n[1].f));
+ break;
+ case OPCODE_POINT_PARAMETERS:
+ {
+ GLfloat params[3];
+ params[0] = n[2].f;
+ params[1] = n[3].f;
+ params[2] = n[4].f;
+ CALL_PointParameterfvEXT(ctx->Exec, (n[1].e, params));
+ }
+ break;
+ case OPCODE_POLYGON_MODE:
+ CALL_PolygonMode(ctx->Exec, (n[1].e, n[2].e));
+ break;
+ case OPCODE_POLYGON_STIPPLE:
+ CALL_PolygonStipple(ctx->Exec, ((GLubyte *) n[1].data));
+ break;
+ case OPCODE_POLYGON_OFFSET:
+ CALL_PolygonOffset(ctx->Exec, (n[1].f, n[2].f));
+ break;
+ case OPCODE_POP_ATTRIB:
+ CALL_PopAttrib(ctx->Exec, ());
+ break;
+ case OPCODE_POP_MATRIX:
+ CALL_PopMatrix(ctx->Exec, ());
+ break;
+ case OPCODE_POP_NAME:
+ CALL_PopName(ctx->Exec, ());
+ break;
+ case OPCODE_PRIORITIZE_TEXTURE:
+ CALL_PrioritizeTextures(ctx->Exec, (1, &n[1].ui, &n[2].f));
+ break;
+ case OPCODE_PUSH_ATTRIB:
+ CALL_PushAttrib(ctx->Exec, (n[1].bf));
+ break;
+ case OPCODE_PUSH_MATRIX:
+ CALL_PushMatrix(ctx->Exec, ());
+ break;
+ case OPCODE_PUSH_NAME:
+ CALL_PushName(ctx->Exec, (n[1].ui));
+ break;
+ case OPCODE_RASTER_POS:
+ CALL_RasterPos4f(ctx->Exec, (n[1].f, n[2].f, n[3].f, n[4].f));
+ break;
+ case OPCODE_READ_BUFFER:
+ CALL_ReadBuffer(ctx->Exec, (n[1].e));
+ break;
+ case OPCODE_RESET_HISTOGRAM:
+ CALL_ResetHistogram(ctx->Exec, (n[1].e));
+ break;
+ case OPCODE_RESET_MIN_MAX:
+ CALL_ResetMinmax(ctx->Exec, (n[1].e));
+ break;
+ case OPCODE_ROTATE:
+ CALL_Rotatef(ctx->Exec, (n[1].f, n[2].f, n[3].f, n[4].f));
+ break;
+ case OPCODE_SCALE:
+ CALL_Scalef(ctx->Exec, (n[1].f, n[2].f, n[3].f));
+ break;
+ case OPCODE_SCISSOR:
+ CALL_Scissor(ctx->Exec, (n[1].i, n[2].i, n[3].i, n[4].i));
+ break;
+ case OPCODE_SHADE_MODEL:
+ CALL_ShadeModel(ctx->Exec, (n[1].e));
+ break;
+ case OPCODE_STENCIL_FUNC:
+ CALL_StencilFunc(ctx->Exec, (n[1].e, n[2].i, n[3].ui));
+ break;
+ case OPCODE_STENCIL_MASK:
+ CALL_StencilMask(ctx->Exec, (n[1].ui));
+ break;
+ case OPCODE_STENCIL_OP:
+ CALL_StencilOp(ctx->Exec, (n[1].e, n[2].e, n[3].e));
+ break;
+ case OPCODE_STENCIL_FUNC_SEPARATE:
+ CALL_StencilFuncSeparate(ctx->Exec,
+ (n[1].e, n[2].e, n[3].i, n[4].ui));
+ break;
+ case OPCODE_STENCIL_MASK_SEPARATE:
+ CALL_StencilMaskSeparate(ctx->Exec, (n[1].e, n[2].ui));
+ break;
+ case OPCODE_STENCIL_OP_SEPARATE:
+ CALL_StencilOpSeparate(ctx->Exec,
+ (n[1].e, n[2].e, n[3].e, n[4].e));
+ break;
+ case OPCODE_TEXENV:
+ {
+ GLfloat params[4];
+ params[0] = n[3].f;
+ params[1] = n[4].f;
+ params[2] = n[5].f;
+ params[3] = n[6].f;
+ CALL_TexEnvfv(ctx->Exec, (n[1].e, n[2].e, params));
+ }
+ break;
+ case OPCODE_TEXGEN:
+ {
+ GLfloat params[4];
+ params[0] = n[3].f;
+ params[1] = n[4].f;
+ params[2] = n[5].f;
+ params[3] = n[6].f;
+ CALL_TexGenfv(ctx->Exec, (n[1].e, n[2].e, params));
+ }
+ break;
+ case OPCODE_TEXPARAMETER:
+ {
+ GLfloat params[4];
+ params[0] = n[3].f;
+ params[1] = n[4].f;
+ params[2] = n[5].f;
+ params[3] = n[6].f;
+ CALL_TexParameterfv(ctx->Exec, (n[1].e, n[2].e, params));
+ }
+ break;
+ case OPCODE_TEX_IMAGE1D:
+ {
+ const struct gl_pixelstore_attrib save = ctx->Unpack;
+ ctx->Unpack = ctx->DefaultPacking;
+ CALL_TexImage1D(ctx->Exec, (n[1].e, /* target */
+ n[2].i, /* level */
+ n[3].i, /* components */
+ n[4].i, /* width */
+ n[5].e, /* border */
+ n[6].e, /* format */
+ n[7].e, /* type */
+ n[8].data));
+ ctx->Unpack = save; /* restore */
+ }
+ break;
+ case OPCODE_TEX_IMAGE2D:
+ {
+ const struct gl_pixelstore_attrib save = ctx->Unpack;
+ ctx->Unpack = ctx->DefaultPacking;
+ CALL_TexImage2D(ctx->Exec, (n[1].e, /* target */
+ n[2].i, /* level */
+ n[3].i, /* components */
+ n[4].i, /* width */
+ n[5].i, /* height */
+ n[6].e, /* border */
+ n[7].e, /* format */
+ n[8].e, /* type */
+ n[9].data));
+ ctx->Unpack = save; /* restore */
+ }
+ break;
+ case OPCODE_TEX_IMAGE3D:
+ {
+ const struct gl_pixelstore_attrib save = ctx->Unpack;
+ ctx->Unpack = ctx->DefaultPacking;
+ CALL_TexImage3D(ctx->Exec, (n[1].e, /* target */
+ n[2].i, /* level */
+ n[3].i, /* components */
+ n[4].i, /* width */
+ n[5].i, /* height */
+ n[6].i, /* depth */
+ n[7].e, /* border */
+ n[8].e, /* format */
+ n[9].e, /* type */
+ n[10].data));
+ ctx->Unpack = save; /* restore */
+ }
+ break;
+ case OPCODE_TEX_SUB_IMAGE1D:
+ {
+ const struct gl_pixelstore_attrib save = ctx->Unpack;
+ ctx->Unpack = ctx->DefaultPacking;
+ CALL_TexSubImage1D(ctx->Exec, (n[1].e, n[2].i, n[3].i,
+ n[4].i, n[5].e,
+ n[6].e, n[7].data));
+ ctx->Unpack = save; /* restore */
+ }
+ break;
+ case OPCODE_TEX_SUB_IMAGE2D:
+ {
+ const struct gl_pixelstore_attrib save = ctx->Unpack;
+ ctx->Unpack = ctx->DefaultPacking;
+ CALL_TexSubImage2D(ctx->Exec, (n[1].e, n[2].i, n[3].i,
+ n[4].i, n[5].e,
+ n[6].i, n[7].e, n[8].e,
+ n[9].data));
+ ctx->Unpack = save; /* restore */
+ }
+ break;
+ case OPCODE_TEX_SUB_IMAGE3D:
+ {
+ const struct gl_pixelstore_attrib save = ctx->Unpack;
+ ctx->Unpack = ctx->DefaultPacking;
+ CALL_TexSubImage3D(ctx->Exec, (n[1].e, n[2].i, n[3].i,
+ n[4].i, n[5].i, n[6].i, n[7].i,
+ n[8].i, n[9].e, n[10].e,
+ n[11].data));
+ ctx->Unpack = save; /* restore */
+ }
+ break;
+ case OPCODE_TRANSLATE:
+ CALL_Translatef(ctx->Exec, (n[1].f, n[2].f, n[3].f));
+ break;
+ case OPCODE_VIEWPORT:
+ CALL_Viewport(ctx->Exec, (n[1].i, n[2].i,
+ (GLsizei) n[3].i, (GLsizei) n[4].i));
+ break;
+ case OPCODE_WINDOW_POS:
+ CALL_WindowPos4fMESA(ctx->Exec, (n[1].f, n[2].f, n[3].f, n[4].f));
+ break;
+ case OPCODE_ACTIVE_TEXTURE: /* GL_ARB_multitexture */
+ CALL_ActiveTextureARB(ctx->Exec, (n[1].e));
+ break;
+ case OPCODE_COMPRESSED_TEX_IMAGE_1D: /* GL_ARB_texture_compression */
+ CALL_CompressedTexImage1DARB(ctx->Exec, (n[1].e, n[2].i, n[3].e,
+ n[4].i, n[5].i, n[6].i,
+ n[7].data));
+ break;
+ case OPCODE_COMPRESSED_TEX_IMAGE_2D: /* GL_ARB_texture_compression */
+ CALL_CompressedTexImage2DARB(ctx->Exec, (n[1].e, n[2].i, n[3].e,
+ n[4].i, n[5].i, n[6].i,
+ n[7].i, n[8].data));
+ break;
+ case OPCODE_COMPRESSED_TEX_IMAGE_3D: /* GL_ARB_texture_compression */
+ CALL_CompressedTexImage3DARB(ctx->Exec, (n[1].e, n[2].i, n[3].e,
+ n[4].i, n[5].i, n[6].i,
+ n[7].i, n[8].i,
+ n[9].data));
+ break;
+ case OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D: /* GL_ARB_texture_compress */
+ CALL_CompressedTexSubImage1DARB(ctx->Exec,
+ (n[1].e, n[2].i, n[3].i, n[4].i,
+ n[5].e, n[6].i, n[7].data));
+ break;
+ case OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D: /* GL_ARB_texture_compress */
+ CALL_CompressedTexSubImage2DARB(ctx->Exec,
+ (n[1].e, n[2].i, n[3].i, n[4].i,
+ n[5].i, n[6].i, n[7].e, n[8].i,
+ n[9].data));
+ break;
+ case OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D: /* GL_ARB_texture_compress */
+ CALL_CompressedTexSubImage3DARB(ctx->Exec,
+ (n[1].e, n[2].i, n[3].i, n[4].i,
+ n[5].i, n[6].i, n[7].i, n[8].i,
+ n[9].e, n[10].i, n[11].data));
+ break;
+ case OPCODE_SAMPLE_COVERAGE: /* GL_ARB_multisample */
+ CALL_SampleCoverageARB(ctx->Exec, (n[1].f, n[2].b));
+ break;
+ case OPCODE_WINDOW_POS_ARB: /* GL_ARB_window_pos */
+ CALL_WindowPos3fMESA(ctx->Exec, (n[1].f, n[2].f, n[3].f));
+ break;
+#if FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program
+ case OPCODE_BIND_PROGRAM_NV: /* GL_NV_vertex_program */
+ CALL_BindProgramNV(ctx->Exec, (n[1].e, n[2].ui));
+ break;
+#endif
+#if FEATURE_NV_vertex_program
+ case OPCODE_EXECUTE_PROGRAM_NV:
+ {
+ GLfloat v[4];
+ v[0] = n[3].f;
+ v[1] = n[4].f;
+ v[2] = n[5].f;
+ v[3] = n[6].f;
+ CALL_ExecuteProgramNV(ctx->Exec, (n[1].e, n[2].ui, v));
+ }
+ break;
+ case OPCODE_REQUEST_RESIDENT_PROGRAMS_NV:
+ CALL_RequestResidentProgramsNV(ctx->Exec, (n[1].ui,
+ (GLuint *) n[2].data));
+ break;
+ case OPCODE_LOAD_PROGRAM_NV:
+ CALL_LoadProgramNV(ctx->Exec, (n[1].e, n[2].ui, n[3].i,
+ (const GLubyte *) n[4].data));
+ break;
+ case OPCODE_PROGRAM_PARAMETER4F_NV:
+ CALL_ProgramParameter4fNV(ctx->Exec, (n[1].e, n[2].ui, n[3].f,
+ n[4].f, n[5].f, n[6].f));
+ break;
+ case OPCODE_TRACK_MATRIX_NV:
+ CALL_TrackMatrixNV(ctx->Exec, (n[1].e, n[2].ui, n[3].e, n[4].e));
+ break;
+#endif
+
+#if FEATURE_NV_fragment_program
+ case OPCODE_PROGRAM_LOCAL_PARAMETER_ARB:
+ CALL_ProgramLocalParameter4fARB(ctx->Exec,
+ (n[1].e, n[2].ui, n[3].f, n[4].f,
+ n[5].f, n[6].f));
+ break;
+ case OPCODE_PROGRAM_NAMED_PARAMETER_NV:
+ CALL_ProgramNamedParameter4fNV(ctx->Exec, (n[1].ui, n[2].i,
+ (const GLubyte *) n[3].
+ data, n[4].f, n[5].f,
+ n[6].f, n[7].f));
+ break;
+#endif
+
+ case OPCODE_ACTIVE_STENCIL_FACE_EXT:
+ CALL_ActiveStencilFaceEXT(ctx->Exec, (n[1].e));
+ break;
+ case OPCODE_DEPTH_BOUNDS_EXT:
+ CALL_DepthBoundsEXT(ctx->Exec, (n[1].f, n[2].f));
+ break;
+#if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program
+ case OPCODE_PROGRAM_STRING_ARB:
+ CALL_ProgramStringARB(ctx->Exec,
+ (n[1].e, n[2].e, n[3].i, n[4].data));
+ break;
+ case OPCODE_PROGRAM_ENV_PARAMETER_ARB:
+ CALL_ProgramEnvParameter4fARB(ctx->Exec, (n[1].e, n[2].ui, n[3].f,
+ n[4].f, n[5].f,
+ n[6].f));
+ break;
+#endif
+#if FEATURE_ARB_occlusion_query
+ case OPCODE_BEGIN_QUERY_ARB:
+ CALL_BeginQueryARB(ctx->Exec, (n[1].e, n[2].ui));
+ break;
+ case OPCODE_END_QUERY_ARB:
+ CALL_EndQueryARB(ctx->Exec, (n[1].e));
+ break;
+#endif
+ case OPCODE_DRAW_BUFFERS_ARB:
+ {
+ GLenum buffers[MAX_DRAW_BUFFERS];
+ GLint i, count = MIN2(n[1].i, MAX_DRAW_BUFFERS);
+ for (i = 0; i < count; i++)
+ buffers[i] = n[2 + i].e;
+ CALL_DrawBuffersARB(ctx->Exec, (n[1].i, buffers));
+ }
+ break;
+#if FEATURE_EXT_framebuffer_blit
+ case OPCODE_BLIT_FRAMEBUFFER:
+ CALL_BlitFramebufferEXT(ctx->Exec, (n[1].i, n[2].i, n[3].i, n[4].i,
+ n[5].i, n[6].i, n[7].i, n[8].i,
+ n[9].i, n[10].e));
+ break;
+#endif
+#if FEATURE_ATI_fragment_shader
+ case OPCODE_BIND_FRAGMENT_SHADER_ATI:
+ CALL_BindFragmentShaderATI(ctx->Exec, (n[1].i));
+ break;
+ case OPCODE_SET_FRAGMENT_SHADER_CONSTANTS_ATI:
+ {
+ GLfloat values[4];
+ GLuint i, dst = n[1].ui;
+
+ for (i = 0; i < 4; i++)
+ values[i] = n[1 + i].f;
+ CALL_SetFragmentShaderConstantATI(ctx->Exec, (dst, values));
+ }
+ break;
+#endif
+ case OPCODE_ATTR_1F_NV:
+ CALL_VertexAttrib1fNV(ctx->Exec, (n[1].e, n[2].f));
+ break;
+ case OPCODE_ATTR_2F_NV:
+ /* Really shouldn't have to do this - the Node structure
+ * is convenient, but it would be better to store the data
+ * packed appropriately so that it can be sent directly
+ * on. With x86_64 becoming common, this will start to
+ * matter more.
+ */
+ if (sizeof(Node) == sizeof(GLfloat))
+ CALL_VertexAttrib2fvNV(ctx->Exec, (n[1].e, &n[2].f));
+ else
+ CALL_VertexAttrib2fNV(ctx->Exec, (n[1].e, n[2].f, n[3].f));
+ break;
+ case OPCODE_ATTR_3F_NV:
+ if (sizeof(Node) == sizeof(GLfloat))
+ CALL_VertexAttrib3fvNV(ctx->Exec, (n[1].e, &n[2].f));
+ else
+ CALL_VertexAttrib3fNV(ctx->Exec, (n[1].e, n[2].f, n[3].f,
+ n[4].f));
+ break;
+ case OPCODE_ATTR_4F_NV:
+ if (sizeof(Node) == sizeof(GLfloat))
+ CALL_VertexAttrib4fvNV(ctx->Exec, (n[1].e, &n[2].f));
+ else
+ CALL_VertexAttrib4fNV(ctx->Exec, (n[1].e, n[2].f, n[3].f,
+ n[4].f, n[5].f));
+ break;
+ case OPCODE_ATTR_1F_ARB:
+ CALL_VertexAttrib1fARB(ctx->Exec, (n[1].e, n[2].f));
+ break;
+ case OPCODE_ATTR_2F_ARB:
+ /* Really shouldn't have to do this - the Node structure
+ * is convenient, but it would be better to store the data
+ * packed appropriately so that it can be sent directly
+ * on. With x86_64 becoming common, this will start to
+ * matter more.
+ */
+ if (sizeof(Node) == sizeof(GLfloat))
+ CALL_VertexAttrib2fvARB(ctx->Exec, (n[1].e, &n[2].f));
+ else
+ CALL_VertexAttrib2fARB(ctx->Exec, (n[1].e, n[2].f, n[3].f));
+ break;
+ case OPCODE_ATTR_3F_ARB:
+ if (sizeof(Node) == sizeof(GLfloat))
+ CALL_VertexAttrib3fvARB(ctx->Exec, (n[1].e, &n[2].f));
+ else
+ CALL_VertexAttrib3fARB(ctx->Exec, (n[1].e, n[2].f, n[3].f,
+ n[4].f));
+ break;
+ case OPCODE_ATTR_4F_ARB:
+ if (sizeof(Node) == sizeof(GLfloat))
+ CALL_VertexAttrib4fvARB(ctx->Exec, (n[1].e, &n[2].f));
+ else
+ CALL_VertexAttrib4fARB(ctx->Exec, (n[1].e, n[2].f, n[3].f,
+ n[4].f, n[5].f));
+ break;
+ case OPCODE_MATERIAL:
+ if (sizeof(Node) == sizeof(GLfloat))
+ CALL_Materialfv(ctx->Exec, (n[1].e, n[2].e, &n[3].f));
+ else {
+ GLfloat f[4];
+ f[0] = n[3].f;
+ f[1] = n[4].f;
+ f[2] = n[5].f;
+ f[3] = n[6].f;
+ CALL_Materialfv(ctx->Exec, (n[1].e, n[2].e, f));
+ }
+ break;
+ case OPCODE_INDEX:
+ CALL_Indexi(ctx->Exec, (n[1].i));
+ break;
+ case OPCODE_EDGEFLAG:
+ CALL_EdgeFlag(ctx->Exec, (n[1].b));
+ break;
+ case OPCODE_BEGIN:
+ CALL_Begin(ctx->Exec, (n[1].e));
+ break;
+ case OPCODE_END:
+ CALL_End(ctx->Exec, ());
+ break;
+ case OPCODE_RECTF:
+ CALL_Rectf(ctx->Exec, (n[1].f, n[2].f, n[3].f, n[4].f));
+ break;
+ case OPCODE_EVAL_C1:
+ CALL_EvalCoord1f(ctx->Exec, (n[1].f));
+ break;
+ case OPCODE_EVAL_C2:
+ CALL_EvalCoord2f(ctx->Exec, (n[1].f, n[2].f));
+ break;
+ case OPCODE_EVAL_P1:
+ CALL_EvalPoint1(ctx->Exec, (n[1].i));
+ break;
+ case OPCODE_EVAL_P2:
+ CALL_EvalPoint2(ctx->Exec, (n[1].i, n[2].i));
+ break;
+
+
+
+
+ case OPCODE_CONTINUE:
+ n = (Node *) n[1].next;
+ break;
+ case OPCODE_END_OF_LIST:
+ done = GL_TRUE;
+ break;
+ default:
+ {
+ char msg[1000];
+ _mesa_sprintf(msg, "Error in execute_list: opcode=%d",
+ (int) opcode);
+ _mesa_problem(ctx, msg);
+ }
+ done = GL_TRUE;
+ }
+
+ /* increment n to point to next compiled command */
+ if (opcode != OPCODE_CONTINUE) {
+ n += InstSize[opcode];
+ }
+ }
+ }
+
+ if (ctx->Driver.EndCallList)
+ ctx->Driver.EndCallList(ctx);
+
+ ctx->ListState.CallStack[ctx->ListState.CallDepth--] = NULL;
+}
+
+
+
+/**********************************************************************/
+/* GL functions */
+/**********************************************************************/
+
+/**
+ * Test if a display list number is valid.
+ */
+GLboolean GLAPIENTRY
+_mesa_IsList(GLuint list)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0); /* must be called before assert */
+ ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
+ return islist(ctx, list);
+}
+
+
+/**
+ * Delete a sequence of consecutive display lists.
+ */
+void GLAPIENTRY
+_mesa_DeleteLists(GLuint list, GLsizei range)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLuint i;
+ FLUSH_VERTICES(ctx, 0); /* must be called before assert */
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (range < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteLists");
+ return;
+ }
+ for (i = list; i < list + range; i++) {
+ _mesa_destroy_list(ctx, i);
+ }
+}
+
+
+/**
+ * Return a display list number, n, such that lists n through n+range-1
+ * are free.
+ */
+GLuint GLAPIENTRY
+_mesa_GenLists(GLsizei range)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLuint base;
+ FLUSH_VERTICES(ctx, 0); /* must be called before assert */
+ ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0);
+
+ if (range < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glGenLists");
+ return 0;
+ }
+ if (range == 0) {
+ return 0;
+ }
+
+ /*
+ * Make this an atomic operation
+ */
+ _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
+
+ base = _mesa_HashFindFreeKeyBlock(ctx->Shared->DisplayList, range);
+ if (base) {
+ /* reserve the list IDs by with empty/dummy lists */
+ GLint i;
+ for (i = 0; i < range; i++) {
+ _mesa_HashInsert(ctx->Shared->DisplayList, base + i,
+ make_list(base + i, 1));
+ }
+ }
+
+ _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+
+ return base;
+}
+
+
+/**
+ * Begin a new display list.
+ */
+void GLAPIENTRY
+_mesa_NewList(GLuint list, GLenum mode)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint i;
+
+ FLUSH_CURRENT(ctx, 0); /* must be called before assert */
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx, "glNewList %u %s\n", list,
+ _mesa_lookup_enum_by_nr(mode));
+
+ if (list == 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glNewList");
+ return;
+ }
+
+ if (mode != GL_COMPILE && mode != GL_COMPILE_AND_EXECUTE) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glNewList");
+ return;
+ }
+
+ if (ctx->ListState.CurrentListPtr) {
+ /* already compiling a display list */
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glNewList");
+ return;
+ }
+
+ ctx->CompileFlag = GL_TRUE;
+ ctx->ExecuteFlag = (mode == GL_COMPILE_AND_EXECUTE);
+
+ /* Allocate new display list */
+ ctx->ListState.CurrentListNum = list;
+ ctx->ListState.CurrentList = make_list(list, BLOCK_SIZE);
+ ctx->ListState.CurrentBlock = ctx->ListState.CurrentList->node;
+ ctx->ListState.CurrentListPtr = ctx->ListState.CurrentBlock;
+ ctx->ListState.CurrentPos = 0;
+
+ /* Reset acumulated list state:
+ */
+ for (i = 0; i < VERT_ATTRIB_MAX; i++)
+ ctx->ListState.ActiveAttribSize[i] = 0;
+
+ for (i = 0; i < MAT_ATTRIB_MAX; i++)
+ ctx->ListState.ActiveMaterialSize[i] = 0;
+
+ ctx->ListState.ActiveIndex = 0;
+ ctx->ListState.ActiveEdgeFlag = 0;
+
+ ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN;
+ ctx->Driver.NewList(ctx, list, mode);
+
+ ctx->CurrentDispatch = ctx->Save;
+ _glapi_set_dispatch(ctx->CurrentDispatch);
+}
+
+
+/**
+ * End definition of current display list.
+ */
+void GLAPIENTRY
+_mesa_EndList(void)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ SAVE_FLUSH_VERTICES(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx, "glEndList\n");
+
+ /* Check that a list is under construction */
+ if (!ctx->ListState.CurrentListPtr) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glEndList");
+ return;
+ }
+
+ (void) ALLOC_INSTRUCTION(ctx, OPCODE_END_OF_LIST, 0);
+
+ /* Destroy old list, if any */
+ _mesa_destroy_list(ctx, ctx->ListState.CurrentListNum);
+ /* Install the list */
+ _mesa_HashInsert(ctx->Shared->DisplayList, ctx->ListState.CurrentListNum,
+ ctx->ListState.CurrentList);
+
+
+ if (MESA_VERBOSE & VERBOSE_DISPLAY_LIST)
+ mesa_print_display_list(ctx->ListState.CurrentListNum);
+
+ ctx->Driver.EndList(ctx);
+
+ ctx->ListState.CurrentList = NULL;
+ ctx->ListState.CurrentListNum = 0;
+ ctx->ListState.CurrentListPtr = NULL;
+ ctx->ExecuteFlag = GL_TRUE;
+ ctx->CompileFlag = GL_FALSE;
+
+ ctx->CurrentDispatch = ctx->Exec;
+ _glapi_set_dispatch(ctx->CurrentDispatch);
+}
+
+
+void GLAPIENTRY
+_mesa_CallList(GLuint list)
+{
+ GLboolean save_compile_flag;
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_CURRENT(ctx, 0);
+ /* VERY IMPORTANT: Save the CompileFlag status, turn it off, */
+ /* execute the display list, and restore the CompileFlag. */
+
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx, "glCallList %d\n", list);
+
+ if (list == 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glCallList(list==0)");
+ return;
+ }
+
+/* mesa_print_display_list( list ); */
+
+ save_compile_flag = ctx->CompileFlag;
+ if (save_compile_flag) {
+ ctx->CompileFlag = GL_FALSE;
+ }
+
+ execute_list(ctx, list);
+ ctx->CompileFlag = save_compile_flag;
+
+ /* also restore API function pointers to point to "save" versions */
+ if (save_compile_flag) {
+ ctx->CurrentDispatch = ctx->Save;
+ _glapi_set_dispatch(ctx->CurrentDispatch);
+ }
+}
+
+
+/**
+ * Execute glCallLists: call multiple display lists.
+ */
+void GLAPIENTRY
+_mesa_CallLists(GLsizei n, GLenum type, const GLvoid * lists)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLuint list;
+ GLint i;
+ GLboolean save_compile_flag;
+
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx, "glCallLists %d\n", n);
+
+ switch (type) {
+ case GL_BYTE:
+ case GL_UNSIGNED_BYTE:
+ case GL_SHORT:
+ case GL_UNSIGNED_SHORT:
+ case GL_INT:
+ case GL_UNSIGNED_INT:
+ case GL_FLOAT:
+ case GL_2_BYTES:
+ case GL_3_BYTES:
+ case GL_4_BYTES:
+ /* OK */
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glCallLists(type)");
+ return;
+ }
+
+ /* Save the CompileFlag status, turn it off, execute display list,
+ * and restore the CompileFlag.
+ */
+ save_compile_flag = ctx->CompileFlag;
+ ctx->CompileFlag = GL_FALSE;
+
+ for (i = 0; i < n; i++) {
+ list = translate_id(i, type, lists);
+ execute_list(ctx, ctx->List.ListBase + list);
+ }
+
+ ctx->CompileFlag = save_compile_flag;
+
+ /* also restore API function pointers to point to "save" versions */
+ if (save_compile_flag) {
+ ctx->CurrentDispatch = ctx->Save;
+ _glapi_set_dispatch(ctx->CurrentDispatch);
+ }
+}
+
+
+/**
+ * Set the offset added to list numbers in glCallLists.
+ */
+void GLAPIENTRY
+_mesa_ListBase(GLuint base)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0); /* must be called before assert */
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+ ctx->List.ListBase = base;
+}
+
+
+/* Can no longer assume ctx->Exec->Func is equal to _mesa_Func.
+ */
+static void GLAPIENTRY
+exec_Finish(void)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_Finish(ctx->Exec, ());
+}
+
+static void GLAPIENTRY
+exec_Flush(void)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_Flush(ctx->Exec, ());
+}
+
+static void GLAPIENTRY
+exec_GetBooleanv(GLenum pname, GLboolean *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetBooleanv(ctx->Exec, (pname, params));
+}
+
+static void GLAPIENTRY
+exec_GetClipPlane(GLenum plane, GLdouble * equation)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetClipPlane(ctx->Exec, (plane, equation));
+}
+
+static void GLAPIENTRY
+exec_GetDoublev(GLenum pname, GLdouble *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetDoublev(ctx->Exec, (pname, params));
+}
+
+static GLenum GLAPIENTRY
+exec_GetError(void)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ return CALL_GetError(ctx->Exec, ());
+}
+
+static void GLAPIENTRY
+exec_GetFloatv(GLenum pname, GLfloat *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetFloatv(ctx->Exec, (pname, params));
+}
+
+static void GLAPIENTRY
+exec_GetIntegerv(GLenum pname, GLint *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetIntegerv(ctx->Exec, (pname, params));
+}
+
+static void GLAPIENTRY
+exec_GetLightfv(GLenum light, GLenum pname, GLfloat *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetLightfv(ctx->Exec, (light, pname, params));
+}
+
+static void GLAPIENTRY
+exec_GetLightiv(GLenum light, GLenum pname, GLint *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetLightiv(ctx->Exec, (light, pname, params));
+}
+
+static void GLAPIENTRY
+exec_GetMapdv(GLenum target, GLenum query, GLdouble * v)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetMapdv(ctx->Exec, (target, query, v));
+}
+
+static void GLAPIENTRY
+exec_GetMapfv(GLenum target, GLenum query, GLfloat * v)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetMapfv(ctx->Exec, (target, query, v));
+}
+
+static void GLAPIENTRY
+exec_GetMapiv(GLenum target, GLenum query, GLint * v)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetMapiv(ctx->Exec, (target, query, v));
+}
+
+static void GLAPIENTRY
+exec_GetMaterialfv(GLenum face, GLenum pname, GLfloat *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetMaterialfv(ctx->Exec, (face, pname, params));
+}
+
+static void GLAPIENTRY
+exec_GetMaterialiv(GLenum face, GLenum pname, GLint *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetMaterialiv(ctx->Exec, (face, pname, params));
+}
+
+static void GLAPIENTRY
+exec_GetPixelMapfv(GLenum map, GLfloat *values)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetPixelMapfv(ctx->Exec, (map, values));
+}
+
+static void GLAPIENTRY
+exec_GetPixelMapuiv(GLenum map, GLuint *values)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetPixelMapuiv(ctx->Exec, (map, values));
+}
+
+static void GLAPIENTRY
+exec_GetPixelMapusv(GLenum map, GLushort *values)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetPixelMapusv(ctx->Exec, (map, values));
+}
+
+static void GLAPIENTRY
+exec_GetPolygonStipple(GLubyte * dest)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetPolygonStipple(ctx->Exec, (dest));
+}
+
+static const GLubyte *GLAPIENTRY
+exec_GetString(GLenum name)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ return CALL_GetString(ctx->Exec, (name));
+}
+
+static void GLAPIENTRY
+exec_GetTexEnvfv(GLenum target, GLenum pname, GLfloat *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetTexEnvfv(ctx->Exec, (target, pname, params));
+}
+
+static void GLAPIENTRY
+exec_GetTexEnviv(GLenum target, GLenum pname, GLint *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetTexEnviv(ctx->Exec, (target, pname, params));
+}
+
+static void GLAPIENTRY
+exec_GetTexGendv(GLenum coord, GLenum pname, GLdouble *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetTexGendv(ctx->Exec, (coord, pname, params));
+}
+
+static void GLAPIENTRY
+exec_GetTexGenfv(GLenum coord, GLenum pname, GLfloat *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetTexGenfv(ctx->Exec, (coord, pname, params));
+}
+
+static void GLAPIENTRY
+exec_GetTexGeniv(GLenum coord, GLenum pname, GLint *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetTexGeniv(ctx->Exec, (coord, pname, params));
+}
+
+static void GLAPIENTRY
+exec_GetTexImage(GLenum target, GLint level, GLenum format,
+ GLenum type, GLvoid * pixels)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetTexImage(ctx->Exec, (target, level, format, type, pixels));
+}
+
+static void GLAPIENTRY
+exec_GetTexLevelParameterfv(GLenum target, GLint level,
+ GLenum pname, GLfloat *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetTexLevelParameterfv(ctx->Exec, (target, level, pname, params));
+}
+
+static void GLAPIENTRY
+exec_GetTexLevelParameteriv(GLenum target, GLint level,
+ GLenum pname, GLint *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetTexLevelParameteriv(ctx->Exec, (target, level, pname, params));
+}
+
+static void GLAPIENTRY
+exec_GetTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetTexParameterfv(ctx->Exec, (target, pname, params));
+}
+
+static void GLAPIENTRY
+exec_GetTexParameteriv(GLenum target, GLenum pname, GLint *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetTexParameteriv(ctx->Exec, (target, pname, params));
+}
+
+static GLboolean GLAPIENTRY
+exec_IsEnabled(GLenum cap)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ return CALL_IsEnabled(ctx->Exec, (cap));
+}
+
+static void GLAPIENTRY
+exec_PixelStoref(GLenum pname, GLfloat param)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_PixelStoref(ctx->Exec, (pname, param));
+}
+
+static void GLAPIENTRY
+exec_PixelStorei(GLenum pname, GLint param)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_PixelStorei(ctx->Exec, (pname, param));
+}
+
+static void GLAPIENTRY
+exec_ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type, GLvoid * pixels)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_ReadPixels(ctx->Exec, (x, y, width, height, format, type, pixels));
+}
+
+static GLint GLAPIENTRY
+exec_RenderMode(GLenum mode)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ return CALL_RenderMode(ctx->Exec, (mode));
+}
+
+static void GLAPIENTRY
+exec_FeedbackBuffer(GLsizei size, GLenum type, GLfloat * buffer)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_FeedbackBuffer(ctx->Exec, (size, type, buffer));
+}
+
+static void GLAPIENTRY
+exec_SelectBuffer(GLsizei size, GLuint * buffer)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_SelectBuffer(ctx->Exec, (size, buffer));
+}
+
+static GLboolean GLAPIENTRY
+exec_AreTexturesResident(GLsizei n, const GLuint * texName,
+ GLboolean * residences)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ return CALL_AreTexturesResident(ctx->Exec, (n, texName, residences));
+}
+
+static void GLAPIENTRY
+exec_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_ColorPointer(ctx->Exec, (size, type, stride, ptr));
+}
+
+static void GLAPIENTRY
+exec_DeleteTextures(GLsizei n, const GLuint * texName)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_DeleteTextures(ctx->Exec, (n, texName));
+}
+
+static void GLAPIENTRY
+exec_DisableClientState(GLenum cap)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_DisableClientState(ctx->Exec, (cap));
+}
+
+static void GLAPIENTRY
+exec_EdgeFlagPointer(GLsizei stride, const GLvoid * vptr)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_EdgeFlagPointer(ctx->Exec, (stride, vptr));
+}
+
+static void GLAPIENTRY
+exec_EnableClientState(GLenum cap)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_EnableClientState(ctx->Exec, (cap));
+}
+
+static void GLAPIENTRY
+exec_GenTextures(GLsizei n, GLuint * texName)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GenTextures(ctx->Exec, (n, texName));
+}
+
+static void GLAPIENTRY
+exec_GetPointerv(GLenum pname, GLvoid **params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetPointerv(ctx->Exec, (pname, params));
+}
+
+static void GLAPIENTRY
+exec_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_IndexPointer(ctx->Exec, (type, stride, ptr));
+}
+
+static void GLAPIENTRY
+exec_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid * pointer)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_InterleavedArrays(ctx->Exec, (format, stride, pointer));
+}
+
+static GLboolean GLAPIENTRY
+exec_IsTexture(GLuint texture)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ return CALL_IsTexture(ctx->Exec, (texture));
+}
+
+static void GLAPIENTRY
+exec_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_NormalPointer(ctx->Exec, (type, stride, ptr));
+}
+
+static void GLAPIENTRY
+exec_PopClientAttrib(void)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_PopClientAttrib(ctx->Exec, ());
+}
+
+static void GLAPIENTRY
+exec_PushClientAttrib(GLbitfield mask)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_PushClientAttrib(ctx->Exec, (mask));
+}
+
+static void GLAPIENTRY
+exec_TexCoordPointer(GLint size, GLenum type, GLsizei stride,
+ const GLvoid *ptr)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_TexCoordPointer(ctx->Exec, (size, type, stride, ptr));
+}
+
+static void GLAPIENTRY
+exec_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid * img)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetCompressedTexImageARB(ctx->Exec, (target, level, img));
+}
+
+static void GLAPIENTRY
+exec_VertexPointer(GLint size, GLenum type, GLsizei stride,
+ const GLvoid *ptr)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_VertexPointer(ctx->Exec, (size, type, stride, ptr));
+}
+
+static void GLAPIENTRY
+exec_CopyConvolutionFilter1D(GLenum target, GLenum internalFormat,
+ GLint x, GLint y, GLsizei width)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_CopyConvolutionFilter1D(ctx->Exec,
+ (target, internalFormat, x, y, width));
+}
+
+static void GLAPIENTRY
+exec_CopyConvolutionFilter2D(GLenum target, GLenum internalFormat,
+ GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_CopyConvolutionFilter2D(ctx->Exec,
+ (target, internalFormat, x, y, width,
+ height));
+}
+
+static void GLAPIENTRY
+exec_GetColorTable(GLenum target, GLenum format, GLenum type, GLvoid * data)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetColorTable(ctx->Exec, (target, format, type, data));
+}
+
+static void GLAPIENTRY
+exec_GetColorTableParameterfv(GLenum target, GLenum pname, GLfloat *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetColorTableParameterfv(ctx->Exec, (target, pname, params));
+}
+
+static void GLAPIENTRY
+exec_GetColorTableParameteriv(GLenum target, GLenum pname, GLint *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetColorTableParameteriv(ctx->Exec, (target, pname, params));
+}
+
+static void GLAPIENTRY
+exec_GetConvolutionFilter(GLenum target, GLenum format, GLenum type,
+ GLvoid * image)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetConvolutionFilter(ctx->Exec, (target, format, type, image));
+}
+
+static void GLAPIENTRY
+exec_GetConvolutionParameterfv(GLenum target, GLenum pname, GLfloat *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetConvolutionParameterfv(ctx->Exec, (target, pname, params));
+}
+
+static void GLAPIENTRY
+exec_GetConvolutionParameteriv(GLenum target, GLenum pname, GLint *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetConvolutionParameteriv(ctx->Exec, (target, pname, params));
+}
+
+static void GLAPIENTRY
+exec_GetHistogram(GLenum target, GLboolean reset, GLenum format,
+ GLenum type, GLvoid *values)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetHistogram(ctx->Exec, (target, reset, format, type, values));
+}
+
+static void GLAPIENTRY
+exec_GetHistogramParameterfv(GLenum target, GLenum pname, GLfloat *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetHistogramParameterfv(ctx->Exec, (target, pname, params));
+}
+
+static void GLAPIENTRY
+exec_GetHistogramParameteriv(GLenum target, GLenum pname, GLint *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetHistogramParameteriv(ctx->Exec, (target, pname, params));
+}
+
+static void GLAPIENTRY
+exec_GetMinmax(GLenum target, GLboolean reset, GLenum format,
+ GLenum type, GLvoid *values)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetMinmax(ctx->Exec, (target, reset, format, type, values));
+}
+
+static void GLAPIENTRY
+exec_GetMinmaxParameterfv(GLenum target, GLenum pname, GLfloat *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetMinmaxParameterfv(ctx->Exec, (target, pname, params));
+}
+
+static void GLAPIENTRY
+exec_GetMinmaxParameteriv(GLenum target, GLenum pname, GLint *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetMinmaxParameteriv(ctx->Exec, (target, pname, params));
+}
+
+static void GLAPIENTRY
+exec_GetSeparableFilter(GLenum target, GLenum format, GLenum type,
+ GLvoid *row, GLvoid *column, GLvoid *span)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_GetSeparableFilter(ctx->Exec,
+ (target, format, type, row, column, span));
+}
+
+static void GLAPIENTRY
+exec_SeparableFilter2D(GLenum target, GLenum internalFormat,
+ GLsizei width, GLsizei height, GLenum format,
+ GLenum type, const GLvoid *row, const GLvoid *column)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_SeparableFilter2D(ctx->Exec,
+ (target, internalFormat, width, height, format,
+ type, row, column));
+}
+
+static void GLAPIENTRY
+exec_ColorPointerEXT(GLint size, GLenum type, GLsizei stride,
+ GLsizei count, const GLvoid *ptr)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_ColorPointerEXT(ctx->Exec, (size, type, stride, count, ptr));
+}
+
+static void GLAPIENTRY
+exec_EdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *ptr)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_EdgeFlagPointerEXT(ctx->Exec, (stride, count, ptr));
+}
+
+static void GLAPIENTRY
+exec_IndexPointerEXT(GLenum type, GLsizei stride, GLsizei count,
+ const GLvoid *ptr)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_IndexPointerEXT(ctx->Exec, (type, stride, count, ptr));
+}
+
+static void GLAPIENTRY
+exec_NormalPointerEXT(GLenum type, GLsizei stride, GLsizei count,
+ const GLvoid *ptr)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_NormalPointerEXT(ctx->Exec, (type, stride, count, ptr));
+}
+
+static void GLAPIENTRY
+exec_TexCoordPointerEXT(GLint size, GLenum type, GLsizei stride,
+ GLsizei count, const GLvoid *ptr)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_TexCoordPointerEXT(ctx->Exec, (size, type, stride, count, ptr));
+}
+
+static void GLAPIENTRY
+exec_VertexPointerEXT(GLint size, GLenum type, GLsizei stride,
+ GLsizei count, const GLvoid *ptr)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_VertexPointerEXT(ctx->Exec, (size, type, stride, count, ptr));
+}
+
+static void GLAPIENTRY
+exec_LockArraysEXT(GLint first, GLsizei count)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_LockArraysEXT(ctx->Exec, (first, count));
+}
+
+static void GLAPIENTRY
+exec_UnlockArraysEXT(void)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_UnlockArraysEXT(ctx->Exec, ());
+}
+
+static void GLAPIENTRY
+exec_ClientActiveTextureARB(GLenum target)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_ClientActiveTextureARB(ctx->Exec, (target));
+}
+
+static void GLAPIENTRY
+exec_SecondaryColorPointerEXT(GLint size, GLenum type,
+ GLsizei stride, const GLvoid *ptr)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_SecondaryColorPointerEXT(ctx->Exec, (size, type, stride, ptr));
+}
+
+static void GLAPIENTRY
+exec_FogCoordPointerEXT(GLenum type, GLsizei stride, const GLvoid *ptr)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_FogCoordPointerEXT(ctx->Exec, (type, stride, ptr));
+}
+
+/* GL_EXT_multi_draw_arrays */
+static void GLAPIENTRY
+exec_MultiDrawArraysEXT(GLenum mode, GLint * first,
+ GLsizei * count, GLsizei primcount)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_MultiDrawArraysEXT(ctx->Exec, (mode, first, count, primcount));
+}
+
+/* GL_EXT_multi_draw_arrays */
+static void GLAPIENTRY
+exec_MultiDrawElementsEXT(GLenum mode, const GLsizei * count,
+ GLenum type, const GLvoid ** indices,
+ GLsizei primcount)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_MultiDrawElementsEXT(ctx->Exec,
+ (mode, count, type, indices, primcount));
+}
+
+/* GL_IBM_multimode_draw_arrays */
+static void GLAPIENTRY
+exec_MultiModeDrawArraysIBM(const GLenum * mode, const GLint * first,
+ const GLsizei * count, GLsizei primcount,
+ GLint modestride)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_MultiModeDrawArraysIBM(ctx->Exec,
+ (mode, first, count, primcount, modestride));
+}
+
+/* GL_IBM_multimode_draw_arrays */
+static void GLAPIENTRY
+exec_MultiModeDrawElementsIBM(const GLenum * mode,
+ const GLsizei * count,
+ GLenum type,
+ const GLvoid * const *indices,
+ GLsizei primcount, GLint modestride)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ CALL_MultiModeDrawElementsIBM(ctx->Exec,
+ (mode, count, type, indices, primcount,
+ modestride));
+}
+
+
+
+/**
+ * Setup the given dispatch table to point to Mesa's display list
+ * building functions.
+ *
+ * This does not include any of the tnl functions - they are
+ * initialized from _mesa_init_api_defaults and from the active vtxfmt
+ * struct.
+ */
+void
+_mesa_init_dlist_table(struct _glapi_table *table)
+{
+ _mesa_loopback_init_api_table(table);
+
+ /* GL 1.0 */
+ SET_Accum(table, save_Accum);
+ SET_AlphaFunc(table, save_AlphaFunc);
+ SET_Bitmap(table, save_Bitmap);
+ SET_BlendFunc(table, _mesa_BlendFunc); /* loops-back to BlendFuncSeparate */
+ SET_CallList(table, _mesa_save_CallList);
+ SET_CallLists(table, _mesa_save_CallLists);
+ SET_Clear(table, save_Clear);
+ SET_ClearAccum(table, save_ClearAccum);
+ SET_ClearColor(table, save_ClearColor);
+ SET_ClearDepth(table, save_ClearDepth);
+ SET_ClearIndex(table, save_ClearIndex);
+ SET_ClearStencil(table, save_ClearStencil);
+ SET_ClipPlane(table, save_ClipPlane);
+ SET_ColorMask(table, save_ColorMask);
+ SET_ColorMaterial(table, save_ColorMaterial);
+ SET_CopyPixels(table, save_CopyPixels);
+ SET_CullFace(table, save_CullFace);
+ SET_DeleteLists(table, _mesa_DeleteLists);
+ SET_DepthFunc(table, save_DepthFunc);
+ SET_DepthMask(table, save_DepthMask);
+ SET_DepthRange(table, save_DepthRange);
+ SET_Disable(table, save_Disable);
+ SET_DrawBuffer(table, save_DrawBuffer);
+ SET_DrawPixels(table, save_DrawPixels);
+ SET_Enable(table, save_Enable);
+ SET_EndList(table, _mesa_EndList);
+ SET_EvalMesh1(table, _mesa_save_EvalMesh1);
+ SET_EvalMesh2(table, _mesa_save_EvalMesh2);
+ SET_Finish(table, exec_Finish);
+ SET_Flush(table, exec_Flush);
+ SET_Fogf(table, save_Fogf);
+ SET_Fogfv(table, save_Fogfv);
+ SET_Fogi(table, save_Fogi);
+ SET_Fogiv(table, save_Fogiv);
+ SET_FrontFace(table, save_FrontFace);
+ SET_Frustum(table, save_Frustum);
+ SET_GenLists(table, _mesa_GenLists);
+ SET_GetBooleanv(table, exec_GetBooleanv);
+ SET_GetClipPlane(table, exec_GetClipPlane);
+ SET_GetDoublev(table, exec_GetDoublev);
+ SET_GetError(table, exec_GetError);
+ SET_GetFloatv(table, exec_GetFloatv);
+ SET_GetIntegerv(table, exec_GetIntegerv);
+ SET_GetLightfv(table, exec_GetLightfv);
+ SET_GetLightiv(table, exec_GetLightiv);
+ SET_GetMapdv(table, exec_GetMapdv);
+ SET_GetMapfv(table, exec_GetMapfv);
+ SET_GetMapiv(table, exec_GetMapiv);
+ SET_GetMaterialfv(table, exec_GetMaterialfv);
+ SET_GetMaterialiv(table, exec_GetMaterialiv);
+ SET_GetPixelMapfv(table, exec_GetPixelMapfv);
+ SET_GetPixelMapuiv(table, exec_GetPixelMapuiv);
+ SET_GetPixelMapusv(table, exec_GetPixelMapusv);
+ SET_GetPolygonStipple(table, exec_GetPolygonStipple);
+ SET_GetString(table, exec_GetString);
+ SET_GetTexEnvfv(table, exec_GetTexEnvfv);
+ SET_GetTexEnviv(table, exec_GetTexEnviv);
+ SET_GetTexGendv(table, exec_GetTexGendv);
+ SET_GetTexGenfv(table, exec_GetTexGenfv);
+ SET_GetTexGeniv(table, exec_GetTexGeniv);
+ SET_GetTexImage(table, exec_GetTexImage);
+ SET_GetTexLevelParameterfv(table, exec_GetTexLevelParameterfv);
+ SET_GetTexLevelParameteriv(table, exec_GetTexLevelParameteriv);
+ SET_GetTexParameterfv(table, exec_GetTexParameterfv);
+ SET_GetTexParameteriv(table, exec_GetTexParameteriv);
+ SET_Hint(table, save_Hint);
+ SET_IndexMask(table, save_IndexMask);
+ SET_InitNames(table, save_InitNames);
+ SET_IsEnabled(table, exec_IsEnabled);
+ SET_IsList(table, _mesa_IsList);
+ SET_LightModelf(table, save_LightModelf);
+ SET_LightModelfv(table, save_LightModelfv);
+ SET_LightModeli(table, save_LightModeli);
+ SET_LightModeliv(table, save_LightModeliv);
+ SET_Lightf(table, save_Lightf);
+ SET_Lightfv(table, save_Lightfv);
+ SET_Lighti(table, save_Lighti);
+ SET_Lightiv(table, save_Lightiv);
+ SET_LineStipple(table, save_LineStipple);
+ SET_LineWidth(table, save_LineWidth);
+ SET_ListBase(table, save_ListBase);
+ SET_LoadIdentity(table, save_LoadIdentity);
+ SET_LoadMatrixd(table, save_LoadMatrixd);
+ SET_LoadMatrixf(table, save_LoadMatrixf);
+ SET_LoadName(table, save_LoadName);
+ SET_LogicOp(table, save_LogicOp);
+ SET_Map1d(table, save_Map1d);
+ SET_Map1f(table, save_Map1f);
+ SET_Map2d(table, save_Map2d);
+ SET_Map2f(table, save_Map2f);
+ SET_MapGrid1d(table, save_MapGrid1d);
+ SET_MapGrid1f(table, save_MapGrid1f);
+ SET_MapGrid2d(table, save_MapGrid2d);
+ SET_MapGrid2f(table, save_MapGrid2f);
+ SET_MatrixMode(table, save_MatrixMode);
+ SET_MultMatrixd(table, save_MultMatrixd);
+ SET_MultMatrixf(table, save_MultMatrixf);
+ SET_NewList(table, save_NewList);
+ SET_Ortho(table, save_Ortho);
+ SET_PassThrough(table, save_PassThrough);
+ SET_PixelMapfv(table, save_PixelMapfv);
+ SET_PixelMapuiv(table, save_PixelMapuiv);
+ SET_PixelMapusv(table, save_PixelMapusv);
+ SET_PixelStoref(table, exec_PixelStoref);
+ SET_PixelStorei(table, exec_PixelStorei);
+ SET_PixelTransferf(table, save_PixelTransferf);
+ SET_PixelTransferi(table, save_PixelTransferi);
+ SET_PixelZoom(table, save_PixelZoom);
+ SET_PointSize(table, save_PointSize);
+ SET_PolygonMode(table, save_PolygonMode);
+ SET_PolygonOffset(table, save_PolygonOffset);
+ SET_PolygonStipple(table, save_PolygonStipple);
+ SET_PopAttrib(table, save_PopAttrib);
+ SET_PopMatrix(table, save_PopMatrix);
+ SET_PopName(table, save_PopName);
+ SET_PushAttrib(table, save_PushAttrib);
+ SET_PushMatrix(table, save_PushMatrix);
+ SET_PushName(table, save_PushName);
+ SET_RasterPos2d(table, save_RasterPos2d);
+ SET_RasterPos2dv(table, save_RasterPos2dv);
+ SET_RasterPos2f(table, save_RasterPos2f);
+ SET_RasterPos2fv(table, save_RasterPos2fv);
+ SET_RasterPos2i(table, save_RasterPos2i);
+ SET_RasterPos2iv(table, save_RasterPos2iv);
+ SET_RasterPos2s(table, save_RasterPos2s);
+ SET_RasterPos2sv(table, save_RasterPos2sv);
+ SET_RasterPos3d(table, save_RasterPos3d);
+ SET_RasterPos3dv(table, save_RasterPos3dv);
+ SET_RasterPos3f(table, save_RasterPos3f);
+ SET_RasterPos3fv(table, save_RasterPos3fv);
+ SET_RasterPos3i(table, save_RasterPos3i);
+ SET_RasterPos3iv(table, save_RasterPos3iv);
+ SET_RasterPos3s(table, save_RasterPos3s);
+ SET_RasterPos3sv(table, save_RasterPos3sv);
+ SET_RasterPos4d(table, save_RasterPos4d);
+ SET_RasterPos4dv(table, save_RasterPos4dv);
+ SET_RasterPos4f(table, save_RasterPos4f);
+ SET_RasterPos4fv(table, save_RasterPos4fv);
+ SET_RasterPos4i(table, save_RasterPos4i);
+ SET_RasterPos4iv(table, save_RasterPos4iv);
+ SET_RasterPos4s(table, save_RasterPos4s);
+ SET_RasterPos4sv(table, save_RasterPos4sv);
+ SET_ReadBuffer(table, save_ReadBuffer);
+ SET_ReadPixels(table, exec_ReadPixels);
+ SET_RenderMode(table, exec_RenderMode);
+ SET_Rotated(table, save_Rotated);
+ SET_Rotatef(table, save_Rotatef);
+ SET_Scaled(table, save_Scaled);
+ SET_Scalef(table, save_Scalef);
+ SET_Scissor(table, save_Scissor);
+ SET_FeedbackBuffer(table, exec_FeedbackBuffer);
+ SET_SelectBuffer(table, exec_SelectBuffer);
+ SET_ShadeModel(table, save_ShadeModel);
+ SET_StencilFunc(table, save_StencilFunc);
+ SET_StencilMask(table, save_StencilMask);
+ SET_StencilOp(table, save_StencilOp);
+ SET_TexEnvf(table, save_TexEnvf);
+ SET_TexEnvfv(table, save_TexEnvfv);
+ SET_TexEnvi(table, save_TexEnvi);
+ SET_TexEnviv(table, save_TexEnviv);
+ SET_TexGend(table, save_TexGend);
+ SET_TexGendv(table, save_TexGendv);
+ SET_TexGenf(table, save_TexGenf);
+ SET_TexGenfv(table, save_TexGenfv);
+ SET_TexGeni(table, save_TexGeni);
+ SET_TexGeniv(table, save_TexGeniv);
+ SET_TexImage1D(table, save_TexImage1D);
+ SET_TexImage2D(table, save_TexImage2D);
+ SET_TexParameterf(table, save_TexParameterf);
+ SET_TexParameterfv(table, save_TexParameterfv);
+ SET_TexParameteri(table, save_TexParameteri);
+ SET_TexParameteriv(table, save_TexParameteriv);
+ SET_Translated(table, save_Translated);
+ SET_Translatef(table, save_Translatef);
+ SET_Viewport(table, save_Viewport);
+
+ /* GL 1.1 */
+ SET_AreTexturesResident(table, exec_AreTexturesResident);
+ SET_AreTexturesResidentEXT(table, exec_AreTexturesResident);
+ SET_BindTexture(table, save_BindTexture);
+ SET_ColorPointer(table, exec_ColorPointer);
+ SET_CopyTexImage1D(table, save_CopyTexImage1D);
+ SET_CopyTexImage2D(table, save_CopyTexImage2D);
+ SET_CopyTexSubImage1D(table, save_CopyTexSubImage1D);
+ SET_CopyTexSubImage2D(table, save_CopyTexSubImage2D);
+ SET_DeleteTextures(table, exec_DeleteTextures);
+ SET_DisableClientState(table, exec_DisableClientState);
+ SET_EdgeFlagPointer(table, exec_EdgeFlagPointer);
+ SET_EnableClientState(table, exec_EnableClientState);
+ SET_GenTextures(table, exec_GenTextures);
+ SET_GenTexturesEXT(table, exec_GenTextures);
+ SET_GetPointerv(table, exec_GetPointerv);
+ SET_IndexPointer(table, exec_IndexPointer);
+ SET_InterleavedArrays(table, exec_InterleavedArrays);
+ SET_IsTexture(table, exec_IsTexture);
+ SET_IsTextureEXT(table, exec_IsTexture);
+ SET_NormalPointer(table, exec_NormalPointer);
+ SET_PopClientAttrib(table, exec_PopClientAttrib);
+ SET_PrioritizeTextures(table, save_PrioritizeTextures);
+ SET_PushClientAttrib(table, exec_PushClientAttrib);
+ SET_TexCoordPointer(table, exec_TexCoordPointer);
+ SET_TexSubImage1D(table, save_TexSubImage1D);
+ SET_TexSubImage2D(table, save_TexSubImage2D);
+ SET_VertexPointer(table, exec_VertexPointer);
+
+ /* GL 1.2 */
+ SET_CopyTexSubImage3D(table, save_CopyTexSubImage3D);
+ SET_TexImage3D(table, save_TexImage3D);
+ SET_TexSubImage3D(table, save_TexSubImage3D);
+
+ /* GL 2.0 */
+ SET_StencilFuncSeparate(table, save_StencilFuncSeparate);
+ SET_StencilMaskSeparate(table, save_StencilMaskSeparate);
+ SET_StencilOpSeparate(table, save_StencilOpSeparate);
+
+ /* GL_ARB_imaging */
+ /* Not all are supported */
+ SET_BlendColor(table, save_BlendColor);
+ SET_BlendEquation(table, save_BlendEquation);
+ SET_ColorSubTable(table, save_ColorSubTable);
+ SET_ColorTable(table, save_ColorTable);
+ SET_ColorTableParameterfv(table, save_ColorTableParameterfv);
+ SET_ColorTableParameteriv(table, save_ColorTableParameteriv);
+ SET_ConvolutionFilter1D(table, save_ConvolutionFilter1D);
+ SET_ConvolutionFilter2D(table, save_ConvolutionFilter2D);
+ SET_ConvolutionParameterf(table, save_ConvolutionParameterf);
+ SET_ConvolutionParameterfv(table, save_ConvolutionParameterfv);
+ SET_ConvolutionParameteri(table, save_ConvolutionParameteri);
+ SET_ConvolutionParameteriv(table, save_ConvolutionParameteriv);
+ SET_CopyColorSubTable(table, save_CopyColorSubTable);
+ SET_CopyColorTable(table, save_CopyColorTable);
+ SET_CopyConvolutionFilter1D(table, exec_CopyConvolutionFilter1D);
+ SET_CopyConvolutionFilter2D(table, exec_CopyConvolutionFilter2D);
+ SET_GetColorTable(table, exec_GetColorTable);
+ SET_GetColorTableEXT(table, exec_GetColorTable);
+ SET_GetColorTableParameterfv(table, exec_GetColorTableParameterfv);
+ SET_GetColorTableParameterfvEXT(table, exec_GetColorTableParameterfv);
+ SET_GetColorTableParameteriv(table, exec_GetColorTableParameteriv);
+ SET_GetColorTableParameterivEXT(table, exec_GetColorTableParameteriv);
+ SET_GetConvolutionFilter(table, exec_GetConvolutionFilter);
+ SET_GetConvolutionFilterEXT(table, exec_GetConvolutionFilter);
+ SET_GetConvolutionParameterfv(table, exec_GetConvolutionParameterfv);
+ SET_GetConvolutionParameterfvEXT(table, exec_GetConvolutionParameterfv);
+ SET_GetConvolutionParameteriv(table, exec_GetConvolutionParameteriv);
+ SET_GetConvolutionParameterivEXT(table, exec_GetConvolutionParameteriv);
+ SET_GetHistogram(table, exec_GetHistogram);
+ SET_GetHistogramEXT(table, exec_GetHistogram);
+ SET_GetHistogramParameterfv(table, exec_GetHistogramParameterfv);
+ SET_GetHistogramParameterfvEXT(table, exec_GetHistogramParameterfv);
+ SET_GetHistogramParameteriv(table, exec_GetHistogramParameteriv);
+ SET_GetHistogramParameterivEXT(table, exec_GetHistogramParameteriv);
+ SET_GetMinmax(table, exec_GetMinmax);
+ SET_GetMinmaxEXT(table, exec_GetMinmax);
+ SET_GetMinmaxParameterfv(table, exec_GetMinmaxParameterfv);
+ SET_GetMinmaxParameterfvEXT(table, exec_GetMinmaxParameterfv);
+ SET_GetMinmaxParameteriv(table, exec_GetMinmaxParameteriv);
+ SET_GetMinmaxParameterivEXT(table, exec_GetMinmaxParameteriv);
+ SET_GetSeparableFilter(table, exec_GetSeparableFilter);
+ SET_GetSeparableFilterEXT(table, exec_GetSeparableFilter);
+ SET_Histogram(table, save_Histogram);
+ SET_Minmax(table, save_Minmax);
+ SET_ResetHistogram(table, save_ResetHistogram);
+ SET_ResetMinmax(table, save_ResetMinmax);
+ SET_SeparableFilter2D(table, exec_SeparableFilter2D);
+
+ /* 2. GL_EXT_blend_color */
+#if 0
+ SET_BlendColorEXT(table, save_BlendColorEXT);
+#endif
+
+ /* 3. GL_EXT_polygon_offset */
+ SET_PolygonOffsetEXT(table, save_PolygonOffsetEXT);
+
+ /* 6. GL_EXT_texture3d */
+#if 0
+ SET_CopyTexSubImage3DEXT(table, save_CopyTexSubImage3D);
+ SET_TexImage3DEXT(table, save_TexImage3DEXT);
+ SET_TexSubImage3DEXT(table, save_TexSubImage3D);
+#endif
+
+ /* 30. GL_EXT_vertex_array */
+ SET_ColorPointerEXT(table, exec_ColorPointerEXT);
+ SET_EdgeFlagPointerEXT(table, exec_EdgeFlagPointerEXT);
+ SET_IndexPointerEXT(table, exec_IndexPointerEXT);
+ SET_NormalPointerEXT(table, exec_NormalPointerEXT);
+ SET_TexCoordPointerEXT(table, exec_TexCoordPointerEXT);
+ SET_VertexPointerEXT(table, exec_VertexPointerEXT);
+
+ /* 37. GL_EXT_blend_minmax */
+#if 0
+ SET_BlendEquationEXT(table, save_BlendEquationEXT);
+#endif
+
+ /* 54. GL_EXT_point_parameters */
+ SET_PointParameterfEXT(table, save_PointParameterfEXT);
+ SET_PointParameterfvEXT(table, save_PointParameterfvEXT);
+
+ /* 78. GL_EXT_paletted_texture */
+#if 0
+ SET_ColorTableEXT(table, save_ColorTable);
+ SET_ColorSubTableEXT(table, save_ColorSubTable);
+#endif
+ SET_GetColorTableEXT(table, exec_GetColorTable);
+ SET_GetColorTableParameterfvEXT(table, exec_GetColorTableParameterfv);
+ SET_GetColorTableParameterivEXT(table, exec_GetColorTableParameteriv);
+
+ /* 97. GL_EXT_compiled_vertex_array */
+ SET_LockArraysEXT(table, exec_LockArraysEXT);
+ SET_UnlockArraysEXT(table, exec_UnlockArraysEXT);
+
+ /* 145. GL_EXT_secondary_color */
+ SET_SecondaryColorPointerEXT(table, exec_SecondaryColorPointerEXT);
+
+ /* 148. GL_EXT_multi_draw_arrays */
+ SET_MultiDrawArraysEXT(table, exec_MultiDrawArraysEXT);
+ SET_MultiDrawElementsEXT(table, exec_MultiDrawElementsEXT);
+
+ /* 149. GL_EXT_fog_coord */
+ SET_FogCoordPointerEXT(table, exec_FogCoordPointerEXT);
+
+ /* 173. GL_EXT_blend_func_separate */
+ SET_BlendFuncSeparateEXT(table, save_BlendFuncSeparateEXT);
+
+ /* 196. GL_MESA_resize_buffers */
+ SET_ResizeBuffersMESA(table, _mesa_ResizeBuffersMESA);
+
+ /* 197. GL_MESA_window_pos */
+ SET_WindowPos2dMESA(table, save_WindowPos2dMESA);
+ SET_WindowPos2dvMESA(table, save_WindowPos2dvMESA);
+ SET_WindowPos2fMESA(table, save_WindowPos2fMESA);
+ SET_WindowPos2fvMESA(table, save_WindowPos2fvMESA);
+ SET_WindowPos2iMESA(table, save_WindowPos2iMESA);
+ SET_WindowPos2ivMESA(table, save_WindowPos2ivMESA);
+ SET_WindowPos2sMESA(table, save_WindowPos2sMESA);
+ SET_WindowPos2svMESA(table, save_WindowPos2svMESA);
+ SET_WindowPos3dMESA(table, save_WindowPos3dMESA);
+ SET_WindowPos3dvMESA(table, save_WindowPos3dvMESA);
+ SET_WindowPos3fMESA(table, save_WindowPos3fMESA);
+ SET_WindowPos3fvMESA(table, save_WindowPos3fvMESA);
+ SET_WindowPos3iMESA(table, save_WindowPos3iMESA);
+ SET_WindowPos3ivMESA(table, save_WindowPos3ivMESA);
+ SET_WindowPos3sMESA(table, save_WindowPos3sMESA);
+ SET_WindowPos3svMESA(table, save_WindowPos3svMESA);
+ SET_WindowPos4dMESA(table, save_WindowPos4dMESA);
+ SET_WindowPos4dvMESA(table, save_WindowPos4dvMESA);
+ SET_WindowPos4fMESA(table, save_WindowPos4fMESA);
+ SET_WindowPos4fvMESA(table, save_WindowPos4fvMESA);
+ SET_WindowPos4iMESA(table, save_WindowPos4iMESA);
+ SET_WindowPos4ivMESA(table, save_WindowPos4ivMESA);
+ SET_WindowPos4sMESA(table, save_WindowPos4sMESA);
+ SET_WindowPos4svMESA(table, save_WindowPos4svMESA);
+
+ /* 200. GL_IBM_multimode_draw_arrays */
+ SET_MultiModeDrawArraysIBM(table, exec_MultiModeDrawArraysIBM);
+ SET_MultiModeDrawElementsIBM(table, exec_MultiModeDrawElementsIBM);
+
+#if FEATURE_NV_vertex_program
+ /* 233. GL_NV_vertex_program */
+ /* The following commands DO NOT go into display lists:
+ * AreProgramsResidentNV, IsProgramNV, GenProgramsNV, DeleteProgramsNV,
+ * VertexAttribPointerNV, GetProgram*, GetVertexAttrib*
+ */
+ SET_BindProgramNV(table, save_BindProgramNV);
+ SET_DeleteProgramsNV(table, _mesa_DeletePrograms);
+ SET_ExecuteProgramNV(table, save_ExecuteProgramNV);
+ SET_GenProgramsNV(table, _mesa_GenPrograms);
+ SET_AreProgramsResidentNV(table, _mesa_AreProgramsResidentNV);
+ SET_RequestResidentProgramsNV(table, save_RequestResidentProgramsNV);
+ SET_GetProgramParameterfvNV(table, _mesa_GetProgramParameterfvNV);
+ SET_GetProgramParameterdvNV(table, _mesa_GetProgramParameterdvNV);
+ SET_GetProgramivNV(table, _mesa_GetProgramivNV);
+ SET_GetProgramStringNV(table, _mesa_GetProgramStringNV);
+ SET_GetTrackMatrixivNV(table, _mesa_GetTrackMatrixivNV);
+ SET_GetVertexAttribdvNV(table, _mesa_GetVertexAttribdvNV);
+ SET_GetVertexAttribfvNV(table, _mesa_GetVertexAttribfvNV);
+ SET_GetVertexAttribivNV(table, _mesa_GetVertexAttribivNV);
+ SET_GetVertexAttribPointervNV(table, _mesa_GetVertexAttribPointervNV);
+ SET_IsProgramNV(table, _mesa_IsProgram);
+ SET_LoadProgramNV(table, save_LoadProgramNV);
+ SET_ProgramParameter4dNV(table, save_ProgramParameter4dNV);
+ SET_ProgramParameter4dvNV(table, save_ProgramParameter4dvNV);
+ SET_ProgramParameter4fNV(table, save_ProgramParameter4fNV);
+ SET_ProgramParameter4fvNV(table, save_ProgramParameter4fvNV);
+ SET_ProgramParameters4dvNV(table, save_ProgramParameters4dvNV);
+ SET_ProgramParameters4fvNV(table, save_ProgramParameters4fvNV);
+ SET_TrackMatrixNV(table, save_TrackMatrixNV);
+ SET_VertexAttribPointerNV(table, _mesa_VertexAttribPointerNV);
+#endif
+
+ /* 245. GL_ATI_fragment_shader */
+#if FEATURE_ATI_fragment_shader
+ SET_BindFragmentShaderATI(table, save_BindFragmentShaderATI);
+ SET_SetFragmentShaderConstantATI(table, save_SetFragmentShaderConstantATI);
+#endif
+
+ /* 282. GL_NV_fragment_program */
+#if FEATURE_NV_fragment_program
+ SET_ProgramNamedParameter4fNV(table, save_ProgramNamedParameter4fNV);
+ SET_ProgramNamedParameter4dNV(table, save_ProgramNamedParameter4dNV);
+ SET_ProgramNamedParameter4fvNV(table, save_ProgramNamedParameter4fvNV);
+ SET_ProgramNamedParameter4dvNV(table, save_ProgramNamedParameter4dvNV);
+ SET_GetProgramNamedParameterfvNV(table,
+ _mesa_GetProgramNamedParameterfvNV);
+ SET_GetProgramNamedParameterdvNV(table,
+ _mesa_GetProgramNamedParameterdvNV);
+ SET_ProgramLocalParameter4dARB(table, save_ProgramLocalParameter4dARB);
+ SET_ProgramLocalParameter4dvARB(table, save_ProgramLocalParameter4dvARB);
+ SET_ProgramLocalParameter4fARB(table, save_ProgramLocalParameter4fARB);
+ SET_ProgramLocalParameter4fvARB(table, save_ProgramLocalParameter4fvARB);
+ SET_GetProgramLocalParameterdvARB(table,
+ _mesa_GetProgramLocalParameterdvARB);
+ SET_GetProgramLocalParameterfvARB(table,
+ _mesa_GetProgramLocalParameterfvARB);
+#endif
+
+ /* 262. GL_NV_point_sprite */
+ SET_PointParameteriNV(table, save_PointParameteriNV);
+ SET_PointParameterivNV(table, save_PointParameterivNV);
+
+ /* 268. GL_EXT_stencil_two_side */
+ SET_ActiveStencilFaceEXT(table, save_ActiveStencilFaceEXT);
+
+ /* ???. GL_EXT_depth_bounds_test */
+ SET_DepthBoundsEXT(table, save_DepthBoundsEXT);
+
+ /* ARB 1. GL_ARB_multitexture */
+ SET_ActiveTextureARB(table, save_ActiveTextureARB);
+ SET_ClientActiveTextureARB(table, exec_ClientActiveTextureARB);
+
+ /* ARB 3. GL_ARB_transpose_matrix */
+ SET_LoadTransposeMatrixdARB(table, save_LoadTransposeMatrixdARB);
+ SET_LoadTransposeMatrixfARB(table, save_LoadTransposeMatrixfARB);
+ SET_MultTransposeMatrixdARB(table, save_MultTransposeMatrixdARB);
+ SET_MultTransposeMatrixfARB(table, save_MultTransposeMatrixfARB);
+
+ /* ARB 5. GL_ARB_multisample */
+ SET_SampleCoverageARB(table, save_SampleCoverageARB);
+
+ /* ARB 12. GL_ARB_texture_compression */
+ SET_CompressedTexImage3DARB(table, save_CompressedTexImage3DARB);
+ SET_CompressedTexImage2DARB(table, save_CompressedTexImage2DARB);
+ SET_CompressedTexImage1DARB(table, save_CompressedTexImage1DARB);
+ SET_CompressedTexSubImage3DARB(table, save_CompressedTexSubImage3DARB);
+ SET_CompressedTexSubImage2DARB(table, save_CompressedTexSubImage2DARB);
+ SET_CompressedTexSubImage1DARB(table, save_CompressedTexSubImage1DARB);
+ SET_GetCompressedTexImageARB(table, exec_GetCompressedTexImageARB);
+
+ /* ARB 14. GL_ARB_point_parameters */
+ /* aliased with EXT_point_parameters functions */
+
+ /* ARB 25. GL_ARB_window_pos */
+ /* aliased with MESA_window_pos functions */
+
+ /* ARB 26. GL_ARB_vertex_program */
+ /* ARB 27. GL_ARB_fragment_program */
+#if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program
+ /* glVertexAttrib* functions alias the NV ones, handled elsewhere */
+ SET_VertexAttribPointerARB(table, _mesa_VertexAttribPointerARB);
+ SET_EnableVertexAttribArrayARB(table, _mesa_EnableVertexAttribArrayARB);
+ SET_DisableVertexAttribArrayARB(table, _mesa_DisableVertexAttribArrayARB);
+ SET_ProgramStringARB(table, save_ProgramStringARB);
+ SET_BindProgramNV(table, save_BindProgramNV);
+ SET_DeleteProgramsNV(table, _mesa_DeletePrograms);
+ SET_GenProgramsNV(table, _mesa_GenPrograms);
+ SET_IsProgramNV(table, _mesa_IsProgram);
+ SET_GetVertexAttribdvNV(table, _mesa_GetVertexAttribdvNV);
+ SET_GetVertexAttribfvNV(table, _mesa_GetVertexAttribfvNV);
+ SET_GetVertexAttribivNV(table, _mesa_GetVertexAttribivNV);
+ SET_GetVertexAttribPointervNV(table, _mesa_GetVertexAttribPointervNV);
+ SET_ProgramEnvParameter4dARB(table, save_ProgramEnvParameter4dARB);
+ SET_ProgramEnvParameter4dvARB(table, save_ProgramEnvParameter4dvARB);
+ SET_ProgramEnvParameter4fARB(table, save_ProgramEnvParameter4fARB);
+ SET_ProgramEnvParameter4fvARB(table, save_ProgramEnvParameter4fvARB);
+ SET_ProgramLocalParameter4dARB(table, save_ProgramLocalParameter4dARB);
+ SET_ProgramLocalParameter4dvARB(table, save_ProgramLocalParameter4dvARB);
+ SET_ProgramLocalParameter4fARB(table, save_ProgramLocalParameter4fARB);
+ SET_ProgramLocalParameter4fvARB(table, save_ProgramLocalParameter4fvARB);
+ SET_GetProgramEnvParameterdvARB(table, _mesa_GetProgramEnvParameterdvARB);
+ SET_GetProgramEnvParameterfvARB(table, _mesa_GetProgramEnvParameterfvARB);
+ SET_GetProgramLocalParameterdvARB(table,
+ _mesa_GetProgramLocalParameterdvARB);
+ SET_GetProgramLocalParameterfvARB(table,
+ _mesa_GetProgramLocalParameterfvARB);
+ SET_GetProgramivARB(table, _mesa_GetProgramivARB);
+ SET_GetProgramStringARB(table, _mesa_GetProgramStringARB);
+#endif
+
+ /* ARB 28. GL_ARB_vertex_buffer_object */
+#if FEATURE_ARB_vertex_buffer_object
+ /* None of the extension's functions get compiled */
+ SET_BindBufferARB(table, _mesa_BindBufferARB);
+ SET_BufferDataARB(table, _mesa_BufferDataARB);
+ SET_BufferSubDataARB(table, _mesa_BufferSubDataARB);
+ SET_DeleteBuffersARB(table, _mesa_DeleteBuffersARB);
+ SET_GenBuffersARB(table, _mesa_GenBuffersARB);
+ SET_GetBufferParameterivARB(table, _mesa_GetBufferParameterivARB);
+ SET_GetBufferPointervARB(table, _mesa_GetBufferPointervARB);
+ SET_GetBufferSubDataARB(table, _mesa_GetBufferSubDataARB);
+ SET_IsBufferARB(table, _mesa_IsBufferARB);
+ SET_MapBufferARB(table, _mesa_MapBufferARB);
+ SET_UnmapBufferARB(table, _mesa_UnmapBufferARB);
+#endif
+
+#if FEATURE_ARB_occlusion_query
+ SET_BeginQueryARB(table, save_BeginQueryARB);
+ SET_EndQueryARB(table, save_EndQueryARB);
+ SET_GenQueriesARB(table, _mesa_GenQueriesARB);
+ SET_DeleteQueriesARB(table, _mesa_DeleteQueriesARB);
+ SET_IsQueryARB(table, _mesa_IsQueryARB);
+ SET_GetQueryivARB(table, _mesa_GetQueryivARB);
+ SET_GetQueryObjectivARB(table, _mesa_GetQueryObjectivARB);
+ SET_GetQueryObjectuivARB(table, _mesa_GetQueryObjectuivARB);
+#endif
+ SET_DrawBuffersARB(table, save_DrawBuffersARB);
+
+#if FEATURE_EXT_framebuffer_blit
+ SET_BlitFramebufferEXT(table, save_BlitFramebufferEXT);
+#endif
+
+ /* 299. GL_EXT_blend_equation_separate */
+ SET_BlendEquationSeparateEXT(table, save_BlendEquationSeparateEXT);
+}
+
+
+
+static const char *
+enum_string(GLenum k)
+{
+ return _mesa_lookup_enum_by_nr(k);
+}
+
+
+/**
+ * Print the commands in a display list. For debugging only.
+ * TODO: many commands aren't handled yet.
+ */
+static void GLAPIENTRY
+print_list(GLcontext *ctx, GLuint list)
+{
+ struct mesa_display_list *dlist;
+ Node *n;
+ GLboolean done;
+
+ if (!islist(ctx, list)) {
+ _mesa_printf("%u is not a display list ID\n", list);
+ return;
+ }
+
+ dlist = (struct mesa_display_list *)
+ _mesa_HashLookup(ctx->Shared->DisplayList, list);
+ if (!dlist)
+ return;
+
+ n = dlist->node;
+
+ _mesa_printf("START-LIST %u, address %p\n", list, (void *) n);
+
+ done = n ? GL_FALSE : GL_TRUE;
+ while (!done) {
+ OpCode opcode = n[0].opcode;
+ GLint i = (GLint) n[0].opcode - (GLint) OPCODE_EXT_0;
+
+ if (i >= 0 && i < (GLint) ctx->ListExt.NumOpcodes) {
+ /* this is a driver-extended opcode */
+ ctx->ListExt.Opcode[i].Print(ctx, &n[1]);
+ n += ctx->ListExt.Opcode[i].Size;
+ }
+ else {
+ switch (opcode) {
+ case OPCODE_ACCUM:
+ _mesa_printf("Accum %s %g\n", enum_string(n[1].e), n[2].f);
+ break;
+ case OPCODE_BITMAP:
+ _mesa_printf("Bitmap %d %d %g %g %g %g %p\n", n[1].i, n[2].i,
+ n[3].f, n[4].f, n[5].f, n[6].f, (void *) n[7].data);
+ break;
+ case OPCODE_CALL_LIST:
+ _mesa_printf("CallList %d\n", (int) n[1].ui);
+ break;
+ case OPCODE_CALL_LIST_OFFSET:
+ _mesa_printf("CallList %d + offset %u = %u\n", (int) n[1].ui,
+ ctx->List.ListBase, ctx->List.ListBase + n[1].ui);
+ break;
+ case OPCODE_COLOR_TABLE_PARAMETER_FV:
+ _mesa_printf("ColorTableParameterfv %s %s %f %f %f %f\n",
+ enum_string(n[1].e), enum_string(n[2].e),
+ n[3].f, n[4].f, n[5].f, n[6].f);
+ break;
+ case OPCODE_COLOR_TABLE_PARAMETER_IV:
+ _mesa_printf("ColorTableParameteriv %s %s %d %d %d %d\n",
+ enum_string(n[1].e), enum_string(n[2].e),
+ n[3].i, n[4].i, n[5].i, n[6].i);
+ break;
+ case OPCODE_DISABLE:
+ _mesa_printf("Disable %s\n", enum_string(n[1].e));
+ break;
+ case OPCODE_ENABLE:
+ _mesa_printf("Enable %s\n", enum_string(n[1].e));
+ break;
+ case OPCODE_FRUSTUM:
+ _mesa_printf("Frustum %g %g %g %g %g %g\n",
+ n[1].f, n[2].f, n[3].f, n[4].f, n[5].f, n[6].f);
+ break;
+ case OPCODE_LINE_STIPPLE:
+ _mesa_printf("LineStipple %d %x\n", n[1].i, (int) n[2].us);
+ break;
+ case OPCODE_LOAD_IDENTITY:
+ _mesa_printf("LoadIdentity\n");
+ break;
+ case OPCODE_LOAD_MATRIX:
+ _mesa_printf("LoadMatrix\n");
+ _mesa_printf(" %8f %8f %8f %8f\n",
+ n[1].f, n[5].f, n[9].f, n[13].f);
+ _mesa_printf(" %8f %8f %8f %8f\n",
+ n[2].f, n[6].f, n[10].f, n[14].f);
+ _mesa_printf(" %8f %8f %8f %8f\n",
+ n[3].f, n[7].f, n[11].f, n[15].f);
+ _mesa_printf(" %8f %8f %8f %8f\n",
+ n[4].f, n[8].f, n[12].f, n[16].f);
+ break;
+ case OPCODE_MULT_MATRIX:
+ _mesa_printf("MultMatrix (or Rotate)\n");
+ _mesa_printf(" %8f %8f %8f %8f\n",
+ n[1].f, n[5].f, n[9].f, n[13].f);
+ _mesa_printf(" %8f %8f %8f %8f\n",
+ n[2].f, n[6].f, n[10].f, n[14].f);
+ _mesa_printf(" %8f %8f %8f %8f\n",
+ n[3].f, n[7].f, n[11].f, n[15].f);
+ _mesa_printf(" %8f %8f %8f %8f\n",
+ n[4].f, n[8].f, n[12].f, n[16].f);
+ break;
+ case OPCODE_ORTHO:
+ _mesa_printf("Ortho %g %g %g %g %g %g\n",
+ n[1].f, n[2].f, n[3].f, n[4].f, n[5].f, n[6].f);
+ break;
+ case OPCODE_POP_ATTRIB:
+ _mesa_printf("PopAttrib\n");
+ break;
+ case OPCODE_POP_MATRIX:
+ _mesa_printf("PopMatrix\n");
+ break;
+ case OPCODE_POP_NAME:
+ _mesa_printf("PopName\n");
+ break;
+ case OPCODE_PUSH_ATTRIB:
+ _mesa_printf("PushAttrib %x\n", n[1].bf);
+ break;
+ case OPCODE_PUSH_MATRIX:
+ _mesa_printf("PushMatrix\n");
+ break;
+ case OPCODE_PUSH_NAME:
+ _mesa_printf("PushName %d\n", (int) n[1].ui);
+ break;
+ case OPCODE_RASTER_POS:
+ _mesa_printf("RasterPos %g %g %g %g\n",
+ n[1].f, n[2].f, n[3].f, n[4].f);
+ break;
+ case OPCODE_ROTATE:
+ _mesa_printf("Rotate %g %g %g %g\n",
+ n[1].f, n[2].f, n[3].f, n[4].f);
+ break;
+ case OPCODE_SCALE:
+ _mesa_printf("Scale %g %g %g\n", n[1].f, n[2].f, n[3].f);
+ break;
+ case OPCODE_TRANSLATE:
+ _mesa_printf("Translate %g %g %g\n", n[1].f, n[2].f, n[3].f);
+ break;
+ case OPCODE_BIND_TEXTURE:
+ _mesa_printf("BindTexture %s %d\n",
+ _mesa_lookup_enum_by_nr(n[1].ui), n[2].ui);
+ break;
+ case OPCODE_SHADE_MODEL:
+ _mesa_printf("ShadeModel %s\n", _mesa_lookup_enum_by_nr(n[1].ui));
+ break;
+ case OPCODE_MAP1:
+ _mesa_printf("Map1 %s %.3f %.3f %d %d\n",
+ _mesa_lookup_enum_by_nr(n[1].ui),
+ n[2].f, n[3].f, n[4].i, n[5].i);
+ break;
+ case OPCODE_MAP2:
+ _mesa_printf("Map2 %s %.3f %.3f %.3f %.3f %d %d %d %d\n",
+ _mesa_lookup_enum_by_nr(n[1].ui),
+ n[2].f, n[3].f, n[4].f, n[5].f,
+ n[6].i, n[7].i, n[8].i, n[9].i);
+ break;
+ case OPCODE_MAPGRID1:
+ _mesa_printf("MapGrid1 %d %.3f %.3f\n", n[1].i, n[2].f, n[3].f);
+ break;
+ case OPCODE_MAPGRID2:
+ _mesa_printf("MapGrid2 %d %.3f %.3f, %d %.3f %.3f\n",
+ n[1].i, n[2].f, n[3].f, n[4].i, n[5].f, n[6].f);
+ break;
+ case OPCODE_EVALMESH1:
+ _mesa_printf("EvalMesh1 %d %d\n", n[1].i, n[2].i);
+ break;
+ case OPCODE_EVALMESH2:
+ _mesa_printf("EvalMesh2 %d %d %d %d\n",
+ n[1].i, n[2].i, n[3].i, n[4].i);
+ break;
+
+ case OPCODE_ATTR_1F_NV:
+ _mesa_printf("ATTR_1F_NV attr %d: %f\n", n[1].i, n[2].f);
+ break;
+ case OPCODE_ATTR_2F_NV:
+ _mesa_printf("ATTR_2F_NV attr %d: %f %f\n",
+ n[1].i, n[2].f, n[3].f);
+ break;
+ case OPCODE_ATTR_3F_NV:
+ _mesa_printf("ATTR_3F_NV attr %d: %f %f %f\n",
+ n[1].i, n[2].f, n[3].f, n[4].f);
+ break;
+ case OPCODE_ATTR_4F_NV:
+ _mesa_printf("ATTR_4F_NV attr %d: %f %f %f %f\n",
+ n[1].i, n[2].f, n[3].f, n[4].f, n[5].f);
+ break;
+ case OPCODE_ATTR_1F_ARB:
+ _mesa_printf("ATTR_1F_ARB attr %d: %f\n", n[1].i, n[2].f);
+ break;
+ case OPCODE_ATTR_2F_ARB:
+ _mesa_printf("ATTR_2F_ARB attr %d: %f %f\n",
+ n[1].i, n[2].f, n[3].f);
+ break;
+ case OPCODE_ATTR_3F_ARB:
+ _mesa_printf("ATTR_3F_ARB attr %d: %f %f %f\n",
+ n[1].i, n[2].f, n[3].f, n[4].f);
+ break;
+ case OPCODE_ATTR_4F_ARB:
+ _mesa_printf("ATTR_4F_ARB attr %d: %f %f %f %f\n",
+ n[1].i, n[2].f, n[3].f, n[4].f, n[5].f);
+ break;
+
+ case OPCODE_MATERIAL:
+ _mesa_printf("MATERIAL %x %x: %f %f %f %f\n",
+ n[1].i, n[2].i, n[3].f, n[4].f, n[5].f, n[6].f);
+ break;
+ case OPCODE_INDEX:
+ _mesa_printf("INDEX: %f\n", n[1].f);
+ break;
+ case OPCODE_EDGEFLAG:
+ _mesa_printf("EDGEFLAG: %d\n", n[1].i);
+ break;
+ case OPCODE_BEGIN:
+ _mesa_printf("BEGIN %x\n", n[1].i);
+ break;
+ case OPCODE_END:
+ _mesa_printf("END\n");
+ break;
+ case OPCODE_RECTF:
+ _mesa_printf("RECTF %f %f %f %f\n", n[1].f, n[2].f, n[3].f,
+ n[4].f);
+ break;
+ case OPCODE_EVAL_C1:
+ _mesa_printf("EVAL_C1 %f\n", n[1].f);
+ break;
+ case OPCODE_EVAL_C2:
+ _mesa_printf("EVAL_C2 %f %f\n", n[1].f, n[2].f);
+ break;
+ case OPCODE_EVAL_P1:
+ _mesa_printf("EVAL_P1 %d\n", n[1].i);
+ break;
+ case OPCODE_EVAL_P2:
+ _mesa_printf("EVAL_P2 %d %d\n", n[1].i, n[2].i);
+ break;
+
+
+
+ /*
+ * meta opcodes/commands
+ */
+ case OPCODE_ERROR:
+ _mesa_printf("Error: %s %s\n",
+ enum_string(n[1].e), (const char *) n[2].data);
+ break;
+ case OPCODE_CONTINUE:
+ _mesa_printf("DISPLAY-LIST-CONTINUE\n");
+ n = (Node *) n[1].next;
+ break;
+ case OPCODE_END_OF_LIST:
+ _mesa_printf("END-LIST %u\n", list);
+ done = GL_TRUE;
+ break;
+ default:
+ if (opcode < 0 || opcode > OPCODE_END_OF_LIST) {
+ _mesa_printf
+ ("ERROR IN DISPLAY LIST: opcode = %d, address = %p\n",
+ opcode, (void *) n);
+ return;
+ }
+ else {
+ _mesa_printf("command %d, %u operands\n", opcode,
+ InstSize[opcode]);
+ }
+ }
+ /* increment n to point to next compiled command */
+ if (opcode != OPCODE_CONTINUE) {
+ n += InstSize[opcode];
+ }
+ }
+ }
+}
+
+
+
+/**
+ * Clients may call this function to help debug display list problems.
+ * This function is _ONLY_FOR_DEBUGGING_PURPOSES_. It may be removed,
+ * changed, or break in the future without notice.
+ */
+void
+mesa_print_display_list(GLuint list)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ print_list(ctx, list);
+}
+
+
+/**********************************************************************/
+/***** Initialization *****/
+/**********************************************************************/
+
+void
+_mesa_save_vtxfmt_init(GLvertexformat * vfmt)
+{
+ vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */
+ vfmt->Begin = save_Begin;
+ vfmt->CallList = _mesa_save_CallList;
+ vfmt->CallLists = _mesa_save_CallLists;
+ vfmt->Color3f = save_Color3f;
+ vfmt->Color3fv = save_Color3fv;
+ vfmt->Color4f = save_Color4f;
+ vfmt->Color4fv = save_Color4fv;
+ vfmt->EdgeFlag = save_EdgeFlag;
+ vfmt->EdgeFlagv = save_EdgeFlagv;
+ vfmt->End = save_End;
+ vfmt->EvalCoord1f = save_EvalCoord1f;
+ vfmt->EvalCoord1fv = save_EvalCoord1fv;
+ vfmt->EvalCoord2f = save_EvalCoord2f;
+ vfmt->EvalCoord2fv = save_EvalCoord2fv;
+ vfmt->EvalPoint1 = save_EvalPoint1;
+ vfmt->EvalPoint2 = save_EvalPoint2;
+ vfmt->FogCoordfEXT = save_FogCoordfEXT;
+ vfmt->FogCoordfvEXT = save_FogCoordfvEXT;
+ vfmt->Indexf = save_Indexf;
+ vfmt->Indexfv = save_Indexfv;
+ vfmt->Materialfv = save_Materialfv;
+ vfmt->MultiTexCoord1fARB = save_MultiTexCoord1f;
+ vfmt->MultiTexCoord1fvARB = save_MultiTexCoord1fv;
+ vfmt->MultiTexCoord2fARB = save_MultiTexCoord2f;
+ vfmt->MultiTexCoord2fvARB = save_MultiTexCoord2fv;
+ vfmt->MultiTexCoord3fARB = save_MultiTexCoord3f;
+ vfmt->MultiTexCoord3fvARB = save_MultiTexCoord3fv;
+ vfmt->MultiTexCoord4fARB = save_MultiTexCoord4f;
+ vfmt->MultiTexCoord4fvARB = save_MultiTexCoord4fv;
+ vfmt->Normal3f = save_Normal3f;
+ vfmt->Normal3fv = save_Normal3fv;
+ vfmt->SecondaryColor3fEXT = save_SecondaryColor3fEXT;
+ vfmt->SecondaryColor3fvEXT = save_SecondaryColor3fvEXT;
+ vfmt->TexCoord1f = save_TexCoord1f;
+ vfmt->TexCoord1fv = save_TexCoord1fv;
+ vfmt->TexCoord2f = save_TexCoord2f;
+ vfmt->TexCoord2fv = save_TexCoord2fv;
+ vfmt->TexCoord3f = save_TexCoord3f;
+ vfmt->TexCoord3fv = save_TexCoord3fv;
+ vfmt->TexCoord4f = save_TexCoord4f;
+ vfmt->TexCoord4fv = save_TexCoord4fv;
+ vfmt->Vertex2f = save_Vertex2f;
+ vfmt->Vertex2fv = save_Vertex2fv;
+ vfmt->Vertex3f = save_Vertex3f;
+ vfmt->Vertex3fv = save_Vertex3fv;
+ vfmt->Vertex4f = save_Vertex4f;
+ vfmt->Vertex4fv = save_Vertex4fv;
+ vfmt->VertexAttrib1fNV = save_VertexAttrib1fNV;
+ vfmt->VertexAttrib1fvNV = save_VertexAttrib1fvNV;
+ vfmt->VertexAttrib2fNV = save_VertexAttrib2fNV;
+ vfmt->VertexAttrib2fvNV = save_VertexAttrib2fvNV;
+ vfmt->VertexAttrib3fNV = save_VertexAttrib3fNV;
+ vfmt->VertexAttrib3fvNV = save_VertexAttrib3fvNV;
+ vfmt->VertexAttrib4fNV = save_VertexAttrib4fNV;
+ vfmt->VertexAttrib4fvNV = save_VertexAttrib4fvNV;
+ vfmt->VertexAttrib1fARB = save_VertexAttrib1fARB;
+ vfmt->VertexAttrib1fvARB = save_VertexAttrib1fvARB;
+ vfmt->VertexAttrib2fARB = save_VertexAttrib2fARB;
+ vfmt->VertexAttrib2fvARB = save_VertexAttrib2fvARB;
+ vfmt->VertexAttrib3fARB = save_VertexAttrib3fARB;
+ vfmt->VertexAttrib3fvARB = save_VertexAttrib3fvARB;
+ vfmt->VertexAttrib4fARB = save_VertexAttrib4fARB;
+ vfmt->VertexAttrib4fvARB = save_VertexAttrib4fvARB;
+
+ vfmt->EvalMesh1 = _mesa_save_EvalMesh1;
+ vfmt->EvalMesh2 = _mesa_save_EvalMesh2;
+ vfmt->Rectf = save_Rectf;
+
+ /* The driver is required to implement these as
+ * 1) They can probably do a better job.
+ * 2) A lot of new mechanisms would have to be added to this module
+ * to support it. That code would probably never get used,
+ * because of (1).
+ */
+#if 0
+ vfmt->DrawArrays = 0;
+ vfmt->DrawElements = 0;
+ vfmt->DrawRangeElements = 0;
+#endif
+}
+
+
+/**
+ * Initialize display list state for given context.
+ */
+void
+_mesa_init_display_list(GLcontext *ctx)
+{
+ static GLboolean tableInitialized = GL_FALSE;
+
+ /* zero-out the instruction size table, just once */
+ if (!tableInitialized) {
+ _mesa_bzero(InstSize, sizeof(InstSize));
+ tableInitialized = GL_TRUE;
+ }
+
+ /* Display list */
+ ctx->ListState.CallDepth = 0;
+ ctx->ExecuteFlag = GL_TRUE;
+ ctx->CompileFlag = GL_FALSE;
+ ctx->ListState.CurrentListPtr = NULL;
+ ctx->ListState.CurrentBlock = NULL;
+ ctx->ListState.CurrentListNum = 0;
+ ctx->ListState.CurrentPos = 0;
+
+ /* Display List group */
+ ctx->List.ListBase = 0;
+
+ _mesa_save_vtxfmt_init(&ctx->ListState.ListVtxfmt);
+}
diff --git a/src/mesa/main/dlist.h b/src/mesa/main/dlist.h
new file mode 100644
index 00000000000..9436603d0a5
--- /dev/null
+++ b/src/mesa/main/dlist.h
@@ -0,0 +1,98 @@
+/**
+ * \file dlist.h
+ * Display lists management.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 5.1
+ *
+ * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+#ifndef DLIST_H
+#define DLIST_H
+
+
+#include "mtypes.h"
+
+
+#if _HAVE_FULL_GL
+
+extern void _mesa_destroy_list( GLcontext *ctx, GLuint list );
+
+extern void GLAPIENTRY _mesa_CallList( GLuint list );
+
+extern void GLAPIENTRY _mesa_CallLists( GLsizei n, GLenum type, const GLvoid *lists );
+
+extern void GLAPIENTRY _mesa_DeleteLists( GLuint list, GLsizei range );
+
+extern void GLAPIENTRY _mesa_EndList( void );
+
+extern GLuint GLAPIENTRY _mesa_GenLists( GLsizei range );
+
+extern GLboolean GLAPIENTRY _mesa_IsList( GLuint list );
+
+extern void GLAPIENTRY _mesa_ListBase( GLuint base );
+
+extern void GLAPIENTRY _mesa_NewList( GLuint list, GLenum mode );
+
+extern void GLAPIENTRY _mesa_save_CallLists( GLsizei n, GLenum type, const GLvoid *lists );
+
+extern void GLAPIENTRY _mesa_save_CallList( GLuint list );
+
+
+
+extern void _mesa_init_dlist_table( struct _glapi_table *table );
+
+extern void _mesa_compile_error( GLcontext *ctx, GLenum error, const char *s );
+
+
+extern void *_mesa_alloc_instruction(GLcontext *ctx, GLuint opcode, GLuint sz);
+
+extern GLint _mesa_alloc_opcode( GLcontext *ctx, GLuint sz,
+ void (*execute)( GLcontext *, void * ),
+ void (*destroy)( GLcontext *, void * ),
+ void (*print)( GLcontext *, void * ) );
+
+extern void _mesa_init_display_list( GLcontext * ctx );
+
+extern void _mesa_save_vtxfmt_init( GLvertexformat *vfmt );
+
+
+#else
+
+/** No-op */
+#define _mesa_destroy_list(c,l) ((void)0)
+
+/** No-op */
+#define _mesa_init_dlist_table(t,ts) ((void)0)
+
+/** No-op */
+#define _mesa_init_display_list(c) ((void)0)
+
+/** No-op */
+#define _mesa_save_vtxfmt_init(v) ((void)0)
+
+#endif
+
+#endif
diff --git a/src/mesa/main/drawpix.c b/src/mesa/main/drawpix.c
new file mode 100644
index 00000000000..c82abccc41a
--- /dev/null
+++ b/src/mesa/main/drawpix.c
@@ -0,0 +1,435 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "glheader.h"
+#include "imports.h"
+#include "context.h"
+#include "drawpix.h"
+#include "feedback.h"
+#include "framebuffer.h"
+#include "image.h"
+#include "state.h"
+
+
+/**
+ * Do error checking of the format/type parameters to glReadPixels and
+ * glDrawPixels.
+ * \param drawing if GL_TRUE do checking for DrawPixels, else do checking
+ * for ReadPixels.
+ * \return GL_TRUE if error detected, GL_FALSE if no errors
+ */
+static GLboolean
+error_check_format_type(GLcontext *ctx, GLenum format, GLenum type,
+ GLboolean drawing)
+{
+ const char *readDraw = drawing ? "Draw" : "Read";
+
+ if (ctx->Extensions.EXT_packed_depth_stencil
+ && type == GL_UNSIGNED_INT_24_8_EXT
+ && format != GL_DEPTH_STENCIL_EXT) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "gl%sPixels(format is not GL_DEPTH_STENCIL_EXT)", readDraw);
+ return GL_TRUE;
+ }
+
+ /* basic combinations test */
+ if (!_mesa_is_legal_format_and_type(ctx, format, type)) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "gl%sPixels(format or type)", readDraw);
+ return GL_TRUE;
+ }
+
+ /* additional checks */
+ switch (format) {
+ case GL_RED:
+ case GL_GREEN:
+ case GL_BLUE:
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ case GL_RGB:
+ case GL_BGR:
+ case GL_RGBA:
+ case GL_BGRA:
+ case GL_ABGR_EXT:
+ if (drawing && !ctx->Visual.rgbMode) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glDrawPixels(drawing RGB pixels into color index buffer)");
+ return GL_TRUE;
+ }
+ if (!drawing && !_mesa_dest_buffer_exists(ctx, GL_COLOR)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glReadPixels(no color buffer)");
+ return GL_TRUE;
+ }
+ break;
+ case GL_COLOR_INDEX:
+ if (!drawing && ctx->Visual.rgbMode) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glReadPixels(reading color index format from RGB buffer)");
+ return GL_TRUE;
+ }
+ if (!drawing && !_mesa_dest_buffer_exists(ctx, GL_COLOR)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glReadPixels(no color buffer)");
+ return GL_TRUE;
+ }
+ break;
+ case GL_STENCIL_INDEX:
+ if ((drawing && !_mesa_dest_buffer_exists(ctx, format)) ||
+ (!drawing && !_mesa_source_buffer_exists(ctx, format))) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "gl%sPixels(no stencil buffer)", readDraw);
+ return GL_TRUE;
+ }
+ break;
+ case GL_DEPTH_COMPONENT:
+ if ((drawing && !_mesa_dest_buffer_exists(ctx, format)) ||
+ (!drawing && !_mesa_source_buffer_exists(ctx, format))) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "gl%sPixels(no depth buffer)", readDraw);
+ return GL_TRUE;
+ }
+ break;
+ case GL_DEPTH_STENCIL_EXT:
+ if (!ctx->Extensions.EXT_packed_depth_stencil ||
+ type != GL_UNSIGNED_INT_24_8_EXT) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "gl%sPixels(type)", readDraw);
+ return GL_TRUE;
+ }
+ if ((drawing && !_mesa_dest_buffer_exists(ctx, format)) ||
+ (!drawing && !_mesa_source_buffer_exists(ctx, format))) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "gl%sPixels(no depth or stencil buffer)", readDraw);
+ return GL_TRUE;
+ }
+ break;
+ default:
+ /* this should have been caught in _mesa_is_legal_format_type() */
+ _mesa_problem(ctx, "unexpected format in _mesa_%sPixels", readDraw);
+ return GL_TRUE;
+ }
+
+ /* no errors */
+ return GL_FALSE;
+}
+
+
+
+#if _HAVE_FULL_GL
+
+/*
+ * Execute glDrawPixels
+ */
+void GLAPIENTRY
+_mesa_DrawPixels( GLsizei width, GLsizei height,
+ GLenum format, GLenum type, const GLvoid *pixels )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (width < 0 || height < 0) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glDrawPixels(width or height < 0" );
+ return;
+ }
+
+ if (ctx->NewState) {
+ _mesa_update_state(ctx);
+ }
+
+ if (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glDrawPixels (invalid fragment program)");
+ return;
+ }
+
+ if (error_check_format_type(ctx, format, type, GL_TRUE)) {
+ /* found an error */
+ return;
+ }
+
+ if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
+ "glDrawPixels(incomplete framebuffer)" );
+ return;
+ }
+
+ if (!ctx->Current.RasterPosValid) {
+ return;
+ }
+
+ if (ctx->RenderMode == GL_RENDER) {
+ /* Round, to satisfy conformance tests (matches SGI's OpenGL) */
+ GLint x = IROUND(ctx->Current.RasterPos[0]);
+ GLint y = IROUND(ctx->Current.RasterPos[1]);
+ ctx->Driver.DrawPixels(ctx, x, y, width, height, format, type,
+ &ctx->Unpack, pixels);
+ }
+ else if (ctx->RenderMode == GL_FEEDBACK) {
+ /* Feedback the current raster pos info */
+ FLUSH_CURRENT( ctx, 0 );
+ FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_DRAW_PIXEL_TOKEN );
+ _mesa_feedback_vertex( ctx,
+ ctx->Current.RasterPos,
+ ctx->Current.RasterColor,
+ ctx->Current.RasterIndex,
+ ctx->Current.RasterTexCoords[0] );
+ }
+ else {
+ ASSERT(ctx->RenderMode == GL_SELECT);
+ /* Do nothing. See OpenGL Spec, Appendix B, Corollary 6. */
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height,
+ GLenum type )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (ctx->NewState) {
+ _mesa_update_state(ctx);
+ }
+
+ if (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glCopyPixels (invalid fragment program)");
+ return;
+ }
+
+ if (width < 0 || height < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glCopyPixels(width or height < 0)");
+ return;
+ }
+
+ if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT ||
+ ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
+ "glCopyPixels(incomplete framebuffer)" );
+ return;
+ }
+
+ if (!_mesa_source_buffer_exists(ctx, type) ||
+ !_mesa_dest_buffer_exists(ctx, type)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glCopyPixels(missing source or dest buffer)");
+ return;
+ }
+
+ if (!ctx->Current.RasterPosValid) {
+ return;
+ }
+
+ if (ctx->RenderMode == GL_RENDER) {
+ /* Round to satisfy conformance tests (matches SGI's OpenGL) */
+ GLint destx = IROUND(ctx->Current.RasterPos[0]);
+ GLint desty = IROUND(ctx->Current.RasterPos[1]);
+ ctx->Driver.CopyPixels( ctx, srcx, srcy, width, height, destx, desty,
+ type );
+ }
+ else if (ctx->RenderMode == GL_FEEDBACK) {
+ FLUSH_CURRENT( ctx, 0 );
+ FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_COPY_PIXEL_TOKEN );
+ _mesa_feedback_vertex( ctx,
+ ctx->Current.RasterPos,
+ ctx->Current.RasterColor,
+ ctx->Current.RasterIndex,
+ ctx->Current.RasterTexCoords[0] );
+ }
+ else {
+ ASSERT(ctx->RenderMode == GL_SELECT);
+ /* Do nothing. See OpenGL Spec, Appendix B, Corollary 6. */
+ }
+}
+
+#endif /* _HAVE_FULL_GL */
+
+
+
+void GLAPIENTRY
+_mesa_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type, GLvoid *pixels )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (width < 0 || height < 0) {
+ _mesa_error( ctx, GL_INVALID_VALUE,
+ "glReadPixels(width=%d height=%d)", width, height );
+ return;
+ }
+
+ if (ctx->NewState)
+ _mesa_update_state(ctx);
+
+ if (error_check_format_type(ctx, format, type, GL_FALSE)) {
+ /* found an error */
+ return;
+ }
+
+ if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
+ "glReadPixels(incomplete framebuffer)" );
+ return;
+ }
+
+ if (!_mesa_source_buffer_exists(ctx, format)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(no readbuffer)");
+ return;
+ }
+
+ ctx->Driver.ReadPixels(ctx, x, y, width, height,
+ format, type, &ctx->Pack, pixels);
+}
+
+
+
+void GLAPIENTRY
+_mesa_Bitmap( GLsizei width, GLsizei height,
+ GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove,
+ const GLubyte *bitmap )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (width < 0 || height < 0) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glBitmap(width or height < 0)" );
+ return;
+ }
+
+ if (!ctx->Current.RasterPosValid) {
+ return; /* do nothing */
+ }
+
+ if (ctx->NewState) {
+ _mesa_update_state(ctx);
+ }
+
+ if (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glBitmap (invalid fragment program)");
+ return;
+ }
+
+ if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
+ "glBitmap(incomplete framebuffer)");
+ return;
+ }
+
+ if (ctx->RenderMode == GL_RENDER) {
+ if (bitmap) {
+ /* Truncate, to satisfy conformance tests (matches SGI's OpenGL). */
+ GLint x = IFLOOR(ctx->Current.RasterPos[0] - xorig);
+ GLint y = IFLOOR(ctx->Current.RasterPos[1] - yorig);
+ ctx->Driver.Bitmap( ctx, x, y, width, height, &ctx->Unpack, bitmap );
+ }
+ }
+#if _HAVE_FULL_GL
+ else if (ctx->RenderMode == GL_FEEDBACK) {
+ FLUSH_CURRENT(ctx, 0);
+ FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_BITMAP_TOKEN );
+ _mesa_feedback_vertex( ctx,
+ ctx->Current.RasterPos,
+ ctx->Current.RasterColor,
+ ctx->Current.RasterIndex,
+ ctx->Current.RasterTexCoords[0] );
+ }
+ else {
+ ASSERT(ctx->RenderMode == GL_SELECT);
+ /* Do nothing. See OpenGL Spec, Appendix B, Corollary 6. */
+ }
+#endif
+
+ /* update raster position */
+ ctx->Current.RasterPos[0] += xmove;
+ ctx->Current.RasterPos[1] += ymove;
+}
+
+
+
+#if 0 /* experimental */
+/*
+ * Execute glDrawDepthPixelsMESA(). This function accepts both a color
+ * image and depth (Z) image. Rasterization produces fragments with
+ * color and Z taken from these images. This function is intended for
+ * Z-compositing. Normally, this operation requires two glDrawPixels
+ * calls with stencil testing.
+ */
+void GLAPIENTRY
+_mesa_DrawDepthPixelsMESA( GLsizei width, GLsizei height,
+ GLenum colorFormat, GLenum colorType,
+ const GLvoid *colors,
+ GLenum depthType, const GLvoid *depths )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (width < 0 || height < 0) {
+ _mesa_error( ctx, GL_INVALID_VALUE,
+ "glDrawDepthPixelsMESA(width or height < 0" );
+ return;
+ }
+
+ if (!ctx->Current.RasterPosValid) {
+ return;
+ }
+
+ if (ctx->NewState) {
+ _mesa_update_state(ctx);
+ }
+
+ if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
+ "glDrawDepthPixelsMESA(incomplete framebuffer)");
+ return;
+ }
+
+ if (ctx->RenderMode == GL_RENDER) {
+ /* Round, to satisfy conformance tests (matches SGI's OpenGL) */
+ GLint x = IROUND(ctx->Current.RasterPos[0]);
+ GLint y = IROUND(ctx->Current.RasterPos[1]);
+ ctx->Driver.DrawDepthPixelsMESA(ctx, x, y, width, height,
+ colorFormat, colorType, colors,
+ depthType, depths, &ctx->Unpack);
+ }
+ else if (ctx->RenderMode == GL_FEEDBACK) {
+ /* Feedback the current raster pos info */
+ FLUSH_CURRENT( ctx, 0 );
+ FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_DRAW_PIXEL_TOKEN );
+ _mesa_feedback_vertex( ctx,
+ ctx->Current.RasterPos,
+ ctx->Current.RasterColor,
+ ctx->Current.RasterIndex,
+ ctx->Current.RasterTexCoords[0] );
+ }
+ else {
+ ASSERT(ctx->RenderMode == GL_SELECT);
+ /* Do nothing. See OpenGL Spec, Appendix B, Corollary 6. */
+ }
+}
+
+#endif
diff --git a/src/mesa/main/drawpix.h b/src/mesa/main/drawpix.h
new file mode 100644
index 00000000000..2a2d7de8d81
--- /dev/null
+++ b/src/mesa/main/drawpix.h
@@ -0,0 +1,55 @@
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.5
+ *
+ * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef DRAWPIXELS_H
+#define DRAWPIXELS_H
+
+
+#include "mtypes.h"
+
+
+extern void GLAPIENTRY
+_mesa_DrawPixels( GLsizei width, GLsizei height,
+ GLenum format, GLenum type, const GLvoid *pixels );
+
+
+extern void GLAPIENTRY
+_mesa_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type, GLvoid *pixels );
+
+
+extern void GLAPIENTRY
+_mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height,
+ GLenum type );
+
+
+extern void GLAPIENTRY
+_mesa_Bitmap( GLsizei width, GLsizei height,
+ GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove,
+ const GLubyte *bitmap );
+
+
+#endif
diff --git a/src/mesa/main/enable.c b/src/mesa/main/enable.c
new file mode 100644
index 00000000000..af54fea30bb
--- /dev/null
+++ b/src/mesa/main/enable.c
@@ -0,0 +1,1426 @@
+/**
+ * \file enable.c
+ * Enable/disable/query GL capabilities.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include "glheader.h"
+#include "context.h"
+#include "enable.h"
+#include "light.h"
+#include "macros.h"
+#include "simple_list.h"
+#include "mtypes.h"
+#include "enums.h"
+#include "math/m_matrix.h"
+#include "math/m_xform.h"
+
+
+
+#define CHECK_EXTENSION(EXTNAME, CAP) \
+ if (!ctx->Extensions.EXTNAME) { \
+ _mesa_error(ctx, GL_INVALID_ENUM, "gl%sClientState(0x%x)", \
+ state ? "Enable" : "Disable", CAP); \
+ return; \
+ }
+
+
+static void
+client_state( GLcontext *ctx, GLenum cap, GLboolean state )
+{
+ GLuint flag;
+ GLuint *var;
+
+ switch (cap) {
+ case GL_VERTEX_ARRAY:
+ var = &ctx->Array.Vertex.Enabled;
+ flag = _NEW_ARRAY_VERTEX;
+ break;
+ case GL_NORMAL_ARRAY:
+ var = &ctx->Array.Normal.Enabled;
+ flag = _NEW_ARRAY_NORMAL;
+ break;
+ case GL_COLOR_ARRAY:
+ var = &ctx->Array.Color.Enabled;
+ flag = _NEW_ARRAY_COLOR0;
+ break;
+ case GL_INDEX_ARRAY:
+ var = &ctx->Array.Index.Enabled;
+ flag = _NEW_ARRAY_INDEX;
+ break;
+ case GL_TEXTURE_COORD_ARRAY:
+ var = &ctx->Array.TexCoord[ctx->Array.ActiveTexture].Enabled;
+ flag = _NEW_ARRAY_TEXCOORD(ctx->Array.ActiveTexture);
+ break;
+ case GL_EDGE_FLAG_ARRAY:
+ var = &ctx->Array.EdgeFlag.Enabled;
+ flag = _NEW_ARRAY_EDGEFLAG;
+ break;
+ case GL_FOG_COORDINATE_ARRAY_EXT:
+ var = &ctx->Array.FogCoord.Enabled;
+ flag = _NEW_ARRAY_FOGCOORD;
+ break;
+ case GL_SECONDARY_COLOR_ARRAY_EXT:
+ var = &ctx->Array.SecondaryColor.Enabled;
+ flag = _NEW_ARRAY_COLOR1;
+ break;
+
+#if FEATURE_NV_vertex_program
+ case GL_VERTEX_ATTRIB_ARRAY0_NV:
+ case GL_VERTEX_ATTRIB_ARRAY1_NV:
+ case GL_VERTEX_ATTRIB_ARRAY2_NV:
+ case GL_VERTEX_ATTRIB_ARRAY3_NV:
+ case GL_VERTEX_ATTRIB_ARRAY4_NV:
+ case GL_VERTEX_ATTRIB_ARRAY5_NV:
+ case GL_VERTEX_ATTRIB_ARRAY6_NV:
+ case GL_VERTEX_ATTRIB_ARRAY7_NV:
+ case GL_VERTEX_ATTRIB_ARRAY8_NV:
+ case GL_VERTEX_ATTRIB_ARRAY9_NV:
+ case GL_VERTEX_ATTRIB_ARRAY10_NV:
+ case GL_VERTEX_ATTRIB_ARRAY11_NV:
+ case GL_VERTEX_ATTRIB_ARRAY12_NV:
+ case GL_VERTEX_ATTRIB_ARRAY13_NV:
+ case GL_VERTEX_ATTRIB_ARRAY14_NV:
+ case GL_VERTEX_ATTRIB_ARRAY15_NV:
+ CHECK_EXTENSION(NV_vertex_program, cap);
+ {
+ GLint n = (GLint) cap - GL_VERTEX_ATTRIB_ARRAY0_NV;
+ var = &ctx->Array.VertexAttrib[n].Enabled;
+ flag = _NEW_ARRAY_ATTRIB(n);
+ }
+ break;
+#endif /* FEATURE_NV_vertex_program */
+
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM,
+ "glEnable/DisableClientState(0x%x)", cap);
+ return;
+ }
+
+ if (*var == state)
+ return;
+
+ FLUSH_VERTICES(ctx, _NEW_ARRAY);
+ ctx->Array.NewState |= flag;
+ *var = state;
+
+ if (state)
+ ctx->Array._Enabled |= flag;
+ else
+ ctx->Array._Enabled &= ~flag;
+
+ if (ctx->Driver.Enable) {
+ (*ctx->Driver.Enable)( ctx, cap, state );
+ }
+}
+
+
+/**
+ * Enable GL capability.
+ *
+ * \param cap capability.
+ *
+ * \sa glEnable().
+ *
+ * Get's the current context, assures that we're outside glBegin()/glEnd() and
+ * calls client_state().
+ */
+void GLAPIENTRY
+_mesa_EnableClientState( GLenum cap )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+ client_state( ctx, cap, GL_TRUE );
+}
+
+
+/**
+ * Disable GL capability.
+ *
+ * \param cap capability.
+ *
+ * \sa glDisable().
+ *
+ * Get's the current context, assures that we're outside glBegin()/glEnd() and
+ * calls client_state().
+ */
+void GLAPIENTRY
+_mesa_DisableClientState( GLenum cap )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+ client_state( ctx, cap, GL_FALSE );
+}
+
+
+#undef CHECK_EXTENSION
+#define CHECK_EXTENSION(EXTNAME, CAP) \
+ if (!ctx->Extensions.EXTNAME) { \
+ _mesa_error(ctx, GL_INVALID_ENUM, "gl%s(0x%x)", \
+ state ? "Enable" : "Disable", CAP); \
+ return; \
+ }
+
+#define CHECK_EXTENSION2(EXT1, EXT2, CAP) \
+ if (!ctx->Extensions.EXT1 && !ctx->Extensions.EXT2) { \
+ _mesa_error(ctx, GL_INVALID_ENUM, "gl%s(0x%x)", \
+ state ? "Enable" : "Disable", CAP); \
+ return; \
+ }
+
+
+
+/**
+ * Perform glEnable() and glDisable() calls.
+ *
+ * \param ctx GL context.
+ * \param cap capability.
+ * \param state whether to enable or disable the specified capability.
+ *
+ * Updates the current context and flushes the vertices as needed. For
+ * capabilities associated with extensions it verifies that those extensions
+ * are effectivly present before updating. Notifies the driver via
+ * dd_function_table::Enable.
+ */
+void _mesa_set_enable( GLcontext *ctx, GLenum cap, GLboolean state )
+{
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx, "%s %s (newstate is %x)\n",
+ state ? "glEnable" : "glDisable",
+ _mesa_lookup_enum_by_nr(cap),
+ ctx->NewState);
+
+ switch (cap) {
+ case GL_ALPHA_TEST:
+ if (ctx->Color.AlphaEnabled == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_COLOR);
+ ctx->Color.AlphaEnabled = state;
+ break;
+ case GL_AUTO_NORMAL:
+ if (ctx->Eval.AutoNormal == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_EVAL);
+ ctx->Eval.AutoNormal = state;
+ break;
+ case GL_BLEND:
+ if (ctx->Color.BlendEnabled == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_COLOR);
+ ctx->Color.BlendEnabled = state;
+ /* This is needed to support 1.1's RGB logic ops AND
+ * 1.0's blending logicops.
+ */
+ ctx->Color._LogicOpEnabled =
+ (ctx->Color.ColorLogicOpEnabled ||
+ (state && ctx->Color.BlendEquationRGB == GL_LOGIC_OP));
+ break;
+#if FEATURE_userclip
+ case GL_CLIP_PLANE0:
+ case GL_CLIP_PLANE1:
+ case GL_CLIP_PLANE2:
+ case GL_CLIP_PLANE3:
+ case GL_CLIP_PLANE4:
+ case GL_CLIP_PLANE5:
+ {
+ const GLuint p = cap - GL_CLIP_PLANE0;
+
+ if ((ctx->Transform.ClipPlanesEnabled & (1 << p)) == ((GLuint) state << p))
+ return;
+
+ FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
+
+ if (state) {
+ ctx->Transform.ClipPlanesEnabled |= (1 << p);
+
+ if (_math_matrix_is_dirty(ctx->ProjectionMatrixStack.Top))
+ _math_matrix_analyse( ctx->ProjectionMatrixStack.Top );
+
+ /* This derived state also calculated in clip.c and
+ * from _mesa_update_state() on changes to EyeUserPlane
+ * and ctx->ProjectionMatrix respectively.
+ */
+ _mesa_transform_vector( ctx->Transform._ClipUserPlane[p],
+ ctx->Transform.EyeUserPlane[p],
+ ctx->ProjectionMatrixStack.Top->inv );
+ }
+ else {
+ ctx->Transform.ClipPlanesEnabled &= ~(1 << p);
+ }
+ }
+ break;
+#endif
+ case GL_COLOR_MATERIAL:
+ if (ctx->Light.ColorMaterialEnabled == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_LIGHT);
+ FLUSH_CURRENT(ctx, 0);
+ ctx->Light.ColorMaterialEnabled = state;
+ if (state) {
+ _mesa_update_color_material( ctx,
+ ctx->Current.Attrib[VERT_ATTRIB_COLOR0] );
+ }
+ break;
+ case GL_CULL_FACE:
+ if (ctx->Polygon.CullFlag == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_POLYGON);
+ ctx->Polygon.CullFlag = state;
+ break;
+
+ case GL_CULL_VERTEX_EXT:
+ CHECK_EXTENSION(EXT_cull_vertex, cap);
+ if (ctx->Transform.CullVertexFlag == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
+ ctx->Transform.CullVertexFlag = state;
+ break;
+
+ case GL_DEPTH_TEST:
+ if (state && ctx->DrawBuffer->Visual.depthBits == 0) {
+ _mesa_warning(ctx,"glEnable(GL_DEPTH_TEST) but no depth buffer");
+ return;
+ }
+ if (ctx->Depth.Test==state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_DEPTH);
+ ctx->Depth.Test = state;
+ break;
+ case GL_DITHER:
+ if (ctx->NoDither) {
+ state = GL_FALSE; /* MESA_NO_DITHER env var */
+ }
+ if (ctx->Color.DitherFlag==state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_COLOR);
+ ctx->Color.DitherFlag = state;
+ break;
+ case GL_FOG:
+ if (ctx->Fog.Enabled==state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_FOG);
+ ctx->Fog.Enabled = state;
+ break;
+ case GL_HISTOGRAM:
+ CHECK_EXTENSION(EXT_histogram, cap);
+ if (ctx->Pixel.HistogramEnabled == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->Pixel.HistogramEnabled = state;
+ break;
+ case GL_LIGHT0:
+ case GL_LIGHT1:
+ case GL_LIGHT2:
+ case GL_LIGHT3:
+ case GL_LIGHT4:
+ case GL_LIGHT5:
+ case GL_LIGHT6:
+ case GL_LIGHT7:
+ if (ctx->Light.Light[cap-GL_LIGHT0].Enabled == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_LIGHT);
+ ctx->Light.Light[cap-GL_LIGHT0].Enabled = state;
+ if (state) {
+ insert_at_tail(&ctx->Light.EnabledList,
+ &ctx->Light.Light[cap-GL_LIGHT0]);
+ }
+ else {
+ remove_from_list(&ctx->Light.Light[cap-GL_LIGHT0]);
+ }
+ break;
+ case GL_LIGHTING:
+ if (ctx->Light.Enabled == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_LIGHT);
+ ctx->Light.Enabled = state;
+
+ if (ctx->Light.Enabled && ctx->Light.Model.TwoSide)
+ ctx->_TriangleCaps |= DD_TRI_LIGHT_TWOSIDE;
+ else
+ ctx->_TriangleCaps &= ~DD_TRI_LIGHT_TWOSIDE;
+
+ break;
+ case GL_LINE_SMOOTH:
+ if (ctx->Line.SmoothFlag == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_LINE);
+ ctx->Line.SmoothFlag = state;
+ ctx->_TriangleCaps ^= DD_LINE_SMOOTH;
+ break;
+ case GL_LINE_STIPPLE:
+ if (ctx->Line.StippleFlag == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_LINE);
+ ctx->Line.StippleFlag = state;
+ ctx->_TriangleCaps ^= DD_LINE_STIPPLE;
+ break;
+ case GL_INDEX_LOGIC_OP:
+ if (ctx->Color.IndexLogicOpEnabled == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_COLOR);
+ ctx->Color.IndexLogicOpEnabled = state;
+ break;
+ case GL_COLOR_LOGIC_OP:
+ if (ctx->Color.ColorLogicOpEnabled == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_COLOR);
+ ctx->Color.ColorLogicOpEnabled = state;
+ /* This is needed to support 1.1's RGB logic ops AND
+ * 1.0's blending logicops.
+ */
+ ctx->Color._LogicOpEnabled =
+ (state || (ctx->Color.BlendEnabled &&
+ ctx->Color.BlendEquationRGB == GL_LOGIC_OP));
+ break;
+ case GL_MAP1_COLOR_4:
+ if (ctx->Eval.Map1Color4 == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_EVAL);
+ ctx->Eval.Map1Color4 = state;
+ break;
+ case GL_MAP1_INDEX:
+ if (ctx->Eval.Map1Index == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_EVAL);
+ ctx->Eval.Map1Index = state;
+ break;
+ case GL_MAP1_NORMAL:
+ if (ctx->Eval.Map1Normal == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_EVAL);
+ ctx->Eval.Map1Normal = state;
+ break;
+ case GL_MAP1_TEXTURE_COORD_1:
+ if (ctx->Eval.Map1TextureCoord1 == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_EVAL);
+ ctx->Eval.Map1TextureCoord1 = state;
+ break;
+ case GL_MAP1_TEXTURE_COORD_2:
+ if (ctx->Eval.Map1TextureCoord2 == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_EVAL);
+ ctx->Eval.Map1TextureCoord2 = state;
+ break;
+ case GL_MAP1_TEXTURE_COORD_3:
+ if (ctx->Eval.Map1TextureCoord3 == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_EVAL);
+ ctx->Eval.Map1TextureCoord3 = state;
+ break;
+ case GL_MAP1_TEXTURE_COORD_4:
+ if (ctx->Eval.Map1TextureCoord4 == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_EVAL);
+ ctx->Eval.Map1TextureCoord4 = state;
+ break;
+ case GL_MAP1_VERTEX_3:
+ if (ctx->Eval.Map1Vertex3 == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_EVAL);
+ ctx->Eval.Map1Vertex3 = state;
+ break;
+ case GL_MAP1_VERTEX_4:
+ if (ctx->Eval.Map1Vertex4 == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_EVAL);
+ ctx->Eval.Map1Vertex4 = state;
+ break;
+ case GL_MAP2_COLOR_4:
+ if (ctx->Eval.Map2Color4 == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_EVAL);
+ ctx->Eval.Map2Color4 = state;
+ break;
+ case GL_MAP2_INDEX:
+ if (ctx->Eval.Map2Index == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_EVAL);
+ ctx->Eval.Map2Index = state;
+ break;
+ case GL_MAP2_NORMAL:
+ if (ctx->Eval.Map2Normal == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_EVAL);
+ ctx->Eval.Map2Normal = state;
+ break;
+ case GL_MAP2_TEXTURE_COORD_1:
+ if (ctx->Eval.Map2TextureCoord1 == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_EVAL);
+ ctx->Eval.Map2TextureCoord1 = state;
+ break;
+ case GL_MAP2_TEXTURE_COORD_2:
+ if (ctx->Eval.Map2TextureCoord2 == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_EVAL);
+ ctx->Eval.Map2TextureCoord2 = state;
+ break;
+ case GL_MAP2_TEXTURE_COORD_3:
+ if (ctx->Eval.Map2TextureCoord3 == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_EVAL);
+ ctx->Eval.Map2TextureCoord3 = state;
+ break;
+ case GL_MAP2_TEXTURE_COORD_4:
+ if (ctx->Eval.Map2TextureCoord4 == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_EVAL);
+ ctx->Eval.Map2TextureCoord4 = state;
+ break;
+ case GL_MAP2_VERTEX_3:
+ if (ctx->Eval.Map2Vertex3 == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_EVAL);
+ ctx->Eval.Map2Vertex3 = state;
+ break;
+ case GL_MAP2_VERTEX_4:
+ if (ctx->Eval.Map2Vertex4 == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_EVAL);
+ ctx->Eval.Map2Vertex4 = state;
+ break;
+ case GL_MINMAX:
+ if (ctx->Pixel.MinMaxEnabled == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->Pixel.MinMaxEnabled = state;
+ break;
+ case GL_NORMALIZE:
+ if (ctx->Transform.Normalize == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
+ ctx->Transform.Normalize = state;
+ break;
+ case GL_POINT_SMOOTH:
+ if (ctx->Point.SmoothFlag==state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_POINT);
+ ctx->Point.SmoothFlag = state;
+ ctx->_TriangleCaps ^= DD_POINT_SMOOTH;
+ break;
+ case GL_POLYGON_SMOOTH:
+ if (ctx->Polygon.SmoothFlag==state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_POLYGON);
+ ctx->Polygon.SmoothFlag = state;
+ ctx->_TriangleCaps ^= DD_TRI_SMOOTH;
+ break;
+ case GL_POLYGON_STIPPLE:
+ if (ctx->Polygon.StippleFlag==state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_POLYGON);
+ ctx->Polygon.StippleFlag = state;
+ ctx->_TriangleCaps ^= DD_TRI_STIPPLE;
+ break;
+ case GL_POLYGON_OFFSET_POINT:
+ if (ctx->Polygon.OffsetPoint==state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_POLYGON);
+ ctx->Polygon.OffsetPoint = state;
+ break;
+ case GL_POLYGON_OFFSET_LINE:
+ if (ctx->Polygon.OffsetLine==state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_POLYGON);
+ ctx->Polygon.OffsetLine = state;
+ break;
+ case GL_POLYGON_OFFSET_FILL:
+ /*case GL_POLYGON_OFFSET_EXT:*/
+ if (ctx->Polygon.OffsetFill==state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_POLYGON);
+ ctx->Polygon.OffsetFill = state;
+ break;
+ case GL_RESCALE_NORMAL_EXT:
+ if (ctx->Transform.RescaleNormals == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
+ ctx->Transform.RescaleNormals = state;
+ break;
+ case GL_SCISSOR_TEST:
+ if (ctx->Scissor.Enabled==state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_SCISSOR);
+ ctx->Scissor.Enabled = state;
+ break;
+ case GL_SHARED_TEXTURE_PALETTE_EXT:
+ if (ctx->Texture.SharedPalette == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ ctx->Texture.SharedPalette = state;
+ break;
+ case GL_STENCIL_TEST:
+ if (state && ctx->DrawBuffer->Visual.stencilBits == 0) {
+ _mesa_warning(ctx,
+ "glEnable(GL_STENCIL_TEST) but no stencil buffer");
+ return;
+ }
+ if (ctx->Stencil.Enabled==state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_STENCIL);
+ ctx->Stencil.Enabled = state;
+ break;
+ case GL_TEXTURE_1D: {
+ const GLuint curr = ctx->Texture.CurrentUnit;
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[curr];
+ GLuint newenabled = texUnit->Enabled & ~TEXTURE_1D_BIT;
+ if (state)
+ newenabled |= TEXTURE_1D_BIT;
+ if (!ctx->DrawBuffer->Visual.rgbMode
+ || texUnit->Enabled == newenabled)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texUnit->Enabled = newenabled;
+ break;
+ }
+ case GL_TEXTURE_2D: {
+ const GLuint curr = ctx->Texture.CurrentUnit;
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[curr];
+ GLuint newenabled = texUnit->Enabled & ~TEXTURE_2D_BIT;
+ if (state)
+ newenabled |= TEXTURE_2D_BIT;
+ if (!ctx->DrawBuffer->Visual.rgbMode
+ || texUnit->Enabled == newenabled)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texUnit->Enabled = newenabled;
+ break;
+ }
+ case GL_TEXTURE_3D: {
+ const GLuint curr = ctx->Texture.CurrentUnit;
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[curr];
+ GLuint newenabled = texUnit->Enabled & ~TEXTURE_3D_BIT;
+ if (state)
+ newenabled |= TEXTURE_3D_BIT;
+ if (!ctx->DrawBuffer->Visual.rgbMode
+ || texUnit->Enabled == newenabled)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texUnit->Enabled = newenabled;
+ break;
+ }
+ case GL_TEXTURE_GEN_Q: {
+ GLuint unit = ctx->Texture.CurrentUnit;
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+ GLuint newenabled = texUnit->TexGenEnabled & ~Q_BIT;
+ if (state)
+ newenabled |= Q_BIT;
+ if (texUnit->TexGenEnabled == newenabled)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texUnit->TexGenEnabled = newenabled;
+ break;
+ }
+ case GL_TEXTURE_GEN_R: {
+ GLuint unit = ctx->Texture.CurrentUnit;
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+ GLuint newenabled = texUnit->TexGenEnabled & ~R_BIT;
+ if (state)
+ newenabled |= R_BIT;
+ if (texUnit->TexGenEnabled == newenabled)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texUnit->TexGenEnabled = newenabled;
+ break;
+ }
+ case GL_TEXTURE_GEN_S: {
+ GLuint unit = ctx->Texture.CurrentUnit;
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+ GLuint newenabled = texUnit->TexGenEnabled & ~S_BIT;
+ if (state)
+ newenabled |= S_BIT;
+ if (texUnit->TexGenEnabled == newenabled)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texUnit->TexGenEnabled = newenabled;
+ break;
+ }
+ case GL_TEXTURE_GEN_T: {
+ GLuint unit = ctx->Texture.CurrentUnit;
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+ GLuint newenabled = texUnit->TexGenEnabled & ~T_BIT;
+ if (state)
+ newenabled |= T_BIT;
+ if (texUnit->TexGenEnabled == newenabled)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texUnit->TexGenEnabled = newenabled;
+ break;
+ }
+
+ /*
+ * CLIENT STATE!!!
+ */
+ case GL_VERTEX_ARRAY:
+ case GL_NORMAL_ARRAY:
+ case GL_COLOR_ARRAY:
+ case GL_INDEX_ARRAY:
+ case GL_TEXTURE_COORD_ARRAY:
+ case GL_EDGE_FLAG_ARRAY:
+ case GL_FOG_COORDINATE_ARRAY_EXT:
+ case GL_SECONDARY_COLOR_ARRAY_EXT:
+ client_state( ctx, cap, state );
+ return;
+
+ /* GL_SGI_color_table */
+ case GL_COLOR_TABLE_SGI:
+ CHECK_EXTENSION(SGI_color_table, cap);
+ if (ctx->Pixel.ColorTableEnabled == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->Pixel.ColorTableEnabled = state;
+ break;
+ case GL_POST_CONVOLUTION_COLOR_TABLE_SGI:
+ CHECK_EXTENSION(SGI_color_table, cap);
+ if (ctx->Pixel.PostConvolutionColorTableEnabled == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->Pixel.PostConvolutionColorTableEnabled = state;
+ break;
+ case GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI:
+ CHECK_EXTENSION(SGI_color_table, cap);
+ if (ctx->Pixel.PostColorMatrixColorTableEnabled == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->Pixel.PostColorMatrixColorTableEnabled = state;
+ break;
+ case GL_TEXTURE_COLOR_TABLE_SGI:
+ CHECK_EXTENSION(SGI_texture_color_table, cap);
+ if (ctx->Texture.Unit[ctx->Texture.CurrentUnit].ColorTableEnabled == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ ctx->Texture.Unit[ctx->Texture.CurrentUnit].ColorTableEnabled = state;
+ break;
+
+ /* GL_EXT_convolution */
+ case GL_CONVOLUTION_1D:
+ CHECK_EXTENSION(EXT_convolution, cap);
+ if (ctx->Pixel.Convolution1DEnabled == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->Pixel.Convolution1DEnabled = state;
+ break;
+ case GL_CONVOLUTION_2D:
+ CHECK_EXTENSION(EXT_convolution, cap);
+ if (ctx->Pixel.Convolution2DEnabled == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->Pixel.Convolution2DEnabled = state;
+ break;
+ case GL_SEPARABLE_2D:
+ CHECK_EXTENSION(EXT_convolution, cap);
+ if (ctx->Pixel.Separable2DEnabled == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->Pixel.Separable2DEnabled = state;
+ break;
+
+ /* GL_ARB_texture_cube_map */
+ case GL_TEXTURE_CUBE_MAP_ARB:
+ {
+ const GLuint curr = ctx->Texture.CurrentUnit;
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[curr];
+ GLuint newenabled = texUnit->Enabled & ~TEXTURE_CUBE_BIT;
+ CHECK_EXTENSION(ARB_texture_cube_map, cap);
+ if (state)
+ newenabled |= TEXTURE_CUBE_BIT;
+ if (!ctx->DrawBuffer->Visual.rgbMode
+ || texUnit->Enabled == newenabled)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texUnit->Enabled = newenabled;
+ }
+ break;
+
+ /* GL_EXT_secondary_color */
+ case GL_COLOR_SUM_EXT:
+ CHECK_EXTENSION2(EXT_secondary_color, ARB_vertex_program, cap);
+ if (ctx->Fog.ColorSumEnabled == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_FOG);
+ ctx->Fog.ColorSumEnabled = state;
+ break;
+
+ /* GL_ARB_multisample */
+ case GL_MULTISAMPLE_ARB:
+ CHECK_EXTENSION(ARB_multisample, cap);
+ if (ctx->Multisample.Enabled == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE);
+ ctx->Multisample.Enabled = state;
+ break;
+ case GL_SAMPLE_ALPHA_TO_COVERAGE_ARB:
+ CHECK_EXTENSION(ARB_multisample, cap);
+ if (ctx->Multisample.SampleAlphaToCoverage == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE);
+ ctx->Multisample.SampleAlphaToCoverage = state;
+ break;
+ case GL_SAMPLE_ALPHA_TO_ONE_ARB:
+ CHECK_EXTENSION(ARB_multisample, cap);
+ if (ctx->Multisample.SampleAlphaToOne == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE);
+ ctx->Multisample.SampleAlphaToOne = state;
+ break;
+ case GL_SAMPLE_COVERAGE_ARB:
+ CHECK_EXTENSION(ARB_multisample, cap);
+ if (ctx->Multisample.SampleCoverage == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE);
+ ctx->Multisample.SampleCoverage = state;
+ break;
+ case GL_SAMPLE_COVERAGE_INVERT_ARB:
+ CHECK_EXTENSION(ARB_multisample, cap);
+ if (ctx->Multisample.SampleCoverageInvert == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE);
+ ctx->Multisample.SampleCoverageInvert = state;
+ break;
+
+ /* GL_IBM_rasterpos_clip */
+ case GL_RASTER_POSITION_UNCLIPPED_IBM:
+ CHECK_EXTENSION(IBM_rasterpos_clip, cap);
+ if (ctx->Transform.RasterPositionUnclipped == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
+ ctx->Transform.RasterPositionUnclipped = state;
+ break;
+
+ /* GL_NV_point_sprite */
+ case GL_POINT_SPRITE_NV:
+ CHECK_EXTENSION2(NV_point_sprite, ARB_point_sprite, cap);
+ if (ctx->Point.PointSprite == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_POINT);
+ ctx->Point.PointSprite = state;
+ break;
+
+#if FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program
+ case GL_VERTEX_PROGRAM_ARB:
+ CHECK_EXTENSION2(ARB_vertex_program, NV_vertex_program, cap);
+ if (ctx->VertexProgram.Enabled == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PROGRAM);
+ ctx->VertexProgram.Enabled = state;
+ break;
+ case GL_VERTEX_PROGRAM_POINT_SIZE_ARB:
+ CHECK_EXTENSION2(ARB_vertex_program, NV_vertex_program, cap);
+ if (ctx->VertexProgram.PointSizeEnabled == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PROGRAM);
+ ctx->VertexProgram.PointSizeEnabled = state;
+ break;
+ case GL_VERTEX_PROGRAM_TWO_SIDE_ARB:
+ CHECK_EXTENSION2(ARB_vertex_program, NV_vertex_program, cap);
+ if (ctx->VertexProgram.TwoSideEnabled == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PROGRAM);
+ ctx->VertexProgram.TwoSideEnabled = state;
+ break;
+#endif
+#if FEATURE_NV_vertex_program
+ case GL_MAP1_VERTEX_ATTRIB0_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB1_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB2_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB3_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB4_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB5_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB6_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB7_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB8_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB9_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB10_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB11_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB12_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB13_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB14_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB15_4_NV:
+ CHECK_EXTENSION(NV_vertex_program, cap);
+ {
+ const GLuint map = (GLuint) (cap - GL_MAP1_VERTEX_ATTRIB0_4_NV);
+ FLUSH_VERTICES(ctx, _NEW_EVAL);
+ ctx->Eval.Map1Attrib[map] = state;
+ }
+ break;
+ case GL_MAP2_VERTEX_ATTRIB0_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB1_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB2_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB3_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB4_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB5_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB6_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB7_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB8_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB9_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB10_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB11_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB12_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB13_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB14_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB15_4_NV:
+ CHECK_EXTENSION(NV_vertex_program, cap);
+ {
+ const GLuint map = (GLuint) (cap - GL_MAP2_VERTEX_ATTRIB0_4_NV);
+ FLUSH_VERTICES(ctx, _NEW_EVAL);
+ ctx->Eval.Map2Attrib[map] = state;
+ }
+ break;
+#endif /* FEATURE_NV_vertex_program */
+
+#if FEATURE_NV_fragment_program
+ case GL_FRAGMENT_PROGRAM_NV:
+ CHECK_EXTENSION(NV_fragment_program, cap);
+ if (ctx->FragmentProgram.Enabled == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PROGRAM);
+ ctx->FragmentProgram.Enabled = state;
+ break;
+#endif /* FEATURE_NV_fragment_program */
+
+ /* GL_NV_texture_rectangle */
+ case GL_TEXTURE_RECTANGLE_NV:
+ CHECK_EXTENSION(NV_texture_rectangle, cap);
+ {
+ const GLuint curr = ctx->Texture.CurrentUnit;
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[curr];
+ GLuint newenabled = texUnit->Enabled & ~TEXTURE_RECT_BIT;
+ CHECK_EXTENSION(NV_texture_rectangle, cap);
+ if (state)
+ newenabled |= TEXTURE_RECT_BIT;
+ if (!ctx->DrawBuffer->Visual.rgbMode
+ || texUnit->Enabled == newenabled)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texUnit->Enabled = newenabled;
+ }
+ break;
+
+ /* GL_EXT_stencil_two_side */
+ case GL_STENCIL_TEST_TWO_SIDE_EXT:
+ CHECK_EXTENSION(EXT_stencil_two_side, cap);
+ if (ctx->Stencil.TestTwoSide == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_STENCIL);
+ ctx->Stencil.TestTwoSide = state;
+ if (state) {
+ ctx->_TriangleCaps |= DD_TRI_TWOSTENCIL;
+ } else {
+ ctx->_TriangleCaps &= ~DD_TRI_TWOSTENCIL;
+ }
+ break;
+
+#if FEATURE_ARB_fragment_program
+ case GL_FRAGMENT_PROGRAM_ARB:
+ CHECK_EXTENSION(ARB_fragment_program, cap);
+ if (ctx->FragmentProgram.Enabled == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PROGRAM);
+ ctx->FragmentProgram.Enabled = state;
+ break;
+#endif /* FEATURE_ARB_fragment_program */
+
+ /* GL_EXT_depth_bounds_test */
+ case GL_DEPTH_BOUNDS_TEST_EXT:
+ CHECK_EXTENSION(EXT_depth_bounds_test, cap);
+ if (state && ctx->DrawBuffer->Visual.depthBits == 0) {
+ _mesa_warning(ctx,
+ "glEnable(GL_DEPTH_BOUNDS_TEST_EXT) but no depth buffer");
+ return;
+ }
+ if (ctx->Depth.BoundsTest == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_DEPTH);
+ ctx->Depth.BoundsTest = state;
+ break;
+
+ /* GL_MESA_program_debug */
+ case GL_FRAGMENT_PROGRAM_CALLBACK_MESA:
+ CHECK_EXTENSION(MESA_program_debug, cap);
+ ctx->FragmentProgram.CallbackEnabled = state;
+ break;
+ case GL_VERTEX_PROGRAM_CALLBACK_MESA:
+ CHECK_EXTENSION(MESA_program_debug, cap);
+ ctx->VertexProgram.CallbackEnabled = state;
+ break;
+
+#if FEATURE_ATI_fragment_shader
+ case GL_FRAGMENT_SHADER_ATI:
+ CHECK_EXTENSION(ATI_fragment_shader, cap);
+ if (ctx->ATIFragmentShader.Enabled == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PROGRAM);
+ ctx->ATIFragmentShader.Enabled = state;
+ break;
+#endif
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "%s(0x%x)", state ? "glEnable" : "glDisable", cap);
+ return;
+ }
+
+ if (ctx->Driver.Enable) {
+ (*ctx->Driver.Enable)( ctx, cap, state );
+ }
+}
+
+
+/**
+ * Enable GL capability.
+ *
+ * \param cap capability.
+ *
+ * \sa glEnable().
+ *
+ * Get's the current context, assures that we're outside glBegin()/glEnd() and
+ * calls _mesa_set_enable().
+ */
+void GLAPIENTRY
+_mesa_Enable( GLenum cap )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ _mesa_set_enable( ctx, cap, GL_TRUE );
+}
+
+
+/**
+ * Disable GL capability.
+ *
+ * \param cap capability.
+ *
+ * \sa glDisable().
+ *
+ * Get's the current context, assures that we're outside glBegin()/glEnd() and
+ * calls _mesa_set_enable().
+ */
+void GLAPIENTRY
+_mesa_Disable( GLenum cap )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ _mesa_set_enable( ctx, cap, GL_FALSE );
+}
+
+
+#undef CHECK_EXTENSION
+#define CHECK_EXTENSION(EXTNAME) \
+ if (!ctx->Extensions.EXTNAME) { \
+ _mesa_error(ctx, GL_INVALID_ENUM, "glIsEnabled"); \
+ return GL_FALSE; \
+ }
+
+#undef CHECK_EXTENSION2
+#define CHECK_EXTENSION2(EXT1, EXT2) \
+ if (!ctx->Extensions.EXT1 && !ctx->Extensions.EXT2) { \
+ _mesa_error(ctx, GL_INVALID_ENUM, "glIsEnabled"); \
+ return GL_FALSE; \
+ }
+
+/**
+ * Test whether a capability is enabled.
+ *
+ * \param cap capability.
+ *
+ * Returns the state of the specified capability from the current GL context.
+ * For the capabilities associated with extensions verifies that those
+ * extensions are effectively present before reporting.
+ */
+GLboolean GLAPIENTRY
+_mesa_IsEnabled( GLenum cap )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ switch (cap) {
+ case GL_ALPHA_TEST:
+ return ctx->Color.AlphaEnabled;
+ case GL_AUTO_NORMAL:
+ return ctx->Eval.AutoNormal;
+ case GL_BLEND:
+ return ctx->Color.BlendEnabled;
+ 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_COLOR_MATERIAL:
+ return ctx->Light.ColorMaterialEnabled;
+ case GL_CULL_FACE:
+ return ctx->Polygon.CullFlag;
+ case GL_DEPTH_TEST:
+ return ctx->Depth.Test;
+ case GL_DITHER:
+ return ctx->Color.DitherFlag;
+ case GL_FOG:
+ return ctx->Fog.Enabled;
+ case GL_LIGHTING:
+ return ctx->Light.Enabled;
+ case GL_LIGHT0:
+ case GL_LIGHT1:
+ case GL_LIGHT2:
+ case GL_LIGHT3:
+ case GL_LIGHT4:
+ case GL_LIGHT5:
+ case GL_LIGHT6:
+ case GL_LIGHT7:
+ return ctx->Light.Light[cap-GL_LIGHT0].Enabled;
+ case GL_LINE_SMOOTH:
+ return ctx->Line.SmoothFlag;
+ case GL_LINE_STIPPLE:
+ return ctx->Line.StippleFlag;
+ case GL_INDEX_LOGIC_OP:
+ return ctx->Color.IndexLogicOpEnabled;
+ case GL_COLOR_LOGIC_OP:
+ return ctx->Color.ColorLogicOpEnabled;
+ case GL_MAP1_COLOR_4:
+ return ctx->Eval.Map1Color4;
+ case GL_MAP1_INDEX:
+ return ctx->Eval.Map1Index;
+ case GL_MAP1_NORMAL:
+ return ctx->Eval.Map1Normal;
+ case GL_MAP1_TEXTURE_COORD_1:
+ return ctx->Eval.Map1TextureCoord1;
+ case GL_MAP1_TEXTURE_COORD_2:
+ return ctx->Eval.Map1TextureCoord2;
+ case GL_MAP1_TEXTURE_COORD_3:
+ return ctx->Eval.Map1TextureCoord3;
+ case GL_MAP1_TEXTURE_COORD_4:
+ return ctx->Eval.Map1TextureCoord4;
+ case GL_MAP1_VERTEX_3:
+ return ctx->Eval.Map1Vertex3;
+ case GL_MAP1_VERTEX_4:
+ return ctx->Eval.Map1Vertex4;
+ case GL_MAP2_COLOR_4:
+ return ctx->Eval.Map2Color4;
+ case GL_MAP2_INDEX:
+ return ctx->Eval.Map2Index;
+ case GL_MAP2_NORMAL:
+ return ctx->Eval.Map2Normal;
+ case GL_MAP2_TEXTURE_COORD_1:
+ return ctx->Eval.Map2TextureCoord1;
+ case GL_MAP2_TEXTURE_COORD_2:
+ return ctx->Eval.Map2TextureCoord2;
+ case GL_MAP2_TEXTURE_COORD_3:
+ return ctx->Eval.Map2TextureCoord3;
+ case GL_MAP2_TEXTURE_COORD_4:
+ return ctx->Eval.Map2TextureCoord4;
+ case GL_MAP2_VERTEX_3:
+ return ctx->Eval.Map2Vertex3;
+ case GL_MAP2_VERTEX_4:
+ return ctx->Eval.Map2Vertex4;
+ case GL_NORMALIZE:
+ return ctx->Transform.Normalize;
+ case GL_POINT_SMOOTH:
+ return ctx->Point.SmoothFlag;
+ case GL_POLYGON_SMOOTH:
+ return ctx->Polygon.SmoothFlag;
+ case GL_POLYGON_STIPPLE:
+ return ctx->Polygon.StippleFlag;
+ case GL_POLYGON_OFFSET_POINT:
+ return ctx->Polygon.OffsetPoint;
+ case GL_POLYGON_OFFSET_LINE:
+ return ctx->Polygon.OffsetLine;
+ case GL_POLYGON_OFFSET_FILL:
+ /*case GL_POLYGON_OFFSET_EXT:*/
+ return ctx->Polygon.OffsetFill;
+ case GL_RESCALE_NORMAL_EXT:
+ return ctx->Transform.RescaleNormals;
+ case GL_SCISSOR_TEST:
+ return ctx->Scissor.Enabled;
+ case GL_SHARED_TEXTURE_PALETTE_EXT:
+ return ctx->Texture.SharedPalette;
+ case GL_STENCIL_TEST:
+ return ctx->Stencil.Enabled;
+ case GL_TEXTURE_1D:
+ {
+ const struct gl_texture_unit *texUnit;
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ return (texUnit->Enabled & TEXTURE_1D_BIT) ? GL_TRUE : GL_FALSE;
+ }
+ case GL_TEXTURE_2D:
+ {
+ const struct gl_texture_unit *texUnit;
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ return (texUnit->Enabled & TEXTURE_2D_BIT) ? GL_TRUE : GL_FALSE;
+ }
+ case GL_TEXTURE_3D:
+ {
+ const struct gl_texture_unit *texUnit;
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ return (texUnit->Enabled & TEXTURE_3D_BIT) ? GL_TRUE : GL_FALSE;
+ }
+ case GL_TEXTURE_GEN_Q:
+ {
+ const struct gl_texture_unit *texUnit;
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ return (texUnit->TexGenEnabled & Q_BIT) ? GL_TRUE : GL_FALSE;
+ }
+ case GL_TEXTURE_GEN_R:
+ {
+ const struct gl_texture_unit *texUnit;
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ return (texUnit->TexGenEnabled & R_BIT) ? GL_TRUE : GL_FALSE;
+ }
+ case GL_TEXTURE_GEN_S:
+ {
+ const struct gl_texture_unit *texUnit;
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ return (texUnit->TexGenEnabled & S_BIT) ? GL_TRUE : GL_FALSE;
+ }
+ case GL_TEXTURE_GEN_T:
+ {
+ const struct gl_texture_unit *texUnit;
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ return (texUnit->TexGenEnabled & T_BIT) ? GL_TRUE : GL_FALSE;
+ }
+
+ /*
+ * CLIENT STATE!!!
+ */
+ case GL_VERTEX_ARRAY:
+ return (ctx->Array.Vertex.Enabled != 0);
+ case GL_NORMAL_ARRAY:
+ return (ctx->Array.Normal.Enabled != 0);
+ case GL_COLOR_ARRAY:
+ return (ctx->Array.Color.Enabled != 0);
+ case GL_INDEX_ARRAY:
+ return (ctx->Array.Index.Enabled != 0);
+ case GL_TEXTURE_COORD_ARRAY:
+ return (ctx->Array.TexCoord[ctx->Array.ActiveTexture].Enabled != 0);
+ case GL_EDGE_FLAG_ARRAY:
+ return (ctx->Array.EdgeFlag.Enabled != 0);
+ case GL_FOG_COORDINATE_ARRAY_EXT:
+ CHECK_EXTENSION(EXT_fog_coord);
+ return (ctx->Array.FogCoord.Enabled != 0);
+ case GL_SECONDARY_COLOR_ARRAY_EXT:
+ CHECK_EXTENSION(EXT_secondary_color);
+ return (ctx->Array.SecondaryColor.Enabled != 0);
+
+ /* GL_EXT_histogram */
+ case GL_HISTOGRAM:
+ CHECK_EXTENSION(EXT_histogram);
+ return ctx->Pixel.HistogramEnabled;
+ case GL_MINMAX:
+ CHECK_EXTENSION(EXT_histogram);
+ return ctx->Pixel.MinMaxEnabled;
+
+ /* GL_SGI_color_table */
+ case GL_COLOR_TABLE_SGI:
+ CHECK_EXTENSION(SGI_color_table);
+ return ctx->Pixel.ColorTableEnabled;
+ case GL_POST_CONVOLUTION_COLOR_TABLE_SGI:
+ CHECK_EXTENSION(SGI_color_table);
+ return ctx->Pixel.PostConvolutionColorTableEnabled;
+ case GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI:
+ CHECK_EXTENSION(SGI_color_table);
+ return ctx->Pixel.PostColorMatrixColorTableEnabled;
+
+ /* GL_SGI_texture_color_table */
+ case GL_TEXTURE_COLOR_TABLE_SGI:
+ CHECK_EXTENSION(SGI_texture_color_table);
+ return ctx->Texture.Unit[ctx->Texture.CurrentUnit].ColorTableEnabled;
+
+ /* GL_EXT_convolution */
+ case GL_CONVOLUTION_1D:
+ CHECK_EXTENSION(EXT_convolution);
+ return ctx->Pixel.Convolution1DEnabled;
+ case GL_CONVOLUTION_2D:
+ CHECK_EXTENSION(EXT_convolution);
+ return ctx->Pixel.Convolution2DEnabled;
+ case GL_SEPARABLE_2D:
+ CHECK_EXTENSION(EXT_convolution);
+ return ctx->Pixel.Separable2DEnabled;
+
+ /* GL_ARB_texture_cube_map */
+ case GL_TEXTURE_CUBE_MAP_ARB:
+ CHECK_EXTENSION(ARB_texture_cube_map);
+ {
+ const struct gl_texture_unit *texUnit;
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ return (texUnit->Enabled & TEXTURE_CUBE_BIT) ? GL_TRUE : GL_FALSE;
+ }
+
+ /* GL_EXT_secondary_color */
+ case GL_COLOR_SUM_EXT:
+ CHECK_EXTENSION2(EXT_secondary_color, ARB_vertex_program);
+ return ctx->Fog.ColorSumEnabled;
+
+ /* GL_ARB_multisample */
+ case GL_MULTISAMPLE_ARB:
+ CHECK_EXTENSION(ARB_multisample);
+ return ctx->Multisample.Enabled;
+ case GL_SAMPLE_ALPHA_TO_COVERAGE_ARB:
+ CHECK_EXTENSION(ARB_multisample);
+ return ctx->Multisample.SampleAlphaToCoverage;
+ case GL_SAMPLE_ALPHA_TO_ONE_ARB:
+ CHECK_EXTENSION(ARB_multisample);
+ return ctx->Multisample.SampleAlphaToOne;
+ case GL_SAMPLE_COVERAGE_ARB:
+ CHECK_EXTENSION(ARB_multisample);
+ return ctx->Multisample.SampleCoverage;
+ case GL_SAMPLE_COVERAGE_INVERT_ARB:
+ CHECK_EXTENSION(ARB_multisample);
+ return ctx->Multisample.SampleCoverageInvert;
+
+ /* GL_IBM_rasterpos_clip */
+ case GL_RASTER_POSITION_UNCLIPPED_IBM:
+ CHECK_EXTENSION(IBM_rasterpos_clip);
+ return ctx->Transform.RasterPositionUnclipped;
+
+ /* GL_NV_point_sprite */
+ case GL_POINT_SPRITE_NV:
+ CHECK_EXTENSION2(NV_point_sprite, ARB_point_sprite)
+ return ctx->Point.PointSprite;
+
+#if FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program
+ case GL_VERTEX_PROGRAM_ARB:
+ CHECK_EXTENSION2(ARB_vertex_program, NV_vertex_program);
+ return ctx->VertexProgram.Enabled;
+ case GL_VERTEX_PROGRAM_POINT_SIZE_ARB:
+ CHECK_EXTENSION2(ARB_vertex_program, NV_vertex_program);
+ return ctx->VertexProgram.PointSizeEnabled;
+ case GL_VERTEX_PROGRAM_TWO_SIDE_ARB:
+ CHECK_EXTENSION2(ARB_vertex_program, NV_vertex_program);
+ return ctx->VertexProgram.TwoSideEnabled;
+#endif
+#if FEATURE_NV_vertex_program
+ case GL_VERTEX_ATTRIB_ARRAY0_NV:
+ case GL_VERTEX_ATTRIB_ARRAY1_NV:
+ case GL_VERTEX_ATTRIB_ARRAY2_NV:
+ case GL_VERTEX_ATTRIB_ARRAY3_NV:
+ case GL_VERTEX_ATTRIB_ARRAY4_NV:
+ case GL_VERTEX_ATTRIB_ARRAY5_NV:
+ case GL_VERTEX_ATTRIB_ARRAY6_NV:
+ case GL_VERTEX_ATTRIB_ARRAY7_NV:
+ case GL_VERTEX_ATTRIB_ARRAY8_NV:
+ case GL_VERTEX_ATTRIB_ARRAY9_NV:
+ case GL_VERTEX_ATTRIB_ARRAY10_NV:
+ case GL_VERTEX_ATTRIB_ARRAY11_NV:
+ case GL_VERTEX_ATTRIB_ARRAY12_NV:
+ case GL_VERTEX_ATTRIB_ARRAY13_NV:
+ case GL_VERTEX_ATTRIB_ARRAY14_NV:
+ case GL_VERTEX_ATTRIB_ARRAY15_NV:
+ CHECK_EXTENSION(NV_vertex_program);
+ {
+ GLint n = (GLint) cap - GL_VERTEX_ATTRIB_ARRAY0_NV;
+ return (ctx->Array.VertexAttrib[n].Enabled != 0);
+ }
+ case GL_MAP1_VERTEX_ATTRIB0_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB1_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB2_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB3_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB4_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB5_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB6_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB7_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB8_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB9_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB10_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB11_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB12_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB13_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB14_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB15_4_NV:
+ CHECK_EXTENSION(NV_vertex_program);
+ {
+ const GLuint map = (GLuint) (cap - GL_MAP1_VERTEX_ATTRIB0_4_NV);
+ return ctx->Eval.Map1Attrib[map];
+ }
+ case GL_MAP2_VERTEX_ATTRIB0_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB1_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB2_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB3_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB4_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB5_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB6_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB7_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB8_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB9_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB10_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB11_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB12_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB13_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB14_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB15_4_NV:
+ CHECK_EXTENSION(NV_vertex_program);
+ {
+ const GLuint map = (GLuint) (cap - GL_MAP2_VERTEX_ATTRIB0_4_NV);
+ return ctx->Eval.Map2Attrib[map];
+ }
+#endif /* FEATURE_NV_vertex_program */
+
+#if FEATURE_NV_fragment_program
+ case GL_FRAGMENT_PROGRAM_NV:
+ CHECK_EXTENSION(NV_fragment_program);
+ return ctx->FragmentProgram.Enabled;
+#endif /* FEATURE_NV_fragment_program */
+
+ /* GL_NV_texture_rectangle */
+ case GL_TEXTURE_RECTANGLE_NV:
+ CHECK_EXTENSION(NV_texture_rectangle);
+ {
+ const struct gl_texture_unit *texUnit;
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ return (texUnit->Enabled & TEXTURE_RECT_BIT) ? GL_TRUE : GL_FALSE;
+ }
+
+ /* GL_EXT_stencil_two_side */
+ case GL_STENCIL_TEST_TWO_SIDE_EXT:
+ CHECK_EXTENSION(EXT_stencil_two_side);
+ return ctx->Stencil.TestTwoSide;
+
+#if FEATURE_ARB_fragment_program
+ case GL_FRAGMENT_PROGRAM_ARB:
+ return ctx->FragmentProgram.Enabled;
+#endif /* FEATURE_ARB_fragment_program */
+
+ /* GL_EXT_depth_bounds_test */
+ case GL_DEPTH_BOUNDS_TEST_EXT:
+ CHECK_EXTENSION(EXT_depth_bounds_test);
+ return ctx->Depth.BoundsTest;
+
+ /* GL_MESA_program_debug */
+ case GL_FRAGMENT_PROGRAM_CALLBACK_MESA:
+ CHECK_EXTENSION(MESA_program_debug);
+ return ctx->FragmentProgram.CallbackEnabled;
+ case GL_VERTEX_PROGRAM_CALLBACK_MESA:
+ CHECK_EXTENSION(MESA_program_debug);
+ return ctx->VertexProgram.CallbackEnabled;
+#if FEATURE_ATI_fragment_shader
+ case GL_FRAGMENT_SHADER_ATI:
+ CHECK_EXTENSION(ATI_fragment_shader);
+ return ctx->ATIFragmentShader.Enabled;
+#endif /* FEATURE_ATI_fragment_shader */
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glIsEnabled(0x%x)", (int) cap);
+ return GL_FALSE;
+ }
+}
diff --git a/src/mesa/main/enable.h b/src/mesa/main/enable.h
new file mode 100644
index 00000000000..25c90b0275a
--- /dev/null
+++ b/src/mesa/main/enable.h
@@ -0,0 +1,57 @@
+/**
+ * \file enable.h
+ * Enable/disable/query GL capabilities.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.5
+ *
+ * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef ENABLE_H
+#define ENABLE_H
+
+
+#include "mtypes.h"
+
+
+extern void
+_mesa_set_enable( GLcontext* ctx, GLenum cap, GLboolean state );
+
+extern void GLAPIENTRY
+_mesa_Disable( GLenum cap );
+
+extern void GLAPIENTRY
+_mesa_Enable( GLenum cap );
+
+extern GLboolean GLAPIENTRY
+_mesa_IsEnabled( GLenum cap );
+
+extern void GLAPIENTRY
+_mesa_EnableClientState( GLenum cap );
+
+extern void GLAPIENTRY
+_mesa_DisableClientState( GLenum cap );
+
+
+#endif
diff --git a/src/mesa/main/enums.c b/src/mesa/main/enums.c
new file mode 100644
index 00000000000..ecda0bfb5ed
--- /dev/null
+++ b/src/mesa/main/enums.c
@@ -0,0 +1,4584 @@
+/* DO NOT EDIT - This file generated automatically by gl_enums.py (from Mesa) script */
+
+/*
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL,
+ * AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "glheader.h"
+#include "enums.h"
+#include "imports.h"
+
+typedef struct {
+ size_t offset;
+ int n;
+} enum_elt;
+
+static const char enum_string_table[] =
+ "GL_2D\0"
+ "GL_2_BYTES\0"
+ "GL_3D\0"
+ "GL_3D_COLOR\0"
+ "GL_3D_COLOR_TEXTURE\0"
+ "GL_3_BYTES\0"
+ "GL_4D_COLOR_TEXTURE\0"
+ "GL_4_BYTES\0"
+ "GL_ACCUM\0"
+ "GL_ACCUM_ALPHA_BITS\0"
+ "GL_ACCUM_BLUE_BITS\0"
+ "GL_ACCUM_BUFFER_BIT\0"
+ "GL_ACCUM_CLEAR_VALUE\0"
+ "GL_ACCUM_GREEN_BITS\0"
+ "GL_ACCUM_RED_BITS\0"
+ "GL_ACTIVE_STENCIL_FACE_EXT\0"
+ "GL_ACTIVE_TEXTURE\0"
+ "GL_ACTIVE_TEXTURE_ARB\0"
+ "GL_ACTIVE_VERTEX_UNITS_ARB\0"
+ "GL_ADD\0"
+ "GL_ADD_SIGNED\0"
+ "GL_ADD_SIGNED_ARB\0"
+ "GL_ADD_SIGNED_EXT\0"
+ "GL_ALIASED_LINE_WIDTH_RANGE\0"
+ "GL_ALIASED_POINT_SIZE_RANGE\0"
+ "GL_ALL_ATTRIB_BITS\0"
+ "GL_ALL_CLIENT_ATTRIB_BITS\0"
+ "GL_ALPHA\0"
+ "GL_ALPHA12\0"
+ "GL_ALPHA12_EXT\0"
+ "GL_ALPHA16\0"
+ "GL_ALPHA16_EXT\0"
+ "GL_ALPHA4\0"
+ "GL_ALPHA4_EXT\0"
+ "GL_ALPHA8\0"
+ "GL_ALPHA8_EXT\0"
+ "GL_ALPHA_BIAS\0"
+ "GL_ALPHA_BITS\0"
+ "GL_ALPHA_SCALE\0"
+ "GL_ALPHA_TEST\0"
+ "GL_ALPHA_TEST_FUNC\0"
+ "GL_ALPHA_TEST_REF\0"
+ "GL_ALWAYS\0"
+ "GL_AMBIENT\0"
+ "GL_AMBIENT_AND_DIFFUSE\0"
+ "GL_AND\0"
+ "GL_AND_INVERTED\0"
+ "GL_AND_REVERSE\0"
+ "GL_ARRAY_BUFFER\0"
+ "GL_ARRAY_BUFFER_ARB\0"
+ "GL_ARRAY_BUFFER_BINDING\0"
+ "GL_ARRAY_BUFFER_BINDING_ARB\0"
+ "GL_ATTRIB_ARRAY_POINTER_NV\0"
+ "GL_ATTRIB_ARRAY_SIZE_NV\0"
+ "GL_ATTRIB_ARRAY_STRIDE_NV\0"
+ "GL_ATTRIB_ARRAY_TYPE_NV\0"
+ "GL_ATTRIB_STACK_DEPTH\0"
+ "GL_AUTO_NORMAL\0"
+ "GL_AUX0\0"
+ "GL_AUX1\0"
+ "GL_AUX2\0"
+ "GL_AUX3\0"
+ "GL_AUX_BUFFERS\0"
+ "GL_BACK\0"
+ "GL_BACK_LEFT\0"
+ "GL_BACK_RIGHT\0"
+ "GL_BGR\0"
+ "GL_BGRA\0"
+ "GL_BITMAP\0"
+ "GL_BITMAP_TOKEN\0"
+ "GL_BLEND\0"
+ "GL_BLEND_COLOR\0"
+ "GL_BLEND_COLOR_EXT\0"
+ "GL_BLEND_DST\0"
+ "GL_BLEND_DST_ALPHA\0"
+ "GL_BLEND_DST_RGB\0"
+ "GL_BLEND_EQUATION\0"
+ "GL_BLEND_EQUATION_ALPHA_EXT\0"
+ "GL_BLEND_EQUATION_EXT\0"
+ "GL_BLEND_EQUATION_RGB_EXT\0"
+ "GL_BLEND_SRC\0"
+ "GL_BLEND_SRC_ALPHA\0"
+ "GL_BLEND_SRC_RGB\0"
+ "GL_BLUE\0"
+ "GL_BLUE_BIAS\0"
+ "GL_BLUE_BITS\0"
+ "GL_BLUE_SCALE\0"
+ "GL_BOOL_ARB\0"
+ "GL_BOOL_VEC2_ARB\0"
+ "GL_BOOL_VEC3_ARB\0"
+ "GL_BOOL_VEC4_ARB\0"
+ "GL_BUFFER_ACCESS\0"
+ "GL_BUFFER_ACCESS_ARB\0"
+ "GL_BUFFER_MAPPED\0"
+ "GL_BUFFER_MAPPED_ARB\0"
+ "GL_BUFFER_MAP_POINTER\0"
+ "GL_BUFFER_MAP_POINTER_ARB\0"
+ "GL_BUFFER_SIZE\0"
+ "GL_BUFFER_SIZE_ARB\0"
+ "GL_BUFFER_USAGE\0"
+ "GL_BUFFER_USAGE_ARB\0"
+ "GL_BYTE\0"
+ "GL_C3F_V3F\0"
+ "GL_C4F_N3F_V3F\0"
+ "GL_C4UB_V2F\0"
+ "GL_C4UB_V3F\0"
+ "GL_CCW\0"
+ "GL_CLAMP\0"
+ "GL_CLAMP_TO_BORDER\0"
+ "GL_CLAMP_TO_BORDER_ARB\0"
+ "GL_CLAMP_TO_BORDER_SGIS\0"
+ "GL_CLAMP_TO_EDGE\0"
+ "GL_CLAMP_TO_EDGE_SGIS\0"
+ "GL_CLEAR\0"
+ "GL_CLIENT_ACTIVE_TEXTURE\0"
+ "GL_CLIENT_ACTIVE_TEXTURE_ARB\0"
+ "GL_CLIENT_ALL_ATTRIB_BITS\0"
+ "GL_CLIENT_ATTRIB_STACK_DEPTH\0"
+ "GL_CLIENT_PIXEL_STORE_BIT\0"
+ "GL_CLIENT_VERTEX_ARRAY_BIT\0"
+ "GL_CLIP_PLANE0\0"
+ "GL_CLIP_PLANE1\0"
+ "GL_CLIP_PLANE2\0"
+ "GL_CLIP_PLANE3\0"
+ "GL_CLIP_PLANE4\0"
+ "GL_CLIP_PLANE5\0"
+ "GL_CLIP_VOLUME_CLIPPING_HINT_EXT\0"
+ "GL_COEFF\0"
+ "GL_COLOR\0"
+ "GL_COLOR_ARRAY\0"
+ "GL_COLOR_ARRAY_BUFFER_BINDING\0"
+ "GL_COLOR_ARRAY_BUFFER_BINDING_ARB\0"
+ "GL_COLOR_ARRAY_POINTER\0"
+ "GL_COLOR_ARRAY_SIZE\0"
+ "GL_COLOR_ARRAY_STRIDE\0"
+ "GL_COLOR_ARRAY_TYPE\0"
+ "GL_COLOR_ATTACHMENT0_EXT\0"
+ "GL_COLOR_ATTACHMENT10_EXT\0"
+ "GL_COLOR_ATTACHMENT11_EXT\0"
+ "GL_COLOR_ATTACHMENT12_EXT\0"
+ "GL_COLOR_ATTACHMENT13_EXT\0"
+ "GL_COLOR_ATTACHMENT14_EXT\0"
+ "GL_COLOR_ATTACHMENT15_EXT\0"
+ "GL_COLOR_ATTACHMENT1_EXT\0"
+ "GL_COLOR_ATTACHMENT2_EXT\0"
+ "GL_COLOR_ATTACHMENT3_EXT\0"
+ "GL_COLOR_ATTACHMENT4_EXT\0"
+ "GL_COLOR_ATTACHMENT5_EXT\0"
+ "GL_COLOR_ATTACHMENT6_EXT\0"
+ "GL_COLOR_ATTACHMENT7_EXT\0"
+ "GL_COLOR_ATTACHMENT8_EXT\0"
+ "GL_COLOR_ATTACHMENT9_EXT\0"
+ "GL_COLOR_BUFFER_BIT\0"
+ "GL_COLOR_CLEAR_VALUE\0"
+ "GL_COLOR_INDEX\0"
+ "GL_COLOR_INDEXES\0"
+ "GL_COLOR_LOGIC_OP\0"
+ "GL_COLOR_MATERIAL\0"
+ "GL_COLOR_MATERIAL_FACE\0"
+ "GL_COLOR_MATERIAL_PARAMETER\0"
+ "GL_COLOR_MATRIX\0"
+ "GL_COLOR_MATRIX_SGI\0"
+ "GL_COLOR_MATRIX_STACK_DEPTH\0"
+ "GL_COLOR_MATRIX_STACK_DEPTH_SGI\0"
+ "GL_COLOR_SUM\0"
+ "GL_COLOR_SUM_ARB\0"
+ "GL_COLOR_TABLE\0"
+ "GL_COLOR_TABLE_ALPHA_SIZE\0"
+ "GL_COLOR_TABLE_ALPHA_SIZE_EXT\0"
+ "GL_COLOR_TABLE_BIAS\0"
+ "GL_COLOR_TABLE_BLUE_SIZE\0"
+ "GL_COLOR_TABLE_BLUE_SIZE_EXT\0"
+ "GL_COLOR_TABLE_FORMAT\0"
+ "GL_COLOR_TABLE_FORMAT_EXT\0"
+ "GL_COLOR_TABLE_GREEN_SIZE\0"
+ "GL_COLOR_TABLE_GREEN_SIZE_EXT\0"
+ "GL_COLOR_TABLE_INTENSITY_SIZE\0"
+ "GL_COLOR_TABLE_INTENSITY_SIZE_EXT\0"
+ "GL_COLOR_TABLE_LUMINANCE_SIZE\0"
+ "GL_COLOR_TABLE_LUMINANCE_SIZE_EXT\0"
+ "GL_COLOR_TABLE_RED_SIZE\0"
+ "GL_COLOR_TABLE_RED_SIZE_EXT\0"
+ "GL_COLOR_TABLE_SCALE\0"
+ "GL_COLOR_TABLE_WIDTH\0"
+ "GL_COLOR_TABLE_WIDTH_EXT\0"
+ "GL_COLOR_WRITEMASK\0"
+ "GL_COMBINE\0"
+ "GL_COMBINE4\0"
+ "GL_COMBINE_ALPHA\0"
+ "GL_COMBINE_ALPHA_ARB\0"
+ "GL_COMBINE_ALPHA_EXT\0"
+ "GL_COMBINE_ARB\0"
+ "GL_COMBINE_EXT\0"
+ "GL_COMBINE_RGB\0"
+ "GL_COMBINE_RGB_ARB\0"
+ "GL_COMBINE_RGB_EXT\0"
+ "GL_COMPARE_R_TO_TEXTURE\0"
+ "GL_COMPARE_R_TO_TEXTURE_ARB\0"
+ "GL_COMPILE\0"
+ "GL_COMPILE_AND_EXECUTE\0"
+ "GL_COMPRESSED_ALPHA\0"
+ "GL_COMPRESSED_ALPHA_ARB\0"
+ "GL_COMPRESSED_INTENSITY\0"
+ "GL_COMPRESSED_INTENSITY_ARB\0"
+ "GL_COMPRESSED_LUMINANCE\0"
+ "GL_COMPRESSED_LUMINANCE_ALPHA\0"
+ "GL_COMPRESSED_LUMINANCE_ALPHA_ARB\0"
+ "GL_COMPRESSED_LUMINANCE_ARB\0"
+ "GL_COMPRESSED_RGB\0"
+ "GL_COMPRESSED_RGBA\0"
+ "GL_COMPRESSED_RGBA_ARB\0"
+ "GL_COMPRESSED_RGBA_FXT1_3DFX\0"
+ "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT\0"
+ "GL_COMPRESSED_RGBA_S3TC_DXT3_EXT\0"
+ "GL_COMPRESSED_RGBA_S3TC_DXT5_EXT\0"
+ "GL_COMPRESSED_RGB_ARB\0"
+ "GL_COMPRESSED_RGB_FXT1_3DFX\0"
+ "GL_COMPRESSED_RGB_S3TC_DXT1_EXT\0"
+ "GL_COMPRESSED_TEXTURE_FORMATS\0"
+ "GL_CONSTANT\0"
+ "GL_CONSTANT_ALPHA\0"
+ "GL_CONSTANT_ALPHA_EXT\0"
+ "GL_CONSTANT_ARB\0"
+ "GL_CONSTANT_ATTENUATION\0"
+ "GL_CONSTANT_BORDER_HP\0"
+ "GL_CONSTANT_COLOR\0"
+ "GL_CONSTANT_COLOR_EXT\0"
+ "GL_CONSTANT_EXT\0"
+ "GL_CONVOLUTION_1D\0"
+ "GL_CONVOLUTION_2D\0"
+ "GL_CONVOLUTION_BORDER_COLOR\0"
+ "GL_CONVOLUTION_BORDER_COLOR_HP\0"
+ "GL_CONVOLUTION_BORDER_MODE\0"
+ "GL_CONVOLUTION_BORDER_MODE_EXT\0"
+ "GL_CONVOLUTION_FILTER_BIAS\0"
+ "GL_CONVOLUTION_FILTER_BIAS_EXT\0"
+ "GL_CONVOLUTION_FILTER_SCALE\0"
+ "GL_CONVOLUTION_FILTER_SCALE_EXT\0"
+ "GL_CONVOLUTION_FORMAT\0"
+ "GL_CONVOLUTION_FORMAT_EXT\0"
+ "GL_CONVOLUTION_HEIGHT\0"
+ "GL_CONVOLUTION_HEIGHT_EXT\0"
+ "GL_CONVOLUTION_WIDTH\0"
+ "GL_CONVOLUTION_WIDTH_EXT\0"
+ "GL_COORD_REPLACE_ARB\0"
+ "GL_COORD_REPLACE_NV\0"
+ "GL_COPY\0"
+ "GL_COPY_INVERTED\0"
+ "GL_COPY_PIXEL_TOKEN\0"
+ "GL_CULL_FACE\0"
+ "GL_CULL_FACE_MODE\0"
+ "GL_CULL_VERTEX_EXT\0"
+ "GL_CULL_VERTEX_EYE_POSITION_EXT\0"
+ "GL_CULL_VERTEX_OBJECT_POSITION_EXT\0"
+ "GL_CURRENT_ATTRIB_NV\0"
+ "GL_CURRENT_BIT\0"
+ "GL_CURRENT_COLOR\0"
+ "GL_CURRENT_FOG_COORD\0"
+ "GL_CURRENT_FOG_COORDINATE\0"
+ "GL_CURRENT_INDEX\0"
+ "GL_CURRENT_MATRIX_ARB\0"
+ "GL_CURRENT_MATRIX_INDEX_ARB\0"
+ "GL_CURRENT_MATRIX_NV\0"
+ "GL_CURRENT_MATRIX_STACK_DEPTH_ARB\0"
+ "GL_CURRENT_MATRIX_STACK_DEPTH_NV\0"
+ "GL_CURRENT_NORMAL\0"
+ "GL_CURRENT_PALETTE_MATRIX_ARB\0"
+ "GL_CURRENT_QUERY\0"
+ "GL_CURRENT_QUERY_ARB\0"
+ "GL_CURRENT_RASTER_COLOR\0"
+ "GL_CURRENT_RASTER_DISTANCE\0"
+ "GL_CURRENT_RASTER_INDEX\0"
+ "GL_CURRENT_RASTER_POSITION\0"
+ "GL_CURRENT_RASTER_POSITION_VALID\0"
+ "GL_CURRENT_RASTER_TEXTURE_COORDS\0"
+ "GL_CURRENT_SECONDARY_COLOR\0"
+ "GL_CURRENT_TEXTURE_COORDS\0"
+ "GL_CURRENT_VERTEX_ATTRIB_ARB\0"
+ "GL_CURRENT_WEIGHT_ARB\0"
+ "GL_CW\0"
+ "GL_DECAL\0"
+ "GL_DECR\0"
+ "GL_DECR_WRAP\0"
+ "GL_DECR_WRAP_EXT\0"
+ "GL_DEPTH\0"
+ "GL_DEPTH_ATTACHMENT_EXT\0"
+ "GL_DEPTH_BIAS\0"
+ "GL_DEPTH_BITS\0"
+ "GL_DEPTH_BOUNDS_EXT\0"
+ "GL_DEPTH_BOUNDS_TEST_EXT\0"
+ "GL_DEPTH_BUFFER_BIT\0"
+ "GL_DEPTH_CLAMP_NV\0"
+ "GL_DEPTH_CLEAR_VALUE\0"
+ "GL_DEPTH_COMPONENT\0"
+ "GL_DEPTH_COMPONENT16\0"
+ "GL_DEPTH_COMPONENT16_ARB\0"
+ "GL_DEPTH_COMPONENT16_SGIX\0"
+ "GL_DEPTH_COMPONENT24\0"
+ "GL_DEPTH_COMPONENT24_ARB\0"
+ "GL_DEPTH_COMPONENT24_SGIX\0"
+ "GL_DEPTH_COMPONENT32\0"
+ "GL_DEPTH_COMPONENT32_ARB\0"
+ "GL_DEPTH_COMPONENT32_SGIX\0"
+ "GL_DEPTH_FUNC\0"
+ "GL_DEPTH_RANGE\0"
+ "GL_DEPTH_SCALE\0"
+ "GL_DEPTH_STENCIL_NV\0"
+ "GL_DEPTH_STENCIL_TO_BGRA_NV\0"
+ "GL_DEPTH_STENCIL_TO_RGBA_NV\0"
+ "GL_DEPTH_TEST\0"
+ "GL_DEPTH_TEXTURE_MODE\0"
+ "GL_DEPTH_TEXTURE_MODE_ARB\0"
+ "GL_DEPTH_WRITEMASK\0"
+ "GL_DIFFUSE\0"
+ "GL_DITHER\0"
+ "GL_DOMAIN\0"
+ "GL_DONT_CARE\0"
+ "GL_DOT3_RGB\0"
+ "GL_DOT3_RGBA\0"
+ "GL_DOT3_RGBA_ARB\0"
+ "GL_DOT3_RGBA_EXT\0"
+ "GL_DOT3_RGB_ARB\0"
+ "GL_DOT3_RGB_EXT\0"
+ "GL_DOUBLE\0"
+ "GL_DOUBLEBUFFER\0"
+ "GL_DRAW_BUFFER\0"
+ "GL_DRAW_BUFFER0_ARB\0"
+ "GL_DRAW_BUFFER0_ATI\0"
+ "GL_DRAW_BUFFER10_ARB\0"
+ "GL_DRAW_BUFFER10_ATI\0"
+ "GL_DRAW_BUFFER11_ARB\0"
+ "GL_DRAW_BUFFER11_ATI\0"
+ "GL_DRAW_BUFFER12_ARB\0"
+ "GL_DRAW_BUFFER12_ATI\0"
+ "GL_DRAW_BUFFER13_ARB\0"
+ "GL_DRAW_BUFFER13_ATI\0"
+ "GL_DRAW_BUFFER14_ARB\0"
+ "GL_DRAW_BUFFER14_ATI\0"
+ "GL_DRAW_BUFFER15_ARB\0"
+ "GL_DRAW_BUFFER15_ATI\0"
+ "GL_DRAW_BUFFER1_ARB\0"
+ "GL_DRAW_BUFFER1_ATI\0"
+ "GL_DRAW_BUFFER2_ARB\0"
+ "GL_DRAW_BUFFER2_ATI\0"
+ "GL_DRAW_BUFFER3_ARB\0"
+ "GL_DRAW_BUFFER3_ATI\0"
+ "GL_DRAW_BUFFER4_ARB\0"
+ "GL_DRAW_BUFFER4_ATI\0"
+ "GL_DRAW_BUFFER5_ARB\0"
+ "GL_DRAW_BUFFER5_ATI\0"
+ "GL_DRAW_BUFFER6_ARB\0"
+ "GL_DRAW_BUFFER6_ATI\0"
+ "GL_DRAW_BUFFER7_ARB\0"
+ "GL_DRAW_BUFFER7_ATI\0"
+ "GL_DRAW_BUFFER8_ARB\0"
+ "GL_DRAW_BUFFER8_ATI\0"
+ "GL_DRAW_BUFFER9_ARB\0"
+ "GL_DRAW_BUFFER9_ATI\0"
+ "GL_DRAW_PIXEL_TOKEN\0"
+ "GL_DST_ALPHA\0"
+ "GL_DST_COLOR\0"
+ "GL_DYNAMIC_COPY\0"
+ "GL_DYNAMIC_COPY_ARB\0"
+ "GL_DYNAMIC_DRAW\0"
+ "GL_DYNAMIC_DRAW_ARB\0"
+ "GL_DYNAMIC_READ\0"
+ "GL_DYNAMIC_READ_ARB\0"
+ "GL_EDGE_FLAG\0"
+ "GL_EDGE_FLAG_ARRAY\0"
+ "GL_EDGE_FLAG_ARRAY_BUFFER_BINDING\0"
+ "GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB\0"
+ "GL_EDGE_FLAG_ARRAY_POINTER\0"
+ "GL_EDGE_FLAG_ARRAY_STRIDE\0"
+ "GL_ELEMENT_ARRAY_BUFFER\0"
+ "GL_ELEMENT_ARRAY_BUFFER_ARB\0"
+ "GL_ELEMENT_ARRAY_BUFFER_BINDING\0"
+ "GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB\0"
+ "GL_EMISSION\0"
+ "GL_ENABLE_BIT\0"
+ "GL_EQUAL\0"
+ "GL_EQUIV\0"
+ "GL_EVAL_BIT\0"
+ "GL_EXP\0"
+ "GL_EXP2\0"
+ "GL_EXTENSIONS\0"
+ "GL_EYE_LINEAR\0"
+ "GL_EYE_PLANE\0"
+ "GL_EYE_PLANE_ABSOLUTE_NV\0"
+ "GL_EYE_RADIAL_NV\0"
+ "GL_FALSE\0"
+ "GL_FASTEST\0"
+ "GL_FEEDBACK\0"
+ "GL_FEEDBACK_BUFFER_POINTER\0"
+ "GL_FEEDBACK_BUFFER_SIZE\0"
+ "GL_FEEDBACK_BUFFER_TYPE\0"
+ "GL_FILL\0"
+ "GL_FLAT\0"
+ "GL_FLOAT\0"
+ "GL_FLOAT_MAT2_ARB\0"
+ "GL_FLOAT_MAT3_ARB\0"
+ "GL_FLOAT_MAT4_ARB\0"
+ "GL_FLOAT_VEC2_ARB\0"
+ "GL_FLOAT_VEC3_ARB\0"
+ "GL_FLOAT_VEC4_ARB\0"
+ "GL_FOG\0"
+ "GL_FOG_BIT\0"
+ "GL_FOG_COLOR\0"
+ "GL_FOG_COORD\0"
+ "GL_FOG_COORDINATE\0"
+ "GL_FOG_COORDINATE_ARRAY\0"
+ "GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING\0"
+ "GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB\0"
+ "GL_FOG_COORDINATE_ARRAY_POINTER\0"
+ "GL_FOG_COORDINATE_ARRAY_STRIDE\0"
+ "GL_FOG_COORDINATE_ARRAY_TYPE\0"
+ "GL_FOG_COORDINATE_SOURCE\0"
+ "GL_FOG_COORD_ARRAY\0"
+ "GL_FOG_COORD_ARRAY_BUFFER_BINDING\0"
+ "GL_FOG_COORD_ARRAY_POINTER\0"
+ "GL_FOG_COORD_ARRAY_STRIDE\0"
+ "GL_FOG_COORD_ARRAY_TYPE\0"
+ "GL_FOG_COORD_SRC\0"
+ "GL_FOG_DENSITY\0"
+ "GL_FOG_DISTANCE_MODE_NV\0"
+ "GL_FOG_END\0"
+ "GL_FOG_HINT\0"
+ "GL_FOG_INDEX\0"
+ "GL_FOG_MODE\0"
+ "GL_FOG_OFFSET_SGIX\0"
+ "GL_FOG_OFFSET_VALUE_SGIX\0"
+ "GL_FOG_START\0"
+ "GL_FRAGMENT_DEPTH\0"
+ "GL_FRAGMENT_PROGRAM_ARB\0"
+ "GL_FRAGMENT_SHADER_ARB\0"
+ "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT\0"
+ "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT\0"
+ "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT\0"
+ "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT\0"
+ "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT\0"
+ "GL_FRAMEBUFFER_BINDING_EXT\0"
+ "GL_FRAMEBUFFER_COMPLETE_EXT\0"
+ "GL_FRAMEBUFFER_EXT\0"
+ "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT\0"
+ "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT\0"
+ "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT\0"
+ "GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT\0"
+ "GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT\0"
+ "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT\0"
+ "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT\0"
+ "GL_FRAMEBUFFER_STATUS_ERROR_EXT\0"
+ "GL_FRAMEBUFFER_UNSUPPORTED_EXT\0"
+ "GL_FRONT\0"
+ "GL_FRONT_AND_BACK\0"
+ "GL_FRONT_FACE\0"
+ "GL_FRONT_LEFT\0"
+ "GL_FRONT_RIGHT\0"
+ "GL_FUNC_ADD\0"
+ "GL_FUNC_ADD_EXT\0"
+ "GL_FUNC_REVERSE_SUBTRACT\0"
+ "GL_FUNC_REVERSE_SUBTRACT_EXT\0"
+ "GL_FUNC_SUBTRACT\0"
+ "GL_FUNC_SUBTRACT_EXT\0"
+ "GL_GENERATE_MIPMAP\0"
+ "GL_GENERATE_MIPMAP_HINT\0"
+ "GL_GENERATE_MIPMAP_HINT_SGIS\0"
+ "GL_GENERATE_MIPMAP_SGIS\0"
+ "GL_GEQUAL\0"
+ "GL_GL_DRAW_FRAMEBUFFER_BINDING_EXT\0"
+ "GL_GL_DRAW_FRAMEBUFFER_EXT\0"
+ "GL_GL_READ_FRAMEBUFFER_BINDING_EXT\0"
+ "GL_GL_READ_FRAMEBUFFER_EXT\0"
+ "GL_GL_TIME_ELAPSED_EXT\0"
+ "GL_GREATER\0"
+ "GL_GREEN\0"
+ "GL_GREEN_BIAS\0"
+ "GL_GREEN_BITS\0"
+ "GL_GREEN_SCALE\0"
+ "GL_HINT_BIT\0"
+ "GL_HISTOGRAM\0"
+ "GL_HISTOGRAM_ALPHA_SIZE\0"
+ "GL_HISTOGRAM_ALPHA_SIZE_EXT\0"
+ "GL_HISTOGRAM_BLUE_SIZE\0"
+ "GL_HISTOGRAM_BLUE_SIZE_EXT\0"
+ "GL_HISTOGRAM_EXT\0"
+ "GL_HISTOGRAM_FORMAT\0"
+ "GL_HISTOGRAM_FORMAT_EXT\0"
+ "GL_HISTOGRAM_GREEN_SIZE\0"
+ "GL_HISTOGRAM_GREEN_SIZE_EXT\0"
+ "GL_HISTOGRAM_LUMINANCE_SIZE\0"
+ "GL_HISTOGRAM_LUMINANCE_SIZE_EXT\0"
+ "GL_HISTOGRAM_RED_SIZE\0"
+ "GL_HISTOGRAM_RED_SIZE_EXT\0"
+ "GL_HISTOGRAM_SINK\0"
+ "GL_HISTOGRAM_SINK_EXT\0"
+ "GL_HISTOGRAM_WIDTH\0"
+ "GL_HISTOGRAM_WIDTH_EXT\0"
+ "GL_IDENTITY_NV\0"
+ "GL_IGNORE_BORDER_HP\0"
+ "GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES\0"
+ "GL_IMPLEMENTATION_COLOR_READ_TYPE_OES\0"
+ "GL_INCR\0"
+ "GL_INCR_WRAP\0"
+ "GL_INCR_WRAP_EXT\0"
+ "GL_INDEX_ARRAY\0"
+ "GL_INDEX_ARRAY_BUFFER_BINDING\0"
+ "GL_INDEX_ARRAY_BUFFER_BINDING_ARB\0"
+ "GL_INDEX_ARRAY_POINTER\0"
+ "GL_INDEX_ARRAY_STRIDE\0"
+ "GL_INDEX_ARRAY_TYPE\0"
+ "GL_INDEX_BITS\0"
+ "GL_INDEX_CLEAR_VALUE\0"
+ "GL_INDEX_LOGIC_OP\0"
+ "GL_INDEX_MODE\0"
+ "GL_INDEX_OFFSET\0"
+ "GL_INDEX_SHIFT\0"
+ "GL_INDEX_WRITEMASK\0"
+ "GL_INT\0"
+ "GL_INTENSITY\0"
+ "GL_INTENSITY12\0"
+ "GL_INTENSITY12_EXT\0"
+ "GL_INTENSITY16\0"
+ "GL_INTENSITY16_EXT\0"
+ "GL_INTENSITY4\0"
+ "GL_INTENSITY4_EXT\0"
+ "GL_INTENSITY8\0"
+ "GL_INTENSITY8_EXT\0"
+ "GL_INTENSITY_EXT\0"
+ "GL_INTERPOLATE\0"
+ "GL_INTERPOLATE_ARB\0"
+ "GL_INTERPOLATE_EXT\0"
+ "GL_INT_VEC2_ARB\0"
+ "GL_INT_VEC3_ARB\0"
+ "GL_INT_VEC4_ARB\0"
+ "GL_INVALID_ENUM\0"
+ "GL_INVALID_FRAMEBUFFER_OPERATION_EXT\0"
+ "GL_INVALID_OPERATION\0"
+ "GL_INVALID_VALUE\0"
+ "GL_INVERSE_NV\0"
+ "GL_INVERSE_TRANSPOSE_NV\0"
+ "GL_INVERT\0"
+ "GL_KEEP\0"
+ "GL_LEFT\0"
+ "GL_LEQUAL\0"
+ "GL_LESS\0"
+ "GL_LIGHT0\0"
+ "GL_LIGHT1\0"
+ "GL_LIGHT2\0"
+ "GL_LIGHT3\0"
+ "GL_LIGHT4\0"
+ "GL_LIGHT5\0"
+ "GL_LIGHT6\0"
+ "GL_LIGHT7\0"
+ "GL_LIGHTING\0"
+ "GL_LIGHTING_BIT\0"
+ "GL_LIGHT_MODEL_AMBIENT\0"
+ "GL_LIGHT_MODEL_COLOR_CONTROL\0"
+ "GL_LIGHT_MODEL_COLOR_CONTROL_EXT\0"
+ "GL_LIGHT_MODEL_LOCAL_VIEWER\0"
+ "GL_LIGHT_MODEL_TWO_SIDE\0"
+ "GL_LINE\0"
+ "GL_LINEAR\0"
+ "GL_LINEAR_ATTENUATION\0"
+ "GL_LINEAR_CLIPMAP_LINEAR_SGIX\0"
+ "GL_LINEAR_CLIPMAP_NEAREST_SGIX\0"
+ "GL_LINEAR_MIPMAP_LINEAR\0"
+ "GL_LINEAR_MIPMAP_NEAREST\0"
+ "GL_LINES\0"
+ "GL_LINE_BIT\0"
+ "GL_LINE_LOOP\0"
+ "GL_LINE_RESET_TOKEN\0"
+ "GL_LINE_SMOOTH\0"
+ "GL_LINE_SMOOTH_HINT\0"
+ "GL_LINE_STIPPLE\0"
+ "GL_LINE_STIPPLE_PATTERN\0"
+ "GL_LINE_STIPPLE_REPEAT\0"
+ "GL_LINE_STRIP\0"
+ "GL_LINE_TOKEN\0"
+ "GL_LINE_WIDTH\0"
+ "GL_LINE_WIDTH_GRANULARITY\0"
+ "GL_LINE_WIDTH_RANGE\0"
+ "GL_LIST_BASE\0"
+ "GL_LIST_BIT\0"
+ "GL_LIST_INDEX\0"
+ "GL_LIST_MODE\0"
+ "GL_LOAD\0"
+ "GL_LOGIC_OP\0"
+ "GL_LOGIC_OP_MODE\0"
+ "GL_LUMINANCE\0"
+ "GL_LUMINANCE12\0"
+ "GL_LUMINANCE12_ALPHA12\0"
+ "GL_LUMINANCE12_ALPHA12_EXT\0"
+ "GL_LUMINANCE12_ALPHA4\0"
+ "GL_LUMINANCE12_ALPHA4_EXT\0"
+ "GL_LUMINANCE12_EXT\0"
+ "GL_LUMINANCE16\0"
+ "GL_LUMINANCE16_ALPHA16\0"
+ "GL_LUMINANCE16_ALPHA16_EXT\0"
+ "GL_LUMINANCE16_EXT\0"
+ "GL_LUMINANCE4\0"
+ "GL_LUMINANCE4_ALPHA4\0"
+ "GL_LUMINANCE4_ALPHA4_EXT\0"
+ "GL_LUMINANCE4_EXT\0"
+ "GL_LUMINANCE6_ALPHA2\0"
+ "GL_LUMINANCE6_ALPHA2_EXT\0"
+ "GL_LUMINANCE8\0"
+ "GL_LUMINANCE8_ALPHA8\0"
+ "GL_LUMINANCE8_ALPHA8_EXT\0"
+ "GL_LUMINANCE8_EXT\0"
+ "GL_LUMINANCE_ALPHA\0"
+ "GL_MAP1_COLOR_4\0"
+ "GL_MAP1_GRID_DOMAIN\0"
+ "GL_MAP1_GRID_SEGMENTS\0"
+ "GL_MAP1_INDEX\0"
+ "GL_MAP1_NORMAL\0"
+ "GL_MAP1_TEXTURE_COORD_1\0"
+ "GL_MAP1_TEXTURE_COORD_2\0"
+ "GL_MAP1_TEXTURE_COORD_3\0"
+ "GL_MAP1_TEXTURE_COORD_4\0"
+ "GL_MAP1_VERTEX_3\0"
+ "GL_MAP1_VERTEX_4\0"
+ "GL_MAP1_VERTEX_ATTRIB0_4_NV\0"
+ "GL_MAP1_VERTEX_ATTRIB10_4_NV\0"
+ "GL_MAP1_VERTEX_ATTRIB11_4_NV\0"
+ "GL_MAP1_VERTEX_ATTRIB12_4_NV\0"
+ "GL_MAP1_VERTEX_ATTRIB13_4_NV\0"
+ "GL_MAP1_VERTEX_ATTRIB14_4_NV\0"
+ "GL_MAP1_VERTEX_ATTRIB15_4_NV\0"
+ "GL_MAP1_VERTEX_ATTRIB1_4_NV\0"
+ "GL_MAP1_VERTEX_ATTRIB2_4_NV\0"
+ "GL_MAP1_VERTEX_ATTRIB3_4_NV\0"
+ "GL_MAP1_VERTEX_ATTRIB4_4_NV\0"
+ "GL_MAP1_VERTEX_ATTRIB5_4_NV\0"
+ "GL_MAP1_VERTEX_ATTRIB6_4_NV\0"
+ "GL_MAP1_VERTEX_ATTRIB7_4_NV\0"
+ "GL_MAP1_VERTEX_ATTRIB8_4_NV\0"
+ "GL_MAP1_VERTEX_ATTRIB9_4_NV\0"
+ "GL_MAP2_COLOR_4\0"
+ "GL_MAP2_GRID_DOMAIN\0"
+ "GL_MAP2_GRID_SEGMENTS\0"
+ "GL_MAP2_INDEX\0"
+ "GL_MAP2_NORMAL\0"
+ "GL_MAP2_TEXTURE_COORD_1\0"
+ "GL_MAP2_TEXTURE_COORD_2\0"
+ "GL_MAP2_TEXTURE_COORD_3\0"
+ "GL_MAP2_TEXTURE_COORD_4\0"
+ "GL_MAP2_VERTEX_3\0"
+ "GL_MAP2_VERTEX_4\0"
+ "GL_MAP2_VERTEX_ATTRIB0_4_NV\0"
+ "GL_MAP2_VERTEX_ATTRIB10_4_NV\0"
+ "GL_MAP2_VERTEX_ATTRIB11_4_NV\0"
+ "GL_MAP2_VERTEX_ATTRIB12_4_NV\0"
+ "GL_MAP2_VERTEX_ATTRIB13_4_NV\0"
+ "GL_MAP2_VERTEX_ATTRIB14_4_NV\0"
+ "GL_MAP2_VERTEX_ATTRIB15_4_NV\0"
+ "GL_MAP2_VERTEX_ATTRIB1_4_NV\0"
+ "GL_MAP2_VERTEX_ATTRIB2_4_NV\0"
+ "GL_MAP2_VERTEX_ATTRIB3_4_NV\0"
+ "GL_MAP2_VERTEX_ATTRIB4_4_NV\0"
+ "GL_MAP2_VERTEX_ATTRIB5_4_NV\0"
+ "GL_MAP2_VERTEX_ATTRIB6_4_NV\0"
+ "GL_MAP2_VERTEX_ATTRIB7_4_NV\0"
+ "GL_MAP2_VERTEX_ATTRIB8_4_NV\0"
+ "GL_MAP2_VERTEX_ATTRIB9_4_NV\0"
+ "GL_MAP_COLOR\0"
+ "GL_MAP_STENCIL\0"
+ "GL_MATRIX0_ARB\0"
+ "GL_MATRIX0_NV\0"
+ "GL_MATRIX10_ARB\0"
+ "GL_MATRIX11_ARB\0"
+ "GL_MATRIX12_ARB\0"
+ "GL_MATRIX13_ARB\0"
+ "GL_MATRIX14_ARB\0"
+ "GL_MATRIX15_ARB\0"
+ "GL_MATRIX16_ARB\0"
+ "GL_MATRIX17_ARB\0"
+ "GL_MATRIX18_ARB\0"
+ "GL_MATRIX19_ARB\0"
+ "GL_MATRIX1_ARB\0"
+ "GL_MATRIX1_NV\0"
+ "GL_MATRIX20_ARB\0"
+ "GL_MATRIX21_ARB\0"
+ "GL_MATRIX22_ARB\0"
+ "GL_MATRIX23_ARB\0"
+ "GL_MATRIX24_ARB\0"
+ "GL_MATRIX25_ARB\0"
+ "GL_MATRIX26_ARB\0"
+ "GL_MATRIX27_ARB\0"
+ "GL_MATRIX28_ARB\0"
+ "GL_MATRIX29_ARB\0"
+ "GL_MATRIX2_ARB\0"
+ "GL_MATRIX2_NV\0"
+ "GL_MATRIX30_ARB\0"
+ "GL_MATRIX31_ARB\0"
+ "GL_MATRIX3_ARB\0"
+ "GL_MATRIX3_NV\0"
+ "GL_MATRIX4_ARB\0"
+ "GL_MATRIX4_NV\0"
+ "GL_MATRIX5_ARB\0"
+ "GL_MATRIX5_NV\0"
+ "GL_MATRIX6_ARB\0"
+ "GL_MATRIX6_NV\0"
+ "GL_MATRIX7_ARB\0"
+ "GL_MATRIX7_NV\0"
+ "GL_MATRIX8_ARB\0"
+ "GL_MATRIX9_ARB\0"
+ "GL_MATRIX_INDEX_ARRAY_ARB\0"
+ "GL_MATRIX_INDEX_ARRAY_POINTER_ARB\0"
+ "GL_MATRIX_INDEX_ARRAY_SIZE_ARB\0"
+ "GL_MATRIX_INDEX_ARRAY_STRIDE_ARB\0"
+ "GL_MATRIX_INDEX_ARRAY_TYPE_ARB\0"
+ "GL_MATRIX_MODE\0"
+ "GL_MATRIX_PALETTE_ARB\0"
+ "GL_MAX\0"
+ "GL_MAX_3D_TEXTURE_SIZE\0"
+ "GL_MAX_ATTRIB_STACK_DEPTH\0"
+ "GL_MAX_CLIENT_ATTRIB_STACK_DEPTH\0"
+ "GL_MAX_CLIPMAP_DEPTH_SGIX\0"
+ "GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX\0"
+ "GL_MAX_CLIP_PLANES\0"
+ "GL_MAX_COLOR_ATTACHMENTS_EXT\0"
+ "GL_MAX_COLOR_MATRIX_STACK_DEPTH\0"
+ "GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI\0"
+ "GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB\0"
+ "GL_MAX_CONVOLUTION_HEIGHT\0"
+ "GL_MAX_CONVOLUTION_HEIGHT_EXT\0"
+ "GL_MAX_CONVOLUTION_WIDTH\0"
+ "GL_MAX_CONVOLUTION_WIDTH_EXT\0"
+ "GL_MAX_CUBE_MAP_TEXTURE_SIZE\0"
+ "GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB\0"
+ "GL_MAX_DRAW_BUFFERS_ARB\0"
+ "GL_MAX_DRAW_BUFFERS_ATI\0"
+ "GL_MAX_ELEMENTS_INDICES\0"
+ "GL_MAX_ELEMENTS_VERTICES\0"
+ "GL_MAX_EVAL_ORDER\0"
+ "GL_MAX_EXT\0"
+ "GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB\0"
+ "GL_MAX_LIGHTS\0"
+ "GL_MAX_LIST_NESTING\0"
+ "GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB\0"
+ "GL_MAX_MODELVIEW_STACK_DEPTH\0"
+ "GL_MAX_NAME_STACK_DEPTH\0"
+ "GL_MAX_PALETTE_MATRICES_ARB\0"
+ "GL_MAX_PIXEL_MAP_TABLE\0"
+ "GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB\0"
+ "GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB\0"
+ "GL_MAX_PROGRAM_ATTRIBS_ARB\0"
+ "GL_MAX_PROGRAM_CALL_DEPTH_NV\0"
+ "GL_MAX_PROGRAM_ENV_PARAMETERS_ARB\0"
+ "GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV\0"
+ "GL_MAX_PROGRAM_IF_DEPTH_NV\0"
+ "GL_MAX_PROGRAM_INSTRUCTIONS_ARB\0"
+ "GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB\0"
+ "GL_MAX_PROGRAM_LOOP_COUNT_NV\0"
+ "GL_MAX_PROGRAM_LOOP_DEPTH_NV\0"
+ "GL_MAX_PROGRAM_MATRICES_ARB\0"
+ "GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB\0"
+ "GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB\0"
+ "GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB\0"
+ "GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB\0"
+ "GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB\0"
+ "GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB\0"
+ "GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB\0"
+ "GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB\0"
+ "GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB\0"
+ "GL_MAX_PROGRAM_PARAMETERS_ARB\0"
+ "GL_MAX_PROGRAM_TEMPORARIES_ARB\0"
+ "GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB\0"
+ "GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB\0"
+ "GL_MAX_PROJECTION_STACK_DEPTH\0"
+ "GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB\0"
+ "GL_MAX_RECTANGLE_TEXTURE_SIZE_NV\0"
+ "GL_MAX_RENDERBUFFER_SIZE_EXT\0"
+ "GL_MAX_SHININESS_NV\0"
+ "GL_MAX_SPOT_EXPONENT_NV\0"
+ "GL_MAX_TEXTURE_COORDS_ARB\0"
+ "GL_MAX_TEXTURE_IMAGE_UNITS_ARB\0"
+ "GL_MAX_TEXTURE_LOD_BIAS\0"
+ "GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT\0"
+ "GL_MAX_TEXTURE_SIZE\0"
+ "GL_MAX_TEXTURE_STACK_DEPTH\0"
+ "GL_MAX_TEXTURE_UNITS\0"
+ "GL_MAX_TEXTURE_UNITS_ARB\0"
+ "GL_MAX_TRACK_MATRICES_NV\0"
+ "GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV\0"
+ "GL_MAX_VARYING_FLOATS_ARB\0"
+ "GL_MAX_VERTEX_ATTRIBS_ARB\0"
+ "GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB\0"
+ "GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB\0"
+ "GL_MAX_VERTEX_UNITS_ARB\0"
+ "GL_MAX_VIEWPORT_DIMS\0"
+ "GL_MIN\0"
+ "GL_MINMAX\0"
+ "GL_MINMAX_EXT\0"
+ "GL_MINMAX_FORMAT\0"
+ "GL_MINMAX_FORMAT_EXT\0"
+ "GL_MINMAX_SINK\0"
+ "GL_MINMAX_SINK_EXT\0"
+ "GL_MIN_EXT\0"
+ "GL_MIRRORED_REPEAT\0"
+ "GL_MIRRORED_REPEAT_ARB\0"
+ "GL_MIRRORED_REPEAT_IBM\0"
+ "GL_MIRROR_CLAMP_ATI\0"
+ "GL_MIRROR_CLAMP_EXT\0"
+ "GL_MIRROR_CLAMP_TO_BORDER_EXT\0"
+ "GL_MIRROR_CLAMP_TO_EDGE_ATI\0"
+ "GL_MIRROR_CLAMP_TO_EDGE_EXT\0"
+ "GL_MODELVIEW\0"
+ "GL_MODELVIEW0_ARB\0"
+ "GL_MODELVIEW10_ARB\0"
+ "GL_MODELVIEW11_ARB\0"
+ "GL_MODELVIEW12_ARB\0"
+ "GL_MODELVIEW13_ARB\0"
+ "GL_MODELVIEW14_ARB\0"
+ "GL_MODELVIEW15_ARB\0"
+ "GL_MODELVIEW16_ARB\0"
+ "GL_MODELVIEW17_ARB\0"
+ "GL_MODELVIEW18_ARB\0"
+ "GL_MODELVIEW19_ARB\0"
+ "GL_MODELVIEW1_ARB\0"
+ "GL_MODELVIEW20_ARB\0"
+ "GL_MODELVIEW21_ARB\0"
+ "GL_MODELVIEW22_ARB\0"
+ "GL_MODELVIEW23_ARB\0"
+ "GL_MODELVIEW24_ARB\0"
+ "GL_MODELVIEW25_ARB\0"
+ "GL_MODELVIEW26_ARB\0"
+ "GL_MODELVIEW27_ARB\0"
+ "GL_MODELVIEW28_ARB\0"
+ "GL_MODELVIEW29_ARB\0"
+ "GL_MODELVIEW2_ARB\0"
+ "GL_MODELVIEW30_ARB\0"
+ "GL_MODELVIEW31_ARB\0"
+ "GL_MODELVIEW3_ARB\0"
+ "GL_MODELVIEW4_ARB\0"
+ "GL_MODELVIEW5_ARB\0"
+ "GL_MODELVIEW6_ARB\0"
+ "GL_MODELVIEW7_ARB\0"
+ "GL_MODELVIEW8_ARB\0"
+ "GL_MODELVIEW9_ARB\0"
+ "GL_MODELVIEW_MATRIX\0"
+ "GL_MODELVIEW_PROJECTION_NV\0"
+ "GL_MODELVIEW_STACK_DEPTH\0"
+ "GL_MODULATE\0"
+ "GL_MODULATE_ADD_ATI\0"
+ "GL_MODULATE_SIGNED_ADD_ATI\0"
+ "GL_MODULATE_SUBTRACT_ATI\0"
+ "GL_MULT\0"
+ "GL_MULTISAMPLE\0"
+ "GL_MULTISAMPLE_3DFX\0"
+ "GL_MULTISAMPLE_ARB\0"
+ "GL_MULTISAMPLE_BIT\0"
+ "GL_MULTISAMPLE_BIT_3DFX\0"
+ "GL_MULTISAMPLE_BIT_ARB\0"
+ "GL_MULTISAMPLE_FILTER_HINT_NV\0"
+ "GL_N3F_V3F\0"
+ "GL_NAME_STACK_DEPTH\0"
+ "GL_NAND\0"
+ "GL_NEAREST\0"
+ "GL_NEAREST_CLIPMAP_LINEAR_SGIX\0"
+ "GL_NEAREST_CLIPMAP_NEAREST_SGIX\0"
+ "GL_NEAREST_MIPMAP_LINEAR\0"
+ "GL_NEAREST_MIPMAP_NEAREST\0"
+ "GL_NEVER\0"
+ "GL_NICEST\0"
+ "GL_NONE\0"
+ "GL_NOOP\0"
+ "GL_NOR\0"
+ "GL_NORMALIZE\0"
+ "GL_NORMAL_ARRAY\0"
+ "GL_NORMAL_ARRAY_BUFFER_BINDING\0"
+ "GL_NORMAL_ARRAY_BUFFER_BINDING_ARB\0"
+ "GL_NORMAL_ARRAY_POINTER\0"
+ "GL_NORMAL_ARRAY_STRIDE\0"
+ "GL_NORMAL_ARRAY_TYPE\0"
+ "GL_NORMAL_MAP\0"
+ "GL_NORMAL_MAP_ARB\0"
+ "GL_NORMAL_MAP_NV\0"
+ "GL_NOTEQUAL\0"
+ "GL_NO_ERROR\0"
+ "GL_NUM_COMPRESSED_TEXTURE_FORMATS\0"
+ "GL_NUM_TEXTURE_COMPRESSED_FORMATS_ARB\0"
+ "GL_OBJECT_ACTIVE_ATTRIBUTES_ARB\0"
+ "GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB\0"
+ "GL_OBJECT_ACTIVE_UNIFORMS_ARB\0"
+ "GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB\0"
+ "GL_OBJECT_ATTACHED_OBJECTS_ARB\0"
+ "GL_OBJECT_COMPILE_STATUS_ARB\0"
+ "GL_OBJECT_DELETE_STATUS_ARB\0"
+ "GL_OBJECT_INFO_LOG_LENGTH_ARB\0"
+ "GL_OBJECT_LINEAR\0"
+ "GL_OBJECT_LINK_STATUS_ARB\0"
+ "GL_OBJECT_PLANE\0"
+ "GL_OBJECT_SHADER_SOURCE_LENGTH_ARB\0"
+ "GL_OBJECT_SUBTYPE_ARB\0"
+ "GL_OBJECT_TYPE_ARB\0"
+ "GL_OBJECT_VALIDATE_STATUS_ARB\0"
+ "GL_OCCLUSION_TEST_HP\0"
+ "GL_OCCLUSION_TEST_RESULT_HP\0"
+ "GL_ONE\0"
+ "GL_ONE_MINUS_CONSTANT_ALPHA\0"
+ "GL_ONE_MINUS_CONSTANT_ALPHA_EXT\0"
+ "GL_ONE_MINUS_CONSTANT_COLOR\0"
+ "GL_ONE_MINUS_CONSTANT_COLOR_EXT\0"
+ "GL_ONE_MINUS_DST_ALPHA\0"
+ "GL_ONE_MINUS_DST_COLOR\0"
+ "GL_ONE_MINUS_SRC_ALPHA\0"
+ "GL_ONE_MINUS_SRC_COLOR\0"
+ "GL_OPERAND0_ALPHA\0"
+ "GL_OPERAND0_ALPHA_ARB\0"
+ "GL_OPERAND0_ALPHA_EXT\0"
+ "GL_OPERAND0_RGB\0"
+ "GL_OPERAND0_RGB_ARB\0"
+ "GL_OPERAND0_RGB_EXT\0"
+ "GL_OPERAND1_ALPHA\0"
+ "GL_OPERAND1_ALPHA_ARB\0"
+ "GL_OPERAND1_ALPHA_EXT\0"
+ "GL_OPERAND1_RGB\0"
+ "GL_OPERAND1_RGB_ARB\0"
+ "GL_OPERAND1_RGB_EXT\0"
+ "GL_OPERAND2_ALPHA\0"
+ "GL_OPERAND2_ALPHA_ARB\0"
+ "GL_OPERAND2_ALPHA_EXT\0"
+ "GL_OPERAND2_RGB\0"
+ "GL_OPERAND2_RGB_ARB\0"
+ "GL_OPERAND2_RGB_EXT\0"
+ "GL_OPERAND3_ALPHA_NV\0"
+ "GL_OPERAND3_RGB_NV\0"
+ "GL_OR\0"
+ "GL_ORDER\0"
+ "GL_OR_INVERTED\0"
+ "GL_OR_REVERSE\0"
+ "GL_OUT_OF_MEMORY\0"
+ "GL_PACK_ALIGNMENT\0"
+ "GL_PACK_IMAGE_HEIGHT\0"
+ "GL_PACK_INVERT_MESA\0"
+ "GL_PACK_LSB_FIRST\0"
+ "GL_PACK_ROW_LENGTH\0"
+ "GL_PACK_SKIP_IMAGES\0"
+ "GL_PACK_SKIP_PIXELS\0"
+ "GL_PACK_SKIP_ROWS\0"
+ "GL_PACK_SWAP_BYTES\0"
+ "GL_PALETTE4_R5_G6_B5_OES\0"
+ "GL_PALETTE4_RGB5_A1_OES\0"
+ "GL_PALETTE4_RGB8_OES\0"
+ "GL_PALETTE4_RGBA4_OES\0"
+ "GL_PALETTE4_RGBA8_OES\0"
+ "GL_PALETTE8_R5_G6_B5_OES\0"
+ "GL_PALETTE8_RGB5_A1_OES\0"
+ "GL_PALETTE8_RGB8_OES\0"
+ "GL_PALETTE8_RGBA4_OES\0"
+ "GL_PALETTE8_RGBA8_OES\0"
+ "GL_PASS_THROUGH_TOKEN\0"
+ "GL_PERSPECTIVE_CORRECTION_HINT\0"
+ "GL_PIXEL_MAP_A_TO_A\0"
+ "GL_PIXEL_MAP_A_TO_A_SIZE\0"
+ "GL_PIXEL_MAP_B_TO_B\0"
+ "GL_PIXEL_MAP_B_TO_B_SIZE\0"
+ "GL_PIXEL_MAP_G_TO_G\0"
+ "GL_PIXEL_MAP_G_TO_G_SIZE\0"
+ "GL_PIXEL_MAP_I_TO_A\0"
+ "GL_PIXEL_MAP_I_TO_A_SIZE\0"
+ "GL_PIXEL_MAP_I_TO_B\0"
+ "GL_PIXEL_MAP_I_TO_B_SIZE\0"
+ "GL_PIXEL_MAP_I_TO_G\0"
+ "GL_PIXEL_MAP_I_TO_G_SIZE\0"
+ "GL_PIXEL_MAP_I_TO_I\0"
+ "GL_PIXEL_MAP_I_TO_I_SIZE\0"
+ "GL_PIXEL_MAP_I_TO_R\0"
+ "GL_PIXEL_MAP_I_TO_R_SIZE\0"
+ "GL_PIXEL_MAP_R_TO_R\0"
+ "GL_PIXEL_MAP_R_TO_R_SIZE\0"
+ "GL_PIXEL_MAP_S_TO_S\0"
+ "GL_PIXEL_MAP_S_TO_S_SIZE\0"
+ "GL_PIXEL_MODE_BIT\0"
+ "GL_PIXEL_PACK_BUFFER_BINDING_EXT\0"
+ "GL_PIXEL_PACK_BUFFER_EXT\0"
+ "GL_PIXEL_UNPACK_BUFFER_BINDING_EXT\0"
+ "GL_PIXEL_UNPACK_BUFFER_EXT\0"
+ "GL_POINT\0"
+ "GL_POINTS\0"
+ "GL_POINT_BIT\0"
+ "GL_POINT_DISTANCE_ATTENUATION\0"
+ "GL_POINT_DISTANCE_ATTENUATION_ARB\0"
+ "GL_POINT_DISTANCE_ATTENUATION_EXT\0"
+ "GL_POINT_DISTANCE_ATTENUATION_SGIS\0"
+ "GL_POINT_FADE_THRESHOLD_SIZE\0"
+ "GL_POINT_FADE_THRESHOLD_SIZE_ARB\0"
+ "GL_POINT_FADE_THRESHOLD_SIZE_EXT\0"
+ "GL_POINT_FADE_THRESHOLD_SIZE_SGIS\0"
+ "GL_POINT_SIZE\0"
+ "GL_POINT_SIZE_GRANULARITY\0"
+ "GL_POINT_SIZE_MAX\0"
+ "GL_POINT_SIZE_MAX_ARB\0"
+ "GL_POINT_SIZE_MAX_EXT\0"
+ "GL_POINT_SIZE_MAX_SGIS\0"
+ "GL_POINT_SIZE_MIN\0"
+ "GL_POINT_SIZE_MIN_ARB\0"
+ "GL_POINT_SIZE_MIN_EXT\0"
+ "GL_POINT_SIZE_MIN_SGIS\0"
+ "GL_POINT_SIZE_RANGE\0"
+ "GL_POINT_SMOOTH\0"
+ "GL_POINT_SMOOTH_HINT\0"
+ "GL_POINT_SPRITE_ARB\0"
+ "GL_POINT_SPRITE_COORD_ORIGIN\0"
+ "GL_POINT_SPRITE_NV\0"
+ "GL_POINT_SPRITE_R_MODE_NV\0"
+ "GL_POINT_TOKEN\0"
+ "GL_POLYGON\0"
+ "GL_POLYGON_BIT\0"
+ "GL_POLYGON_MODE\0"
+ "GL_POLYGON_OFFSET_BIAS\0"
+ "GL_POLYGON_OFFSET_FACTOR\0"
+ "GL_POLYGON_OFFSET_FILL\0"
+ "GL_POLYGON_OFFSET_LINE\0"
+ "GL_POLYGON_OFFSET_POINT\0"
+ "GL_POLYGON_OFFSET_UNITS\0"
+ "GL_POLYGON_SMOOTH\0"
+ "GL_POLYGON_SMOOTH_HINT\0"
+ "GL_POLYGON_STIPPLE\0"
+ "GL_POLYGON_STIPPLE_BIT\0"
+ "GL_POLYGON_TOKEN\0"
+ "GL_POSITION\0"
+ "GL_POST_COLOR_MATRIX_ALPHA_BIAS\0"
+ "GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI\0"
+ "GL_POST_COLOR_MATRIX_ALPHA_SCALE\0"
+ "GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI\0"
+ "GL_POST_COLOR_MATRIX_BLUE_BIAS\0"
+ "GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI\0"
+ "GL_POST_COLOR_MATRIX_BLUE_SCALE\0"
+ "GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI\0"
+ "GL_POST_COLOR_MATRIX_COLOR_TABLE\0"
+ "GL_POST_COLOR_MATRIX_GREEN_BIAS\0"
+ "GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI\0"
+ "GL_POST_COLOR_MATRIX_GREEN_SCALE\0"
+ "GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI\0"
+ "GL_POST_COLOR_MATRIX_RED_BIAS\0"
+ "GL_POST_COLOR_MATRIX_RED_BIAS_SGI\0"
+ "GL_POST_COLOR_MATRIX_RED_SCALE\0"
+ "GL_POST_COLOR_MATRIX_RED_SCALE_SGI\0"
+ "GL_POST_CONVOLUTION_ALPHA_BIAS\0"
+ "GL_POST_CONVOLUTION_ALPHA_BIAS_EXT\0"
+ "GL_POST_CONVOLUTION_ALPHA_SCALE\0"
+ "GL_POST_CONVOLUTION_ALPHA_SCALE_EXT\0"
+ "GL_POST_CONVOLUTION_BLUE_BIAS\0"
+ "GL_POST_CONVOLUTION_BLUE_BIAS_EXT\0"
+ "GL_POST_CONVOLUTION_BLUE_SCALE\0"
+ "GL_POST_CONVOLUTION_BLUE_SCALE_EXT\0"
+ "GL_POST_CONVOLUTION_COLOR_TABLE\0"
+ "GL_POST_CONVOLUTION_GREEN_BIAS\0"
+ "GL_POST_CONVOLUTION_GREEN_BIAS_EXT\0"
+ "GL_POST_CONVOLUTION_GREEN_SCALE\0"
+ "GL_POST_CONVOLUTION_GREEN_SCALE_EXT\0"
+ "GL_POST_CONVOLUTION_RED_BIAS\0"
+ "GL_POST_CONVOLUTION_RED_BIAS_EXT\0"
+ "GL_POST_CONVOLUTION_RED_SCALE\0"
+ "GL_POST_CONVOLUTION_RED_SCALE_EXT\0"
+ "GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX\0"
+ "GL_POST_TEXTURE_FILTER_BIAS_SGIX\0"
+ "GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX\0"
+ "GL_POST_TEXTURE_FILTER_SCALE_SGIX\0"
+ "GL_PREVIOUS\0"
+ "GL_PREVIOUS_ARB\0"
+ "GL_PREVIOUS_EXT\0"
+ "GL_PRIMARY_COLOR\0"
+ "GL_PRIMARY_COLOR_ARB\0"
+ "GL_PRIMARY_COLOR_EXT\0"
+ "GL_PROGRAM_ADDRESS_REGISTERS_ARB\0"
+ "GL_PROGRAM_ALU_INSTRUCTIONS_ARB\0"
+ "GL_PROGRAM_ATTRIBS_ARB\0"
+ "GL_PROGRAM_BINDING_ARB\0"
+ "GL_PROGRAM_ERROR_POSITION_ARB\0"
+ "GL_PROGRAM_ERROR_POSITION_NV\0"
+ "GL_PROGRAM_ERROR_STRING_ARB\0"
+ "GL_PROGRAM_FORMAT_ARB\0"
+ "GL_PROGRAM_FORMAT_ASCII_ARB\0"
+ "GL_PROGRAM_INSTRUCTIONS_ARB\0"
+ "GL_PROGRAM_LENGTH_ARB\0"
+ "GL_PROGRAM_LENGTH_NV\0"
+ "GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB\0"
+ "GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB\0"
+ "GL_PROGRAM_NATIVE_ATTRIBS_ARB\0"
+ "GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB\0"
+ "GL_PROGRAM_NATIVE_PARAMETERS_ARB\0"
+ "GL_PROGRAM_NATIVE_TEMPORARIES_ARB\0"
+ "GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB\0"
+ "GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB\0"
+ "GL_PROGRAM_OBJECT_ARB\0"
+ "GL_PROGRAM_PARAMETERS_ARB\0"
+ "GL_PROGRAM_PARAMETER_NV\0"
+ "GL_PROGRAM_RESIDENT_NV\0"
+ "GL_PROGRAM_STRING_ARB\0"
+ "GL_PROGRAM_STRING_NV\0"
+ "GL_PROGRAM_TARGET_NV\0"
+ "GL_PROGRAM_TEMPORARIES_ARB\0"
+ "GL_PROGRAM_TEX_INDIRECTIONS_ARB\0"
+ "GL_PROGRAM_TEX_INSTRUCTIONS_ARB\0"
+ "GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB\0"
+ "GL_PROJECTION\0"
+ "GL_PROJECTION_MATRIX\0"
+ "GL_PROJECTION_STACK_DEPTH\0"
+ "GL_PROXY_COLOR_TABLE\0"
+ "GL_PROXY_HISTOGRAM\0"
+ "GL_PROXY_HISTOGRAM_EXT\0"
+ "GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE\0"
+ "GL_PROXY_POST_CONVOLUTION_COLOR_TABLE\0"
+ "GL_PROXY_TEXTURE_1D\0"
+ "GL_PROXY_TEXTURE_1D_EXT\0"
+ "GL_PROXY_TEXTURE_2D\0"
+ "GL_PROXY_TEXTURE_2D_EXT\0"
+ "GL_PROXY_TEXTURE_3D\0"
+ "GL_PROXY_TEXTURE_COLOR_TABLE_SGI\0"
+ "GL_PROXY_TEXTURE_CUBE_MAP\0"
+ "GL_PROXY_TEXTURE_CUBE_MAP_ARB\0"
+ "GL_PROXY_TEXTURE_RECTANGLE_ARB\0"
+ "GL_PROXY_TEXTURE_RECTANGLE_NV\0"
+ "GL_Q\0"
+ "GL_QUADRATIC_ATTENUATION\0"
+ "GL_QUADS\0"
+ "GL_QUAD_MESH_SUN\0"
+ "GL_QUAD_STRIP\0"
+ "GL_QUERY_COUNTER_BITS\0"
+ "GL_QUERY_COUNTER_BITS_ARB\0"
+ "GL_QUERY_RESULT\0"
+ "GL_QUERY_RESULT_ARB\0"
+ "GL_QUERY_RESULT_AVAILABLE\0"
+ "GL_QUERY_RESULT_AVAILABLE_ARB\0"
+ "GL_R\0"
+ "GL_R3_G3_B2\0"
+ "GL_RASTER_POSITION_UNCLIPPED_IBM\0"
+ "GL_READ_BUFFER\0"
+ "GL_READ_ONLY\0"
+ "GL_READ_ONLY_ARB\0"
+ "GL_READ_WRITE\0"
+ "GL_READ_WRITE_ARB\0"
+ "GL_RED\0"
+ "GL_REDUCE\0"
+ "GL_REDUCE_EXT\0"
+ "GL_RED_BIAS\0"
+ "GL_RED_BITS\0"
+ "GL_RED_SCALE\0"
+ "GL_REFLECTION_MAP\0"
+ "GL_REFLECTION_MAP_ARB\0"
+ "GL_REFLECTION_MAP_NV\0"
+ "GL_RENDER\0"
+ "GL_RENDERBUFFER_BINDING_EXT\0"
+ "GL_RENDERBUFFER_EXT\0"
+ "GL_RENDERBUFFER_HEIGHT_EXT\0"
+ "GL_RENDERBUFFER_INTERNAL_FORMAT_EXT\0"
+ "GL_RENDERBUFFER_WIDTH_EXT\0"
+ "GL_RENDERER\0"
+ "GL_RENDER_MODE\0"
+ "GL_REPEAT\0"
+ "GL_REPLACE\0"
+ "GL_REPLACE_EXT\0"
+ "GL_REPLICATE_BORDER_HP\0"
+ "GL_RESCALE_NORMAL\0"
+ "GL_RESCALE_NORMAL_EXT\0"
+ "GL_RETURN\0"
+ "GL_RGB\0"
+ "GL_RGB10\0"
+ "GL_RGB10_A2\0"
+ "GL_RGB10_A2_EXT\0"
+ "GL_RGB10_EXT\0"
+ "GL_RGB12\0"
+ "GL_RGB12_EXT\0"
+ "GL_RGB16\0"
+ "GL_RGB16_EXT\0"
+ "GL_RGB2_EXT\0"
+ "GL_RGB4\0"
+ "GL_RGB4_EXT\0"
+ "GL_RGB4_S3TC\0"
+ "GL_RGB5\0"
+ "GL_RGB5_A1\0"
+ "GL_RGB5_A1_EXT\0"
+ "GL_RGB5_EXT\0"
+ "GL_RGB8\0"
+ "GL_RGB8_EXT\0"
+ "GL_RGBA\0"
+ "GL_RGBA12\0"
+ "GL_RGBA12_EXT\0"
+ "GL_RGBA16\0"
+ "GL_RGBA16_EXT\0"
+ "GL_RGBA2\0"
+ "GL_RGBA2_EXT\0"
+ "GL_RGBA4\0"
+ "GL_RGBA4_DXT5_S3TC\0"
+ "GL_RGBA4_EXT\0"
+ "GL_RGBA4_S3TC\0"
+ "GL_RGBA8\0"
+ "GL_RGBA8_EXT\0"
+ "GL_RGBA_DXT5_S3TC\0"
+ "GL_RGBA_MODE\0"
+ "GL_RGBA_S3TC\0"
+ "GL_RGB_S3TC\0"
+ "GL_RGB_SCALE\0"
+ "GL_RGB_SCALE_ARB\0"
+ "GL_RGB_SCALE_EXT\0"
+ "GL_RIGHT\0"
+ "GL_S\0"
+ "GL_SAMPLES\0"
+ "GL_SAMPLES_3DFX\0"
+ "GL_SAMPLES_ARB\0"
+ "GL_SAMPLES_PASSED\0"
+ "GL_SAMPLES_PASSED_ARB\0"
+ "GL_SAMPLE_ALPHA_TO_COVERAGE\0"
+ "GL_SAMPLE_ALPHA_TO_COVERAGE_ARB\0"
+ "GL_SAMPLE_ALPHA_TO_ONE\0"
+ "GL_SAMPLE_ALPHA_TO_ONE_ARB\0"
+ "GL_SAMPLE_BUFFERS\0"
+ "GL_SAMPLE_BUFFERS_3DFX\0"
+ "GL_SAMPLE_BUFFERS_ARB\0"
+ "GL_SAMPLE_COVERAGE\0"
+ "GL_SAMPLE_COVERAGE_ARB\0"
+ "GL_SAMPLE_COVERAGE_INVERT\0"
+ "GL_SAMPLE_COVERAGE_INVERT_ARB\0"
+ "GL_SAMPLE_COVERAGE_VALUE\0"
+ "GL_SAMPLE_COVERAGE_VALUE_ARB\0"
+ "GL_SCISSOR_BIT\0"
+ "GL_SCISSOR_BOX\0"
+ "GL_SCISSOR_TEST\0"
+ "GL_SECONDARY_COLOR_ARRAY\0"
+ "GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING\0"
+ "GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB\0"
+ "GL_SECONDARY_COLOR_ARRAY_POINTER\0"
+ "GL_SECONDARY_COLOR_ARRAY_SIZE\0"
+ "GL_SECONDARY_COLOR_ARRAY_STRIDE\0"
+ "GL_SECONDARY_COLOR_ARRAY_TYPE\0"
+ "GL_SELECT\0"
+ "GL_SELECTION_BUFFER_POINTER\0"
+ "GL_SELECTION_BUFFER_SIZE\0"
+ "GL_SEPARABLE_2D\0"
+ "GL_SEPARATE_SPECULAR_COLOR\0"
+ "GL_SEPARATE_SPECULAR_COLOR_EXT\0"
+ "GL_SET\0"
+ "GL_SHADER_OBJECT_ARB\0"
+ "GL_SHADE_MODEL\0"
+ "GL_SHADOW_AMBIENT_SGIX\0"
+ "GL_SHARED_TEXTURE_PALETTE_EXT\0"
+ "GL_SHININESS\0"
+ "GL_SHORT\0"
+ "GL_SINGLE_COLOR\0"
+ "GL_SINGLE_COLOR_EXT\0"
+ "GL_SLICE_ACCUM_SUN\0"
+ "GL_SMOOTH\0"
+ "GL_SMOOTH_LINE_WIDTH_GRANULARITY\0"
+ "GL_SMOOTH_LINE_WIDTH_RANGE\0"
+ "GL_SMOOTH_POINT_SIZE_GRANULARITY\0"
+ "GL_SMOOTH_POINT_SIZE_RANGE\0"
+ "GL_SOURCE0_ALPHA\0"
+ "GL_SOURCE0_ALPHA_ARB\0"
+ "GL_SOURCE0_ALPHA_EXT\0"
+ "GL_SOURCE0_RGB\0"
+ "GL_SOURCE0_RGB_ARB\0"
+ "GL_SOURCE0_RGB_EXT\0"
+ "GL_SOURCE1_ALPHA\0"
+ "GL_SOURCE1_ALPHA_ARB\0"
+ "GL_SOURCE1_ALPHA_EXT\0"
+ "GL_SOURCE1_RGB\0"
+ "GL_SOURCE1_RGB_ARB\0"
+ "GL_SOURCE1_RGB_EXT\0"
+ "GL_SOURCE2_ALPHA\0"
+ "GL_SOURCE2_ALPHA_ARB\0"
+ "GL_SOURCE2_ALPHA_EXT\0"
+ "GL_SOURCE2_RGB\0"
+ "GL_SOURCE2_RGB_ARB\0"
+ "GL_SOURCE2_RGB_EXT\0"
+ "GL_SOURCE3_ALPHA_NV\0"
+ "GL_SOURCE3_RGB_NV\0"
+ "GL_SPECULAR\0"
+ "GL_SPHERE_MAP\0"
+ "GL_SPOT_CUTOFF\0"
+ "GL_SPOT_DIRECTION\0"
+ "GL_SPOT_EXPONENT\0"
+ "GL_SRC0_ALPHA\0"
+ "GL_SRC0_RGB\0"
+ "GL_SRC1_ALPHA\0"
+ "GL_SRC1_RGB\0"
+ "GL_SRC2_ALPHA\0"
+ "GL_SRC2_RGB\0"
+ "GL_SRC_ALPHA\0"
+ "GL_SRC_ALPHA_SATURATE\0"
+ "GL_SRC_COLOR\0"
+ "GL_STACK_OVERFLOW\0"
+ "GL_STACK_UNDERFLOW\0"
+ "GL_STATIC_COPY\0"
+ "GL_STATIC_COPY_ARB\0"
+ "GL_STATIC_DRAW\0"
+ "GL_STATIC_DRAW_ARB\0"
+ "GL_STATIC_READ\0"
+ "GL_STATIC_READ_ARB\0"
+ "GL_STENCIL\0"
+ "GL_STENCIL_ATTACHMENT_EXT\0"
+ "GL_STENCIL_BITS\0"
+ "GL_STENCIL_BUFFER_BIT\0"
+ "GL_STENCIL_CLEAR_VALUE\0"
+ "GL_STENCIL_FAIL\0"
+ "GL_STENCIL_FUNC\0"
+ "GL_STENCIL_INDEX\0"
+ "GL_STENCIL_INDEX16_EXT\0"
+ "GL_STENCIL_INDEX1_EXT\0"
+ "GL_STENCIL_INDEX4_EXT\0"
+ "GL_STENCIL_INDEX8_EXT\0"
+ "GL_STENCIL_INDEX_EXT\0"
+ "GL_STENCIL_PASS_DEPTH_FAIL\0"
+ "GL_STENCIL_PASS_DEPTH_PASS\0"
+ "GL_STENCIL_REF\0"
+ "GL_STENCIL_TEST\0"
+ "GL_STENCIL_TEST_TWO_SIDE_EXT\0"
+ "GL_STENCIL_VALUE_MASK\0"
+ "GL_STENCIL_WRITEMASK\0"
+ "GL_STEREO\0"
+ "GL_STREAM_COPY\0"
+ "GL_STREAM_COPY_ARB\0"
+ "GL_STREAM_DRAW\0"
+ "GL_STREAM_DRAW_ARB\0"
+ "GL_STREAM_READ\0"
+ "GL_STREAM_READ_ARB\0"
+ "GL_SUBPIXEL_BITS\0"
+ "GL_SUBTRACT\0"
+ "GL_SUBTRACT_ARB\0"
+ "GL_T\0"
+ "GL_T2F_C3F_V3F\0"
+ "GL_T2F_C4F_N3F_V3F\0"
+ "GL_T2F_C4UB_V3F\0"
+ "GL_T2F_N3F_V3F\0"
+ "GL_T2F_V3F\0"
+ "GL_T4F_C4F_N3F_V4F\0"
+ "GL_T4F_V4F\0"
+ "GL_TABLE_TOO_LARGE_EXT\0"
+ "GL_TEXTURE\0"
+ "GL_TEXTURE0\0"
+ "GL_TEXTURE0_ARB\0"
+ "GL_TEXTURE1\0"
+ "GL_TEXTURE10\0"
+ "GL_TEXTURE10_ARB\0"
+ "GL_TEXTURE11\0"
+ "GL_TEXTURE11_ARB\0"
+ "GL_TEXTURE12\0"
+ "GL_TEXTURE12_ARB\0"
+ "GL_TEXTURE13\0"
+ "GL_TEXTURE13_ARB\0"
+ "GL_TEXTURE14\0"
+ "GL_TEXTURE14_ARB\0"
+ "GL_TEXTURE15\0"
+ "GL_TEXTURE15_ARB\0"
+ "GL_TEXTURE16\0"
+ "GL_TEXTURE16_ARB\0"
+ "GL_TEXTURE17\0"
+ "GL_TEXTURE17_ARB\0"
+ "GL_TEXTURE18\0"
+ "GL_TEXTURE18_ARB\0"
+ "GL_TEXTURE19\0"
+ "GL_TEXTURE19_ARB\0"
+ "GL_TEXTURE1_ARB\0"
+ "GL_TEXTURE2\0"
+ "GL_TEXTURE20\0"
+ "GL_TEXTURE20_ARB\0"
+ "GL_TEXTURE21\0"
+ "GL_TEXTURE21_ARB\0"
+ "GL_TEXTURE22\0"
+ "GL_TEXTURE22_ARB\0"
+ "GL_TEXTURE23\0"
+ "GL_TEXTURE23_ARB\0"
+ "GL_TEXTURE24\0"
+ "GL_TEXTURE24_ARB\0"
+ "GL_TEXTURE25\0"
+ "GL_TEXTURE25_ARB\0"
+ "GL_TEXTURE26\0"
+ "GL_TEXTURE26_ARB\0"
+ "GL_TEXTURE27\0"
+ "GL_TEXTURE27_ARB\0"
+ "GL_TEXTURE28\0"
+ "GL_TEXTURE28_ARB\0"
+ "GL_TEXTURE29\0"
+ "GL_TEXTURE29_ARB\0"
+ "GL_TEXTURE2_ARB\0"
+ "GL_TEXTURE3\0"
+ "GL_TEXTURE30\0"
+ "GL_TEXTURE30_ARB\0"
+ "GL_TEXTURE31\0"
+ "GL_TEXTURE31_ARB\0"
+ "GL_TEXTURE3_ARB\0"
+ "GL_TEXTURE4\0"
+ "GL_TEXTURE4_ARB\0"
+ "GL_TEXTURE5\0"
+ "GL_TEXTURE5_ARB\0"
+ "GL_TEXTURE6\0"
+ "GL_TEXTURE6_ARB\0"
+ "GL_TEXTURE7\0"
+ "GL_TEXTURE7_ARB\0"
+ "GL_TEXTURE8\0"
+ "GL_TEXTURE8_ARB\0"
+ "GL_TEXTURE9\0"
+ "GL_TEXTURE9_ARB\0"
+ "GL_TEXTURE_1D\0"
+ "GL_TEXTURE_2D\0"
+ "GL_TEXTURE_3D\0"
+ "GL_TEXTURE_ALPHA_SIZE\0"
+ "GL_TEXTURE_ALPHA_SIZE_EXT\0"
+ "GL_TEXTURE_BASE_LEVEL\0"
+ "GL_TEXTURE_BINDING_1D\0"
+ "GL_TEXTURE_BINDING_2D\0"
+ "GL_TEXTURE_BINDING_3D\0"
+ "GL_TEXTURE_BINDING_CUBE_MAP\0"
+ "GL_TEXTURE_BINDING_CUBE_MAP_ARB\0"
+ "GL_TEXTURE_BINDING_RECTANGLE_ARB\0"
+ "GL_TEXTURE_BINDING_RECTANGLE_NV\0"
+ "GL_TEXTURE_BIT\0"
+ "GL_TEXTURE_BLUE_SIZE\0"
+ "GL_TEXTURE_BLUE_SIZE_EXT\0"
+ "GL_TEXTURE_BORDER\0"
+ "GL_TEXTURE_BORDER_COLOR\0"
+ "GL_TEXTURE_CLIPMAP_CENTER_SGIX\0"
+ "GL_TEXTURE_CLIPMAP_DEPTH_SGIX\0"
+ "GL_TEXTURE_CLIPMAP_FRAME_SGIX\0"
+ "GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX\0"
+ "GL_TEXTURE_CLIPMAP_OFFSET_SGIX\0"
+ "GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX\0"
+ "GL_TEXTURE_COLOR_TABLE_SGI\0"
+ "GL_TEXTURE_COLOR_WRITEMASK_SGIS\0"
+ "GL_TEXTURE_COMPARE_FAIL_VALUE_ARB\0"
+ "GL_TEXTURE_COMPARE_FUNC\0"
+ "GL_TEXTURE_COMPARE_FUNC_ARB\0"
+ "GL_TEXTURE_COMPARE_MODE\0"
+ "GL_TEXTURE_COMPARE_MODE_ARB\0"
+ "GL_TEXTURE_COMPARE_OPERATOR_SGIX\0"
+ "GL_TEXTURE_COMPARE_SGIX\0"
+ "GL_TEXTURE_COMPONENTS\0"
+ "GL_TEXTURE_COMPRESSED\0"
+ "GL_TEXTURE_COMPRESSED_ARB\0"
+ "GL_TEXTURE_COMPRESSED_FORMATS_ARB\0"
+ "GL_TEXTURE_COMPRESSED_IMAGE_SIZE\0"
+ "GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB\0"
+ "GL_TEXTURE_COMPRESSION_HINT\0"
+ "GL_TEXTURE_COMPRESSION_HINT_ARB\0"
+ "GL_TEXTURE_COORD_ARRAY\0"
+ "GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING\0"
+ "GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB\0"
+ "GL_TEXTURE_COORD_ARRAY_POINTER\0"
+ "GL_TEXTURE_COORD_ARRAY_SIZE\0"
+ "GL_TEXTURE_COORD_ARRAY_STRIDE\0"
+ "GL_TEXTURE_COORD_ARRAY_TYPE\0"
+ "GL_TEXTURE_CUBE_MAP\0"
+ "GL_TEXTURE_CUBE_MAP_ARB\0"
+ "GL_TEXTURE_CUBE_MAP_NEGATIVE_X\0"
+ "GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB\0"
+ "GL_TEXTURE_CUBE_MAP_NEGATIVE_Y\0"
+ "GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB\0"
+ "GL_TEXTURE_CUBE_MAP_NEGATIVE_Z\0"
+ "GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB\0"
+ "GL_TEXTURE_CUBE_MAP_POSITIVE_X\0"
+ "GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB\0"
+ "GL_TEXTURE_CUBE_MAP_POSITIVE_Y\0"
+ "GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB\0"
+ "GL_TEXTURE_CUBE_MAP_POSITIVE_Z\0"
+ "GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB\0"
+ "GL_TEXTURE_DEPTH\0"
+ "GL_TEXTURE_DEPTH_SIZE\0"
+ "GL_TEXTURE_DEPTH_SIZE_ARB\0"
+ "GL_TEXTURE_ENV\0"
+ "GL_TEXTURE_ENV_COLOR\0"
+ "GL_TEXTURE_ENV_MODE\0"
+ "GL_TEXTURE_FILTER_CONTROL\0"
+ "GL_TEXTURE_GEN_MODE\0"
+ "GL_TEXTURE_GEN_Q\0"
+ "GL_TEXTURE_GEN_R\0"
+ "GL_TEXTURE_GEN_S\0"
+ "GL_TEXTURE_GEN_T\0"
+ "GL_TEXTURE_GEQUAL_R_SGIX\0"
+ "GL_TEXTURE_GREEN_SIZE\0"
+ "GL_TEXTURE_GREEN_SIZE_EXT\0"
+ "GL_TEXTURE_HEIGHT\0"
+ "GL_TEXTURE_INDEX_SIZE_EXT\0"
+ "GL_TEXTURE_INTENSITY_SIZE\0"
+ "GL_TEXTURE_INTENSITY_SIZE_EXT\0"
+ "GL_TEXTURE_INTERNAL_FORMAT\0"
+ "GL_TEXTURE_LEQUAL_R_SGIX\0"
+ "GL_TEXTURE_LOD_BIAS\0"
+ "GL_TEXTURE_LOD_BIAS_EXT\0"
+ "GL_TEXTURE_LOD_BIAS_R_SGIX\0"
+ "GL_TEXTURE_LOD_BIAS_S_SGIX\0"
+ "GL_TEXTURE_LOD_BIAS_T_SGIX\0"
+ "GL_TEXTURE_LUMINANCE_SIZE\0"
+ "GL_TEXTURE_LUMINANCE_SIZE_EXT\0"
+ "GL_TEXTURE_MAG_FILTER\0"
+ "GL_TEXTURE_MATRIX\0"
+ "GL_TEXTURE_MAX_ANISOTROPY_EXT\0"
+ "GL_TEXTURE_MAX_CLAMP_R_SGIX\0"
+ "GL_TEXTURE_MAX_CLAMP_S_SGIX\0"
+ "GL_TEXTURE_MAX_CLAMP_T_SGIX\0"
+ "GL_TEXTURE_MAX_LEVEL\0"
+ "GL_TEXTURE_MAX_LOD\0"
+ "GL_TEXTURE_MIN_FILTER\0"
+ "GL_TEXTURE_MIN_LOD\0"
+ "GL_TEXTURE_PRIORITY\0"
+ "GL_TEXTURE_RECTANGLE_ARB\0"
+ "GL_TEXTURE_RECTANGLE_NV\0"
+ "GL_TEXTURE_RED_SIZE\0"
+ "GL_TEXTURE_RED_SIZE_EXT\0"
+ "GL_TEXTURE_RESIDENT\0"
+ "GL_TEXTURE_STACK_DEPTH\0"
+ "GL_TEXTURE_TOO_LARGE_EXT\0"
+ "GL_TEXTURE_UNSIGNED_REMAP_MODE_NV\0"
+ "GL_TEXTURE_WIDTH\0"
+ "GL_TEXTURE_WRAP_R\0"
+ "GL_TEXTURE_WRAP_S\0"
+ "GL_TEXTURE_WRAP_T\0"
+ "GL_TRACK_MATRIX_NV\0"
+ "GL_TRACK_MATRIX_TRANSFORM_NV\0"
+ "GL_TRANSFORM_BIT\0"
+ "GL_TRANSPOSE_COLOR_MATRIX\0"
+ "GL_TRANSPOSE_COLOR_MATRIX_ARB\0"
+ "GL_TRANSPOSE_CURRENT_MATRIX_ARB\0"
+ "GL_TRANSPOSE_MODELVIEW_MATRIX\0"
+ "GL_TRANSPOSE_MODELVIEW_MATRIX_ARB\0"
+ "GL_TRANSPOSE_NV\0"
+ "GL_TRANSPOSE_PROJECTION_MATRIX\0"
+ "GL_TRANSPOSE_PROJECTION_MATRIX_ARB\0"
+ "GL_TRANSPOSE_TEXTURE_MATRIX\0"
+ "GL_TRANSPOSE_TEXTURE_MATRIX_ARB\0"
+ "GL_TRIANGLES\0"
+ "GL_TRIANGLE_FAN\0"
+ "GL_TRIANGLE_MESH_SUN\0"
+ "GL_TRIANGLE_STRIP\0"
+ "GL_TRUE\0"
+ "GL_UNPACK_ALIGNMENT\0"
+ "GL_UNPACK_IMAGE_HEIGHT\0"
+ "GL_UNPACK_LSB_FIRST\0"
+ "GL_UNPACK_ROW_LENGTH\0"
+ "GL_UNPACK_SKIP_IMAGES\0"
+ "GL_UNPACK_SKIP_PIXELS\0"
+ "GL_UNPACK_SKIP_ROWS\0"
+ "GL_UNPACK_SWAP_BYTES\0"
+ "GL_UNSIGNED_BYTE\0"
+ "GL_UNSIGNED_BYTE_2_3_3_REV\0"
+ "GL_UNSIGNED_BYTE_3_3_2\0"
+ "GL_UNSIGNED_INT\0"
+ "GL_UNSIGNED_INT_10_10_10_2\0"
+ "GL_UNSIGNED_INT_24_8_NV\0"
+ "GL_UNSIGNED_INT_2_10_10_10_REV\0"
+ "GL_UNSIGNED_INT_8_8_8_8\0"
+ "GL_UNSIGNED_INT_8_8_8_8_REV\0"
+ "GL_UNSIGNED_SHORT\0"
+ "GL_UNSIGNED_SHORT_1_5_5_5_REV\0"
+ "GL_UNSIGNED_SHORT_4_4_4_4\0"
+ "GL_UNSIGNED_SHORT_4_4_4_4_REV\0"
+ "GL_UNSIGNED_SHORT_5_5_5_1\0"
+ "GL_UNSIGNED_SHORT_5_6_5\0"
+ "GL_UNSIGNED_SHORT_5_6_5_REV\0"
+ "GL_UNSIGNED_SHORT_8_8_APPLE\0"
+ "GL_UNSIGNED_SHORT_8_8_MESA\0"
+ "GL_UNSIGNED_SHORT_8_8_REV_APPLE\0"
+ "GL_UNSIGNED_SHORT_8_8_REV_MESA\0"
+ "GL_V2F\0"
+ "GL_V3F\0"
+ "GL_VENDOR\0"
+ "GL_VERSION\0"
+ "GL_VERTEX_ARRAY\0"
+ "GL_VERTEX_ARRAY_BUFFER_BINDING\0"
+ "GL_VERTEX_ARRAY_BUFFER_BINDING_ARB\0"
+ "GL_VERTEX_ARRAY_POINTER\0"
+ "GL_VERTEX_ARRAY_SIZE\0"
+ "GL_VERTEX_ARRAY_STRIDE\0"
+ "GL_VERTEX_ARRAY_TYPE\0"
+ "GL_VERTEX_ATTRIB_ARRAY0_NV\0"
+ "GL_VERTEX_ATTRIB_ARRAY10_NV\0"
+ "GL_VERTEX_ATTRIB_ARRAY11_NV\0"
+ "GL_VERTEX_ATTRIB_ARRAY12_NV\0"
+ "GL_VERTEX_ATTRIB_ARRAY13_NV\0"
+ "GL_VERTEX_ATTRIB_ARRAY14_NV\0"
+ "GL_VERTEX_ATTRIB_ARRAY15_NV\0"
+ "GL_VERTEX_ATTRIB_ARRAY1_NV\0"
+ "GL_VERTEX_ATTRIB_ARRAY2_NV\0"
+ "GL_VERTEX_ATTRIB_ARRAY3_NV\0"
+ "GL_VERTEX_ATTRIB_ARRAY4_NV\0"
+ "GL_VERTEX_ATTRIB_ARRAY5_NV\0"
+ "GL_VERTEX_ATTRIB_ARRAY6_NV\0"
+ "GL_VERTEX_ATTRIB_ARRAY7_NV\0"
+ "GL_VERTEX_ATTRIB_ARRAY8_NV\0"
+ "GL_VERTEX_ATTRIB_ARRAY9_NV\0"
+ "GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING\0"
+ "GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB\0"
+ "GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB\0"
+ "GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB\0"
+ "GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB\0"
+ "GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB\0"
+ "GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB\0"
+ "GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB\0"
+ "GL_VERTEX_BLEND_ARB\0"
+ "GL_VERTEX_PROGRAM_ARB\0"
+ "GL_VERTEX_PROGRAM_BINDING_NV\0"
+ "GL_VERTEX_PROGRAM_NV\0"
+ "GL_VERTEX_PROGRAM_POINT_SIZE_ARB\0"
+ "GL_VERTEX_PROGRAM_POINT_SIZE_NV\0"
+ "GL_VERTEX_PROGRAM_TWO_SIDE_ARB\0"
+ "GL_VERTEX_PROGRAM_TWO_SIDE_NV\0"
+ "GL_VERTEX_SHADER_ARB\0"
+ "GL_VERTEX_STATE_PROGRAM_NV\0"
+ "GL_VIEWPORT\0"
+ "GL_VIEWPORT_BIT\0"
+ "GL_WEIGHT_ARRAY_ARB\0"
+ "GL_WEIGHT_ARRAY_BUFFER_BINDING\0"
+ "GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB\0"
+ "GL_WEIGHT_ARRAY_POINTER_ARB\0"
+ "GL_WEIGHT_ARRAY_SIZE_ARB\0"
+ "GL_WEIGHT_ARRAY_STRIDE_ARB\0"
+ "GL_WEIGHT_ARRAY_TYPE_ARB\0"
+ "GL_WEIGHT_SUM_UNITY_ARB\0"
+ "GL_WRAP_BORDER_SUN\0"
+ "GL_WRITE_ONLY\0"
+ "GL_WRITE_ONLY_ARB\0"
+ "GL_XOR\0"
+ "GL_YCBCR_422_APPLE\0"
+ "GL_YCBCR_MESA\0"
+ "GL_ZERO\0"
+ "GL_ZOOM_X\0"
+ "GL_ZOOM_Y\0"
+ ;
+
+static const enum_elt all_enums[1617] =
+{
+ { 0, 0x00000600 }, /* GL_2D */
+ { 6, 0x00001407 }, /* GL_2_BYTES */
+ { 17, 0x00000601 }, /* GL_3D */
+ { 23, 0x00000602 }, /* GL_3D_COLOR */
+ { 35, 0x00000603 }, /* GL_3D_COLOR_TEXTURE */
+ { 55, 0x00001408 }, /* GL_3_BYTES */
+ { 66, 0x00000604 }, /* GL_4D_COLOR_TEXTURE */
+ { 86, 0x00001409 }, /* GL_4_BYTES */
+ { 97, 0x00000100 }, /* GL_ACCUM */
+ { 106, 0x00000D5B }, /* GL_ACCUM_ALPHA_BITS */
+ { 126, 0x00000D5A }, /* GL_ACCUM_BLUE_BITS */
+ { 145, 0x00000200 }, /* GL_ACCUM_BUFFER_BIT */
+ { 165, 0x00000B80 }, /* GL_ACCUM_CLEAR_VALUE */
+ { 186, 0x00000D59 }, /* GL_ACCUM_GREEN_BITS */
+ { 206, 0x00000D58 }, /* GL_ACCUM_RED_BITS */
+ { 224, 0x00008911 }, /* GL_ACTIVE_STENCIL_FACE_EXT */
+ { 251, 0x000084E0 }, /* GL_ACTIVE_TEXTURE */
+ { 269, 0x000084E0 }, /* GL_ACTIVE_TEXTURE_ARB */
+ { 291, 0x000086A5 }, /* GL_ACTIVE_VERTEX_UNITS_ARB */
+ { 318, 0x00000104 }, /* GL_ADD */
+ { 325, 0x00008574 }, /* GL_ADD_SIGNED */
+ { 339, 0x00008574 }, /* GL_ADD_SIGNED_ARB */
+ { 357, 0x00008574 }, /* GL_ADD_SIGNED_EXT */
+ { 375, 0x0000846E }, /* GL_ALIASED_LINE_WIDTH_RANGE */
+ { 403, 0x0000846D }, /* GL_ALIASED_POINT_SIZE_RANGE */
+ { 431, 0x000FFFFF }, /* GL_ALL_ATTRIB_BITS */
+ { 450, 0xFFFFFFFF }, /* GL_ALL_CLIENT_ATTRIB_BITS */
+ { 476, 0x00001906 }, /* GL_ALPHA */
+ { 485, 0x0000803D }, /* GL_ALPHA12 */
+ { 496, 0x0000803D }, /* GL_ALPHA12_EXT */
+ { 511, 0x0000803E }, /* GL_ALPHA16 */
+ { 522, 0x0000803E }, /* GL_ALPHA16_EXT */
+ { 537, 0x0000803B }, /* GL_ALPHA4 */
+ { 547, 0x0000803B }, /* GL_ALPHA4_EXT */
+ { 561, 0x0000803C }, /* GL_ALPHA8 */
+ { 571, 0x0000803C }, /* GL_ALPHA8_EXT */
+ { 585, 0x00000D1D }, /* GL_ALPHA_BIAS */
+ { 599, 0x00000D55 }, /* GL_ALPHA_BITS */
+ { 613, 0x00000D1C }, /* GL_ALPHA_SCALE */
+ { 628, 0x00000BC0 }, /* GL_ALPHA_TEST */
+ { 642, 0x00000BC1 }, /* GL_ALPHA_TEST_FUNC */
+ { 661, 0x00000BC2 }, /* GL_ALPHA_TEST_REF */
+ { 679, 0x00000207 }, /* GL_ALWAYS */
+ { 689, 0x00001200 }, /* GL_AMBIENT */
+ { 700, 0x00001602 }, /* GL_AMBIENT_AND_DIFFUSE */
+ { 723, 0x00001501 }, /* GL_AND */
+ { 730, 0x00001504 }, /* GL_AND_INVERTED */
+ { 746, 0x00001502 }, /* GL_AND_REVERSE */
+ { 761, 0x00008892 }, /* GL_ARRAY_BUFFER */
+ { 777, 0x00008892 }, /* GL_ARRAY_BUFFER_ARB */
+ { 797, 0x00008894 }, /* GL_ARRAY_BUFFER_BINDING */
+ { 821, 0x00008894 }, /* GL_ARRAY_BUFFER_BINDING_ARB */
+ { 849, 0x00008645 }, /* GL_ATTRIB_ARRAY_POINTER_NV */
+ { 876, 0x00008623 }, /* GL_ATTRIB_ARRAY_SIZE_NV */
+ { 900, 0x00008624 }, /* GL_ATTRIB_ARRAY_STRIDE_NV */
+ { 926, 0x00008625 }, /* GL_ATTRIB_ARRAY_TYPE_NV */
+ { 950, 0x00000BB0 }, /* GL_ATTRIB_STACK_DEPTH */
+ { 972, 0x00000D80 }, /* GL_AUTO_NORMAL */
+ { 987, 0x00000409 }, /* GL_AUX0 */
+ { 995, 0x0000040A }, /* GL_AUX1 */
+ { 1003, 0x0000040B }, /* GL_AUX2 */
+ { 1011, 0x0000040C }, /* GL_AUX3 */
+ { 1019, 0x00000C00 }, /* GL_AUX_BUFFERS */
+ { 1034, 0x00000405 }, /* GL_BACK */
+ { 1042, 0x00000402 }, /* GL_BACK_LEFT */
+ { 1055, 0x00000403 }, /* GL_BACK_RIGHT */
+ { 1069, 0x000080E0 }, /* GL_BGR */
+ { 1076, 0x000080E1 }, /* GL_BGRA */
+ { 1084, 0x00001A00 }, /* GL_BITMAP */
+ { 1094, 0x00000704 }, /* GL_BITMAP_TOKEN */
+ { 1110, 0x00000BE2 }, /* GL_BLEND */
+ { 1119, 0x00008005 }, /* GL_BLEND_COLOR */
+ { 1134, 0x00008005 }, /* GL_BLEND_COLOR_EXT */
+ { 1153, 0x00000BE0 }, /* GL_BLEND_DST */
+ { 1166, 0x000080CA }, /* GL_BLEND_DST_ALPHA */
+ { 1185, 0x000080C8 }, /* GL_BLEND_DST_RGB */
+ { 1202, 0x00008009 }, /* GL_BLEND_EQUATION */
+ { 1220, 0x0000883D }, /* GL_BLEND_EQUATION_ALPHA_EXT */
+ { 1248, 0x00008009 }, /* GL_BLEND_EQUATION_EXT */
+ { 1270, 0x00008009 }, /* GL_BLEND_EQUATION_RGB_EXT */
+ { 1296, 0x00000BE1 }, /* GL_BLEND_SRC */
+ { 1309, 0x000080CB }, /* GL_BLEND_SRC_ALPHA */
+ { 1328, 0x000080C9 }, /* GL_BLEND_SRC_RGB */
+ { 1345, 0x00001905 }, /* GL_BLUE */
+ { 1353, 0x00000D1B }, /* GL_BLUE_BIAS */
+ { 1366, 0x00000D54 }, /* GL_BLUE_BITS */
+ { 1379, 0x00000D1A }, /* GL_BLUE_SCALE */
+ { 1393, 0x00008B56 }, /* GL_BOOL_ARB */
+ { 1405, 0x00008B57 }, /* GL_BOOL_VEC2_ARB */
+ { 1422, 0x00008B58 }, /* GL_BOOL_VEC3_ARB */
+ { 1439, 0x00008B59 }, /* GL_BOOL_VEC4_ARB */
+ { 1456, 0x000088BB }, /* GL_BUFFER_ACCESS */
+ { 1473, 0x000088BB }, /* GL_BUFFER_ACCESS_ARB */
+ { 1494, 0x000088BC }, /* GL_BUFFER_MAPPED */
+ { 1511, 0x000088BC }, /* GL_BUFFER_MAPPED_ARB */
+ { 1532, 0x000088BD }, /* GL_BUFFER_MAP_POINTER */
+ { 1554, 0x000088BD }, /* GL_BUFFER_MAP_POINTER_ARB */
+ { 1580, 0x00008764 }, /* GL_BUFFER_SIZE */
+ { 1595, 0x00008764 }, /* GL_BUFFER_SIZE_ARB */
+ { 1614, 0x00008765 }, /* GL_BUFFER_USAGE */
+ { 1630, 0x00008765 }, /* GL_BUFFER_USAGE_ARB */
+ { 1650, 0x00001400 }, /* GL_BYTE */
+ { 1658, 0x00002A24 }, /* GL_C3F_V3F */
+ { 1669, 0x00002A26 }, /* GL_C4F_N3F_V3F */
+ { 1684, 0x00002A22 }, /* GL_C4UB_V2F */
+ { 1696, 0x00002A23 }, /* GL_C4UB_V3F */
+ { 1708, 0x00000901 }, /* GL_CCW */
+ { 1715, 0x00002900 }, /* GL_CLAMP */
+ { 1724, 0x0000812D }, /* GL_CLAMP_TO_BORDER */
+ { 1743, 0x0000812D }, /* GL_CLAMP_TO_BORDER_ARB */
+ { 1766, 0x0000812D }, /* GL_CLAMP_TO_BORDER_SGIS */
+ { 1790, 0x0000812F }, /* GL_CLAMP_TO_EDGE */
+ { 1807, 0x0000812F }, /* GL_CLAMP_TO_EDGE_SGIS */
+ { 1829, 0x00001500 }, /* GL_CLEAR */
+ { 1838, 0x000084E1 }, /* GL_CLIENT_ACTIVE_TEXTURE */
+ { 1863, 0x000084E1 }, /* GL_CLIENT_ACTIVE_TEXTURE_ARB */
+ { 1892, 0xFFFFFFFF }, /* GL_CLIENT_ALL_ATTRIB_BITS */
+ { 1918, 0x00000BB1 }, /* GL_CLIENT_ATTRIB_STACK_DEPTH */
+ { 1947, 0x00000001 }, /* GL_CLIENT_PIXEL_STORE_BIT */
+ { 1973, 0x00000002 }, /* GL_CLIENT_VERTEX_ARRAY_BIT */
+ { 2000, 0x00003000 }, /* GL_CLIP_PLANE0 */
+ { 2015, 0x00003001 }, /* GL_CLIP_PLANE1 */
+ { 2030, 0x00003002 }, /* GL_CLIP_PLANE2 */
+ { 2045, 0x00003003 }, /* GL_CLIP_PLANE3 */
+ { 2060, 0x00003004 }, /* GL_CLIP_PLANE4 */
+ { 2075, 0x00003005 }, /* GL_CLIP_PLANE5 */
+ { 2090, 0x000080F0 }, /* GL_CLIP_VOLUME_CLIPPING_HINT_EXT */
+ { 2123, 0x00000A00 }, /* GL_COEFF */
+ { 2132, 0x00001800 }, /* GL_COLOR */
+ { 2141, 0x00008076 }, /* GL_COLOR_ARRAY */
+ { 2156, 0x00008898 }, /* GL_COLOR_ARRAY_BUFFER_BINDING */
+ { 2186, 0x00008898 }, /* GL_COLOR_ARRAY_BUFFER_BINDING_ARB */
+ { 2220, 0x00008090 }, /* GL_COLOR_ARRAY_POINTER */
+ { 2243, 0x00008081 }, /* GL_COLOR_ARRAY_SIZE */
+ { 2263, 0x00008083 }, /* GL_COLOR_ARRAY_STRIDE */
+ { 2285, 0x00008082 }, /* GL_COLOR_ARRAY_TYPE */
+ { 2305, 0x00008CE0 }, /* GL_COLOR_ATTACHMENT0_EXT */
+ { 2330, 0x00008CEA }, /* GL_COLOR_ATTACHMENT10_EXT */
+ { 2356, 0x00008CEB }, /* GL_COLOR_ATTACHMENT11_EXT */
+ { 2382, 0x00008CEC }, /* GL_COLOR_ATTACHMENT12_EXT */
+ { 2408, 0x00008CED }, /* GL_COLOR_ATTACHMENT13_EXT */
+ { 2434, 0x00008CEE }, /* GL_COLOR_ATTACHMENT14_EXT */
+ { 2460, 0x00008CEF }, /* GL_COLOR_ATTACHMENT15_EXT */
+ { 2486, 0x00008CE1 }, /* GL_COLOR_ATTACHMENT1_EXT */
+ { 2511, 0x00008CE2 }, /* GL_COLOR_ATTACHMENT2_EXT */
+ { 2536, 0x00008CE3 }, /* GL_COLOR_ATTACHMENT3_EXT */
+ { 2561, 0x00008CE4 }, /* GL_COLOR_ATTACHMENT4_EXT */
+ { 2586, 0x00008CE5 }, /* GL_COLOR_ATTACHMENT5_EXT */
+ { 2611, 0x00008CE6 }, /* GL_COLOR_ATTACHMENT6_EXT */
+ { 2636, 0x00008CE7 }, /* GL_COLOR_ATTACHMENT7_EXT */
+ { 2661, 0x00008CE8 }, /* GL_COLOR_ATTACHMENT8_EXT */
+ { 2686, 0x00008CE9 }, /* GL_COLOR_ATTACHMENT9_EXT */
+ { 2711, 0x00004000 }, /* GL_COLOR_BUFFER_BIT */
+ { 2731, 0x00000C22 }, /* GL_COLOR_CLEAR_VALUE */
+ { 2752, 0x00001900 }, /* GL_COLOR_INDEX */
+ { 2767, 0x00001603 }, /* GL_COLOR_INDEXES */
+ { 2784, 0x00000BF2 }, /* GL_COLOR_LOGIC_OP */
+ { 2802, 0x00000B57 }, /* GL_COLOR_MATERIAL */
+ { 2820, 0x00000B55 }, /* GL_COLOR_MATERIAL_FACE */
+ { 2843, 0x00000B56 }, /* GL_COLOR_MATERIAL_PARAMETER */
+ { 2871, 0x000080B1 }, /* GL_COLOR_MATRIX */
+ { 2887, 0x000080B1 }, /* GL_COLOR_MATRIX_SGI */
+ { 2907, 0x000080B2 }, /* GL_COLOR_MATRIX_STACK_DEPTH */
+ { 2935, 0x000080B2 }, /* GL_COLOR_MATRIX_STACK_DEPTH_SGI */
+ { 2967, 0x00008458 }, /* GL_COLOR_SUM */
+ { 2980, 0x00008458 }, /* GL_COLOR_SUM_ARB */
+ { 2997, 0x000080D0 }, /* GL_COLOR_TABLE */
+ { 3012, 0x000080DD }, /* GL_COLOR_TABLE_ALPHA_SIZE */
+ { 3038, 0x000080DD }, /* GL_COLOR_TABLE_ALPHA_SIZE_EXT */
+ { 3068, 0x000080D7 }, /* GL_COLOR_TABLE_BIAS */
+ { 3088, 0x000080DC }, /* GL_COLOR_TABLE_BLUE_SIZE */
+ { 3113, 0x000080DC }, /* GL_COLOR_TABLE_BLUE_SIZE_EXT */
+ { 3142, 0x000080D8 }, /* GL_COLOR_TABLE_FORMAT */
+ { 3164, 0x000080D8 }, /* GL_COLOR_TABLE_FORMAT_EXT */
+ { 3190, 0x000080DB }, /* GL_COLOR_TABLE_GREEN_SIZE */
+ { 3216, 0x000080DB }, /* GL_COLOR_TABLE_GREEN_SIZE_EXT */
+ { 3246, 0x000080DF }, /* GL_COLOR_TABLE_INTENSITY_SIZE */
+ { 3276, 0x000080DF }, /* GL_COLOR_TABLE_INTENSITY_SIZE_EXT */
+ { 3310, 0x000080DE }, /* GL_COLOR_TABLE_LUMINANCE_SIZE */
+ { 3340, 0x000080DE }, /* GL_COLOR_TABLE_LUMINANCE_SIZE_EXT */
+ { 3374, 0x000080DA }, /* GL_COLOR_TABLE_RED_SIZE */
+ { 3398, 0x000080DA }, /* GL_COLOR_TABLE_RED_SIZE_EXT */
+ { 3426, 0x000080D6 }, /* GL_COLOR_TABLE_SCALE */
+ { 3447, 0x000080D9 }, /* GL_COLOR_TABLE_WIDTH */
+ { 3468, 0x000080D9 }, /* GL_COLOR_TABLE_WIDTH_EXT */
+ { 3493, 0x00000C23 }, /* GL_COLOR_WRITEMASK */
+ { 3512, 0x00008570 }, /* GL_COMBINE */
+ { 3523, 0x00008503 }, /* GL_COMBINE4 */
+ { 3535, 0x00008572 }, /* GL_COMBINE_ALPHA */
+ { 3552, 0x00008572 }, /* GL_COMBINE_ALPHA_ARB */
+ { 3573, 0x00008572 }, /* GL_COMBINE_ALPHA_EXT */
+ { 3594, 0x00008570 }, /* GL_COMBINE_ARB */
+ { 3609, 0x00008570 }, /* GL_COMBINE_EXT */
+ { 3624, 0x00008571 }, /* GL_COMBINE_RGB */
+ { 3639, 0x00008571 }, /* GL_COMBINE_RGB_ARB */
+ { 3658, 0x00008571 }, /* GL_COMBINE_RGB_EXT */
+ { 3677, 0x0000884E }, /* GL_COMPARE_R_TO_TEXTURE */
+ { 3701, 0x0000884E }, /* GL_COMPARE_R_TO_TEXTURE_ARB */
+ { 3729, 0x00001300 }, /* GL_COMPILE */
+ { 3740, 0x00001301 }, /* GL_COMPILE_AND_EXECUTE */
+ { 3763, 0x000084E9 }, /* GL_COMPRESSED_ALPHA */
+ { 3783, 0x000084E9 }, /* GL_COMPRESSED_ALPHA_ARB */
+ { 3807, 0x000084EC }, /* GL_COMPRESSED_INTENSITY */
+ { 3831, 0x000084EC }, /* GL_COMPRESSED_INTENSITY_ARB */
+ { 3859, 0x000084EA }, /* GL_COMPRESSED_LUMINANCE */
+ { 3883, 0x000084EB }, /* GL_COMPRESSED_LUMINANCE_ALPHA */
+ { 3913, 0x000084EB }, /* GL_COMPRESSED_LUMINANCE_ALPHA_ARB */
+ { 3947, 0x000084EA }, /* GL_COMPRESSED_LUMINANCE_ARB */
+ { 3975, 0x000084ED }, /* GL_COMPRESSED_RGB */
+ { 3993, 0x000084EE }, /* GL_COMPRESSED_RGBA */
+ { 4012, 0x000084EE }, /* GL_COMPRESSED_RGBA_ARB */
+ { 4035, 0x000086B1 }, /* GL_COMPRESSED_RGBA_FXT1_3DFX */
+ { 4064, 0x000083F1 }, /* GL_COMPRESSED_RGBA_S3TC_DXT1_EXT */
+ { 4097, 0x000083F2 }, /* GL_COMPRESSED_RGBA_S3TC_DXT3_EXT */
+ { 4130, 0x000083F3 }, /* GL_COMPRESSED_RGBA_S3TC_DXT5_EXT */
+ { 4163, 0x000084ED }, /* GL_COMPRESSED_RGB_ARB */
+ { 4185, 0x000086B0 }, /* GL_COMPRESSED_RGB_FXT1_3DFX */
+ { 4213, 0x000083F0 }, /* GL_COMPRESSED_RGB_S3TC_DXT1_EXT */
+ { 4245, 0x000086A3 }, /* GL_COMPRESSED_TEXTURE_FORMATS */
+ { 4275, 0x00008576 }, /* GL_CONSTANT */
+ { 4287, 0x00008003 }, /* GL_CONSTANT_ALPHA */
+ { 4305, 0x00008003 }, /* GL_CONSTANT_ALPHA_EXT */
+ { 4327, 0x00008576 }, /* GL_CONSTANT_ARB */
+ { 4343, 0x00001207 }, /* GL_CONSTANT_ATTENUATION */
+ { 4367, 0x00008151 }, /* GL_CONSTANT_BORDER_HP */
+ { 4389, 0x00008001 }, /* GL_CONSTANT_COLOR */
+ { 4407, 0x00008001 }, /* GL_CONSTANT_COLOR_EXT */
+ { 4429, 0x00008576 }, /* GL_CONSTANT_EXT */
+ { 4445, 0x00008010 }, /* GL_CONVOLUTION_1D */
+ { 4463, 0x00008011 }, /* GL_CONVOLUTION_2D */
+ { 4481, 0x00008154 }, /* GL_CONVOLUTION_BORDER_COLOR */
+ { 4509, 0x00008154 }, /* GL_CONVOLUTION_BORDER_COLOR_HP */
+ { 4540, 0x00008013 }, /* GL_CONVOLUTION_BORDER_MODE */
+ { 4567, 0x00008013 }, /* GL_CONVOLUTION_BORDER_MODE_EXT */
+ { 4598, 0x00008015 }, /* GL_CONVOLUTION_FILTER_BIAS */
+ { 4625, 0x00008015 }, /* GL_CONVOLUTION_FILTER_BIAS_EXT */
+ { 4656, 0x00008014 }, /* GL_CONVOLUTION_FILTER_SCALE */
+ { 4684, 0x00008014 }, /* GL_CONVOLUTION_FILTER_SCALE_EXT */
+ { 4716, 0x00008017 }, /* GL_CONVOLUTION_FORMAT */
+ { 4738, 0x00008017 }, /* GL_CONVOLUTION_FORMAT_EXT */
+ { 4764, 0x00008019 }, /* GL_CONVOLUTION_HEIGHT */
+ { 4786, 0x00008019 }, /* GL_CONVOLUTION_HEIGHT_EXT */
+ { 4812, 0x00008018 }, /* GL_CONVOLUTION_WIDTH */
+ { 4833, 0x00008018 }, /* GL_CONVOLUTION_WIDTH_EXT */
+ { 4858, 0x00008862 }, /* GL_COORD_REPLACE_ARB */
+ { 4879, 0x00008862 }, /* GL_COORD_REPLACE_NV */
+ { 4899, 0x00001503 }, /* GL_COPY */
+ { 4907, 0x0000150C }, /* GL_COPY_INVERTED */
+ { 4924, 0x00000706 }, /* GL_COPY_PIXEL_TOKEN */
+ { 4944, 0x00000B44 }, /* GL_CULL_FACE */
+ { 4957, 0x00000B45 }, /* GL_CULL_FACE_MODE */
+ { 4975, 0x000081AA }, /* GL_CULL_VERTEX_EXT */
+ { 4994, 0x000081AC }, /* GL_CULL_VERTEX_EYE_POSITION_EXT */
+ { 5026, 0x000081AB }, /* GL_CULL_VERTEX_OBJECT_POSITION_EXT */
+ { 5061, 0x00008626 }, /* GL_CURRENT_ATTRIB_NV */
+ { 5082, 0x00000001 }, /* GL_CURRENT_BIT */
+ { 5097, 0x00000B00 }, /* GL_CURRENT_COLOR */
+ { 5114, 0x00008453 }, /* GL_CURRENT_FOG_COORD */
+ { 5135, 0x00008453 }, /* GL_CURRENT_FOG_COORDINATE */
+ { 5161, 0x00000B01 }, /* GL_CURRENT_INDEX */
+ { 5178, 0x00008641 }, /* GL_CURRENT_MATRIX_ARB */
+ { 5200, 0x00008845 }, /* GL_CURRENT_MATRIX_INDEX_ARB */
+ { 5228, 0x00008641 }, /* GL_CURRENT_MATRIX_NV */
+ { 5249, 0x00008640 }, /* GL_CURRENT_MATRIX_STACK_DEPTH_ARB */
+ { 5283, 0x00008640 }, /* GL_CURRENT_MATRIX_STACK_DEPTH_NV */
+ { 5316, 0x00000B02 }, /* GL_CURRENT_NORMAL */
+ { 5334, 0x00008843 }, /* GL_CURRENT_PALETTE_MATRIX_ARB */
+ { 5364, 0x00008865 }, /* GL_CURRENT_QUERY */
+ { 5381, 0x00008865 }, /* GL_CURRENT_QUERY_ARB */
+ { 5402, 0x00000B04 }, /* GL_CURRENT_RASTER_COLOR */
+ { 5426, 0x00000B09 }, /* GL_CURRENT_RASTER_DISTANCE */
+ { 5453, 0x00000B05 }, /* GL_CURRENT_RASTER_INDEX */
+ { 5477, 0x00000B07 }, /* GL_CURRENT_RASTER_POSITION */
+ { 5504, 0x00000B08 }, /* GL_CURRENT_RASTER_POSITION_VALID */
+ { 5537, 0x00000B06 }, /* GL_CURRENT_RASTER_TEXTURE_COORDS */
+ { 5570, 0x00008459 }, /* GL_CURRENT_SECONDARY_COLOR */
+ { 5597, 0x00000B03 }, /* GL_CURRENT_TEXTURE_COORDS */
+ { 5623, 0x00008626 }, /* GL_CURRENT_VERTEX_ATTRIB_ARB */
+ { 5652, 0x000086A8 }, /* GL_CURRENT_WEIGHT_ARB */
+ { 5674, 0x00000900 }, /* GL_CW */
+ { 5680, 0x00002101 }, /* GL_DECAL */
+ { 5689, 0x00001E03 }, /* GL_DECR */
+ { 5697, 0x00008508 }, /* GL_DECR_WRAP */
+ { 5710, 0x00008508 }, /* GL_DECR_WRAP_EXT */
+ { 5727, 0x00001801 }, /* GL_DEPTH */
+ { 5736, 0x00008D00 }, /* GL_DEPTH_ATTACHMENT_EXT */
+ { 5760, 0x00000D1F }, /* GL_DEPTH_BIAS */
+ { 5774, 0x00000D56 }, /* GL_DEPTH_BITS */
+ { 5788, 0x00008891 }, /* GL_DEPTH_BOUNDS_EXT */
+ { 5808, 0x00008890 }, /* GL_DEPTH_BOUNDS_TEST_EXT */
+ { 5833, 0x00000100 }, /* GL_DEPTH_BUFFER_BIT */
+ { 5853, 0x0000864F }, /* GL_DEPTH_CLAMP_NV */
+ { 5871, 0x00000B73 }, /* GL_DEPTH_CLEAR_VALUE */
+ { 5892, 0x00001902 }, /* GL_DEPTH_COMPONENT */
+ { 5911, 0x000081A5 }, /* GL_DEPTH_COMPONENT16 */
+ { 5932, 0x000081A5 }, /* GL_DEPTH_COMPONENT16_ARB */
+ { 5957, 0x000081A5 }, /* GL_DEPTH_COMPONENT16_SGIX */
+ { 5983, 0x000081A6 }, /* GL_DEPTH_COMPONENT24 */
+ { 6004, 0x000081A6 }, /* GL_DEPTH_COMPONENT24_ARB */
+ { 6029, 0x000081A6 }, /* GL_DEPTH_COMPONENT24_SGIX */
+ { 6055, 0x000081A7 }, /* GL_DEPTH_COMPONENT32 */
+ { 6076, 0x000081A7 }, /* GL_DEPTH_COMPONENT32_ARB */
+ { 6101, 0x000081A7 }, /* GL_DEPTH_COMPONENT32_SGIX */
+ { 6127, 0x00000B74 }, /* GL_DEPTH_FUNC */
+ { 6141, 0x00000B70 }, /* GL_DEPTH_RANGE */
+ { 6156, 0x00000D1E }, /* GL_DEPTH_SCALE */
+ { 6171, 0x000084F9 }, /* GL_DEPTH_STENCIL_NV */
+ { 6191, 0x0000886F }, /* GL_DEPTH_STENCIL_TO_BGRA_NV */
+ { 6219, 0x0000886E }, /* GL_DEPTH_STENCIL_TO_RGBA_NV */
+ { 6247, 0x00000B71 }, /* GL_DEPTH_TEST */
+ { 6261, 0x0000884B }, /* GL_DEPTH_TEXTURE_MODE */
+ { 6283, 0x0000884B }, /* GL_DEPTH_TEXTURE_MODE_ARB */
+ { 6309, 0x00000B72 }, /* GL_DEPTH_WRITEMASK */
+ { 6328, 0x00001201 }, /* GL_DIFFUSE */
+ { 6339, 0x00000BD0 }, /* GL_DITHER */
+ { 6349, 0x00000A02 }, /* GL_DOMAIN */
+ { 6359, 0x00001100 }, /* GL_DONT_CARE */
+ { 6372, 0x000086AE }, /* GL_DOT3_RGB */
+ { 6384, 0x000086AF }, /* GL_DOT3_RGBA */
+ { 6397, 0x000086AF }, /* GL_DOT3_RGBA_ARB */
+ { 6414, 0x00008741 }, /* GL_DOT3_RGBA_EXT */
+ { 6431, 0x000086AE }, /* GL_DOT3_RGB_ARB */
+ { 6447, 0x00008740 }, /* GL_DOT3_RGB_EXT */
+ { 6463, 0x0000140A }, /* GL_DOUBLE */
+ { 6473, 0x00000C32 }, /* GL_DOUBLEBUFFER */
+ { 6489, 0x00000C01 }, /* GL_DRAW_BUFFER */
+ { 6504, 0x00008825 }, /* GL_DRAW_BUFFER0_ARB */
+ { 6524, 0x00008825 }, /* GL_DRAW_BUFFER0_ATI */
+ { 6544, 0x0000882F }, /* GL_DRAW_BUFFER10_ARB */
+ { 6565, 0x0000882F }, /* GL_DRAW_BUFFER10_ATI */
+ { 6586, 0x00008830 }, /* GL_DRAW_BUFFER11_ARB */
+ { 6607, 0x00008830 }, /* GL_DRAW_BUFFER11_ATI */
+ { 6628, 0x00008831 }, /* GL_DRAW_BUFFER12_ARB */
+ { 6649, 0x00008831 }, /* GL_DRAW_BUFFER12_ATI */
+ { 6670, 0x00008832 }, /* GL_DRAW_BUFFER13_ARB */
+ { 6691, 0x00008832 }, /* GL_DRAW_BUFFER13_ATI */
+ { 6712, 0x00008833 }, /* GL_DRAW_BUFFER14_ARB */
+ { 6733, 0x00008833 }, /* GL_DRAW_BUFFER14_ATI */
+ { 6754, 0x00008834 }, /* GL_DRAW_BUFFER15_ARB */
+ { 6775, 0x00008834 }, /* GL_DRAW_BUFFER15_ATI */
+ { 6796, 0x00008826 }, /* GL_DRAW_BUFFER1_ARB */
+ { 6816, 0x00008826 }, /* GL_DRAW_BUFFER1_ATI */
+ { 6836, 0x00008827 }, /* GL_DRAW_BUFFER2_ARB */
+ { 6856, 0x00008827 }, /* GL_DRAW_BUFFER2_ATI */
+ { 6876, 0x00008828 }, /* GL_DRAW_BUFFER3_ARB */
+ { 6896, 0x00008828 }, /* GL_DRAW_BUFFER3_ATI */
+ { 6916, 0x00008829 }, /* GL_DRAW_BUFFER4_ARB */
+ { 6936, 0x00008829 }, /* GL_DRAW_BUFFER4_ATI */
+ { 6956, 0x0000882A }, /* GL_DRAW_BUFFER5_ARB */
+ { 6976, 0x0000882A }, /* GL_DRAW_BUFFER5_ATI */
+ { 6996, 0x0000882B }, /* GL_DRAW_BUFFER6_ARB */
+ { 7016, 0x0000882B }, /* GL_DRAW_BUFFER6_ATI */
+ { 7036, 0x0000882C }, /* GL_DRAW_BUFFER7_ARB */
+ { 7056, 0x0000882C }, /* GL_DRAW_BUFFER7_ATI */
+ { 7076, 0x0000882D }, /* GL_DRAW_BUFFER8_ARB */
+ { 7096, 0x0000882D }, /* GL_DRAW_BUFFER8_ATI */
+ { 7116, 0x0000882E }, /* GL_DRAW_BUFFER9_ARB */
+ { 7136, 0x0000882E }, /* GL_DRAW_BUFFER9_ATI */
+ { 7156, 0x00000705 }, /* GL_DRAW_PIXEL_TOKEN */
+ { 7176, 0x00000304 }, /* GL_DST_ALPHA */
+ { 7189, 0x00000306 }, /* GL_DST_COLOR */
+ { 7202, 0x000088EA }, /* GL_DYNAMIC_COPY */
+ { 7218, 0x000088EA }, /* GL_DYNAMIC_COPY_ARB */
+ { 7238, 0x000088E8 }, /* GL_DYNAMIC_DRAW */
+ { 7254, 0x000088E8 }, /* GL_DYNAMIC_DRAW_ARB */
+ { 7274, 0x000088E9 }, /* GL_DYNAMIC_READ */
+ { 7290, 0x000088E9 }, /* GL_DYNAMIC_READ_ARB */
+ { 7310, 0x00000B43 }, /* GL_EDGE_FLAG */
+ { 7323, 0x00008079 }, /* GL_EDGE_FLAG_ARRAY */
+ { 7342, 0x0000889B }, /* GL_EDGE_FLAG_ARRAY_BUFFER_BINDING */
+ { 7376, 0x0000889B }, /* GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB */
+ { 7414, 0x00008093 }, /* GL_EDGE_FLAG_ARRAY_POINTER */
+ { 7441, 0x0000808C }, /* GL_EDGE_FLAG_ARRAY_STRIDE */
+ { 7467, 0x00008893 }, /* GL_ELEMENT_ARRAY_BUFFER */
+ { 7491, 0x00008893 }, /* GL_ELEMENT_ARRAY_BUFFER_ARB */
+ { 7519, 0x00008895 }, /* GL_ELEMENT_ARRAY_BUFFER_BINDING */
+ { 7551, 0x00008895 }, /* GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB */
+ { 7587, 0x00001600 }, /* GL_EMISSION */
+ { 7599, 0x00002000 }, /* GL_ENABLE_BIT */
+ { 7613, 0x00000202 }, /* GL_EQUAL */
+ { 7622, 0x00001509 }, /* GL_EQUIV */
+ { 7631, 0x00010000 }, /* GL_EVAL_BIT */
+ { 7643, 0x00000800 }, /* GL_EXP */
+ { 7650, 0x00000801 }, /* GL_EXP2 */
+ { 7658, 0x00001F03 }, /* GL_EXTENSIONS */
+ { 7672, 0x00002400 }, /* GL_EYE_LINEAR */
+ { 7686, 0x00002502 }, /* GL_EYE_PLANE */
+ { 7699, 0x0000855C }, /* GL_EYE_PLANE_ABSOLUTE_NV */
+ { 7724, 0x0000855B }, /* GL_EYE_RADIAL_NV */
+ { 7741, 0x00000000 }, /* GL_FALSE */
+ { 7750, 0x00001101 }, /* GL_FASTEST */
+ { 7761, 0x00001C01 }, /* GL_FEEDBACK */
+ { 7773, 0x00000DF0 }, /* GL_FEEDBACK_BUFFER_POINTER */
+ { 7800, 0x00000DF1 }, /* GL_FEEDBACK_BUFFER_SIZE */
+ { 7824, 0x00000DF2 }, /* GL_FEEDBACK_BUFFER_TYPE */
+ { 7848, 0x00001B02 }, /* GL_FILL */
+ { 7856, 0x00001D00 }, /* GL_FLAT */
+ { 7864, 0x00001406 }, /* GL_FLOAT */
+ { 7873, 0x00008B5A }, /* GL_FLOAT_MAT2_ARB */
+ { 7891, 0x00008B5B }, /* GL_FLOAT_MAT3_ARB */
+ { 7909, 0x00008B5C }, /* GL_FLOAT_MAT4_ARB */
+ { 7927, 0x00008B50 }, /* GL_FLOAT_VEC2_ARB */
+ { 7945, 0x00008B51 }, /* GL_FLOAT_VEC3_ARB */
+ { 7963, 0x00008B52 }, /* GL_FLOAT_VEC4_ARB */
+ { 7981, 0x00000B60 }, /* GL_FOG */
+ { 7988, 0x00000080 }, /* GL_FOG_BIT */
+ { 7999, 0x00000B66 }, /* GL_FOG_COLOR */
+ { 8012, 0x00008451 }, /* GL_FOG_COORD */
+ { 8025, 0x00008451 }, /* GL_FOG_COORDINATE */
+ { 8043, 0x00008457 }, /* GL_FOG_COORDINATE_ARRAY */
+ { 8067, 0x0000889D }, /* GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING */
+ { 8106, 0x0000889D }, /* GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB */
+ { 8149, 0x00008456 }, /* GL_FOG_COORDINATE_ARRAY_POINTER */
+ { 8181, 0x00008455 }, /* GL_FOG_COORDINATE_ARRAY_STRIDE */
+ { 8212, 0x00008454 }, /* GL_FOG_COORDINATE_ARRAY_TYPE */
+ { 8241, 0x00008450 }, /* GL_FOG_COORDINATE_SOURCE */
+ { 8266, 0x00008457 }, /* GL_FOG_COORD_ARRAY */
+ { 8285, 0x0000889D }, /* GL_FOG_COORD_ARRAY_BUFFER_BINDING */
+ { 8319, 0x00008456 }, /* GL_FOG_COORD_ARRAY_POINTER */
+ { 8346, 0x00008455 }, /* GL_FOG_COORD_ARRAY_STRIDE */
+ { 8372, 0x00008454 }, /* GL_FOG_COORD_ARRAY_TYPE */
+ { 8396, 0x00008450 }, /* GL_FOG_COORD_SRC */
+ { 8413, 0x00000B62 }, /* GL_FOG_DENSITY */
+ { 8428, 0x0000855A }, /* GL_FOG_DISTANCE_MODE_NV */
+ { 8452, 0x00000B64 }, /* GL_FOG_END */
+ { 8463, 0x00000C54 }, /* GL_FOG_HINT */
+ { 8475, 0x00000B61 }, /* GL_FOG_INDEX */
+ { 8488, 0x00000B65 }, /* GL_FOG_MODE */
+ { 8500, 0x00008198 }, /* GL_FOG_OFFSET_SGIX */
+ { 8519, 0x00008199 }, /* GL_FOG_OFFSET_VALUE_SGIX */
+ { 8544, 0x00000B63 }, /* GL_FOG_START */
+ { 8557, 0x00008452 }, /* GL_FRAGMENT_DEPTH */
+ { 8575, 0x00008804 }, /* GL_FRAGMENT_PROGRAM_ARB */
+ { 8599, 0x00008B30 }, /* GL_FRAGMENT_SHADER_ARB */
+ { 8622, 0x00008CD1 }, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT */
+ { 8664, 0x00008CD0 }, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT */
+ { 8706, 0x00008CD4 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT */
+ { 8755, 0x00008CD3 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT */
+ { 8807, 0x00008CD2 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT */
+ { 8851, 0x00008CA6 }, /* GL_FRAMEBUFFER_BINDING_EXT */
+ { 8878, 0x00008CD5 }, /* GL_FRAMEBUFFER_COMPLETE_EXT */
+ { 8906, 0x00008D40 }, /* GL_FRAMEBUFFER_EXT */
+ { 8925, 0x00008CD6 }, /* GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT */
+ { 8966, 0x00008CD9 }, /* GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT */
+ { 9007, 0x00008CDB }, /* GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT */
+ { 9049, 0x00008CD8 }, /* GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT */
+ { 9100, 0x00008CDA }, /* GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT */
+ { 9138, 0x00008CD7 }, /* GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT */
+ { 9187, 0x00008CDC }, /* GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT */
+ { 9229, 0x00008CDE }, /* GL_FRAMEBUFFER_STATUS_ERROR_EXT */
+ { 9261, 0x00008CDD }, /* GL_FRAMEBUFFER_UNSUPPORTED_EXT */
+ { 9292, 0x00000404 }, /* GL_FRONT */
+ { 9301, 0x00000408 }, /* GL_FRONT_AND_BACK */
+ { 9319, 0x00000B46 }, /* GL_FRONT_FACE */
+ { 9333, 0x00000400 }, /* GL_FRONT_LEFT */
+ { 9347, 0x00000401 }, /* GL_FRONT_RIGHT */
+ { 9362, 0x00008006 }, /* GL_FUNC_ADD */
+ { 9374, 0x00008006 }, /* GL_FUNC_ADD_EXT */
+ { 9390, 0x0000800B }, /* GL_FUNC_REVERSE_SUBTRACT */
+ { 9415, 0x0000800B }, /* GL_FUNC_REVERSE_SUBTRACT_EXT */
+ { 9444, 0x0000800A }, /* GL_FUNC_SUBTRACT */
+ { 9461, 0x0000800A }, /* GL_FUNC_SUBTRACT_EXT */
+ { 9482, 0x00008191 }, /* GL_GENERATE_MIPMAP */
+ { 9501, 0x00008192 }, /* GL_GENERATE_MIPMAP_HINT */
+ { 9525, 0x00008192 }, /* GL_GENERATE_MIPMAP_HINT_SGIS */
+ { 9554, 0x00008191 }, /* GL_GENERATE_MIPMAP_SGIS */
+ { 9578, 0x00000206 }, /* GL_GEQUAL */
+ { 9588, 0x00008CA6 }, /* GL_GL_DRAW_FRAMEBUFFER_BINDING_EXT */
+ { 9623, 0x00008CA9 }, /* GL_GL_DRAW_FRAMEBUFFER_EXT */
+ { 9650, 0x00008CAA }, /* GL_GL_READ_FRAMEBUFFER_BINDING_EXT */
+ { 9685, 0x00008CA8 }, /* GL_GL_READ_FRAMEBUFFER_EXT */
+ { 9712, 0x000088BF }, /* GL_GL_TIME_ELAPSED_EXT */
+ { 9735, 0x00000204 }, /* GL_GREATER */
+ { 9746, 0x00001904 }, /* GL_GREEN */
+ { 9755, 0x00000D19 }, /* GL_GREEN_BIAS */
+ { 9769, 0x00000D53 }, /* GL_GREEN_BITS */
+ { 9783, 0x00000D18 }, /* GL_GREEN_SCALE */
+ { 9798, 0x00008000 }, /* GL_HINT_BIT */
+ { 9810, 0x00008024 }, /* GL_HISTOGRAM */
+ { 9823, 0x0000802B }, /* GL_HISTOGRAM_ALPHA_SIZE */
+ { 9847, 0x0000802B }, /* GL_HISTOGRAM_ALPHA_SIZE_EXT */
+ { 9875, 0x0000802A }, /* GL_HISTOGRAM_BLUE_SIZE */
+ { 9898, 0x0000802A }, /* GL_HISTOGRAM_BLUE_SIZE_EXT */
+ { 9925, 0x00008024 }, /* GL_HISTOGRAM_EXT */
+ { 9942, 0x00008027 }, /* GL_HISTOGRAM_FORMAT */
+ { 9962, 0x00008027 }, /* GL_HISTOGRAM_FORMAT_EXT */
+ { 9986, 0x00008029 }, /* GL_HISTOGRAM_GREEN_SIZE */
+ { 10010, 0x00008029 }, /* GL_HISTOGRAM_GREEN_SIZE_EXT */
+ { 10038, 0x0000802C }, /* GL_HISTOGRAM_LUMINANCE_SIZE */
+ { 10066, 0x0000802C }, /* GL_HISTOGRAM_LUMINANCE_SIZE_EXT */
+ { 10098, 0x00008028 }, /* GL_HISTOGRAM_RED_SIZE */
+ { 10120, 0x00008028 }, /* GL_HISTOGRAM_RED_SIZE_EXT */
+ { 10146, 0x0000802D }, /* GL_HISTOGRAM_SINK */
+ { 10164, 0x0000802D }, /* GL_HISTOGRAM_SINK_EXT */
+ { 10186, 0x00008026 }, /* GL_HISTOGRAM_WIDTH */
+ { 10205, 0x00008026 }, /* GL_HISTOGRAM_WIDTH_EXT */
+ { 10228, 0x0000862A }, /* GL_IDENTITY_NV */
+ { 10243, 0x00008150 }, /* GL_IGNORE_BORDER_HP */
+ { 10263, 0x00008B9B }, /* GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES */
+ { 10303, 0x00008B9A }, /* GL_IMPLEMENTATION_COLOR_READ_TYPE_OES */
+ { 10341, 0x00001E02 }, /* GL_INCR */
+ { 10349, 0x00008507 }, /* GL_INCR_WRAP */
+ { 10362, 0x00008507 }, /* GL_INCR_WRAP_EXT */
+ { 10379, 0x00008077 }, /* GL_INDEX_ARRAY */
+ { 10394, 0x00008899 }, /* GL_INDEX_ARRAY_BUFFER_BINDING */
+ { 10424, 0x00008899 }, /* GL_INDEX_ARRAY_BUFFER_BINDING_ARB */
+ { 10458, 0x00008091 }, /* GL_INDEX_ARRAY_POINTER */
+ { 10481, 0x00008086 }, /* GL_INDEX_ARRAY_STRIDE */
+ { 10503, 0x00008085 }, /* GL_INDEX_ARRAY_TYPE */
+ { 10523, 0x00000D51 }, /* GL_INDEX_BITS */
+ { 10537, 0x00000C20 }, /* GL_INDEX_CLEAR_VALUE */
+ { 10558, 0x00000BF1 }, /* GL_INDEX_LOGIC_OP */
+ { 10576, 0x00000C30 }, /* GL_INDEX_MODE */
+ { 10590, 0x00000D13 }, /* GL_INDEX_OFFSET */
+ { 10606, 0x00000D12 }, /* GL_INDEX_SHIFT */
+ { 10621, 0x00000C21 }, /* GL_INDEX_WRITEMASK */
+ { 10640, 0x00001404 }, /* GL_INT */
+ { 10647, 0x00008049 }, /* GL_INTENSITY */
+ { 10660, 0x0000804C }, /* GL_INTENSITY12 */
+ { 10675, 0x0000804C }, /* GL_INTENSITY12_EXT */
+ { 10694, 0x0000804D }, /* GL_INTENSITY16 */
+ { 10709, 0x0000804D }, /* GL_INTENSITY16_EXT */
+ { 10728, 0x0000804A }, /* GL_INTENSITY4 */
+ { 10742, 0x0000804A }, /* GL_INTENSITY4_EXT */
+ { 10760, 0x0000804B }, /* GL_INTENSITY8 */
+ { 10774, 0x0000804B }, /* GL_INTENSITY8_EXT */
+ { 10792, 0x00008049 }, /* GL_INTENSITY_EXT */
+ { 10809, 0x00008575 }, /* GL_INTERPOLATE */
+ { 10824, 0x00008575 }, /* GL_INTERPOLATE_ARB */
+ { 10843, 0x00008575 }, /* GL_INTERPOLATE_EXT */
+ { 10862, 0x00008B53 }, /* GL_INT_VEC2_ARB */
+ { 10878, 0x00008B54 }, /* GL_INT_VEC3_ARB */
+ { 10894, 0x00008B55 }, /* GL_INT_VEC4_ARB */
+ { 10910, 0x00000500 }, /* GL_INVALID_ENUM */
+ { 10926, 0x00000506 }, /* GL_INVALID_FRAMEBUFFER_OPERATION_EXT */
+ { 10963, 0x00000502 }, /* GL_INVALID_OPERATION */
+ { 10984, 0x00000501 }, /* GL_INVALID_VALUE */
+ { 11001, 0x0000862B }, /* GL_INVERSE_NV */
+ { 11015, 0x0000862D }, /* GL_INVERSE_TRANSPOSE_NV */
+ { 11039, 0x0000150A }, /* GL_INVERT */
+ { 11049, 0x00001E00 }, /* GL_KEEP */
+ { 11057, 0x00000406 }, /* GL_LEFT */
+ { 11065, 0x00000203 }, /* GL_LEQUAL */
+ { 11075, 0x00000201 }, /* GL_LESS */
+ { 11083, 0x00004000 }, /* GL_LIGHT0 */
+ { 11093, 0x00004001 }, /* GL_LIGHT1 */
+ { 11103, 0x00004002 }, /* GL_LIGHT2 */
+ { 11113, 0x00004003 }, /* GL_LIGHT3 */
+ { 11123, 0x00004004 }, /* GL_LIGHT4 */
+ { 11133, 0x00004005 }, /* GL_LIGHT5 */
+ { 11143, 0x00004006 }, /* GL_LIGHT6 */
+ { 11153, 0x00004007 }, /* GL_LIGHT7 */
+ { 11163, 0x00000B50 }, /* GL_LIGHTING */
+ { 11175, 0x00000040 }, /* GL_LIGHTING_BIT */
+ { 11191, 0x00000B53 }, /* GL_LIGHT_MODEL_AMBIENT */
+ { 11214, 0x000081F8 }, /* GL_LIGHT_MODEL_COLOR_CONTROL */
+ { 11243, 0x000081F8 }, /* GL_LIGHT_MODEL_COLOR_CONTROL_EXT */
+ { 11276, 0x00000B51 }, /* GL_LIGHT_MODEL_LOCAL_VIEWER */
+ { 11304, 0x00000B52 }, /* GL_LIGHT_MODEL_TWO_SIDE */
+ { 11328, 0x00001B01 }, /* GL_LINE */
+ { 11336, 0x00002601 }, /* GL_LINEAR */
+ { 11346, 0x00001208 }, /* GL_LINEAR_ATTENUATION */
+ { 11368, 0x00008170 }, /* GL_LINEAR_CLIPMAP_LINEAR_SGIX */
+ { 11398, 0x0000844F }, /* GL_LINEAR_CLIPMAP_NEAREST_SGIX */
+ { 11429, 0x00002703 }, /* GL_LINEAR_MIPMAP_LINEAR */
+ { 11453, 0x00002701 }, /* GL_LINEAR_MIPMAP_NEAREST */
+ { 11478, 0x00000001 }, /* GL_LINES */
+ { 11487, 0x00000004 }, /* GL_LINE_BIT */
+ { 11499, 0x00000002 }, /* GL_LINE_LOOP */
+ { 11512, 0x00000707 }, /* GL_LINE_RESET_TOKEN */
+ { 11532, 0x00000B20 }, /* GL_LINE_SMOOTH */
+ { 11547, 0x00000C52 }, /* GL_LINE_SMOOTH_HINT */
+ { 11567, 0x00000B24 }, /* GL_LINE_STIPPLE */
+ { 11583, 0x00000B25 }, /* GL_LINE_STIPPLE_PATTERN */
+ { 11607, 0x00000B26 }, /* GL_LINE_STIPPLE_REPEAT */
+ { 11630, 0x00000003 }, /* GL_LINE_STRIP */
+ { 11644, 0x00000702 }, /* GL_LINE_TOKEN */
+ { 11658, 0x00000B21 }, /* GL_LINE_WIDTH */
+ { 11672, 0x00000B23 }, /* GL_LINE_WIDTH_GRANULARITY */
+ { 11698, 0x00000B22 }, /* GL_LINE_WIDTH_RANGE */
+ { 11718, 0x00000B32 }, /* GL_LIST_BASE */
+ { 11731, 0x00020000 }, /* GL_LIST_BIT */
+ { 11743, 0x00000B33 }, /* GL_LIST_INDEX */
+ { 11757, 0x00000B30 }, /* GL_LIST_MODE */
+ { 11770, 0x00000101 }, /* GL_LOAD */
+ { 11778, 0x00000BF1 }, /* GL_LOGIC_OP */
+ { 11790, 0x00000BF0 }, /* GL_LOGIC_OP_MODE */
+ { 11807, 0x00001909 }, /* GL_LUMINANCE */
+ { 11820, 0x00008041 }, /* GL_LUMINANCE12 */
+ { 11835, 0x00008047 }, /* GL_LUMINANCE12_ALPHA12 */
+ { 11858, 0x00008047 }, /* GL_LUMINANCE12_ALPHA12_EXT */
+ { 11885, 0x00008046 }, /* GL_LUMINANCE12_ALPHA4 */
+ { 11907, 0x00008046 }, /* GL_LUMINANCE12_ALPHA4_EXT */
+ { 11933, 0x00008041 }, /* GL_LUMINANCE12_EXT */
+ { 11952, 0x00008042 }, /* GL_LUMINANCE16 */
+ { 11967, 0x00008048 }, /* GL_LUMINANCE16_ALPHA16 */
+ { 11990, 0x00008048 }, /* GL_LUMINANCE16_ALPHA16_EXT */
+ { 12017, 0x00008042 }, /* GL_LUMINANCE16_EXT */
+ { 12036, 0x0000803F }, /* GL_LUMINANCE4 */
+ { 12050, 0x00008043 }, /* GL_LUMINANCE4_ALPHA4 */
+ { 12071, 0x00008043 }, /* GL_LUMINANCE4_ALPHA4_EXT */
+ { 12096, 0x0000803F }, /* GL_LUMINANCE4_EXT */
+ { 12114, 0x00008044 }, /* GL_LUMINANCE6_ALPHA2 */
+ { 12135, 0x00008044 }, /* GL_LUMINANCE6_ALPHA2_EXT */
+ { 12160, 0x00008040 }, /* GL_LUMINANCE8 */
+ { 12174, 0x00008045 }, /* GL_LUMINANCE8_ALPHA8 */
+ { 12195, 0x00008045 }, /* GL_LUMINANCE8_ALPHA8_EXT */
+ { 12220, 0x00008040 }, /* GL_LUMINANCE8_EXT */
+ { 12238, 0x0000190A }, /* GL_LUMINANCE_ALPHA */
+ { 12257, 0x00000D90 }, /* GL_MAP1_COLOR_4 */
+ { 12273, 0x00000DD0 }, /* GL_MAP1_GRID_DOMAIN */
+ { 12293, 0x00000DD1 }, /* GL_MAP1_GRID_SEGMENTS */
+ { 12315, 0x00000D91 }, /* GL_MAP1_INDEX */
+ { 12329, 0x00000D92 }, /* GL_MAP1_NORMAL */
+ { 12344, 0x00000D93 }, /* GL_MAP1_TEXTURE_COORD_1 */
+ { 12368, 0x00000D94 }, /* GL_MAP1_TEXTURE_COORD_2 */
+ { 12392, 0x00000D95 }, /* GL_MAP1_TEXTURE_COORD_3 */
+ { 12416, 0x00000D96 }, /* GL_MAP1_TEXTURE_COORD_4 */
+ { 12440, 0x00000D97 }, /* GL_MAP1_VERTEX_3 */
+ { 12457, 0x00000D98 }, /* GL_MAP1_VERTEX_4 */
+ { 12474, 0x00008660 }, /* GL_MAP1_VERTEX_ATTRIB0_4_NV */
+ { 12502, 0x0000866A }, /* GL_MAP1_VERTEX_ATTRIB10_4_NV */
+ { 12531, 0x0000866B }, /* GL_MAP1_VERTEX_ATTRIB11_4_NV */
+ { 12560, 0x0000866C }, /* GL_MAP1_VERTEX_ATTRIB12_4_NV */
+ { 12589, 0x0000866D }, /* GL_MAP1_VERTEX_ATTRIB13_4_NV */
+ { 12618, 0x0000866E }, /* GL_MAP1_VERTEX_ATTRIB14_4_NV */
+ { 12647, 0x0000866F }, /* GL_MAP1_VERTEX_ATTRIB15_4_NV */
+ { 12676, 0x00008661 }, /* GL_MAP1_VERTEX_ATTRIB1_4_NV */
+ { 12704, 0x00008662 }, /* GL_MAP1_VERTEX_ATTRIB2_4_NV */
+ { 12732, 0x00008663 }, /* GL_MAP1_VERTEX_ATTRIB3_4_NV */
+ { 12760, 0x00008664 }, /* GL_MAP1_VERTEX_ATTRIB4_4_NV */
+ { 12788, 0x00008665 }, /* GL_MAP1_VERTEX_ATTRIB5_4_NV */
+ { 12816, 0x00008666 }, /* GL_MAP1_VERTEX_ATTRIB6_4_NV */
+ { 12844, 0x00008667 }, /* GL_MAP1_VERTEX_ATTRIB7_4_NV */
+ { 12872, 0x00008668 }, /* GL_MAP1_VERTEX_ATTRIB8_4_NV */
+ { 12900, 0x00008669 }, /* GL_MAP1_VERTEX_ATTRIB9_4_NV */
+ { 12928, 0x00000DB0 }, /* GL_MAP2_COLOR_4 */
+ { 12944, 0x00000DD2 }, /* GL_MAP2_GRID_DOMAIN */
+ { 12964, 0x00000DD3 }, /* GL_MAP2_GRID_SEGMENTS */
+ { 12986, 0x00000DB1 }, /* GL_MAP2_INDEX */
+ { 13000, 0x00000DB2 }, /* GL_MAP2_NORMAL */
+ { 13015, 0x00000DB3 }, /* GL_MAP2_TEXTURE_COORD_1 */
+ { 13039, 0x00000DB4 }, /* GL_MAP2_TEXTURE_COORD_2 */
+ { 13063, 0x00000DB5 }, /* GL_MAP2_TEXTURE_COORD_3 */
+ { 13087, 0x00000DB6 }, /* GL_MAP2_TEXTURE_COORD_4 */
+ { 13111, 0x00000DB7 }, /* GL_MAP2_VERTEX_3 */
+ { 13128, 0x00000DB8 }, /* GL_MAP2_VERTEX_4 */
+ { 13145, 0x00008670 }, /* GL_MAP2_VERTEX_ATTRIB0_4_NV */
+ { 13173, 0x0000867A }, /* GL_MAP2_VERTEX_ATTRIB10_4_NV */
+ { 13202, 0x0000867B }, /* GL_MAP2_VERTEX_ATTRIB11_4_NV */
+ { 13231, 0x0000867C }, /* GL_MAP2_VERTEX_ATTRIB12_4_NV */
+ { 13260, 0x0000867D }, /* GL_MAP2_VERTEX_ATTRIB13_4_NV */
+ { 13289, 0x0000867E }, /* GL_MAP2_VERTEX_ATTRIB14_4_NV */
+ { 13318, 0x0000867F }, /* GL_MAP2_VERTEX_ATTRIB15_4_NV */
+ { 13347, 0x00008671 }, /* GL_MAP2_VERTEX_ATTRIB1_4_NV */
+ { 13375, 0x00008672 }, /* GL_MAP2_VERTEX_ATTRIB2_4_NV */
+ { 13403, 0x00008673 }, /* GL_MAP2_VERTEX_ATTRIB3_4_NV */
+ { 13431, 0x00008674 }, /* GL_MAP2_VERTEX_ATTRIB4_4_NV */
+ { 13459, 0x00008675 }, /* GL_MAP2_VERTEX_ATTRIB5_4_NV */
+ { 13487, 0x00008676 }, /* GL_MAP2_VERTEX_ATTRIB6_4_NV */
+ { 13515, 0x00008677 }, /* GL_MAP2_VERTEX_ATTRIB7_4_NV */
+ { 13543, 0x00008678 }, /* GL_MAP2_VERTEX_ATTRIB8_4_NV */
+ { 13571, 0x00008679 }, /* GL_MAP2_VERTEX_ATTRIB9_4_NV */
+ { 13599, 0x00000D10 }, /* GL_MAP_COLOR */
+ { 13612, 0x00000D11 }, /* GL_MAP_STENCIL */
+ { 13627, 0x000088C0 }, /* GL_MATRIX0_ARB */
+ { 13642, 0x00008630 }, /* GL_MATRIX0_NV */
+ { 13656, 0x000088CA }, /* GL_MATRIX10_ARB */
+ { 13672, 0x000088CB }, /* GL_MATRIX11_ARB */
+ { 13688, 0x000088CC }, /* GL_MATRIX12_ARB */
+ { 13704, 0x000088CD }, /* GL_MATRIX13_ARB */
+ { 13720, 0x000088CE }, /* GL_MATRIX14_ARB */
+ { 13736, 0x000088CF }, /* GL_MATRIX15_ARB */
+ { 13752, 0x000088D0 }, /* GL_MATRIX16_ARB */
+ { 13768, 0x000088D1 }, /* GL_MATRIX17_ARB */
+ { 13784, 0x000088D2 }, /* GL_MATRIX18_ARB */
+ { 13800, 0x000088D3 }, /* GL_MATRIX19_ARB */
+ { 13816, 0x000088C1 }, /* GL_MATRIX1_ARB */
+ { 13831, 0x00008631 }, /* GL_MATRIX1_NV */
+ { 13845, 0x000088D4 }, /* GL_MATRIX20_ARB */
+ { 13861, 0x000088D5 }, /* GL_MATRIX21_ARB */
+ { 13877, 0x000088D6 }, /* GL_MATRIX22_ARB */
+ { 13893, 0x000088D7 }, /* GL_MATRIX23_ARB */
+ { 13909, 0x000088D8 }, /* GL_MATRIX24_ARB */
+ { 13925, 0x000088D9 }, /* GL_MATRIX25_ARB */
+ { 13941, 0x000088DA }, /* GL_MATRIX26_ARB */
+ { 13957, 0x000088DB }, /* GL_MATRIX27_ARB */
+ { 13973, 0x000088DC }, /* GL_MATRIX28_ARB */
+ { 13989, 0x000088DD }, /* GL_MATRIX29_ARB */
+ { 14005, 0x000088C2 }, /* GL_MATRIX2_ARB */
+ { 14020, 0x00008632 }, /* GL_MATRIX2_NV */
+ { 14034, 0x000088DE }, /* GL_MATRIX30_ARB */
+ { 14050, 0x000088DF }, /* GL_MATRIX31_ARB */
+ { 14066, 0x000088C3 }, /* GL_MATRIX3_ARB */
+ { 14081, 0x00008633 }, /* GL_MATRIX3_NV */
+ { 14095, 0x000088C4 }, /* GL_MATRIX4_ARB */
+ { 14110, 0x00008634 }, /* GL_MATRIX4_NV */
+ { 14124, 0x000088C5 }, /* GL_MATRIX5_ARB */
+ { 14139, 0x00008635 }, /* GL_MATRIX5_NV */
+ { 14153, 0x000088C6 }, /* GL_MATRIX6_ARB */
+ { 14168, 0x00008636 }, /* GL_MATRIX6_NV */
+ { 14182, 0x000088C7 }, /* GL_MATRIX7_ARB */
+ { 14197, 0x00008637 }, /* GL_MATRIX7_NV */
+ { 14211, 0x000088C8 }, /* GL_MATRIX8_ARB */
+ { 14226, 0x000088C9 }, /* GL_MATRIX9_ARB */
+ { 14241, 0x00008844 }, /* GL_MATRIX_INDEX_ARRAY_ARB */
+ { 14267, 0x00008849 }, /* GL_MATRIX_INDEX_ARRAY_POINTER_ARB */
+ { 14301, 0x00008846 }, /* GL_MATRIX_INDEX_ARRAY_SIZE_ARB */
+ { 14332, 0x00008848 }, /* GL_MATRIX_INDEX_ARRAY_STRIDE_ARB */
+ { 14365, 0x00008847 }, /* GL_MATRIX_INDEX_ARRAY_TYPE_ARB */
+ { 14396, 0x00000BA0 }, /* GL_MATRIX_MODE */
+ { 14411, 0x00008840 }, /* GL_MATRIX_PALETTE_ARB */
+ { 14433, 0x00008008 }, /* GL_MAX */
+ { 14440, 0x00008073 }, /* GL_MAX_3D_TEXTURE_SIZE */
+ { 14463, 0x00000D35 }, /* GL_MAX_ATTRIB_STACK_DEPTH */
+ { 14489, 0x00000D3B }, /* GL_MAX_CLIENT_ATTRIB_STACK_DEPTH */
+ { 14522, 0x00008177 }, /* GL_MAX_CLIPMAP_DEPTH_SGIX */
+ { 14548, 0x00008178 }, /* GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX */
+ { 14582, 0x00000D32 }, /* GL_MAX_CLIP_PLANES */
+ { 14601, 0x00008CDF }, /* GL_MAX_COLOR_ATTACHMENTS_EXT */
+ { 14630, 0x000080B3 }, /* GL_MAX_COLOR_MATRIX_STACK_DEPTH */
+ { 14662, 0x000080B3 }, /* GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI */
+ { 14698, 0x00008B4D }, /* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB */
+ { 14738, 0x0000801B }, /* GL_MAX_CONVOLUTION_HEIGHT */
+ { 14764, 0x0000801B }, /* GL_MAX_CONVOLUTION_HEIGHT_EXT */
+ { 14794, 0x0000801A }, /* GL_MAX_CONVOLUTION_WIDTH */
+ { 14819, 0x0000801A }, /* GL_MAX_CONVOLUTION_WIDTH_EXT */
+ { 14848, 0x0000851C }, /* GL_MAX_CUBE_MAP_TEXTURE_SIZE */
+ { 14877, 0x0000851C }, /* GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB */
+ { 14910, 0x00008824 }, /* GL_MAX_DRAW_BUFFERS_ARB */
+ { 14934, 0x00008824 }, /* GL_MAX_DRAW_BUFFERS_ATI */
+ { 14958, 0x000080E9 }, /* GL_MAX_ELEMENTS_INDICES */
+ { 14982, 0x000080E8 }, /* GL_MAX_ELEMENTS_VERTICES */
+ { 15007, 0x00000D30 }, /* GL_MAX_EVAL_ORDER */
+ { 15025, 0x00008008 }, /* GL_MAX_EXT */
+ { 15036, 0x00008B49 }, /* GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB */
+ { 15075, 0x00000D31 }, /* GL_MAX_LIGHTS */
+ { 15089, 0x00000B31 }, /* GL_MAX_LIST_NESTING */
+ { 15109, 0x00008841 }, /* GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB */
+ { 15147, 0x00000D36 }, /* GL_MAX_MODELVIEW_STACK_DEPTH */
+ { 15176, 0x00000D37 }, /* GL_MAX_NAME_STACK_DEPTH */
+ { 15200, 0x00008842 }, /* GL_MAX_PALETTE_MATRICES_ARB */
+ { 15228, 0x00000D34 }, /* GL_MAX_PIXEL_MAP_TABLE */
+ { 15251, 0x000088B1 }, /* GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB */
+ { 15288, 0x0000880B }, /* GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB */
+ { 15324, 0x000088AD }, /* GL_MAX_PROGRAM_ATTRIBS_ARB */
+ { 15351, 0x000088F5 }, /* GL_MAX_PROGRAM_CALL_DEPTH_NV */
+ { 15380, 0x000088B5 }, /* GL_MAX_PROGRAM_ENV_PARAMETERS_ARB */
+ { 15414, 0x000088F4 }, /* GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV */
+ { 15450, 0x000088F6 }, /* GL_MAX_PROGRAM_IF_DEPTH_NV */
+ { 15477, 0x000088A1 }, /* GL_MAX_PROGRAM_INSTRUCTIONS_ARB */
+ { 15509, 0x000088B4 }, /* GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB */
+ { 15545, 0x000088F8 }, /* GL_MAX_PROGRAM_LOOP_COUNT_NV */
+ { 15574, 0x000088F7 }, /* GL_MAX_PROGRAM_LOOP_DEPTH_NV */
+ { 15603, 0x0000862F }, /* GL_MAX_PROGRAM_MATRICES_ARB */
+ { 15631, 0x0000862E }, /* GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB */
+ { 15669, 0x000088B3 }, /* GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */
+ { 15713, 0x0000880E }, /* GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */
+ { 15756, 0x000088AF }, /* GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB */
+ { 15790, 0x000088A3 }, /* GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB */
+ { 15829, 0x000088AB }, /* GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB */
+ { 15866, 0x000088A7 }, /* GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB */
+ { 15904, 0x00008810 }, /* GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */
+ { 15947, 0x0000880F }, /* GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */
+ { 15990, 0x000088A9 }, /* GL_MAX_PROGRAM_PARAMETERS_ARB */
+ { 16020, 0x000088A5 }, /* GL_MAX_PROGRAM_TEMPORARIES_ARB */
+ { 16051, 0x0000880D }, /* GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB */
+ { 16087, 0x0000880C }, /* GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB */
+ { 16123, 0x00000D38 }, /* GL_MAX_PROJECTION_STACK_DEPTH */
+ { 16153, 0x000084F8 }, /* GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB */
+ { 16187, 0x000084F8 }, /* GL_MAX_RECTANGLE_TEXTURE_SIZE_NV */
+ { 16220, 0x000084E8 }, /* GL_MAX_RENDERBUFFER_SIZE_EXT */
+ { 16249, 0x00008504 }, /* GL_MAX_SHININESS_NV */
+ { 16269, 0x00008505 }, /* GL_MAX_SPOT_EXPONENT_NV */
+ { 16293, 0x00008871 }, /* GL_MAX_TEXTURE_COORDS_ARB */
+ { 16319, 0x00008872 }, /* GL_MAX_TEXTURE_IMAGE_UNITS_ARB */
+ { 16350, 0x000084FD }, /* GL_MAX_TEXTURE_LOD_BIAS */
+ { 16374, 0x000084FF }, /* GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT */
+ { 16408, 0x00000D33 }, /* GL_MAX_TEXTURE_SIZE */
+ { 16428, 0x00000D39 }, /* GL_MAX_TEXTURE_STACK_DEPTH */
+ { 16455, 0x000084E2 }, /* GL_MAX_TEXTURE_UNITS */
+ { 16476, 0x000084E2 }, /* GL_MAX_TEXTURE_UNITS_ARB */
+ { 16501, 0x0000862F }, /* GL_MAX_TRACK_MATRICES_NV */
+ { 16526, 0x0000862E }, /* GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV */
+ { 16561, 0x00008B4B }, /* GL_MAX_VARYING_FLOATS_ARB */
+ { 16587, 0x00008869 }, /* GL_MAX_VERTEX_ATTRIBS_ARB */
+ { 16613, 0x00008B4C }, /* GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB */
+ { 16651, 0x00008B4A }, /* GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB */
+ { 16688, 0x000086A4 }, /* GL_MAX_VERTEX_UNITS_ARB */
+ { 16712, 0x00000D3A }, /* GL_MAX_VIEWPORT_DIMS */
+ { 16733, 0x00008007 }, /* GL_MIN */
+ { 16740, 0x0000802E }, /* GL_MINMAX */
+ { 16750, 0x0000802E }, /* GL_MINMAX_EXT */
+ { 16764, 0x0000802F }, /* GL_MINMAX_FORMAT */
+ { 16781, 0x0000802F }, /* GL_MINMAX_FORMAT_EXT */
+ { 16802, 0x00008030 }, /* GL_MINMAX_SINK */
+ { 16817, 0x00008030 }, /* GL_MINMAX_SINK_EXT */
+ { 16836, 0x00008007 }, /* GL_MIN_EXT */
+ { 16847, 0x00008370 }, /* GL_MIRRORED_REPEAT */
+ { 16866, 0x00008370 }, /* GL_MIRRORED_REPEAT_ARB */
+ { 16889, 0x00008370 }, /* GL_MIRRORED_REPEAT_IBM */
+ { 16912, 0x00008742 }, /* GL_MIRROR_CLAMP_ATI */
+ { 16932, 0x00008742 }, /* GL_MIRROR_CLAMP_EXT */
+ { 16952, 0x00008912 }, /* GL_MIRROR_CLAMP_TO_BORDER_EXT */
+ { 16982, 0x00008743 }, /* GL_MIRROR_CLAMP_TO_EDGE_ATI */
+ { 17010, 0x00008743 }, /* GL_MIRROR_CLAMP_TO_EDGE_EXT */
+ { 17038, 0x00001700 }, /* GL_MODELVIEW */
+ { 17051, 0x00001700 }, /* GL_MODELVIEW0_ARB */
+ { 17069, 0x0000872A }, /* GL_MODELVIEW10_ARB */
+ { 17088, 0x0000872B }, /* GL_MODELVIEW11_ARB */
+ { 17107, 0x0000872C }, /* GL_MODELVIEW12_ARB */
+ { 17126, 0x0000872D }, /* GL_MODELVIEW13_ARB */
+ { 17145, 0x0000872E }, /* GL_MODELVIEW14_ARB */
+ { 17164, 0x0000872F }, /* GL_MODELVIEW15_ARB */
+ { 17183, 0x00008730 }, /* GL_MODELVIEW16_ARB */
+ { 17202, 0x00008731 }, /* GL_MODELVIEW17_ARB */
+ { 17221, 0x00008732 }, /* GL_MODELVIEW18_ARB */
+ { 17240, 0x00008733 }, /* GL_MODELVIEW19_ARB */
+ { 17259, 0x0000850A }, /* GL_MODELVIEW1_ARB */
+ { 17277, 0x00008734 }, /* GL_MODELVIEW20_ARB */
+ { 17296, 0x00008735 }, /* GL_MODELVIEW21_ARB */
+ { 17315, 0x00008736 }, /* GL_MODELVIEW22_ARB */
+ { 17334, 0x00008737 }, /* GL_MODELVIEW23_ARB */
+ { 17353, 0x00008738 }, /* GL_MODELVIEW24_ARB */
+ { 17372, 0x00008739 }, /* GL_MODELVIEW25_ARB */
+ { 17391, 0x0000873A }, /* GL_MODELVIEW26_ARB */
+ { 17410, 0x0000873B }, /* GL_MODELVIEW27_ARB */
+ { 17429, 0x0000873C }, /* GL_MODELVIEW28_ARB */
+ { 17448, 0x0000873D }, /* GL_MODELVIEW29_ARB */
+ { 17467, 0x00008722 }, /* GL_MODELVIEW2_ARB */
+ { 17485, 0x0000873E }, /* GL_MODELVIEW30_ARB */
+ { 17504, 0x0000873F }, /* GL_MODELVIEW31_ARB */
+ { 17523, 0x00008723 }, /* GL_MODELVIEW3_ARB */
+ { 17541, 0x00008724 }, /* GL_MODELVIEW4_ARB */
+ { 17559, 0x00008725 }, /* GL_MODELVIEW5_ARB */
+ { 17577, 0x00008726 }, /* GL_MODELVIEW6_ARB */
+ { 17595, 0x00008727 }, /* GL_MODELVIEW7_ARB */
+ { 17613, 0x00008728 }, /* GL_MODELVIEW8_ARB */
+ { 17631, 0x00008729 }, /* GL_MODELVIEW9_ARB */
+ { 17649, 0x00000BA6 }, /* GL_MODELVIEW_MATRIX */
+ { 17669, 0x00008629 }, /* GL_MODELVIEW_PROJECTION_NV */
+ { 17696, 0x00000BA3 }, /* GL_MODELVIEW_STACK_DEPTH */
+ { 17721, 0x00002100 }, /* GL_MODULATE */
+ { 17733, 0x00008744 }, /* GL_MODULATE_ADD_ATI */
+ { 17753, 0x00008745 }, /* GL_MODULATE_SIGNED_ADD_ATI */
+ { 17780, 0x00008746 }, /* GL_MODULATE_SUBTRACT_ATI */
+ { 17805, 0x00000103 }, /* GL_MULT */
+ { 17813, 0x0000809D }, /* GL_MULTISAMPLE */
+ { 17828, 0x000086B2 }, /* GL_MULTISAMPLE_3DFX */
+ { 17848, 0x0000809D }, /* GL_MULTISAMPLE_ARB */
+ { 17867, 0x20000000 }, /* GL_MULTISAMPLE_BIT */
+ { 17886, 0x20000000 }, /* GL_MULTISAMPLE_BIT_3DFX */
+ { 17910, 0x20000000 }, /* GL_MULTISAMPLE_BIT_ARB */
+ { 17933, 0x00008534 }, /* GL_MULTISAMPLE_FILTER_HINT_NV */
+ { 17963, 0x00002A25 }, /* GL_N3F_V3F */
+ { 17974, 0x00000D70 }, /* GL_NAME_STACK_DEPTH */
+ { 17994, 0x0000150E }, /* GL_NAND */
+ { 18002, 0x00002600 }, /* GL_NEAREST */
+ { 18013, 0x0000844E }, /* GL_NEAREST_CLIPMAP_LINEAR_SGIX */
+ { 18044, 0x0000844D }, /* GL_NEAREST_CLIPMAP_NEAREST_SGIX */
+ { 18076, 0x00002702 }, /* GL_NEAREST_MIPMAP_LINEAR */
+ { 18101, 0x00002700 }, /* GL_NEAREST_MIPMAP_NEAREST */
+ { 18127, 0x00000200 }, /* GL_NEVER */
+ { 18136, 0x00001102 }, /* GL_NICEST */
+ { 18146, 0x00000000 }, /* GL_NONE */
+ { 18154, 0x00001505 }, /* GL_NOOP */
+ { 18162, 0x00001508 }, /* GL_NOR */
+ { 18169, 0x00000BA1 }, /* GL_NORMALIZE */
+ { 18182, 0x00008075 }, /* GL_NORMAL_ARRAY */
+ { 18198, 0x00008897 }, /* GL_NORMAL_ARRAY_BUFFER_BINDING */
+ { 18229, 0x00008897 }, /* GL_NORMAL_ARRAY_BUFFER_BINDING_ARB */
+ { 18264, 0x0000808F }, /* GL_NORMAL_ARRAY_POINTER */
+ { 18288, 0x0000807F }, /* GL_NORMAL_ARRAY_STRIDE */
+ { 18311, 0x0000807E }, /* GL_NORMAL_ARRAY_TYPE */
+ { 18332, 0x00008511 }, /* GL_NORMAL_MAP */
+ { 18346, 0x00008511 }, /* GL_NORMAL_MAP_ARB */
+ { 18364, 0x00008511 }, /* GL_NORMAL_MAP_NV */
+ { 18381, 0x00000205 }, /* GL_NOTEQUAL */
+ { 18393, 0x00000000 }, /* GL_NO_ERROR */
+ { 18405, 0x000086A2 }, /* GL_NUM_COMPRESSED_TEXTURE_FORMATS */
+ { 18439, 0x000086A2 }, /* GL_NUM_TEXTURE_COMPRESSED_FORMATS_ARB */
+ { 18477, 0x00008B89 }, /* GL_OBJECT_ACTIVE_ATTRIBUTES_ARB */
+ { 18509, 0x00008B8A }, /* GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB */
+ { 18551, 0x00008B86 }, /* GL_OBJECT_ACTIVE_UNIFORMS_ARB */
+ { 18581, 0x00008B87 }, /* GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB */
+ { 18621, 0x00008B85 }, /* GL_OBJECT_ATTACHED_OBJECTS_ARB */
+ { 18652, 0x00008B81 }, /* GL_OBJECT_COMPILE_STATUS_ARB */
+ { 18681, 0x00008B80 }, /* GL_OBJECT_DELETE_STATUS_ARB */
+ { 18709, 0x00008B84 }, /* GL_OBJECT_INFO_LOG_LENGTH_ARB */
+ { 18739, 0x00002401 }, /* GL_OBJECT_LINEAR */
+ { 18756, 0x00008B82 }, /* GL_OBJECT_LINK_STATUS_ARB */
+ { 18782, 0x00002501 }, /* GL_OBJECT_PLANE */
+ { 18798, 0x00008B88 }, /* GL_OBJECT_SHADER_SOURCE_LENGTH_ARB */
+ { 18833, 0x00008B4F }, /* GL_OBJECT_SUBTYPE_ARB */
+ { 18855, 0x00008B4E }, /* GL_OBJECT_TYPE_ARB */
+ { 18874, 0x00008B83 }, /* GL_OBJECT_VALIDATE_STATUS_ARB */
+ { 18904, 0x00008165 }, /* GL_OCCLUSION_TEST_HP */
+ { 18925, 0x00008166 }, /* GL_OCCLUSION_TEST_RESULT_HP */
+ { 18953, 0x00000001 }, /* GL_ONE */
+ { 18960, 0x00008004 }, /* GL_ONE_MINUS_CONSTANT_ALPHA */
+ { 18988, 0x00008004 }, /* GL_ONE_MINUS_CONSTANT_ALPHA_EXT */
+ { 19020, 0x00008002 }, /* GL_ONE_MINUS_CONSTANT_COLOR */
+ { 19048, 0x00008002 }, /* GL_ONE_MINUS_CONSTANT_COLOR_EXT */
+ { 19080, 0x00000305 }, /* GL_ONE_MINUS_DST_ALPHA */
+ { 19103, 0x00000307 }, /* GL_ONE_MINUS_DST_COLOR */
+ { 19126, 0x00000303 }, /* GL_ONE_MINUS_SRC_ALPHA */
+ { 19149, 0x00000301 }, /* GL_ONE_MINUS_SRC_COLOR */
+ { 19172, 0x00008598 }, /* GL_OPERAND0_ALPHA */
+ { 19190, 0x00008598 }, /* GL_OPERAND0_ALPHA_ARB */
+ { 19212, 0x00008598 }, /* GL_OPERAND0_ALPHA_EXT */
+ { 19234, 0x00008590 }, /* GL_OPERAND0_RGB */
+ { 19250, 0x00008590 }, /* GL_OPERAND0_RGB_ARB */
+ { 19270, 0x00008590 }, /* GL_OPERAND0_RGB_EXT */
+ { 19290, 0x00008599 }, /* GL_OPERAND1_ALPHA */
+ { 19308, 0x00008599 }, /* GL_OPERAND1_ALPHA_ARB */
+ { 19330, 0x00008599 }, /* GL_OPERAND1_ALPHA_EXT */
+ { 19352, 0x00008591 }, /* GL_OPERAND1_RGB */
+ { 19368, 0x00008591 }, /* GL_OPERAND1_RGB_ARB */
+ { 19388, 0x00008591 }, /* GL_OPERAND1_RGB_EXT */
+ { 19408, 0x0000859A }, /* GL_OPERAND2_ALPHA */
+ { 19426, 0x0000859A }, /* GL_OPERAND2_ALPHA_ARB */
+ { 19448, 0x0000859A }, /* GL_OPERAND2_ALPHA_EXT */
+ { 19470, 0x00008592 }, /* GL_OPERAND2_RGB */
+ { 19486, 0x00008592 }, /* GL_OPERAND2_RGB_ARB */
+ { 19506, 0x00008592 }, /* GL_OPERAND2_RGB_EXT */
+ { 19526, 0x0000859B }, /* GL_OPERAND3_ALPHA_NV */
+ { 19547, 0x00008593 }, /* GL_OPERAND3_RGB_NV */
+ { 19566, 0x00001507 }, /* GL_OR */
+ { 19572, 0x00000A01 }, /* GL_ORDER */
+ { 19581, 0x0000150D }, /* GL_OR_INVERTED */
+ { 19596, 0x0000150B }, /* GL_OR_REVERSE */
+ { 19610, 0x00000505 }, /* GL_OUT_OF_MEMORY */
+ { 19627, 0x00000D05 }, /* GL_PACK_ALIGNMENT */
+ { 19645, 0x0000806C }, /* GL_PACK_IMAGE_HEIGHT */
+ { 19666, 0x00008758 }, /* GL_PACK_INVERT_MESA */
+ { 19686, 0x00000D01 }, /* GL_PACK_LSB_FIRST */
+ { 19704, 0x00000D02 }, /* GL_PACK_ROW_LENGTH */
+ { 19723, 0x0000806B }, /* GL_PACK_SKIP_IMAGES */
+ { 19743, 0x00000D04 }, /* GL_PACK_SKIP_PIXELS */
+ { 19763, 0x00000D03 }, /* GL_PACK_SKIP_ROWS */
+ { 19781, 0x00000D00 }, /* GL_PACK_SWAP_BYTES */
+ { 19800, 0x00008B92 }, /* GL_PALETTE4_R5_G6_B5_OES */
+ { 19825, 0x00008B94 }, /* GL_PALETTE4_RGB5_A1_OES */
+ { 19849, 0x00008B90 }, /* GL_PALETTE4_RGB8_OES */
+ { 19870, 0x00008B93 }, /* GL_PALETTE4_RGBA4_OES */
+ { 19892, 0x00008B91 }, /* GL_PALETTE4_RGBA8_OES */
+ { 19914, 0x00008B97 }, /* GL_PALETTE8_R5_G6_B5_OES */
+ { 19939, 0x00008B99 }, /* GL_PALETTE8_RGB5_A1_OES */
+ { 19963, 0x00008B95 }, /* GL_PALETTE8_RGB8_OES */
+ { 19984, 0x00008B98 }, /* GL_PALETTE8_RGBA4_OES */
+ { 20006, 0x00008B96 }, /* GL_PALETTE8_RGBA8_OES */
+ { 20028, 0x00000700 }, /* GL_PASS_THROUGH_TOKEN */
+ { 20050, 0x00000C50 }, /* GL_PERSPECTIVE_CORRECTION_HINT */
+ { 20081, 0x00000C79 }, /* GL_PIXEL_MAP_A_TO_A */
+ { 20101, 0x00000CB9 }, /* GL_PIXEL_MAP_A_TO_A_SIZE */
+ { 20126, 0x00000C78 }, /* GL_PIXEL_MAP_B_TO_B */
+ { 20146, 0x00000CB8 }, /* GL_PIXEL_MAP_B_TO_B_SIZE */
+ { 20171, 0x00000C77 }, /* GL_PIXEL_MAP_G_TO_G */
+ { 20191, 0x00000CB7 }, /* GL_PIXEL_MAP_G_TO_G_SIZE */
+ { 20216, 0x00000C75 }, /* GL_PIXEL_MAP_I_TO_A */
+ { 20236, 0x00000CB5 }, /* GL_PIXEL_MAP_I_TO_A_SIZE */
+ { 20261, 0x00000C74 }, /* GL_PIXEL_MAP_I_TO_B */
+ { 20281, 0x00000CB4 }, /* GL_PIXEL_MAP_I_TO_B_SIZE */
+ { 20306, 0x00000C73 }, /* GL_PIXEL_MAP_I_TO_G */
+ { 20326, 0x00000CB3 }, /* GL_PIXEL_MAP_I_TO_G_SIZE */
+ { 20351, 0x00000C70 }, /* GL_PIXEL_MAP_I_TO_I */
+ { 20371, 0x00000CB0 }, /* GL_PIXEL_MAP_I_TO_I_SIZE */
+ { 20396, 0x00000C72 }, /* GL_PIXEL_MAP_I_TO_R */
+ { 20416, 0x00000CB2 }, /* GL_PIXEL_MAP_I_TO_R_SIZE */
+ { 20441, 0x00000C76 }, /* GL_PIXEL_MAP_R_TO_R */
+ { 20461, 0x00000CB6 }, /* GL_PIXEL_MAP_R_TO_R_SIZE */
+ { 20486, 0x00000C71 }, /* GL_PIXEL_MAP_S_TO_S */
+ { 20506, 0x00000CB1 }, /* GL_PIXEL_MAP_S_TO_S_SIZE */
+ { 20531, 0x00000020 }, /* GL_PIXEL_MODE_BIT */
+ { 20549, 0x000088ED }, /* GL_PIXEL_PACK_BUFFER_BINDING_EXT */
+ { 20582, 0x000088EB }, /* GL_PIXEL_PACK_BUFFER_EXT */
+ { 20607, 0x000088EF }, /* GL_PIXEL_UNPACK_BUFFER_BINDING_EXT */
+ { 20642, 0x000088EC }, /* GL_PIXEL_UNPACK_BUFFER_EXT */
+ { 20669, 0x00001B00 }, /* GL_POINT */
+ { 20678, 0x00000000 }, /* GL_POINTS */
+ { 20688, 0x00000002 }, /* GL_POINT_BIT */
+ { 20701, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION */
+ { 20731, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION_ARB */
+ { 20765, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION_EXT */
+ { 20799, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION_SGIS */
+ { 20834, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE */
+ { 20863, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE_ARB */
+ { 20896, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE_EXT */
+ { 20929, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE_SGIS */
+ { 20963, 0x00000B11 }, /* GL_POINT_SIZE */
+ { 20977, 0x00000B13 }, /* GL_POINT_SIZE_GRANULARITY */
+ { 21003, 0x00008127 }, /* GL_POINT_SIZE_MAX */
+ { 21021, 0x00008127 }, /* GL_POINT_SIZE_MAX_ARB */
+ { 21043, 0x00008127 }, /* GL_POINT_SIZE_MAX_EXT */
+ { 21065, 0x00008127 }, /* GL_POINT_SIZE_MAX_SGIS */
+ { 21088, 0x00008126 }, /* GL_POINT_SIZE_MIN */
+ { 21106, 0x00008126 }, /* GL_POINT_SIZE_MIN_ARB */
+ { 21128, 0x00008126 }, /* GL_POINT_SIZE_MIN_EXT */
+ { 21150, 0x00008126 }, /* GL_POINT_SIZE_MIN_SGIS */
+ { 21173, 0x00000B12 }, /* GL_POINT_SIZE_RANGE */
+ { 21193, 0x00000B10 }, /* GL_POINT_SMOOTH */
+ { 21209, 0x00000C51 }, /* GL_POINT_SMOOTH_HINT */
+ { 21230, 0x00008861 }, /* GL_POINT_SPRITE_ARB */
+ { 21250, 0x00008CA0 }, /* GL_POINT_SPRITE_COORD_ORIGIN */
+ { 21279, 0x00008861 }, /* GL_POINT_SPRITE_NV */
+ { 21298, 0x00008863 }, /* GL_POINT_SPRITE_R_MODE_NV */
+ { 21324, 0x00000701 }, /* GL_POINT_TOKEN */
+ { 21339, 0x00000009 }, /* GL_POLYGON */
+ { 21350, 0x00000008 }, /* GL_POLYGON_BIT */
+ { 21365, 0x00000B40 }, /* GL_POLYGON_MODE */
+ { 21381, 0x00008039 }, /* GL_POLYGON_OFFSET_BIAS */
+ { 21404, 0x00008038 }, /* GL_POLYGON_OFFSET_FACTOR */
+ { 21429, 0x00008037 }, /* GL_POLYGON_OFFSET_FILL */
+ { 21452, 0x00002A02 }, /* GL_POLYGON_OFFSET_LINE */
+ { 21475, 0x00002A01 }, /* GL_POLYGON_OFFSET_POINT */
+ { 21499, 0x00002A00 }, /* GL_POLYGON_OFFSET_UNITS */
+ { 21523, 0x00000B41 }, /* GL_POLYGON_SMOOTH */
+ { 21541, 0x00000C53 }, /* GL_POLYGON_SMOOTH_HINT */
+ { 21564, 0x00000B42 }, /* GL_POLYGON_STIPPLE */
+ { 21583, 0x00000010 }, /* GL_POLYGON_STIPPLE_BIT */
+ { 21606, 0x00000703 }, /* GL_POLYGON_TOKEN */
+ { 21623, 0x00001203 }, /* GL_POSITION */
+ { 21635, 0x000080BB }, /* GL_POST_COLOR_MATRIX_ALPHA_BIAS */
+ { 21667, 0x000080BB }, /* GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI */
+ { 21703, 0x000080B7 }, /* GL_POST_COLOR_MATRIX_ALPHA_SCALE */
+ { 21736, 0x000080B7 }, /* GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI */
+ { 21773, 0x000080BA }, /* GL_POST_COLOR_MATRIX_BLUE_BIAS */
+ { 21804, 0x000080BA }, /* GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI */
+ { 21839, 0x000080B6 }, /* GL_POST_COLOR_MATRIX_BLUE_SCALE */
+ { 21871, 0x000080B6 }, /* GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI */
+ { 21907, 0x000080D2 }, /* GL_POST_COLOR_MATRIX_COLOR_TABLE */
+ { 21940, 0x000080B9 }, /* GL_POST_COLOR_MATRIX_GREEN_BIAS */
+ { 21972, 0x000080B9 }, /* GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI */
+ { 22008, 0x000080B5 }, /* GL_POST_COLOR_MATRIX_GREEN_SCALE */
+ { 22041, 0x000080B5 }, /* GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI */
+ { 22078, 0x000080B8 }, /* GL_POST_COLOR_MATRIX_RED_BIAS */
+ { 22108, 0x000080B8 }, /* GL_POST_COLOR_MATRIX_RED_BIAS_SGI */
+ { 22142, 0x000080B4 }, /* GL_POST_COLOR_MATRIX_RED_SCALE */
+ { 22173, 0x000080B4 }, /* GL_POST_COLOR_MATRIX_RED_SCALE_SGI */
+ { 22208, 0x00008023 }, /* GL_POST_CONVOLUTION_ALPHA_BIAS */
+ { 22239, 0x00008023 }, /* GL_POST_CONVOLUTION_ALPHA_BIAS_EXT */
+ { 22274, 0x0000801F }, /* GL_POST_CONVOLUTION_ALPHA_SCALE */
+ { 22306, 0x0000801F }, /* GL_POST_CONVOLUTION_ALPHA_SCALE_EXT */
+ { 22342, 0x00008022 }, /* GL_POST_CONVOLUTION_BLUE_BIAS */
+ { 22372, 0x00008022 }, /* GL_POST_CONVOLUTION_BLUE_BIAS_EXT */
+ { 22406, 0x0000801E }, /* GL_POST_CONVOLUTION_BLUE_SCALE */
+ { 22437, 0x0000801E }, /* GL_POST_CONVOLUTION_BLUE_SCALE_EXT */
+ { 22472, 0x000080D1 }, /* GL_POST_CONVOLUTION_COLOR_TABLE */
+ { 22504, 0x00008021 }, /* GL_POST_CONVOLUTION_GREEN_BIAS */
+ { 22535, 0x00008021 }, /* GL_POST_CONVOLUTION_GREEN_BIAS_EXT */
+ { 22570, 0x0000801D }, /* GL_POST_CONVOLUTION_GREEN_SCALE */
+ { 22602, 0x0000801D }, /* GL_POST_CONVOLUTION_GREEN_SCALE_EXT */
+ { 22638, 0x00008020 }, /* GL_POST_CONVOLUTION_RED_BIAS */
+ { 22667, 0x00008020 }, /* GL_POST_CONVOLUTION_RED_BIAS_EXT */
+ { 22700, 0x0000801C }, /* GL_POST_CONVOLUTION_RED_SCALE */
+ { 22730, 0x0000801C }, /* GL_POST_CONVOLUTION_RED_SCALE_EXT */
+ { 22764, 0x0000817B }, /* GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX */
+ { 22803, 0x00008179 }, /* GL_POST_TEXTURE_FILTER_BIAS_SGIX */
+ { 22836, 0x0000817C }, /* GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX */
+ { 22876, 0x0000817A }, /* GL_POST_TEXTURE_FILTER_SCALE_SGIX */
+ { 22910, 0x00008578 }, /* GL_PREVIOUS */
+ { 22922, 0x00008578 }, /* GL_PREVIOUS_ARB */
+ { 22938, 0x00008578 }, /* GL_PREVIOUS_EXT */
+ { 22954, 0x00008577 }, /* GL_PRIMARY_COLOR */
+ { 22971, 0x00008577 }, /* GL_PRIMARY_COLOR_ARB */
+ { 22992, 0x00008577 }, /* GL_PRIMARY_COLOR_EXT */
+ { 23013, 0x000088B0 }, /* GL_PROGRAM_ADDRESS_REGISTERS_ARB */
+ { 23046, 0x00008805 }, /* GL_PROGRAM_ALU_INSTRUCTIONS_ARB */
+ { 23078, 0x000088AC }, /* GL_PROGRAM_ATTRIBS_ARB */
+ { 23101, 0x00008677 }, /* GL_PROGRAM_BINDING_ARB */
+ { 23124, 0x0000864B }, /* GL_PROGRAM_ERROR_POSITION_ARB */
+ { 23154, 0x0000864B }, /* GL_PROGRAM_ERROR_POSITION_NV */
+ { 23183, 0x00008874 }, /* GL_PROGRAM_ERROR_STRING_ARB */
+ { 23211, 0x00008876 }, /* GL_PROGRAM_FORMAT_ARB */
+ { 23233, 0x00008875 }, /* GL_PROGRAM_FORMAT_ASCII_ARB */
+ { 23261, 0x000088A0 }, /* GL_PROGRAM_INSTRUCTIONS_ARB */
+ { 23289, 0x00008627 }, /* GL_PROGRAM_LENGTH_ARB */
+ { 23311, 0x00008627 }, /* GL_PROGRAM_LENGTH_NV */
+ { 23332, 0x000088B2 }, /* GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */
+ { 23372, 0x00008808 }, /* GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */
+ { 23411, 0x000088AE }, /* GL_PROGRAM_NATIVE_ATTRIBS_ARB */
+ { 23441, 0x000088A2 }, /* GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB */
+ { 23476, 0x000088AA }, /* GL_PROGRAM_NATIVE_PARAMETERS_ARB */
+ { 23509, 0x000088A6 }, /* GL_PROGRAM_NATIVE_TEMPORARIES_ARB */
+ { 23543, 0x0000880A }, /* GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */
+ { 23582, 0x00008809 }, /* GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */
+ { 23621, 0x00008B40 }, /* GL_PROGRAM_OBJECT_ARB */
+ { 23643, 0x000088A8 }, /* GL_PROGRAM_PARAMETERS_ARB */
+ { 23669, 0x00008644 }, /* GL_PROGRAM_PARAMETER_NV */
+ { 23693, 0x00008647 }, /* GL_PROGRAM_RESIDENT_NV */
+ { 23716, 0x00008628 }, /* GL_PROGRAM_STRING_ARB */
+ { 23738, 0x00008628 }, /* GL_PROGRAM_STRING_NV */
+ { 23759, 0x00008646 }, /* GL_PROGRAM_TARGET_NV */
+ { 23780, 0x000088A4 }, /* GL_PROGRAM_TEMPORARIES_ARB */
+ { 23807, 0x00008807 }, /* GL_PROGRAM_TEX_INDIRECTIONS_ARB */
+ { 23839, 0x00008806 }, /* GL_PROGRAM_TEX_INSTRUCTIONS_ARB */
+ { 23871, 0x000088B6 }, /* GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB */
+ { 23906, 0x00001701 }, /* GL_PROJECTION */
+ { 23920, 0x00000BA7 }, /* GL_PROJECTION_MATRIX */
+ { 23941, 0x00000BA4 }, /* GL_PROJECTION_STACK_DEPTH */
+ { 23967, 0x000080D3 }, /* GL_PROXY_COLOR_TABLE */
+ { 23988, 0x00008025 }, /* GL_PROXY_HISTOGRAM */
+ { 24007, 0x00008025 }, /* GL_PROXY_HISTOGRAM_EXT */
+ { 24030, 0x000080D5 }, /* GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE */
+ { 24069, 0x000080D4 }, /* GL_PROXY_POST_CONVOLUTION_COLOR_TABLE */
+ { 24107, 0x00008063 }, /* GL_PROXY_TEXTURE_1D */
+ { 24127, 0x00008063 }, /* GL_PROXY_TEXTURE_1D_EXT */
+ { 24151, 0x00008064 }, /* GL_PROXY_TEXTURE_2D */
+ { 24171, 0x00008064 }, /* GL_PROXY_TEXTURE_2D_EXT */
+ { 24195, 0x00008070 }, /* GL_PROXY_TEXTURE_3D */
+ { 24215, 0x000080BD }, /* GL_PROXY_TEXTURE_COLOR_TABLE_SGI */
+ { 24248, 0x0000851B }, /* GL_PROXY_TEXTURE_CUBE_MAP */
+ { 24274, 0x0000851B }, /* GL_PROXY_TEXTURE_CUBE_MAP_ARB */
+ { 24304, 0x000084F7 }, /* GL_PROXY_TEXTURE_RECTANGLE_ARB */
+ { 24335, 0x000084F7 }, /* GL_PROXY_TEXTURE_RECTANGLE_NV */
+ { 24365, 0x00002003 }, /* GL_Q */
+ { 24370, 0x00001209 }, /* GL_QUADRATIC_ATTENUATION */
+ { 24395, 0x00000007 }, /* GL_QUADS */
+ { 24404, 0x00008614 }, /* GL_QUAD_MESH_SUN */
+ { 24421, 0x00000008 }, /* GL_QUAD_STRIP */
+ { 24435, 0x00008864 }, /* GL_QUERY_COUNTER_BITS */
+ { 24457, 0x00008864 }, /* GL_QUERY_COUNTER_BITS_ARB */
+ { 24483, 0x00008866 }, /* GL_QUERY_RESULT */
+ { 24499, 0x00008866 }, /* GL_QUERY_RESULT_ARB */
+ { 24519, 0x00008867 }, /* GL_QUERY_RESULT_AVAILABLE */
+ { 24545, 0x00008867 }, /* GL_QUERY_RESULT_AVAILABLE_ARB */
+ { 24575, 0x00002002 }, /* GL_R */
+ { 24580, 0x00002A10 }, /* GL_R3_G3_B2 */
+ { 24592, 0x00019262 }, /* GL_RASTER_POSITION_UNCLIPPED_IBM */
+ { 24625, 0x00000C02 }, /* GL_READ_BUFFER */
+ { 24640, 0x000088B8 }, /* GL_READ_ONLY */
+ { 24653, 0x000088B8 }, /* GL_READ_ONLY_ARB */
+ { 24670, 0x000088BA }, /* GL_READ_WRITE */
+ { 24684, 0x000088BA }, /* GL_READ_WRITE_ARB */
+ { 24702, 0x00001903 }, /* GL_RED */
+ { 24709, 0x00008016 }, /* GL_REDUCE */
+ { 24719, 0x00008016 }, /* GL_REDUCE_EXT */
+ { 24733, 0x00000D15 }, /* GL_RED_BIAS */
+ { 24745, 0x00000D52 }, /* GL_RED_BITS */
+ { 24757, 0x00000D14 }, /* GL_RED_SCALE */
+ { 24770, 0x00008512 }, /* GL_REFLECTION_MAP */
+ { 24788, 0x00008512 }, /* GL_REFLECTION_MAP_ARB */
+ { 24810, 0x00008512 }, /* GL_REFLECTION_MAP_NV */
+ { 24831, 0x00001C00 }, /* GL_RENDER */
+ { 24841, 0x00008CA7 }, /* GL_RENDERBUFFER_BINDING_EXT */
+ { 24869, 0x00008D41 }, /* GL_RENDERBUFFER_EXT */
+ { 24889, 0x00008D43 }, /* GL_RENDERBUFFER_HEIGHT_EXT */
+ { 24916, 0x00008D44 }, /* GL_RENDERBUFFER_INTERNAL_FORMAT_EXT */
+ { 24952, 0x00008D42 }, /* GL_RENDERBUFFER_WIDTH_EXT */
+ { 24978, 0x00001F01 }, /* GL_RENDERER */
+ { 24990, 0x00000C40 }, /* GL_RENDER_MODE */
+ { 25005, 0x00002901 }, /* GL_REPEAT */
+ { 25015, 0x00001E01 }, /* GL_REPLACE */
+ { 25026, 0x00008062 }, /* GL_REPLACE_EXT */
+ { 25041, 0x00008153 }, /* GL_REPLICATE_BORDER_HP */
+ { 25064, 0x0000803A }, /* GL_RESCALE_NORMAL */
+ { 25082, 0x0000803A }, /* GL_RESCALE_NORMAL_EXT */
+ { 25104, 0x00000102 }, /* GL_RETURN */
+ { 25114, 0x00001907 }, /* GL_RGB */
+ { 25121, 0x00008052 }, /* GL_RGB10 */
+ { 25130, 0x00008059 }, /* GL_RGB10_A2 */
+ { 25142, 0x00008059 }, /* GL_RGB10_A2_EXT */
+ { 25158, 0x00008052 }, /* GL_RGB10_EXT */
+ { 25171, 0x00008053 }, /* GL_RGB12 */
+ { 25180, 0x00008053 }, /* GL_RGB12_EXT */
+ { 25193, 0x00008054 }, /* GL_RGB16 */
+ { 25202, 0x00008054 }, /* GL_RGB16_EXT */
+ { 25215, 0x0000804E }, /* GL_RGB2_EXT */
+ { 25227, 0x0000804F }, /* GL_RGB4 */
+ { 25235, 0x0000804F }, /* GL_RGB4_EXT */
+ { 25247, 0x000083A1 }, /* GL_RGB4_S3TC */
+ { 25260, 0x00008050 }, /* GL_RGB5 */
+ { 25268, 0x00008057 }, /* GL_RGB5_A1 */
+ { 25279, 0x00008057 }, /* GL_RGB5_A1_EXT */
+ { 25294, 0x00008050 }, /* GL_RGB5_EXT */
+ { 25306, 0x00008051 }, /* GL_RGB8 */
+ { 25314, 0x00008051 }, /* GL_RGB8_EXT */
+ { 25326, 0x00001908 }, /* GL_RGBA */
+ { 25334, 0x0000805A }, /* GL_RGBA12 */
+ { 25344, 0x0000805A }, /* GL_RGBA12_EXT */
+ { 25358, 0x0000805B }, /* GL_RGBA16 */
+ { 25368, 0x0000805B }, /* GL_RGBA16_EXT */
+ { 25382, 0x00008055 }, /* GL_RGBA2 */
+ { 25391, 0x00008055 }, /* GL_RGBA2_EXT */
+ { 25404, 0x00008056 }, /* GL_RGBA4 */
+ { 25413, 0x000083A5 }, /* GL_RGBA4_DXT5_S3TC */
+ { 25432, 0x00008056 }, /* GL_RGBA4_EXT */
+ { 25445, 0x000083A3 }, /* GL_RGBA4_S3TC */
+ { 25459, 0x00008058 }, /* GL_RGBA8 */
+ { 25468, 0x00008058 }, /* GL_RGBA8_EXT */
+ { 25481, 0x000083A4 }, /* GL_RGBA_DXT5_S3TC */
+ { 25499, 0x00000C31 }, /* GL_RGBA_MODE */
+ { 25512, 0x000083A2 }, /* GL_RGBA_S3TC */
+ { 25525, 0x000083A0 }, /* GL_RGB_S3TC */
+ { 25537, 0x00008573 }, /* GL_RGB_SCALE */
+ { 25550, 0x00008573 }, /* GL_RGB_SCALE_ARB */
+ { 25567, 0x00008573 }, /* GL_RGB_SCALE_EXT */
+ { 25584, 0x00000407 }, /* GL_RIGHT */
+ { 25593, 0x00002000 }, /* GL_S */
+ { 25598, 0x000080A9 }, /* GL_SAMPLES */
+ { 25609, 0x000086B4 }, /* GL_SAMPLES_3DFX */
+ { 25625, 0x000080A9 }, /* GL_SAMPLES_ARB */
+ { 25640, 0x00008914 }, /* GL_SAMPLES_PASSED */
+ { 25658, 0x00008914 }, /* GL_SAMPLES_PASSED_ARB */
+ { 25680, 0x0000809E }, /* GL_SAMPLE_ALPHA_TO_COVERAGE */
+ { 25708, 0x0000809E }, /* GL_SAMPLE_ALPHA_TO_COVERAGE_ARB */
+ { 25740, 0x0000809F }, /* GL_SAMPLE_ALPHA_TO_ONE */
+ { 25763, 0x0000809F }, /* GL_SAMPLE_ALPHA_TO_ONE_ARB */
+ { 25790, 0x000080A8 }, /* GL_SAMPLE_BUFFERS */
+ { 25808, 0x000086B3 }, /* GL_SAMPLE_BUFFERS_3DFX */
+ { 25831, 0x000080A8 }, /* GL_SAMPLE_BUFFERS_ARB */
+ { 25853, 0x000080A0 }, /* GL_SAMPLE_COVERAGE */
+ { 25872, 0x000080A0 }, /* GL_SAMPLE_COVERAGE_ARB */
+ { 25895, 0x000080AB }, /* GL_SAMPLE_COVERAGE_INVERT */
+ { 25921, 0x000080AB }, /* GL_SAMPLE_COVERAGE_INVERT_ARB */
+ { 25951, 0x000080AA }, /* GL_SAMPLE_COVERAGE_VALUE */
+ { 25976, 0x000080AA }, /* GL_SAMPLE_COVERAGE_VALUE_ARB */
+ { 26005, 0x00080000 }, /* GL_SCISSOR_BIT */
+ { 26020, 0x00000C10 }, /* GL_SCISSOR_BOX */
+ { 26035, 0x00000C11 }, /* GL_SCISSOR_TEST */
+ { 26051, 0x0000845E }, /* GL_SECONDARY_COLOR_ARRAY */
+ { 26076, 0x0000889C }, /* GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING */
+ { 26116, 0x0000889C }, /* GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB */
+ { 26160, 0x0000845D }, /* GL_SECONDARY_COLOR_ARRAY_POINTER */
+ { 26193, 0x0000845A }, /* GL_SECONDARY_COLOR_ARRAY_SIZE */
+ { 26223, 0x0000845C }, /* GL_SECONDARY_COLOR_ARRAY_STRIDE */
+ { 26255, 0x0000845B }, /* GL_SECONDARY_COLOR_ARRAY_TYPE */
+ { 26285, 0x00001C02 }, /* GL_SELECT */
+ { 26295, 0x00000DF3 }, /* GL_SELECTION_BUFFER_POINTER */
+ { 26323, 0x00000DF4 }, /* GL_SELECTION_BUFFER_SIZE */
+ { 26348, 0x00008012 }, /* GL_SEPARABLE_2D */
+ { 26364, 0x000081FA }, /* GL_SEPARATE_SPECULAR_COLOR */
+ { 26391, 0x000081FA }, /* GL_SEPARATE_SPECULAR_COLOR_EXT */
+ { 26422, 0x0000150F }, /* GL_SET */
+ { 26429, 0x00008B48 }, /* GL_SHADER_OBJECT_ARB */
+ { 26450, 0x00000B54 }, /* GL_SHADE_MODEL */
+ { 26465, 0x000080BF }, /* GL_SHADOW_AMBIENT_SGIX */
+ { 26488, 0x000081FB }, /* GL_SHARED_TEXTURE_PALETTE_EXT */
+ { 26518, 0x00001601 }, /* GL_SHININESS */
+ { 26531, 0x00001402 }, /* GL_SHORT */
+ { 26540, 0x000081F9 }, /* GL_SINGLE_COLOR */
+ { 26556, 0x000081F9 }, /* GL_SINGLE_COLOR_EXT */
+ { 26576, 0x000085CC }, /* GL_SLICE_ACCUM_SUN */
+ { 26595, 0x00001D01 }, /* GL_SMOOTH */
+ { 26605, 0x00000B23 }, /* GL_SMOOTH_LINE_WIDTH_GRANULARITY */
+ { 26638, 0x00000B22 }, /* GL_SMOOTH_LINE_WIDTH_RANGE */
+ { 26665, 0x00000B13 }, /* GL_SMOOTH_POINT_SIZE_GRANULARITY */
+ { 26698, 0x00000B12 }, /* GL_SMOOTH_POINT_SIZE_RANGE */
+ { 26725, 0x00008588 }, /* GL_SOURCE0_ALPHA */
+ { 26742, 0x00008588 }, /* GL_SOURCE0_ALPHA_ARB */
+ { 26763, 0x00008588 }, /* GL_SOURCE0_ALPHA_EXT */
+ { 26784, 0x00008580 }, /* GL_SOURCE0_RGB */
+ { 26799, 0x00008580 }, /* GL_SOURCE0_RGB_ARB */
+ { 26818, 0x00008580 }, /* GL_SOURCE0_RGB_EXT */
+ { 26837, 0x00008589 }, /* GL_SOURCE1_ALPHA */
+ { 26854, 0x00008589 }, /* GL_SOURCE1_ALPHA_ARB */
+ { 26875, 0x00008589 }, /* GL_SOURCE1_ALPHA_EXT */
+ { 26896, 0x00008581 }, /* GL_SOURCE1_RGB */
+ { 26911, 0x00008581 }, /* GL_SOURCE1_RGB_ARB */
+ { 26930, 0x00008581 }, /* GL_SOURCE1_RGB_EXT */
+ { 26949, 0x0000858A }, /* GL_SOURCE2_ALPHA */
+ { 26966, 0x0000858A }, /* GL_SOURCE2_ALPHA_ARB */
+ { 26987, 0x0000858A }, /* GL_SOURCE2_ALPHA_EXT */
+ { 27008, 0x00008582 }, /* GL_SOURCE2_RGB */
+ { 27023, 0x00008582 }, /* GL_SOURCE2_RGB_ARB */
+ { 27042, 0x00008582 }, /* GL_SOURCE2_RGB_EXT */
+ { 27061, 0x0000858B }, /* GL_SOURCE3_ALPHA_NV */
+ { 27081, 0x00008583 }, /* GL_SOURCE3_RGB_NV */
+ { 27099, 0x00001202 }, /* GL_SPECULAR */
+ { 27111, 0x00002402 }, /* GL_SPHERE_MAP */
+ { 27125, 0x00001206 }, /* GL_SPOT_CUTOFF */
+ { 27140, 0x00001204 }, /* GL_SPOT_DIRECTION */
+ { 27158, 0x00001205 }, /* GL_SPOT_EXPONENT */
+ { 27175, 0x00008588 }, /* GL_SRC0_ALPHA */
+ { 27189, 0x00008580 }, /* GL_SRC0_RGB */
+ { 27201, 0x00008589 }, /* GL_SRC1_ALPHA */
+ { 27215, 0x00008581 }, /* GL_SRC1_RGB */
+ { 27227, 0x0000858A }, /* GL_SRC2_ALPHA */
+ { 27241, 0x00008582 }, /* GL_SRC2_RGB */
+ { 27253, 0x00000302 }, /* GL_SRC_ALPHA */
+ { 27266, 0x00000308 }, /* GL_SRC_ALPHA_SATURATE */
+ { 27288, 0x00000300 }, /* GL_SRC_COLOR */
+ { 27301, 0x00000503 }, /* GL_STACK_OVERFLOW */
+ { 27319, 0x00000504 }, /* GL_STACK_UNDERFLOW */
+ { 27338, 0x000088E6 }, /* GL_STATIC_COPY */
+ { 27353, 0x000088E6 }, /* GL_STATIC_COPY_ARB */
+ { 27372, 0x000088E4 }, /* GL_STATIC_DRAW */
+ { 27387, 0x000088E4 }, /* GL_STATIC_DRAW_ARB */
+ { 27406, 0x000088E5 }, /* GL_STATIC_READ */
+ { 27421, 0x000088E5 }, /* GL_STATIC_READ_ARB */
+ { 27440, 0x00001802 }, /* GL_STENCIL */
+ { 27451, 0x00008D20 }, /* GL_STENCIL_ATTACHMENT_EXT */
+ { 27477, 0x00000D57 }, /* GL_STENCIL_BITS */
+ { 27493, 0x00000400 }, /* GL_STENCIL_BUFFER_BIT */
+ { 27515, 0x00000B91 }, /* GL_STENCIL_CLEAR_VALUE */
+ { 27538, 0x00000B94 }, /* GL_STENCIL_FAIL */
+ { 27554, 0x00000B92 }, /* GL_STENCIL_FUNC */
+ { 27570, 0x00001901 }, /* GL_STENCIL_INDEX */
+ { 27587, 0x00008D49 }, /* GL_STENCIL_INDEX16_EXT */
+ { 27610, 0x00008D46 }, /* GL_STENCIL_INDEX1_EXT */
+ { 27632, 0x00008D47 }, /* GL_STENCIL_INDEX4_EXT */
+ { 27654, 0x00008D48 }, /* GL_STENCIL_INDEX8_EXT */
+ { 27676, 0x00008D45 }, /* GL_STENCIL_INDEX_EXT */
+ { 27697, 0x00000B95 }, /* GL_STENCIL_PASS_DEPTH_FAIL */
+ { 27724, 0x00000B96 }, /* GL_STENCIL_PASS_DEPTH_PASS */
+ { 27751, 0x00000B97 }, /* GL_STENCIL_REF */
+ { 27766, 0x00000B90 }, /* GL_STENCIL_TEST */
+ { 27782, 0x00008910 }, /* GL_STENCIL_TEST_TWO_SIDE_EXT */
+ { 27811, 0x00000B93 }, /* GL_STENCIL_VALUE_MASK */
+ { 27833, 0x00000B98 }, /* GL_STENCIL_WRITEMASK */
+ { 27854, 0x00000C33 }, /* GL_STEREO */
+ { 27864, 0x000088E2 }, /* GL_STREAM_COPY */
+ { 27879, 0x000088E2 }, /* GL_STREAM_COPY_ARB */
+ { 27898, 0x000088E0 }, /* GL_STREAM_DRAW */
+ { 27913, 0x000088E0 }, /* GL_STREAM_DRAW_ARB */
+ { 27932, 0x000088E1 }, /* GL_STREAM_READ */
+ { 27947, 0x000088E1 }, /* GL_STREAM_READ_ARB */
+ { 27966, 0x00000D50 }, /* GL_SUBPIXEL_BITS */
+ { 27983, 0x000084E7 }, /* GL_SUBTRACT */
+ { 27995, 0x000084E7 }, /* GL_SUBTRACT_ARB */
+ { 28011, 0x00002001 }, /* GL_T */
+ { 28016, 0x00002A2A }, /* GL_T2F_C3F_V3F */
+ { 28031, 0x00002A2C }, /* GL_T2F_C4F_N3F_V3F */
+ { 28050, 0x00002A29 }, /* GL_T2F_C4UB_V3F */
+ { 28066, 0x00002A2B }, /* GL_T2F_N3F_V3F */
+ { 28081, 0x00002A27 }, /* GL_T2F_V3F */
+ { 28092, 0x00002A2D }, /* GL_T4F_C4F_N3F_V4F */
+ { 28111, 0x00002A28 }, /* GL_T4F_V4F */
+ { 28122, 0x00008031 }, /* GL_TABLE_TOO_LARGE_EXT */
+ { 28145, 0x00001702 }, /* GL_TEXTURE */
+ { 28156, 0x000084C0 }, /* GL_TEXTURE0 */
+ { 28168, 0x000084C0 }, /* GL_TEXTURE0_ARB */
+ { 28184, 0x000084C1 }, /* GL_TEXTURE1 */
+ { 28196, 0x000084CA }, /* GL_TEXTURE10 */
+ { 28209, 0x000084CA }, /* GL_TEXTURE10_ARB */
+ { 28226, 0x000084CB }, /* GL_TEXTURE11 */
+ { 28239, 0x000084CB }, /* GL_TEXTURE11_ARB */
+ { 28256, 0x000084CC }, /* GL_TEXTURE12 */
+ { 28269, 0x000084CC }, /* GL_TEXTURE12_ARB */
+ { 28286, 0x000084CD }, /* GL_TEXTURE13 */
+ { 28299, 0x000084CD }, /* GL_TEXTURE13_ARB */
+ { 28316, 0x000084CE }, /* GL_TEXTURE14 */
+ { 28329, 0x000084CE }, /* GL_TEXTURE14_ARB */
+ { 28346, 0x000084CF }, /* GL_TEXTURE15 */
+ { 28359, 0x000084CF }, /* GL_TEXTURE15_ARB */
+ { 28376, 0x000084D0 }, /* GL_TEXTURE16 */
+ { 28389, 0x000084D0 }, /* GL_TEXTURE16_ARB */
+ { 28406, 0x000084D1 }, /* GL_TEXTURE17 */
+ { 28419, 0x000084D1 }, /* GL_TEXTURE17_ARB */
+ { 28436, 0x000084D2 }, /* GL_TEXTURE18 */
+ { 28449, 0x000084D2 }, /* GL_TEXTURE18_ARB */
+ { 28466, 0x000084D3 }, /* GL_TEXTURE19 */
+ { 28479, 0x000084D3 }, /* GL_TEXTURE19_ARB */
+ { 28496, 0x000084C1 }, /* GL_TEXTURE1_ARB */
+ { 28512, 0x000084C2 }, /* GL_TEXTURE2 */
+ { 28524, 0x000084D4 }, /* GL_TEXTURE20 */
+ { 28537, 0x000084D4 }, /* GL_TEXTURE20_ARB */
+ { 28554, 0x000084D5 }, /* GL_TEXTURE21 */
+ { 28567, 0x000084D5 }, /* GL_TEXTURE21_ARB */
+ { 28584, 0x000084D6 }, /* GL_TEXTURE22 */
+ { 28597, 0x000084D6 }, /* GL_TEXTURE22_ARB */
+ { 28614, 0x000084D7 }, /* GL_TEXTURE23 */
+ { 28627, 0x000084D7 }, /* GL_TEXTURE23_ARB */
+ { 28644, 0x000084D8 }, /* GL_TEXTURE24 */
+ { 28657, 0x000084D8 }, /* GL_TEXTURE24_ARB */
+ { 28674, 0x000084D9 }, /* GL_TEXTURE25 */
+ { 28687, 0x000084D9 }, /* GL_TEXTURE25_ARB */
+ { 28704, 0x000084DA }, /* GL_TEXTURE26 */
+ { 28717, 0x000084DA }, /* GL_TEXTURE26_ARB */
+ { 28734, 0x000084DB }, /* GL_TEXTURE27 */
+ { 28747, 0x000084DB }, /* GL_TEXTURE27_ARB */
+ { 28764, 0x000084DC }, /* GL_TEXTURE28 */
+ { 28777, 0x000084DC }, /* GL_TEXTURE28_ARB */
+ { 28794, 0x000084DD }, /* GL_TEXTURE29 */
+ { 28807, 0x000084DD }, /* GL_TEXTURE29_ARB */
+ { 28824, 0x000084C2 }, /* GL_TEXTURE2_ARB */
+ { 28840, 0x000084C3 }, /* GL_TEXTURE3 */
+ { 28852, 0x000084DE }, /* GL_TEXTURE30 */
+ { 28865, 0x000084DE }, /* GL_TEXTURE30_ARB */
+ { 28882, 0x000084DF }, /* GL_TEXTURE31 */
+ { 28895, 0x000084DF }, /* GL_TEXTURE31_ARB */
+ { 28912, 0x000084C3 }, /* GL_TEXTURE3_ARB */
+ { 28928, 0x000084C4 }, /* GL_TEXTURE4 */
+ { 28940, 0x000084C4 }, /* GL_TEXTURE4_ARB */
+ { 28956, 0x000084C5 }, /* GL_TEXTURE5 */
+ { 28968, 0x000084C5 }, /* GL_TEXTURE5_ARB */
+ { 28984, 0x000084C6 }, /* GL_TEXTURE6 */
+ { 28996, 0x000084C6 }, /* GL_TEXTURE6_ARB */
+ { 29012, 0x000084C7 }, /* GL_TEXTURE7 */
+ { 29024, 0x000084C7 }, /* GL_TEXTURE7_ARB */
+ { 29040, 0x000084C8 }, /* GL_TEXTURE8 */
+ { 29052, 0x000084C8 }, /* GL_TEXTURE8_ARB */
+ { 29068, 0x000084C9 }, /* GL_TEXTURE9 */
+ { 29080, 0x000084C9 }, /* GL_TEXTURE9_ARB */
+ { 29096, 0x00000DE0 }, /* GL_TEXTURE_1D */
+ { 29110, 0x00000DE1 }, /* GL_TEXTURE_2D */
+ { 29124, 0x0000806F }, /* GL_TEXTURE_3D */
+ { 29138, 0x0000805F }, /* GL_TEXTURE_ALPHA_SIZE */
+ { 29160, 0x0000805F }, /* GL_TEXTURE_ALPHA_SIZE_EXT */
+ { 29186, 0x0000813C }, /* GL_TEXTURE_BASE_LEVEL */
+ { 29208, 0x00008068 }, /* GL_TEXTURE_BINDING_1D */
+ { 29230, 0x00008069 }, /* GL_TEXTURE_BINDING_2D */
+ { 29252, 0x0000806A }, /* GL_TEXTURE_BINDING_3D */
+ { 29274, 0x00008514 }, /* GL_TEXTURE_BINDING_CUBE_MAP */
+ { 29302, 0x00008514 }, /* GL_TEXTURE_BINDING_CUBE_MAP_ARB */
+ { 29334, 0x000084F6 }, /* GL_TEXTURE_BINDING_RECTANGLE_ARB */
+ { 29367, 0x000084F6 }, /* GL_TEXTURE_BINDING_RECTANGLE_NV */
+ { 29399, 0x00040000 }, /* GL_TEXTURE_BIT */
+ { 29414, 0x0000805E }, /* GL_TEXTURE_BLUE_SIZE */
+ { 29435, 0x0000805E }, /* GL_TEXTURE_BLUE_SIZE_EXT */
+ { 29460, 0x00001005 }, /* GL_TEXTURE_BORDER */
+ { 29478, 0x00001004 }, /* GL_TEXTURE_BORDER_COLOR */
+ { 29502, 0x00008171 }, /* GL_TEXTURE_CLIPMAP_CENTER_SGIX */
+ { 29533, 0x00008176 }, /* GL_TEXTURE_CLIPMAP_DEPTH_SGIX */
+ { 29563, 0x00008172 }, /* GL_TEXTURE_CLIPMAP_FRAME_SGIX */
+ { 29593, 0x00008175 }, /* GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX */
+ { 29628, 0x00008173 }, /* GL_TEXTURE_CLIPMAP_OFFSET_SGIX */
+ { 29659, 0x00008174 }, /* GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX */
+ { 29697, 0x000080BC }, /* GL_TEXTURE_COLOR_TABLE_SGI */
+ { 29724, 0x000081EF }, /* GL_TEXTURE_COLOR_WRITEMASK_SGIS */
+ { 29756, 0x000080BF }, /* GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
+ { 29790, 0x0000884D }, /* GL_TEXTURE_COMPARE_FUNC */
+ { 29814, 0x0000884D }, /* GL_TEXTURE_COMPARE_FUNC_ARB */
+ { 29842, 0x0000884C }, /* GL_TEXTURE_COMPARE_MODE */
+ { 29866, 0x0000884C }, /* GL_TEXTURE_COMPARE_MODE_ARB */
+ { 29894, 0x0000819B }, /* GL_TEXTURE_COMPARE_OPERATOR_SGIX */
+ { 29927, 0x0000819A }, /* GL_TEXTURE_COMPARE_SGIX */
+ { 29951, 0x00001003 }, /* GL_TEXTURE_COMPONENTS */
+ { 29973, 0x000086A1 }, /* GL_TEXTURE_COMPRESSED */
+ { 29995, 0x000086A1 }, /* GL_TEXTURE_COMPRESSED_ARB */
+ { 30021, 0x000086A3 }, /* GL_TEXTURE_COMPRESSED_FORMATS_ARB */
+ { 30055, 0x000086A0 }, /* GL_TEXTURE_COMPRESSED_IMAGE_SIZE */
+ { 30088, 0x000086A0 }, /* GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB */
+ { 30125, 0x000084EF }, /* GL_TEXTURE_COMPRESSION_HINT */
+ { 30153, 0x000084EF }, /* GL_TEXTURE_COMPRESSION_HINT_ARB */
+ { 30185, 0x00008078 }, /* GL_TEXTURE_COORD_ARRAY */
+ { 30208, 0x0000889A }, /* GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING */
+ { 30246, 0x0000889A }, /* GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB */
+ { 30288, 0x00008092 }, /* GL_TEXTURE_COORD_ARRAY_POINTER */
+ { 30319, 0x00008088 }, /* GL_TEXTURE_COORD_ARRAY_SIZE */
+ { 30347, 0x0000808A }, /* GL_TEXTURE_COORD_ARRAY_STRIDE */
+ { 30377, 0x00008089 }, /* GL_TEXTURE_COORD_ARRAY_TYPE */
+ { 30405, 0x00008513 }, /* GL_TEXTURE_CUBE_MAP */
+ { 30425, 0x00008513 }, /* GL_TEXTURE_CUBE_MAP_ARB */
+ { 30449, 0x00008516 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X */
+ { 30480, 0x00008516 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB */
+ { 30515, 0x00008518 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y */
+ { 30546, 0x00008518 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB */
+ { 30581, 0x0000851A }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z */
+ { 30612, 0x0000851A }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB */
+ { 30647, 0x00008515 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_X */
+ { 30678, 0x00008515 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB */
+ { 30713, 0x00008517 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y */
+ { 30744, 0x00008517 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB */
+ { 30779, 0x00008519 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z */
+ { 30810, 0x00008519 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB */
+ { 30845, 0x00008071 }, /* GL_TEXTURE_DEPTH */
+ { 30862, 0x0000884A }, /* GL_TEXTURE_DEPTH_SIZE */
+ { 30884, 0x0000884A }, /* GL_TEXTURE_DEPTH_SIZE_ARB */
+ { 30910, 0x00002300 }, /* GL_TEXTURE_ENV */
+ { 30925, 0x00002201 }, /* GL_TEXTURE_ENV_COLOR */
+ { 30946, 0x00002200 }, /* GL_TEXTURE_ENV_MODE */
+ { 30966, 0x00008500 }, /* GL_TEXTURE_FILTER_CONTROL */
+ { 30992, 0x00002500 }, /* GL_TEXTURE_GEN_MODE */
+ { 31012, 0x00000C63 }, /* GL_TEXTURE_GEN_Q */
+ { 31029, 0x00000C62 }, /* GL_TEXTURE_GEN_R */
+ { 31046, 0x00000C60 }, /* GL_TEXTURE_GEN_S */
+ { 31063, 0x00000C61 }, /* GL_TEXTURE_GEN_T */
+ { 31080, 0x0000819D }, /* GL_TEXTURE_GEQUAL_R_SGIX */
+ { 31105, 0x0000805D }, /* GL_TEXTURE_GREEN_SIZE */
+ { 31127, 0x0000805D }, /* GL_TEXTURE_GREEN_SIZE_EXT */
+ { 31153, 0x00001001 }, /* GL_TEXTURE_HEIGHT */
+ { 31171, 0x000080ED }, /* GL_TEXTURE_INDEX_SIZE_EXT */
+ { 31197, 0x00008061 }, /* GL_TEXTURE_INTENSITY_SIZE */
+ { 31223, 0x00008061 }, /* GL_TEXTURE_INTENSITY_SIZE_EXT */
+ { 31253, 0x00001003 }, /* GL_TEXTURE_INTERNAL_FORMAT */
+ { 31280, 0x0000819C }, /* GL_TEXTURE_LEQUAL_R_SGIX */
+ { 31305, 0x00008501 }, /* GL_TEXTURE_LOD_BIAS */
+ { 31325, 0x00008501 }, /* GL_TEXTURE_LOD_BIAS_EXT */
+ { 31349, 0x00008190 }, /* GL_TEXTURE_LOD_BIAS_R_SGIX */
+ { 31376, 0x0000818E }, /* GL_TEXTURE_LOD_BIAS_S_SGIX */
+ { 31403, 0x0000818F }, /* GL_TEXTURE_LOD_BIAS_T_SGIX */
+ { 31430, 0x00008060 }, /* GL_TEXTURE_LUMINANCE_SIZE */
+ { 31456, 0x00008060 }, /* GL_TEXTURE_LUMINANCE_SIZE_EXT */
+ { 31486, 0x00002800 }, /* GL_TEXTURE_MAG_FILTER */
+ { 31508, 0x00000BA8 }, /* GL_TEXTURE_MATRIX */
+ { 31526, 0x000084FE }, /* GL_TEXTURE_MAX_ANISOTROPY_EXT */
+ { 31556, 0x0000836B }, /* GL_TEXTURE_MAX_CLAMP_R_SGIX */
+ { 31584, 0x00008369 }, /* GL_TEXTURE_MAX_CLAMP_S_SGIX */
+ { 31612, 0x0000836A }, /* GL_TEXTURE_MAX_CLAMP_T_SGIX */
+ { 31640, 0x0000813D }, /* GL_TEXTURE_MAX_LEVEL */
+ { 31661, 0x0000813B }, /* GL_TEXTURE_MAX_LOD */
+ { 31680, 0x00002801 }, /* GL_TEXTURE_MIN_FILTER */
+ { 31702, 0x0000813A }, /* GL_TEXTURE_MIN_LOD */
+ { 31721, 0x00008066 }, /* GL_TEXTURE_PRIORITY */
+ { 31741, 0x000084F5 }, /* GL_TEXTURE_RECTANGLE_ARB */
+ { 31766, 0x000084F5 }, /* GL_TEXTURE_RECTANGLE_NV */
+ { 31790, 0x0000805C }, /* GL_TEXTURE_RED_SIZE */
+ { 31810, 0x0000805C }, /* GL_TEXTURE_RED_SIZE_EXT */
+ { 31834, 0x00008067 }, /* GL_TEXTURE_RESIDENT */
+ { 31854, 0x00000BA5 }, /* GL_TEXTURE_STACK_DEPTH */
+ { 31877, 0x00008065 }, /* GL_TEXTURE_TOO_LARGE_EXT */
+ { 31902, 0x0000888F }, /* GL_TEXTURE_UNSIGNED_REMAP_MODE_NV */
+ { 31936, 0x00001000 }, /* GL_TEXTURE_WIDTH */
+ { 31953, 0x00008072 }, /* GL_TEXTURE_WRAP_R */
+ { 31971, 0x00002802 }, /* GL_TEXTURE_WRAP_S */
+ { 31989, 0x00002803 }, /* GL_TEXTURE_WRAP_T */
+ { 32007, 0x00008648 }, /* GL_TRACK_MATRIX_NV */
+ { 32026, 0x00008649 }, /* GL_TRACK_MATRIX_TRANSFORM_NV */
+ { 32055, 0x00001000 }, /* GL_TRANSFORM_BIT */
+ { 32072, 0x000084E6 }, /* GL_TRANSPOSE_COLOR_MATRIX */
+ { 32098, 0x000084E6 }, /* GL_TRANSPOSE_COLOR_MATRIX_ARB */
+ { 32128, 0x000088B7 }, /* GL_TRANSPOSE_CURRENT_MATRIX_ARB */
+ { 32160, 0x000084E3 }, /* GL_TRANSPOSE_MODELVIEW_MATRIX */
+ { 32190, 0x000084E3 }, /* GL_TRANSPOSE_MODELVIEW_MATRIX_ARB */
+ { 32224, 0x0000862C }, /* GL_TRANSPOSE_NV */
+ { 32240, 0x000084E4 }, /* GL_TRANSPOSE_PROJECTION_MATRIX */
+ { 32271, 0x000084E4 }, /* GL_TRANSPOSE_PROJECTION_MATRIX_ARB */
+ { 32306, 0x000084E5 }, /* GL_TRANSPOSE_TEXTURE_MATRIX */
+ { 32334, 0x000084E5 }, /* GL_TRANSPOSE_TEXTURE_MATRIX_ARB */
+ { 32366, 0x00000004 }, /* GL_TRIANGLES */
+ { 32379, 0x00000006 }, /* GL_TRIANGLE_FAN */
+ { 32395, 0x00008615 }, /* GL_TRIANGLE_MESH_SUN */
+ { 32416, 0x00000005 }, /* GL_TRIANGLE_STRIP */
+ { 32434, 0x00000001 }, /* GL_TRUE */
+ { 32442, 0x00000CF5 }, /* GL_UNPACK_ALIGNMENT */
+ { 32462, 0x0000806E }, /* GL_UNPACK_IMAGE_HEIGHT */
+ { 32485, 0x00000CF1 }, /* GL_UNPACK_LSB_FIRST */
+ { 32505, 0x00000CF2 }, /* GL_UNPACK_ROW_LENGTH */
+ { 32526, 0x0000806D }, /* GL_UNPACK_SKIP_IMAGES */
+ { 32548, 0x00000CF4 }, /* GL_UNPACK_SKIP_PIXELS */
+ { 32570, 0x00000CF3 }, /* GL_UNPACK_SKIP_ROWS */
+ { 32590, 0x00000CF0 }, /* GL_UNPACK_SWAP_BYTES */
+ { 32611, 0x00001401 }, /* GL_UNSIGNED_BYTE */
+ { 32628, 0x00008362 }, /* GL_UNSIGNED_BYTE_2_3_3_REV */
+ { 32655, 0x00008032 }, /* GL_UNSIGNED_BYTE_3_3_2 */
+ { 32678, 0x00001405 }, /* GL_UNSIGNED_INT */
+ { 32694, 0x00008036 }, /* GL_UNSIGNED_INT_10_10_10_2 */
+ { 32721, 0x000084FA }, /* GL_UNSIGNED_INT_24_8_NV */
+ { 32745, 0x00008368 }, /* GL_UNSIGNED_INT_2_10_10_10_REV */
+ { 32776, 0x00008035 }, /* GL_UNSIGNED_INT_8_8_8_8 */
+ { 32800, 0x00008367 }, /* GL_UNSIGNED_INT_8_8_8_8_REV */
+ { 32828, 0x00001403 }, /* GL_UNSIGNED_SHORT */
+ { 32846, 0x00008366 }, /* GL_UNSIGNED_SHORT_1_5_5_5_REV */
+ { 32876, 0x00008033 }, /* GL_UNSIGNED_SHORT_4_4_4_4 */
+ { 32902, 0x00008365 }, /* GL_UNSIGNED_SHORT_4_4_4_4_REV */
+ { 32932, 0x00008034 }, /* GL_UNSIGNED_SHORT_5_5_5_1 */
+ { 32958, 0x00008363 }, /* GL_UNSIGNED_SHORT_5_6_5 */
+ { 32982, 0x00008364 }, /* GL_UNSIGNED_SHORT_5_6_5_REV */
+ { 33010, 0x000085BA }, /* GL_UNSIGNED_SHORT_8_8_APPLE */
+ { 33038, 0x000085BA }, /* GL_UNSIGNED_SHORT_8_8_MESA */
+ { 33065, 0x000085BB }, /* GL_UNSIGNED_SHORT_8_8_REV_APPLE */
+ { 33097, 0x000085BB }, /* GL_UNSIGNED_SHORT_8_8_REV_MESA */
+ { 33128, 0x00002A20 }, /* GL_V2F */
+ { 33135, 0x00002A21 }, /* GL_V3F */
+ { 33142, 0x00001F00 }, /* GL_VENDOR */
+ { 33152, 0x00001F02 }, /* GL_VERSION */
+ { 33163, 0x00008074 }, /* GL_VERTEX_ARRAY */
+ { 33179, 0x00008896 }, /* GL_VERTEX_ARRAY_BUFFER_BINDING */
+ { 33210, 0x00008896 }, /* GL_VERTEX_ARRAY_BUFFER_BINDING_ARB */
+ { 33245, 0x0000808E }, /* GL_VERTEX_ARRAY_POINTER */
+ { 33269, 0x0000807A }, /* GL_VERTEX_ARRAY_SIZE */
+ { 33290, 0x0000807C }, /* GL_VERTEX_ARRAY_STRIDE */
+ { 33313, 0x0000807B }, /* GL_VERTEX_ARRAY_TYPE */
+ { 33334, 0x00008650 }, /* GL_VERTEX_ATTRIB_ARRAY0_NV */
+ { 33361, 0x0000865A }, /* GL_VERTEX_ATTRIB_ARRAY10_NV */
+ { 33389, 0x0000865B }, /* GL_VERTEX_ATTRIB_ARRAY11_NV */
+ { 33417, 0x0000865C }, /* GL_VERTEX_ATTRIB_ARRAY12_NV */
+ { 33445, 0x0000865D }, /* GL_VERTEX_ATTRIB_ARRAY13_NV */
+ { 33473, 0x0000865E }, /* GL_VERTEX_ATTRIB_ARRAY14_NV */
+ { 33501, 0x0000865F }, /* GL_VERTEX_ATTRIB_ARRAY15_NV */
+ { 33529, 0x00008651 }, /* GL_VERTEX_ATTRIB_ARRAY1_NV */
+ { 33556, 0x00008652 }, /* GL_VERTEX_ATTRIB_ARRAY2_NV */
+ { 33583, 0x00008653 }, /* GL_VERTEX_ATTRIB_ARRAY3_NV */
+ { 33610, 0x00008654 }, /* GL_VERTEX_ATTRIB_ARRAY4_NV */
+ { 33637, 0x00008655 }, /* GL_VERTEX_ATTRIB_ARRAY5_NV */
+ { 33664, 0x00008656 }, /* GL_VERTEX_ATTRIB_ARRAY6_NV */
+ { 33691, 0x00008657 }, /* GL_VERTEX_ATTRIB_ARRAY7_NV */
+ { 33718, 0x00008658 }, /* GL_VERTEX_ATTRIB_ARRAY8_NV */
+ { 33745, 0x00008659 }, /* GL_VERTEX_ATTRIB_ARRAY9_NV */
+ { 33772, 0x0000889F }, /* GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING */
+ { 33810, 0x0000889F }, /* GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB */
+ { 33852, 0x00008622 }, /* GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB */
+ { 33887, 0x0000886A }, /* GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB */
+ { 33925, 0x00008645 }, /* GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB */
+ { 33960, 0x00008623 }, /* GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB */
+ { 33992, 0x00008624 }, /* GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB */
+ { 34026, 0x00008625 }, /* GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB */
+ { 34058, 0x000086A7 }, /* GL_VERTEX_BLEND_ARB */
+ { 34078, 0x00008620 }, /* GL_VERTEX_PROGRAM_ARB */
+ { 34100, 0x0000864A }, /* GL_VERTEX_PROGRAM_BINDING_NV */
+ { 34129, 0x00008620 }, /* GL_VERTEX_PROGRAM_NV */
+ { 34150, 0x00008642 }, /* GL_VERTEX_PROGRAM_POINT_SIZE_ARB */
+ { 34183, 0x00008642 }, /* GL_VERTEX_PROGRAM_POINT_SIZE_NV */
+ { 34215, 0x00008643 }, /* GL_VERTEX_PROGRAM_TWO_SIDE_ARB */
+ { 34246, 0x00008643 }, /* GL_VERTEX_PROGRAM_TWO_SIDE_NV */
+ { 34276, 0x00008B31 }, /* GL_VERTEX_SHADER_ARB */
+ { 34297, 0x00008621 }, /* GL_VERTEX_STATE_PROGRAM_NV */
+ { 34324, 0x00000BA2 }, /* GL_VIEWPORT */
+ { 34336, 0x00000800 }, /* GL_VIEWPORT_BIT */
+ { 34352, 0x000086AD }, /* GL_WEIGHT_ARRAY_ARB */
+ { 34372, 0x0000889E }, /* GL_WEIGHT_ARRAY_BUFFER_BINDING */
+ { 34403, 0x0000889E }, /* GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB */
+ { 34438, 0x000086AC }, /* GL_WEIGHT_ARRAY_POINTER_ARB */
+ { 34466, 0x000086AB }, /* GL_WEIGHT_ARRAY_SIZE_ARB */
+ { 34491, 0x000086AA }, /* GL_WEIGHT_ARRAY_STRIDE_ARB */
+ { 34518, 0x000086A9 }, /* GL_WEIGHT_ARRAY_TYPE_ARB */
+ { 34543, 0x000086A6 }, /* GL_WEIGHT_SUM_UNITY_ARB */
+ { 34567, 0x000081D4 }, /* GL_WRAP_BORDER_SUN */
+ { 34586, 0x000088B9 }, /* GL_WRITE_ONLY */
+ { 34600, 0x000088B9 }, /* GL_WRITE_ONLY_ARB */
+ { 34618, 0x00001506 }, /* GL_XOR */
+ { 34625, 0x000085B9 }, /* GL_YCBCR_422_APPLE */
+ { 34644, 0x00008757 }, /* GL_YCBCR_MESA */
+ { 34658, 0x00000000 }, /* GL_ZERO */
+ { 34666, 0x00000D16 }, /* GL_ZOOM_X */
+ { 34676, 0x00000D17 }, /* GL_ZOOM_Y */
+};
+
+static const unsigned reduced_enums[1236] =
+{
+ 26, /* GL_ALL_CLIENT_ATTRIB_BITS */
+ 389, /* GL_FALSE */
+ 566, /* GL_LINES */
+ 568, /* GL_LINE_LOOP */
+ 575, /* GL_LINE_STRIP */
+ 1520, /* GL_TRIANGLES */
+ 1523, /* GL_TRIANGLE_STRIP */
+ 1521, /* GL_TRIANGLE_FAN */
+ 1117, /* GL_QUADS */
+ 1119, /* GL_QUAD_STRIP */
+ 1007, /* GL_POLYGON */
+ 1019, /* GL_POLYGON_STIPPLE_BIT */
+ 973, /* GL_PIXEL_MODE_BIT */
+ 553, /* GL_LIGHTING_BIT */
+ 405, /* GL_FOG_BIT */
+ 8, /* GL_ACCUM */
+ 584, /* GL_LOAD */
+ 1157, /* GL_RETURN */
+ 846, /* GL_MULT */
+ 19, /* GL_ADD */
+ 862, /* GL_NEVER */
+ 543, /* GL_LESS */
+ 379, /* GL_EQUAL */
+ 542, /* GL_LEQUAL */
+ 472, /* GL_GREATER */
+ 877, /* GL_NOTEQUAL */
+ 466, /* GL_GEQUAL */
+ 42, /* GL_ALWAYS */
+ 1281, /* GL_SRC_COLOR */
+ 906, /* GL_ONE_MINUS_SRC_COLOR */
+ 1279, /* GL_SRC_ALPHA */
+ 905, /* GL_ONE_MINUS_SRC_ALPHA */
+ 359, /* GL_DST_ALPHA */
+ 903, /* GL_ONE_MINUS_DST_ALPHA */
+ 360, /* GL_DST_COLOR */
+ 904, /* GL_ONE_MINUS_DST_COLOR */
+ 1280, /* GL_SRC_ALPHA_SATURATE */
+ 454, /* GL_FRONT_LEFT */
+ 455, /* GL_FRONT_RIGHT */
+ 64, /* GL_BACK_LEFT */
+ 65, /* GL_BACK_RIGHT */
+ 451, /* GL_FRONT */
+ 63, /* GL_BACK */
+ 541, /* GL_LEFT */
+ 1197, /* GL_RIGHT */
+ 452, /* GL_FRONT_AND_BACK */
+ 58, /* GL_AUX0 */
+ 59, /* GL_AUX1 */
+ 60, /* GL_AUX2 */
+ 61, /* GL_AUX3 */
+ 533, /* GL_INVALID_ENUM */
+ 536, /* GL_INVALID_VALUE */
+ 535, /* GL_INVALID_OPERATION */
+ 1282, /* GL_STACK_OVERFLOW */
+ 1283, /* GL_STACK_UNDERFLOW */
+ 931, /* GL_OUT_OF_MEMORY */
+ 534, /* GL_INVALID_FRAMEBUFFER_OPERATION_EXT */
+ 0, /* GL_2D */
+ 2, /* GL_3D */
+ 3, /* GL_3D_COLOR */
+ 4, /* GL_3D_COLOR_TEXTURE */
+ 6, /* GL_4D_COLOR_TEXTURE */
+ 951, /* GL_PASS_THROUGH_TOKEN */
+ 1006, /* GL_POINT_TOKEN */
+ 576, /* GL_LINE_TOKEN */
+ 1020, /* GL_POLYGON_TOKEN */
+ 69, /* GL_BITMAP_TOKEN */
+ 358, /* GL_DRAW_PIXEL_TOKEN */
+ 248, /* GL_COPY_PIXEL_TOKEN */
+ 569, /* GL_LINE_RESET_TOKEN */
+ 382, /* GL_EXP */
+ 383, /* GL_EXP2 */
+ 279, /* GL_CW */
+ 106, /* GL_CCW */
+ 127, /* GL_COEFF */
+ 928, /* GL_ORDER */
+ 315, /* GL_DOMAIN */
+ 256, /* GL_CURRENT_COLOR */
+ 259, /* GL_CURRENT_INDEX */
+ 265, /* GL_CURRENT_NORMAL */
+ 276, /* GL_CURRENT_TEXTURE_COORDS */
+ 269, /* GL_CURRENT_RASTER_COLOR */
+ 271, /* GL_CURRENT_RASTER_INDEX */
+ 274, /* GL_CURRENT_RASTER_TEXTURE_COORDS */
+ 272, /* GL_CURRENT_RASTER_POSITION */
+ 273, /* GL_CURRENT_RASTER_POSITION_VALID */
+ 270, /* GL_CURRENT_RASTER_DISTANCE */
+ 1000, /* GL_POINT_SMOOTH */
+ 989, /* GL_POINT_SIZE */
+ 999, /* GL_POINT_SIZE_RANGE */
+ 990, /* GL_POINT_SIZE_GRANULARITY */
+ 570, /* GL_LINE_SMOOTH */
+ 577, /* GL_LINE_WIDTH */
+ 579, /* GL_LINE_WIDTH_RANGE */
+ 578, /* GL_LINE_WIDTH_GRANULARITY */
+ 572, /* GL_LINE_STIPPLE */
+ 573, /* GL_LINE_STIPPLE_PATTERN */
+ 574, /* GL_LINE_STIPPLE_REPEAT */
+ 583, /* GL_LIST_MODE */
+ 737, /* GL_MAX_LIST_NESTING */
+ 580, /* GL_LIST_BASE */
+ 582, /* GL_LIST_INDEX */
+ 1009, /* GL_POLYGON_MODE */
+ 1016, /* GL_POLYGON_SMOOTH */
+ 1018, /* GL_POLYGON_STIPPLE */
+ 367, /* GL_EDGE_FLAG */
+ 249, /* GL_CULL_FACE */
+ 250, /* GL_CULL_FACE_MODE */
+ 453, /* GL_FRONT_FACE */
+ 552, /* GL_LIGHTING */
+ 557, /* GL_LIGHT_MODEL_LOCAL_VIEWER */
+ 558, /* GL_LIGHT_MODEL_TWO_SIDE */
+ 554, /* GL_LIGHT_MODEL_AMBIENT */
+ 1235, /* GL_SHADE_MODEL */
+ 158, /* GL_COLOR_MATERIAL_FACE */
+ 159, /* GL_COLOR_MATERIAL_PARAMETER */
+ 157, /* GL_COLOR_MATERIAL */
+ 404, /* GL_FOG */
+ 426, /* GL_FOG_INDEX */
+ 422, /* GL_FOG_DENSITY */
+ 430, /* GL_FOG_START */
+ 424, /* GL_FOG_END */
+ 427, /* GL_FOG_MODE */
+ 406, /* GL_FOG_COLOR */
+ 304, /* GL_DEPTH_RANGE */
+ 309, /* GL_DEPTH_TEST */
+ 312, /* GL_DEPTH_WRITEMASK */
+ 292, /* GL_DEPTH_CLEAR_VALUE */
+ 303, /* GL_DEPTH_FUNC */
+ 12, /* GL_ACCUM_CLEAR_VALUE */
+ 1306, /* GL_STENCIL_TEST */
+ 1294, /* GL_STENCIL_CLEAR_VALUE */
+ 1296, /* GL_STENCIL_FUNC */
+ 1308, /* GL_STENCIL_VALUE_MASK */
+ 1295, /* GL_STENCIL_FAIL */
+ 1303, /* GL_STENCIL_PASS_DEPTH_FAIL */
+ 1304, /* GL_STENCIL_PASS_DEPTH_PASS */
+ 1305, /* GL_STENCIL_REF */
+ 1309, /* GL_STENCIL_WRITEMASK */
+ 710, /* GL_MATRIX_MODE */
+ 867, /* GL_NORMALIZE */
+ 1598, /* GL_VIEWPORT */
+ 841, /* GL_MODELVIEW_STACK_DEPTH */
+ 1099, /* GL_PROJECTION_STACK_DEPTH */
+ 1500, /* GL_TEXTURE_STACK_DEPTH */
+ 839, /* GL_MODELVIEW_MATRIX */
+ 1098, /* GL_PROJECTION_MATRIX */
+ 1485, /* GL_TEXTURE_MATRIX */
+ 56, /* GL_ATTRIB_STACK_DEPTH */
+ 117, /* GL_CLIENT_ATTRIB_STACK_DEPTH */
+ 39, /* GL_ALPHA_TEST */
+ 40, /* GL_ALPHA_TEST_FUNC */
+ 41, /* GL_ALPHA_TEST_REF */
+ 314, /* GL_DITHER */
+ 73, /* GL_BLEND_DST */
+ 80, /* GL_BLEND_SRC */
+ 70, /* GL_BLEND */
+ 586, /* GL_LOGIC_OP_MODE */
+ 511, /* GL_INDEX_LOGIC_OP */
+ 156, /* GL_COLOR_LOGIC_OP */
+ 62, /* GL_AUX_BUFFERS */
+ 325, /* GL_DRAW_BUFFER */
+ 1129, /* GL_READ_BUFFER */
+ 1218, /* GL_SCISSOR_BOX */
+ 1219, /* GL_SCISSOR_TEST */
+ 510, /* GL_INDEX_CLEAR_VALUE */
+ 515, /* GL_INDEX_WRITEMASK */
+ 153, /* GL_COLOR_CLEAR_VALUE */
+ 185, /* GL_COLOR_WRITEMASK */
+ 512, /* GL_INDEX_MODE */
+ 1191, /* GL_RGBA_MODE */
+ 324, /* GL_DOUBLEBUFFER */
+ 1310, /* GL_STEREO */
+ 1150, /* GL_RENDER_MODE */
+ 952, /* GL_PERSPECTIVE_CORRECTION_HINT */
+ 1001, /* GL_POINT_SMOOTH_HINT */
+ 571, /* GL_LINE_SMOOTH_HINT */
+ 1017, /* GL_POLYGON_SMOOTH_HINT */
+ 425, /* GL_FOG_HINT */
+ 1466, /* GL_TEXTURE_GEN_S */
+ 1467, /* GL_TEXTURE_GEN_T */
+ 1465, /* GL_TEXTURE_GEN_R */
+ 1464, /* GL_TEXTURE_GEN_Q */
+ 965, /* GL_PIXEL_MAP_I_TO_I */
+ 971, /* GL_PIXEL_MAP_S_TO_S */
+ 967, /* GL_PIXEL_MAP_I_TO_R */
+ 963, /* GL_PIXEL_MAP_I_TO_G */
+ 961, /* GL_PIXEL_MAP_I_TO_B */
+ 959, /* GL_PIXEL_MAP_I_TO_A */
+ 969, /* GL_PIXEL_MAP_R_TO_R */
+ 957, /* GL_PIXEL_MAP_G_TO_G */
+ 955, /* GL_PIXEL_MAP_B_TO_B */
+ 953, /* GL_PIXEL_MAP_A_TO_A */
+ 966, /* GL_PIXEL_MAP_I_TO_I_SIZE */
+ 972, /* GL_PIXEL_MAP_S_TO_S_SIZE */
+ 968, /* GL_PIXEL_MAP_I_TO_R_SIZE */
+ 964, /* GL_PIXEL_MAP_I_TO_G_SIZE */
+ 962, /* GL_PIXEL_MAP_I_TO_B_SIZE */
+ 960, /* GL_PIXEL_MAP_I_TO_A_SIZE */
+ 970, /* GL_PIXEL_MAP_R_TO_R_SIZE */
+ 958, /* GL_PIXEL_MAP_G_TO_G_SIZE */
+ 956, /* GL_PIXEL_MAP_B_TO_B_SIZE */
+ 954, /* GL_PIXEL_MAP_A_TO_A_SIZE */
+ 1532, /* GL_UNPACK_SWAP_BYTES */
+ 1527, /* GL_UNPACK_LSB_FIRST */
+ 1528, /* GL_UNPACK_ROW_LENGTH */
+ 1531, /* GL_UNPACK_SKIP_ROWS */
+ 1530, /* GL_UNPACK_SKIP_PIXELS */
+ 1525, /* GL_UNPACK_ALIGNMENT */
+ 940, /* GL_PACK_SWAP_BYTES */
+ 935, /* GL_PACK_LSB_FIRST */
+ 936, /* GL_PACK_ROW_LENGTH */
+ 939, /* GL_PACK_SKIP_ROWS */
+ 938, /* GL_PACK_SKIP_PIXELS */
+ 932, /* GL_PACK_ALIGNMENT */
+ 663, /* GL_MAP_COLOR */
+ 664, /* GL_MAP_STENCIL */
+ 514, /* GL_INDEX_SHIFT */
+ 513, /* GL_INDEX_OFFSET */
+ 1139, /* GL_RED_SCALE */
+ 1137, /* GL_RED_BIAS */
+ 1615, /* GL_ZOOM_X */
+ 1616, /* GL_ZOOM_Y */
+ 476, /* GL_GREEN_SCALE */
+ 474, /* GL_GREEN_BIAS */
+ 86, /* GL_BLUE_SCALE */
+ 84, /* GL_BLUE_BIAS */
+ 38, /* GL_ALPHA_SCALE */
+ 36, /* GL_ALPHA_BIAS */
+ 305, /* GL_DEPTH_SCALE */
+ 286, /* GL_DEPTH_BIAS */
+ 733, /* GL_MAX_EVAL_ORDER */
+ 736, /* GL_MAX_LIGHTS */
+ 718, /* GL_MAX_CLIP_PLANES */
+ 778, /* GL_MAX_TEXTURE_SIZE */
+ 742, /* GL_MAX_PIXEL_MAP_TABLE */
+ 714, /* GL_MAX_ATTRIB_STACK_DEPTH */
+ 739, /* GL_MAX_MODELVIEW_STACK_DEPTH */
+ 740, /* GL_MAX_NAME_STACK_DEPTH */
+ 768, /* GL_MAX_PROJECTION_STACK_DEPTH */
+ 779, /* GL_MAX_TEXTURE_STACK_DEPTH */
+ 789, /* GL_MAX_VIEWPORT_DIMS */
+ 715, /* GL_MAX_CLIENT_ATTRIB_STACK_DEPTH */
+ 1317, /* GL_SUBPIXEL_BITS */
+ 509, /* GL_INDEX_BITS */
+ 1138, /* GL_RED_BITS */
+ 475, /* GL_GREEN_BITS */
+ 85, /* GL_BLUE_BITS */
+ 37, /* GL_ALPHA_BITS */
+ 287, /* GL_DEPTH_BITS */
+ 1292, /* GL_STENCIL_BITS */
+ 14, /* GL_ACCUM_RED_BITS */
+ 13, /* GL_ACCUM_GREEN_BITS */
+ 10, /* GL_ACCUM_BLUE_BITS */
+ 9, /* GL_ACCUM_ALPHA_BITS */
+ 855, /* GL_NAME_STACK_DEPTH */
+ 57, /* GL_AUTO_NORMAL */
+ 609, /* GL_MAP1_COLOR_4 */
+ 612, /* GL_MAP1_INDEX */
+ 613, /* GL_MAP1_NORMAL */
+ 614, /* GL_MAP1_TEXTURE_COORD_1 */
+ 615, /* GL_MAP1_TEXTURE_COORD_2 */
+ 616, /* GL_MAP1_TEXTURE_COORD_3 */
+ 617, /* GL_MAP1_TEXTURE_COORD_4 */
+ 618, /* GL_MAP1_VERTEX_3 */
+ 619, /* GL_MAP1_VERTEX_4 */
+ 636, /* GL_MAP2_COLOR_4 */
+ 639, /* GL_MAP2_INDEX */
+ 640, /* GL_MAP2_NORMAL */
+ 641, /* GL_MAP2_TEXTURE_COORD_1 */
+ 642, /* GL_MAP2_TEXTURE_COORD_2 */
+ 643, /* GL_MAP2_TEXTURE_COORD_3 */
+ 644, /* GL_MAP2_TEXTURE_COORD_4 */
+ 645, /* GL_MAP2_VERTEX_3 */
+ 646, /* GL_MAP2_VERTEX_4 */
+ 610, /* GL_MAP1_GRID_DOMAIN */
+ 611, /* GL_MAP1_GRID_SEGMENTS */
+ 637, /* GL_MAP2_GRID_DOMAIN */
+ 638, /* GL_MAP2_GRID_SEGMENTS */
+ 1394, /* GL_TEXTURE_1D */
+ 1395, /* GL_TEXTURE_2D */
+ 392, /* GL_FEEDBACK_BUFFER_POINTER */
+ 393, /* GL_FEEDBACK_BUFFER_SIZE */
+ 394, /* GL_FEEDBACK_BUFFER_TYPE */
+ 1228, /* GL_SELECTION_BUFFER_POINTER */
+ 1229, /* GL_SELECTION_BUFFER_SIZE */
+ 1503, /* GL_TEXTURE_WIDTH */
+ 1471, /* GL_TEXTURE_HEIGHT */
+ 1427, /* GL_TEXTURE_COMPONENTS */
+ 1411, /* GL_TEXTURE_BORDER_COLOR */
+ 1410, /* GL_TEXTURE_BORDER */
+ 316, /* GL_DONT_CARE */
+ 390, /* GL_FASTEST */
+ 863, /* GL_NICEST */
+ 43, /* GL_AMBIENT */
+ 313, /* GL_DIFFUSE */
+ 1268, /* GL_SPECULAR */
+ 1021, /* GL_POSITION */
+ 1271, /* GL_SPOT_DIRECTION */
+ 1272, /* GL_SPOT_EXPONENT */
+ 1270, /* GL_SPOT_CUTOFF */
+ 223, /* GL_CONSTANT_ATTENUATION */
+ 561, /* GL_LINEAR_ATTENUATION */
+ 1116, /* GL_QUADRATIC_ATTENUATION */
+ 198, /* GL_COMPILE */
+ 199, /* GL_COMPILE_AND_EXECUTE */
+ 101, /* GL_BYTE */
+ 1533, /* GL_UNSIGNED_BYTE */
+ 1239, /* GL_SHORT */
+ 1542, /* GL_UNSIGNED_SHORT */
+ 516, /* GL_INT */
+ 1536, /* GL_UNSIGNED_INT */
+ 397, /* GL_FLOAT */
+ 1, /* GL_2_BYTES */
+ 5, /* GL_3_BYTES */
+ 7, /* GL_4_BYTES */
+ 323, /* GL_DOUBLE */
+ 113, /* GL_CLEAR */
+ 45, /* GL_AND */
+ 47, /* GL_AND_REVERSE */
+ 246, /* GL_COPY */
+ 46, /* GL_AND_INVERTED */
+ 865, /* GL_NOOP */
+ 1611, /* GL_XOR */
+ 927, /* GL_OR */
+ 866, /* GL_NOR */
+ 380, /* GL_EQUIV */
+ 539, /* GL_INVERT */
+ 930, /* GL_OR_REVERSE */
+ 247, /* GL_COPY_INVERTED */
+ 929, /* GL_OR_INVERTED */
+ 856, /* GL_NAND */
+ 1233, /* GL_SET */
+ 377, /* GL_EMISSION */
+ 1238, /* GL_SHININESS */
+ 44, /* GL_AMBIENT_AND_DIFFUSE */
+ 155, /* GL_COLOR_INDEXES */
+ 806, /* GL_MODELVIEW */
+ 1097, /* GL_PROJECTION */
+ 1329, /* GL_TEXTURE */
+ 128, /* GL_COLOR */
+ 284, /* GL_DEPTH */
+ 1290, /* GL_STENCIL */
+ 154, /* GL_COLOR_INDEX */
+ 1297, /* GL_STENCIL_INDEX */
+ 293, /* GL_DEPTH_COMPONENT */
+ 1134, /* GL_RED */
+ 473, /* GL_GREEN */
+ 83, /* GL_BLUE */
+ 27, /* GL_ALPHA */
+ 1158, /* GL_RGB */
+ 1177, /* GL_RGBA */
+ 587, /* GL_LUMINANCE */
+ 608, /* GL_LUMINANCE_ALPHA */
+ 68, /* GL_BITMAP */
+ 978, /* GL_POINT */
+ 559, /* GL_LINE */
+ 395, /* GL_FILL */
+ 1143, /* GL_RENDER */
+ 391, /* GL_FEEDBACK */
+ 1227, /* GL_SELECT */
+ 396, /* GL_FLAT */
+ 1243, /* GL_SMOOTH */
+ 540, /* GL_KEEP */
+ 1152, /* GL_REPLACE */
+ 500, /* GL_INCR */
+ 281, /* GL_DECR */
+ 1555, /* GL_VENDOR */
+ 1149, /* GL_RENDERER */
+ 1556, /* GL_VERSION */
+ 384, /* GL_EXTENSIONS */
+ 1198, /* GL_S */
+ 1320, /* GL_T */
+ 1126, /* GL_R */
+ 1115, /* GL_Q */
+ 842, /* GL_MODULATE */
+ 280, /* GL_DECAL */
+ 1461, /* GL_TEXTURE_ENV_MODE */
+ 1460, /* GL_TEXTURE_ENV_COLOR */
+ 1459, /* GL_TEXTURE_ENV */
+ 385, /* GL_EYE_LINEAR */
+ 889, /* GL_OBJECT_LINEAR */
+ 1269, /* GL_SPHERE_MAP */
+ 1463, /* GL_TEXTURE_GEN_MODE */
+ 891, /* GL_OBJECT_PLANE */
+ 386, /* GL_EYE_PLANE */
+ 857, /* GL_NEAREST */
+ 560, /* GL_LINEAR */
+ 861, /* GL_NEAREST_MIPMAP_NEAREST */
+ 565, /* GL_LINEAR_MIPMAP_NEAREST */
+ 860, /* GL_NEAREST_MIPMAP_LINEAR */
+ 564, /* GL_LINEAR_MIPMAP_LINEAR */
+ 1484, /* GL_TEXTURE_MAG_FILTER */
+ 1492, /* GL_TEXTURE_MIN_FILTER */
+ 1505, /* GL_TEXTURE_WRAP_S */
+ 1506, /* GL_TEXTURE_WRAP_T */
+ 107, /* GL_CLAMP */
+ 1151, /* GL_REPEAT */
+ 1015, /* GL_POLYGON_OFFSET_UNITS */
+ 1014, /* GL_POLYGON_OFFSET_POINT */
+ 1013, /* GL_POLYGON_OFFSET_LINE */
+ 1127, /* GL_R3_G3_B2 */
+ 1553, /* GL_V2F */
+ 1554, /* GL_V3F */
+ 104, /* GL_C4UB_V2F */
+ 105, /* GL_C4UB_V3F */
+ 102, /* GL_C3F_V3F */
+ 854, /* GL_N3F_V3F */
+ 103, /* GL_C4F_N3F_V3F */
+ 1325, /* GL_T2F_V3F */
+ 1327, /* GL_T4F_V4F */
+ 1323, /* GL_T2F_C4UB_V3F */
+ 1321, /* GL_T2F_C3F_V3F */
+ 1324, /* GL_T2F_N3F_V3F */
+ 1322, /* GL_T2F_C4F_N3F_V3F */
+ 1326, /* GL_T4F_C4F_N3F_V4F */
+ 120, /* GL_CLIP_PLANE0 */
+ 121, /* GL_CLIP_PLANE1 */
+ 122, /* GL_CLIP_PLANE2 */
+ 123, /* GL_CLIP_PLANE3 */
+ 124, /* GL_CLIP_PLANE4 */
+ 125, /* GL_CLIP_PLANE5 */
+ 544, /* GL_LIGHT0 */
+ 545, /* GL_LIGHT1 */
+ 546, /* GL_LIGHT2 */
+ 547, /* GL_LIGHT3 */
+ 548, /* GL_LIGHT4 */
+ 549, /* GL_LIGHT5 */
+ 550, /* GL_LIGHT6 */
+ 551, /* GL_LIGHT7 */
+ 477, /* GL_HINT_BIT */
+ 225, /* GL_CONSTANT_COLOR */
+ 901, /* GL_ONE_MINUS_CONSTANT_COLOR */
+ 220, /* GL_CONSTANT_ALPHA */
+ 899, /* GL_ONE_MINUS_CONSTANT_ALPHA */
+ 71, /* GL_BLEND_COLOR */
+ 456, /* GL_FUNC_ADD */
+ 790, /* GL_MIN */
+ 712, /* GL_MAX */
+ 76, /* GL_BLEND_EQUATION */
+ 460, /* GL_FUNC_SUBTRACT */
+ 458, /* GL_FUNC_REVERSE_SUBTRACT */
+ 228, /* GL_CONVOLUTION_1D */
+ 229, /* GL_CONVOLUTION_2D */
+ 1230, /* GL_SEPARABLE_2D */
+ 232, /* GL_CONVOLUTION_BORDER_MODE */
+ 236, /* GL_CONVOLUTION_FILTER_SCALE */
+ 234, /* GL_CONVOLUTION_FILTER_BIAS */
+ 1135, /* GL_REDUCE */
+ 238, /* GL_CONVOLUTION_FORMAT */
+ 242, /* GL_CONVOLUTION_WIDTH */
+ 240, /* GL_CONVOLUTION_HEIGHT */
+ 725, /* GL_MAX_CONVOLUTION_WIDTH */
+ 723, /* GL_MAX_CONVOLUTION_HEIGHT */
+ 1054, /* GL_POST_CONVOLUTION_RED_SCALE */
+ 1050, /* GL_POST_CONVOLUTION_GREEN_SCALE */
+ 1045, /* GL_POST_CONVOLUTION_BLUE_SCALE */
+ 1041, /* GL_POST_CONVOLUTION_ALPHA_SCALE */
+ 1052, /* GL_POST_CONVOLUTION_RED_BIAS */
+ 1048, /* GL_POST_CONVOLUTION_GREEN_BIAS */
+ 1043, /* GL_POST_CONVOLUTION_BLUE_BIAS */
+ 1039, /* GL_POST_CONVOLUTION_ALPHA_BIAS */
+ 478, /* GL_HISTOGRAM */
+ 1101, /* GL_PROXY_HISTOGRAM */
+ 494, /* GL_HISTOGRAM_WIDTH */
+ 484, /* GL_HISTOGRAM_FORMAT */
+ 490, /* GL_HISTOGRAM_RED_SIZE */
+ 486, /* GL_HISTOGRAM_GREEN_SIZE */
+ 481, /* GL_HISTOGRAM_BLUE_SIZE */
+ 479, /* GL_HISTOGRAM_ALPHA_SIZE */
+ 488, /* GL_HISTOGRAM_LUMINANCE_SIZE */
+ 492, /* GL_HISTOGRAM_SINK */
+ 791, /* GL_MINMAX */
+ 793, /* GL_MINMAX_FORMAT */
+ 795, /* GL_MINMAX_SINK */
+ 1328, /* GL_TABLE_TOO_LARGE_EXT */
+ 1535, /* GL_UNSIGNED_BYTE_3_3_2 */
+ 1544, /* GL_UNSIGNED_SHORT_4_4_4_4 */
+ 1546, /* GL_UNSIGNED_SHORT_5_5_5_1 */
+ 1540, /* GL_UNSIGNED_INT_8_8_8_8 */
+ 1537, /* GL_UNSIGNED_INT_10_10_10_2 */
+ 1012, /* GL_POLYGON_OFFSET_FILL */
+ 1011, /* GL_POLYGON_OFFSET_FACTOR */
+ 1010, /* GL_POLYGON_OFFSET_BIAS */
+ 1155, /* GL_RESCALE_NORMAL */
+ 32, /* GL_ALPHA4 */
+ 34, /* GL_ALPHA8 */
+ 28, /* GL_ALPHA12 */
+ 30, /* GL_ALPHA16 */
+ 598, /* GL_LUMINANCE4 */
+ 604, /* GL_LUMINANCE8 */
+ 588, /* GL_LUMINANCE12 */
+ 594, /* GL_LUMINANCE16 */
+ 599, /* GL_LUMINANCE4_ALPHA4 */
+ 602, /* GL_LUMINANCE6_ALPHA2 */
+ 605, /* GL_LUMINANCE8_ALPHA8 */
+ 591, /* GL_LUMINANCE12_ALPHA4 */
+ 589, /* GL_LUMINANCE12_ALPHA12 */
+ 595, /* GL_LUMINANCE16_ALPHA16 */
+ 517, /* GL_INTENSITY */
+ 522, /* GL_INTENSITY4 */
+ 524, /* GL_INTENSITY8 */
+ 518, /* GL_INTENSITY12 */
+ 520, /* GL_INTENSITY16 */
+ 1167, /* GL_RGB2_EXT */
+ 1168, /* GL_RGB4 */
+ 1171, /* GL_RGB5 */
+ 1175, /* GL_RGB8 */
+ 1159, /* GL_RGB10 */
+ 1163, /* GL_RGB12 */
+ 1165, /* GL_RGB16 */
+ 1182, /* GL_RGBA2 */
+ 1184, /* GL_RGBA4 */
+ 1172, /* GL_RGB5_A1 */
+ 1188, /* GL_RGBA8 */
+ 1160, /* GL_RGB10_A2 */
+ 1178, /* GL_RGBA12 */
+ 1180, /* GL_RGBA16 */
+ 1497, /* GL_TEXTURE_RED_SIZE */
+ 1469, /* GL_TEXTURE_GREEN_SIZE */
+ 1408, /* GL_TEXTURE_BLUE_SIZE */
+ 1397, /* GL_TEXTURE_ALPHA_SIZE */
+ 1482, /* GL_TEXTURE_LUMINANCE_SIZE */
+ 1473, /* GL_TEXTURE_INTENSITY_SIZE */
+ 1153, /* GL_REPLACE_EXT */
+ 1105, /* GL_PROXY_TEXTURE_1D */
+ 1107, /* GL_PROXY_TEXTURE_2D */
+ 1501, /* GL_TEXTURE_TOO_LARGE_EXT */
+ 1494, /* GL_TEXTURE_PRIORITY */
+ 1499, /* GL_TEXTURE_RESIDENT */
+ 1400, /* GL_TEXTURE_BINDING_1D */
+ 1401, /* GL_TEXTURE_BINDING_2D */
+ 1402, /* GL_TEXTURE_BINDING_3D */
+ 937, /* GL_PACK_SKIP_IMAGES */
+ 933, /* GL_PACK_IMAGE_HEIGHT */
+ 1529, /* GL_UNPACK_SKIP_IMAGES */
+ 1526, /* GL_UNPACK_IMAGE_HEIGHT */
+ 1396, /* GL_TEXTURE_3D */
+ 1109, /* GL_PROXY_TEXTURE_3D */
+ 1456, /* GL_TEXTURE_DEPTH */
+ 1504, /* GL_TEXTURE_WRAP_R */
+ 713, /* GL_MAX_3D_TEXTURE_SIZE */
+ 1557, /* GL_VERTEX_ARRAY */
+ 868, /* GL_NORMAL_ARRAY */
+ 129, /* GL_COLOR_ARRAY */
+ 503, /* GL_INDEX_ARRAY */
+ 1435, /* GL_TEXTURE_COORD_ARRAY */
+ 368, /* GL_EDGE_FLAG_ARRAY */
+ 1561, /* GL_VERTEX_ARRAY_SIZE */
+ 1563, /* GL_VERTEX_ARRAY_TYPE */
+ 1562, /* GL_VERTEX_ARRAY_STRIDE */
+ 873, /* GL_NORMAL_ARRAY_TYPE */
+ 872, /* GL_NORMAL_ARRAY_STRIDE */
+ 133, /* GL_COLOR_ARRAY_SIZE */
+ 135, /* GL_COLOR_ARRAY_TYPE */
+ 134, /* GL_COLOR_ARRAY_STRIDE */
+ 508, /* GL_INDEX_ARRAY_TYPE */
+ 507, /* GL_INDEX_ARRAY_STRIDE */
+ 1439, /* GL_TEXTURE_COORD_ARRAY_SIZE */
+ 1441, /* GL_TEXTURE_COORD_ARRAY_TYPE */
+ 1440, /* GL_TEXTURE_COORD_ARRAY_STRIDE */
+ 372, /* GL_EDGE_FLAG_ARRAY_STRIDE */
+ 1560, /* GL_VERTEX_ARRAY_POINTER */
+ 871, /* GL_NORMAL_ARRAY_POINTER */
+ 132, /* GL_COLOR_ARRAY_POINTER */
+ 506, /* GL_INDEX_ARRAY_POINTER */
+ 1438, /* GL_TEXTURE_COORD_ARRAY_POINTER */
+ 371, /* GL_EDGE_FLAG_ARRAY_POINTER */
+ 847, /* GL_MULTISAMPLE */
+ 1204, /* GL_SAMPLE_ALPHA_TO_COVERAGE */
+ 1206, /* GL_SAMPLE_ALPHA_TO_ONE */
+ 1211, /* GL_SAMPLE_COVERAGE */
+ 1208, /* GL_SAMPLE_BUFFERS */
+ 1199, /* GL_SAMPLES */
+ 1215, /* GL_SAMPLE_COVERAGE_VALUE */
+ 1213, /* GL_SAMPLE_COVERAGE_INVERT */
+ 160, /* GL_COLOR_MATRIX */
+ 162, /* GL_COLOR_MATRIX_STACK_DEPTH */
+ 720, /* GL_MAX_COLOR_MATRIX_STACK_DEPTH */
+ 1037, /* GL_POST_COLOR_MATRIX_RED_SCALE */
+ 1033, /* GL_POST_COLOR_MATRIX_GREEN_SCALE */
+ 1028, /* GL_POST_COLOR_MATRIX_BLUE_SCALE */
+ 1024, /* GL_POST_COLOR_MATRIX_ALPHA_SCALE */
+ 1035, /* GL_POST_COLOR_MATRIX_RED_BIAS */
+ 1031, /* GL_POST_COLOR_MATRIX_GREEN_BIAS */
+ 1026, /* GL_POST_COLOR_MATRIX_BLUE_BIAS */
+ 1022, /* GL_POST_COLOR_MATRIX_ALPHA_BIAS */
+ 1418, /* GL_TEXTURE_COLOR_TABLE_SGI */
+ 1110, /* GL_PROXY_TEXTURE_COLOR_TABLE_SGI */
+ 1420, /* GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
+ 75, /* GL_BLEND_DST_RGB */
+ 82, /* GL_BLEND_SRC_RGB */
+ 74, /* GL_BLEND_DST_ALPHA */
+ 81, /* GL_BLEND_SRC_ALPHA */
+ 166, /* GL_COLOR_TABLE */
+ 1047, /* GL_POST_CONVOLUTION_COLOR_TABLE */
+ 1030, /* GL_POST_COLOR_MATRIX_COLOR_TABLE */
+ 1100, /* GL_PROXY_COLOR_TABLE */
+ 1104, /* GL_PROXY_POST_CONVOLUTION_COLOR_TABLE */
+ 1103, /* GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE */
+ 182, /* GL_COLOR_TABLE_SCALE */
+ 169, /* GL_COLOR_TABLE_BIAS */
+ 172, /* GL_COLOR_TABLE_FORMAT */
+ 183, /* GL_COLOR_TABLE_WIDTH */
+ 180, /* GL_COLOR_TABLE_RED_SIZE */
+ 174, /* GL_COLOR_TABLE_GREEN_SIZE */
+ 170, /* GL_COLOR_TABLE_BLUE_SIZE */
+ 167, /* GL_COLOR_TABLE_ALPHA_SIZE */
+ 178, /* GL_COLOR_TABLE_LUMINANCE_SIZE */
+ 176, /* GL_COLOR_TABLE_INTENSITY_SIZE */
+ 66, /* GL_BGR */
+ 67, /* GL_BGRA */
+ 732, /* GL_MAX_ELEMENTS_VERTICES */
+ 731, /* GL_MAX_ELEMENTS_INDICES */
+ 1472, /* GL_TEXTURE_INDEX_SIZE_EXT */
+ 126, /* GL_CLIP_VOLUME_CLIPPING_HINT_EXT */
+ 995, /* GL_POINT_SIZE_MIN */
+ 991, /* GL_POINT_SIZE_MAX */
+ 985, /* GL_POINT_FADE_THRESHOLD_SIZE */
+ 981, /* GL_POINT_DISTANCE_ATTENUATION */
+ 108, /* GL_CLAMP_TO_BORDER */
+ 111, /* GL_CLAMP_TO_EDGE */
+ 1493, /* GL_TEXTURE_MIN_LOD */
+ 1491, /* GL_TEXTURE_MAX_LOD */
+ 1399, /* GL_TEXTURE_BASE_LEVEL */
+ 1490, /* GL_TEXTURE_MAX_LEVEL */
+ 497, /* GL_IGNORE_BORDER_HP */
+ 224, /* GL_CONSTANT_BORDER_HP */
+ 1154, /* GL_REPLICATE_BORDER_HP */
+ 230, /* GL_CONVOLUTION_BORDER_COLOR */
+ 896, /* GL_OCCLUSION_TEST_HP */
+ 897, /* GL_OCCLUSION_TEST_RESULT_HP */
+ 562, /* GL_LINEAR_CLIPMAP_LINEAR_SGIX */
+ 1412, /* GL_TEXTURE_CLIPMAP_CENTER_SGIX */
+ 1414, /* GL_TEXTURE_CLIPMAP_FRAME_SGIX */
+ 1416, /* GL_TEXTURE_CLIPMAP_OFFSET_SGIX */
+ 1417, /* GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX */
+ 1415, /* GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX */
+ 1413, /* GL_TEXTURE_CLIPMAP_DEPTH_SGIX */
+ 716, /* GL_MAX_CLIPMAP_DEPTH_SGIX */
+ 717, /* GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX */
+ 1057, /* GL_POST_TEXTURE_FILTER_BIAS_SGIX */
+ 1059, /* GL_POST_TEXTURE_FILTER_SCALE_SGIX */
+ 1056, /* GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX */
+ 1058, /* GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX */
+ 1480, /* GL_TEXTURE_LOD_BIAS_S_SGIX */
+ 1481, /* GL_TEXTURE_LOD_BIAS_T_SGIX */
+ 1479, /* GL_TEXTURE_LOD_BIAS_R_SGIX */
+ 462, /* GL_GENERATE_MIPMAP */
+ 463, /* GL_GENERATE_MIPMAP_HINT */
+ 428, /* GL_FOG_OFFSET_SGIX */
+ 429, /* GL_FOG_OFFSET_VALUE_SGIX */
+ 1426, /* GL_TEXTURE_COMPARE_SGIX */
+ 1425, /* GL_TEXTURE_COMPARE_OPERATOR_SGIX */
+ 1476, /* GL_TEXTURE_LEQUAL_R_SGIX */
+ 1468, /* GL_TEXTURE_GEQUAL_R_SGIX */
+ 294, /* GL_DEPTH_COMPONENT16 */
+ 297, /* GL_DEPTH_COMPONENT24 */
+ 300, /* GL_DEPTH_COMPONENT32 */
+ 251, /* GL_CULL_VERTEX_EXT */
+ 253, /* GL_CULL_VERTEX_OBJECT_POSITION_EXT */
+ 252, /* GL_CULL_VERTEX_EYE_POSITION_EXT */
+ 1608, /* GL_WRAP_BORDER_SUN */
+ 1419, /* GL_TEXTURE_COLOR_WRITEMASK_SGIS */
+ 555, /* GL_LIGHT_MODEL_COLOR_CONTROL */
+ 1240, /* GL_SINGLE_COLOR */
+ 1231, /* GL_SEPARATE_SPECULAR_COLOR */
+ 1237, /* GL_SHARED_TEXTURE_PALETTE_EXT */
+ 1534, /* GL_UNSIGNED_BYTE_2_3_3_REV */
+ 1547, /* GL_UNSIGNED_SHORT_5_6_5 */
+ 1548, /* GL_UNSIGNED_SHORT_5_6_5_REV */
+ 1545, /* GL_UNSIGNED_SHORT_4_4_4_4_REV */
+ 1543, /* GL_UNSIGNED_SHORT_1_5_5_5_REV */
+ 1541, /* GL_UNSIGNED_INT_8_8_8_8_REV */
+ 1539, /* GL_UNSIGNED_INT_2_10_10_10_REV */
+ 1488, /* GL_TEXTURE_MAX_CLAMP_S_SGIX */
+ 1489, /* GL_TEXTURE_MAX_CLAMP_T_SGIX */
+ 1487, /* GL_TEXTURE_MAX_CLAMP_R_SGIX */
+ 798, /* GL_MIRRORED_REPEAT */
+ 1193, /* GL_RGB_S3TC */
+ 1170, /* GL_RGB4_S3TC */
+ 1192, /* GL_RGBA_S3TC */
+ 1187, /* GL_RGBA4_S3TC */
+ 1190, /* GL_RGBA_DXT5_S3TC */
+ 1185, /* GL_RGBA4_DXT5_S3TC */
+ 217, /* GL_COMPRESSED_RGB_S3TC_DXT1_EXT */
+ 212, /* GL_COMPRESSED_RGBA_S3TC_DXT1_EXT */
+ 213, /* GL_COMPRESSED_RGBA_S3TC_DXT3_EXT */
+ 214, /* GL_COMPRESSED_RGBA_S3TC_DXT5_EXT */
+ 859, /* GL_NEAREST_CLIPMAP_NEAREST_SGIX */
+ 858, /* GL_NEAREST_CLIPMAP_LINEAR_SGIX */
+ 563, /* GL_LINEAR_CLIPMAP_NEAREST_SGIX */
+ 415, /* GL_FOG_COORDINATE_SOURCE */
+ 407, /* GL_FOG_COORD */
+ 431, /* GL_FRAGMENT_DEPTH */
+ 257, /* GL_CURRENT_FOG_COORD */
+ 414, /* GL_FOG_COORDINATE_ARRAY_TYPE */
+ 413, /* GL_FOG_COORDINATE_ARRAY_STRIDE */
+ 412, /* GL_FOG_COORDINATE_ARRAY_POINTER */
+ 409, /* GL_FOG_COORDINATE_ARRAY */
+ 164, /* GL_COLOR_SUM */
+ 275, /* GL_CURRENT_SECONDARY_COLOR */
+ 1224, /* GL_SECONDARY_COLOR_ARRAY_SIZE */
+ 1226, /* GL_SECONDARY_COLOR_ARRAY_TYPE */
+ 1225, /* GL_SECONDARY_COLOR_ARRAY_STRIDE */
+ 1223, /* GL_SECONDARY_COLOR_ARRAY_POINTER */
+ 1220, /* GL_SECONDARY_COLOR_ARRAY */
+ 24, /* GL_ALIASED_POINT_SIZE_RANGE */
+ 23, /* GL_ALIASED_LINE_WIDTH_RANGE */
+ 1330, /* GL_TEXTURE0 */
+ 1332, /* GL_TEXTURE1 */
+ 1354, /* GL_TEXTURE2 */
+ 1376, /* GL_TEXTURE3 */
+ 1382, /* GL_TEXTURE4 */
+ 1384, /* GL_TEXTURE5 */
+ 1386, /* GL_TEXTURE6 */
+ 1388, /* GL_TEXTURE7 */
+ 1390, /* GL_TEXTURE8 */
+ 1392, /* GL_TEXTURE9 */
+ 1333, /* GL_TEXTURE10 */
+ 1335, /* GL_TEXTURE11 */
+ 1337, /* GL_TEXTURE12 */
+ 1339, /* GL_TEXTURE13 */
+ 1341, /* GL_TEXTURE14 */
+ 1343, /* GL_TEXTURE15 */
+ 1345, /* GL_TEXTURE16 */
+ 1347, /* GL_TEXTURE17 */
+ 1349, /* GL_TEXTURE18 */
+ 1351, /* GL_TEXTURE19 */
+ 1355, /* GL_TEXTURE20 */
+ 1357, /* GL_TEXTURE21 */
+ 1359, /* GL_TEXTURE22 */
+ 1361, /* GL_TEXTURE23 */
+ 1363, /* GL_TEXTURE24 */
+ 1365, /* GL_TEXTURE25 */
+ 1367, /* GL_TEXTURE26 */
+ 1369, /* GL_TEXTURE27 */
+ 1371, /* GL_TEXTURE28 */
+ 1373, /* GL_TEXTURE29 */
+ 1377, /* GL_TEXTURE30 */
+ 1379, /* GL_TEXTURE31 */
+ 16, /* GL_ACTIVE_TEXTURE */
+ 114, /* GL_CLIENT_ACTIVE_TEXTURE */
+ 780, /* GL_MAX_TEXTURE_UNITS */
+ 1513, /* GL_TRANSPOSE_MODELVIEW_MATRIX */
+ 1516, /* GL_TRANSPOSE_PROJECTION_MATRIX */
+ 1518, /* GL_TRANSPOSE_TEXTURE_MATRIX */
+ 1510, /* GL_TRANSPOSE_COLOR_MATRIX */
+ 1318, /* GL_SUBTRACT */
+ 771, /* GL_MAX_RENDERBUFFER_SIZE_EXT */
+ 200, /* GL_COMPRESSED_ALPHA */
+ 204, /* GL_COMPRESSED_LUMINANCE */
+ 205, /* GL_COMPRESSED_LUMINANCE_ALPHA */
+ 202, /* GL_COMPRESSED_INTENSITY */
+ 208, /* GL_COMPRESSED_RGB */
+ 209, /* GL_COMPRESSED_RGBA */
+ 1433, /* GL_TEXTURE_COMPRESSION_HINT */
+ 1495, /* GL_TEXTURE_RECTANGLE_ARB */
+ 1405, /* GL_TEXTURE_BINDING_RECTANGLE_ARB */
+ 1113, /* GL_PROXY_TEXTURE_RECTANGLE_ARB */
+ 769, /* GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB */
+ 306, /* GL_DEPTH_STENCIL_NV */
+ 1538, /* GL_UNSIGNED_INT_24_8_NV */
+ 776, /* GL_MAX_TEXTURE_LOD_BIAS */
+ 1486, /* GL_TEXTURE_MAX_ANISOTROPY_EXT */
+ 777, /* GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT */
+ 1462, /* GL_TEXTURE_FILTER_CONTROL */
+ 1477, /* GL_TEXTURE_LOD_BIAS */
+ 187, /* GL_COMBINE4 */
+ 772, /* GL_MAX_SHININESS_NV */
+ 773, /* GL_MAX_SPOT_EXPONENT_NV */
+ 501, /* GL_INCR_WRAP */
+ 282, /* GL_DECR_WRAP */
+ 818, /* GL_MODELVIEW1_ARB */
+ 874, /* GL_NORMAL_MAP */
+ 1140, /* GL_REFLECTION_MAP */
+ 1442, /* GL_TEXTURE_CUBE_MAP */
+ 1403, /* GL_TEXTURE_BINDING_CUBE_MAP */
+ 1450, /* GL_TEXTURE_CUBE_MAP_POSITIVE_X */
+ 1444, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X */
+ 1452, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y */
+ 1446, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y */
+ 1454, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z */
+ 1448, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z */
+ 1111, /* GL_PROXY_TEXTURE_CUBE_MAP */
+ 727, /* GL_MAX_CUBE_MAP_TEXTURE_SIZE */
+ 853, /* GL_MULTISAMPLE_FILTER_HINT_NV */
+ 423, /* GL_FOG_DISTANCE_MODE_NV */
+ 388, /* GL_EYE_RADIAL_NV */
+ 387, /* GL_EYE_PLANE_ABSOLUTE_NV */
+ 186, /* GL_COMBINE */
+ 193, /* GL_COMBINE_RGB */
+ 188, /* GL_COMBINE_ALPHA */
+ 1194, /* GL_RGB_SCALE */
+ 20, /* GL_ADD_SIGNED */
+ 527, /* GL_INTERPOLATE */
+ 219, /* GL_CONSTANT */
+ 1063, /* GL_PRIMARY_COLOR */
+ 1060, /* GL_PREVIOUS */
+ 1251, /* GL_SOURCE0_RGB */
+ 1257, /* GL_SOURCE1_RGB */
+ 1263, /* GL_SOURCE2_RGB */
+ 1267, /* GL_SOURCE3_RGB_NV */
+ 1248, /* GL_SOURCE0_ALPHA */
+ 1254, /* GL_SOURCE1_ALPHA */
+ 1260, /* GL_SOURCE2_ALPHA */
+ 1266, /* GL_SOURCE3_ALPHA_NV */
+ 910, /* GL_OPERAND0_RGB */
+ 916, /* GL_OPERAND1_RGB */
+ 922, /* GL_OPERAND2_RGB */
+ 926, /* GL_OPERAND3_RGB_NV */
+ 907, /* GL_OPERAND0_ALPHA */
+ 913, /* GL_OPERAND1_ALPHA */
+ 919, /* GL_OPERAND2_ALPHA */
+ 925, /* GL_OPERAND3_ALPHA_NV */
+ 1612, /* GL_YCBCR_422_APPLE */
+ 1549, /* GL_UNSIGNED_SHORT_8_8_APPLE */
+ 1551, /* GL_UNSIGNED_SHORT_8_8_REV_APPLE */
+ 1242, /* GL_SLICE_ACCUM_SUN */
+ 1118, /* GL_QUAD_MESH_SUN */
+ 1522, /* GL_TRIANGLE_MESH_SUN */
+ 1589, /* GL_VERTEX_PROGRAM_ARB */
+ 1597, /* GL_VERTEX_STATE_PROGRAM_NV */
+ 1582, /* GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB */
+ 1585, /* GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB */
+ 1586, /* GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB */
+ 1587, /* GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB */
+ 277, /* GL_CURRENT_VERTEX_ATTRIB_ARB */
+ 1076, /* GL_PROGRAM_LENGTH_ARB */
+ 1090, /* GL_PROGRAM_STRING_ARB */
+ 840, /* GL_MODELVIEW_PROJECTION_NV */
+ 496, /* GL_IDENTITY_NV */
+ 537, /* GL_INVERSE_NV */
+ 1515, /* GL_TRANSPOSE_NV */
+ 538, /* GL_INVERSE_TRANSPOSE_NV */
+ 755, /* GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB */
+ 754, /* GL_MAX_PROGRAM_MATRICES_ARB */
+ 666, /* GL_MATRIX0_NV */
+ 678, /* GL_MATRIX1_NV */
+ 690, /* GL_MATRIX2_NV */
+ 694, /* GL_MATRIX3_NV */
+ 696, /* GL_MATRIX4_NV */
+ 698, /* GL_MATRIX5_NV */
+ 700, /* GL_MATRIX6_NV */
+ 702, /* GL_MATRIX7_NV */
+ 263, /* GL_CURRENT_MATRIX_STACK_DEPTH_ARB */
+ 260, /* GL_CURRENT_MATRIX_ARB */
+ 1592, /* GL_VERTEX_PROGRAM_POINT_SIZE_ARB */
+ 1594, /* GL_VERTEX_PROGRAM_TWO_SIDE_ARB */
+ 1088, /* GL_PROGRAM_PARAMETER_NV */
+ 1584, /* GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB */
+ 1092, /* GL_PROGRAM_TARGET_NV */
+ 1089, /* GL_PROGRAM_RESIDENT_NV */
+ 1507, /* GL_TRACK_MATRIX_NV */
+ 1508, /* GL_TRACK_MATRIX_TRANSFORM_NV */
+ 1590, /* GL_VERTEX_PROGRAM_BINDING_NV */
+ 1070, /* GL_PROGRAM_ERROR_POSITION_ARB */
+ 291, /* GL_DEPTH_CLAMP_NV */
+ 1564, /* GL_VERTEX_ATTRIB_ARRAY0_NV */
+ 1571, /* GL_VERTEX_ATTRIB_ARRAY1_NV */
+ 1572, /* GL_VERTEX_ATTRIB_ARRAY2_NV */
+ 1573, /* GL_VERTEX_ATTRIB_ARRAY3_NV */
+ 1574, /* GL_VERTEX_ATTRIB_ARRAY4_NV */
+ 1575, /* GL_VERTEX_ATTRIB_ARRAY5_NV */
+ 1576, /* GL_VERTEX_ATTRIB_ARRAY6_NV */
+ 1577, /* GL_VERTEX_ATTRIB_ARRAY7_NV */
+ 1578, /* GL_VERTEX_ATTRIB_ARRAY8_NV */
+ 1579, /* GL_VERTEX_ATTRIB_ARRAY9_NV */
+ 1565, /* GL_VERTEX_ATTRIB_ARRAY10_NV */
+ 1566, /* GL_VERTEX_ATTRIB_ARRAY11_NV */
+ 1567, /* GL_VERTEX_ATTRIB_ARRAY12_NV */
+ 1568, /* GL_VERTEX_ATTRIB_ARRAY13_NV */
+ 1569, /* GL_VERTEX_ATTRIB_ARRAY14_NV */
+ 1570, /* GL_VERTEX_ATTRIB_ARRAY15_NV */
+ 620, /* GL_MAP1_VERTEX_ATTRIB0_4_NV */
+ 627, /* GL_MAP1_VERTEX_ATTRIB1_4_NV */
+ 628, /* GL_MAP1_VERTEX_ATTRIB2_4_NV */
+ 629, /* GL_MAP1_VERTEX_ATTRIB3_4_NV */
+ 630, /* GL_MAP1_VERTEX_ATTRIB4_4_NV */
+ 631, /* GL_MAP1_VERTEX_ATTRIB5_4_NV */
+ 632, /* GL_MAP1_VERTEX_ATTRIB6_4_NV */
+ 633, /* GL_MAP1_VERTEX_ATTRIB7_4_NV */
+ 634, /* GL_MAP1_VERTEX_ATTRIB8_4_NV */
+ 635, /* GL_MAP1_VERTEX_ATTRIB9_4_NV */
+ 621, /* GL_MAP1_VERTEX_ATTRIB10_4_NV */
+ 622, /* GL_MAP1_VERTEX_ATTRIB11_4_NV */
+ 623, /* GL_MAP1_VERTEX_ATTRIB12_4_NV */
+ 624, /* GL_MAP1_VERTEX_ATTRIB13_4_NV */
+ 625, /* GL_MAP1_VERTEX_ATTRIB14_4_NV */
+ 626, /* GL_MAP1_VERTEX_ATTRIB15_4_NV */
+ 647, /* GL_MAP2_VERTEX_ATTRIB0_4_NV */
+ 654, /* GL_MAP2_VERTEX_ATTRIB1_4_NV */
+ 655, /* GL_MAP2_VERTEX_ATTRIB2_4_NV */
+ 656, /* GL_MAP2_VERTEX_ATTRIB3_4_NV */
+ 657, /* GL_MAP2_VERTEX_ATTRIB4_4_NV */
+ 658, /* GL_MAP2_VERTEX_ATTRIB5_4_NV */
+ 659, /* GL_MAP2_VERTEX_ATTRIB6_4_NV */
+ 1069, /* GL_PROGRAM_BINDING_ARB */
+ 661, /* GL_MAP2_VERTEX_ATTRIB8_4_NV */
+ 662, /* GL_MAP2_VERTEX_ATTRIB9_4_NV */
+ 648, /* GL_MAP2_VERTEX_ATTRIB10_4_NV */
+ 649, /* GL_MAP2_VERTEX_ATTRIB11_4_NV */
+ 650, /* GL_MAP2_VERTEX_ATTRIB12_4_NV */
+ 651, /* GL_MAP2_VERTEX_ATTRIB13_4_NV */
+ 652, /* GL_MAP2_VERTEX_ATTRIB14_4_NV */
+ 653, /* GL_MAP2_VERTEX_ATTRIB15_4_NV */
+ 1431, /* GL_TEXTURE_COMPRESSED_IMAGE_SIZE */
+ 1428, /* GL_TEXTURE_COMPRESSED */
+ 879, /* GL_NUM_COMPRESSED_TEXTURE_FORMATS */
+ 218, /* GL_COMPRESSED_TEXTURE_FORMATS */
+ 788, /* GL_MAX_VERTEX_UNITS_ARB */
+ 18, /* GL_ACTIVE_VERTEX_UNITS_ARB */
+ 1607, /* GL_WEIGHT_SUM_UNITY_ARB */
+ 1588, /* GL_VERTEX_BLEND_ARB */
+ 278, /* GL_CURRENT_WEIGHT_ARB */
+ 1606, /* GL_WEIGHT_ARRAY_TYPE_ARB */
+ 1605, /* GL_WEIGHT_ARRAY_STRIDE_ARB */
+ 1604, /* GL_WEIGHT_ARRAY_SIZE_ARB */
+ 1603, /* GL_WEIGHT_ARRAY_POINTER_ARB */
+ 1600, /* GL_WEIGHT_ARRAY_ARB */
+ 317, /* GL_DOT3_RGB */
+ 318, /* GL_DOT3_RGBA */
+ 216, /* GL_COMPRESSED_RGB_FXT1_3DFX */
+ 211, /* GL_COMPRESSED_RGBA_FXT1_3DFX */
+ 848, /* GL_MULTISAMPLE_3DFX */
+ 1209, /* GL_SAMPLE_BUFFERS_3DFX */
+ 1200, /* GL_SAMPLES_3DFX */
+ 829, /* GL_MODELVIEW2_ARB */
+ 832, /* GL_MODELVIEW3_ARB */
+ 833, /* GL_MODELVIEW4_ARB */
+ 834, /* GL_MODELVIEW5_ARB */
+ 835, /* GL_MODELVIEW6_ARB */
+ 836, /* GL_MODELVIEW7_ARB */
+ 837, /* GL_MODELVIEW8_ARB */
+ 838, /* GL_MODELVIEW9_ARB */
+ 808, /* GL_MODELVIEW10_ARB */
+ 809, /* GL_MODELVIEW11_ARB */
+ 810, /* GL_MODELVIEW12_ARB */
+ 811, /* GL_MODELVIEW13_ARB */
+ 812, /* GL_MODELVIEW14_ARB */
+ 813, /* GL_MODELVIEW15_ARB */
+ 814, /* GL_MODELVIEW16_ARB */
+ 815, /* GL_MODELVIEW17_ARB */
+ 816, /* GL_MODELVIEW18_ARB */
+ 817, /* GL_MODELVIEW19_ARB */
+ 819, /* GL_MODELVIEW20_ARB */
+ 820, /* GL_MODELVIEW21_ARB */
+ 821, /* GL_MODELVIEW22_ARB */
+ 822, /* GL_MODELVIEW23_ARB */
+ 823, /* GL_MODELVIEW24_ARB */
+ 824, /* GL_MODELVIEW25_ARB */
+ 825, /* GL_MODELVIEW26_ARB */
+ 826, /* GL_MODELVIEW27_ARB */
+ 827, /* GL_MODELVIEW28_ARB */
+ 828, /* GL_MODELVIEW29_ARB */
+ 830, /* GL_MODELVIEW30_ARB */
+ 831, /* GL_MODELVIEW31_ARB */
+ 322, /* GL_DOT3_RGB_EXT */
+ 320, /* GL_DOT3_RGBA_EXT */
+ 802, /* GL_MIRROR_CLAMP_EXT */
+ 805, /* GL_MIRROR_CLAMP_TO_EDGE_EXT */
+ 843, /* GL_MODULATE_ADD_ATI */
+ 844, /* GL_MODULATE_SIGNED_ADD_ATI */
+ 845, /* GL_MODULATE_SUBTRACT_ATI */
+ 1613, /* GL_YCBCR_MESA */
+ 934, /* GL_PACK_INVERT_MESA */
+ 97, /* GL_BUFFER_SIZE */
+ 99, /* GL_BUFFER_USAGE */
+ 432, /* GL_FRAGMENT_PROGRAM_ARB */
+ 1067, /* GL_PROGRAM_ALU_INSTRUCTIONS_ARB */
+ 1095, /* GL_PROGRAM_TEX_INSTRUCTIONS_ARB */
+ 1094, /* GL_PROGRAM_TEX_INDIRECTIONS_ARB */
+ 1079, /* GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */
+ 1085, /* GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */
+ 1084, /* GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */
+ 744, /* GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB */
+ 767, /* GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB */
+ 766, /* GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB */
+ 757, /* GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */
+ 763, /* GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */
+ 762, /* GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */
+ 729, /* GL_MAX_DRAW_BUFFERS_ARB */
+ 326, /* GL_DRAW_BUFFER0_ARB */
+ 340, /* GL_DRAW_BUFFER1_ARB */
+ 342, /* GL_DRAW_BUFFER2_ARB */
+ 344, /* GL_DRAW_BUFFER3_ARB */
+ 346, /* GL_DRAW_BUFFER4_ARB */
+ 348, /* GL_DRAW_BUFFER5_ARB */
+ 350, /* GL_DRAW_BUFFER6_ARB */
+ 352, /* GL_DRAW_BUFFER7_ARB */
+ 354, /* GL_DRAW_BUFFER8_ARB */
+ 356, /* GL_DRAW_BUFFER9_ARB */
+ 328, /* GL_DRAW_BUFFER10_ARB */
+ 330, /* GL_DRAW_BUFFER11_ARB */
+ 332, /* GL_DRAW_BUFFER12_ARB */
+ 334, /* GL_DRAW_BUFFER13_ARB */
+ 336, /* GL_DRAW_BUFFER14_ARB */
+ 338, /* GL_DRAW_BUFFER15_ARB */
+ 77, /* GL_BLEND_EQUATION_ALPHA_EXT */
+ 711, /* GL_MATRIX_PALETTE_ARB */
+ 738, /* GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB */
+ 741, /* GL_MAX_PALETTE_MATRICES_ARB */
+ 266, /* GL_CURRENT_PALETTE_MATRIX_ARB */
+ 705, /* GL_MATRIX_INDEX_ARRAY_ARB */
+ 261, /* GL_CURRENT_MATRIX_INDEX_ARB */
+ 707, /* GL_MATRIX_INDEX_ARRAY_SIZE_ARB */
+ 709, /* GL_MATRIX_INDEX_ARRAY_TYPE_ARB */
+ 708, /* GL_MATRIX_INDEX_ARRAY_STRIDE_ARB */
+ 706, /* GL_MATRIX_INDEX_ARRAY_POINTER_ARB */
+ 1457, /* GL_TEXTURE_DEPTH_SIZE */
+ 310, /* GL_DEPTH_TEXTURE_MODE */
+ 1423, /* GL_TEXTURE_COMPARE_MODE */
+ 1421, /* GL_TEXTURE_COMPARE_FUNC */
+ 196, /* GL_COMPARE_R_TO_TEXTURE */
+ 1002, /* GL_POINT_SPRITE_ARB */
+ 244, /* GL_COORD_REPLACE_ARB */
+ 1005, /* GL_POINT_SPRITE_R_MODE_NV */
+ 1120, /* GL_QUERY_COUNTER_BITS */
+ 267, /* GL_CURRENT_QUERY */
+ 1122, /* GL_QUERY_RESULT */
+ 1124, /* GL_QUERY_RESULT_AVAILABLE */
+ 785, /* GL_MAX_VERTEX_ATTRIBS_ARB */
+ 1583, /* GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB */
+ 308, /* GL_DEPTH_STENCIL_TO_RGBA_NV */
+ 307, /* GL_DEPTH_STENCIL_TO_BGRA_NV */
+ 774, /* GL_MAX_TEXTURE_COORDS_ARB */
+ 775, /* GL_MAX_TEXTURE_IMAGE_UNITS_ARB */
+ 1072, /* GL_PROGRAM_ERROR_STRING_ARB */
+ 1074, /* GL_PROGRAM_FORMAT_ASCII_ARB */
+ 1073, /* GL_PROGRAM_FORMAT_ARB */
+ 1502, /* GL_TEXTURE_UNSIGNED_REMAP_MODE_NV */
+ 289, /* GL_DEPTH_BOUNDS_TEST_EXT */
+ 288, /* GL_DEPTH_BOUNDS_EXT */
+ 48, /* GL_ARRAY_BUFFER */
+ 373, /* GL_ELEMENT_ARRAY_BUFFER */
+ 50, /* GL_ARRAY_BUFFER_BINDING */
+ 375, /* GL_ELEMENT_ARRAY_BUFFER_BINDING */
+ 1558, /* GL_VERTEX_ARRAY_BUFFER_BINDING */
+ 869, /* GL_NORMAL_ARRAY_BUFFER_BINDING */
+ 130, /* GL_COLOR_ARRAY_BUFFER_BINDING */
+ 504, /* GL_INDEX_ARRAY_BUFFER_BINDING */
+ 1436, /* GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING */
+ 369, /* GL_EDGE_FLAG_ARRAY_BUFFER_BINDING */
+ 1221, /* GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING */
+ 410, /* GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING */
+ 1601, /* GL_WEIGHT_ARRAY_BUFFER_BINDING */
+ 1580, /* GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING */
+ 1075, /* GL_PROGRAM_INSTRUCTIONS_ARB */
+ 750, /* GL_MAX_PROGRAM_INSTRUCTIONS_ARB */
+ 1081, /* GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB */
+ 759, /* GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB */
+ 1093, /* GL_PROGRAM_TEMPORARIES_ARB */
+ 765, /* GL_MAX_PROGRAM_TEMPORARIES_ARB */
+ 1083, /* GL_PROGRAM_NATIVE_TEMPORARIES_ARB */
+ 761, /* GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB */
+ 1087, /* GL_PROGRAM_PARAMETERS_ARB */
+ 764, /* GL_MAX_PROGRAM_PARAMETERS_ARB */
+ 1082, /* GL_PROGRAM_NATIVE_PARAMETERS_ARB */
+ 760, /* GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB */
+ 1068, /* GL_PROGRAM_ATTRIBS_ARB */
+ 745, /* GL_MAX_PROGRAM_ATTRIBS_ARB */
+ 1080, /* GL_PROGRAM_NATIVE_ATTRIBS_ARB */
+ 758, /* GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB */
+ 1066, /* GL_PROGRAM_ADDRESS_REGISTERS_ARB */
+ 743, /* GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB */
+ 1078, /* GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */
+ 756, /* GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */
+ 751, /* GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB */
+ 747, /* GL_MAX_PROGRAM_ENV_PARAMETERS_ARB */
+ 1096, /* GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB */
+ 1512, /* GL_TRANSPOSE_CURRENT_MATRIX_ARB */
+ 1130, /* GL_READ_ONLY */
+ 1609, /* GL_WRITE_ONLY */
+ 1132, /* GL_READ_WRITE */
+ 91, /* GL_BUFFER_ACCESS */
+ 93, /* GL_BUFFER_MAPPED */
+ 95, /* GL_BUFFER_MAP_POINTER */
+ 471, /* GL_GL_TIME_ELAPSED_EXT */
+ 665, /* GL_MATRIX0_ARB */
+ 677, /* GL_MATRIX1_ARB */
+ 689, /* GL_MATRIX2_ARB */
+ 693, /* GL_MATRIX3_ARB */
+ 695, /* GL_MATRIX4_ARB */
+ 697, /* GL_MATRIX5_ARB */
+ 699, /* GL_MATRIX6_ARB */
+ 701, /* GL_MATRIX7_ARB */
+ 703, /* GL_MATRIX8_ARB */
+ 704, /* GL_MATRIX9_ARB */
+ 667, /* GL_MATRIX10_ARB */
+ 668, /* GL_MATRIX11_ARB */
+ 669, /* GL_MATRIX12_ARB */
+ 670, /* GL_MATRIX13_ARB */
+ 671, /* GL_MATRIX14_ARB */
+ 672, /* GL_MATRIX15_ARB */
+ 673, /* GL_MATRIX16_ARB */
+ 674, /* GL_MATRIX17_ARB */
+ 675, /* GL_MATRIX18_ARB */
+ 676, /* GL_MATRIX19_ARB */
+ 679, /* GL_MATRIX20_ARB */
+ 680, /* GL_MATRIX21_ARB */
+ 681, /* GL_MATRIX22_ARB */
+ 682, /* GL_MATRIX23_ARB */
+ 683, /* GL_MATRIX24_ARB */
+ 684, /* GL_MATRIX25_ARB */
+ 685, /* GL_MATRIX26_ARB */
+ 686, /* GL_MATRIX27_ARB */
+ 687, /* GL_MATRIX28_ARB */
+ 688, /* GL_MATRIX29_ARB */
+ 691, /* GL_MATRIX30_ARB */
+ 692, /* GL_MATRIX31_ARB */
+ 1313, /* GL_STREAM_DRAW */
+ 1315, /* GL_STREAM_READ */
+ 1311, /* GL_STREAM_COPY */
+ 1286, /* GL_STATIC_DRAW */
+ 1288, /* GL_STATIC_READ */
+ 1284, /* GL_STATIC_COPY */
+ 363, /* GL_DYNAMIC_DRAW */
+ 365, /* GL_DYNAMIC_READ */
+ 361, /* GL_DYNAMIC_COPY */
+ 975, /* GL_PIXEL_PACK_BUFFER_EXT */
+ 977, /* GL_PIXEL_UNPACK_BUFFER_EXT */
+ 974, /* GL_PIXEL_PACK_BUFFER_BINDING_EXT */
+ 976, /* GL_PIXEL_UNPACK_BUFFER_BINDING_EXT */
+ 748, /* GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV */
+ 746, /* GL_MAX_PROGRAM_CALL_DEPTH_NV */
+ 749, /* GL_MAX_PROGRAM_IF_DEPTH_NV */
+ 753, /* GL_MAX_PROGRAM_LOOP_DEPTH_NV */
+ 752, /* GL_MAX_PROGRAM_LOOP_COUNT_NV */
+ 1307, /* GL_STENCIL_TEST_TWO_SIDE_EXT */
+ 15, /* GL_ACTIVE_STENCIL_FACE_EXT */
+ 803, /* GL_MIRROR_CLAMP_TO_BORDER_EXT */
+ 1202, /* GL_SAMPLES_PASSED */
+ 433, /* GL_FRAGMENT_SHADER_ARB */
+ 1596, /* GL_VERTEX_SHADER_ARB */
+ 1086, /* GL_PROGRAM_OBJECT_ARB */
+ 1234, /* GL_SHADER_OBJECT_ARB */
+ 735, /* GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB */
+ 787, /* GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB */
+ 784, /* GL_MAX_VARYING_FLOATS_ARB */
+ 786, /* GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB */
+ 722, /* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB */
+ 894, /* GL_OBJECT_TYPE_ARB */
+ 893, /* GL_OBJECT_SUBTYPE_ARB */
+ 401, /* GL_FLOAT_VEC2_ARB */
+ 402, /* GL_FLOAT_VEC3_ARB */
+ 403, /* GL_FLOAT_VEC4_ARB */
+ 530, /* GL_INT_VEC2_ARB */
+ 531, /* GL_INT_VEC3_ARB */
+ 532, /* GL_INT_VEC4_ARB */
+ 87, /* GL_BOOL_ARB */
+ 88, /* GL_BOOL_VEC2_ARB */
+ 89, /* GL_BOOL_VEC3_ARB */
+ 90, /* GL_BOOL_VEC4_ARB */
+ 398, /* GL_FLOAT_MAT2_ARB */
+ 399, /* GL_FLOAT_MAT3_ARB */
+ 400, /* GL_FLOAT_MAT4_ARB */
+ 887, /* GL_OBJECT_DELETE_STATUS_ARB */
+ 886, /* GL_OBJECT_COMPILE_STATUS_ARB */
+ 890, /* GL_OBJECT_LINK_STATUS_ARB */
+ 895, /* GL_OBJECT_VALIDATE_STATUS_ARB */
+ 888, /* GL_OBJECT_INFO_LOG_LENGTH_ARB */
+ 885, /* GL_OBJECT_ATTACHED_OBJECTS_ARB */
+ 883, /* GL_OBJECT_ACTIVE_UNIFORMS_ARB */
+ 884, /* GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB */
+ 892, /* GL_OBJECT_SHADER_SOURCE_LENGTH_ARB */
+ 881, /* GL_OBJECT_ACTIVE_ATTRIBUTES_ARB */
+ 882, /* GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB */
+ 943, /* GL_PALETTE4_RGB8_OES */
+ 945, /* GL_PALETTE4_RGBA8_OES */
+ 941, /* GL_PALETTE4_R5_G6_B5_OES */
+ 944, /* GL_PALETTE4_RGBA4_OES */
+ 942, /* GL_PALETTE4_RGB5_A1_OES */
+ 948, /* GL_PALETTE8_RGB8_OES */
+ 950, /* GL_PALETTE8_RGBA8_OES */
+ 946, /* GL_PALETTE8_R5_G6_B5_OES */
+ 949, /* GL_PALETTE8_RGBA4_OES */
+ 947, /* GL_PALETTE8_RGB5_A1_OES */
+ 499, /* GL_IMPLEMENTATION_COLOR_READ_TYPE_OES */
+ 498, /* GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES */
+ 1003, /* GL_POINT_SPRITE_COORD_ORIGIN */
+ 439, /* GL_FRAMEBUFFER_BINDING_EXT */
+ 1144, /* GL_RENDERBUFFER_BINDING_EXT */
+ 470, /* GL_GL_READ_FRAMEBUFFER_EXT */
+ 468, /* GL_GL_DRAW_FRAMEBUFFER_EXT */
+ 469, /* GL_GL_READ_FRAMEBUFFER_BINDING_EXT */
+ 435, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT */
+ 434, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT */
+ 438, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT */
+ 437, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT */
+ 436, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT */
+ 440, /* GL_FRAMEBUFFER_COMPLETE_EXT */
+ 442, /* GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT */
+ 447, /* GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT */
+ 445, /* GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT */
+ 443, /* GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT */
+ 446, /* GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT */
+ 444, /* GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT */
+ 448, /* GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT */
+ 450, /* GL_FRAMEBUFFER_UNSUPPORTED_EXT */
+ 449, /* GL_FRAMEBUFFER_STATUS_ERROR_EXT */
+ 719, /* GL_MAX_COLOR_ATTACHMENTS_EXT */
+ 136, /* GL_COLOR_ATTACHMENT0_EXT */
+ 143, /* GL_COLOR_ATTACHMENT1_EXT */
+ 144, /* GL_COLOR_ATTACHMENT2_EXT */
+ 145, /* GL_COLOR_ATTACHMENT3_EXT */
+ 146, /* GL_COLOR_ATTACHMENT4_EXT */
+ 147, /* GL_COLOR_ATTACHMENT5_EXT */
+ 148, /* GL_COLOR_ATTACHMENT6_EXT */
+ 149, /* GL_COLOR_ATTACHMENT7_EXT */
+ 150, /* GL_COLOR_ATTACHMENT8_EXT */
+ 151, /* GL_COLOR_ATTACHMENT9_EXT */
+ 137, /* GL_COLOR_ATTACHMENT10_EXT */
+ 138, /* GL_COLOR_ATTACHMENT11_EXT */
+ 139, /* GL_COLOR_ATTACHMENT12_EXT */
+ 140, /* GL_COLOR_ATTACHMENT13_EXT */
+ 141, /* GL_COLOR_ATTACHMENT14_EXT */
+ 142, /* GL_COLOR_ATTACHMENT15_EXT */
+ 285, /* GL_DEPTH_ATTACHMENT_EXT */
+ 1291, /* GL_STENCIL_ATTACHMENT_EXT */
+ 441, /* GL_FRAMEBUFFER_EXT */
+ 1145, /* GL_RENDERBUFFER_EXT */
+ 1148, /* GL_RENDERBUFFER_WIDTH_EXT */
+ 1146, /* GL_RENDERBUFFER_HEIGHT_EXT */
+ 1147, /* GL_RENDERBUFFER_INTERNAL_FORMAT_EXT */
+ 1302, /* GL_STENCIL_INDEX_EXT */
+ 1299, /* GL_STENCIL_INDEX1_EXT */
+ 1300, /* GL_STENCIL_INDEX4_EXT */
+ 1301, /* GL_STENCIL_INDEX8_EXT */
+ 1298, /* GL_STENCIL_INDEX16_EXT */
+ 381, /* GL_EVAL_BIT */
+ 1128, /* GL_RASTER_POSITION_UNCLIPPED_IBM */
+ 581, /* GL_LIST_BIT */
+ 1407, /* GL_TEXTURE_BIT */
+ 1217, /* GL_SCISSOR_BIT */
+ 25, /* GL_ALL_ATTRIB_BITS */
+ 850, /* GL_MULTISAMPLE_BIT */
+};
+
+#define Elements(x) sizeof(x)/sizeof(*x)
+
+typedef int (*cfunc)(const void *, const void *);
+
+/**
+ * Compare a key name to an element in the \c all_enums array.
+ *
+ * \c bsearch always passes the key as the first parameter and the pointer
+ * to the array element as the second parameter. We can elimiate some
+ * extra work by taking advantage of that fact.
+ *
+ * \param a Pointer to the desired enum name.
+ * \param b Pointer to an element of the \c all_enums array.
+ */
+static int compar_name( const char *a, const enum_elt *b )
+{
+ return _mesa_strcmp( a, & enum_string_table[ b->offset ] );
+}
+
+/**
+ * Compare a key enum value to an element in the \c all_enums array.
+ *
+ * \c bsearch always passes the key as the first parameter and the pointer
+ * to the array element as the second parameter. We can elimiate some
+ * extra work by taking advantage of that fact.
+ *
+ * \param a Pointer to the desired enum name.
+ * \param b Pointer to an index into the \c all_enums array.
+ */
+static int compar_nr( const int *a, const unsigned *b )
+{
+ return a[0] - all_enums[*b].n;
+}
+
+
+static char token_tmp[20];
+
+const char *_mesa_lookup_enum_by_nr( int nr )
+{
+ unsigned * i;
+
+ i = (unsigned *)bsearch( & nr, reduced_enums, Elements(reduced_enums),
+ sizeof(reduced_enums[0]), (cfunc) compar_nr );
+
+ if ( i != NULL ) {
+ return & enum_string_table[ all_enums[ *i ].offset ];
+ }
+ else {
+ /* this is not re-entrant safe, no big deal here */
+ _mesa_sprintf(token_tmp, "0x%x", nr);
+ return token_tmp;
+ }
+}
+
+int _mesa_lookup_enum_by_name( const char *symbol )
+{
+ enum_elt * f = NULL;
+
+ if ( symbol != NULL ) {
+ f = (enum_elt *)bsearch( symbol, all_enums, Elements(all_enums),
+ sizeof( enum_elt ), (cfunc) compar_name );
+ }
+
+ return (f != NULL) ? f->n : -1;
+}
+
+
diff --git a/src/mesa/main/enums.h b/src/mesa/main/enums.h
new file mode 100644
index 00000000000..7e8d4ee94fc
--- /dev/null
+++ b/src/mesa/main/enums.h
@@ -0,0 +1,55 @@
+/**
+ * \file enums.h
+ * Enumeration name/number lookup functions.
+ *
+ * \if subset
+ * (No-op)
+ *
+ * \endif
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.5
+ *
+ * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/* $XFree86: xc/extras/Mesa/src/mesa/main/enums.h,v 1.2 2004/06/23 19:40:14 tsi Exp $ */
+
+#ifndef _ENUMS_H_
+#define _ENUMS_H_
+
+
+#if defined(_HAVE_FULL_GL) && _HAVE_FULL_GL
+
+extern const char *_mesa_lookup_enum_by_nr( int nr );
+extern int _mesa_lookup_enum_by_name( const char *symbol );
+
+#else
+
+/** No-op */
+#define _mesa_lookup_enum_by_name( s ) 0
+
+/** No-op */
+#define _mesa_lookup_enum_by_nr( n ) "unknown"
+
+#endif
+
+#endif
diff --git a/src/mesa/main/eval.c b/src/mesa/main/eval.c
new file mode 100644
index 00000000000..3f89f9c1eae
--- /dev/null
+++ b/src/mesa/main/eval.c
@@ -0,0 +1,962 @@
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 5.1
+ *
+ * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/*
+ * eval.c was written by
+ * Bernd Barsuhn (bdbarsuh@cip.informatik.uni-erlangen.de) and
+ * Volker Weiss (vrweiss@cip.informatik.uni-erlangen.de).
+ *
+ * My original implementation of evaluators was simplistic and didn't
+ * compute surface normal vectors properly. Bernd and Volker applied
+ * used more sophisticated methods to get better results.
+ *
+ * Thanks guys!
+ */
+
+
+#include "glheader.h"
+#include "imports.h"
+#include "colormac.h"
+#include "context.h"
+#include "eval.h"
+#include "macros.h"
+#include "mtypes.h"
+
+
+/*
+ * Return the number of components per control point for any type of
+ * evaluator. Return 0 if bad target.
+ * See table 5.1 in the OpenGL 1.2 spec.
+ */
+GLuint _mesa_evaluator_components( GLenum target )
+{
+ switch (target) {
+ case GL_MAP1_VERTEX_3: return 3;
+ case GL_MAP1_VERTEX_4: return 4;
+ case GL_MAP1_INDEX: return 1;
+ case GL_MAP1_COLOR_4: return 4;
+ case GL_MAP1_NORMAL: return 3;
+ case GL_MAP1_TEXTURE_COORD_1: return 1;
+ case GL_MAP1_TEXTURE_COORD_2: return 2;
+ case GL_MAP1_TEXTURE_COORD_3: return 3;
+ case GL_MAP1_TEXTURE_COORD_4: return 4;
+ case GL_MAP2_VERTEX_3: return 3;
+ case GL_MAP2_VERTEX_4: return 4;
+ case GL_MAP2_INDEX: return 1;
+ case GL_MAP2_COLOR_4: return 4;
+ case GL_MAP2_NORMAL: return 3;
+ case GL_MAP2_TEXTURE_COORD_1: return 1;
+ case GL_MAP2_TEXTURE_COORD_2: return 2;
+ case GL_MAP2_TEXTURE_COORD_3: return 3;
+ case GL_MAP2_TEXTURE_COORD_4: return 4;
+ default: break;
+ }
+
+ /* XXX need to check for the vertex program extension
+ if (!ctx->Extensions.NV_vertex_program)
+ return 0;
+ */
+
+ if (target >= GL_MAP1_VERTEX_ATTRIB0_4_NV &&
+ target <= GL_MAP1_VERTEX_ATTRIB15_4_NV)
+ return 4;
+
+ if (target >= GL_MAP2_VERTEX_ATTRIB0_4_NV &&
+ target <= GL_MAP2_VERTEX_ATTRIB15_4_NV)
+ return 4;
+
+ return 0;
+}
+
+
+/*
+ * Return pointer to the gl_1d_map struct for the named target.
+ */
+static struct gl_1d_map *
+get_1d_map( GLcontext *ctx, GLenum target )
+{
+ switch (target) {
+ case GL_MAP1_VERTEX_3:
+ return &ctx->EvalMap.Map1Vertex3;
+ case GL_MAP1_VERTEX_4:
+ return &ctx->EvalMap.Map1Vertex4;
+ case GL_MAP1_INDEX:
+ return &ctx->EvalMap.Map1Index;
+ case GL_MAP1_COLOR_4:
+ return &ctx->EvalMap.Map1Color4;
+ case GL_MAP1_NORMAL:
+ return &ctx->EvalMap.Map1Normal;
+ case GL_MAP1_TEXTURE_COORD_1:
+ return &ctx->EvalMap.Map1Texture1;
+ case GL_MAP1_TEXTURE_COORD_2:
+ return &ctx->EvalMap.Map1Texture2;
+ case GL_MAP1_TEXTURE_COORD_3:
+ return &ctx->EvalMap.Map1Texture3;
+ case GL_MAP1_TEXTURE_COORD_4:
+ return &ctx->EvalMap.Map1Texture4;
+ case GL_MAP1_VERTEX_ATTRIB0_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB1_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB2_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB3_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB4_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB5_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB6_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB7_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB8_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB9_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB10_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB11_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB12_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB13_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB14_4_NV:
+ case GL_MAP1_VERTEX_ATTRIB15_4_NV:
+ if (!ctx->Extensions.NV_vertex_program)
+ return NULL;
+ return &ctx->EvalMap.Map1Attrib[target - GL_MAP1_VERTEX_ATTRIB0_4_NV];
+ default:
+ return NULL;
+ }
+}
+
+
+/*
+ * Return pointer to the gl_2d_map struct for the named target.
+ */
+static struct gl_2d_map *
+get_2d_map( GLcontext *ctx, GLenum target )
+{
+ switch (target) {
+ case GL_MAP2_VERTEX_3:
+ return &ctx->EvalMap.Map2Vertex3;
+ case GL_MAP2_VERTEX_4:
+ return &ctx->EvalMap.Map2Vertex4;
+ case GL_MAP2_INDEX:
+ return &ctx->EvalMap.Map2Index;
+ case GL_MAP2_COLOR_4:
+ return &ctx->EvalMap.Map2Color4;
+ case GL_MAP2_NORMAL:
+ return &ctx->EvalMap.Map2Normal;
+ case GL_MAP2_TEXTURE_COORD_1:
+ return &ctx->EvalMap.Map2Texture1;
+ case GL_MAP2_TEXTURE_COORD_2:
+ return &ctx->EvalMap.Map2Texture2;
+ case GL_MAP2_TEXTURE_COORD_3:
+ return &ctx->EvalMap.Map2Texture3;
+ case GL_MAP2_TEXTURE_COORD_4:
+ return &ctx->EvalMap.Map2Texture4;
+ case GL_MAP2_VERTEX_ATTRIB0_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB1_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB2_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB3_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB4_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB5_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB6_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB7_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB8_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB9_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB10_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB11_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB12_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB13_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB14_4_NV:
+ case GL_MAP2_VERTEX_ATTRIB15_4_NV:
+ if (!ctx->Extensions.NV_vertex_program)
+ return NULL;
+ return &ctx->EvalMap.Map2Attrib[target - GL_MAP2_VERTEX_ATTRIB0_4_NV];
+ default:
+ return NULL;
+ }
+}
+
+
+/**********************************************************************/
+/*** Copy and deallocate control points ***/
+/**********************************************************************/
+
+
+/*
+ * Copy 1-parametric evaluator control points from user-specified
+ * memory space to a buffer of contiguous control points.
+ * \param see glMap1f for details
+ * \return pointer to buffer of contiguous control points or NULL if out
+ * of memory.
+ */
+GLfloat *_mesa_copy_map_points1f( GLenum target, GLint ustride, GLint uorder,
+ const GLfloat *points )
+{
+ GLfloat *buffer, *p;
+ GLint i, k, size = _mesa_evaluator_components(target);
+
+ if (!points || !size)
+ return NULL;
+
+ buffer = (GLfloat *) MALLOC(uorder * size * sizeof(GLfloat));
+
+ if (buffer)
+ for (i = 0, p = buffer; i < uorder; i++, points += ustride)
+ for (k = 0; k < size; k++)
+ *p++ = points[k];
+
+ return buffer;
+}
+
+
+
+/*
+ * Same as above but convert doubles to floats.
+ */
+GLfloat *_mesa_copy_map_points1d( GLenum target, GLint ustride, GLint uorder,
+ const GLdouble *points )
+{
+ GLfloat *buffer, *p;
+ GLint i, k, size = _mesa_evaluator_components(target);
+
+ if (!points || !size)
+ return NULL;
+
+ buffer = (GLfloat *) MALLOC(uorder * size * sizeof(GLfloat));
+
+ if (buffer)
+ for (i = 0, p = buffer; i < uorder; i++, points += ustride)
+ for (k = 0; k < size; k++)
+ *p++ = (GLfloat) points[k];
+
+ return buffer;
+}
+
+
+
+/*
+ * Copy 2-parametric evaluator control points from user-specified
+ * memory space to a buffer of contiguous control points.
+ * Additional memory is allocated to be used by the horner and
+ * de Casteljau evaluation schemes.
+ *
+ * \param see glMap2f for details
+ * \return pointer to buffer of contiguous control points or NULL if out
+ * of memory.
+ */
+GLfloat *_mesa_copy_map_points2f( GLenum target,
+ GLint ustride, GLint uorder,
+ GLint vstride, GLint vorder,
+ const GLfloat *points )
+{
+ GLfloat *buffer, *p;
+ GLint i, j, k, size, dsize, hsize;
+ GLint uinc;
+
+ size = _mesa_evaluator_components(target);
+
+ if (!points || size==0) {
+ return NULL;
+ }
+
+ /* max(uorder, vorder) additional points are used in */
+ /* horner evaluation and uorder*vorder additional */
+ /* values are needed for de Casteljau */
+ dsize = (uorder == 2 && vorder == 2)? 0 : uorder*vorder;
+ hsize = (uorder > vorder ? uorder : vorder)*size;
+
+ if(hsize>dsize)
+ buffer = (GLfloat *) MALLOC((uorder*vorder*size+hsize)*sizeof(GLfloat));
+ else
+ buffer = (GLfloat *) MALLOC((uorder*vorder*size+dsize)*sizeof(GLfloat));
+
+ /* compute the increment value for the u-loop */
+ uinc = ustride - vorder*vstride;
+
+ if (buffer)
+ for (i=0, p=buffer; i<uorder; i++, points += uinc)
+ for (j=0; j<vorder; j++, points += vstride)
+ for (k=0; k<size; k++)
+ *p++ = points[k];
+
+ return buffer;
+}
+
+
+
+/*
+ * Same as above but convert doubles to floats.
+ */
+GLfloat *_mesa_copy_map_points2d(GLenum target,
+ GLint ustride, GLint uorder,
+ GLint vstride, GLint vorder,
+ const GLdouble *points )
+{
+ GLfloat *buffer, *p;
+ GLint i, j, k, size, hsize, dsize;
+ GLint uinc;
+
+ size = _mesa_evaluator_components(target);
+
+ if (!points || size==0) {
+ return NULL;
+ }
+
+ /* max(uorder, vorder) additional points are used in */
+ /* horner evaluation and uorder*vorder additional */
+ /* values are needed for de Casteljau */
+ dsize = (uorder == 2 && vorder == 2)? 0 : uorder*vorder;
+ hsize = (uorder > vorder ? uorder : vorder)*size;
+
+ if(hsize>dsize)
+ buffer = (GLfloat *) MALLOC((uorder*vorder*size+hsize)*sizeof(GLfloat));
+ else
+ buffer = (GLfloat *) MALLOC((uorder*vorder*size+dsize)*sizeof(GLfloat));
+
+ /* compute the increment value for the u-loop */
+ uinc = ustride - vorder*vstride;
+
+ if (buffer)
+ for (i=0, p=buffer; i<uorder; i++, points += uinc)
+ for (j=0; j<vorder; j++, points += vstride)
+ for (k=0; k<size; k++)
+ *p++ = (GLfloat) points[k];
+
+ return buffer;
+}
+
+
+
+
+/**********************************************************************/
+/*** API entry points ***/
+/**********************************************************************/
+
+
+/*
+ * This does the work of glMap1[fd].
+ */
+static void
+map1(GLenum target, GLfloat u1, GLfloat u2, GLint ustride,
+ GLint uorder, const GLvoid *points, GLenum type )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint k;
+ GLfloat *pnts;
+ struct gl_1d_map *map = NULL;
+
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+ ASSERT(type == GL_FLOAT || type == GL_DOUBLE);
+
+ if (u1 == u2) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glMap1(u1,u2)" );
+ return;
+ }
+ if (uorder < 1 || uorder > MAX_EVAL_ORDER) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glMap1(order)" );
+ return;
+ }
+ if (!points) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glMap1(points)" );
+ return;
+ }
+
+ k = _mesa_evaluator_components( target );
+ if (k == 0) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glMap1(target)" );
+ }
+
+ if (ustride < k) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glMap1(stride)" );
+ return;
+ }
+
+ if (ctx->Texture.CurrentUnit != 0) {
+ /* See OpenGL 1.2.1 spec, section F.2.13 */
+ _mesa_error( ctx, GL_INVALID_OPERATION, "glMap2(ACTIVE_TEXTURE != 0)" );
+ return;
+ }
+
+ map = get_1d_map(ctx, target);
+ if (!map) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glMap1(target)" );
+ return;
+ }
+
+ /* make copy of the control points */
+ if (type == GL_FLOAT)
+ pnts = _mesa_copy_map_points1f(target, ustride, uorder, (GLfloat*) points);
+ else
+ pnts = _mesa_copy_map_points1d(target, ustride, uorder, (GLdouble*) points);
+
+
+ FLUSH_VERTICES(ctx, _NEW_EVAL);
+ map->Order = uorder;
+ map->u1 = u1;
+ map->u2 = u2;
+ map->du = 1.0F / (u2 - u1);
+ if (map->Points)
+ FREE( map->Points );
+ map->Points = pnts;
+}
+
+
+
+void GLAPIENTRY
+_mesa_Map1f( GLenum target, GLfloat u1, GLfloat u2, GLint stride,
+ GLint order, const GLfloat *points )
+{
+ map1(target, u1, u2, stride, order, points, GL_FLOAT);
+}
+
+
+void GLAPIENTRY
+_mesa_Map1d( GLenum target, GLdouble u1, GLdouble u2, GLint stride,
+ GLint order, const GLdouble *points )
+{
+ map1(target, (GLfloat) u1, (GLfloat) u2, stride, order, points, GL_DOUBLE);
+}
+
+
+static void
+map2( GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder,
+ GLfloat v1, GLfloat v2, GLint vstride, GLint vorder,
+ const GLvoid *points, GLenum type )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint k;
+ GLfloat *pnts;
+ struct gl_2d_map *map = NULL;
+
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+ ASSERT(type == GL_FLOAT || type == GL_DOUBLE);
+
+ if (u1==u2) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(u1,u2)" );
+ return;
+ }
+
+ if (v1==v2) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(v1,v2)" );
+ return;
+ }
+
+ if (uorder<1 || uorder>MAX_EVAL_ORDER) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(uorder)" );
+ return;
+ }
+
+ if (vorder<1 || vorder>MAX_EVAL_ORDER) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(vorder)" );
+ return;
+ }
+
+ k = _mesa_evaluator_components( target );
+ if (k==0) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glMap2(target)" );
+ }
+
+ if (ustride < k) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(ustride)" );
+ return;
+ }
+ if (vstride < k) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(vstride)" );
+ return;
+ }
+
+ if (ctx->Texture.CurrentUnit != 0) {
+ /* See OpenGL 1.2.1 spec, section F.2.13 */
+ _mesa_error( ctx, GL_INVALID_OPERATION, "glMap2(ACTIVE_TEXTURE != 0)" );
+ return;
+ }
+
+ map = get_2d_map(ctx, target);
+ if (!map) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glMap2(target)" );
+ return;
+ }
+
+ /* make copy of the control points */
+ if (type == GL_FLOAT)
+ pnts = _mesa_copy_map_points2f(target, ustride, uorder,
+ vstride, vorder, (GLfloat*) points);
+ else
+ pnts = _mesa_copy_map_points2d(target, ustride, uorder,
+ vstride, vorder, (GLdouble*) points);
+
+
+ FLUSH_VERTICES(ctx, _NEW_EVAL);
+ map->Uorder = uorder;
+ map->u1 = u1;
+ map->u2 = u2;
+ map->du = 1.0F / (u2 - u1);
+ map->Vorder = vorder;
+ map->v1 = v1;
+ map->v2 = v2;
+ map->dv = 1.0F / (v2 - v1);
+ if (map->Points)
+ FREE( map->Points );
+ map->Points = pnts;
+}
+
+
+void GLAPIENTRY
+_mesa_Map2f( GLenum target,
+ GLfloat u1, GLfloat u2, GLint ustride, GLint uorder,
+ GLfloat v1, GLfloat v2, GLint vstride, GLint vorder,
+ const GLfloat *points)
+{
+ map2(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder,
+ points, GL_FLOAT);
+}
+
+
+void GLAPIENTRY
+_mesa_Map2d( GLenum target,
+ GLdouble u1, GLdouble u2, GLint ustride, GLint uorder,
+ GLdouble v1, GLdouble v2, GLint vstride, GLint vorder,
+ const GLdouble *points )
+{
+ map2(target, (GLfloat) u1, (GLfloat) u2, ustride, uorder,
+ (GLfloat) v1, (GLfloat) v2, vstride, vorder, points, GL_DOUBLE);
+}
+
+
+
+void GLAPIENTRY
+_mesa_GetMapdv( GLenum target, GLenum query, GLdouble *v )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_1d_map *map1d;
+ struct gl_2d_map *map2d;
+ GLint i, n;
+ GLfloat *data;
+ GLuint comps;
+
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ comps = _mesa_evaluator_components(target);
+ if (!comps) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapdv(target)" );
+ return;
+ }
+
+ map1d = get_1d_map(ctx, target);
+ map2d = get_2d_map(ctx, target);
+ ASSERT(map1d || map2d);
+
+ switch (query) {
+ case GL_COEFF:
+ if (map1d) {
+ data = map1d->Points;
+ n = map1d->Order * comps;
+ }
+ else {
+ data = map2d->Points;
+ n = map2d->Uorder * map2d->Vorder * comps;
+ }
+ if (data) {
+ for (i=0;i<n;i++) {
+ v[i] = data[i];
+ }
+ }
+ break;
+ case GL_ORDER:
+ if (map1d) {
+ v[0] = (GLdouble) map1d->Order;
+ }
+ else {
+ v[0] = (GLdouble) map2d->Uorder;
+ v[1] = (GLdouble) map2d->Vorder;
+ }
+ break;
+ case GL_DOMAIN:
+ if (map1d) {
+ v[0] = (GLdouble) map1d->u1;
+ v[1] = (GLdouble) map1d->u2;
+ }
+ else {
+ v[0] = (GLdouble) map2d->u1;
+ v[1] = (GLdouble) map2d->u2;
+ v[2] = (GLdouble) map2d->v1;
+ v[3] = (GLdouble) map2d->v2;
+ }
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapdv(query)" );
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_GetMapfv( GLenum target, GLenum query, GLfloat *v )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_1d_map *map1d;
+ struct gl_2d_map *map2d;
+ GLint i, n;
+ GLfloat *data;
+ GLuint comps;
+
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ comps = _mesa_evaluator_components(target);
+ if (!comps) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapfv(target)" );
+ return;
+ }
+
+ map1d = get_1d_map(ctx, target);
+ map2d = get_2d_map(ctx, target);
+ ASSERT(map1d || map2d);
+
+ switch (query) {
+ case GL_COEFF:
+ if (map1d) {
+ data = map1d->Points;
+ n = map1d->Order * comps;
+ }
+ else {
+ data = map2d->Points;
+ n = map2d->Uorder * map2d->Vorder * comps;
+ }
+ if (data) {
+ for (i=0;i<n;i++) {
+ v[i] = data[i];
+ }
+ }
+ break;
+ case GL_ORDER:
+ if (map1d) {
+ v[0] = (GLfloat) map1d->Order;
+ }
+ else {
+ v[0] = (GLfloat) map2d->Uorder;
+ v[1] = (GLfloat) map2d->Vorder;
+ }
+ break;
+ case GL_DOMAIN:
+ if (map1d) {
+ v[0] = map1d->u1;
+ v[1] = map1d->u2;
+ }
+ else {
+ v[0] = map2d->u1;
+ v[1] = map2d->u2;
+ v[2] = map2d->v1;
+ v[3] = map2d->v2;
+ }
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapfv(query)" );
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_GetMapiv( GLenum target, GLenum query, GLint *v )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_1d_map *map1d;
+ struct gl_2d_map *map2d;
+ GLuint i, n;
+ GLfloat *data;
+ GLuint comps;
+
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ comps = _mesa_evaluator_components(target);
+ if (!comps) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapiv(target)" );
+ return;
+ }
+
+ map1d = get_1d_map(ctx, target);
+ map2d = get_2d_map(ctx, target);
+ ASSERT(map1d || map2d);
+
+ switch (query) {
+ case GL_COEFF:
+ if (map1d) {
+ data = map1d->Points;
+ n = map1d->Order * comps;
+ }
+ else {
+ data = map2d->Points;
+ n = map2d->Uorder * map2d->Vorder * comps;
+ }
+ if (data) {
+ for (i=0;i<n;i++) {
+ v[i] = IROUND(data[i]);
+ }
+ }
+ break;
+ case GL_ORDER:
+ if (map1d) {
+ v[0] = map1d->Order;
+ }
+ else {
+ v[0] = map2d->Uorder;
+ v[1] = map2d->Vorder;
+ }
+ break;
+ case GL_DOMAIN:
+ if (map1d) {
+ v[0] = IROUND(map1d->u1);
+ v[1] = IROUND(map1d->u2);
+ }
+ else {
+ v[0] = IROUND(map2d->u1);
+ v[1] = IROUND(map2d->u2);
+ v[2] = IROUND(map2d->v1);
+ v[3] = IROUND(map2d->v2);
+ }
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapiv(query)" );
+ }
+}
+
+
+
+void GLAPIENTRY
+_mesa_MapGrid1f( GLint un, GLfloat u1, GLfloat u2 )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (un<1) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glMapGrid1f" );
+ return;
+ }
+ FLUSH_VERTICES(ctx, _NEW_EVAL);
+ ctx->Eval.MapGrid1un = un;
+ ctx->Eval.MapGrid1u1 = u1;
+ ctx->Eval.MapGrid1u2 = u2;
+ ctx->Eval.MapGrid1du = (u2 - u1) / (GLfloat) un;
+}
+
+
+void GLAPIENTRY
+_mesa_MapGrid1d( GLint un, GLdouble u1, GLdouble u2 )
+{
+ _mesa_MapGrid1f( un, (GLfloat) u1, (GLfloat) u2 );
+}
+
+
+void GLAPIENTRY
+_mesa_MapGrid2f( GLint un, GLfloat u1, GLfloat u2,
+ GLint vn, GLfloat v1, GLfloat v2 )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (un<1) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glMapGrid2f(un)" );
+ return;
+ }
+ if (vn<1) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glMapGrid2f(vn)" );
+ return;
+ }
+
+ FLUSH_VERTICES(ctx, _NEW_EVAL);
+ ctx->Eval.MapGrid2un = un;
+ ctx->Eval.MapGrid2u1 = u1;
+ ctx->Eval.MapGrid2u2 = u2;
+ ctx->Eval.MapGrid2du = (u2 - u1) / (GLfloat) un;
+ ctx->Eval.MapGrid2vn = vn;
+ ctx->Eval.MapGrid2v1 = v1;
+ ctx->Eval.MapGrid2v2 = v2;
+ ctx->Eval.MapGrid2dv = (v2 - v1) / (GLfloat) vn;
+}
+
+
+void GLAPIENTRY
+_mesa_MapGrid2d( GLint un, GLdouble u1, GLdouble u2,
+ GLint vn, GLdouble v1, GLdouble v2 )
+{
+ _mesa_MapGrid2f( un, (GLfloat) u1, (GLfloat) u2,
+ vn, (GLfloat) v1, (GLfloat) v2 );
+}
+
+
+
+/**********************************************************************/
+/***** Initialization *****/
+/**********************************************************************/
+
+/**
+ * Initialize a 1-D evaluator map.
+ */
+static void
+init_1d_map( struct gl_1d_map *map, int n, const float *initial )
+{
+ map->Order = 1;
+ map->u1 = 0.0;
+ map->u2 = 1.0;
+ map->Points = (GLfloat *) MALLOC(n * sizeof(GLfloat));
+ if (map->Points) {
+ GLint i;
+ for (i=0;i<n;i++)
+ map->Points[i] = initial[i];
+ }
+}
+
+
+/**
+ * Initialize a 2-D evaluator map
+ */
+static void
+init_2d_map( struct gl_2d_map *map, int n, const float *initial )
+{
+ map->Uorder = 1;
+ map->Vorder = 1;
+ map->u1 = 0.0;
+ map->u2 = 1.0;
+ map->v1 = 0.0;
+ map->v2 = 1.0;
+ map->Points = (GLfloat *) MALLOC(n * sizeof(GLfloat));
+ if (map->Points) {
+ GLint i;
+ for (i=0;i<n;i++)
+ map->Points[i] = initial[i];
+ }
+}
+
+
+void _mesa_init_eval( GLcontext *ctx )
+{
+ int i;
+
+ /* Evaluators group */
+ ctx->Eval.Map1Color4 = GL_FALSE;
+ ctx->Eval.Map1Index = GL_FALSE;
+ ctx->Eval.Map1Normal = GL_FALSE;
+ ctx->Eval.Map1TextureCoord1 = GL_FALSE;
+ ctx->Eval.Map1TextureCoord2 = GL_FALSE;
+ ctx->Eval.Map1TextureCoord3 = GL_FALSE;
+ ctx->Eval.Map1TextureCoord4 = GL_FALSE;
+ ctx->Eval.Map1Vertex3 = GL_FALSE;
+ ctx->Eval.Map1Vertex4 = GL_FALSE;
+ MEMSET(ctx->Eval.Map1Attrib, 0, sizeof(ctx->Eval.Map1Attrib));
+ ctx->Eval.Map2Color4 = GL_FALSE;
+ ctx->Eval.Map2Index = GL_FALSE;
+ ctx->Eval.Map2Normal = GL_FALSE;
+ ctx->Eval.Map2TextureCoord1 = GL_FALSE;
+ ctx->Eval.Map2TextureCoord2 = GL_FALSE;
+ ctx->Eval.Map2TextureCoord3 = GL_FALSE;
+ ctx->Eval.Map2TextureCoord4 = GL_FALSE;
+ ctx->Eval.Map2Vertex3 = GL_FALSE;
+ ctx->Eval.Map2Vertex4 = GL_FALSE;
+ MEMSET(ctx->Eval.Map2Attrib, 0, sizeof(ctx->Eval.Map2Attrib));
+ ctx->Eval.AutoNormal = GL_FALSE;
+ ctx->Eval.MapGrid1un = 1;
+ ctx->Eval.MapGrid1u1 = 0.0;
+ ctx->Eval.MapGrid1u2 = 1.0;
+ ctx->Eval.MapGrid2un = 1;
+ ctx->Eval.MapGrid2vn = 1;
+ ctx->Eval.MapGrid2u1 = 0.0;
+ ctx->Eval.MapGrid2u2 = 1.0;
+ ctx->Eval.MapGrid2v1 = 0.0;
+ ctx->Eval.MapGrid2v2 = 1.0;
+
+ /* Evaluator data */
+ {
+ static GLfloat vertex[4] = { 0.0, 0.0, 0.0, 1.0 };
+ static GLfloat normal[3] = { 0.0, 0.0, 1.0 };
+ static GLfloat index[1] = { 1.0 };
+ static GLfloat color[4] = { 1.0, 1.0, 1.0, 1.0 };
+ static GLfloat texcoord[4] = { 0.0, 0.0, 0.0, 1.0 };
+ static GLfloat attrib[4] = { 0.0, 0.0, 0.0, 1.0 };
+
+ init_1d_map( &ctx->EvalMap.Map1Vertex3, 3, vertex );
+ init_1d_map( &ctx->EvalMap.Map1Vertex4, 4, vertex );
+ init_1d_map( &ctx->EvalMap.Map1Index, 1, index );
+ init_1d_map( &ctx->EvalMap.Map1Color4, 4, color );
+ init_1d_map( &ctx->EvalMap.Map1Normal, 3, normal );
+ init_1d_map( &ctx->EvalMap.Map1Texture1, 1, texcoord );
+ init_1d_map( &ctx->EvalMap.Map1Texture2, 2, texcoord );
+ init_1d_map( &ctx->EvalMap.Map1Texture3, 3, texcoord );
+ init_1d_map( &ctx->EvalMap.Map1Texture4, 4, texcoord );
+ for (i = 0; i < 16; i++)
+ init_1d_map( ctx->EvalMap.Map1Attrib + i, 4, attrib );
+
+ init_2d_map( &ctx->EvalMap.Map2Vertex3, 3, vertex );
+ init_2d_map( &ctx->EvalMap.Map2Vertex4, 4, vertex );
+ init_2d_map( &ctx->EvalMap.Map2Index, 1, index );
+ init_2d_map( &ctx->EvalMap.Map2Color4, 4, color );
+ init_2d_map( &ctx->EvalMap.Map2Normal, 3, normal );
+ init_2d_map( &ctx->EvalMap.Map2Texture1, 1, texcoord );
+ init_2d_map( &ctx->EvalMap.Map2Texture2, 2, texcoord );
+ init_2d_map( &ctx->EvalMap.Map2Texture3, 3, texcoord );
+ init_2d_map( &ctx->EvalMap.Map2Texture4, 4, texcoord );
+ for (i = 0; i < 16; i++)
+ init_2d_map( ctx->EvalMap.Map2Attrib + i, 4, attrib );
+ }
+}
+
+
+void _mesa_free_eval_data( GLcontext *ctx )
+{
+ int i;
+
+ /* Free evaluator data */
+ if (ctx->EvalMap.Map1Vertex3.Points)
+ FREE( ctx->EvalMap.Map1Vertex3.Points );
+ if (ctx->EvalMap.Map1Vertex4.Points)
+ FREE( ctx->EvalMap.Map1Vertex4.Points );
+ if (ctx->EvalMap.Map1Index.Points)
+ FREE( ctx->EvalMap.Map1Index.Points );
+ if (ctx->EvalMap.Map1Color4.Points)
+ FREE( ctx->EvalMap.Map1Color4.Points );
+ if (ctx->EvalMap.Map1Normal.Points)
+ FREE( ctx->EvalMap.Map1Normal.Points );
+ if (ctx->EvalMap.Map1Texture1.Points)
+ FREE( ctx->EvalMap.Map1Texture1.Points );
+ if (ctx->EvalMap.Map1Texture2.Points)
+ FREE( ctx->EvalMap.Map1Texture2.Points );
+ if (ctx->EvalMap.Map1Texture3.Points)
+ FREE( ctx->EvalMap.Map1Texture3.Points );
+ if (ctx->EvalMap.Map1Texture4.Points)
+ FREE( ctx->EvalMap.Map1Texture4.Points );
+ for (i = 0; i < 16; i++)
+ FREE((ctx->EvalMap.Map1Attrib[i].Points));
+
+ if (ctx->EvalMap.Map2Vertex3.Points)
+ FREE( ctx->EvalMap.Map2Vertex3.Points );
+ if (ctx->EvalMap.Map2Vertex4.Points)
+ FREE( ctx->EvalMap.Map2Vertex4.Points );
+ if (ctx->EvalMap.Map2Index.Points)
+ FREE( ctx->EvalMap.Map2Index.Points );
+ if (ctx->EvalMap.Map2Color4.Points)
+ FREE( ctx->EvalMap.Map2Color4.Points );
+ if (ctx->EvalMap.Map2Normal.Points)
+ FREE( ctx->EvalMap.Map2Normal.Points );
+ if (ctx->EvalMap.Map2Texture1.Points)
+ FREE( ctx->EvalMap.Map2Texture1.Points );
+ if (ctx->EvalMap.Map2Texture2.Points)
+ FREE( ctx->EvalMap.Map2Texture2.Points );
+ if (ctx->EvalMap.Map2Texture3.Points)
+ FREE( ctx->EvalMap.Map2Texture3.Points );
+ if (ctx->EvalMap.Map2Texture4.Points)
+ FREE( ctx->EvalMap.Map2Texture4.Points );
+ for (i = 0; i < 16; i++)
+ FREE((ctx->EvalMap.Map2Attrib[i].Points));
+}
diff --git a/src/mesa/main/eval.h b/src/mesa/main/eval.h
new file mode 100644
index 00000000000..b3ff0a96f82
--- /dev/null
+++ b/src/mesa/main/eval.h
@@ -0,0 +1,128 @@
+/**
+ * \file eval.h
+ * Eval operations.
+ *
+ * \if subset
+ * (No-op)
+ *
+ * \endif
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.5
+ *
+ * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef EVAL_H
+#define EVAL_H
+
+
+#include "mtypes.h"
+
+#if _HAVE_FULL_GL
+
+extern void _mesa_init_eval( GLcontext *ctx );
+extern void _mesa_free_eval_data( GLcontext *ctx );
+
+
+extern GLuint _mesa_evaluator_components( GLenum target );
+
+
+extern void gl_free_control_points( GLcontext *ctx,
+ GLenum target, GLfloat *data );
+
+
+extern GLfloat *_mesa_copy_map_points1f( GLenum target,
+ GLint ustride, GLint uorder,
+ const GLfloat *points );
+
+extern GLfloat *_mesa_copy_map_points1d( GLenum target,
+ GLint ustride, GLint uorder,
+ const GLdouble *points );
+
+extern GLfloat *_mesa_copy_map_points2f( GLenum target,
+ GLint ustride, GLint uorder,
+ GLint vstride, GLint vorder,
+ const GLfloat *points );
+
+extern GLfloat *_mesa_copy_map_points2d(GLenum target,
+ GLint ustride, GLint uorder,
+ GLint vstride, GLint vorder,
+ const GLdouble *points );
+
+
+
+extern void GLAPIENTRY
+_mesa_Map1f( GLenum target, GLfloat u1, GLfloat u2, GLint stride,
+ GLint order, const GLfloat *points );
+
+extern void GLAPIENTRY
+_mesa_Map2f( GLenum target,
+ GLfloat u1, GLfloat u2, GLint ustride, GLint uorder,
+ GLfloat v1, GLfloat v2, GLint vstride, GLint vorder,
+ const GLfloat *points );
+
+extern void GLAPIENTRY
+_mesa_Map1d( GLenum target, GLdouble u1, GLdouble u2, GLint stride,
+ GLint order, const GLdouble *points );
+
+extern void GLAPIENTRY
+_mesa_Map2d( GLenum target,
+ GLdouble u1, GLdouble u2, GLint ustride, GLint uorder,
+ GLdouble v1, GLdouble v2, GLint vstride, GLint vorder,
+ const GLdouble *points );
+
+extern void GLAPIENTRY
+_mesa_MapGrid1f( GLint un, GLfloat u1, GLfloat u2 );
+
+extern void GLAPIENTRY
+_mesa_MapGrid1d( GLint un, GLdouble u1, GLdouble u2 );
+
+extern void GLAPIENTRY
+_mesa_MapGrid2f( GLint un, GLfloat u1, GLfloat u2,
+ GLint vn, GLfloat v1, GLfloat v2 );
+
+extern void GLAPIENTRY
+_mesa_MapGrid2d( GLint un, GLdouble u1, GLdouble u2,
+ GLint vn, GLdouble v1, GLdouble v2 );
+
+extern void GLAPIENTRY
+_mesa_GetMapdv( GLenum target, GLenum query, GLdouble *v );
+
+extern void GLAPIENTRY
+_mesa_GetMapfv( GLenum target, GLenum query, GLfloat *v );
+
+extern void GLAPIENTRY
+_mesa_GetMapiv( GLenum target, GLenum query, GLint *v );
+
+#else
+
+/** No-op */
+#define _mesa_init_eval( c ) ((void)0)
+
+/** No-op */
+#define _mesa_free_eval_data( c ) ((void)0)
+
+#endif
+
+#endif
diff --git a/src/mesa/main/execmem.c b/src/mesa/main/execmem.c
new file mode 100644
index 00000000000..7d498a82791
--- /dev/null
+++ b/src/mesa/main/execmem.c
@@ -0,0 +1,131 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/**
+ * \file exemem.c
+ * Functions for allocating executable memory.
+ *
+ * \author Keith Whitwell
+ */
+
+
+#include "imports.h"
+#include "glthread.h"
+
+
+
+#if defined(__linux__) && !defined(XFree86Server)
+
+/*
+ * Allocate a large block of memory which can hold code then dole it out
+ * in pieces by means of the generic memory manager code.
+*/
+
+#include <unistd.h>
+#include <sys/mman.h>
+#include "mm.h"
+
+#define EXEC_HEAP_SIZE (128*1024)
+
+_glthread_DECLARE_STATIC_MUTEX(exec_mutex);
+
+static struct mem_block *exec_heap = NULL;
+static unsigned char *exec_mem = NULL;
+
+
+static void
+init_heap(void)
+{
+ if (!exec_heap)
+ exec_heap = mmInit( 0, EXEC_HEAP_SIZE );
+
+ if (!exec_mem)
+ exec_mem = (unsigned char *) mmap(0, EXEC_HEAP_SIZE,
+ PROT_EXEC | PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+}
+
+
+void *
+_mesa_exec_malloc(GLuint size)
+{
+ struct mem_block *block = NULL;
+ void *addr = NULL;
+
+ _glthread_LOCK_MUTEX(exec_mutex);
+
+ init_heap();
+
+ if (exec_heap) {
+ size = (size + 31) & ~31;
+ block = mmAllocMem( exec_heap, size, 32, 0 );
+ }
+
+ if (block)
+ addr = exec_mem + block->ofs;
+
+ _glthread_UNLOCK_MUTEX(exec_mutex);
+
+ return addr;
+}
+
+
+void
+_mesa_exec_free(void *addr)
+{
+ _glthread_LOCK_MUTEX(exec_mutex);
+
+ if (exec_heap) {
+ struct mem_block *block = mmFindBlock(exec_heap, (unsigned char *)addr - exec_mem);
+
+ if (block)
+ mmFreeMem(block);
+ }
+
+ _glthread_UNLOCK_MUTEX(exec_mutex);
+}
+
+
+#else
+
+/*
+ * Just use regular memory.
+ */
+
+void *
+_mesa_exec_malloc(GLuint size)
+{
+ return _mesa_malloc( size );
+}
+
+
+void
+_mesa_exec_free(void *addr)
+{
+ _mesa_free(addr);
+}
+
+
+#endif
diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c
new file mode 100644
index 00000000000..5bd2515f053
--- /dev/null
+++ b/src/mesa/main/extensions.c
@@ -0,0 +1,517 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include "glheader.h"
+#include "imports.h"
+#include "context.h"
+#include "extensions.h"
+#include "simple_list.h"
+#include "mtypes.h"
+
+
+#define F(x) (int)(uintptr_t)&(((struct gl_extensions *)0)->x)
+#define ON GL_TRUE
+#define OFF GL_FALSE
+
+
+/*
+ * Note: The GL_MESAX_* extensions are placeholders for future ARB extensions.
+ */
+static const struct {
+ GLboolean enabled;
+ const char *name;
+ int flag_offset;
+} default_extensions[] = {
+ { OFF, "GL_ARB_depth_texture", F(ARB_depth_texture) },
+ { OFF, "GL_ARB_draw_buffers", F(ARB_draw_buffers) },
+ { OFF, "GL_ARB_fragment_program", F(ARB_fragment_program) },
+ { OFF, "GL_ARB_fragment_shader", F(ARB_fragment_shader) },
+ { OFF, "GL_ARB_half_float_pixel", F(ARB_half_float_pixel) },
+ { OFF, "GL_ARB_imaging", F(ARB_imaging) },
+ { OFF, "GL_ARB_multisample", F(ARB_multisample) },
+ { OFF, "GL_ARB_multitexture", F(ARB_multitexture) },
+ { OFF, "GL_ARB_occlusion_query", F(ARB_occlusion_query) },
+ { OFF, "GL_ARB_pixel_buffer_object", F(EXT_pixel_buffer_object) },
+ { OFF, "GL_ARB_point_parameters", F(EXT_point_parameters) },
+ { OFF, "GL_ARB_point_sprite", F(ARB_point_sprite) },
+ { OFF, "GL_ARB_shader_objects", F(ARB_shader_objects) },
+ { OFF, "GL_ARB_shading_language_100", F(ARB_shading_language_100) },
+ { OFF, "GL_ARB_shadow", F(ARB_shadow) },
+ { OFF, "GL_ARB_shadow_ambient", F(SGIX_shadow_ambient) },
+ { OFF, "GL_ARB_texture_border_clamp", F(ARB_texture_border_clamp) },
+ { OFF, "GL_ARB_texture_compression", F(ARB_texture_compression) },
+ { OFF, "GL_ARB_texture_cube_map", F(ARB_texture_cube_map) },
+ { OFF, "GL_ARB_texture_env_add", F(EXT_texture_env_add) },
+ { OFF, "GL_ARB_texture_env_combine", F(ARB_texture_env_combine) },
+ { OFF, "GL_ARB_texture_env_crossbar", F(ARB_texture_env_crossbar) },
+ { OFF, "GL_ARB_texture_env_dot3", F(ARB_texture_env_dot3) },
+ { OFF, "GL_MESAX_texture_float", F(ARB_texture_float) },
+ { OFF, "GL_ARB_texture_mirrored_repeat", F(ARB_texture_mirrored_repeat)},
+ { OFF, "GL_ARB_texture_non_power_of_two", F(ARB_texture_non_power_of_two)},
+ { OFF, "GL_ARB_texture_rectangle", F(NV_texture_rectangle) },
+ { ON, "GL_ARB_transpose_matrix", F(ARB_transpose_matrix) },
+ { OFF, "GL_ARB_vertex_buffer_object", F(ARB_vertex_buffer_object) },
+ { OFF, "GL_ARB_vertex_program", F(ARB_vertex_program) },
+ { OFF, "GL_ARB_vertex_shader", F(ARB_vertex_shader) },
+ { ON, "GL_ARB_window_pos", F(ARB_window_pos) },
+ { ON, "GL_EXT_abgr", F(EXT_abgr) },
+ { ON, "GL_EXT_bgra", F(EXT_bgra) },
+ { OFF, "GL_EXT_blend_color", F(EXT_blend_color) },
+ { OFF, "GL_EXT_blend_equation_separate", F(EXT_blend_equation_separate) },
+ { OFF, "GL_EXT_blend_func_separate", F(EXT_blend_func_separate) },
+ { OFF, "GL_EXT_blend_logic_op", F(EXT_blend_logic_op) },
+ { OFF, "GL_EXT_blend_minmax", F(EXT_blend_minmax) },
+ { OFF, "GL_EXT_blend_subtract", F(EXT_blend_subtract) },
+ { ON, "GL_EXT_clip_volume_hint", F(EXT_clip_volume_hint) },
+ { OFF, "GL_EXT_cull_vertex", F(EXT_cull_vertex) },
+ { ON, "GL_EXT_compiled_vertex_array", F(EXT_compiled_vertex_array) },
+ { OFF, "GL_EXT_convolution", F(EXT_convolution) },
+ { ON, "GL_EXT_copy_texture", F(EXT_copy_texture) },
+ { OFF, "GL_EXT_depth_bounds_test", F(EXT_depth_bounds_test) },
+ { ON, "GL_EXT_draw_range_elements", F(EXT_draw_range_elements) },
+ { OFF, "GL_EXT_framebuffer_object", F(EXT_framebuffer_object) },
+ { OFF, "GL_EXT_framebuffer_blit", F(EXT_framebuffer_blit) },
+ { OFF, "GL_EXT_fog_coord", F(EXT_fog_coord) },
+ { OFF, "GL_EXT_histogram", F(EXT_histogram) },
+ { OFF, "GL_EXT_multi_draw_arrays", F(EXT_multi_draw_arrays) },
+ { OFF, "GL_EXT_packed_depth_stencil", F(EXT_packed_depth_stencil) },
+ { ON, "GL_EXT_packed_pixels", F(EXT_packed_pixels) },
+ { OFF, "GL_EXT_paletted_texture", F(EXT_paletted_texture) },
+ { OFF, "GL_EXT_pixel_buffer_object", F(EXT_pixel_buffer_object) },
+ { OFF, "GL_EXT_point_parameters", F(EXT_point_parameters) },
+ { ON, "GL_EXT_polygon_offset", F(EXT_polygon_offset) },
+ { ON, "GL_EXT_rescale_normal", F(EXT_rescale_normal) },
+ { OFF, "GL_EXT_secondary_color", F(EXT_secondary_color) },
+ { ON, "GL_EXT_separate_specular_color", F(EXT_separate_specular_color) },
+ { OFF, "GL_EXT_shadow_funcs", F(EXT_shadow_funcs) },
+ { OFF, "GL_EXT_shared_texture_palette", F(EXT_shared_texture_palette) },
+ { OFF, "GL_EXT_stencil_two_side", F(EXT_stencil_two_side) },
+ { OFF, "GL_EXT_stencil_wrap", F(EXT_stencil_wrap) },
+ { ON, "GL_EXT_subtexture", F(EXT_subtexture) },
+ { ON, "GL_EXT_texture", F(EXT_texture) },
+ { ON, "GL_EXT_texture3D", F(EXT_texture3D) },
+ { OFF, "GL_EXT_texture_compression_s3tc", F(EXT_texture_compression_s3tc) },
+ { ON, "GL_EXT_texture_edge_clamp", F(SGIS_texture_edge_clamp) },
+ { OFF, "GL_EXT_texture_env_add", F(EXT_texture_env_add) },
+ { OFF, "GL_EXT_texture_env_combine", F(EXT_texture_env_combine) },
+ { OFF, "GL_EXT_texture_env_dot3", F(EXT_texture_env_dot3) },
+ { OFF, "GL_EXT_texture_filter_anisotropic", F(EXT_texture_filter_anisotropic) },
+ { OFF, "GL_EXT_texture_lod_bias", F(EXT_texture_lod_bias) },
+ { OFF, "GL_EXT_texture_mirror_clamp", F(EXT_texture_mirror_clamp) },
+ { ON, "GL_EXT_texture_object", F(EXT_texture_object) },
+ { OFF, "GL_EXT_texture_rectangle", F(NV_texture_rectangle) },
+ { OFF, "GL_EXT_timer_query", F(EXT_timer_query) },
+ { ON, "GL_EXT_vertex_array", F(EXT_vertex_array) },
+ { OFF, "GL_EXT_vertex_array_set", F(EXT_vertex_array_set) },
+ { OFF, "GL_3DFX_texture_compression_FXT1", F(TDFX_texture_compression_FXT1) },
+ { OFF, "GL_APPLE_client_storage", F(APPLE_client_storage) },
+ { ON, "GL_APPLE_packed_pixels", F(APPLE_packed_pixels) },
+ { OFF, "GL_ATI_blend_equation_separate", F(EXT_blend_equation_separate) },
+ { OFF, "GL_ATI_texture_env_combine3", F(ATI_texture_env_combine3)},
+ { OFF, "GL_ATI_texture_mirror_once", F(ATI_texture_mirror_once)},
+ { OFF, "GL_ATI_fragment_shader", F(ATI_fragment_shader)},
+ { OFF, "GL_IBM_multimode_draw_arrays", F(IBM_multimode_draw_arrays) },
+ { ON, "GL_IBM_rasterpos_clip", F(IBM_rasterpos_clip) },
+ { OFF, "GL_IBM_texture_mirrored_repeat", F(ARB_texture_mirrored_repeat)},
+ { OFF, "GL_INGR_blend_func_separate", F(EXT_blend_func_separate) },
+ { OFF, "GL_MESA_pack_invert", F(MESA_pack_invert) },
+ { OFF, "GL_MESA_packed_depth_stencil", F(MESA_packed_depth_stencil) },
+ { OFF, "GL_MESA_program_debug", F(MESA_program_debug) },
+ { OFF, "GL_MESA_resize_buffers", F(MESA_resize_buffers) },
+ { OFF, "GL_MESA_ycbcr_texture", F(MESA_ycbcr_texture) },
+ { ON, "GL_MESA_window_pos", F(ARB_window_pos) },
+ { OFF, "GL_NV_blend_square", F(NV_blend_square) },
+ { OFF, "GL_NV_fragment_program", F(NV_fragment_program) },
+ { ON, "GL_NV_light_max_exponent", F(NV_light_max_exponent) },
+ { OFF, "GL_NV_point_sprite", F(NV_point_sprite) },
+ { OFF, "GL_NV_texture_rectangle", F(NV_texture_rectangle) },
+ { ON, "GL_NV_texgen_reflection", F(NV_texgen_reflection) },
+ { OFF, "GL_NV_vertex_program", F(NV_vertex_program) },
+ { OFF, "GL_NV_vertex_program1_1", F(NV_vertex_program1_1) },
+ { ON, "GL_OES_read_format", F(OES_read_format) },
+ { OFF, "GL_SGI_color_matrix", F(SGI_color_matrix) },
+ { OFF, "GL_SGI_color_table", F(SGI_color_table) },
+ { OFF, "GL_SGI_texture_color_table", F(SGI_texture_color_table) },
+ { OFF, "GL_SGIS_generate_mipmap", F(SGIS_generate_mipmap) },
+ { OFF, "GL_SGIS_texture_border_clamp", F(ARB_texture_border_clamp) },
+ { ON, "GL_SGIS_texture_edge_clamp", F(SGIS_texture_edge_clamp) },
+ { ON, "GL_SGIS_texture_lod", F(SGIS_texture_lod) },
+ { OFF, "GL_SGIX_depth_texture", F(SGIX_depth_texture) },
+ { OFF, "GL_SGIX_shadow", F(SGIX_shadow) },
+ { OFF, "GL_SGIX_shadow_ambient", F(SGIX_shadow_ambient) },
+ { OFF, "GL_SUN_multi_draw_arrays", F(EXT_multi_draw_arrays) },
+ { OFF, "GL_S3_s3tc", F(S3_s3tc) },
+};
+
+
+
+/**
+ * Enable all extensions suitable for a software-only renderer.
+ * This is a convenience function used by the XMesa, OSMesa, GGI drivers, etc.
+ */
+void
+_mesa_enable_sw_extensions(GLcontext *ctx)
+{
+ ctx->Extensions.ARB_depth_texture = GL_TRUE;
+ ctx->Extensions.ARB_draw_buffers = GL_TRUE;
+#if FEATURE_ARB_fragment_program
+ ctx->Extensions.ARB_fragment_program = GL_TRUE;
+#endif
+#if FEATURE_ARB_fragment_shader
+ ctx->Extensions.ARB_fragment_shader = GL_TRUE;
+#endif
+ ctx->Extensions.ARB_half_float_pixel = GL_TRUE;
+ ctx->Extensions.ARB_imaging = GL_TRUE;
+ ctx->Extensions.ARB_multitexture = GL_TRUE;
+#if FEATURE_ARB_occlusion_query
+ ctx->Extensions.ARB_occlusion_query = GL_TRUE;
+#endif
+ ctx->Extensions.ARB_point_sprite = GL_TRUE;
+#if FEATURE_ARB_shader_objects
+ ctx->Extensions.ARB_shader_objects = GL_TRUE;
+#endif
+#if FEATURE_ARB_shading_language_100
+ ctx->Extensions.ARB_shading_language_100 = GL_TRUE;
+#endif
+ ctx->Extensions.ARB_shadow = GL_TRUE;
+ ctx->Extensions.ARB_texture_border_clamp = GL_TRUE;
+ ctx->Extensions.ARB_texture_cube_map = GL_TRUE;
+ ctx->Extensions.ARB_texture_env_combine = GL_TRUE;
+ ctx->Extensions.ARB_texture_env_crossbar = GL_TRUE;
+ ctx->Extensions.ARB_texture_env_dot3 = GL_TRUE;
+ /*ctx->Extensions.ARB_texture_float = GL_TRUE;*/
+ ctx->Extensions.ARB_texture_mirrored_repeat = GL_TRUE;
+ ctx->Extensions.ARB_texture_non_power_of_two = GL_TRUE;
+#if FEATURE_ARB_vertex_program
+ ctx->Extensions.ARB_vertex_program = GL_TRUE;
+#endif
+#if FEATURE_ARB_vertex_shader
+ ctx->Extensions.ARB_vertex_shader = GL_TRUE;
+#endif
+#if FEATURE_ARB_vertex_buffer_object
+ ctx->Extensions.ARB_vertex_buffer_object = GL_TRUE;
+#endif
+#if FEATURE_ATI_fragment_shader
+ ctx->Extensions.ATI_fragment_shader = GL_TRUE;
+#endif
+ ctx->Extensions.ATI_texture_env_combine3 = GL_TRUE;
+ ctx->Extensions.ATI_texture_mirror_once = GL_TRUE;
+ ctx->Extensions.EXT_blend_color = GL_TRUE;
+ ctx->Extensions.EXT_blend_equation_separate = GL_TRUE;
+ ctx->Extensions.EXT_blend_func_separate = GL_TRUE;
+ ctx->Extensions.EXT_blend_logic_op = GL_TRUE;
+ ctx->Extensions.EXT_blend_minmax = GL_TRUE;
+ ctx->Extensions.EXT_blend_subtract = GL_TRUE;
+ ctx->Extensions.EXT_convolution = GL_TRUE;
+ ctx->Extensions.EXT_depth_bounds_test = GL_TRUE;
+ ctx->Extensions.EXT_fog_coord = GL_TRUE;
+#if FEATURE_EXT_framebuffer_object
+ ctx->Extensions.EXT_framebuffer_object = GL_TRUE;
+#endif
+#if FEATURE_EXT_framebuffer_blit
+ ctx->Extensions.EXT_framebuffer_blit = GL_TRUE;
+#endif
+ ctx->Extensions.EXT_histogram = GL_TRUE;
+ ctx->Extensions.EXT_multi_draw_arrays = GL_TRUE;
+ ctx->Extensions.EXT_packed_depth_stencil = GL_TRUE;
+ ctx->Extensions.EXT_paletted_texture = GL_TRUE;
+#if FEATURE_EXT_pixel_buffer_object
+ ctx->Extensions.EXT_pixel_buffer_object = GL_TRUE;
+#endif
+ ctx->Extensions.EXT_point_parameters = GL_TRUE;
+ ctx->Extensions.EXT_shadow_funcs = GL_TRUE;
+ ctx->Extensions.EXT_secondary_color = GL_TRUE;
+ ctx->Extensions.EXT_shared_texture_palette = GL_TRUE;
+ ctx->Extensions.EXT_stencil_wrap = GL_TRUE;
+ ctx->Extensions.EXT_stencil_two_side = GL_TRUE;
+ ctx->Extensions.EXT_texture_env_add = GL_TRUE;
+ ctx->Extensions.EXT_texture_env_combine = GL_TRUE;
+ ctx->Extensions.EXT_texture_env_dot3 = GL_TRUE;
+ ctx->Extensions.EXT_texture_mirror_clamp = GL_TRUE;
+ ctx->Extensions.EXT_texture_lod_bias = GL_TRUE;
+ ctx->Extensions.IBM_multimode_draw_arrays = GL_TRUE;
+ ctx->Extensions.MESA_pack_invert = GL_TRUE;
+#if FEATURE_MESA_program_debug
+ ctx->Extensions.MESA_program_debug = GL_TRUE;
+#endif
+ ctx->Extensions.MESA_resize_buffers = GL_TRUE;
+ ctx->Extensions.MESA_ycbcr_texture = GL_TRUE;
+ ctx->Extensions.NV_blend_square = GL_TRUE;
+ /*ctx->Extensions.NV_light_max_exponent = GL_TRUE;*/
+ ctx->Extensions.NV_point_sprite = GL_TRUE;
+ ctx->Extensions.NV_texture_rectangle = GL_TRUE;
+ /*ctx->Extensions.NV_texgen_reflection = GL_TRUE;*/
+#if FEATURE_NV_vertex_program
+ ctx->Extensions.NV_vertex_program = GL_TRUE;
+ ctx->Extensions.NV_vertex_program1_1 = GL_TRUE;
+#endif
+#if FEATURE_NV_fragment_program
+ ctx->Extensions.NV_fragment_program = GL_TRUE;
+#endif
+ ctx->Extensions.SGI_color_matrix = GL_TRUE;
+ ctx->Extensions.SGI_color_table = GL_TRUE;
+ ctx->Extensions.SGI_texture_color_table = GL_TRUE;
+ ctx->Extensions.SGIS_generate_mipmap = GL_TRUE;
+ ctx->Extensions.SGIS_texture_edge_clamp = GL_TRUE;
+ ctx->Extensions.SGIX_depth_texture = GL_TRUE;
+ ctx->Extensions.SGIX_shadow = GL_TRUE;
+ ctx->Extensions.SGIX_shadow_ambient = GL_TRUE;
+}
+
+
+/**
+ * Enable GL_ARB_imaging and all the EXT extensions that are subsets of it.
+ */
+void
+_mesa_enable_imaging_extensions(GLcontext *ctx)
+{
+ ctx->Extensions.ARB_imaging = GL_TRUE;
+ ctx->Extensions.EXT_blend_color = GL_TRUE;
+ ctx->Extensions.EXT_blend_minmax = GL_TRUE;
+ ctx->Extensions.EXT_blend_subtract = GL_TRUE;
+ ctx->Extensions.EXT_convolution = GL_TRUE;
+ ctx->Extensions.EXT_histogram = GL_TRUE;
+ ctx->Extensions.SGI_color_matrix = GL_TRUE;
+ ctx->Extensions.SGI_color_table = GL_TRUE;
+}
+
+
+
+/**
+ * Enable all OpenGL 1.3 features and extensions.
+ * A convenience function to be called by drivers.
+ */
+void
+_mesa_enable_1_3_extensions(GLcontext *ctx)
+{
+ ctx->Extensions.ARB_multisample = GL_TRUE;
+ ctx->Extensions.ARB_multitexture = GL_TRUE;
+ ctx->Extensions.ARB_texture_border_clamp = GL_TRUE;
+ ctx->Extensions.ARB_texture_compression = GL_TRUE;
+ ctx->Extensions.ARB_texture_cube_map = GL_TRUE;
+ ctx->Extensions.ARB_texture_env_combine = GL_TRUE;
+ ctx->Extensions.ARB_texture_env_dot3 = GL_TRUE;
+ ctx->Extensions.EXT_texture_env_add = GL_TRUE;
+ /*ctx->Extensions.ARB_transpose_matrix = GL_TRUE;*/
+}
+
+
+
+/**
+ * Enable all OpenGL 1.4 features and extensions.
+ * A convenience function to be called by drivers.
+ */
+void
+_mesa_enable_1_4_extensions(GLcontext *ctx)
+{
+ ctx->Extensions.ARB_depth_texture = GL_TRUE;
+ ctx->Extensions.ARB_shadow = GL_TRUE;
+ ctx->Extensions.ARB_texture_env_crossbar = GL_TRUE;
+ ctx->Extensions.ARB_texture_mirrored_repeat = GL_TRUE;
+ ctx->Extensions.ARB_window_pos = GL_TRUE;
+ ctx->Extensions.EXT_blend_color = GL_TRUE;
+ ctx->Extensions.EXT_blend_func_separate = GL_TRUE;
+ ctx->Extensions.EXT_blend_logic_op = GL_TRUE;
+ ctx->Extensions.EXT_blend_minmax = GL_TRUE;
+ ctx->Extensions.EXT_blend_subtract = GL_TRUE;
+ ctx->Extensions.EXT_fog_coord = GL_TRUE;
+ ctx->Extensions.EXT_multi_draw_arrays = GL_TRUE;
+ ctx->Extensions.EXT_point_parameters = GL_TRUE;
+ ctx->Extensions.EXT_secondary_color = GL_TRUE;
+ ctx->Extensions.EXT_stencil_wrap = GL_TRUE;
+ ctx->Extensions.EXT_texture_lod_bias = GL_TRUE;
+ ctx->Extensions.SGIS_generate_mipmap = GL_TRUE;
+}
+
+
+/**
+ * Enable all OpenGL 1.5 features and extensions.
+ * A convenience function to be called by drivers.
+ */
+void
+_mesa_enable_1_5_extensions(GLcontext *ctx)
+{
+ ctx->Extensions.ARB_occlusion_query = GL_TRUE;
+ ctx->Extensions.ARB_vertex_buffer_object = GL_TRUE;
+ ctx->Extensions.EXT_shadow_funcs = GL_TRUE;
+}
+
+
+/**
+ * Enable all OpenGL 2.0 features and extensions.
+ * A convenience function to be called by drivers.
+ */
+void
+_mesa_enable_2_0_extensions(GLcontext *ctx)
+{
+ ctx->Extensions.ARB_draw_buffers = GL_TRUE;
+#if FEATURE_ARB_fragment_shader
+ ctx->Extensions.ARB_fragment_shader = GL_TRUE;
+#endif
+ ctx->Extensions.ARB_point_sprite = GL_TRUE;
+ ctx->Extensions.ARB_texture_non_power_of_two = GL_TRUE;
+#if FEATURE_ARB_shader_objects
+ ctx->Extensions.ARB_shader_objects = GL_TRUE;
+#endif
+#if FEATURE_ARB_shading_language_100
+ ctx->Extensions.ARB_shading_language_100 = GL_TRUE;
+#endif
+ ctx->Extensions.EXT_stencil_two_side = GL_FALSE; /* yes, turn it off */
+#if FEATURE_ARB_vertex_shader
+ ctx->Extensions.ARB_vertex_shader = GL_TRUE;
+#endif
+}
+
+
+
+/**
+ * Either enable or disable the named extension.
+ */
+static void
+set_extension( GLcontext *ctx, const char *name, GLboolean state )
+{
+ GLboolean *base = (GLboolean *) &ctx->Extensions;
+ GLuint i;
+
+ if (ctx->Extensions.String) {
+ /* The string was already queried - can't change it now! */
+ _mesa_problem(ctx, "Trying to enable/disable extension after glGetString(GL_EXTENSIONS): %s", name);
+ return;
+ }
+
+ for (i = 0 ; i < Elements(default_extensions) ; i++) {
+ if (_mesa_strcmp(default_extensions[i].name, name) == 0) {
+ if (default_extensions[i].flag_offset) {
+ GLboolean *enabled = base + default_extensions[i].flag_offset;
+ *enabled = state;
+ }
+ return;
+ }
+ }
+ _mesa_problem(ctx, "Trying to enable unknown extension: %s", name);
+}
+
+
+/**
+ * Enable the named extension.
+ * Typically called by drivers.
+ */
+void
+_mesa_enable_extension( GLcontext *ctx, const char *name )
+{
+ set_extension(ctx, name, GL_TRUE);
+}
+
+
+/**
+ * Disable the named extension.
+ * XXX is this really needed???
+ */
+void
+_mesa_disable_extension( GLcontext *ctx, const char *name )
+{
+ set_extension(ctx, name, GL_FALSE);
+}
+
+
+/**
+ * Test if the named extension is enabled in this context.
+ */
+GLboolean
+_mesa_extension_is_enabled( GLcontext *ctx, const char *name )
+{
+ const GLboolean *base = (const GLboolean *) &ctx->Extensions;
+ GLuint i;
+
+ for (i = 0 ; i < Elements(default_extensions) ; i++) {
+ if (_mesa_strcmp(default_extensions[i].name, name) == 0) {
+ if (!default_extensions[i].flag_offset)
+ return GL_TRUE;
+ return *(base + default_extensions[i].flag_offset);
+ }
+ }
+ return GL_FALSE;
+}
+
+
+/**
+ * Run through the default_extensions array above and set the
+ * ctx->Extensions.ARB/EXT_* flags accordingly.
+ * To be called during context initialization.
+ */
+void
+_mesa_init_extensions( GLcontext *ctx )
+{
+ GLboolean *base = (GLboolean *) &ctx->Extensions;
+ GLuint i;
+
+ for (i = 0 ; i < Elements(default_extensions) ; i++) {
+ if (default_extensions[i].enabled &&
+ default_extensions[i].flag_offset) {
+ *(base + default_extensions[i].flag_offset) = GL_TRUE;
+ }
+ }
+}
+
+
+/**
+ * Construct the GL_EXTENSIONS string. Called the first time that
+ * glGetString(GL_EXTENSIONS) is called.
+ */
+GLubyte *
+_mesa_make_extension_string( GLcontext *ctx )
+{
+ const GLboolean *base = (const GLboolean *) &ctx->Extensions;
+ GLuint extStrLen = 0;
+ GLubyte *s;
+ GLuint i;
+
+ /* first, compute length of the extension string */
+ for (i = 0 ; i < Elements(default_extensions) ; i++) {
+ if (!default_extensions[i].flag_offset ||
+ *(base + default_extensions[i].flag_offset)) {
+ extStrLen += (GLuint)_mesa_strlen(default_extensions[i].name) + 1;
+ }
+ }
+ s = (GLubyte *) _mesa_malloc(extStrLen);
+
+ /* second, build the extension string */
+ extStrLen = 0;
+ for (i = 0 ; i < Elements(default_extensions) ; i++) {
+ if (!default_extensions[i].flag_offset ||
+ *(base + default_extensions[i].flag_offset)) {
+ GLuint len = (GLuint)_mesa_strlen(default_extensions[i].name);
+ _mesa_memcpy(s + extStrLen, default_extensions[i].name, len);
+ extStrLen += len;
+ s[extStrLen] = (GLubyte) ' ';
+ extStrLen++;
+ }
+ }
+ ASSERT(extStrLen > 0);
+
+ s[extStrLen - 1] = 0;
+
+ return s;
+}
diff --git a/src/mesa/main/extensions.h b/src/mesa/main/extensions.h
new file mode 100644
index 00000000000..9d843a8b6b6
--- /dev/null
+++ b/src/mesa/main/extensions.h
@@ -0,0 +1,84 @@
+/**
+ * \file extensions.h
+ * Extension handling.
+ *
+ * \if subset
+ * (No-op)
+ *
+ * \endif
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.3
+ *
+ * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef _EXTENSIONS_H_
+#define _EXTENSIONS_H_
+
+#include "mtypes.h"
+
+#if _HAVE_FULL_GL
+
+extern void _mesa_enable_sw_extensions(GLcontext *ctx);
+
+extern void _mesa_enable_imaging_extensions(GLcontext *ctx);
+
+extern void _mesa_enable_1_3_extensions(GLcontext *ctx);
+
+extern void _mesa_enable_1_4_extensions(GLcontext *ctx);
+
+extern void _mesa_enable_1_5_extensions(GLcontext *ctx);
+
+extern void _mesa_enable_2_0_extensions(GLcontext *ctx);
+
+extern void _mesa_enable_extension(GLcontext *ctx, const char *name);
+
+extern void _mesa_disable_extension(GLcontext *ctx, const char *name);
+
+extern GLboolean _mesa_extension_is_enabled(GLcontext *ctx, const char *name);
+
+extern void _mesa_init_extensions(GLcontext *ctx);
+
+extern GLubyte *_mesa_make_extension_string(GLcontext *ctx);
+
+#else
+
+/** No-op */
+#define _mesa_extensions_dtr( ctx ) ((void)0)
+
+/** No-op */
+#define _mesa_extensions_ctr( ctx ) ((void)0)
+
+/** No-op */
+#define _mesa_extensions_get_string( ctx ) "GL_EXT_texture_object"
+
+/** No-op */
+#define _mesa_enable_imaging_extensions( c ) ((void)0)
+
+/** No-op */
+#define _mesa_enable_extension( c, n ) ((void)0)
+
+#endif
+
+#endif
diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
new file mode 100644
index 00000000000..191b81c39c6
--- /dev/null
+++ b/src/mesa/main/fbobject.c
@@ -0,0 +1,1644 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/*
+ * Authors:
+ * Brian Paul
+ */
+
+
+#include "context.h"
+#include "fbobject.h"
+#include "framebuffer.h"
+#include "hash.h"
+#include "renderbuffer.h"
+#include "state.h"
+#include "teximage.h"
+#include "texobj.h"
+#include "texstore.h"
+
+
+/**
+ * Notes:
+ *
+ * None of the GL_EXT_framebuffer_object functions are compiled into
+ * display lists.
+ */
+
+
+
+/*
+ * When glGenRender/FramebuffersEXT() is called we insert pointers to
+ * these placeholder objects into the hash table.
+ * Later, when the object ID is first bound, we replace the placeholder
+ * with the real frame/renderbuffer.
+ */
+static struct gl_framebuffer DummyFramebuffer;
+static struct gl_renderbuffer DummyRenderbuffer;
+
+
+#define IS_CUBE_FACE(TARGET) \
+ ((TARGET) >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && \
+ (TARGET) <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
+
+
+/**
+ * Helper routine for getting a gl_renderbuffer.
+ */
+struct gl_renderbuffer *
+_mesa_lookup_renderbuffer(GLcontext *ctx, GLuint id)
+{
+ struct gl_renderbuffer *rb;
+
+ if (id == 0)
+ return NULL;
+
+ rb = (struct gl_renderbuffer *)
+ _mesa_HashLookup(ctx->Shared->RenderBuffers, id);
+ return rb;
+}
+
+
+/**
+ * Helper routine for getting a gl_framebuffer.
+ */
+struct gl_framebuffer *
+_mesa_lookup_framebuffer(GLcontext *ctx, GLuint id)
+{
+ struct gl_framebuffer *fb;
+
+ if (id == 0)
+ return NULL;
+
+ fb = (struct gl_framebuffer *)
+ _mesa_HashLookup(ctx->Shared->FrameBuffers, id);
+ return fb;
+}
+
+
+/**
+ * Given a GL_*_ATTACHMENTn token, return a pointer to the corresponding
+ * gl_renderbuffer_attachment object.
+ */
+struct gl_renderbuffer_attachment *
+_mesa_get_attachment(GLcontext *ctx, struct gl_framebuffer *fb,
+ GLenum attachment)
+{
+ GLuint i;
+
+ switch (attachment) {
+ case GL_COLOR_ATTACHMENT0_EXT:
+ case GL_COLOR_ATTACHMENT1_EXT:
+ case GL_COLOR_ATTACHMENT2_EXT:
+ case GL_COLOR_ATTACHMENT3_EXT:
+ case GL_COLOR_ATTACHMENT4_EXT:
+ case GL_COLOR_ATTACHMENT5_EXT:
+ case GL_COLOR_ATTACHMENT6_EXT:
+ case GL_COLOR_ATTACHMENT7_EXT:
+ case GL_COLOR_ATTACHMENT8_EXT:
+ case GL_COLOR_ATTACHMENT9_EXT:
+ case GL_COLOR_ATTACHMENT10_EXT:
+ case GL_COLOR_ATTACHMENT11_EXT:
+ case GL_COLOR_ATTACHMENT12_EXT:
+ case GL_COLOR_ATTACHMENT13_EXT:
+ case GL_COLOR_ATTACHMENT14_EXT:
+ case GL_COLOR_ATTACHMENT15_EXT:
+ i = attachment - GL_COLOR_ATTACHMENT0_EXT;
+ if (i >= ctx->Const.MaxColorAttachments) {
+ return NULL;
+ }
+ return &fb->Attachment[BUFFER_COLOR0 + i];
+ case GL_DEPTH_ATTACHMENT_EXT:
+ return &fb->Attachment[BUFFER_DEPTH];
+ case GL_STENCIL_ATTACHMENT_EXT:
+ return &fb->Attachment[BUFFER_STENCIL];
+ default:
+ return NULL;
+ }
+}
+
+
+/**
+ * Remove any texture or renderbuffer attached to the given attachment
+ * point. Update reference counts, etc.
+ */
+void
+_mesa_remove_attachment(GLcontext *ctx, struct gl_renderbuffer_attachment *att)
+{
+ if (att->Type == GL_TEXTURE) {
+ ASSERT(att->Texture);
+ att->Texture->RefCount--;
+ if (att->Texture->RefCount == 0) {
+ ctx->Driver.DeleteTexture(ctx, att->Texture);
+ }
+ else {
+ /* tell driver that we're done rendering to this texture. */
+ if (ctx->Driver.FinishRenderTexture) {
+ ctx->Driver.FinishRenderTexture(ctx, att);
+ }
+ }
+ att->Texture = NULL;
+ }
+ if (att->Type == GL_TEXTURE || att->Type == GL_RENDERBUFFER_EXT) {
+ ASSERT(att->Renderbuffer);
+ ASSERT(!att->Texture);
+ att->Renderbuffer->RefCount--;
+ if (att->Renderbuffer->RefCount == 0) {
+ att->Renderbuffer->Delete(att->Renderbuffer);
+ }
+ att->Renderbuffer = NULL;
+ }
+ att->Type = GL_NONE;
+ att->Complete = GL_TRUE;
+}
+
+
+/**
+ * Bind a texture object to an attachment point.
+ * The previous binding, if any, will be removed first.
+ */
+void
+_mesa_set_texture_attachment(GLcontext *ctx,
+ struct gl_framebuffer *fb,
+ struct gl_renderbuffer_attachment *att,
+ struct gl_texture_object *texObj,
+ GLenum texTarget, GLuint level, GLuint zoffset)
+{
+ if (att->Texture == texObj) {
+ /* re-attaching same texture */
+ ASSERT(att->Type == GL_TEXTURE);
+ }
+ else {
+ /* new attachment */
+ _mesa_remove_attachment(ctx, att);
+ att->Type = GL_TEXTURE;
+ att->Texture = texObj;
+ texObj->RefCount++;
+ }
+
+ /* always update these fields */
+ att->TextureLevel = level;
+ if (IS_CUBE_FACE(texTarget)) {
+ att->CubeMapFace = texTarget - GL_TEXTURE_CUBE_MAP_POSITIVE_X;
+ }
+ else {
+ att->CubeMapFace = 0;
+ }
+ att->Zoffset = zoffset;
+ att->Complete = GL_FALSE;
+
+ if (att->Texture->Image[att->CubeMapFace][att->TextureLevel]) {
+ ctx->Driver.RenderTexture(ctx, fb, att);
+ }
+}
+
+
+/**
+ * Bind a renderbuffer to an attachment point.
+ * The previous binding, if any, will be removed first.
+ */
+void
+_mesa_set_renderbuffer_attachment(GLcontext *ctx,
+ struct gl_renderbuffer_attachment *att,
+ struct gl_renderbuffer *rb)
+{
+ /* XXX check if re-doing same attachment, exit early */
+ _mesa_remove_attachment(ctx, att);
+ att->Type = GL_RENDERBUFFER_EXT;
+ att->Renderbuffer = rb;
+ att->Texture = NULL; /* just to be safe */
+ att->Complete = GL_FALSE;
+ rb->RefCount++;
+}
+
+
+/**
+ * Fallback for ctx->Driver.FramebufferRenderbuffer()
+ * Attach a renderbuffer object to a framebuffer object.
+ */
+void
+_mesa_framebuffer_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
+ GLenum attachment, struct gl_renderbuffer *rb)
+{
+ struct gl_renderbuffer_attachment *att;
+
+ _glthread_LOCK_MUTEX(fb->Mutex);
+ if (rb)
+ _glthread_LOCK_MUTEX(rb->Mutex);
+
+ att = _mesa_get_attachment(ctx, fb, attachment);
+ ASSERT(att);
+
+ if (rb) {
+ _mesa_set_renderbuffer_attachment(ctx, att, rb);
+ }
+ else {
+ _mesa_remove_attachment(ctx, att);
+ }
+
+ if (rb)
+ _glthread_UNLOCK_MUTEX(rb->Mutex);
+ _glthread_UNLOCK_MUTEX(fb->Mutex);
+}
+
+
+/**
+ * Test if an attachment point is complete and update its Complete field.
+ * \param format if GL_COLOR, this is a color attachment point,
+ * if GL_DEPTH, this is a depth component attachment point,
+ * if GL_STENCIL, this is a stencil component attachment point.
+ */
+static void
+test_attachment_completeness(const GLcontext *ctx, GLenum format,
+ struct gl_renderbuffer_attachment *att)
+{
+ assert(format == GL_COLOR || format == GL_DEPTH || format == GL_STENCIL);
+
+ /* assume complete */
+ att->Complete = GL_TRUE;
+
+ /* Look for reasons why the attachment might be incomplete */
+ if (att->Type == GL_TEXTURE) {
+ const struct gl_texture_object *texObj = att->Texture;
+ struct gl_texture_image *texImage;
+
+ if (!texObj) {
+ att->Complete = GL_FALSE;
+ return;
+ }
+
+ texImage = texObj->Image[att->CubeMapFace][att->TextureLevel];
+ if (!texImage) {
+ att->Complete = GL_FALSE;
+ return;
+ }
+ if (texImage->Width < 1 || texImage->Height < 1) {
+ att->Complete = GL_FALSE;
+ return;
+ }
+ if (texObj->Target == GL_TEXTURE_3D && att->Zoffset >= texImage->Depth) {
+ att->Complete = GL_FALSE;
+ return;
+ }
+
+ if (format == GL_COLOR) {
+ if (texImage->TexFormat->BaseFormat != GL_RGB &&
+ texImage->TexFormat->BaseFormat != GL_RGBA) {
+ att->Complete = GL_FALSE;
+ return;
+ }
+ }
+ else if (format == GL_DEPTH) {
+ if (texImage->TexFormat->BaseFormat == GL_DEPTH_COMPONENT) {
+ /* OK */
+ }
+ else if (ctx->Extensions.EXT_packed_depth_stencil &&
+ att->Renderbuffer->_BaseFormat == GL_DEPTH_STENCIL_EXT) {
+ /* OK */
+ }
+ else {
+ att->Complete = GL_FALSE;
+ return;
+ }
+ }
+ else {
+ /* no such thing as stencil textures */
+ att->Complete = GL_FALSE;
+ return;
+ }
+ }
+ else if (att->Type == GL_RENDERBUFFER_EXT) {
+ ASSERT(att->Renderbuffer);
+ if (!att->Renderbuffer->InternalFormat ||
+ att->Renderbuffer->Width < 1 ||
+ att->Renderbuffer->Height < 1) {
+ att->Complete = GL_FALSE;
+ return;
+ }
+ if (format == GL_COLOR) {
+ if (att->Renderbuffer->_BaseFormat != GL_RGB &&
+ att->Renderbuffer->_BaseFormat != GL_RGBA) {
+ ASSERT(att->Renderbuffer->RedBits);
+ ASSERT(att->Renderbuffer->GreenBits);
+ ASSERT(att->Renderbuffer->BlueBits);
+ att->Complete = GL_FALSE;
+ return;
+ }
+ }
+ else if (format == GL_DEPTH) {
+ ASSERT(att->Renderbuffer->DepthBits);
+ if (att->Renderbuffer->_BaseFormat == GL_DEPTH_COMPONENT) {
+ /* OK */
+ }
+ else if (ctx->Extensions.EXT_packed_depth_stencil &&
+ att->Renderbuffer->_BaseFormat == GL_DEPTH_STENCIL_EXT) {
+ /* OK */
+ }
+ else {
+ att->Complete = GL_FALSE;
+ return;
+ }
+ }
+ else {
+ assert(format == GL_STENCIL);
+ ASSERT(att->Renderbuffer->StencilBits);
+ if (att->Renderbuffer->_BaseFormat == GL_STENCIL_INDEX) {
+ /* OK */
+ }
+ else if (ctx->Extensions.EXT_packed_depth_stencil &&
+ att->Renderbuffer->_BaseFormat == GL_DEPTH_STENCIL_EXT) {
+ /* OK */
+ }
+ else {
+ att->Complete = GL_FALSE;
+ return;
+ }
+ }
+ }
+ else {
+ ASSERT(att->Type == GL_NONE);
+ /* complete */
+ return;
+ }
+}
+
+
+/**
+ * Helpful for debugging
+ */
+static void
+fbo_incomplete(const char *msg, int index)
+{
+ /*
+ _mesa_debug(NULL, "FBO Incomplete: %s [%d]\n", msg, index);
+ */
+}
+
+
+/**
+ * Test if the given framebuffer object is complete and update its
+ * Status field with the results.
+ * Also update the framebuffer's Width and Height fields if the
+ * framebuffer is complete.
+ */
+void
+_mesa_test_framebuffer_completeness(GLcontext *ctx, struct gl_framebuffer *fb)
+{
+ GLuint numImages, width = 0, height = 0;
+ GLenum intFormat = GL_NONE;
+ GLuint w = 0, h = 0;
+ GLint i;
+
+ assert(fb->Name != 0);
+
+ numImages = 0;
+ fb->Width = 0;
+ fb->Height = 0;
+
+ /* Start at -2 to more easily loop over all attachment points */
+ for (i = -2; i < (GLint) ctx->Const.MaxColorAttachments; i++) {
+ struct gl_renderbuffer_attachment *att;
+ GLenum f;
+
+ if (i == -2) {
+ att = &fb->Attachment[BUFFER_DEPTH];
+ test_attachment_completeness(ctx, GL_DEPTH, att);
+ if (!att->Complete) {
+ fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT;
+ fbo_incomplete("depth attachment incomplete", -1);
+ return;
+ }
+ }
+ else if (i == -1) {
+ att = &fb->Attachment[BUFFER_STENCIL];
+ test_attachment_completeness(ctx, GL_STENCIL, att);
+ if (!att->Complete) {
+ fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT;
+ fbo_incomplete("stencil attachment incomplete", -1);
+ return;
+ }
+ }
+ else {
+ att = &fb->Attachment[BUFFER_COLOR0 + i];
+ test_attachment_completeness(ctx, GL_COLOR, att);
+ if (!att->Complete) {
+ fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT;
+ fbo_incomplete("color attachment incomplete", i);
+ return;
+ }
+ }
+
+ if (att->Type == GL_TEXTURE) {
+ const struct gl_texture_image *texImg
+ = att->Texture->Image[att->CubeMapFace][att->TextureLevel];
+ w = texImg->Width;
+ h = texImg->Height;
+ f = texImg->_BaseFormat;
+ numImages++;
+ if (f != GL_RGB && f != GL_RGBA && f != GL_DEPTH_COMPONENT
+ && f != GL_DEPTH_STENCIL_EXT) {
+ fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT;
+ fbo_incomplete("texture attachment incomplete", -1);
+ return;
+ }
+ }
+ else if (att->Type == GL_RENDERBUFFER_EXT) {
+ w = att->Renderbuffer->Width;
+ h = att->Renderbuffer->Height;
+ f = att->Renderbuffer->InternalFormat;
+ numImages++;
+ }
+ else {
+ assert(att->Type == GL_NONE);
+ continue;
+ }
+
+ if (numImages == 1) {
+ /* set required width, height and format */
+ width = w;
+ height = h;
+ if (i >= 0)
+ intFormat = f;
+ }
+ else {
+ /* check that width, height, format are same */
+ if (w != width || h != height) {
+ fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT;
+ fbo_incomplete("width or height mismatch", -1);
+ return;
+ }
+ if (intFormat != GL_NONE && f != intFormat) {
+ fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT;
+ fbo_incomplete("format mismatch", -1);
+ return;
+ }
+ }
+ }
+
+ /* Check that all DrawBuffers are present */
+ for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
+ if (fb->ColorDrawBuffer[i] != GL_NONE) {
+ const struct gl_renderbuffer_attachment *att
+ = _mesa_get_attachment(ctx, fb, fb->ColorDrawBuffer[i]);
+ assert(att);
+ if (att->Type == GL_NONE) {
+ fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT;
+ fbo_incomplete("missing drawbuffer", i);
+ return;
+ }
+ }
+ }
+
+ /* Check that the ReadBuffer is present */
+ if (fb->ColorReadBuffer != GL_NONE) {
+ const struct gl_renderbuffer_attachment *att
+ = _mesa_get_attachment(ctx, fb, fb->ColorReadBuffer);
+ assert(att);
+ if (att->Type == GL_NONE) {
+ fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT;
+ fbo_incomplete("missing readbuffer", -1);
+ return;
+ }
+ }
+
+ /* Check if any renderbuffer is attached more than once.
+ * Note that there's one exception: a GL_DEPTH_STENCIL renderbuffer can be
+ * bound to both the stencil and depth attachment points at the same time.
+ */
+ for (i = 0; i < BUFFER_COUNT - 1; i++) {
+ struct gl_renderbuffer *rb_i = fb->Attachment[i].Renderbuffer;
+ if (rb_i) {
+ GLint j;
+ for (j = i + 1; j < BUFFER_COUNT; j++) {
+ struct gl_renderbuffer *rb_j = fb->Attachment[j].Renderbuffer;
+ if (rb_i == rb_j && rb_i->_BaseFormat != GL_DEPTH_STENCIL_EXT) {
+ fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT;
+ fbo_incomplete("multiply bound renderbuffer", -1);
+ return;
+ }
+ }
+ }
+ }
+
+
+ if (numImages == 0) {
+ fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT;
+ fbo_incomplete("no attachments", -1);
+ return;
+ }
+
+ /*
+ * If we get here, the framebuffer is complete!
+ */
+ fb->_Status = GL_FRAMEBUFFER_COMPLETE_EXT;
+ fb->Width = w;
+ fb->Height = h;
+}
+
+
+GLboolean GLAPIENTRY
+_mesa_IsRenderbufferEXT(GLuint renderbuffer)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
+ if (renderbuffer) {
+ struct gl_renderbuffer *rb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
+ if (rb != NULL && rb != &DummyRenderbuffer)
+ return GL_TRUE;
+ }
+ return GL_FALSE;
+}
+
+
+void GLAPIENTRY
+_mesa_BindRenderbufferEXT(GLenum target, GLuint renderbuffer)
+{
+ struct gl_renderbuffer *newRb, *oldRb;
+ GET_CURRENT_CONTEXT(ctx);
+
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (target != GL_RENDERBUFFER_EXT) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glBindRenderbufferEXT(target)");
+ return;
+ }
+
+ FLUSH_VERTICES(ctx, _NEW_BUFFERS);
+
+ if (renderbuffer) {
+ newRb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
+ if (newRb == &DummyRenderbuffer) {
+ /* ID was reserved, but no real renderbuffer object made yet */
+ newRb = NULL;
+ }
+ if (!newRb) {
+ /* create new renderbuffer object */
+ newRb = ctx->Driver.NewRenderbuffer(ctx, renderbuffer);
+ if (!newRb) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindRenderbufferEXT");
+ return;
+ }
+ ASSERT(newRb->AllocStorage);
+ _mesa_HashInsert(ctx->Shared->RenderBuffers, renderbuffer, newRb);
+ }
+ newRb->RefCount++;
+ }
+ else {
+ newRb = NULL;
+ }
+
+ oldRb = ctx->CurrentRenderbuffer;
+ if (oldRb) {
+ oldRb->RefCount--;
+ if (oldRb->RefCount == 0) {
+ oldRb->Delete(oldRb);
+ }
+ }
+
+ ASSERT(newRb != &DummyRenderbuffer);
+
+ ctx->CurrentRenderbuffer = newRb;
+}
+
+
+void GLAPIENTRY
+_mesa_DeleteRenderbuffersEXT(GLsizei n, const GLuint *renderbuffers)
+{
+ GLint i;
+ GET_CURRENT_CONTEXT(ctx);
+
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+ FLUSH_VERTICES(ctx, _NEW_BUFFERS);
+
+ for (i = 0; i < n; i++) {
+ if (renderbuffers[i] > 0) {
+ struct gl_renderbuffer *rb;
+ rb = _mesa_lookup_renderbuffer(ctx, renderbuffers[i]);
+ if (rb) {
+ /* check if deleting currently bound renderbuffer object */
+ if (rb == ctx->CurrentRenderbuffer) {
+ /* bind default */
+ ASSERT(rb->RefCount >= 2);
+ _mesa_BindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
+ }
+
+ /* remove from hash table immediately, to free the ID */
+ _mesa_HashRemove(ctx->Shared->RenderBuffers, renderbuffers[i]);
+
+ if (rb != &DummyRenderbuffer) {
+ /* But the object will not be freed until it's no longer
+ * bound in any context.
+ */
+ rb->RefCount--;
+ if (rb->RefCount == 0) {
+ rb->Delete(rb);
+ }
+ }
+ }
+ }
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_GenRenderbuffersEXT(GLsizei n, GLuint *renderbuffers)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLuint first;
+ GLint i;
+
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (n < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glGenRenderbuffersEXT(n)");
+ return;
+ }
+
+ if (!renderbuffers)
+ return;
+
+ first = _mesa_HashFindFreeKeyBlock(ctx->Shared->RenderBuffers, n);
+
+ for (i = 0; i < n; i++) {
+ GLuint name = first + i;
+ renderbuffers[i] = name;
+ /* insert dummy placeholder into hash table */
+ _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
+ _mesa_HashInsert(ctx->Shared->RenderBuffers, name, &DummyRenderbuffer);
+ _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+ }
+}
+
+
+/**
+ * Given an internal format token for a render buffer, return the
+ * corresponding base format.
+ * This is very similar to _mesa_base_tex_format() but the set of valid
+ * internal formats is somewhat different.
+ *
+ * \return one of GL_RGB, GL_RGBA, GL_STENCIL_INDEX, GL_DEPTH_COMPONENT
+ * GL_DEPTH_STENCIL_EXT or zero if error.
+ */
+GLenum
+_mesa_base_fbo_format(GLcontext *ctx, GLenum internalFormat)
+{
+ switch (internalFormat) {
+ case GL_RGB:
+ case GL_R3_G3_B2:
+ case GL_RGB4:
+ case GL_RGB5:
+ case GL_RGB8:
+ case GL_RGB10:
+ case GL_RGB12:
+ case GL_RGB16:
+ return GL_RGB;
+ case GL_RGBA:
+ case GL_RGBA2:
+ case GL_RGBA4:
+ case GL_RGB5_A1:
+ case GL_RGBA8:
+ case GL_RGB10_A2:
+ case GL_RGBA12:
+ case GL_RGBA16:
+ return GL_RGBA;
+ case GL_STENCIL_INDEX:
+ case GL_STENCIL_INDEX1_EXT:
+ case GL_STENCIL_INDEX4_EXT:
+ case GL_STENCIL_INDEX8_EXT:
+ case GL_STENCIL_INDEX16_EXT:
+ return GL_STENCIL_INDEX;
+ case GL_DEPTH_COMPONENT:
+ case GL_DEPTH_COMPONENT16:
+ case GL_DEPTH_COMPONENT24:
+ case GL_DEPTH_COMPONENT32:
+ return GL_DEPTH_COMPONENT;
+ case GL_DEPTH_STENCIL_EXT:
+ case GL_DEPTH24_STENCIL8_EXT:
+ if (ctx->Extensions.EXT_packed_depth_stencil)
+ return GL_DEPTH_STENCIL_EXT;
+ else
+ return 0;
+ /* XXX add floating point formats eventually */
+ default:
+ return 0;
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_RenderbufferStorageEXT(GLenum target, GLenum internalFormat,
+ GLsizei width, GLsizei height)
+{
+ struct gl_renderbuffer *rb;
+ GLenum baseFormat;
+ GET_CURRENT_CONTEXT(ctx);
+
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (target != GL_RENDERBUFFER_EXT) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glRenderbufferStorageEXT(target)");
+ return;
+ }
+
+ baseFormat = _mesa_base_fbo_format(ctx, internalFormat);
+ if (baseFormat == 0) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glRenderbufferStorageEXT(internalFormat)");
+ return;
+ }
+
+ if (width < 1 || width > ctx->Const.MaxRenderbufferSize) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glRenderbufferStorageEXT(width)");
+ return;
+ }
+
+ if (height < 1 || height > ctx->Const.MaxRenderbufferSize) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glRenderbufferStorageEXT(height)");
+ return;
+ }
+
+ rb = ctx->CurrentRenderbuffer;
+
+ if (!rb) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glRenderbufferStorageEXT");
+ return;
+ }
+
+ FLUSH_VERTICES(ctx, _NEW_BUFFERS);
+
+ if (rb->InternalFormat == internalFormat &&
+ rb->Width == width &&
+ rb->Height == height) {
+ /* no change in allocation needed */
+ return;
+ }
+
+ /* These MUST get set by the AllocStorage func */
+ rb->_ActualFormat = 0;
+ rb->RedBits =
+ rb->GreenBits =
+ rb->BlueBits =
+ rb->AlphaBits =
+ rb->IndexBits =
+ rb->DepthBits =
+ rb->StencilBits = 0;
+
+ /* Now allocate the storage */
+ ASSERT(rb->AllocStorage);
+ if (rb->AllocStorage(ctx, rb, internalFormat, width, height)) {
+ /* No error - check/set fields now */
+ assert(rb->_ActualFormat);
+ assert(rb->Width == width);
+ assert(rb->Height == height);
+ assert(rb->RedBits || rb->GreenBits || rb->BlueBits || rb->AlphaBits ||
+ rb->DepthBits || rb->StencilBits || rb->IndexBits);
+ rb->InternalFormat = internalFormat;
+ rb->_BaseFormat = baseFormat;
+ }
+ else {
+ /* Probably ran out of memory - clear the fields */
+ rb->Width = 0;
+ rb->Height = 0;
+ rb->InternalFormat = GL_NONE;
+ rb->_ActualFormat = GL_NONE;
+ rb->_BaseFormat = GL_NONE;
+ rb->RedBits =
+ rb->GreenBits =
+ rb->BlueBits =
+ rb->AlphaBits =
+ rb->IndexBits =
+ rb->DepthBits =
+ rb->StencilBits = 0;
+ }
+
+ /*
+ test_framebuffer_completeness(ctx, fb);
+ */
+ /* XXX if this renderbuffer is attached anywhere, invalidate attachment
+ * points???
+ */
+}
+
+
+void GLAPIENTRY
+_mesa_GetRenderbufferParameterivEXT(GLenum target, GLenum pname, GLint *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (target != GL_RENDERBUFFER_EXT) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetRenderbufferParameterivEXT(target)");
+ return;
+ }
+
+ if (!ctx->CurrentRenderbuffer) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetRenderbufferParameterivEXT");
+ return;
+ }
+
+ FLUSH_VERTICES(ctx, _NEW_BUFFERS);
+
+ switch (pname) {
+ case GL_RENDERBUFFER_WIDTH_EXT:
+ *params = ctx->CurrentRenderbuffer->Width;
+ return;
+ case GL_RENDERBUFFER_HEIGHT_EXT:
+ *params = ctx->CurrentRenderbuffer->Height;
+ return;
+ case GL_RENDERBUFFER_INTERNAL_FORMAT_EXT:
+ *params = ctx->CurrentRenderbuffer->InternalFormat;
+ return;
+ case GL_RENDERBUFFER_RED_SIZE_EXT:
+ *params = ctx->CurrentRenderbuffer->RedBits;
+ break;
+ case GL_RENDERBUFFER_GREEN_SIZE_EXT:
+ *params = ctx->CurrentRenderbuffer->GreenBits;
+ break;
+ case GL_RENDERBUFFER_BLUE_SIZE_EXT:
+ *params = ctx->CurrentRenderbuffer->BlueBits;
+ break;
+ case GL_RENDERBUFFER_ALPHA_SIZE_EXT:
+ *params = ctx->CurrentRenderbuffer->AlphaBits;
+ break;
+ case GL_RENDERBUFFER_DEPTH_SIZE_EXT:
+ *params = ctx->CurrentRenderbuffer->DepthBits;
+ break;
+ case GL_RENDERBUFFER_STENCIL_SIZE_EXT:
+ *params = ctx->CurrentRenderbuffer->StencilBits;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetRenderbufferParameterivEXT(target)");
+ return;
+ }
+}
+
+
+GLboolean GLAPIENTRY
+_mesa_IsFramebufferEXT(GLuint framebuffer)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
+ if (framebuffer) {
+ struct gl_framebuffer *rb = _mesa_lookup_framebuffer(ctx, framebuffer);
+ if (rb != NULL && rb != &DummyFramebuffer)
+ return GL_TRUE;
+ }
+ return GL_FALSE;
+}
+
+
+static void
+check_begin_texture_render(GLcontext *ctx, struct gl_framebuffer *fb)
+{
+ GLuint i;
+ ASSERT(ctx->Driver.RenderTexture);
+ for (i = 0; i < BUFFER_COUNT; i++) {
+ struct gl_renderbuffer_attachment *att = fb->Attachment + i;
+ struct gl_texture_object *texObj = att->Texture;
+ if (texObj
+ && att->Texture->Image[att->CubeMapFace][att->TextureLevel]) {
+ ctx->Driver.RenderTexture(ctx, fb, att);
+ }
+ }
+}
+
+
+/**
+ * Examine all the framebuffer's attachments to see if any are textures.
+ * If so, call ctx->Driver.FinishRenderTexture() for each texture to
+ * notify the device driver that the texture image may have changed.
+ */
+static void
+check_end_texture_render(GLcontext *ctx, struct gl_framebuffer *fb)
+{
+ if (ctx->Driver.FinishRenderTexture) {
+ GLuint i;
+ for (i = 0; i < BUFFER_COUNT; i++) {
+ struct gl_renderbuffer_attachment *att = fb->Attachment + i;
+ struct gl_texture_object *texObj = att->Texture;
+ if (texObj) {
+ ctx->Driver.FinishRenderTexture(ctx, att);
+ }
+ }
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer)
+{
+ struct gl_framebuffer *newFb, *oldFb;
+ GLboolean bindReadBuf, bindDrawBuf;
+ GET_CURRENT_CONTEXT(ctx);
+
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (!ctx->Extensions.EXT_framebuffer_object) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glBindFramebufferEXT(unsupported)");
+ return;
+ }
+
+ switch (target) {
+#if FEATURE_EXT_framebuffer_blit
+ case GL_DRAW_FRAMEBUFFER_EXT:
+ if (!ctx->Extensions.EXT_framebuffer_blit) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glBindFramebufferEXT(target)");
+ return;
+ }
+ bindDrawBuf = GL_TRUE;
+ bindReadBuf = GL_FALSE;
+ break;
+ case GL_READ_FRAMEBUFFER_EXT:
+ if (!ctx->Extensions.EXT_framebuffer_blit) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glBindFramebufferEXT(target)");
+ return;
+ }
+ bindDrawBuf = GL_FALSE;
+ bindReadBuf = GL_TRUE;
+ break;
+#endif
+ case GL_FRAMEBUFFER_EXT:
+ bindDrawBuf = GL_TRUE;
+ bindReadBuf = GL_TRUE;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glBindFramebufferEXT(target)");
+ return;
+ }
+
+ FLUSH_VERTICES(ctx, _NEW_BUFFERS);
+
+ if (framebuffer) {
+ /* Binding a user-created framebuffer object */
+ newFb = _mesa_lookup_framebuffer(ctx, framebuffer);
+ if (newFb == &DummyFramebuffer) {
+ /* ID was reserved, but no real framebuffer object made yet */
+ newFb = NULL;
+ }
+ if (!newFb) {
+ /* create new framebuffer object */
+ newFb = ctx->Driver.NewFramebuffer(ctx, framebuffer);
+ if (!newFb) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindFramebufferEXT");
+ return;
+ }
+ _mesa_HashInsert(ctx->Shared->FrameBuffers, framebuffer, newFb);
+ }
+ _glthread_LOCK_MUTEX(newFb->Mutex);
+ if (bindReadBuf)
+ newFb->RefCount++;
+ if (bindDrawBuf)
+ newFb->RefCount++;
+ _glthread_UNLOCK_MUTEX(newFb->Mutex);
+ }
+ else {
+ /* Binding the window system framebuffer (which was originally set
+ * with MakeCurrent).
+ */
+ newFb = ctx->WinSysDrawBuffer;
+ }
+
+ ASSERT(newFb);
+ ASSERT(newFb != &DummyFramebuffer);
+
+ /*
+ * XXX check if re-binding same buffer and skip some of this code.
+ */
+
+ if (bindReadBuf) {
+ oldFb = ctx->ReadBuffer;
+ if (oldFb && oldFb->Name != 0) {
+ _glthread_LOCK_MUTEX(oldFb->Mutex);
+ oldFb->RefCount--;
+ _glthread_UNLOCK_MUTEX(oldFb->Mutex);
+ if (oldFb->RefCount == 0) {
+ oldFb->Delete(oldFb);
+ }
+ }
+ ctx->ReadBuffer = newFb;
+ }
+
+ if (bindDrawBuf) {
+ oldFb = ctx->DrawBuffer;
+ if (oldFb && oldFb->Name != 0) {
+ /* check if old FB had any texture attachments */
+ check_end_texture_render(ctx, oldFb);
+ /* check if time to delete this framebuffer */
+ _glthread_LOCK_MUTEX(oldFb->Mutex);
+ oldFb->RefCount--;
+ if (oldFb->RefCount == 0) {
+ oldFb->Delete(oldFb);
+ }
+ _glthread_UNLOCK_MUTEX(oldFb->Mutex);
+ }
+ ctx->DrawBuffer = newFb;
+ if (newFb->Name != 0) {
+ /* check if newly bound framebuffer has any texture attachments */
+ check_begin_texture_render(ctx, newFb);
+ }
+ }
+
+ if (ctx->Driver.BindFramebuffer) {
+ ctx->Driver.BindFramebuffer(ctx, target, newFb);
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_DeleteFramebuffersEXT(GLsizei n, const GLuint *framebuffers)
+{
+ GLint i;
+ GET_CURRENT_CONTEXT(ctx);
+
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+ FLUSH_VERTICES(ctx, _NEW_BUFFERS);
+
+ for (i = 0; i < n; i++) {
+ if (framebuffers[i] > 0) {
+ struct gl_framebuffer *fb;
+ fb = _mesa_lookup_framebuffer(ctx, framebuffers[i]);
+ if (fb) {
+ ASSERT(fb == &DummyFramebuffer || fb->Name == framebuffers[i]);
+
+ /* check if deleting currently bound framebuffer object */
+ if (fb == ctx->DrawBuffer) {
+ /* bind default */
+ ASSERT(fb->RefCount >= 2);
+ _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+ }
+
+ /* remove from hash table immediately, to free the ID */
+ _mesa_HashRemove(ctx->Shared->FrameBuffers, framebuffers[i]);
+
+ if (fb != &DummyFramebuffer) {
+ /* But the object will not be freed until it's no longer
+ * bound in any context.
+ */
+ _glthread_LOCK_MUTEX(fb->Mutex);
+ fb->RefCount--;
+ _glthread_UNLOCK_MUTEX(fb->Mutex);
+ if (fb->RefCount == 0) {
+ fb->Delete(fb);
+ }
+ }
+ }
+ }
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_GenFramebuffersEXT(GLsizei n, GLuint *framebuffers)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLuint first;
+ GLint i;
+
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (n < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glGenFramebuffersEXT(n)");
+ return;
+ }
+
+ if (!framebuffers)
+ return;
+
+ first = _mesa_HashFindFreeKeyBlock(ctx->Shared->FrameBuffers, n);
+
+ for (i = 0; i < n; i++) {
+ GLuint name = first + i;
+ framebuffers[i] = name;
+ /* insert dummy placeholder into hash table */
+ _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
+ _mesa_HashInsert(ctx->Shared->FrameBuffers, name, &DummyFramebuffer);
+ _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+ }
+}
+
+
+
+GLenum GLAPIENTRY
+_mesa_CheckFramebufferStatusEXT(GLenum target)
+{
+ struct gl_framebuffer *buffer;
+ GET_CURRENT_CONTEXT(ctx);
+
+ ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0);
+
+ switch (target) {
+#if FEATURE_EXT_framebuffer_blit
+ case GL_DRAW_FRAMEBUFFER_EXT:
+ if (!ctx->Extensions.EXT_framebuffer_blit) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glCheckFramebufferStatus(target)");
+ return 0;
+ }
+ buffer = ctx->DrawBuffer;
+ break;
+ case GL_READ_FRAMEBUFFER_EXT:
+ if (!ctx->Extensions.EXT_framebuffer_blit) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glCheckFramebufferStatus(target)");
+ return 0;
+ }
+ buffer = ctx->ReadBuffer;
+ break;
+#endif
+ case GL_FRAMEBUFFER_EXT:
+ buffer = ctx->DrawBuffer;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glCheckFramebufferStatus(target)");
+ return 0; /* formerly GL_FRAMEBUFFER_STATUS_ERROR_EXT */
+ }
+
+ if (buffer->Name == 0) {
+ /* The window system / default framebuffer is always complete */
+ return GL_FRAMEBUFFER_COMPLETE_EXT;
+ }
+
+ FLUSH_VERTICES(ctx, _NEW_BUFFERS);
+
+ _mesa_test_framebuffer_completeness(ctx, buffer);
+ return buffer->_Status;
+}
+
+
+
+/**
+ * Common code called by glFramebufferTexture1D/2D/3DEXT().
+ */
+static void
+framebuffer_texture(GLuint dims, GLenum target, GLenum attachment,
+ GLenum textarget, GLuint texture,
+ GLint level, GLint zoffset)
+{
+ struct gl_renderbuffer_attachment *att;
+ struct gl_texture_object *texObj = NULL;
+ struct gl_framebuffer *fb;
+ GET_CURRENT_CONTEXT(ctx);
+
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (target != GL_FRAMEBUFFER_EXT) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glFramebufferTexture%dDEXT(target)", dims);
+ return;
+ }
+
+ fb = ctx->DrawBuffer;
+ ASSERT(fb);
+
+ /* check framebuffer binding */
+ if (fb->Name == 0) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glFramebufferTexture%dDEXT", dims);
+ return;
+ }
+
+ if (texture) {
+ texObj = _mesa_lookup_texture(ctx, texture);
+ }
+
+ /* Check dimension-dependent things */
+ switch (dims) {
+ case 1:
+ if (textarget != GL_TEXTURE_1D) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glFramebufferTexture1DEXT(textarget)");
+ return;
+ }
+ if (texObj && texObj->Target != GL_TEXTURE_1D) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glFramebufferTexture1DEXT(texture target mismatch)");
+ return;
+ }
+ break;
+ case 2:
+ if (textarget != GL_TEXTURE_2D &&
+ textarget != GL_TEXTURE_RECTANGLE_ARB &&
+ !IS_CUBE_FACE(textarget)) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glFramebufferTexture2DEXT(textarget)");
+ return;
+ }
+ if (texObj) {
+ if ((texObj->Target == GL_TEXTURE_2D && textarget != GL_TEXTURE_2D) ||
+ (texObj->Target == GL_TEXTURE_RECTANGLE_ARB
+ && textarget != GL_TEXTURE_RECTANGLE_ARB) ||
+ (texObj->Target == GL_TEXTURE_CUBE_MAP
+ && !IS_CUBE_FACE(textarget))) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glFramebufferTexture1DEXT(texture target mismatch)");
+ return;
+ }
+ }
+ break;
+ case 3:
+ if (textarget != GL_TEXTURE_3D) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glFramebufferTexture3DEXT(textarget)");
+ return;
+ }
+ if (texObj && texObj->Target != GL_TEXTURE_3D) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glFramebufferTexture3DEXT(texture target mismatch)");
+ return;
+ }
+ {
+ const GLint maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1);
+ if (zoffset < 0 || zoffset >= maxSize) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glFramebufferTexture3DEXT(zoffset)");
+ return;
+ }
+ }
+ break;
+ default:
+ _mesa_problem(ctx, "Unexpected dims in error_check_framebuffer_texture");
+ return;
+ }
+
+ if ((level < 0) || level >= _mesa_max_texture_levels(ctx, textarget)) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glFramebufferTexture%dDEXT(level)", dims);
+ return;
+ }
+
+ att = _mesa_get_attachment(ctx, fb, attachment);
+ if (att == NULL) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glFramebufferTexture%dDEXT(attachment)", dims);
+ return;
+ }
+
+ FLUSH_VERTICES(ctx, _NEW_BUFFERS);
+
+ _glthread_LOCK_MUTEX(fb->Mutex);
+ if (texObj) {
+ _mesa_set_texture_attachment(ctx, fb, att, texObj, textarget,
+ level, zoffset);
+ }
+ else {
+ _mesa_remove_attachment(ctx, att);
+ }
+ _glthread_UNLOCK_MUTEX(fb->Mutex);
+}
+
+
+
+void GLAPIENTRY
+_mesa_FramebufferTexture1DEXT(GLenum target, GLenum attachment,
+ GLenum textarget, GLuint texture, GLint level)
+{
+ const GLint zoffset = 0;
+ framebuffer_texture(1, target, attachment, textarget, texture,
+ level, zoffset);
+}
+
+
+void GLAPIENTRY
+_mesa_FramebufferTexture2DEXT(GLenum target, GLenum attachment,
+ GLenum textarget, GLuint texture, GLint level)
+{
+ const GLint zoffset = 0;
+ framebuffer_texture(2, target, attachment, textarget, texture,
+ level, zoffset);
+}
+
+
+void GLAPIENTRY
+_mesa_FramebufferTexture3DEXT(GLenum target, GLenum attachment,
+ GLenum textarget, GLuint texture,
+ GLint level, GLint zoffset)
+{
+ framebuffer_texture(3, target, attachment, textarget, texture,
+ level, zoffset);
+}
+
+
+
+void GLAPIENTRY
+_mesa_FramebufferRenderbufferEXT(GLenum target, GLenum attachment,
+ GLenum renderbufferTarget,
+ GLuint renderbuffer)
+{
+ struct gl_renderbuffer_attachment *att;
+ struct gl_framebuffer *fb;
+ struct gl_renderbuffer *rb;
+ GET_CURRENT_CONTEXT(ctx);
+
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ switch (target) {
+#if FEATURE_EXT_framebuffer_blit
+ case GL_DRAW_FRAMEBUFFER_EXT:
+ if (!ctx->Extensions.EXT_framebuffer_blit) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glFramebufferRenderbufferEXT(target)");
+ return;
+ }
+ fb = ctx->DrawBuffer;
+ break;
+ case GL_READ_FRAMEBUFFER_EXT:
+ if (!ctx->Extensions.EXT_framebuffer_blit) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glFramebufferRenderbufferEXT(target)");
+ return;
+ }
+ fb = ctx->ReadBuffer;
+ break;
+#endif
+ case GL_FRAMEBUFFER_EXT:
+ fb = ctx->DrawBuffer;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glFramebufferRenderbufferEXT(target)");
+ return;
+ }
+
+ if (renderbufferTarget != GL_RENDERBUFFER_EXT) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glFramebufferRenderbufferEXT(renderbufferTarget)");
+ return;
+ }
+
+ if (fb->Name == 0) {
+ /* Can't attach new renderbuffers to a window system framebuffer */
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glFramebufferRenderbufferEXT");
+ return;
+ }
+
+ att = _mesa_get_attachment(ctx, fb, attachment);
+ if (att == NULL) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glFramebufferRenderbufferEXT(attachment)");
+ return;
+ }
+
+ if (renderbuffer) {
+ rb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
+ if (!rb) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glFramebufferRenderbufferEXT(renderbuffer)");
+ return;
+ }
+ }
+ else {
+ /* remove renderbuffer attachment */
+ rb = NULL;
+ }
+
+ FLUSH_VERTICES(ctx, _NEW_BUFFERS);
+
+ assert(ctx->Driver.FramebufferRenderbuffer);
+ ctx->Driver.FramebufferRenderbuffer(ctx, fb, attachment, rb);
+
+ /* Some subsequent GL commands may depend on the framebuffer's visual
+ * after the binding is updated. Update visual info now.
+ */
+ _mesa_update_framebuffer_visual(fb);
+}
+
+
+void GLAPIENTRY
+_mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
+ GLenum pname, GLint *params)
+{
+ const struct gl_renderbuffer_attachment *att;
+ struct gl_framebuffer *buffer;
+ GET_CURRENT_CONTEXT(ctx);
+
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ switch (target) {
+#if FEATURE_EXT_framebuffer_blit
+ case GL_DRAW_FRAMEBUFFER_EXT:
+ if (!ctx->Extensions.EXT_framebuffer_blit) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetFramebufferAttachmentParameterivEXT(target)");
+ return;
+ }
+ buffer = ctx->DrawBuffer;
+ break;
+ case GL_READ_FRAMEBUFFER_EXT:
+ if (!ctx->Extensions.EXT_framebuffer_blit) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetFramebufferAttachmentParameterivEXT(target)");
+ return;
+ }
+ buffer = ctx->ReadBuffer;
+ break;
+#endif
+ case GL_FRAMEBUFFER_EXT:
+ buffer = ctx->DrawBuffer;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetFramebufferAttachmentParameterivEXT(target)");
+ return;
+ }
+
+ if (buffer->Name == 0) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetFramebufferAttachmentParameterivEXT");
+ return;
+ }
+
+ att = _mesa_get_attachment(ctx, buffer, attachment);
+ if (att == NULL) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetFramebufferAttachmentParameterivEXT(attachment)");
+ return;
+ }
+
+ FLUSH_VERTICES(ctx, _NEW_BUFFERS);
+
+ switch (pname) {
+ case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT:
+ *params = att->Type;
+ return;
+ case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT:
+ if (att->Type == GL_RENDERBUFFER_EXT) {
+ *params = att->Renderbuffer->Name;
+ }
+ else if (att->Type == GL_TEXTURE) {
+ *params = att->Texture->Name;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetFramebufferAttachmentParameterivEXT(pname)");
+ }
+ return;
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT:
+ if (att->Type == GL_TEXTURE) {
+ *params = att->TextureLevel;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetFramebufferAttachmentParameterivEXT(pname)");
+ }
+ return;
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT:
+ if (att->Type == GL_TEXTURE) {
+ *params = GL_TEXTURE_CUBE_MAP_POSITIVE_X + att->CubeMapFace;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetFramebufferAttachmentParameterivEXT(pname)");
+ }
+ return;
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT:
+ if (att->Type == GL_TEXTURE) {
+ *params = att->Zoffset;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetFramebufferAttachmentParameterivEXT(pname)");
+ }
+ return;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetFramebufferAttachmentParameterivEXT(pname)");
+ return;
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_GenerateMipmapEXT(GLenum target)
+{
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_object *texObj;
+ GET_CURRENT_CONTEXT(ctx);
+
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+ FLUSH_VERTICES(ctx, _NEW_BUFFERS);
+
+ switch (target) {
+ case GL_TEXTURE_1D:
+ case GL_TEXTURE_2D:
+ case GL_TEXTURE_3D:
+ case GL_TEXTURE_CUBE_MAP:
+ /* OK, legal value */
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGenerateMipmapEXT(target)");
+ return;
+ }
+
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+
+ /* XXX this might not handle cube maps correctly */
+ _mesa_generate_mipmap(ctx, target, texUnit, texObj);
+}
+
+
+#if FEATURE_EXT_framebuffer_blit
+void GLAPIENTRY
+_mesa_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+ FLUSH_VERTICES(ctx, _NEW_BUFFERS);
+
+ if (ctx->NewState) {
+ _mesa_update_state(ctx);
+ }
+
+ if (!ctx->ReadBuffer) {
+ /* XXX */
+ }
+
+ /* check for complete framebuffers */
+ if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT ||
+ ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
+ "glBlitFramebufferEXT(incomplete draw/read buffers)");
+ return;
+ }
+
+ if (filter != GL_NEAREST && filter != GL_LINEAR) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glBlitFramebufferEXT(filter)");
+ return;
+ }
+
+ if (mask & ~(GL_COLOR_BUFFER_BIT |
+ GL_DEPTH_BUFFER_BIT |
+ GL_STENCIL_BUFFER_BIT)) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glBlitFramebufferEXT(mask)");
+ return;
+ }
+
+ /* depth/stencil must be blitted with nearest filtering */
+ if ((mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
+ && filter != GL_NEAREST) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glBlitFramebufferEXT(depth/stencil requires GL_NEAREST filter");
+ return;
+ }
+
+ if (mask & GL_STENCIL_BUFFER_BIT) {
+ struct gl_renderbuffer *readRb = ctx->ReadBuffer->_StencilBuffer;
+ struct gl_renderbuffer *drawRb = ctx->DrawBuffer->_StencilBuffer;
+ if (readRb->StencilBits != drawRb->StencilBits) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glBlitFramebufferEXT(stencil buffer size mismatch");
+ return;
+ }
+ }
+
+ if (mask & GL_DEPTH_BUFFER_BIT) {
+ struct gl_renderbuffer *readRb = ctx->ReadBuffer->_DepthBuffer;
+ struct gl_renderbuffer *drawRb = ctx->DrawBuffer->_DepthBuffer;
+ if (readRb->DepthBits != drawRb->DepthBits) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glBlitFramebufferEXT(depth buffer size mismatch");
+ return;
+ }
+ }
+
+ if (!ctx->Extensions.EXT_framebuffer_blit) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glBlitFramebufferEXT");
+ return;
+ }
+
+ ASSERT(ctx->Driver.BlitFramebuffer);
+ ctx->Driver.BlitFramebuffer(ctx,
+ srcX0, srcY0, srcX1, srcY1,
+ dstX0, dstY0, dstX1, dstY1,
+ mask, filter);
+}
+#endif /* FEATURE_EXT_framebuffer_blit */
diff --git a/src/mesa/main/fbobject.h b/src/mesa/main/fbobject.h
new file mode 100644
index 00000000000..301e2da4495
--- /dev/null
+++ b/src/mesa/main/fbobject.h
@@ -0,0 +1,134 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef FBOBJECT_H
+#define FBOBJECT_H
+
+
+extern struct gl_renderbuffer *
+_mesa_lookup_renderbuffer(GLcontext *ctx, GLuint id);
+
+extern struct gl_framebuffer *
+_mesa_lookup_framebuffer(GLcontext *ctx, GLuint id);
+
+extern struct gl_renderbuffer_attachment *
+_mesa_get_attachment(GLcontext *ctx, struct gl_framebuffer *fb,
+ GLenum attachment);
+
+
+extern void
+_mesa_remove_attachment(GLcontext *ctx,
+ struct gl_renderbuffer_attachment *att);
+
+extern void
+_mesa_set_texture_attachment(GLcontext *ctx,
+ struct gl_framebuffer *fb,
+ struct gl_renderbuffer_attachment *att,
+ struct gl_texture_object *texObj,
+ GLenum texTarget, GLuint level, GLuint zoffset);
+
+extern void
+_mesa_set_renderbuffer_attachment(GLcontext *ctx,
+ struct gl_renderbuffer_attachment *att,
+ struct gl_renderbuffer *rb);
+
+extern void
+_mesa_framebuffer_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
+ GLenum attachment, struct gl_renderbuffer *rb);
+
+extern void
+_mesa_test_framebuffer_completeness(GLcontext *ctx, struct gl_framebuffer *fb);
+
+extern GLenum
+_mesa_base_fbo_format(GLcontext *ctx, GLenum internalFormat);
+
+extern GLboolean GLAPIENTRY
+_mesa_IsRenderbufferEXT(GLuint renderbuffer);
+
+extern void GLAPIENTRY
+_mesa_BindRenderbufferEXT(GLenum target, GLuint renderbuffer);
+
+extern void GLAPIENTRY
+_mesa_DeleteRenderbuffersEXT(GLsizei n, const GLuint *renderbuffers);
+
+extern void GLAPIENTRY
+_mesa_GenRenderbuffersEXT(GLsizei n, GLuint *renderbuffers);
+
+extern void GLAPIENTRY
+_mesa_RenderbufferStorageEXT(GLenum target, GLenum internalformat,
+ GLsizei width, GLsizei height);
+
+extern void GLAPIENTRY
+_mesa_GetRenderbufferParameterivEXT(GLenum target, GLenum pname,
+ GLint *params);
+
+extern GLboolean GLAPIENTRY
+_mesa_IsFramebufferEXT(GLuint framebuffer);
+
+extern void GLAPIENTRY
+_mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer);
+
+extern void GLAPIENTRY
+_mesa_DeleteFramebuffersEXT(GLsizei n, const GLuint *framebuffers);
+
+extern void GLAPIENTRY
+_mesa_GenFramebuffersEXT(GLsizei n, GLuint *framebuffers);
+
+extern GLenum GLAPIENTRY
+_mesa_CheckFramebufferStatusEXT(GLenum target);
+
+extern void GLAPIENTRY
+_mesa_FramebufferTexture1DEXT(GLenum target, GLenum attachment,
+ GLenum textarget, GLuint texture, GLint level);
+
+extern void GLAPIENTRY
+_mesa_FramebufferTexture2DEXT(GLenum target, GLenum attachment,
+ GLenum textarget, GLuint texture, GLint level);
+
+extern void GLAPIENTRY
+_mesa_FramebufferTexture3DEXT(GLenum target, GLenum attachment,
+ GLenum textarget, GLuint texture,
+ GLint level, GLint zoffset);
+
+extern void GLAPIENTRY
+_mesa_FramebufferRenderbufferEXT(GLenum target, GLenum attachment,
+ GLenum renderbuffertarget,
+ GLuint renderbuffer);
+
+extern void GLAPIENTRY
+_mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
+ GLenum pname, GLint *params);
+
+extern void GLAPIENTRY
+_mesa_GenerateMipmapEXT(GLenum target);
+
+
+extern void GLAPIENTRY
+_mesa_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter);
+
+
+#endif /* FBOBJECT_H */
diff --git a/src/mesa/main/feedback.c b/src/mesa/main/feedback.c
new file mode 100644
index 00000000000..48c2ccbff30
--- /dev/null
+++ b/src/mesa/main/feedback.c
@@ -0,0 +1,541 @@
+/**
+ * \file feedback.c
+ * Selection and feedback modes functions.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 5.1
+ *
+ * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include "glheader.h"
+#include "colormac.h"
+#include "context.h"
+#include "enums.h"
+#include "feedback.h"
+#include "macros.h"
+#include "mtypes.h"
+
+
+#if _HAVE_FULL_GL
+
+
+#define FB_3D 0x01
+#define FB_4D 0x02
+#define FB_INDEX 0x04
+#define FB_COLOR 0x08
+#define FB_TEXTURE 0X10
+
+
+
+void GLAPIENTRY
+_mesa_FeedbackBuffer( GLsizei size, GLenum type, GLfloat *buffer )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (ctx->RenderMode==GL_FEEDBACK) {
+ _mesa_error( ctx, GL_INVALID_OPERATION, "glFeedbackBuffer" );
+ return;
+ }
+ if (size<0) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glFeedbackBuffer(size<0)" );
+ return;
+ }
+ if (!buffer) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glFeedbackBuffer(buffer==NULL)" );
+ ctx->Feedback.BufferSize = 0;
+ return;
+ }
+
+ switch (type) {
+ case GL_2D:
+ ctx->Feedback._Mask = 0;
+ break;
+ case GL_3D:
+ ctx->Feedback._Mask = FB_3D;
+ break;
+ case GL_3D_COLOR:
+ ctx->Feedback._Mask = (FB_3D |
+ (ctx->Visual.rgbMode ? FB_COLOR : FB_INDEX));
+ break;
+ case GL_3D_COLOR_TEXTURE:
+ ctx->Feedback._Mask = (FB_3D |
+ (ctx->Visual.rgbMode ? FB_COLOR : FB_INDEX) |
+ FB_TEXTURE);
+ break;
+ case GL_4D_COLOR_TEXTURE:
+ ctx->Feedback._Mask = (FB_3D | FB_4D |
+ (ctx->Visual.rgbMode ? FB_COLOR : FB_INDEX) |
+ FB_TEXTURE);
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glFeedbackBuffer" );
+ return;
+ }
+
+ FLUSH_VERTICES(ctx, _NEW_RENDERMODE); /* Always flush */
+ ctx->Feedback.Type = type;
+ ctx->Feedback.BufferSize = size;
+ ctx->Feedback.Buffer = buffer;
+ ctx->Feedback.Count = 0; /* Becaues of this. */
+}
+
+
+void GLAPIENTRY
+_mesa_PassThrough( GLfloat token )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (ctx->RenderMode==GL_FEEDBACK) {
+ FLUSH_VERTICES(ctx, 0);
+ FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_PASS_THROUGH_TOKEN );
+ FEEDBACK_TOKEN( ctx, token );
+ }
+}
+
+
+
+/*
+ * Put a vertex into the feedback buffer.
+ */
+void _mesa_feedback_vertex( GLcontext *ctx,
+ const GLfloat win[4],
+ const GLfloat color[4],
+ GLfloat index,
+ const GLfloat texcoord[4] )
+{
+#if 0
+ {
+ /* snap window x, y to fractional pixel position */
+ const GLint snapMask = ~((FIXED_ONE / (1 << SUB_PIXEL_BITS)) - 1);
+ GLfixed x, y;
+ x = FloatToFixed(win[0]) & snapMask;
+ y = FloatToFixed(win[1]) & snapMask;
+ FEEDBACK_TOKEN(ctx, FixedToFloat(x));
+ FEEDBACK_TOKEN(ctx, FixedToFloat(y) );
+ }
+#else
+ FEEDBACK_TOKEN( ctx, win[0] );
+ FEEDBACK_TOKEN( ctx, win[1] );
+#endif
+ if (ctx->Feedback._Mask & FB_3D) {
+ FEEDBACK_TOKEN( ctx, win[2] );
+ }
+ if (ctx->Feedback._Mask & FB_4D) {
+ FEEDBACK_TOKEN( ctx, win[3] );
+ }
+ if (ctx->Feedback._Mask & FB_INDEX) {
+ FEEDBACK_TOKEN( ctx, (GLfloat) index );
+ }
+ if (ctx->Feedback._Mask & FB_COLOR) {
+ FEEDBACK_TOKEN( ctx, color[0] );
+ FEEDBACK_TOKEN( ctx, color[1] );
+ FEEDBACK_TOKEN( ctx, color[2] );
+ FEEDBACK_TOKEN( ctx, color[3] );
+ }
+ if (ctx->Feedback._Mask & FB_TEXTURE) {
+ FEEDBACK_TOKEN( ctx, texcoord[0] );
+ FEEDBACK_TOKEN( ctx, texcoord[1] );
+ FEEDBACK_TOKEN( ctx, texcoord[2] );
+ FEEDBACK_TOKEN( ctx, texcoord[3] );
+ }
+}
+
+#endif
+
+
+/**********************************************************************/
+/** \name Selection */
+/*@{*/
+
+/**
+ * Establish a buffer for selection mode values.
+ *
+ * \param size buffer size.
+ * \param buffer buffer.
+ *
+ * \sa glSelectBuffer().
+ *
+ * \note this function can't be put in a display list.
+ *
+ * Verifies we're not in selection mode, flushes the vertices and initialize
+ * the fields in __GLcontextRec::Select with the given buffer.
+ */
+void GLAPIENTRY
+_mesa_SelectBuffer( GLsizei size, GLuint *buffer )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (ctx->RenderMode==GL_SELECT) {
+ _mesa_error( ctx, GL_INVALID_OPERATION, "glSelectBuffer" );
+ return; /* KW: added return */
+ }
+
+ FLUSH_VERTICES(ctx, _NEW_RENDERMODE);
+ ctx->Select.Buffer = buffer;
+ ctx->Select.BufferSize = size;
+ ctx->Select.BufferCount = 0;
+ ctx->Select.HitFlag = GL_FALSE;
+ ctx->Select.HitMinZ = 1.0;
+ ctx->Select.HitMaxZ = 0.0;
+}
+
+
+/**
+ * Write a value of a record into the selection buffer.
+ *
+ * \param CTX GL context.
+ * \param V value.
+ *
+ * Verifies there is free space in the buffer to write the value and
+ * increments the pointer.
+ */
+#define WRITE_RECORD( CTX, V ) \
+ if (CTX->Select.BufferCount < CTX->Select.BufferSize) { \
+ CTX->Select.Buffer[CTX->Select.BufferCount] = (V); \
+ } \
+ CTX->Select.BufferCount++;
+
+
+/**
+ * Update the hit flag and the maximum and minimum depth values.
+ *
+ * \param ctx GL context.
+ * \param z depth.
+ *
+ * Sets gl_selection::HitFlag and updates gl_selection::HitMinZ and
+ * gl_selection::HitMaxZ.
+ */
+void _mesa_update_hitflag( GLcontext *ctx, GLfloat z )
+{
+ ctx->Select.HitFlag = GL_TRUE;
+ if (z < ctx->Select.HitMinZ) {
+ ctx->Select.HitMinZ = z;
+ }
+ if (z > ctx->Select.HitMaxZ) {
+ ctx->Select.HitMaxZ = z;
+ }
+}
+
+
+/**
+ * Write the hit record.
+ *
+ * \param ctx GL context.
+ *
+ * Write the hit record, i.e., the number of names in the stack, the minimum and
+ * maximum depth values and the number of names in the name stack at the time
+ * of the event. Resets the hit flag.
+ *
+ * \sa gl_selection.
+ */
+static void write_hit_record( GLcontext *ctx )
+{
+ GLuint i;
+ GLuint zmin, zmax, zscale = (~0u);
+
+ /* HitMinZ and HitMaxZ are in [0,1]. Multiply these values by */
+ /* 2^32-1 and round to nearest unsigned integer. */
+
+ assert( ctx != NULL ); /* this line magically fixes a SunOS 5.x/gcc bug */
+ zmin = (GLuint) ((GLfloat) zscale * ctx->Select.HitMinZ);
+ zmax = (GLuint) ((GLfloat) zscale * ctx->Select.HitMaxZ);
+
+ WRITE_RECORD( ctx, ctx->Select.NameStackDepth );
+ WRITE_RECORD( ctx, zmin );
+ WRITE_RECORD( ctx, zmax );
+ for (i = 0; i < ctx->Select.NameStackDepth; i++) {
+ WRITE_RECORD( ctx, ctx->Select.NameStack[i] );
+ }
+
+ ctx->Select.Hits++;
+ ctx->Select.HitFlag = GL_FALSE;
+ ctx->Select.HitMinZ = 1.0;
+ ctx->Select.HitMaxZ = -1.0;
+}
+
+
+/**
+ * Initialize the name stack.
+ *
+ * Verifies we are in select mode and resets the name stack depth and resets
+ * the hit record data in gl_selection. Marks new render mode in
+ * __GLcontextRec::NewState.
+ */
+void GLAPIENTRY
+_mesa_InitNames( void )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ /* Record the hit before the HitFlag is wiped out again. */
+ if (ctx->RenderMode == GL_SELECT) {
+ if (ctx->Select.HitFlag) {
+ write_hit_record( ctx );
+ }
+ }
+ ctx->Select.NameStackDepth = 0;
+ ctx->Select.HitFlag = GL_FALSE;
+ ctx->Select.HitMinZ = 1.0;
+ ctx->Select.HitMaxZ = 0.0;
+ ctx->NewState |= _NEW_RENDERMODE;
+}
+
+
+/**
+ * Load the top-most name of the name stack.
+ *
+ * \param name name.
+ *
+ * Verifies we are in selection mode and that the name stack is not empty.
+ * Flushes vertices. If there is a hit flag writes it (via write_hit_record()),
+ * and replace the top-most name in the stack.
+ *
+ * sa __GLcontextRec::Select.
+ */
+void GLAPIENTRY
+_mesa_LoadName( GLuint name )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (ctx->RenderMode != GL_SELECT) {
+ return;
+ }
+ if (ctx->Select.NameStackDepth == 0) {
+ _mesa_error( ctx, GL_INVALID_OPERATION, "glLoadName" );
+ return;
+ }
+
+ FLUSH_VERTICES(ctx, _NEW_RENDERMODE);
+
+ if (ctx->Select.HitFlag) {
+ write_hit_record( ctx );
+ }
+ if (ctx->Select.NameStackDepth < MAX_NAME_STACK_DEPTH) {
+ ctx->Select.NameStack[ctx->Select.NameStackDepth-1] = name;
+ }
+ else {
+ ctx->Select.NameStack[MAX_NAME_STACK_DEPTH-1] = name;
+ }
+}
+
+
+/**
+ * Push a name into the name stack.
+ *
+ * \param name name.
+ *
+ * Verifies we are in selection mode and that the name stack is not full.
+ * Flushes vertices. If there is a hit flag writes it (via write_hit_record()),
+ * and adds the name to the top of the name stack.
+ *
+ * sa __GLcontextRec::Select.
+ */
+void GLAPIENTRY
+_mesa_PushName( GLuint name )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (ctx->RenderMode != GL_SELECT) {
+ return;
+ }
+
+ FLUSH_VERTICES(ctx, _NEW_RENDERMODE);
+ if (ctx->Select.HitFlag) {
+ write_hit_record( ctx );
+ }
+ if (ctx->Select.NameStackDepth >= MAX_NAME_STACK_DEPTH) {
+ _mesa_error( ctx, GL_STACK_OVERFLOW, "glPushName" );
+ }
+ else
+ ctx->Select.NameStack[ctx->Select.NameStackDepth++] = name;
+}
+
+
+/**
+ * Pop a name into the name stack.
+ *
+ * Verifies we are in selection mode and that the name stack is not empty.
+ * Flushes vertices. If there is a hit flag writes it (via write_hit_record()),
+ * and removes top-most name in the name stack.
+ *
+ * sa __GLcontextRec::Select.
+ */
+void GLAPIENTRY
+_mesa_PopName( void )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (ctx->RenderMode != GL_SELECT) {
+ return;
+ }
+
+ FLUSH_VERTICES(ctx, _NEW_RENDERMODE);
+ if (ctx->Select.HitFlag) {
+ write_hit_record( ctx );
+ }
+ if (ctx->Select.NameStackDepth == 0) {
+ _mesa_error( ctx, GL_STACK_UNDERFLOW, "glPopName" );
+ }
+ else
+ ctx->Select.NameStackDepth--;
+}
+
+/*@}*/
+
+
+/**********************************************************************/
+/** \name Render Mode */
+/*@{*/
+
+/**
+ * Set rasterization mode.
+ *
+ * \param mode rasterization mode.
+ *
+ * \note this function can't be put in a display list.
+ *
+ * \sa glRenderMode().
+ *
+ * Flushes the vertices and do the necessary cleanup according to the previous
+ * rasterization mode, such as writing the hit record or resent the select
+ * buffer index when exiting the select mode. Updates
+ * __GLcontextRec::RenderMode and notifies the driver via the
+ * dd_function_table::RenderMode callback.
+ */
+GLint GLAPIENTRY
+_mesa_RenderMode( GLenum mode )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint result;
+ ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0);
+
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx, "glRenderMode %s\n", _mesa_lookup_enum_by_nr(mode));
+
+ FLUSH_VERTICES(ctx, _NEW_RENDERMODE);
+
+ switch (ctx->RenderMode) {
+ case GL_RENDER:
+ result = 0;
+ break;
+ case GL_SELECT:
+ if (ctx->Select.HitFlag) {
+ write_hit_record( ctx );
+ }
+ if (ctx->Select.BufferCount > ctx->Select.BufferSize) {
+ /* overflow */
+#ifdef DEBUG
+ _mesa_warning(ctx, "Feedback buffer overflow");
+#endif
+ result = -1;
+ }
+ else {
+ result = ctx->Select.Hits;
+ }
+ ctx->Select.BufferCount = 0;
+ ctx->Select.Hits = 0;
+ ctx->Select.NameStackDepth = 0;
+ break;
+#if _HAVE_FULL_GL
+ case GL_FEEDBACK:
+ if (ctx->Feedback.Count > ctx->Feedback.BufferSize) {
+ /* overflow */
+ result = -1;
+ }
+ else {
+ result = ctx->Feedback.Count;
+ }
+ ctx->Feedback.Count = 0;
+ break;
+#endif
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glRenderMode" );
+ return 0;
+ }
+
+ switch (mode) {
+ case GL_RENDER:
+ break;
+ case GL_SELECT:
+ if (ctx->Select.BufferSize==0) {
+ /* haven't called glSelectBuffer yet */
+ _mesa_error( ctx, GL_INVALID_OPERATION, "glRenderMode" );
+ }
+ break;
+#if _HAVE_FULL_GL
+ case GL_FEEDBACK:
+ if (ctx->Feedback.BufferSize==0) {
+ /* haven't called glFeedbackBuffer yet */
+ _mesa_error( ctx, GL_INVALID_OPERATION, "glRenderMode" );
+ }
+ break;
+#endif
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glRenderMode" );
+ return 0;
+ }
+
+ ctx->RenderMode = mode;
+ if (ctx->Driver.RenderMode)
+ ctx->Driver.RenderMode( ctx, mode );
+
+ return result;
+}
+
+/*@}*/
+
+
+/**********************************************************************/
+/** \name Initialization */
+/*@{*/
+
+/**
+ * Initialize context feedback data.
+ */
+void _mesa_init_feedback( GLcontext * ctx )
+{
+ /* Feedback */
+ ctx->Feedback.Type = GL_2D; /* TODO: verify */
+ ctx->Feedback.Buffer = NULL;
+ ctx->Feedback.BufferSize = 0;
+ ctx->Feedback.Count = 0;
+
+ /* Selection/picking */
+ ctx->Select.Buffer = NULL;
+ ctx->Select.BufferSize = 0;
+ ctx->Select.BufferCount = 0;
+ ctx->Select.Hits = 0;
+ ctx->Select.NameStackDepth = 0;
+
+ /* Miscellaneous */
+ ctx->RenderMode = GL_RENDER;
+}
+
+/*@}*/
diff --git a/src/mesa/main/feedback.h b/src/mesa/main/feedback.h
new file mode 100644
index 00000000000..6c448ad631b
--- /dev/null
+++ b/src/mesa/main/feedback.h
@@ -0,0 +1,82 @@
+/**
+ * \file feedback.h
+ * Selection and feedback modes functions.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.5
+ *
+ * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef FEEDBACK_H
+#define FEEDBACK_H
+
+
+#include "mtypes.h"
+
+
+#define FEEDBACK_TOKEN( CTX, T ) \
+ if (CTX->Feedback.Count < CTX->Feedback.BufferSize) { \
+ CTX->Feedback.Buffer[CTX->Feedback.Count] = (GLfloat) (T); \
+ } \
+ CTX->Feedback.Count++;
+
+
+extern void _mesa_init_feedback( GLcontext * ctx );
+
+extern void _mesa_feedback_vertex( GLcontext *ctx,
+ const GLfloat win[4],
+ const GLfloat color[4],
+ GLfloat index,
+ const GLfloat texcoord[4] );
+
+
+extern void _mesa_update_hitflag( GLcontext *ctx, GLfloat z );
+
+
+extern void GLAPIENTRY
+_mesa_PassThrough( GLfloat token );
+
+extern void GLAPIENTRY
+_mesa_FeedbackBuffer( GLsizei size, GLenum type, GLfloat *buffer );
+
+extern void GLAPIENTRY
+_mesa_SelectBuffer( GLsizei size, GLuint *buffer );
+
+extern void GLAPIENTRY
+_mesa_InitNames( void );
+
+extern void GLAPIENTRY
+_mesa_LoadName( GLuint name );
+
+extern void GLAPIENTRY
+_mesa_PushName( GLuint name );
+
+extern void GLAPIENTRY
+_mesa_PopName( void );
+
+extern GLint GLAPIENTRY
+_mesa_RenderMode( GLenum mode );
+
+
+#endif
diff --git a/src/mesa/main/fog.c b/src/mesa/main/fog.c
new file mode 100644
index 00000000000..50a61bd84bf
--- /dev/null
+++ b/src/mesa/main/fog.c
@@ -0,0 +1,188 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 5.1
+ *
+ * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include "glheader.h"
+#include "colormac.h"
+#include "context.h"
+#include "fog.h"
+#include "mtypes.h"
+
+
+
+void GLAPIENTRY
+_mesa_Fogf(GLenum pname, GLfloat param)
+{
+ _mesa_Fogfv(pname, &param);
+}
+
+
+void GLAPIENTRY
+_mesa_Fogi(GLenum pname, GLint param )
+{
+ GLfloat fparam = (GLfloat) param;
+ _mesa_Fogfv(pname, &fparam);
+}
+
+
+void GLAPIENTRY
+_mesa_Fogiv(GLenum pname, const GLint *params )
+{
+ GLfloat p[4];
+ switch (pname) {
+ case GL_FOG_MODE:
+ case GL_FOG_DENSITY:
+ case GL_FOG_START:
+ case GL_FOG_END:
+ case GL_FOG_INDEX:
+ case GL_FOG_COORDINATE_SOURCE_EXT:
+ p[0] = (GLfloat) *params;
+ break;
+ case GL_FOG_COLOR:
+ p[0] = INT_TO_FLOAT( params[0] );
+ p[1] = INT_TO_FLOAT( params[1] );
+ p[2] = INT_TO_FLOAT( params[2] );
+ p[3] = INT_TO_FLOAT( params[3] );
+ break;
+ default:
+ /* Error will be caught later in _mesa_Fogfv */
+ ;
+ }
+ _mesa_Fogfv(pname, p);
+}
+
+
+#define UPDATE_FOG_SCALE(ctx) do {\
+ if (ctx->Fog.End == ctx->Fog.Start)\
+ ctx->Fog._Scale = 1.0f;\
+ else\
+ ctx->Fog._Scale = 1.0f / (ctx->Fog.End - ctx->Fog.Start);\
+ } while(0)
+
+
+void GLAPIENTRY
+_mesa_Fogfv( GLenum pname, const GLfloat *params )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLenum m;
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ switch (pname) {
+ case GL_FOG_MODE:
+ m = (GLenum) (GLint) *params;
+ switch (m) {
+ case GL_LINEAR:
+ case GL_EXP:
+ case GL_EXP2:
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glFog" );
+ return;
+ }
+ if (ctx->Fog.Mode == m)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_FOG);
+ ctx->Fog.Mode = m;
+ break;
+ case GL_FOG_DENSITY:
+ if (*params<0.0) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glFog" );
+ return;
+ }
+ if (ctx->Fog.Density == *params)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_FOG);
+ ctx->Fog.Density = *params;
+ break;
+ case GL_FOG_START:
+ if (ctx->Fog.Start == *params)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_FOG);
+ ctx->Fog.Start = *params;
+ UPDATE_FOG_SCALE(ctx);
+ break;
+ case GL_FOG_END:
+ if (ctx->Fog.End == *params)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_FOG);
+ ctx->Fog.End = *params;
+ UPDATE_FOG_SCALE(ctx);
+ break;
+ case GL_FOG_INDEX:
+ if (ctx->Fog.Index == *params)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_FOG);
+ ctx->Fog.Index = *params;
+ break;
+ case GL_FOG_COLOR:
+ if (TEST_EQ_4V(ctx->Fog.Color, params))
+ return;
+ FLUSH_VERTICES(ctx, _NEW_FOG);
+ ctx->Fog.Color[0] = CLAMP(params[0], 0.0F, 1.0F);
+ ctx->Fog.Color[1] = CLAMP(params[1], 0.0F, 1.0F);
+ ctx->Fog.Color[2] = CLAMP(params[2], 0.0F, 1.0F);
+ ctx->Fog.Color[3] = CLAMP(params[3], 0.0F, 1.0F);
+ break;
+ case GL_FOG_COORDINATE_SOURCE_EXT: {
+ GLenum p = (GLenum) (GLint) *params;
+ if (!ctx->Extensions.EXT_fog_coord ||
+ (p != GL_FOG_COORDINATE_EXT && p != GL_FRAGMENT_DEPTH_EXT)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glFog");
+ return;
+ }
+ if (ctx->Fog.FogCoordinateSource == p)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_FOG);
+ ctx->Fog.FogCoordinateSource = p;
+ break;
+ }
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glFog" );
+ return;
+ }
+
+ if (ctx->Driver.Fogfv) {
+ (*ctx->Driver.Fogfv)( ctx, pname, params );
+ }
+}
+
+
+/**********************************************************************/
+/***** Initialization *****/
+/**********************************************************************/
+
+void _mesa_init_fog( GLcontext * ctx )
+{
+ /* Fog group */
+ ctx->Fog.Enabled = GL_FALSE;
+ ctx->Fog.Mode = GL_EXP;
+ ASSIGN_4V( ctx->Fog.Color, 0.0, 0.0, 0.0, 0.0 );
+ ctx->Fog.Index = 0.0;
+ ctx->Fog.Density = 1.0;
+ ctx->Fog.Start = 0.0;
+ ctx->Fog.End = 1.0;
+ ctx->Fog.ColorSumEnabled = GL_FALSE;
+ ctx->Fog.FogCoordinateSource = GL_FRAGMENT_DEPTH_EXT;
+ ctx->Fog._Scale = 1.0f;
+}
diff --git a/src/mesa/main/fog.h b/src/mesa/main/fog.h
new file mode 100644
index 00000000000..a14d19cdb39
--- /dev/null
+++ b/src/mesa/main/fog.h
@@ -0,0 +1,66 @@
+/**
+ * \file fog.h
+ * Fog operations.
+ *
+ * \if subset
+ * (No-op)
+ *
+ * \endif
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.5
+ *
+ * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef FOG_H
+#define FOG_H
+
+
+#include "mtypes.h"
+
+
+#if _HAVE_FULL_GL
+
+extern void GLAPIENTRY
+_mesa_Fogf(GLenum pname, GLfloat param);
+
+extern void GLAPIENTRY
+_mesa_Fogi(GLenum pname, GLint param );
+
+extern void GLAPIENTRY
+_mesa_Fogfv(GLenum pname, const GLfloat *params );
+
+extern void GLAPIENTRY
+_mesa_Fogiv(GLenum pname, const GLint *params );
+
+extern void _mesa_init_fog( GLcontext * ctx );
+
+#else
+
+/** No-op */
+#define _mesa_init_fog( c ) ((void)0)
+
+#endif
+
+#endif
diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c
new file mode 100644
index 00000000000..a6607387fee
--- /dev/null
+++ b/src/mesa/main/framebuffer.c
@@ -0,0 +1,766 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/**
+ * Functions for allocating/managing framebuffers and renderbuffers.
+ * Also, routines for reading/writing renderbuffer data as ubytes,
+ * ushorts, uints, etc.
+ */
+
+
+#include "glheader.h"
+#include "imports.h"
+#include "context.h"
+#include "depthstencil.h"
+#include "mtypes.h"
+#include "fbobject.h"
+#include "framebuffer.h"
+#include "renderbuffer.h"
+
+
+
+/**
+ * Compute/set the _DepthMax field for the given framebuffer.
+ * This value depends on the Z buffer resolution.
+ */
+static void
+compute_depth_max(struct gl_framebuffer *fb)
+{
+ if (fb->Visual.depthBits == 0) {
+ /* Special case. Even if we don't have a depth buffer we need
+ * good values for DepthMax for Z vertex transformation purposes
+ * and for per-fragment fog computation.
+ */
+ fb->_DepthMax = (1 << 16) - 1;
+ }
+ else if (fb->Visual.depthBits < 32) {
+ fb->_DepthMax = (1 << fb->Visual.depthBits) - 1;
+ }
+ else {
+ /* Special case since shift values greater than or equal to the
+ * number of bits in the left hand expression's type are undefined.
+ */
+ fb->_DepthMax = 0xffffffff;
+ }
+ fb->_DepthMaxF = (GLfloat) fb->_DepthMax;
+ fb->_MRD = 1.0; /* Minimum resolvable depth value, for polygon offset */
+}
+
+
+/**
+ * Set the framebuffer's _DepthBuffer field, taking care of
+ * reference counts, etc.
+ */
+static void
+set_depth_renderbuffer(struct gl_framebuffer *fb,
+ struct gl_renderbuffer *rb)
+{
+ if (fb->_DepthBuffer) {
+ fb->_DepthBuffer->RefCount--;
+ if (fb->_DepthBuffer->RefCount <= 0) {
+ fb->_DepthBuffer->Delete(fb->_DepthBuffer);
+ }
+ }
+ fb->_DepthBuffer = rb;
+ if (rb) {
+ rb->RefCount++;
+ }
+}
+
+
+/**
+ * Set the framebuffer's _StencilBuffer field, taking care of
+ * reference counts, etc.
+ */
+static void
+set_stencil_renderbuffer(struct gl_framebuffer *fb,
+ struct gl_renderbuffer *rb)
+{
+ if (fb->_StencilBuffer) {
+ fb->_StencilBuffer->RefCount--;
+ if (fb->_StencilBuffer->RefCount <= 0) {
+ fb->_StencilBuffer->Delete(fb->_StencilBuffer);
+ }
+ }
+ fb->_StencilBuffer = rb;
+ if (rb) {
+ rb->RefCount++;
+ }
+}
+
+
+/**
+ * Create and initialize a gl_framebuffer object.
+ * This is intended for creating _window_system_ framebuffers, not generic
+ * framebuffer objects ala GL_EXT_framebuffer_object.
+ *
+ * \sa _mesa_new_framebuffer
+ */
+struct gl_framebuffer *
+_mesa_create_framebuffer(const GLvisual *visual)
+{
+ struct gl_framebuffer *fb = CALLOC_STRUCT(gl_framebuffer);
+ assert(visual);
+ if (fb) {
+ _mesa_initialize_framebuffer(fb, visual);
+ }
+ return fb;
+}
+
+
+/**
+ * Allocate a new gl_framebuffer object.
+ * This is the default function for ctx->Driver.NewFramebuffer().
+ * This is for allocating user-created framebuffers, not window-system
+ * framebuffers!
+ * \sa _mesa_create_framebuffer
+ */
+struct gl_framebuffer *
+_mesa_new_framebuffer(GLcontext *ctx, GLuint name)
+{
+ struct gl_framebuffer *fb;
+ assert(name != 0);
+ fb = CALLOC_STRUCT(gl_framebuffer);
+ if (fb) {
+ fb->Name = name;
+ fb->RefCount = 1;
+ fb->ColorDrawBuffer[0] = GL_COLOR_ATTACHMENT0_EXT;
+ fb->_ColorDrawBufferMask[0] = BUFFER_BIT_COLOR0;
+ fb->ColorReadBuffer = GL_COLOR_ATTACHMENT0_EXT;
+ fb->_ColorReadBufferIndex = BUFFER_COLOR0;
+ fb->Delete = _mesa_destroy_framebuffer;
+ }
+ return fb;
+}
+
+
+/**
+ * Initialize a gl_framebuffer object. Typically used to initialize
+ * window system-created framebuffers, not user-created framebuffers.
+ * \sa _mesa_create_framebuffer
+ */
+void
+_mesa_initialize_framebuffer(struct gl_framebuffer *fb, const GLvisual *visual)
+{
+ assert(fb);
+ assert(visual);
+
+ _mesa_bzero(fb, sizeof(struct gl_framebuffer));
+
+ _glthread_INIT_MUTEX(fb->Mutex);
+
+ /* save the visual */
+ fb->Visual = *visual;
+
+ /* Init glRead/DrawBuffer state */
+ if (visual->doubleBufferMode) {
+ fb->ColorDrawBuffer[0] = GL_BACK;
+ fb->_ColorDrawBufferMask[0] = BUFFER_BIT_BACK_LEFT;
+ fb->ColorReadBuffer = GL_BACK;
+ fb->_ColorReadBufferIndex = BUFFER_BACK_LEFT;
+ }
+ else {
+ fb->ColorDrawBuffer[0] = GL_FRONT;
+ fb->_ColorDrawBufferMask[0] = BUFFER_BIT_FRONT_LEFT;
+ fb->ColorReadBuffer = GL_FRONT;
+ fb->_ColorReadBufferIndex = BUFFER_FRONT_LEFT;
+ }
+
+ fb->Delete = _mesa_destroy_framebuffer;
+ fb->_Status = GL_FRAMEBUFFER_COMPLETE_EXT;
+
+ compute_depth_max(fb);
+}
+
+
+/**
+ * Deallocate buffer and everything attached to it.
+ * Typically called via the gl_framebuffer->Delete() method.
+ */
+void
+_mesa_destroy_framebuffer(struct gl_framebuffer *fb)
+{
+ if (fb) {
+ _glthread_DESTROY_MUTEX(fb->Mutex);
+ _mesa_free_framebuffer_data(fb);
+ _mesa_free(fb);
+ }
+}
+
+
+/**
+ * Free all the data hanging off the given gl_framebuffer, but don't free
+ * the gl_framebuffer object itself.
+ */
+void
+_mesa_free_framebuffer_data(struct gl_framebuffer *fb)
+{
+ GLuint i;
+
+ assert(fb);
+
+ for (i = 0; i < BUFFER_COUNT; i++) {
+ struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
+ if (att->Renderbuffer) {
+ struct gl_renderbuffer *rb = att->Renderbuffer;
+ _glthread_LOCK_MUTEX(rb->Mutex);
+ rb->RefCount--;
+ _glthread_UNLOCK_MUTEX(rb->Mutex);
+ if (rb->RefCount == 0) {
+ rb->Delete(rb);
+ }
+ }
+ att->Type = GL_NONE;
+ att->Renderbuffer = NULL;
+ }
+
+ /* unbind depth/stencil to decr ref counts */
+ set_depth_renderbuffer(fb, NULL);
+ set_stencil_renderbuffer(fb, NULL);
+}
+
+
+/**
+ * Resize the given framebuffer's renderbuffers to the new width and height.
+ * This should only be used for window-system framebuffers, not
+ * user-created renderbuffers (i.e. made with GL_EXT_framebuffer_object).
+ * This will typically be called via ctx->Driver.ResizeBuffers() or directly
+ * from a device driver.
+ *
+ * \note it's possible for ctx to be null since a window can be resized
+ * without a currently bound rendering context.
+ */
+void
+_mesa_resize_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb,
+ GLuint width, GLuint height)
+{
+ GLuint i;
+
+ /* XXX I think we could check if the size is not changing
+ * and return early.
+ */
+
+ /* For window system framebuffers, Name is zero */
+ assert(fb->Name == 0);
+
+ for (i = 0; i < BUFFER_COUNT; i++) {
+ struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
+ if (att->Type == GL_RENDERBUFFER_EXT && att->Renderbuffer) {
+ struct gl_renderbuffer *rb = att->Renderbuffer;
+ /* only resize if size is changing */
+ if (rb->Width != width || rb->Height != height) {
+ /* could just as well pass rb->_ActualFormat here */
+ if (rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height)) {
+ ASSERT(rb->Width == width);
+ ASSERT(rb->Height == height);
+ }
+ else {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "Resizing framebuffer");
+ /* no return */
+ }
+ }
+ }
+ }
+
+ if (fb->_DepthBuffer) {
+ struct gl_renderbuffer *rb = fb->_DepthBuffer;
+ if (rb->Width != width || rb->Height != height) {
+ if (!rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height)) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "Resizing framebuffer");
+ }
+ }
+ }
+
+ if (fb->_StencilBuffer) {
+ struct gl_renderbuffer *rb = fb->_StencilBuffer;
+ if (rb->Width != width || rb->Height != height) {
+ if (!rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height)) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "Resizing framebuffer");
+ }
+ }
+ }
+
+ fb->Width = width;
+ fb->Height = height;
+
+ /* to update scissor / window bounds */
+ _mesa_update_draw_buffer_bounds(ctx);
+}
+
+
+/**
+ * Examine all the framebuffer's renderbuffers to update the Width/Height
+ * fields of the framebuffer. If we have renderbuffers with different
+ * sizes, set the framebuffer's width and height to zero.
+ * Note: this is only intended for user-created framebuffers, not
+ * window-system framebuffes.
+ */
+static void
+update_framebuffer_size(struct gl_framebuffer *fb)
+{
+ GLboolean haveSize = GL_FALSE;
+ GLuint i;
+
+ /* user-created framebuffers only */
+ assert(fb->Name);
+
+ for (i = 0; i < BUFFER_COUNT; i++) {
+ struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
+ const struct gl_renderbuffer *rb = att->Renderbuffer;
+ if (rb) {
+ if (haveSize) {
+ if (rb->Width != fb->Width && rb->Height != fb->Height) {
+ /* size mismatch! */
+ fb->Width = 0;
+ fb->Height = 0;
+ return;
+ }
+ }
+ else {
+ fb->Width = rb->Width;
+ fb->Height = rb->Height;
+ haveSize = GL_TRUE;
+ }
+ }
+ }
+}
+
+
+/**
+ * Update the context's current drawing buffer's Xmin, Xmax, Ymin, Ymax fields.
+ * These values are computed from the buffer's width and height and
+ * the scissor box, if it's enabled.
+ * \param ctx the GL context.
+ */
+void
+_mesa_update_draw_buffer_bounds(GLcontext *ctx)
+{
+ struct gl_framebuffer *buffer = ctx->DrawBuffer;
+
+ if (buffer->Name) {
+ /* user-created framebuffer size depends on the renderbuffers */
+ update_framebuffer_size(buffer);
+ }
+
+ buffer->_Xmin = 0;
+ buffer->_Ymin = 0;
+ buffer->_Xmax = buffer->Width;
+ buffer->_Ymax = buffer->Height;
+
+ if (ctx->Scissor.Enabled) {
+ if (ctx->Scissor.X > buffer->_Xmin) {
+ buffer->_Xmin = ctx->Scissor.X;
+ }
+ if (ctx->Scissor.Y > buffer->_Ymin) {
+ buffer->_Ymin = ctx->Scissor.Y;
+ }
+ if (ctx->Scissor.X + ctx->Scissor.Width < buffer->_Xmax) {
+ buffer->_Xmax = ctx->Scissor.X + ctx->Scissor.Width;
+ }
+ if (ctx->Scissor.Y + ctx->Scissor.Height < buffer->_Ymax) {
+ buffer->_Ymax = ctx->Scissor.Y + ctx->Scissor.Height;
+ }
+ /* finally, check for empty region */
+ if (buffer->_Xmin > buffer->_Xmax) {
+ buffer->_Xmin = buffer->_Xmax;
+ }
+ if (buffer->_Ymin > buffer->_Ymax) {
+ buffer->_Ymin = buffer->_Ymax;
+ }
+ }
+
+ ASSERT(buffer->_Xmin <= buffer->_Xmax);
+ ASSERT(buffer->_Ymin <= buffer->_Ymax);
+}
+
+
+/**
+ * The glGet queries of the framebuffer red/green/blue size, stencil size,
+ * etc. are satisfied by the fields of ctx->DrawBuffer->Visual. These can
+ * change depending on the renderbuffer bindings. This function updates
+ * the given framebuffer's Visual from the current renderbuffer bindings.
+ * This is only intended for user-created framebuffers.
+ *
+ * Also note: ctx->DrawBuffer->Visual.depthBits might not equal
+ * ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer.DepthBits.
+ * The former one is used to convert floating point depth values into
+ * integer Z values.
+ */
+void
+_mesa_update_framebuffer_visual(struct gl_framebuffer *fb)
+{
+ GLuint i;
+
+ assert(fb->Name != 0);
+
+ _mesa_bzero(&fb->Visual, sizeof(fb->Visual));
+ fb->Visual.rgbMode = GL_TRUE; /* assume this */
+
+ /* find first RGB or CI renderbuffer */
+ for (i = 0; i < BUFFER_COUNT; i++) {
+ if (fb->Attachment[i].Renderbuffer) {
+ const struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
+ if (rb->_BaseFormat == GL_RGBA || rb->_BaseFormat == GL_RGB) {
+ fb->Visual.redBits = rb->RedBits;
+ fb->Visual.greenBits = rb->GreenBits;
+ fb->Visual.blueBits = rb->BlueBits;
+ fb->Visual.alphaBits = rb->AlphaBits;
+ fb->Visual.rgbBits = fb->Visual.redBits
+ + fb->Visual.greenBits + fb->Visual.blueBits;
+ fb->Visual.floatMode = GL_FALSE;
+ break;
+ }
+ else if (rb->_BaseFormat == GL_COLOR_INDEX) {
+ fb->Visual.indexBits = rb->IndexBits;
+ fb->Visual.rgbMode = GL_FALSE;
+ break;
+ }
+ }
+ }
+
+ if (fb->Attachment[BUFFER_DEPTH].Renderbuffer) {
+ fb->Visual.haveDepthBuffer = GL_TRUE;
+ fb->Visual.depthBits
+ = fb->Attachment[BUFFER_DEPTH].Renderbuffer->DepthBits;
+ }
+
+ if (fb->Attachment[BUFFER_STENCIL].Renderbuffer) {
+ fb->Visual.haveStencilBuffer = GL_TRUE;
+ fb->Visual.stencilBits
+ = fb->Attachment[BUFFER_STENCIL].Renderbuffer->StencilBits;
+ }
+
+ compute_depth_max(fb);
+}
+
+
+/**
+ * Update the framebuffer's _DepthBuffer field using the renderbuffer
+ * found at the given attachment index.
+ *
+ * If that attachment points to a combined GL_DEPTH_STENCIL renderbuffer,
+ * create and install a depth wrapper/adaptor.
+ *
+ * \param fb the framebuffer whose _DepthBuffer field to update
+ * \param attIndex indicates the renderbuffer to possibly wrap
+ */
+void
+_mesa_update_depth_buffer(GLcontext *ctx,
+ struct gl_framebuffer *fb,
+ GLuint attIndex)
+{
+ struct gl_renderbuffer *depthRb;
+
+ /* only one possiblity for now */
+ ASSERT(attIndex == BUFFER_DEPTH);
+
+ depthRb = fb->Attachment[attIndex].Renderbuffer;
+
+ if (depthRb && depthRb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT) {
+ /* The attached depth buffer is a GL_DEPTH_STENCIL renderbuffer */
+ if (!fb->_DepthBuffer || fb->_DepthBuffer->Wrapped != depthRb) {
+ /* need to update wrapper */
+ struct gl_renderbuffer *wrapper
+ = _mesa_new_z24_renderbuffer_wrapper(ctx, depthRb);
+ set_depth_renderbuffer(fb, wrapper);
+ ASSERT(fb->_DepthBuffer->Wrapped == depthRb);
+ }
+ }
+ else {
+ /* depthRb may be null */
+ set_depth_renderbuffer(fb, depthRb);
+ }
+}
+
+
+/**
+ * Update the framebuffer's _StencilBuffer field using the renderbuffer
+ * found at the given attachment index.
+ *
+ * If that attachment points to a combined GL_DEPTH_STENCIL renderbuffer,
+ * create and install a stencil wrapper/adaptor.
+ *
+ * \param fb the framebuffer whose _StencilBuffer field to update
+ * \param attIndex indicates the renderbuffer to possibly wrap
+ */
+void
+_mesa_update_stencil_buffer(GLcontext *ctx,
+ struct gl_framebuffer *fb,
+ GLuint attIndex)
+{
+ struct gl_renderbuffer *stencilRb;
+
+ ASSERT(attIndex == BUFFER_DEPTH ||
+ attIndex == BUFFER_STENCIL);
+
+ stencilRb = fb->Attachment[attIndex].Renderbuffer;
+
+ if (stencilRb && stencilRb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT) {
+ /* The attached stencil buffer is a GL_DEPTH_STENCIL renderbuffer */
+ if (!fb->_StencilBuffer || fb->_StencilBuffer->Wrapped != stencilRb) {
+ /* need to update wrapper */
+ struct gl_renderbuffer *wrapper
+ = _mesa_new_s8_renderbuffer_wrapper(ctx, stencilRb);
+ set_stencil_renderbuffer(fb, wrapper);
+ ASSERT(fb->_StencilBuffer->Wrapped == stencilRb);
+ }
+ }
+ else {
+ /* stencilRb may be null */
+ set_stencil_renderbuffer(fb, stencilRb);
+ }
+}
+
+
+/**
+ * Update the list of color drawing renderbuffer pointers.
+ * Later, when we're rendering we'll loop from 0 to _NumColorDrawBuffers
+ * writing colors.
+ */
+static void
+update_color_draw_buffers(GLcontext *ctx, struct gl_framebuffer *fb)
+{
+ GLuint output;
+
+ /*
+ * Fragment programs can write to multiple colorbuffers with
+ * the GL_ARB_draw_buffers extension.
+ */
+ for (output = 0; output < ctx->Const.MaxDrawBuffers; output++) {
+ GLbitfield bufferMask = fb->_ColorDrawBufferMask[output];
+ GLuint count = 0;
+ GLuint i;
+ /* We need the inner loop here because glDrawBuffer(GL_FRONT_AND_BACK)
+ * can specify writing to two or four color buffers (for example).
+ */
+ for (i = 0; bufferMask && i < BUFFER_COUNT; i++) {
+ const GLuint bufferBit = 1 << i;
+ if (bufferBit & bufferMask) {
+ struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
+ if (rb) {
+ fb->_ColorDrawBuffers[output][count] = rb;
+ count++;
+ }
+ else {
+ /*_mesa_warning(ctx, "DrawBuffer names a missing buffer!\n");*/
+ }
+ bufferMask &= ~bufferBit;
+ }
+ }
+ fb->_NumColorDrawBuffers[output] = count;
+ }
+}
+
+
+/**
+ * Update the color read renderbuffer pointer.
+ * Unlike the DrawBuffer, we can only read from one (or zero) color buffers.
+ */
+static void
+update_color_read_buffer(GLcontext *ctx, struct gl_framebuffer *fb)
+{
+ if (fb->_ColorReadBufferIndex == -1) {
+ fb->_ColorReadBuffer = NULL; /* legal! */
+ }
+ else {
+ ASSERT(fb->_ColorReadBufferIndex >= 0);
+ ASSERT(fb->_ColorReadBufferIndex < BUFFER_COUNT);
+ fb->_ColorReadBuffer
+ = fb->Attachment[fb->_ColorReadBufferIndex].Renderbuffer;
+ }
+}
+
+
+/**
+ * Update state related to the current draw/read framebuffers.
+ * Specifically, update these framebuffer fields:
+ * _ColorDrawBuffers
+ * _NumColorDrawBuffers
+ * _ColorReadBuffer
+ * _DepthBuffer
+ * _StencilBuffer
+ * If the current framebuffer is user-created, make sure it's complete.
+ * The following functions can effect this state: glReadBuffer,
+ * glDrawBuffer, glDrawBuffersARB, glFramebufferRenderbufferEXT,
+ * glRenderbufferStorageEXT.
+ */
+void
+_mesa_update_framebuffer(GLcontext *ctx)
+{
+ struct gl_framebuffer *fb = ctx->DrawBuffer;
+
+ /* Completeness only matters for user-created framebuffers */
+ if (fb->Name != 0) {
+ _mesa_test_framebuffer_completeness(ctx, fb);
+ _mesa_update_framebuffer_visual(fb);
+ }
+
+ update_color_draw_buffers(ctx, fb);
+ update_color_read_buffer(ctx, fb);
+ _mesa_update_depth_buffer(ctx, fb, BUFFER_DEPTH);
+ _mesa_update_stencil_buffer(ctx, fb, BUFFER_STENCIL);
+
+ compute_depth_max(fb);
+}
+
+
+/**
+ * Check if the renderbuffer for a read operation (glReadPixels, glCopyPixels,
+ * glCopyTex[Sub]Image, etc. exists.
+ * \param format a basic image format such as GL_RGB, GL_RGBA, GL_ALPHA,
+ * GL_DEPTH_COMPONENT, etc. or GL_COLOR, GL_DEPTH, GL_STENCIL.
+ * \return GL_TRUE if buffer exists, GL_FALSE otherwise
+ */
+GLboolean
+_mesa_source_buffer_exists(GLcontext *ctx, GLenum format)
+{
+ const struct gl_renderbuffer_attachment *att
+ = ctx->ReadBuffer->Attachment;
+
+ if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ return GL_FALSE;
+ }
+
+ switch (format) {
+ case GL_COLOR:
+ case GL_RED:
+ case GL_GREEN:
+ case GL_BLUE:
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ case GL_RGB:
+ case GL_BGR:
+ case GL_RGBA:
+ case GL_BGRA:
+ case GL_ABGR_EXT:
+ case GL_COLOR_INDEX:
+ if (ctx->ReadBuffer->_ColorReadBuffer == NULL) {
+ return GL_FALSE;
+ }
+ /* XXX enable this post 6.5 release:
+ ASSERT(ctx->ReadBuffer->_ColorReadBuffer->RedBits > 0 ||
+ ctx->ReadBuffer->_ColorReadBuffer->IndexBits > 0);
+ */
+ break;
+ case GL_DEPTH:
+ case GL_DEPTH_COMPONENT:
+ if (!att[BUFFER_DEPTH].Renderbuffer) {
+ return GL_FALSE;
+ }
+ ASSERT(att[BUFFER_DEPTH].Renderbuffer->DepthBits > 0);
+ break;
+ case GL_STENCIL:
+ case GL_STENCIL_INDEX:
+ if (!att[BUFFER_STENCIL].Renderbuffer) {
+ return GL_FALSE;
+ }
+ ASSERT(att[BUFFER_STENCIL].Renderbuffer->StencilBits > 0);
+ break;
+ case GL_DEPTH_STENCIL_EXT:
+ if (!att[BUFFER_DEPTH].Renderbuffer ||
+ !att[BUFFER_STENCIL].Renderbuffer) {
+ return GL_FALSE;
+ }
+ ASSERT(att[BUFFER_DEPTH].Renderbuffer->DepthBits > 0);
+ ASSERT(att[BUFFER_STENCIL].Renderbuffer->StencilBits > 0);
+ break;
+ default:
+ _mesa_problem(ctx,
+ "Unexpected format 0x%x in _mesa_source_buffer_exists",
+ format);
+ return GL_FALSE;
+ }
+
+ /* OK */
+ return GL_TRUE;
+}
+
+
+/**
+ * As above, but for drawing operations.
+ * XXX code do some code merging w/ above function.
+ */
+GLboolean
+_mesa_dest_buffer_exists(GLcontext *ctx, GLenum format)
+{
+ const struct gl_renderbuffer_attachment *att
+ = ctx->ReadBuffer->Attachment;
+
+ if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ return GL_FALSE;
+ }
+
+ switch (format) {
+ case GL_COLOR:
+ case GL_RED:
+ case GL_GREEN:
+ case GL_BLUE:
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ case GL_RGB:
+ case GL_BGR:
+ case GL_RGBA:
+ case GL_BGRA:
+ case GL_ABGR_EXT:
+ case GL_COLOR_INDEX:
+ /* nothing special */
+ /* Could assert that colorbuffer has RedBits > 0 */
+ break;
+ case GL_DEPTH:
+ case GL_DEPTH_COMPONENT:
+ if (!att[BUFFER_DEPTH].Renderbuffer) {
+ return GL_FALSE;
+ }
+ ASSERT(att[BUFFER_DEPTH].Renderbuffer->DepthBits > 0);
+ break;
+ case GL_STENCIL:
+ case GL_STENCIL_INDEX:
+ if (!att[BUFFER_STENCIL].Renderbuffer) {
+ return GL_FALSE;
+ }
+ ASSERT(att[BUFFER_STENCIL].Renderbuffer->StencilBits > 0);
+ break;
+ case GL_DEPTH_STENCIL_EXT:
+ if (!att[BUFFER_DEPTH].Renderbuffer ||
+ !att[BUFFER_STENCIL].Renderbuffer) {
+ return GL_FALSE;
+ }
+ ASSERT(att[BUFFER_DEPTH].Renderbuffer->DepthBits > 0);
+ ASSERT(att[BUFFER_STENCIL].Renderbuffer->StencilBits > 0);
+ break;
+ default:
+ _mesa_problem(ctx,
+ "Unexpected format 0x%x in _mesa_source_buffer_exists",
+ format);
+ return GL_FALSE;
+ }
+
+ /* OK */
+ return GL_TRUE;
+}
diff --git a/src/mesa/main/framebuffer.h b/src/mesa/main/framebuffer.h
new file mode 100644
index 00000000000..1ff04085f34
--- /dev/null
+++ b/src/mesa/main/framebuffer.h
@@ -0,0 +1,73 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef FRAMEBUFFER_H
+#define FRAMEBUFFER_H
+
+
+extern struct gl_framebuffer *
+_mesa_create_framebuffer(const GLvisual *visual);
+
+extern struct gl_framebuffer *
+_mesa_new_framebuffer(GLcontext *ctx, GLuint name);
+
+extern void
+_mesa_initialize_framebuffer(struct gl_framebuffer *fb, const GLvisual *visual);
+
+extern void
+_mesa_destroy_framebuffer(struct gl_framebuffer *buffer);
+
+extern void
+_mesa_free_framebuffer_data(struct gl_framebuffer *buffer);
+
+extern void
+_mesa_resize_framebuffer(GLcontext *ctx, struct gl_framebuffer *b,
+ GLuint width, GLuint height);
+
+extern void
+_mesa_update_draw_buffer_bounds(GLcontext *ctx);
+
+extern void
+_mesa_update_framebuffer_visual(struct gl_framebuffer *fb);
+
+extern void
+_mesa_update_depth_buffer(GLcontext *ctx, struct gl_framebuffer *fb,
+ GLuint attIndex);
+
+extern void
+_mesa_update_stencil_buffer(GLcontext *ctx, struct gl_framebuffer *fb,
+ GLuint attIndex);
+
+extern void
+_mesa_update_framebuffer(GLcontext *ctx);
+
+extern GLboolean
+_mesa_source_buffer_exists(GLcontext *ctx, GLenum format);
+
+extern GLboolean
+_mesa_dest_buffer_exists(GLcontext *ctx, GLenum format);
+
+
+#endif /* FRAMEBUFFER_H */
diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c
new file mode 100644
index 00000000000..7147c9a5ccc
--- /dev/null
+++ b/src/mesa/main/get.c
@@ -0,0 +1,5545 @@
+
+/***
+ *** NOTE!!! DO NOT EDIT THIS FILE!!! IT IS GENERATED BY get_gen.py
+ ***/
+
+#include "glheader.h"
+#include "context.h"
+#include "enable.h"
+#include "extensions.h"
+#include "fbobject.h"
+#include "get.h"
+#include "macros.h"
+#include "mtypes.h"
+#include "state.h"
+#include "texcompress.h"
+
+
+#define FLOAT_TO_BOOLEAN(X) ( (X) ? GL_TRUE : GL_FALSE )
+
+#define INT_TO_BOOLEAN(I) ( (I) ? GL_TRUE : GL_FALSE )
+
+#define ENUM_TO_BOOLEAN(E) ( (E) ? GL_TRUE : GL_FALSE )
+#define ENUM_TO_INT(E) ( (GLint) (E) )
+#define ENUM_TO_FLOAT(E) ( (GLfloat) (E) )
+
+#define BOOLEAN_TO_INT(B) ( (GLint) (B) )
+#define BOOLEAN_TO_FLOAT(B) ( (B) ? 1.0F : 0.0F )
+
+
+/*
+ * Check if named extension is enabled, if not generate error and return.
+ */
+#define CHECK_EXT1(EXT1, FUNC) \
+ if (!ctx->Extensions.EXT1) { \
+ _mesa_error(ctx, GL_INVALID_ENUM, FUNC "(0x%x)", (int) pname); \
+ return; \
+ }
+
+/*
+ * Check if either of two extensions is enabled.
+ */
+#define CHECK_EXT2(EXT1, EXT2, FUNC) \
+ if (!ctx->Extensions.EXT1 && !ctx->Extensions.EXT2) { \
+ _mesa_error(ctx, GL_INVALID_ENUM, FUNC "(0x%x)", (int) pname); \
+ return; \
+ }
+
+/*
+ * Check if either of three extensions is enabled.
+ */
+#define CHECK_EXT3(EXT1, EXT2, EXT3, FUNC) \
+ if (!ctx->Extensions.EXT1 && !ctx->Extensions.EXT2 && \
+ !ctx->Extensions.EXT3) { \
+ _mesa_error(ctx, GL_INVALID_ENUM, FUNC "(0x%x)", (int) pname); \
+ return; \
+ }
+
+/*
+ * Check if either of four extensions is enabled.
+ */
+#define CHECK_EXT4(EXT1, EXT2, EXT3, EXT4, FUNC) \
+ if (!ctx->Extensions.EXT1 && !ctx->Extensions.EXT2 && \
+ !ctx->Extensions.EXT3 && !ctx->Extensions.EXT4) { \
+ _mesa_error(ctx, GL_INVALID_ENUM, FUNC "(0x%x)", (int) pname); \
+ return; \
+ }
+
+
+void GLAPIENTRY
+_mesa_GetBooleanv( GLenum pname, GLboolean *params )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (!params)
+ return;
+
+ if (ctx->NewState)
+ _mesa_update_state(ctx);
+
+ if (ctx->Driver.GetBooleanv &&
+ ctx->Driver.GetBooleanv(ctx, pname, params))
+ return;
+
+ switch (pname) {
+ case GL_ACCUM_RED_BITS:
+ params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.accumRedBits);
+ break;
+ case GL_ACCUM_GREEN_BITS:
+ params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.accumGreenBits);
+ break;
+ case GL_ACCUM_BLUE_BITS:
+ params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.accumBlueBits);
+ break;
+ case GL_ACCUM_ALPHA_BITS:
+ params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.accumAlphaBits);
+ break;
+ case GL_ACCUM_CLEAR_VALUE:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Accum.ClearColor[0]);
+ params[1] = FLOAT_TO_BOOLEAN(ctx->Accum.ClearColor[1]);
+ params[2] = FLOAT_TO_BOOLEAN(ctx->Accum.ClearColor[2]);
+ params[3] = FLOAT_TO_BOOLEAN(ctx->Accum.ClearColor[3]);
+ break;
+ case GL_ALPHA_BIAS:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.AlphaBias);
+ break;
+ case GL_ALPHA_BITS:
+ params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.alphaBits);
+ break;
+ case GL_ALPHA_SCALE:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.AlphaScale);
+ break;
+ case GL_ALPHA_TEST:
+ params[0] = ctx->Color.AlphaEnabled;
+ break;
+ case GL_ALPHA_TEST_FUNC:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Color.AlphaFunc);
+ break;
+ case GL_ALPHA_TEST_REF:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Color.AlphaRef);
+ break;
+ case GL_ATTRIB_STACK_DEPTH:
+ params[0] = INT_TO_BOOLEAN(ctx->AttribStackDepth);
+ break;
+ case GL_AUTO_NORMAL:
+ params[0] = ctx->Eval.AutoNormal;
+ break;
+ case GL_AUX_BUFFERS:
+ params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.numAuxBuffers);
+ break;
+ case GL_BLEND:
+ params[0] = ctx->Color.BlendEnabled;
+ break;
+ case GL_BLEND_DST:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Color.BlendDstRGB);
+ break;
+ case GL_BLEND_SRC:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Color.BlendSrcRGB);
+ break;
+ case GL_BLEND_SRC_RGB_EXT:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Color.BlendSrcRGB);
+ break;
+ case GL_BLEND_DST_RGB_EXT:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Color.BlendDstRGB);
+ break;
+ case GL_BLEND_SRC_ALPHA_EXT:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Color.BlendSrcA);
+ break;
+ case GL_BLEND_DST_ALPHA_EXT:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Color.BlendDstA);
+ break;
+ case GL_BLEND_EQUATION:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Color.BlendEquationRGB );
+ break;
+ case GL_BLEND_EQUATION_ALPHA_EXT:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Color.BlendEquationA );
+ break;
+ case GL_BLEND_COLOR_EXT:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Color.BlendColor[0]);
+ params[1] = FLOAT_TO_BOOLEAN(ctx->Color.BlendColor[1]);
+ params[2] = FLOAT_TO_BOOLEAN(ctx->Color.BlendColor[2]);
+ params[3] = FLOAT_TO_BOOLEAN(ctx->Color.BlendColor[3]);
+ break;
+ case GL_BLUE_BIAS:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.BlueBias);
+ break;
+ case GL_BLUE_BITS:
+ params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.blueBits);
+ break;
+ case GL_BLUE_SCALE:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.BlueScale);
+ break;
+ case GL_CLIENT_ATTRIB_STACK_DEPTH:
+ params[0] = INT_TO_BOOLEAN(ctx->ClientAttribStackDepth);
+ break;
+ case GL_CLIP_PLANE0:
+ params[0] = (ctx->Transform.ClipPlanesEnabled >> 0) & 1;
+ break;
+ case GL_CLIP_PLANE1:
+ params[0] = (ctx->Transform.ClipPlanesEnabled >> 1) & 1;
+ break;
+ case GL_CLIP_PLANE2:
+ params[0] = (ctx->Transform.ClipPlanesEnabled >> 2) & 1;
+ break;
+ case GL_CLIP_PLANE3:
+ params[0] = (ctx->Transform.ClipPlanesEnabled >> 3) & 1;
+ break;
+ case GL_CLIP_PLANE4:
+ params[0] = (ctx->Transform.ClipPlanesEnabled >> 4) & 1;
+ break;
+ case GL_CLIP_PLANE5:
+ params[0] = (ctx->Transform.ClipPlanesEnabled >> 5) & 1;
+ break;
+ case GL_COLOR_CLEAR_VALUE:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Color.ClearColor[0]);
+ params[1] = FLOAT_TO_BOOLEAN(ctx->Color.ClearColor[1]);
+ params[2] = FLOAT_TO_BOOLEAN(ctx->Color.ClearColor[2]);
+ params[3] = FLOAT_TO_BOOLEAN(ctx->Color.ClearColor[3]);
+ break;
+ case GL_COLOR_MATERIAL:
+ params[0] = ctx->Light.ColorMaterialEnabled;
+ break;
+ case GL_COLOR_MATERIAL_FACE:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Light.ColorMaterialFace);
+ break;
+ case GL_COLOR_MATERIAL_PARAMETER:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Light.ColorMaterialMode);
+ break;
+ case GL_COLOR_WRITEMASK:
+ params[0] = INT_TO_BOOLEAN(ctx->Color.ColorMask[RCOMP] ? 1 : 0);
+ params[1] = INT_TO_BOOLEAN(ctx->Color.ColorMask[GCOMP] ? 1 : 0);
+ params[2] = INT_TO_BOOLEAN(ctx->Color.ColorMask[BCOMP] ? 1 : 0);
+ params[3] = INT_TO_BOOLEAN(ctx->Color.ColorMask[ACOMP] ? 1 : 0);
+ break;
+ case GL_CULL_FACE:
+ params[0] = ctx->Polygon.CullFlag;
+ break;
+ case GL_CULL_FACE_MODE:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Polygon.CullFaceMode);
+ break;
+ case GL_CURRENT_COLOR:
+ {
+ FLUSH_CURRENT(ctx, 0);
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0]);
+ params[1] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1]);
+ params[2] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2]);
+ params[3] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3]);
+ }
+ break;
+ case GL_CURRENT_INDEX:
+ {
+ FLUSH_CURRENT(ctx, 0);
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Current.Index);
+ }
+ break;
+ case GL_CURRENT_NORMAL:
+ {
+ FLUSH_CURRENT(ctx, 0);
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_NORMAL][0]);
+ params[1] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_NORMAL][1]);
+ params[2] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_NORMAL][2]);
+ }
+ break;
+ case GL_CURRENT_RASTER_COLOR:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Current.RasterColor[0]);
+ params[1] = FLOAT_TO_BOOLEAN(ctx->Current.RasterColor[1]);
+ params[2] = FLOAT_TO_BOOLEAN(ctx->Current.RasterColor[2]);
+ params[3] = FLOAT_TO_BOOLEAN(ctx->Current.RasterColor[3]);
+ break;
+ case GL_CURRENT_RASTER_DISTANCE:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Current.RasterDistance);
+ break;
+ case GL_CURRENT_RASTER_INDEX:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Current.RasterIndex);
+ break;
+ case GL_CURRENT_RASTER_POSITION:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Current.RasterPos[0]);
+ params[1] = FLOAT_TO_BOOLEAN(ctx->Current.RasterPos[1]);
+ params[2] = FLOAT_TO_BOOLEAN(ctx->Current.RasterPos[2]);
+ params[3] = FLOAT_TO_BOOLEAN(ctx->Current.RasterPos[3]);
+ break;
+ case GL_CURRENT_RASTER_TEXTURE_COORDS:
+ {
+ const GLuint texUnit = ctx->Texture.CurrentUnit;
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Current.RasterTexCoords[texUnit][0]);
+ params[1] = FLOAT_TO_BOOLEAN(ctx->Current.RasterTexCoords[texUnit][1]);
+ params[2] = FLOAT_TO_BOOLEAN(ctx->Current.RasterTexCoords[texUnit][2]);
+ params[3] = FLOAT_TO_BOOLEAN(ctx->Current.RasterTexCoords[texUnit][3]);
+ }
+ break;
+ case GL_CURRENT_RASTER_POSITION_VALID:
+ params[0] = ctx->Current.RasterPosValid;
+ break;
+ case GL_CURRENT_TEXTURE_COORDS:
+ {
+ const GLuint texUnit = ctx->Texture.CurrentUnit;
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][0]);
+ params[1] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][1]);
+ params[2] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][2]);
+ params[3] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][3]);
+ }
+ break;
+ case GL_DEPTH_BIAS:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.DepthBias);
+ break;
+ case GL_DEPTH_BITS:
+ params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.depthBits);
+ break;
+ case GL_DEPTH_CLEAR_VALUE:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Depth.Clear);
+ break;
+ case GL_DEPTH_FUNC:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Depth.Func);
+ break;
+ case GL_DEPTH_RANGE:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Viewport.Near);
+ params[1] = FLOAT_TO_BOOLEAN(ctx->Viewport.Far);
+ break;
+ case GL_DEPTH_SCALE:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.DepthScale);
+ break;
+ case GL_DEPTH_TEST:
+ params[0] = ctx->Depth.Test;
+ break;
+ case GL_DEPTH_WRITEMASK:
+ params[0] = ctx->Depth.Mask;
+ break;
+ case GL_DITHER:
+ params[0] = ctx->Color.DitherFlag;
+ break;
+ case GL_DOUBLEBUFFER:
+ params[0] = ctx->DrawBuffer->Visual.doubleBufferMode;
+ break;
+ case GL_DRAW_BUFFER:
+ params[0] = ENUM_TO_BOOLEAN(ctx->DrawBuffer->ColorDrawBuffer[0]);
+ break;
+ case GL_EDGE_FLAG:
+ {
+ FLUSH_CURRENT(ctx, 0);
+ params[0] = ctx->Current.EdgeFlag;
+ }
+ break;
+ case GL_FEEDBACK_BUFFER_SIZE:
+ params[0] = INT_TO_BOOLEAN(ctx->Feedback.BufferSize);
+ break;
+ case GL_FEEDBACK_BUFFER_TYPE:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Feedback.Type);
+ break;
+ case GL_FOG:
+ params[0] = ctx->Fog.Enabled;
+ break;
+ case GL_FOG_COLOR:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Fog.Color[0]);
+ params[1] = FLOAT_TO_BOOLEAN(ctx->Fog.Color[1]);
+ params[2] = FLOAT_TO_BOOLEAN(ctx->Fog.Color[2]);
+ params[3] = FLOAT_TO_BOOLEAN(ctx->Fog.Color[3]);
+ break;
+ case GL_FOG_DENSITY:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Fog.Density);
+ break;
+ case GL_FOG_END:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Fog.End);
+ break;
+ case GL_FOG_HINT:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Hint.Fog);
+ break;
+ case GL_FOG_INDEX:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Fog.Index);
+ break;
+ case GL_FOG_MODE:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Fog.Mode);
+ break;
+ case GL_FOG_START:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Fog.Start);
+ break;
+ case GL_FRONT_FACE:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Polygon.FrontFace);
+ break;
+ case GL_GREEN_BIAS:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.GreenBias);
+ break;
+ case GL_GREEN_BITS:
+ params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.greenBits);
+ break;
+ case GL_GREEN_SCALE:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.GreenScale);
+ break;
+ case GL_INDEX_BITS:
+ params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.indexBits);
+ break;
+ case GL_INDEX_CLEAR_VALUE:
+ params[0] = INT_TO_BOOLEAN(ctx->Color.ClearIndex);
+ break;
+ case GL_INDEX_MODE:
+ params[0] = !ctx->DrawBuffer->Visual.rgbMode;
+ break;
+ case GL_INDEX_OFFSET:
+ params[0] = INT_TO_BOOLEAN(ctx->Pixel.IndexOffset);
+ break;
+ case GL_INDEX_SHIFT:
+ params[0] = INT_TO_BOOLEAN(ctx->Pixel.IndexShift);
+ break;
+ case GL_INDEX_WRITEMASK:
+ params[0] = INT_TO_BOOLEAN(ctx->Color.IndexMask);
+ break;
+ case GL_LIGHT0:
+ params[0] = ctx->Light.Light[0].Enabled;
+ break;
+ case GL_LIGHT1:
+ params[0] = ctx->Light.Light[1].Enabled;
+ break;
+ case GL_LIGHT2:
+ params[0] = ctx->Light.Light[2].Enabled;
+ break;
+ case GL_LIGHT3:
+ params[0] = ctx->Light.Light[3].Enabled;
+ break;
+ case GL_LIGHT4:
+ params[0] = ctx->Light.Light[4].Enabled;
+ break;
+ case GL_LIGHT5:
+ params[0] = ctx->Light.Light[5].Enabled;
+ break;
+ case GL_LIGHT6:
+ params[0] = ctx->Light.Light[6].Enabled;
+ break;
+ case GL_LIGHT7:
+ params[0] = ctx->Light.Light[7].Enabled;
+ break;
+ case GL_LIGHTING:
+ params[0] = ctx->Light.Enabled;
+ break;
+ case GL_LIGHT_MODEL_AMBIENT:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Light.Model.Ambient[0]);
+ params[1] = FLOAT_TO_BOOLEAN(ctx->Light.Model.Ambient[1]);
+ params[2] = FLOAT_TO_BOOLEAN(ctx->Light.Model.Ambient[2]);
+ params[3] = FLOAT_TO_BOOLEAN(ctx->Light.Model.Ambient[3]);
+ break;
+ case GL_LIGHT_MODEL_COLOR_CONTROL:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Light.Model.ColorControl);
+ break;
+ case GL_LIGHT_MODEL_LOCAL_VIEWER:
+ params[0] = ctx->Light.Model.LocalViewer;
+ break;
+ case GL_LIGHT_MODEL_TWO_SIDE:
+ params[0] = ctx->Light.Model.TwoSide;
+ break;
+ case GL_LINE_SMOOTH:
+ params[0] = ctx->Line.SmoothFlag;
+ break;
+ case GL_LINE_SMOOTH_HINT:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Hint.LineSmooth);
+ break;
+ case GL_LINE_STIPPLE:
+ params[0] = ctx->Line.StippleFlag;
+ break;
+ case GL_LINE_STIPPLE_PATTERN:
+ params[0] = INT_TO_BOOLEAN(ctx->Line.StipplePattern);
+ break;
+ case GL_LINE_STIPPLE_REPEAT:
+ params[0] = INT_TO_BOOLEAN(ctx->Line.StippleFactor);
+ break;
+ case GL_LINE_WIDTH:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Line.Width);
+ break;
+ case GL_LINE_WIDTH_GRANULARITY:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Const.LineWidthGranularity);
+ break;
+ case GL_LINE_WIDTH_RANGE:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Const.MinLineWidthAA);
+ params[1] = FLOAT_TO_BOOLEAN(ctx->Const.MaxLineWidthAA);
+ break;
+ case GL_ALIASED_LINE_WIDTH_RANGE:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Const.MinLineWidth);
+ params[1] = FLOAT_TO_BOOLEAN(ctx->Const.MaxLineWidth);
+ break;
+ case GL_LIST_BASE:
+ params[0] = INT_TO_BOOLEAN(ctx->List.ListBase);
+ break;
+ case GL_LIST_INDEX:
+ params[0] = INT_TO_BOOLEAN(ctx->ListState.CurrentListNum);
+ break;
+ case GL_LIST_MODE:
+ {
+ GLenum mode;
+ if (!ctx->CompileFlag)
+ mode = 0;
+ else if (ctx->ExecuteFlag)
+ mode = GL_COMPILE_AND_EXECUTE;
+ else
+ mode = GL_COMPILE;
+ params[0] = ENUM_TO_BOOLEAN(mode);
+ }
+ break;
+ case GL_INDEX_LOGIC_OP:
+ params[0] = ctx->Color.IndexLogicOpEnabled;
+ break;
+ case GL_COLOR_LOGIC_OP:
+ params[0] = ctx->Color.ColorLogicOpEnabled;
+ break;
+ case GL_LOGIC_OP_MODE:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Color.LogicOp);
+ break;
+ case GL_MAP1_COLOR_4:
+ params[0] = ctx->Eval.Map1Color4;
+ break;
+ case GL_MAP1_GRID_DOMAIN:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Eval.MapGrid1u1);
+ params[1] = FLOAT_TO_BOOLEAN(ctx->Eval.MapGrid1u2);
+ break;
+ case GL_MAP1_GRID_SEGMENTS:
+ params[0] = INT_TO_BOOLEAN(ctx->Eval.MapGrid1un);
+ break;
+ case GL_MAP1_INDEX:
+ params[0] = ctx->Eval.Map1Index;
+ break;
+ case GL_MAP1_NORMAL:
+ params[0] = ctx->Eval.Map1Normal;
+ break;
+ case GL_MAP1_TEXTURE_COORD_1:
+ params[0] = ctx->Eval.Map1TextureCoord1;
+ break;
+ case GL_MAP1_TEXTURE_COORD_2:
+ params[0] = ctx->Eval.Map1TextureCoord2;
+ break;
+ case GL_MAP1_TEXTURE_COORD_3:
+ params[0] = ctx->Eval.Map1TextureCoord3;
+ break;
+ case GL_MAP1_TEXTURE_COORD_4:
+ params[0] = ctx->Eval.Map1TextureCoord4;
+ break;
+ case GL_MAP1_VERTEX_3:
+ params[0] = ctx->Eval.Map1Vertex3;
+ break;
+ case GL_MAP1_VERTEX_4:
+ params[0] = ctx->Eval.Map1Vertex4;
+ break;
+ case GL_MAP2_COLOR_4:
+ params[0] = ctx->Eval.Map2Color4;
+ break;
+ case GL_MAP2_GRID_DOMAIN:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Eval.MapGrid2u1);
+ params[1] = FLOAT_TO_BOOLEAN(ctx->Eval.MapGrid2u2);
+ params[2] = FLOAT_TO_BOOLEAN(ctx->Eval.MapGrid2v1);
+ params[3] = FLOAT_TO_BOOLEAN(ctx->Eval.MapGrid2v2);
+ break;
+ case GL_MAP2_GRID_SEGMENTS:
+ params[0] = INT_TO_BOOLEAN(ctx->Eval.MapGrid2un);
+ params[1] = INT_TO_BOOLEAN(ctx->Eval.MapGrid2vn);
+ break;
+ case GL_MAP2_INDEX:
+ params[0] = ctx->Eval.Map2Index;
+ break;
+ case GL_MAP2_NORMAL:
+ params[0] = ctx->Eval.Map2Normal;
+ break;
+ case GL_MAP2_TEXTURE_COORD_1:
+ params[0] = ctx->Eval.Map2TextureCoord1;
+ break;
+ case GL_MAP2_TEXTURE_COORD_2:
+ params[0] = ctx->Eval.Map2TextureCoord2;
+ break;
+ case GL_MAP2_TEXTURE_COORD_3:
+ params[0] = ctx->Eval.Map2TextureCoord3;
+ break;
+ case GL_MAP2_TEXTURE_COORD_4:
+ params[0] = ctx->Eval.Map2TextureCoord4;
+ break;
+ case GL_MAP2_VERTEX_3:
+ params[0] = ctx->Eval.Map2Vertex3;
+ break;
+ case GL_MAP2_VERTEX_4:
+ params[0] = ctx->Eval.Map2Vertex4;
+ break;
+ case GL_MAP_COLOR:
+ params[0] = ctx->Pixel.MapColorFlag;
+ break;
+ case GL_MAP_STENCIL:
+ params[0] = ctx->Pixel.MapStencilFlag;
+ break;
+ case GL_MATRIX_MODE:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Transform.MatrixMode);
+ break;
+ case GL_MAX_ATTRIB_STACK_DEPTH:
+ params[0] = INT_TO_BOOLEAN(MAX_ATTRIB_STACK_DEPTH);
+ break;
+ case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH:
+ params[0] = INT_TO_BOOLEAN(MAX_CLIENT_ATTRIB_STACK_DEPTH);
+ break;
+ case GL_MAX_CLIP_PLANES:
+ params[0] = INT_TO_BOOLEAN(ctx->Const.MaxClipPlanes);
+ break;
+ case GL_MAX_ELEMENTS_VERTICES:
+ params[0] = INT_TO_BOOLEAN(ctx->Const.MaxArrayLockSize);
+ break;
+ case GL_MAX_ELEMENTS_INDICES:
+ params[0] = INT_TO_BOOLEAN(ctx->Const.MaxArrayLockSize);
+ break;
+ case GL_MAX_EVAL_ORDER:
+ params[0] = INT_TO_BOOLEAN(MAX_EVAL_ORDER);
+ break;
+ case GL_MAX_LIGHTS:
+ params[0] = INT_TO_BOOLEAN(ctx->Const.MaxLights);
+ break;
+ case GL_MAX_LIST_NESTING:
+ params[0] = INT_TO_BOOLEAN(MAX_LIST_NESTING);
+ break;
+ case GL_MAX_MODELVIEW_STACK_DEPTH:
+ params[0] = INT_TO_BOOLEAN(MAX_MODELVIEW_STACK_DEPTH);
+ break;
+ case GL_MAX_NAME_STACK_DEPTH:
+ params[0] = INT_TO_BOOLEAN(MAX_NAME_STACK_DEPTH);
+ break;
+ case GL_MAX_PIXEL_MAP_TABLE:
+ params[0] = INT_TO_BOOLEAN(MAX_PIXEL_MAP_TABLE);
+ break;
+ case GL_MAX_PROJECTION_STACK_DEPTH:
+ params[0] = INT_TO_BOOLEAN(MAX_PROJECTION_STACK_DEPTH);
+ break;
+ case GL_MAX_TEXTURE_SIZE:
+ params[0] = INT_TO_BOOLEAN(1 << (ctx->Const.MaxTextureLevels - 1));
+ break;
+ case GL_MAX_3D_TEXTURE_SIZE:
+ params[0] = INT_TO_BOOLEAN(1 << (ctx->Const.Max3DTextureLevels - 1));
+ break;
+ case GL_MAX_TEXTURE_STACK_DEPTH:
+ params[0] = INT_TO_BOOLEAN(MAX_TEXTURE_STACK_DEPTH);
+ break;
+ case GL_MAX_VIEWPORT_DIMS:
+ params[0] = INT_TO_BOOLEAN(ctx->Const.MaxViewportWidth);
+ params[1] = INT_TO_BOOLEAN(ctx->Const.MaxViewportHeight);
+ break;
+ case GL_MODELVIEW_MATRIX:
+ {
+ const GLfloat *matrix = ctx->ModelviewMatrixStack.Top->m;
+ params[0] = FLOAT_TO_BOOLEAN(matrix[0]);
+ params[1] = FLOAT_TO_BOOLEAN(matrix[1]);
+ params[2] = FLOAT_TO_BOOLEAN(matrix[2]);
+ params[3] = FLOAT_TO_BOOLEAN(matrix[3]);
+ params[4] = FLOAT_TO_BOOLEAN(matrix[4]);
+ params[5] = FLOAT_TO_BOOLEAN(matrix[5]);
+ params[6] = FLOAT_TO_BOOLEAN(matrix[6]);
+ params[7] = FLOAT_TO_BOOLEAN(matrix[7]);
+ params[8] = FLOAT_TO_BOOLEAN(matrix[8]);
+ params[9] = FLOAT_TO_BOOLEAN(matrix[9]);
+ params[10] = FLOAT_TO_BOOLEAN(matrix[10]);
+ params[11] = FLOAT_TO_BOOLEAN(matrix[11]);
+ params[12] = FLOAT_TO_BOOLEAN(matrix[12]);
+ params[13] = FLOAT_TO_BOOLEAN(matrix[13]);
+ params[14] = FLOAT_TO_BOOLEAN(matrix[14]);
+ params[15] = FLOAT_TO_BOOLEAN(matrix[15]);
+ }
+ break;
+ case GL_MODELVIEW_STACK_DEPTH:
+ params[0] = INT_TO_BOOLEAN(ctx->ModelviewMatrixStack.Depth + 1);
+ break;
+ case GL_NAME_STACK_DEPTH:
+ params[0] = INT_TO_BOOLEAN(ctx->Select.NameStackDepth);
+ break;
+ case GL_NORMALIZE:
+ params[0] = ctx->Transform.Normalize;
+ break;
+ case GL_PACK_ALIGNMENT:
+ params[0] = INT_TO_BOOLEAN(ctx->Pack.Alignment);
+ break;
+ case GL_PACK_LSB_FIRST:
+ params[0] = ctx->Pack.LsbFirst;
+ break;
+ case GL_PACK_ROW_LENGTH:
+ params[0] = INT_TO_BOOLEAN(ctx->Pack.RowLength);
+ break;
+ case GL_PACK_SKIP_PIXELS:
+ params[0] = INT_TO_BOOLEAN(ctx->Pack.SkipPixels);
+ break;
+ case GL_PACK_SKIP_ROWS:
+ params[0] = INT_TO_BOOLEAN(ctx->Pack.SkipRows);
+ break;
+ case GL_PACK_SWAP_BYTES:
+ params[0] = ctx->Pack.SwapBytes;
+ break;
+ case GL_PACK_SKIP_IMAGES_EXT:
+ params[0] = INT_TO_BOOLEAN(ctx->Pack.SkipImages);
+ break;
+ case GL_PACK_IMAGE_HEIGHT_EXT:
+ params[0] = INT_TO_BOOLEAN(ctx->Pack.ImageHeight);
+ break;
+ case GL_PACK_INVERT_MESA:
+ params[0] = ctx->Pack.Invert;
+ break;
+ case GL_PERSPECTIVE_CORRECTION_HINT:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Hint.PerspectiveCorrection);
+ break;
+ case GL_PIXEL_MAP_A_TO_A_SIZE:
+ params[0] = INT_TO_BOOLEAN(ctx->Pixel.MapAtoAsize);
+ break;
+ case GL_PIXEL_MAP_B_TO_B_SIZE:
+ params[0] = INT_TO_BOOLEAN(ctx->Pixel.MapBtoBsize);
+ break;
+ case GL_PIXEL_MAP_G_TO_G_SIZE:
+ params[0] = INT_TO_BOOLEAN(ctx->Pixel.MapGtoGsize);
+ break;
+ case GL_PIXEL_MAP_I_TO_A_SIZE:
+ params[0] = INT_TO_BOOLEAN(ctx->Pixel.MapItoAsize);
+ break;
+ case GL_PIXEL_MAP_I_TO_B_SIZE:
+ params[0] = INT_TO_BOOLEAN(ctx->Pixel.MapItoBsize);
+ break;
+ case GL_PIXEL_MAP_I_TO_G_SIZE:
+ params[0] = INT_TO_BOOLEAN(ctx->Pixel.MapItoGsize);
+ break;
+ case GL_PIXEL_MAP_I_TO_I_SIZE:
+ params[0] = INT_TO_BOOLEAN(ctx->Pixel.MapItoIsize);
+ break;
+ case GL_PIXEL_MAP_I_TO_R_SIZE:
+ params[0] = INT_TO_BOOLEAN(ctx->Pixel.MapItoRsize);
+ break;
+ case GL_PIXEL_MAP_R_TO_R_SIZE:
+ params[0] = INT_TO_BOOLEAN(ctx->Pixel.MapRtoRsize);
+ break;
+ case GL_PIXEL_MAP_S_TO_S_SIZE:
+ params[0] = INT_TO_BOOLEAN(ctx->Pixel.MapStoSsize);
+ break;
+ case GL_POINT_SIZE:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Point.Size);
+ break;
+ case GL_POINT_SIZE_GRANULARITY:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Const.PointSizeGranularity);
+ break;
+ case GL_POINT_SIZE_RANGE:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Const.MinPointSizeAA);
+ params[1] = FLOAT_TO_BOOLEAN(ctx->Const.MaxPointSizeAA);
+ break;
+ case GL_ALIASED_POINT_SIZE_RANGE:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Const.MinPointSize);
+ params[1] = FLOAT_TO_BOOLEAN(ctx->Const.MaxPointSize);
+ break;
+ case GL_POINT_SMOOTH:
+ params[0] = ctx->Point.SmoothFlag;
+ break;
+ case GL_POINT_SMOOTH_HINT:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Hint.PointSmooth);
+ break;
+ case GL_POINT_SIZE_MIN_EXT:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Point.MinSize);
+ break;
+ case GL_POINT_SIZE_MAX_EXT:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Point.MaxSize);
+ break;
+ case GL_POINT_FADE_THRESHOLD_SIZE_EXT:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Point.Threshold);
+ break;
+ case GL_DISTANCE_ATTENUATION_EXT:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Point.Params[0]);
+ params[1] = FLOAT_TO_BOOLEAN(ctx->Point.Params[1]);
+ params[2] = FLOAT_TO_BOOLEAN(ctx->Point.Params[2]);
+ break;
+ case GL_POLYGON_MODE:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Polygon.FrontMode);
+ params[1] = ENUM_TO_BOOLEAN(ctx->Polygon.BackMode);
+ break;
+ case GL_POLYGON_OFFSET_BIAS_EXT:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Polygon.OffsetUnits);
+ break;
+ case GL_POLYGON_OFFSET_FACTOR:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Polygon.OffsetFactor );
+ break;
+ case GL_POLYGON_OFFSET_UNITS:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Polygon.OffsetUnits );
+ break;
+ case GL_POLYGON_SMOOTH:
+ params[0] = ctx->Polygon.SmoothFlag;
+ break;
+ case GL_POLYGON_SMOOTH_HINT:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Hint.PolygonSmooth);
+ break;
+ case GL_POLYGON_STIPPLE:
+ params[0] = ctx->Polygon.StippleFlag;
+ break;
+ case GL_PROJECTION_MATRIX:
+ {
+ const GLfloat *matrix = ctx->ProjectionMatrixStack.Top->m;
+ params[0] = FLOAT_TO_BOOLEAN(matrix[0]);
+ params[1] = FLOAT_TO_BOOLEAN(matrix[1]);
+ params[2] = FLOAT_TO_BOOLEAN(matrix[2]);
+ params[3] = FLOAT_TO_BOOLEAN(matrix[3]);
+ params[4] = FLOAT_TO_BOOLEAN(matrix[4]);
+ params[5] = FLOAT_TO_BOOLEAN(matrix[5]);
+ params[6] = FLOAT_TO_BOOLEAN(matrix[6]);
+ params[7] = FLOAT_TO_BOOLEAN(matrix[7]);
+ params[8] = FLOAT_TO_BOOLEAN(matrix[8]);
+ params[9] = FLOAT_TO_BOOLEAN(matrix[9]);
+ params[10] = FLOAT_TO_BOOLEAN(matrix[10]);
+ params[11] = FLOAT_TO_BOOLEAN(matrix[11]);
+ params[12] = FLOAT_TO_BOOLEAN(matrix[12]);
+ params[13] = FLOAT_TO_BOOLEAN(matrix[13]);
+ params[14] = FLOAT_TO_BOOLEAN(matrix[14]);
+ params[15] = FLOAT_TO_BOOLEAN(matrix[15]);
+ }
+ break;
+ case GL_PROJECTION_STACK_DEPTH:
+ params[0] = INT_TO_BOOLEAN(ctx->ProjectionMatrixStack.Depth + 1);
+ break;
+ case GL_READ_BUFFER:
+ params[0] = ENUM_TO_BOOLEAN(ctx->ReadBuffer->ColorReadBuffer);
+ break;
+ case GL_RED_BIAS:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.RedBias);
+ break;
+ case GL_RED_BITS:
+ params[0] = INT_TO_BOOLEAN( ctx->DrawBuffer->Visual.redBits );
+ break;
+ case GL_RED_SCALE:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.RedScale);
+ break;
+ case GL_RENDER_MODE:
+ params[0] = ENUM_TO_BOOLEAN(ctx->RenderMode);
+ break;
+ case GL_RESCALE_NORMAL:
+ params[0] = ctx->Transform.RescaleNormals;
+ break;
+ case GL_RGBA_MODE:
+ params[0] = ctx->DrawBuffer->Visual.rgbMode;
+ break;
+ case GL_SCISSOR_BOX:
+ params[0] = INT_TO_BOOLEAN(ctx->Scissor.X);
+ params[1] = INT_TO_BOOLEAN(ctx->Scissor.Y);
+ params[2] = INT_TO_BOOLEAN(ctx->Scissor.Width);
+ params[3] = INT_TO_BOOLEAN(ctx->Scissor.Height);
+ break;
+ case GL_SCISSOR_TEST:
+ params[0] = ctx->Scissor.Enabled;
+ break;
+ case GL_SELECTION_BUFFER_SIZE:
+ params[0] = INT_TO_BOOLEAN(ctx->Select.BufferSize);
+ break;
+ case GL_SHADE_MODEL:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Light.ShadeModel);
+ break;
+ case GL_SHARED_TEXTURE_PALETTE_EXT:
+ params[0] = ctx->Texture.SharedPalette;
+ break;
+ case GL_STENCIL_BITS:
+ params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.stencilBits);
+ break;
+ case GL_STENCIL_CLEAR_VALUE:
+ params[0] = INT_TO_BOOLEAN(ctx->Stencil.Clear);
+ break;
+ case GL_STENCIL_FAIL:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Stencil.FailFunc[ctx->Stencil.ActiveFace]);
+ break;
+ case GL_STENCIL_FUNC:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Stencil.Function[ctx->Stencil.ActiveFace]);
+ break;
+ case GL_STENCIL_PASS_DEPTH_FAIL:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Stencil.ZFailFunc[ctx->Stencil.ActiveFace]);
+ break;
+ case GL_STENCIL_PASS_DEPTH_PASS:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Stencil.ZPassFunc[ctx->Stencil.ActiveFace]);
+ break;
+ case GL_STENCIL_REF:
+ params[0] = INT_TO_BOOLEAN(ctx->Stencil.Ref[ctx->Stencil.ActiveFace]);
+ break;
+ case GL_STENCIL_TEST:
+ params[0] = ctx->Stencil.Enabled;
+ break;
+ case GL_STENCIL_VALUE_MASK:
+ params[0] = INT_TO_BOOLEAN(ctx->Stencil.ValueMask[ctx->Stencil.ActiveFace]);
+ break;
+ case GL_STENCIL_WRITEMASK:
+ params[0] = INT_TO_BOOLEAN(ctx->Stencil.WriteMask[ctx->Stencil.ActiveFace]);
+ break;
+ case GL_STEREO:
+ params[0] = ctx->DrawBuffer->Visual.stereoMode;
+ break;
+ case GL_SUBPIXEL_BITS:
+ params[0] = INT_TO_BOOLEAN(ctx->Const.SubPixelBits);
+ break;
+ case GL_TEXTURE_1D:
+ params[0] = _mesa_IsEnabled(GL_TEXTURE_1D);
+ break;
+ case GL_TEXTURE_2D:
+ params[0] = _mesa_IsEnabled(GL_TEXTURE_2D);
+ break;
+ case GL_TEXTURE_3D:
+ params[0] = _mesa_IsEnabled(GL_TEXTURE_3D);
+ break;
+ case GL_TEXTURE_BINDING_1D:
+ params[0] = INT_TO_BOOLEAN(ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current1D->Name);
+ break;
+ case GL_TEXTURE_BINDING_2D:
+ params[0] = INT_TO_BOOLEAN(ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current2D->Name);
+ break;
+ case GL_TEXTURE_BINDING_3D:
+ params[0] = INT_TO_BOOLEAN(ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current3D->Name);
+ break;
+ case GL_TEXTURE_ENV_COLOR:
+ {
+ const GLfloat *color = ctx->Texture.Unit[ctx->Texture.CurrentUnit].EnvColor;
+ params[0] = FLOAT_TO_BOOLEAN(color[0]);
+ params[1] = FLOAT_TO_BOOLEAN(color[1]);
+ params[2] = FLOAT_TO_BOOLEAN(color[2]);
+ params[3] = FLOAT_TO_BOOLEAN(color[3]);
+ }
+ break;
+ case GL_TEXTURE_ENV_MODE:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Texture.Unit[ctx->Texture.CurrentUnit].EnvMode);
+ break;
+ case GL_TEXTURE_GEN_S:
+ params[0] = ((ctx->Texture.Unit[ctx->Texture.CurrentUnit].TexGenEnabled & S_BIT) ? 1 : 0);
+ break;
+ case GL_TEXTURE_GEN_T:
+ params[0] = ((ctx->Texture.Unit[ctx->Texture.CurrentUnit].TexGenEnabled & T_BIT) ? 1 : 0);
+ break;
+ case GL_TEXTURE_GEN_R:
+ params[0] = ((ctx->Texture.Unit[ctx->Texture.CurrentUnit].TexGenEnabled & R_BIT) ? 1 : 0);
+ break;
+ case GL_TEXTURE_GEN_Q:
+ params[0] = ((ctx->Texture.Unit[ctx->Texture.CurrentUnit].TexGenEnabled & Q_BIT) ? 1 : 0);
+ break;
+ case GL_TEXTURE_MATRIX:
+ {
+ const GLfloat *matrix = ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Top->m;
+ params[0] = FLOAT_TO_BOOLEAN(matrix[0]);
+ params[1] = FLOAT_TO_BOOLEAN(matrix[1]);
+ params[2] = FLOAT_TO_BOOLEAN(matrix[2]);
+ params[3] = FLOAT_TO_BOOLEAN(matrix[3]);
+ params[4] = FLOAT_TO_BOOLEAN(matrix[4]);
+ params[5] = FLOAT_TO_BOOLEAN(matrix[5]);
+ params[6] = FLOAT_TO_BOOLEAN(matrix[6]);
+ params[7] = FLOAT_TO_BOOLEAN(matrix[7]);
+ params[8] = FLOAT_TO_BOOLEAN(matrix[8]);
+ params[9] = FLOAT_TO_BOOLEAN(matrix[9]);
+ params[10] = FLOAT_TO_BOOLEAN(matrix[10]);
+ params[11] = FLOAT_TO_BOOLEAN(matrix[11]);
+ params[12] = FLOAT_TO_BOOLEAN(matrix[12]);
+ params[13] = FLOAT_TO_BOOLEAN(matrix[13]);
+ params[14] = FLOAT_TO_BOOLEAN(matrix[14]);
+ params[15] = FLOAT_TO_BOOLEAN(matrix[15]);
+ }
+ break;
+ case GL_TEXTURE_STACK_DEPTH:
+ params[0] = INT_TO_BOOLEAN(ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Depth + 1);
+ break;
+ case GL_UNPACK_ALIGNMENT:
+ params[0] = INT_TO_BOOLEAN(ctx->Unpack.Alignment);
+ break;
+ case GL_UNPACK_LSB_FIRST:
+ params[0] = ctx->Unpack.LsbFirst;
+ break;
+ case GL_UNPACK_ROW_LENGTH:
+ params[0] = INT_TO_BOOLEAN(ctx->Unpack.RowLength);
+ break;
+ case GL_UNPACK_SKIP_PIXELS:
+ params[0] = INT_TO_BOOLEAN(ctx->Unpack.SkipPixels);
+ break;
+ case GL_UNPACK_SKIP_ROWS:
+ params[0] = INT_TO_BOOLEAN(ctx->Unpack.SkipRows);
+ break;
+ case GL_UNPACK_SWAP_BYTES:
+ params[0] = ctx->Unpack.SwapBytes;
+ break;
+ case GL_UNPACK_SKIP_IMAGES_EXT:
+ params[0] = INT_TO_BOOLEAN(ctx->Unpack.SkipImages);
+ break;
+ case GL_UNPACK_IMAGE_HEIGHT_EXT:
+ params[0] = INT_TO_BOOLEAN(ctx->Unpack.ImageHeight);
+ break;
+ case GL_UNPACK_CLIENT_STORAGE_APPLE:
+ params[0] = ctx->Unpack.ClientStorage;
+ break;
+ case GL_VIEWPORT:
+ params[0] = INT_TO_BOOLEAN(ctx->Viewport.X);
+ params[1] = INT_TO_BOOLEAN(ctx->Viewport.Y);
+ params[2] = INT_TO_BOOLEAN(ctx->Viewport.Width);
+ params[3] = INT_TO_BOOLEAN(ctx->Viewport.Height);
+ break;
+ case GL_ZOOM_X:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.ZoomX);
+ break;
+ case GL_ZOOM_Y:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.ZoomY);
+ break;
+ case GL_VERTEX_ARRAY:
+ params[0] = ctx->Array.Vertex.Enabled;
+ break;
+ case GL_VERTEX_ARRAY_SIZE:
+ params[0] = INT_TO_BOOLEAN(ctx->Array.Vertex.Size);
+ break;
+ case GL_VERTEX_ARRAY_TYPE:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Array.Vertex.Type);
+ break;
+ case GL_VERTEX_ARRAY_STRIDE:
+ params[0] = INT_TO_BOOLEAN(ctx->Array.Vertex.Stride);
+ break;
+ case GL_VERTEX_ARRAY_COUNT_EXT:
+ params[0] = INT_TO_BOOLEAN(0);
+ break;
+ case GL_NORMAL_ARRAY:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Array.Normal.Enabled);
+ break;
+ case GL_NORMAL_ARRAY_TYPE:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Array.Normal.Type);
+ break;
+ case GL_NORMAL_ARRAY_STRIDE:
+ params[0] = INT_TO_BOOLEAN(ctx->Array.Normal.Stride);
+ break;
+ case GL_NORMAL_ARRAY_COUNT_EXT:
+ params[0] = INT_TO_BOOLEAN(0);
+ break;
+ case GL_COLOR_ARRAY:
+ params[0] = ctx->Array.Color.Enabled;
+ break;
+ case GL_COLOR_ARRAY_SIZE:
+ params[0] = INT_TO_BOOLEAN(ctx->Array.Color.Size);
+ break;
+ case GL_COLOR_ARRAY_TYPE:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Array.Color.Type);
+ break;
+ case GL_COLOR_ARRAY_STRIDE:
+ params[0] = INT_TO_BOOLEAN(ctx->Array.Color.Stride);
+ break;
+ case GL_COLOR_ARRAY_COUNT_EXT:
+ params[0] = INT_TO_BOOLEAN(0);
+ break;
+ case GL_INDEX_ARRAY:
+ params[0] = ctx->Array.Index.Enabled;
+ break;
+ case GL_INDEX_ARRAY_TYPE:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Array.Index.Type);
+ break;
+ case GL_INDEX_ARRAY_STRIDE:
+ params[0] = INT_TO_BOOLEAN(ctx->Array.Index.Stride);
+ break;
+ case GL_INDEX_ARRAY_COUNT_EXT:
+ params[0] = INT_TO_BOOLEAN(0);
+ break;
+ case GL_TEXTURE_COORD_ARRAY:
+ params[0] = ctx->Array.TexCoord[ctx->Array.ActiveTexture].Enabled;
+ break;
+ case GL_TEXTURE_COORD_ARRAY_SIZE:
+ params[0] = INT_TO_BOOLEAN(ctx->Array.TexCoord[ctx->Array.ActiveTexture].Size);
+ break;
+ case GL_TEXTURE_COORD_ARRAY_TYPE:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Array.TexCoord[ctx->Array.ActiveTexture].Type);
+ break;
+ case GL_TEXTURE_COORD_ARRAY_STRIDE:
+ params[0] = INT_TO_BOOLEAN(ctx->Array.TexCoord[ctx->Array.ActiveTexture].Stride);
+ break;
+ case GL_TEXTURE_COORD_ARRAY_COUNT_EXT:
+ params[0] = INT_TO_BOOLEAN(0);
+ break;
+ case GL_EDGE_FLAG_ARRAY:
+ params[0] = ctx->Array.EdgeFlag.Enabled;
+ break;
+ case GL_EDGE_FLAG_ARRAY_STRIDE:
+ params[0] = INT_TO_BOOLEAN(ctx->Array.EdgeFlag.Stride);
+ break;
+ case GL_EDGE_FLAG_ARRAY_COUNT_EXT:
+ params[0] = INT_TO_BOOLEAN(0);
+ break;
+ case GL_MAX_TEXTURE_UNITS_ARB:
+ CHECK_EXT1(ARB_multitexture, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(MIN2(ctx->Const.MaxTextureImageUnits, ctx->Const.MaxTextureCoordUnits));
+ break;
+ case GL_ACTIVE_TEXTURE_ARB:
+ CHECK_EXT1(ARB_multitexture, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(GL_TEXTURE0_ARB + ctx->Texture.CurrentUnit);
+ break;
+ case GL_CLIENT_ACTIVE_TEXTURE_ARB:
+ CHECK_EXT1(ARB_multitexture, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(GL_TEXTURE0_ARB + ctx->Array.ActiveTexture);
+ break;
+ case GL_TEXTURE_CUBE_MAP_ARB:
+ CHECK_EXT1(ARB_texture_cube_map, "GetBooleanv");
+ params[0] = _mesa_IsEnabled(GL_TEXTURE_CUBE_MAP_ARB);
+ break;
+ case GL_TEXTURE_BINDING_CUBE_MAP_ARB:
+ CHECK_EXT1(ARB_texture_cube_map, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentCubeMap->Name);
+ break;
+ case GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB:
+ CHECK_EXT1(ARB_texture_cube_map, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN((1 << (ctx->Const.MaxCubeTextureLevels - 1)));
+ break;
+ case GL_TEXTURE_COMPRESSION_HINT_ARB:
+ CHECK_EXT1(ARB_texture_compression, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->Hint.TextureCompression);
+ break;
+ case GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB:
+ CHECK_EXT1(ARB_texture_compression, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(_mesa_get_compressed_formats(ctx, NULL));
+ break;
+ case GL_COMPRESSED_TEXTURE_FORMATS_ARB:
+ CHECK_EXT1(ARB_texture_compression, "GetBooleanv");
+ {
+ GLint formats[100];
+ GLuint i, n = _mesa_get_compressed_formats(ctx, formats);
+ ASSERT(n <= 100);
+ for (i = 0; i < n; i++)
+ params[i] = ENUM_TO_INT(formats[i]);
+ }
+ break;
+ case GL_ARRAY_ELEMENT_LOCK_FIRST_EXT:
+ CHECK_EXT1(EXT_compiled_vertex_array, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->Array.LockFirst);
+ break;
+ case GL_ARRAY_ELEMENT_LOCK_COUNT_EXT:
+ CHECK_EXT1(EXT_compiled_vertex_array, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->Array.LockCount);
+ break;
+ case GL_TRANSPOSE_COLOR_MATRIX_ARB:
+ {
+ const GLfloat *matrix = ctx->ColorMatrixStack.Top->m;
+ params[0] = FLOAT_TO_BOOLEAN(matrix[0]);
+ params[1] = FLOAT_TO_BOOLEAN(matrix[4]);
+ params[2] = FLOAT_TO_BOOLEAN(matrix[8]);
+ params[3] = FLOAT_TO_BOOLEAN(matrix[12]);
+ params[4] = FLOAT_TO_BOOLEAN(matrix[1]);
+ params[5] = FLOAT_TO_BOOLEAN(matrix[5]);
+ params[6] = FLOAT_TO_BOOLEAN(matrix[9]);
+ params[7] = FLOAT_TO_BOOLEAN(matrix[13]);
+ params[8] = FLOAT_TO_BOOLEAN(matrix[2]);
+ params[9] = FLOAT_TO_BOOLEAN(matrix[6]);
+ params[10] = FLOAT_TO_BOOLEAN(matrix[10]);
+ params[11] = FLOAT_TO_BOOLEAN(matrix[14]);
+ params[12] = FLOAT_TO_BOOLEAN(matrix[3]);
+ params[13] = FLOAT_TO_BOOLEAN(matrix[7]);
+ params[14] = FLOAT_TO_BOOLEAN(matrix[11]);
+ params[15] = FLOAT_TO_BOOLEAN(matrix[15]);
+ }
+ break;
+ case GL_TRANSPOSE_MODELVIEW_MATRIX_ARB:
+ {
+ const GLfloat *matrix = ctx->ModelviewMatrixStack.Top->m;
+ params[0] = FLOAT_TO_BOOLEAN(matrix[0]);
+ params[1] = FLOAT_TO_BOOLEAN(matrix[4]);
+ params[2] = FLOAT_TO_BOOLEAN(matrix[8]);
+ params[3] = FLOAT_TO_BOOLEAN(matrix[12]);
+ params[4] = FLOAT_TO_BOOLEAN(matrix[1]);
+ params[5] = FLOAT_TO_BOOLEAN(matrix[5]);
+ params[6] = FLOAT_TO_BOOLEAN(matrix[9]);
+ params[7] = FLOAT_TO_BOOLEAN(matrix[13]);
+ params[8] = FLOAT_TO_BOOLEAN(matrix[2]);
+ params[9] = FLOAT_TO_BOOLEAN(matrix[6]);
+ params[10] = FLOAT_TO_BOOLEAN(matrix[10]);
+ params[11] = FLOAT_TO_BOOLEAN(matrix[14]);
+ params[12] = FLOAT_TO_BOOLEAN(matrix[3]);
+ params[13] = FLOAT_TO_BOOLEAN(matrix[7]);
+ params[14] = FLOAT_TO_BOOLEAN(matrix[11]);
+ params[15] = FLOAT_TO_BOOLEAN(matrix[15]);
+ }
+ break;
+ case GL_TRANSPOSE_PROJECTION_MATRIX_ARB:
+ {
+ const GLfloat *matrix = ctx->ProjectionMatrixStack.Top->m;
+ params[0] = FLOAT_TO_BOOLEAN(matrix[0]);
+ params[1] = FLOAT_TO_BOOLEAN(matrix[4]);
+ params[2] = FLOAT_TO_BOOLEAN(matrix[8]);
+ params[3] = FLOAT_TO_BOOLEAN(matrix[12]);
+ params[4] = FLOAT_TO_BOOLEAN(matrix[1]);
+ params[5] = FLOAT_TO_BOOLEAN(matrix[5]);
+ params[6] = FLOAT_TO_BOOLEAN(matrix[9]);
+ params[7] = FLOAT_TO_BOOLEAN(matrix[13]);
+ params[8] = FLOAT_TO_BOOLEAN(matrix[2]);
+ params[9] = FLOAT_TO_BOOLEAN(matrix[6]);
+ params[10] = FLOAT_TO_BOOLEAN(matrix[10]);
+ params[11] = FLOAT_TO_BOOLEAN(matrix[14]);
+ params[12] = FLOAT_TO_BOOLEAN(matrix[3]);
+ params[13] = FLOAT_TO_BOOLEAN(matrix[7]);
+ params[14] = FLOAT_TO_BOOLEAN(matrix[11]);
+ params[15] = FLOAT_TO_BOOLEAN(matrix[15]);
+ }
+ break;
+ case GL_TRANSPOSE_TEXTURE_MATRIX_ARB:
+ {
+ const GLfloat *matrix = ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Top->m;
+ params[0] = FLOAT_TO_BOOLEAN(matrix[0]);
+ params[1] = FLOAT_TO_BOOLEAN(matrix[4]);
+ params[2] = FLOAT_TO_BOOLEAN(matrix[8]);
+ params[3] = FLOAT_TO_BOOLEAN(matrix[12]);
+ params[4] = FLOAT_TO_BOOLEAN(matrix[1]);
+ params[5] = FLOAT_TO_BOOLEAN(matrix[5]);
+ params[6] = FLOAT_TO_BOOLEAN(matrix[9]);
+ params[7] = FLOAT_TO_BOOLEAN(matrix[13]);
+ params[8] = FLOAT_TO_BOOLEAN(matrix[2]);
+ params[9] = FLOAT_TO_BOOLEAN(matrix[6]);
+ params[10] = FLOAT_TO_BOOLEAN(matrix[10]);
+ params[11] = FLOAT_TO_BOOLEAN(matrix[14]);
+ params[12] = FLOAT_TO_BOOLEAN(matrix[3]);
+ params[13] = FLOAT_TO_BOOLEAN(matrix[7]);
+ params[14] = FLOAT_TO_BOOLEAN(matrix[11]);
+ params[15] = FLOAT_TO_BOOLEAN(matrix[15]);
+ }
+ break;
+ case GL_COLOR_MATRIX_SGI:
+ {
+ const GLfloat *matrix = ctx->ColorMatrixStack.Top->m;
+ params[0] = FLOAT_TO_BOOLEAN(matrix[0]);
+ params[1] = FLOAT_TO_BOOLEAN(matrix[1]);
+ params[2] = FLOAT_TO_BOOLEAN(matrix[2]);
+ params[3] = FLOAT_TO_BOOLEAN(matrix[3]);
+ params[4] = FLOAT_TO_BOOLEAN(matrix[4]);
+ params[5] = FLOAT_TO_BOOLEAN(matrix[5]);
+ params[6] = FLOAT_TO_BOOLEAN(matrix[6]);
+ params[7] = FLOAT_TO_BOOLEAN(matrix[7]);
+ params[8] = FLOAT_TO_BOOLEAN(matrix[8]);
+ params[9] = FLOAT_TO_BOOLEAN(matrix[9]);
+ params[10] = FLOAT_TO_BOOLEAN(matrix[10]);
+ params[11] = FLOAT_TO_BOOLEAN(matrix[11]);
+ params[12] = FLOAT_TO_BOOLEAN(matrix[12]);
+ params[13] = FLOAT_TO_BOOLEAN(matrix[13]);
+ params[14] = FLOAT_TO_BOOLEAN(matrix[14]);
+ params[15] = FLOAT_TO_BOOLEAN(matrix[15]);
+ }
+ break;
+ case GL_COLOR_MATRIX_STACK_DEPTH_SGI:
+ params[0] = INT_TO_BOOLEAN(ctx->ColorMatrixStack.Depth + 1);
+ break;
+ case GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI:
+ params[0] = INT_TO_BOOLEAN(MAX_COLOR_STACK_DEPTH);
+ break;
+ case GL_POST_COLOR_MATRIX_RED_SCALE_SGI:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.PostColorMatrixScale[0]);
+ break;
+ case GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.PostColorMatrixScale[1]);
+ break;
+ case GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.PostColorMatrixScale[2]);
+ break;
+ case GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.PostColorMatrixScale[3]);
+ break;
+ case GL_POST_COLOR_MATRIX_RED_BIAS_SGI:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.PostColorMatrixBias[0]);
+ break;
+ case GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.PostColorMatrixBias[1]);
+ break;
+ case GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.PostColorMatrixBias[2]);
+ break;
+ case GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI:
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.PostColorMatrixBias[3]);
+ break;
+ case GL_CONVOLUTION_1D_EXT:
+ CHECK_EXT1(EXT_convolution, "GetBooleanv");
+ params[0] = ctx->Pixel.Convolution1DEnabled;
+ break;
+ case GL_CONVOLUTION_2D_EXT:
+ CHECK_EXT1(EXT_convolution, "GetBooleanv");
+ params[0] = ctx->Pixel.Convolution2DEnabled;
+ break;
+ case GL_SEPARABLE_2D_EXT:
+ CHECK_EXT1(EXT_convolution, "GetBooleanv");
+ params[0] = ctx->Pixel.Separable2DEnabled;
+ break;
+ case GL_POST_CONVOLUTION_RED_SCALE_EXT:
+ CHECK_EXT1(EXT_convolution, "GetBooleanv");
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.PostConvolutionScale[0]);
+ break;
+ case GL_POST_CONVOLUTION_GREEN_SCALE_EXT:
+ CHECK_EXT1(EXT_convolution, "GetBooleanv");
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.PostConvolutionScale[1]);
+ break;
+ case GL_POST_CONVOLUTION_BLUE_SCALE_EXT:
+ CHECK_EXT1(EXT_convolution, "GetBooleanv");
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.PostConvolutionScale[2]);
+ break;
+ case GL_POST_CONVOLUTION_ALPHA_SCALE_EXT:
+ CHECK_EXT1(EXT_convolution, "GetBooleanv");
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.PostConvolutionScale[3]);
+ break;
+ case GL_POST_CONVOLUTION_RED_BIAS_EXT:
+ CHECK_EXT1(EXT_convolution, "GetBooleanv");
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.PostConvolutionBias[0]);
+ break;
+ case GL_POST_CONVOLUTION_GREEN_BIAS_EXT:
+ CHECK_EXT1(EXT_convolution, "GetBooleanv");
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.PostConvolutionBias[1]);
+ break;
+ case GL_POST_CONVOLUTION_BLUE_BIAS_EXT:
+ CHECK_EXT1(EXT_convolution, "GetBooleanv");
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.PostConvolutionBias[2]);
+ break;
+ case GL_POST_CONVOLUTION_ALPHA_BIAS_EXT:
+ CHECK_EXT1(EXT_convolution, "GetBooleanv");
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.PostConvolutionBias[3]);
+ break;
+ case GL_HISTOGRAM:
+ CHECK_EXT1(EXT_histogram, "GetBooleanv");
+ params[0] = ctx->Pixel.HistogramEnabled;
+ break;
+ case GL_MINMAX:
+ CHECK_EXT1(EXT_histogram, "GetBooleanv");
+ params[0] = ctx->Pixel.MinMaxEnabled;
+ break;
+ case GL_COLOR_TABLE_SGI:
+ CHECK_EXT1(SGI_color_table, "GetBooleanv");
+ params[0] = ctx->Pixel.ColorTableEnabled;
+ break;
+ case GL_POST_CONVOLUTION_COLOR_TABLE_SGI:
+ CHECK_EXT1(SGI_color_table, "GetBooleanv");
+ params[0] = ctx->Pixel.PostConvolutionColorTableEnabled;
+ break;
+ case GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI:
+ CHECK_EXT1(SGI_color_table, "GetBooleanv");
+ params[0] = ctx->Pixel.PostColorMatrixColorTableEnabled;
+ break;
+ case GL_TEXTURE_COLOR_TABLE_SGI:
+ CHECK_EXT1(SGI_texture_color_table, "GetBooleanv");
+ params[0] = ctx->Texture.Unit[ctx->Texture.CurrentUnit].ColorTableEnabled;
+ break;
+ case GL_COLOR_SUM_EXT:
+ CHECK_EXT2(EXT_secondary_color, ARB_vertex_program, "GetBooleanv");
+ params[0] = ctx->Fog.ColorSumEnabled;
+ break;
+ case GL_CURRENT_SECONDARY_COLOR_EXT:
+ CHECK_EXT1(EXT_secondary_color, "GetBooleanv");
+ {
+ FLUSH_CURRENT(ctx, 0);
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0]);
+ params[1] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1]);
+ params[2] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2]);
+ params[3] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][3]);
+ }
+ break;
+ case GL_SECONDARY_COLOR_ARRAY_EXT:
+ CHECK_EXT1(EXT_secondary_color, "GetBooleanv");
+ params[0] = ctx->Array.SecondaryColor.Enabled;
+ break;
+ case GL_SECONDARY_COLOR_ARRAY_TYPE_EXT:
+ CHECK_EXT1(EXT_secondary_color, "GetBooleanv");
+ params[0] = ENUM_TO_BOOLEAN(ctx->Array.SecondaryColor.Type);
+ break;
+ case GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT:
+ CHECK_EXT1(EXT_secondary_color, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->Array.SecondaryColor.Stride);
+ break;
+ case GL_SECONDARY_COLOR_ARRAY_SIZE_EXT:
+ CHECK_EXT1(EXT_secondary_color, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->Array.SecondaryColor.Size);
+ break;
+ case GL_CURRENT_FOG_COORDINATE_EXT:
+ CHECK_EXT1(EXT_fog_coord, "GetBooleanv");
+ {
+ FLUSH_CURRENT(ctx, 0);
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_FOG][0]);
+ }
+ break;
+ case GL_FOG_COORDINATE_ARRAY_EXT:
+ CHECK_EXT1(EXT_fog_coord, "GetBooleanv");
+ params[0] = ctx->Array.FogCoord.Enabled;
+ break;
+ case GL_FOG_COORDINATE_ARRAY_TYPE_EXT:
+ CHECK_EXT1(EXT_fog_coord, "GetBooleanv");
+ params[0] = ENUM_TO_BOOLEAN(ctx->Array.FogCoord.Type);
+ break;
+ case GL_FOG_COORDINATE_ARRAY_STRIDE_EXT:
+ CHECK_EXT1(EXT_fog_coord, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->Array.FogCoord.Stride);
+ break;
+ case GL_FOG_COORDINATE_SOURCE_EXT:
+ CHECK_EXT1(EXT_fog_coord, "GetBooleanv");
+ params[0] = ENUM_TO_BOOLEAN(ctx->Fog.FogCoordinateSource);
+ break;
+ case GL_MAX_TEXTURE_LOD_BIAS_EXT:
+ CHECK_EXT1(EXT_texture_lod_bias, "GetBooleanv");
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Const.MaxTextureLodBias);
+ break;
+ case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
+ CHECK_EXT1(EXT_texture_filter_anisotropic, "GetBooleanv");
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Const.MaxTextureMaxAnisotropy);
+ break;
+ case GL_MULTISAMPLE_ARB:
+ CHECK_EXT1(ARB_multisample, "GetBooleanv");
+ params[0] = ctx->Multisample.Enabled;
+ break;
+ case GL_SAMPLE_ALPHA_TO_COVERAGE_ARB:
+ CHECK_EXT1(ARB_multisample, "GetBooleanv");
+ params[0] = ctx->Multisample.SampleAlphaToCoverage;
+ break;
+ case GL_SAMPLE_ALPHA_TO_ONE_ARB:
+ CHECK_EXT1(ARB_multisample, "GetBooleanv");
+ params[0] = ctx->Multisample.SampleAlphaToOne;
+ break;
+ case GL_SAMPLE_COVERAGE_ARB:
+ CHECK_EXT1(ARB_multisample, "GetBooleanv");
+ params[0] = ctx->Multisample.SampleCoverage;
+ break;
+ case GL_SAMPLE_COVERAGE_VALUE_ARB:
+ CHECK_EXT1(ARB_multisample, "GetBooleanv");
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Multisample.SampleCoverageValue);
+ break;
+ case GL_SAMPLE_COVERAGE_INVERT_ARB:
+ CHECK_EXT1(ARB_multisample, "GetBooleanv");
+ params[0] = ctx->Multisample.SampleCoverageInvert;
+ break;
+ case GL_SAMPLE_BUFFERS_ARB:
+ CHECK_EXT1(ARB_multisample, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.sampleBuffers);
+ break;
+ case GL_SAMPLES_ARB:
+ CHECK_EXT1(ARB_multisample, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.samples);
+ break;
+ case GL_RASTER_POSITION_UNCLIPPED_IBM:
+ CHECK_EXT1(IBM_rasterpos_clip, "GetBooleanv");
+ params[0] = ctx->Transform.RasterPositionUnclipped;
+ break;
+ case GL_POINT_SPRITE_NV:
+ CHECK_EXT2(NV_point_sprite, ARB_point_sprite, "GetBooleanv");
+ params[0] = ctx->Point.PointSprite;
+ break;
+ case GL_POINT_SPRITE_R_MODE_NV:
+ CHECK_EXT1(NV_point_sprite, "GetBooleanv");
+ params[0] = ENUM_TO_BOOLEAN(ctx->Point.SpriteRMode);
+ break;
+ case GL_POINT_SPRITE_COORD_ORIGIN:
+ CHECK_EXT2(NV_point_sprite, ARB_point_sprite, "GetBooleanv");
+ params[0] = ENUM_TO_BOOLEAN(ctx->Point.SpriteOrigin);
+ break;
+ case GL_GENERATE_MIPMAP_HINT_SGIS:
+ CHECK_EXT1(SGIS_generate_mipmap, "GetBooleanv");
+ params[0] = ENUM_TO_BOOLEAN(ctx->Hint.GenerateMipmap);
+ break;
+ case GL_VERTEX_PROGRAM_BINDING_NV:
+ CHECK_EXT1(NV_vertex_program, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN((ctx->VertexProgram.Current ? ctx->VertexProgram.Current->Base.Id : 0));
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY0_NV:
+ CHECK_EXT1(NV_vertex_program, "GetBooleanv");
+ params[0] = ctx->Array.VertexAttrib[0].Enabled;
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY1_NV:
+ CHECK_EXT1(NV_vertex_program, "GetBooleanv");
+ params[0] = ctx->Array.VertexAttrib[1].Enabled;
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY2_NV:
+ CHECK_EXT1(NV_vertex_program, "GetBooleanv");
+ params[0] = ctx->Array.VertexAttrib[2].Enabled;
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY3_NV:
+ CHECK_EXT1(NV_vertex_program, "GetBooleanv");
+ params[0] = ctx->Array.VertexAttrib[3].Enabled;
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetBooleanv");
+ params[0] = ctx->Array.VertexAttrib[4].Enabled;
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY5_NV:
+ CHECK_EXT1(NV_vertex_program, "GetBooleanv");
+ params[0] = ctx->Array.VertexAttrib[5].Enabled;
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY6_NV:
+ CHECK_EXT1(NV_vertex_program, "GetBooleanv");
+ params[0] = ctx->Array.VertexAttrib[6].Enabled;
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY7_NV:
+ CHECK_EXT1(NV_vertex_program, "GetBooleanv");
+ params[0] = ctx->Array.VertexAttrib[7].Enabled;
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY8_NV:
+ CHECK_EXT1(NV_vertex_program, "GetBooleanv");
+ params[0] = ctx->Array.VertexAttrib[8].Enabled;
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY9_NV:
+ CHECK_EXT1(NV_vertex_program, "GetBooleanv");
+ params[0] = ctx->Array.VertexAttrib[9].Enabled;
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY10_NV:
+ CHECK_EXT1(NV_vertex_program, "GetBooleanv");
+ params[0] = ctx->Array.VertexAttrib[10].Enabled;
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY11_NV:
+ CHECK_EXT1(NV_vertex_program, "GetBooleanv");
+ params[0] = ctx->Array.VertexAttrib[11].Enabled;
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY12_NV:
+ CHECK_EXT1(NV_vertex_program, "GetBooleanv");
+ params[0] = ctx->Array.VertexAttrib[12].Enabled;
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY13_NV:
+ CHECK_EXT1(NV_vertex_program, "GetBooleanv");
+ params[0] = ctx->Array.VertexAttrib[13].Enabled;
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY14_NV:
+ CHECK_EXT1(NV_vertex_program, "GetBooleanv");
+ params[0] = ctx->Array.VertexAttrib[14].Enabled;
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY15_NV:
+ CHECK_EXT1(NV_vertex_program, "GetBooleanv");
+ params[0] = ctx->Array.VertexAttrib[15].Enabled;
+ break;
+ case GL_MAP1_VERTEX_ATTRIB0_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetBooleanv");
+ params[0] = ctx->Eval.Map1Attrib[0];
+ break;
+ case GL_MAP1_VERTEX_ATTRIB1_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetBooleanv");
+ params[0] = ctx->Eval.Map1Attrib[1];
+ break;
+ case GL_MAP1_VERTEX_ATTRIB2_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetBooleanv");
+ params[0] = ctx->Eval.Map1Attrib[2];
+ break;
+ case GL_MAP1_VERTEX_ATTRIB3_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetBooleanv");
+ params[0] = ctx->Eval.Map1Attrib[3];
+ break;
+ case GL_MAP1_VERTEX_ATTRIB4_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetBooleanv");
+ params[0] = ctx->Eval.Map1Attrib[4];
+ break;
+ case GL_MAP1_VERTEX_ATTRIB5_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetBooleanv");
+ params[0] = ctx->Eval.Map1Attrib[5];
+ break;
+ case GL_MAP1_VERTEX_ATTRIB6_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetBooleanv");
+ params[0] = ctx->Eval.Map1Attrib[6];
+ break;
+ case GL_MAP1_VERTEX_ATTRIB7_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetBooleanv");
+ params[0] = ctx->Eval.Map1Attrib[7];
+ break;
+ case GL_MAP1_VERTEX_ATTRIB8_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetBooleanv");
+ params[0] = ctx->Eval.Map1Attrib[8];
+ break;
+ case GL_MAP1_VERTEX_ATTRIB9_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetBooleanv");
+ params[0] = ctx->Eval.Map1Attrib[9];
+ break;
+ case GL_MAP1_VERTEX_ATTRIB10_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetBooleanv");
+ params[0] = ctx->Eval.Map1Attrib[10];
+ break;
+ case GL_MAP1_VERTEX_ATTRIB11_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetBooleanv");
+ params[0] = ctx->Eval.Map1Attrib[11];
+ break;
+ case GL_MAP1_VERTEX_ATTRIB12_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetBooleanv");
+ params[0] = ctx->Eval.Map1Attrib[12];
+ break;
+ case GL_MAP1_VERTEX_ATTRIB13_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetBooleanv");
+ params[0] = ctx->Eval.Map1Attrib[13];
+ break;
+ case GL_MAP1_VERTEX_ATTRIB14_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetBooleanv");
+ params[0] = ctx->Eval.Map1Attrib[14];
+ break;
+ case GL_MAP1_VERTEX_ATTRIB15_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetBooleanv");
+ params[0] = ctx->Eval.Map1Attrib[15];
+ break;
+ case GL_FRAGMENT_PROGRAM_NV:
+ CHECK_EXT1(NV_fragment_program, "GetBooleanv");
+ params[0] = ctx->FragmentProgram.Enabled;
+ break;
+ case GL_FRAGMENT_PROGRAM_BINDING_NV:
+ CHECK_EXT1(NV_fragment_program, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->FragmentProgram.Current ? ctx->FragmentProgram.Current->Base.Id : 0);
+ break;
+ case GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV:
+ CHECK_EXT1(NV_fragment_program, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(MAX_NV_FRAGMENT_PROGRAM_PARAMS);
+ break;
+ case GL_TEXTURE_RECTANGLE_NV:
+ CHECK_EXT1(NV_texture_rectangle, "GetBooleanv");
+ params[0] = _mesa_IsEnabled(GL_TEXTURE_RECTANGLE_NV);
+ break;
+ case GL_TEXTURE_BINDING_RECTANGLE_NV:
+ CHECK_EXT1(NV_texture_rectangle, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentRect->Name);
+ break;
+ case GL_MAX_RECTANGLE_TEXTURE_SIZE_NV:
+ CHECK_EXT1(NV_texture_rectangle, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->Const.MaxTextureRectSize);
+ break;
+ case GL_STENCIL_TEST_TWO_SIDE_EXT:
+ CHECK_EXT1(EXT_stencil_two_side, "GetBooleanv");
+ params[0] = ctx->Stencil.TestTwoSide;
+ break;
+ case GL_ACTIVE_STENCIL_FACE_EXT:
+ CHECK_EXT1(EXT_stencil_two_side, "GetBooleanv");
+ params[0] = ENUM_TO_BOOLEAN(ctx->Stencil.ActiveFace ? GL_BACK : GL_FRONT);
+ break;
+ case GL_MAX_SHININESS_NV:
+ CHECK_EXT1(NV_light_max_exponent, "GetBooleanv");
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Const.MaxShininess);
+ break;
+ case GL_MAX_SPOT_EXPONENT_NV:
+ CHECK_EXT1(NV_light_max_exponent, "GetBooleanv");
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Const.MaxSpotExponent);
+ break;
+ case GL_ARRAY_BUFFER_BINDING_ARB:
+ CHECK_EXT1(ARB_vertex_buffer_object, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->Array.ArrayBufferObj->Name);
+ break;
+ case GL_VERTEX_ARRAY_BUFFER_BINDING_ARB:
+ CHECK_EXT1(ARB_vertex_buffer_object, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->Array.Vertex.BufferObj->Name);
+ break;
+ case GL_NORMAL_ARRAY_BUFFER_BINDING_ARB:
+ CHECK_EXT1(ARB_vertex_buffer_object, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->Array.Normal.BufferObj->Name);
+ break;
+ case GL_COLOR_ARRAY_BUFFER_BINDING_ARB:
+ CHECK_EXT1(ARB_vertex_buffer_object, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->Array.Color.BufferObj->Name);
+ break;
+ case GL_INDEX_ARRAY_BUFFER_BINDING_ARB:
+ CHECK_EXT1(ARB_vertex_buffer_object, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->Array.Index.BufferObj->Name);
+ break;
+ case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB:
+ CHECK_EXT1(ARB_vertex_buffer_object, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->Array.TexCoord[ctx->Array.ActiveTexture].BufferObj->Name);
+ break;
+ case GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB:
+ CHECK_EXT1(ARB_vertex_buffer_object, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->Array.EdgeFlag.BufferObj->Name);
+ break;
+ case GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB:
+ CHECK_EXT1(ARB_vertex_buffer_object, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->Array.SecondaryColor.BufferObj->Name);
+ break;
+ case GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB:
+ CHECK_EXT1(ARB_vertex_buffer_object, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->Array.FogCoord.BufferObj->Name);
+ break;
+ case GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB:
+ CHECK_EXT1(ARB_vertex_buffer_object, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->Array.ElementArrayBufferObj->Name);
+ break;
+ case GL_PIXEL_PACK_BUFFER_BINDING_EXT:
+ CHECK_EXT1(EXT_pixel_buffer_object, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->Pack.BufferObj->Name);
+ break;
+ case GL_PIXEL_UNPACK_BUFFER_BINDING_EXT:
+ CHECK_EXT1(EXT_pixel_buffer_object, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->Unpack.BufferObj->Name);
+ break;
+ case GL_VERTEX_PROGRAM_ARB:
+ CHECK_EXT2(ARB_vertex_program, NV_vertex_program, "GetBooleanv");
+ params[0] = ctx->VertexProgram.Enabled;
+ break;
+ case GL_VERTEX_PROGRAM_POINT_SIZE_ARB:
+ CHECK_EXT2(ARB_vertex_program, NV_vertex_program, "GetBooleanv");
+ params[0] = ctx->VertexProgram.PointSizeEnabled;
+ break;
+ case GL_VERTEX_PROGRAM_TWO_SIDE_ARB:
+ CHECK_EXT2(ARB_vertex_program, NV_vertex_program, "GetBooleanv");
+ params[0] = ctx->VertexProgram.TwoSideEnabled;
+ break;
+ case GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB:
+ CHECK_EXT3(ARB_vertex_program, ARB_fragment_program, NV_vertex_program, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->Const.MaxProgramMatrixStackDepth);
+ break;
+ case GL_MAX_PROGRAM_MATRICES_ARB:
+ CHECK_EXT3(ARB_vertex_program, ARB_fragment_program, NV_vertex_program, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->Const.MaxProgramMatrices);
+ break;
+ case GL_CURRENT_MATRIX_STACK_DEPTH_ARB:
+ CHECK_EXT3(ARB_vertex_program, ARB_fragment_program, NV_vertex_program, "GetBooleanv");
+ params[0] = ctx->CurrentStack->Depth + 1;
+ break;
+ case GL_CURRENT_MATRIX_ARB:
+ CHECK_EXT3(ARB_vertex_program, ARB_fragment_program, NV_fragment_program, "GetBooleanv");
+ {
+ const GLfloat *matrix = ctx->CurrentStack->Top->m;
+ params[0] = FLOAT_TO_BOOLEAN(matrix[0]);
+ params[1] = FLOAT_TO_BOOLEAN(matrix[1]);
+ params[2] = FLOAT_TO_BOOLEAN(matrix[2]);
+ params[3] = FLOAT_TO_BOOLEAN(matrix[3]);
+ params[4] = FLOAT_TO_BOOLEAN(matrix[4]);
+ params[5] = FLOAT_TO_BOOLEAN(matrix[5]);
+ params[6] = FLOAT_TO_BOOLEAN(matrix[6]);
+ params[7] = FLOAT_TO_BOOLEAN(matrix[7]);
+ params[8] = FLOAT_TO_BOOLEAN(matrix[8]);
+ params[9] = FLOAT_TO_BOOLEAN(matrix[9]);
+ params[10] = FLOAT_TO_BOOLEAN(matrix[10]);
+ params[11] = FLOAT_TO_BOOLEAN(matrix[11]);
+ params[12] = FLOAT_TO_BOOLEAN(matrix[12]);
+ params[13] = FLOAT_TO_BOOLEAN(matrix[13]);
+ params[14] = FLOAT_TO_BOOLEAN(matrix[14]);
+ params[15] = FLOAT_TO_BOOLEAN(matrix[15]);
+ }
+ break;
+ case GL_TRANSPOSE_CURRENT_MATRIX_ARB:
+ CHECK_EXT2(ARB_vertex_program, ARB_fragment_program, "GetBooleanv");
+ {
+ const GLfloat *matrix = ctx->CurrentStack->Top->m;
+ params[0] = FLOAT_TO_BOOLEAN(matrix[0]);
+ params[1] = FLOAT_TO_BOOLEAN(matrix[4]);
+ params[2] = FLOAT_TO_BOOLEAN(matrix[8]);
+ params[3] = FLOAT_TO_BOOLEAN(matrix[12]);
+ params[4] = FLOAT_TO_BOOLEAN(matrix[1]);
+ params[5] = FLOAT_TO_BOOLEAN(matrix[5]);
+ params[6] = FLOAT_TO_BOOLEAN(matrix[9]);
+ params[7] = FLOAT_TO_BOOLEAN(matrix[13]);
+ params[8] = FLOAT_TO_BOOLEAN(matrix[2]);
+ params[9] = FLOAT_TO_BOOLEAN(matrix[6]);
+ params[10] = FLOAT_TO_BOOLEAN(matrix[10]);
+ params[11] = FLOAT_TO_BOOLEAN(matrix[14]);
+ params[12] = FLOAT_TO_BOOLEAN(matrix[3]);
+ params[13] = FLOAT_TO_BOOLEAN(matrix[7]);
+ params[14] = FLOAT_TO_BOOLEAN(matrix[11]);
+ params[15] = FLOAT_TO_BOOLEAN(matrix[15]);
+ }
+ break;
+ case GL_MAX_VERTEX_ATTRIBS_ARB:
+ CHECK_EXT1(ARB_vertex_program, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->Const.VertexProgram.MaxAttribs);
+ break;
+ case GL_PROGRAM_ERROR_POSITION_ARB:
+ CHECK_EXT4(NV_vertex_program, ARB_vertex_program, NV_fragment_program, ARB_fragment_program, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->Program.ErrorPos);
+ break;
+ case GL_FRAGMENT_PROGRAM_ARB:
+ CHECK_EXT1(ARB_fragment_program, "GetBooleanv");
+ params[0] = ctx->FragmentProgram.Enabled;
+ break;
+ case GL_MAX_TEXTURE_COORDS_ARB:
+ CHECK_EXT2(ARB_fragment_program, NV_fragment_program, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->Const.MaxTextureCoordUnits);
+ break;
+ case GL_MAX_TEXTURE_IMAGE_UNITS_ARB:
+ CHECK_EXT2(ARB_fragment_program, NV_fragment_program, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->Const.MaxTextureImageUnits);
+ break;
+ case GL_DEPTH_BOUNDS_TEST_EXT:
+ CHECK_EXT1(EXT_depth_bounds_test, "GetBooleanv");
+ params[0] = ctx->Depth.BoundsTest;
+ break;
+ case GL_DEPTH_BOUNDS_EXT:
+ CHECK_EXT1(EXT_depth_bounds_test, "GetBooleanv");
+ params[0] = FLOAT_TO_BOOLEAN(ctx->Depth.BoundsMin);
+ params[1] = FLOAT_TO_BOOLEAN(ctx->Depth.BoundsMax);
+ break;
+ case GL_FRAGMENT_PROGRAM_CALLBACK_MESA:
+ CHECK_EXT1(MESA_program_debug, "GetBooleanv");
+ params[0] = ctx->FragmentProgram.CallbackEnabled;
+ break;
+ case GL_VERTEX_PROGRAM_CALLBACK_MESA:
+ CHECK_EXT1(MESA_program_debug, "GetBooleanv");
+ params[0] = ctx->VertexProgram.CallbackEnabled;
+ break;
+ case GL_FRAGMENT_PROGRAM_POSITION_MESA:
+ CHECK_EXT1(MESA_program_debug, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->FragmentProgram.CurrentPosition);
+ break;
+ case GL_VERTEX_PROGRAM_POSITION_MESA:
+ CHECK_EXT1(MESA_program_debug, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->VertexProgram.CurrentPosition);
+ break;
+ case GL_MAX_DRAW_BUFFERS_ARB:
+ CHECK_EXT1(ARB_draw_buffers, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->Const.MaxDrawBuffers);
+ break;
+ case GL_DRAW_BUFFER0_ARB:
+ CHECK_EXT1(ARB_draw_buffers, "GetBooleanv");
+ params[0] = ENUM_TO_BOOLEAN(ctx->DrawBuffer->ColorDrawBuffer[0]);
+ break;
+ case GL_DRAW_BUFFER1_ARB:
+ CHECK_EXT1(ARB_draw_buffers, "GetBooleanv");
+ {
+ GLenum buffer;
+ if (pname - GL_DRAW_BUFFER0_ARB >= ctx->Const.MaxDrawBuffers) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGet(GL_DRAW_BUFFERx_ARB)");
+ return;
+ }
+ buffer = ctx->DrawBuffer->ColorDrawBuffer[1];
+ params[0] = ENUM_TO_BOOLEAN(buffer);
+ }
+ break;
+ case GL_DRAW_BUFFER2_ARB:
+ CHECK_EXT1(ARB_draw_buffers, "GetBooleanv");
+ {
+ GLenum buffer;
+ if (pname - GL_DRAW_BUFFER0_ARB >= ctx->Const.MaxDrawBuffers) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGet(GL_DRAW_BUFFERx_ARB)");
+ return;
+ }
+ buffer = ctx->DrawBuffer->ColorDrawBuffer[2];
+ params[0] = ENUM_TO_BOOLEAN(buffer);
+ }
+ break;
+ case GL_DRAW_BUFFER3_ARB:
+ CHECK_EXT1(ARB_draw_buffers, "GetBooleanv");
+ {
+ GLenum buffer;
+ if (pname - GL_DRAW_BUFFER0_ARB >= ctx->Const.MaxDrawBuffers) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGet(GL_DRAW_BUFFERx_ARB)");
+ return;
+ }
+ buffer = ctx->DrawBuffer->ColorDrawBuffer[3];
+ params[0] = ENUM_TO_BOOLEAN(buffer);
+ }
+ break;
+ case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
+ CHECK_EXT1(OES_read_format, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->Const.ColorReadType);
+ break;
+ case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
+ CHECK_EXT1(OES_read_format, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->Const.ColorReadFormat);
+ break;
+ case GL_NUM_FRAGMENT_REGISTERS_ATI:
+ CHECK_EXT1(ATI_fragment_shader, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(6);
+ break;
+ case GL_NUM_FRAGMENT_CONSTANTS_ATI:
+ CHECK_EXT1(ATI_fragment_shader, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(8);
+ break;
+ case GL_NUM_PASSES_ATI:
+ CHECK_EXT1(ATI_fragment_shader, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(2);
+ break;
+ case GL_NUM_INSTRUCTIONS_PER_PASS_ATI:
+ CHECK_EXT1(ATI_fragment_shader, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(8);
+ break;
+ case GL_NUM_INSTRUCTIONS_TOTAL_ATI:
+ CHECK_EXT1(ATI_fragment_shader, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(16);
+ break;
+ case GL_COLOR_ALPHA_PAIRING_ATI:
+ CHECK_EXT1(ATI_fragment_shader, "GetBooleanv");
+ params[0] = GL_TRUE;
+ break;
+ case GL_NUM_LOOPBACK_COMPONENTS_ATI:
+ CHECK_EXT1(ATI_fragment_shader, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(3);
+ break;
+ case GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI:
+ CHECK_EXT1(ATI_fragment_shader, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(3);
+ break;
+ case GL_STENCIL_BACK_FUNC:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Stencil.Function[1]);
+ break;
+ case GL_STENCIL_BACK_VALUE_MASK:
+ params[0] = INT_TO_BOOLEAN(ctx->Stencil.ValueMask[1]);
+ break;
+ case GL_STENCIL_BACK_REF:
+ params[0] = INT_TO_BOOLEAN(ctx->Stencil.Ref[1]);
+ break;
+ case GL_STENCIL_BACK_FAIL:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Stencil.FailFunc[1]);
+ break;
+ case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Stencil.ZFailFunc[1]);
+ break;
+ case GL_STENCIL_BACK_PASS_DEPTH_PASS:
+ params[0] = ENUM_TO_BOOLEAN(ctx->Stencil.ZPassFunc[1]);
+ break;
+ case GL_FRAMEBUFFER_BINDING_EXT:
+ CHECK_EXT1(EXT_framebuffer_object, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Name);
+ break;
+ case GL_RENDERBUFFER_BINDING_EXT:
+ CHECK_EXT1(EXT_framebuffer_object, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->CurrentRenderbuffer ? ctx->CurrentRenderbuffer->Name : 0);
+ break;
+ case GL_MAX_COLOR_ATTACHMENTS_EXT:
+ CHECK_EXT1(EXT_framebuffer_object, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->Const.MaxColorAttachments);
+ break;
+ case GL_MAX_RENDERBUFFER_SIZE_EXT:
+ CHECK_EXT1(EXT_framebuffer_object, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(ctx->Const.MaxRenderbufferSize);
+ break;
+ case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB:
+ CHECK_EXT1(ARB_fragment_shader, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(MAX_FRAGMENT_UNIFORM_COMPONENTS);
+ break;
+ case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB:
+ CHECK_EXT1(ARB_fragment_shader, "GetBooleanv");
+ params[0] = ENUM_TO_BOOLEAN(ctx->Hint.FragmentShaderDerivative);
+ break;
+ case GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB:
+ CHECK_EXT1(ARB_vertex_shader, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(MAX_VERTEX_UNIFORM_COMPONENTS);
+ break;
+ case GL_MAX_VARYING_FLOATS_ARB:
+ CHECK_EXT1(ARB_vertex_shader, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(MAX_VARYING_FLOATS);
+ break;
+ case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB:
+ CHECK_EXT1(ARB_vertex_shader, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(MAX_VERTEX_TEXTURE_IMAGE_UNITS);
+ break;
+ case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB:
+ CHECK_EXT1(ARB_vertex_shader, "GetBooleanv");
+ params[0] = INT_TO_BOOLEAN(MAX_COMBINED_TEXTURE_IMAGE_UNITS);
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetBooleanv(pname=0x%x)", pname);
+ }
+}
+
+void GLAPIENTRY
+_mesa_GetFloatv( GLenum pname, GLfloat *params )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (!params)
+ return;
+
+ if (ctx->NewState)
+ _mesa_update_state(ctx);
+
+ if (ctx->Driver.GetFloatv &&
+ ctx->Driver.GetFloatv(ctx, pname, params))
+ return;
+
+ switch (pname) {
+ case GL_ACCUM_RED_BITS:
+ params[0] = (GLfloat)(ctx->DrawBuffer->Visual.accumRedBits);
+ break;
+ case GL_ACCUM_GREEN_BITS:
+ params[0] = (GLfloat)(ctx->DrawBuffer->Visual.accumGreenBits);
+ break;
+ case GL_ACCUM_BLUE_BITS:
+ params[0] = (GLfloat)(ctx->DrawBuffer->Visual.accumBlueBits);
+ break;
+ case GL_ACCUM_ALPHA_BITS:
+ params[0] = (GLfloat)(ctx->DrawBuffer->Visual.accumAlphaBits);
+ break;
+ case GL_ACCUM_CLEAR_VALUE:
+ params[0] = ctx->Accum.ClearColor[0];
+ params[1] = ctx->Accum.ClearColor[1];
+ params[2] = ctx->Accum.ClearColor[2];
+ params[3] = ctx->Accum.ClearColor[3];
+ break;
+ case GL_ALPHA_BIAS:
+ params[0] = ctx->Pixel.AlphaBias;
+ break;
+ case GL_ALPHA_BITS:
+ params[0] = (GLfloat)(ctx->DrawBuffer->Visual.alphaBits);
+ break;
+ case GL_ALPHA_SCALE:
+ params[0] = ctx->Pixel.AlphaScale;
+ break;
+ case GL_ALPHA_TEST:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Color.AlphaEnabled);
+ break;
+ case GL_ALPHA_TEST_FUNC:
+ params[0] = ENUM_TO_FLOAT(ctx->Color.AlphaFunc);
+ break;
+ case GL_ALPHA_TEST_REF:
+ params[0] = ctx->Color.AlphaRef;
+ break;
+ case GL_ATTRIB_STACK_DEPTH:
+ params[0] = (GLfloat)(ctx->AttribStackDepth);
+ break;
+ case GL_AUTO_NORMAL:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.AutoNormal);
+ break;
+ case GL_AUX_BUFFERS:
+ params[0] = (GLfloat)(ctx->DrawBuffer->Visual.numAuxBuffers);
+ break;
+ case GL_BLEND:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Color.BlendEnabled);
+ break;
+ case GL_BLEND_DST:
+ params[0] = ENUM_TO_FLOAT(ctx->Color.BlendDstRGB);
+ break;
+ case GL_BLEND_SRC:
+ params[0] = ENUM_TO_FLOAT(ctx->Color.BlendSrcRGB);
+ break;
+ case GL_BLEND_SRC_RGB_EXT:
+ params[0] = ENUM_TO_FLOAT(ctx->Color.BlendSrcRGB);
+ break;
+ case GL_BLEND_DST_RGB_EXT:
+ params[0] = ENUM_TO_FLOAT(ctx->Color.BlendDstRGB);
+ break;
+ case GL_BLEND_SRC_ALPHA_EXT:
+ params[0] = ENUM_TO_FLOAT(ctx->Color.BlendSrcA);
+ break;
+ case GL_BLEND_DST_ALPHA_EXT:
+ params[0] = ENUM_TO_FLOAT(ctx->Color.BlendDstA);
+ break;
+ case GL_BLEND_EQUATION:
+ params[0] = ENUM_TO_FLOAT(ctx->Color.BlendEquationRGB );
+ break;
+ case GL_BLEND_EQUATION_ALPHA_EXT:
+ params[0] = ENUM_TO_FLOAT(ctx->Color.BlendEquationA );
+ break;
+ case GL_BLEND_COLOR_EXT:
+ params[0] = ctx->Color.BlendColor[0];
+ params[1] = ctx->Color.BlendColor[1];
+ params[2] = ctx->Color.BlendColor[2];
+ params[3] = ctx->Color.BlendColor[3];
+ break;
+ case GL_BLUE_BIAS:
+ params[0] = ctx->Pixel.BlueBias;
+ break;
+ case GL_BLUE_BITS:
+ params[0] = (GLfloat)(ctx->DrawBuffer->Visual.blueBits);
+ break;
+ case GL_BLUE_SCALE:
+ params[0] = ctx->Pixel.BlueScale;
+ break;
+ case GL_CLIENT_ATTRIB_STACK_DEPTH:
+ params[0] = (GLfloat)(ctx->ClientAttribStackDepth);
+ break;
+ case GL_CLIP_PLANE0:
+ params[0] = BOOLEAN_TO_FLOAT((ctx->Transform.ClipPlanesEnabled >> 0) & 1);
+ break;
+ case GL_CLIP_PLANE1:
+ params[0] = BOOLEAN_TO_FLOAT((ctx->Transform.ClipPlanesEnabled >> 1) & 1);
+ break;
+ case GL_CLIP_PLANE2:
+ params[0] = BOOLEAN_TO_FLOAT((ctx->Transform.ClipPlanesEnabled >> 2) & 1);
+ break;
+ case GL_CLIP_PLANE3:
+ params[0] = BOOLEAN_TO_FLOAT((ctx->Transform.ClipPlanesEnabled >> 3) & 1);
+ break;
+ case GL_CLIP_PLANE4:
+ params[0] = BOOLEAN_TO_FLOAT((ctx->Transform.ClipPlanesEnabled >> 4) & 1);
+ break;
+ case GL_CLIP_PLANE5:
+ params[0] = BOOLEAN_TO_FLOAT((ctx->Transform.ClipPlanesEnabled >> 5) & 1);
+ break;
+ case GL_COLOR_CLEAR_VALUE:
+ params[0] = ctx->Color.ClearColor[0];
+ params[1] = ctx->Color.ClearColor[1];
+ params[2] = ctx->Color.ClearColor[2];
+ params[3] = ctx->Color.ClearColor[3];
+ break;
+ case GL_COLOR_MATERIAL:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Light.ColorMaterialEnabled);
+ break;
+ case GL_COLOR_MATERIAL_FACE:
+ params[0] = ENUM_TO_FLOAT(ctx->Light.ColorMaterialFace);
+ break;
+ case GL_COLOR_MATERIAL_PARAMETER:
+ params[0] = ENUM_TO_FLOAT(ctx->Light.ColorMaterialMode);
+ break;
+ case GL_COLOR_WRITEMASK:
+ params[0] = (GLfloat)(ctx->Color.ColorMask[RCOMP] ? 1 : 0);
+ params[1] = (GLfloat)(ctx->Color.ColorMask[GCOMP] ? 1 : 0);
+ params[2] = (GLfloat)(ctx->Color.ColorMask[BCOMP] ? 1 : 0);
+ params[3] = (GLfloat)(ctx->Color.ColorMask[ACOMP] ? 1 : 0);
+ break;
+ case GL_CULL_FACE:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Polygon.CullFlag);
+ break;
+ case GL_CULL_FACE_MODE:
+ params[0] = ENUM_TO_FLOAT(ctx->Polygon.CullFaceMode);
+ break;
+ case GL_CURRENT_COLOR:
+ {
+ FLUSH_CURRENT(ctx, 0);
+ params[0] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0];
+ params[1] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1];
+ params[2] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2];
+ params[3] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3];
+ }
+ break;
+ case GL_CURRENT_INDEX:
+ {
+ FLUSH_CURRENT(ctx, 0);
+ params[0] = ctx->Current.Index;
+ }
+ break;
+ case GL_CURRENT_NORMAL:
+ {
+ FLUSH_CURRENT(ctx, 0);
+ params[0] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][0];
+ params[1] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][1];
+ params[2] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][2];
+ }
+ break;
+ case GL_CURRENT_RASTER_COLOR:
+ params[0] = ctx->Current.RasterColor[0];
+ params[1] = ctx->Current.RasterColor[1];
+ params[2] = ctx->Current.RasterColor[2];
+ params[3] = ctx->Current.RasterColor[3];
+ break;
+ case GL_CURRENT_RASTER_DISTANCE:
+ params[0] = ctx->Current.RasterDistance;
+ break;
+ case GL_CURRENT_RASTER_INDEX:
+ params[0] = ctx->Current.RasterIndex;
+ break;
+ case GL_CURRENT_RASTER_POSITION:
+ params[0] = ctx->Current.RasterPos[0];
+ params[1] = ctx->Current.RasterPos[1];
+ params[2] = ctx->Current.RasterPos[2];
+ params[3] = ctx->Current.RasterPos[3];
+ break;
+ case GL_CURRENT_RASTER_TEXTURE_COORDS:
+ {
+ const GLuint texUnit = ctx->Texture.CurrentUnit;
+ params[0] = ctx->Current.RasterTexCoords[texUnit][0];
+ params[1] = ctx->Current.RasterTexCoords[texUnit][1];
+ params[2] = ctx->Current.RasterTexCoords[texUnit][2];
+ params[3] = ctx->Current.RasterTexCoords[texUnit][3];
+ }
+ break;
+ case GL_CURRENT_RASTER_POSITION_VALID:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Current.RasterPosValid);
+ break;
+ case GL_CURRENT_TEXTURE_COORDS:
+ {
+ const GLuint texUnit = ctx->Texture.CurrentUnit;
+ params[0] = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][0];
+ params[1] = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][1];
+ params[2] = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][2];
+ params[3] = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][3];
+ }
+ break;
+ case GL_DEPTH_BIAS:
+ params[0] = ctx->Pixel.DepthBias;
+ break;
+ case GL_DEPTH_BITS:
+ params[0] = (GLfloat)(ctx->DrawBuffer->Visual.depthBits);
+ break;
+ case GL_DEPTH_CLEAR_VALUE:
+ params[0] = ctx->Depth.Clear;
+ break;
+ case GL_DEPTH_FUNC:
+ params[0] = ENUM_TO_FLOAT(ctx->Depth.Func);
+ break;
+ case GL_DEPTH_RANGE:
+ params[0] = ctx->Viewport.Near;
+ params[1] = ctx->Viewport.Far;
+ break;
+ case GL_DEPTH_SCALE:
+ params[0] = ctx->Pixel.DepthScale;
+ break;
+ case GL_DEPTH_TEST:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Depth.Test);
+ break;
+ case GL_DEPTH_WRITEMASK:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Depth.Mask);
+ break;
+ case GL_DITHER:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Color.DitherFlag);
+ break;
+ case GL_DOUBLEBUFFER:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->DrawBuffer->Visual.doubleBufferMode);
+ break;
+ case GL_DRAW_BUFFER:
+ params[0] = ENUM_TO_FLOAT(ctx->DrawBuffer->ColorDrawBuffer[0]);
+ break;
+ case GL_EDGE_FLAG:
+ {
+ FLUSH_CURRENT(ctx, 0);
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Current.EdgeFlag);
+ }
+ break;
+ case GL_FEEDBACK_BUFFER_SIZE:
+ params[0] = (GLfloat)(ctx->Feedback.BufferSize);
+ break;
+ case GL_FEEDBACK_BUFFER_TYPE:
+ params[0] = ENUM_TO_FLOAT(ctx->Feedback.Type);
+ break;
+ case GL_FOG:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Fog.Enabled);
+ break;
+ case GL_FOG_COLOR:
+ params[0] = ctx->Fog.Color[0];
+ params[1] = ctx->Fog.Color[1];
+ params[2] = ctx->Fog.Color[2];
+ params[3] = ctx->Fog.Color[3];
+ break;
+ case GL_FOG_DENSITY:
+ params[0] = ctx->Fog.Density;
+ break;
+ case GL_FOG_END:
+ params[0] = ctx->Fog.End;
+ break;
+ case GL_FOG_HINT:
+ params[0] = ENUM_TO_FLOAT(ctx->Hint.Fog);
+ break;
+ case GL_FOG_INDEX:
+ params[0] = ctx->Fog.Index;
+ break;
+ case GL_FOG_MODE:
+ params[0] = ENUM_TO_FLOAT(ctx->Fog.Mode);
+ break;
+ case GL_FOG_START:
+ params[0] = ctx->Fog.Start;
+ break;
+ case GL_FRONT_FACE:
+ params[0] = ENUM_TO_FLOAT(ctx->Polygon.FrontFace);
+ break;
+ case GL_GREEN_BIAS:
+ params[0] = ctx->Pixel.GreenBias;
+ break;
+ case GL_GREEN_BITS:
+ params[0] = (GLfloat)(ctx->DrawBuffer->Visual.greenBits);
+ break;
+ case GL_GREEN_SCALE:
+ params[0] = ctx->Pixel.GreenScale;
+ break;
+ case GL_INDEX_BITS:
+ params[0] = (GLfloat)(ctx->DrawBuffer->Visual.indexBits);
+ break;
+ case GL_INDEX_CLEAR_VALUE:
+ params[0] = (GLfloat)(ctx->Color.ClearIndex);
+ break;
+ case GL_INDEX_MODE:
+ params[0] = BOOLEAN_TO_FLOAT(!ctx->DrawBuffer->Visual.rgbMode);
+ break;
+ case GL_INDEX_OFFSET:
+ params[0] = (GLfloat)(ctx->Pixel.IndexOffset);
+ break;
+ case GL_INDEX_SHIFT:
+ params[0] = (GLfloat)(ctx->Pixel.IndexShift);
+ break;
+ case GL_INDEX_WRITEMASK:
+ params[0] = (GLfloat)(ctx->Color.IndexMask);
+ break;
+ case GL_LIGHT0:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Light.Light[0].Enabled);
+ break;
+ case GL_LIGHT1:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Light.Light[1].Enabled);
+ break;
+ case GL_LIGHT2:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Light.Light[2].Enabled);
+ break;
+ case GL_LIGHT3:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Light.Light[3].Enabled);
+ break;
+ case GL_LIGHT4:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Light.Light[4].Enabled);
+ break;
+ case GL_LIGHT5:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Light.Light[5].Enabled);
+ break;
+ case GL_LIGHT6:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Light.Light[6].Enabled);
+ break;
+ case GL_LIGHT7:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Light.Light[7].Enabled);
+ break;
+ case GL_LIGHTING:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Light.Enabled);
+ break;
+ case GL_LIGHT_MODEL_AMBIENT:
+ params[0] = ctx->Light.Model.Ambient[0];
+ params[1] = ctx->Light.Model.Ambient[1];
+ params[2] = ctx->Light.Model.Ambient[2];
+ params[3] = ctx->Light.Model.Ambient[3];
+ break;
+ case GL_LIGHT_MODEL_COLOR_CONTROL:
+ params[0] = ENUM_TO_FLOAT(ctx->Light.Model.ColorControl);
+ break;
+ case GL_LIGHT_MODEL_LOCAL_VIEWER:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Light.Model.LocalViewer);
+ break;
+ case GL_LIGHT_MODEL_TWO_SIDE:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Light.Model.TwoSide);
+ break;
+ case GL_LINE_SMOOTH:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Line.SmoothFlag);
+ break;
+ case GL_LINE_SMOOTH_HINT:
+ params[0] = ENUM_TO_FLOAT(ctx->Hint.LineSmooth);
+ break;
+ case GL_LINE_STIPPLE:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Line.StippleFlag);
+ break;
+ case GL_LINE_STIPPLE_PATTERN:
+ params[0] = (GLfloat)(ctx->Line.StipplePattern);
+ break;
+ case GL_LINE_STIPPLE_REPEAT:
+ params[0] = (GLfloat)(ctx->Line.StippleFactor);
+ break;
+ case GL_LINE_WIDTH:
+ params[0] = ctx->Line.Width;
+ break;
+ case GL_LINE_WIDTH_GRANULARITY:
+ params[0] = ctx->Const.LineWidthGranularity;
+ break;
+ case GL_LINE_WIDTH_RANGE:
+ params[0] = ctx->Const.MinLineWidthAA;
+ params[1] = ctx->Const.MaxLineWidthAA;
+ break;
+ case GL_ALIASED_LINE_WIDTH_RANGE:
+ params[0] = ctx->Const.MinLineWidth;
+ params[1] = ctx->Const.MaxLineWidth;
+ break;
+ case GL_LIST_BASE:
+ params[0] = (GLfloat)(ctx->List.ListBase);
+ break;
+ case GL_LIST_INDEX:
+ params[0] = (GLfloat)(ctx->ListState.CurrentListNum);
+ break;
+ case GL_LIST_MODE:
+ {
+ GLenum mode;
+ if (!ctx->CompileFlag)
+ mode = 0;
+ else if (ctx->ExecuteFlag)
+ mode = GL_COMPILE_AND_EXECUTE;
+ else
+ mode = GL_COMPILE;
+ params[0] = ENUM_TO_FLOAT(mode);
+ }
+ break;
+ case GL_INDEX_LOGIC_OP:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Color.IndexLogicOpEnabled);
+ break;
+ case GL_COLOR_LOGIC_OP:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Color.ColorLogicOpEnabled);
+ break;
+ case GL_LOGIC_OP_MODE:
+ params[0] = ENUM_TO_FLOAT(ctx->Color.LogicOp);
+ break;
+ case GL_MAP1_COLOR_4:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Color4);
+ break;
+ case GL_MAP1_GRID_DOMAIN:
+ params[0] = ctx->Eval.MapGrid1u1;
+ params[1] = ctx->Eval.MapGrid1u2;
+ break;
+ case GL_MAP1_GRID_SEGMENTS:
+ params[0] = (GLfloat)(ctx->Eval.MapGrid1un);
+ break;
+ case GL_MAP1_INDEX:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Index);
+ break;
+ case GL_MAP1_NORMAL:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Normal);
+ break;
+ case GL_MAP1_TEXTURE_COORD_1:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1TextureCoord1);
+ break;
+ case GL_MAP1_TEXTURE_COORD_2:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1TextureCoord2);
+ break;
+ case GL_MAP1_TEXTURE_COORD_3:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1TextureCoord3);
+ break;
+ case GL_MAP1_TEXTURE_COORD_4:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1TextureCoord4);
+ break;
+ case GL_MAP1_VERTEX_3:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Vertex3);
+ break;
+ case GL_MAP1_VERTEX_4:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Vertex4);
+ break;
+ case GL_MAP2_COLOR_4:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map2Color4);
+ break;
+ case GL_MAP2_GRID_DOMAIN:
+ params[0] = ctx->Eval.MapGrid2u1;
+ params[1] = ctx->Eval.MapGrid2u2;
+ params[2] = ctx->Eval.MapGrid2v1;
+ params[3] = ctx->Eval.MapGrid2v2;
+ break;
+ case GL_MAP2_GRID_SEGMENTS:
+ params[0] = (GLfloat)(ctx->Eval.MapGrid2un);
+ params[1] = (GLfloat)(ctx->Eval.MapGrid2vn);
+ break;
+ case GL_MAP2_INDEX:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map2Index);
+ break;
+ case GL_MAP2_NORMAL:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map2Normal);
+ break;
+ case GL_MAP2_TEXTURE_COORD_1:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map2TextureCoord1);
+ break;
+ case GL_MAP2_TEXTURE_COORD_2:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map2TextureCoord2);
+ break;
+ case GL_MAP2_TEXTURE_COORD_3:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map2TextureCoord3);
+ break;
+ case GL_MAP2_TEXTURE_COORD_4:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map2TextureCoord4);
+ break;
+ case GL_MAP2_VERTEX_3:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map2Vertex3);
+ break;
+ case GL_MAP2_VERTEX_4:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map2Vertex4);
+ break;
+ case GL_MAP_COLOR:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Pixel.MapColorFlag);
+ break;
+ case GL_MAP_STENCIL:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Pixel.MapStencilFlag);
+ break;
+ case GL_MATRIX_MODE:
+ params[0] = ENUM_TO_FLOAT(ctx->Transform.MatrixMode);
+ break;
+ case GL_MAX_ATTRIB_STACK_DEPTH:
+ params[0] = (GLfloat)(MAX_ATTRIB_STACK_DEPTH);
+ break;
+ case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH:
+ params[0] = (GLfloat)(MAX_CLIENT_ATTRIB_STACK_DEPTH);
+ break;
+ case GL_MAX_CLIP_PLANES:
+ params[0] = (GLfloat)(ctx->Const.MaxClipPlanes);
+ break;
+ case GL_MAX_ELEMENTS_VERTICES:
+ params[0] = (GLfloat)(ctx->Const.MaxArrayLockSize);
+ break;
+ case GL_MAX_ELEMENTS_INDICES:
+ params[0] = (GLfloat)(ctx->Const.MaxArrayLockSize);
+ break;
+ case GL_MAX_EVAL_ORDER:
+ params[0] = (GLfloat)(MAX_EVAL_ORDER);
+ break;
+ case GL_MAX_LIGHTS:
+ params[0] = (GLfloat)(ctx->Const.MaxLights);
+ break;
+ case GL_MAX_LIST_NESTING:
+ params[0] = (GLfloat)(MAX_LIST_NESTING);
+ break;
+ case GL_MAX_MODELVIEW_STACK_DEPTH:
+ params[0] = (GLfloat)(MAX_MODELVIEW_STACK_DEPTH);
+ break;
+ case GL_MAX_NAME_STACK_DEPTH:
+ params[0] = (GLfloat)(MAX_NAME_STACK_DEPTH);
+ break;
+ case GL_MAX_PIXEL_MAP_TABLE:
+ params[0] = (GLfloat)(MAX_PIXEL_MAP_TABLE);
+ break;
+ case GL_MAX_PROJECTION_STACK_DEPTH:
+ params[0] = (GLfloat)(MAX_PROJECTION_STACK_DEPTH);
+ break;
+ case GL_MAX_TEXTURE_SIZE:
+ params[0] = (GLfloat)(1 << (ctx->Const.MaxTextureLevels - 1));
+ break;
+ case GL_MAX_3D_TEXTURE_SIZE:
+ params[0] = (GLfloat)(1 << (ctx->Const.Max3DTextureLevels - 1));
+ break;
+ case GL_MAX_TEXTURE_STACK_DEPTH:
+ params[0] = (GLfloat)(MAX_TEXTURE_STACK_DEPTH);
+ break;
+ case GL_MAX_VIEWPORT_DIMS:
+ params[0] = (GLfloat)(ctx->Const.MaxViewportWidth);
+ params[1] = (GLfloat)(ctx->Const.MaxViewportHeight);
+ break;
+ case GL_MODELVIEW_MATRIX:
+ {
+ const GLfloat *matrix = ctx->ModelviewMatrixStack.Top->m;
+ params[0] = matrix[0];
+ params[1] = matrix[1];
+ params[2] = matrix[2];
+ params[3] = matrix[3];
+ params[4] = matrix[4];
+ params[5] = matrix[5];
+ params[6] = matrix[6];
+ params[7] = matrix[7];
+ params[8] = matrix[8];
+ params[9] = matrix[9];
+ params[10] = matrix[10];
+ params[11] = matrix[11];
+ params[12] = matrix[12];
+ params[13] = matrix[13];
+ params[14] = matrix[14];
+ params[15] = matrix[15];
+ }
+ break;
+ case GL_MODELVIEW_STACK_DEPTH:
+ params[0] = (GLfloat)(ctx->ModelviewMatrixStack.Depth + 1);
+ break;
+ case GL_NAME_STACK_DEPTH:
+ params[0] = (GLfloat)(ctx->Select.NameStackDepth);
+ break;
+ case GL_NORMALIZE:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Transform.Normalize);
+ break;
+ case GL_PACK_ALIGNMENT:
+ params[0] = (GLfloat)(ctx->Pack.Alignment);
+ break;
+ case GL_PACK_LSB_FIRST:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Pack.LsbFirst);
+ break;
+ case GL_PACK_ROW_LENGTH:
+ params[0] = (GLfloat)(ctx->Pack.RowLength);
+ break;
+ case GL_PACK_SKIP_PIXELS:
+ params[0] = (GLfloat)(ctx->Pack.SkipPixels);
+ break;
+ case GL_PACK_SKIP_ROWS:
+ params[0] = (GLfloat)(ctx->Pack.SkipRows);
+ break;
+ case GL_PACK_SWAP_BYTES:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Pack.SwapBytes);
+ break;
+ case GL_PACK_SKIP_IMAGES_EXT:
+ params[0] = (GLfloat)(ctx->Pack.SkipImages);
+ break;
+ case GL_PACK_IMAGE_HEIGHT_EXT:
+ params[0] = (GLfloat)(ctx->Pack.ImageHeight);
+ break;
+ case GL_PACK_INVERT_MESA:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Pack.Invert);
+ break;
+ case GL_PERSPECTIVE_CORRECTION_HINT:
+ params[0] = ENUM_TO_FLOAT(ctx->Hint.PerspectiveCorrection);
+ break;
+ case GL_PIXEL_MAP_A_TO_A_SIZE:
+ params[0] = (GLfloat)(ctx->Pixel.MapAtoAsize);
+ break;
+ case GL_PIXEL_MAP_B_TO_B_SIZE:
+ params[0] = (GLfloat)(ctx->Pixel.MapBtoBsize);
+ break;
+ case GL_PIXEL_MAP_G_TO_G_SIZE:
+ params[0] = (GLfloat)(ctx->Pixel.MapGtoGsize);
+ break;
+ case GL_PIXEL_MAP_I_TO_A_SIZE:
+ params[0] = (GLfloat)(ctx->Pixel.MapItoAsize);
+ break;
+ case GL_PIXEL_MAP_I_TO_B_SIZE:
+ params[0] = (GLfloat)(ctx->Pixel.MapItoBsize);
+ break;
+ case GL_PIXEL_MAP_I_TO_G_SIZE:
+ params[0] = (GLfloat)(ctx->Pixel.MapItoGsize);
+ break;
+ case GL_PIXEL_MAP_I_TO_I_SIZE:
+ params[0] = (GLfloat)(ctx->Pixel.MapItoIsize);
+ break;
+ case GL_PIXEL_MAP_I_TO_R_SIZE:
+ params[0] = (GLfloat)(ctx->Pixel.MapItoRsize);
+ break;
+ case GL_PIXEL_MAP_R_TO_R_SIZE:
+ params[0] = (GLfloat)(ctx->Pixel.MapRtoRsize);
+ break;
+ case GL_PIXEL_MAP_S_TO_S_SIZE:
+ params[0] = (GLfloat)(ctx->Pixel.MapStoSsize);
+ break;
+ case GL_POINT_SIZE:
+ params[0] = ctx->Point.Size;
+ break;
+ case GL_POINT_SIZE_GRANULARITY:
+ params[0] = ctx->Const.PointSizeGranularity;
+ break;
+ case GL_POINT_SIZE_RANGE:
+ params[0] = ctx->Const.MinPointSizeAA;
+ params[1] = ctx->Const.MaxPointSizeAA;
+ break;
+ case GL_ALIASED_POINT_SIZE_RANGE:
+ params[0] = ctx->Const.MinPointSize;
+ params[1] = ctx->Const.MaxPointSize;
+ break;
+ case GL_POINT_SMOOTH:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Point.SmoothFlag);
+ break;
+ case GL_POINT_SMOOTH_HINT:
+ params[0] = ENUM_TO_FLOAT(ctx->Hint.PointSmooth);
+ break;
+ case GL_POINT_SIZE_MIN_EXT:
+ params[0] = ctx->Point.MinSize;
+ break;
+ case GL_POINT_SIZE_MAX_EXT:
+ params[0] = ctx->Point.MaxSize;
+ break;
+ case GL_POINT_FADE_THRESHOLD_SIZE_EXT:
+ params[0] = ctx->Point.Threshold;
+ break;
+ case GL_DISTANCE_ATTENUATION_EXT:
+ params[0] = ctx->Point.Params[0];
+ params[1] = ctx->Point.Params[1];
+ params[2] = ctx->Point.Params[2];
+ break;
+ case GL_POLYGON_MODE:
+ params[0] = ENUM_TO_FLOAT(ctx->Polygon.FrontMode);
+ params[1] = ENUM_TO_FLOAT(ctx->Polygon.BackMode);
+ break;
+ case GL_POLYGON_OFFSET_BIAS_EXT:
+ params[0] = ctx->Polygon.OffsetUnits;
+ break;
+ case GL_POLYGON_OFFSET_FACTOR:
+ params[0] = ctx->Polygon.OffsetFactor ;
+ break;
+ case GL_POLYGON_OFFSET_UNITS:
+ params[0] = ctx->Polygon.OffsetUnits ;
+ break;
+ case GL_POLYGON_SMOOTH:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Polygon.SmoothFlag);
+ break;
+ case GL_POLYGON_SMOOTH_HINT:
+ params[0] = ENUM_TO_FLOAT(ctx->Hint.PolygonSmooth);
+ break;
+ case GL_POLYGON_STIPPLE:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Polygon.StippleFlag);
+ break;
+ case GL_PROJECTION_MATRIX:
+ {
+ const GLfloat *matrix = ctx->ProjectionMatrixStack.Top->m;
+ params[0] = matrix[0];
+ params[1] = matrix[1];
+ params[2] = matrix[2];
+ params[3] = matrix[3];
+ params[4] = matrix[4];
+ params[5] = matrix[5];
+ params[6] = matrix[6];
+ params[7] = matrix[7];
+ params[8] = matrix[8];
+ params[9] = matrix[9];
+ params[10] = matrix[10];
+ params[11] = matrix[11];
+ params[12] = matrix[12];
+ params[13] = matrix[13];
+ params[14] = matrix[14];
+ params[15] = matrix[15];
+ }
+ break;
+ case GL_PROJECTION_STACK_DEPTH:
+ params[0] = (GLfloat)(ctx->ProjectionMatrixStack.Depth + 1);
+ break;
+ case GL_READ_BUFFER:
+ params[0] = ENUM_TO_FLOAT(ctx->ReadBuffer->ColorReadBuffer);
+ break;
+ case GL_RED_BIAS:
+ params[0] = ctx->Pixel.RedBias;
+ break;
+ case GL_RED_BITS:
+ params[0] = (GLfloat)( ctx->DrawBuffer->Visual.redBits );
+ break;
+ case GL_RED_SCALE:
+ params[0] = ctx->Pixel.RedScale;
+ break;
+ case GL_RENDER_MODE:
+ params[0] = ENUM_TO_FLOAT(ctx->RenderMode);
+ break;
+ case GL_RESCALE_NORMAL:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Transform.RescaleNormals);
+ break;
+ case GL_RGBA_MODE:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->DrawBuffer->Visual.rgbMode);
+ break;
+ case GL_SCISSOR_BOX:
+ params[0] = (GLfloat)(ctx->Scissor.X);
+ params[1] = (GLfloat)(ctx->Scissor.Y);
+ params[2] = (GLfloat)(ctx->Scissor.Width);
+ params[3] = (GLfloat)(ctx->Scissor.Height);
+ break;
+ case GL_SCISSOR_TEST:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Scissor.Enabled);
+ break;
+ case GL_SELECTION_BUFFER_SIZE:
+ params[0] = (GLfloat)(ctx->Select.BufferSize);
+ break;
+ case GL_SHADE_MODEL:
+ params[0] = ENUM_TO_FLOAT(ctx->Light.ShadeModel);
+ break;
+ case GL_SHARED_TEXTURE_PALETTE_EXT:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Texture.SharedPalette);
+ break;
+ case GL_STENCIL_BITS:
+ params[0] = (GLfloat)(ctx->DrawBuffer->Visual.stencilBits);
+ break;
+ case GL_STENCIL_CLEAR_VALUE:
+ params[0] = (GLfloat)(ctx->Stencil.Clear);
+ break;
+ case GL_STENCIL_FAIL:
+ params[0] = ENUM_TO_FLOAT(ctx->Stencil.FailFunc[ctx->Stencil.ActiveFace]);
+ break;
+ case GL_STENCIL_FUNC:
+ params[0] = ENUM_TO_FLOAT(ctx->Stencil.Function[ctx->Stencil.ActiveFace]);
+ break;
+ case GL_STENCIL_PASS_DEPTH_FAIL:
+ params[0] = ENUM_TO_FLOAT(ctx->Stencil.ZFailFunc[ctx->Stencil.ActiveFace]);
+ break;
+ case GL_STENCIL_PASS_DEPTH_PASS:
+ params[0] = ENUM_TO_FLOAT(ctx->Stencil.ZPassFunc[ctx->Stencil.ActiveFace]);
+ break;
+ case GL_STENCIL_REF:
+ params[0] = (GLfloat)(ctx->Stencil.Ref[ctx->Stencil.ActiveFace]);
+ break;
+ case GL_STENCIL_TEST:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Stencil.Enabled);
+ break;
+ case GL_STENCIL_VALUE_MASK:
+ params[0] = (GLfloat)(ctx->Stencil.ValueMask[ctx->Stencil.ActiveFace]);
+ break;
+ case GL_STENCIL_WRITEMASK:
+ params[0] = (GLfloat)(ctx->Stencil.WriteMask[ctx->Stencil.ActiveFace]);
+ break;
+ case GL_STEREO:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->DrawBuffer->Visual.stereoMode);
+ break;
+ case GL_SUBPIXEL_BITS:
+ params[0] = (GLfloat)(ctx->Const.SubPixelBits);
+ break;
+ case GL_TEXTURE_1D:
+ params[0] = BOOLEAN_TO_FLOAT(_mesa_IsEnabled(GL_TEXTURE_1D));
+ break;
+ case GL_TEXTURE_2D:
+ params[0] = BOOLEAN_TO_FLOAT(_mesa_IsEnabled(GL_TEXTURE_2D));
+ break;
+ case GL_TEXTURE_3D:
+ params[0] = BOOLEAN_TO_FLOAT(_mesa_IsEnabled(GL_TEXTURE_3D));
+ break;
+ case GL_TEXTURE_BINDING_1D:
+ params[0] = (GLfloat)(ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current1D->Name);
+ break;
+ case GL_TEXTURE_BINDING_2D:
+ params[0] = (GLfloat)(ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current2D->Name);
+ break;
+ case GL_TEXTURE_BINDING_3D:
+ params[0] = (GLfloat)(ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current3D->Name);
+ break;
+ case GL_TEXTURE_ENV_COLOR:
+ {
+ const GLfloat *color = ctx->Texture.Unit[ctx->Texture.CurrentUnit].EnvColor;
+ params[0] = color[0];
+ params[1] = color[1];
+ params[2] = color[2];
+ params[3] = color[3];
+ }
+ break;
+ case GL_TEXTURE_ENV_MODE:
+ params[0] = ENUM_TO_FLOAT(ctx->Texture.Unit[ctx->Texture.CurrentUnit].EnvMode);
+ break;
+ case GL_TEXTURE_GEN_S:
+ params[0] = BOOLEAN_TO_FLOAT(((ctx->Texture.Unit[ctx->Texture.CurrentUnit].TexGenEnabled & S_BIT) ? 1 : 0));
+ break;
+ case GL_TEXTURE_GEN_T:
+ params[0] = BOOLEAN_TO_FLOAT(((ctx->Texture.Unit[ctx->Texture.CurrentUnit].TexGenEnabled & T_BIT) ? 1 : 0));
+ break;
+ case GL_TEXTURE_GEN_R:
+ params[0] = BOOLEAN_TO_FLOAT(((ctx->Texture.Unit[ctx->Texture.CurrentUnit].TexGenEnabled & R_BIT) ? 1 : 0));
+ break;
+ case GL_TEXTURE_GEN_Q:
+ params[0] = BOOLEAN_TO_FLOAT(((ctx->Texture.Unit[ctx->Texture.CurrentUnit].TexGenEnabled & Q_BIT) ? 1 : 0));
+ break;
+ case GL_TEXTURE_MATRIX:
+ {
+ const GLfloat *matrix = ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Top->m;
+ params[0] = matrix[0];
+ params[1] = matrix[1];
+ params[2] = matrix[2];
+ params[3] = matrix[3];
+ params[4] = matrix[4];
+ params[5] = matrix[5];
+ params[6] = matrix[6];
+ params[7] = matrix[7];
+ params[8] = matrix[8];
+ params[9] = matrix[9];
+ params[10] = matrix[10];
+ params[11] = matrix[11];
+ params[12] = matrix[12];
+ params[13] = matrix[13];
+ params[14] = matrix[14];
+ params[15] = matrix[15];
+ }
+ break;
+ case GL_TEXTURE_STACK_DEPTH:
+ params[0] = (GLfloat)(ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Depth + 1);
+ break;
+ case GL_UNPACK_ALIGNMENT:
+ params[0] = (GLfloat)(ctx->Unpack.Alignment);
+ break;
+ case GL_UNPACK_LSB_FIRST:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Unpack.LsbFirst);
+ break;
+ case GL_UNPACK_ROW_LENGTH:
+ params[0] = (GLfloat)(ctx->Unpack.RowLength);
+ break;
+ case GL_UNPACK_SKIP_PIXELS:
+ params[0] = (GLfloat)(ctx->Unpack.SkipPixels);
+ break;
+ case GL_UNPACK_SKIP_ROWS:
+ params[0] = (GLfloat)(ctx->Unpack.SkipRows);
+ break;
+ case GL_UNPACK_SWAP_BYTES:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Unpack.SwapBytes);
+ break;
+ case GL_UNPACK_SKIP_IMAGES_EXT:
+ params[0] = (GLfloat)(ctx->Unpack.SkipImages);
+ break;
+ case GL_UNPACK_IMAGE_HEIGHT_EXT:
+ params[0] = (GLfloat)(ctx->Unpack.ImageHeight);
+ break;
+ case GL_UNPACK_CLIENT_STORAGE_APPLE:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Unpack.ClientStorage);
+ break;
+ case GL_VIEWPORT:
+ params[0] = (GLfloat)(ctx->Viewport.X);
+ params[1] = (GLfloat)(ctx->Viewport.Y);
+ params[2] = (GLfloat)(ctx->Viewport.Width);
+ params[3] = (GLfloat)(ctx->Viewport.Height);
+ break;
+ case GL_ZOOM_X:
+ params[0] = ctx->Pixel.ZoomX;
+ break;
+ case GL_ZOOM_Y:
+ params[0] = ctx->Pixel.ZoomY;
+ break;
+ case GL_VERTEX_ARRAY:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Array.Vertex.Enabled);
+ break;
+ case GL_VERTEX_ARRAY_SIZE:
+ params[0] = (GLfloat)(ctx->Array.Vertex.Size);
+ break;
+ case GL_VERTEX_ARRAY_TYPE:
+ params[0] = ENUM_TO_FLOAT(ctx->Array.Vertex.Type);
+ break;
+ case GL_VERTEX_ARRAY_STRIDE:
+ params[0] = (GLfloat)(ctx->Array.Vertex.Stride);
+ break;
+ case GL_VERTEX_ARRAY_COUNT_EXT:
+ params[0] = (GLfloat)(0);
+ break;
+ case GL_NORMAL_ARRAY:
+ params[0] = ENUM_TO_FLOAT(ctx->Array.Normal.Enabled);
+ break;
+ case GL_NORMAL_ARRAY_TYPE:
+ params[0] = ENUM_TO_FLOAT(ctx->Array.Normal.Type);
+ break;
+ case GL_NORMAL_ARRAY_STRIDE:
+ params[0] = (GLfloat)(ctx->Array.Normal.Stride);
+ break;
+ case GL_NORMAL_ARRAY_COUNT_EXT:
+ params[0] = (GLfloat)(0);
+ break;
+ case GL_COLOR_ARRAY:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Array.Color.Enabled);
+ break;
+ case GL_COLOR_ARRAY_SIZE:
+ params[0] = (GLfloat)(ctx->Array.Color.Size);
+ break;
+ case GL_COLOR_ARRAY_TYPE:
+ params[0] = ENUM_TO_FLOAT(ctx->Array.Color.Type);
+ break;
+ case GL_COLOR_ARRAY_STRIDE:
+ params[0] = (GLfloat)(ctx->Array.Color.Stride);
+ break;
+ case GL_COLOR_ARRAY_COUNT_EXT:
+ params[0] = (GLfloat)(0);
+ break;
+ case GL_INDEX_ARRAY:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Array.Index.Enabled);
+ break;
+ case GL_INDEX_ARRAY_TYPE:
+ params[0] = ENUM_TO_FLOAT(ctx->Array.Index.Type);
+ break;
+ case GL_INDEX_ARRAY_STRIDE:
+ params[0] = (GLfloat)(ctx->Array.Index.Stride);
+ break;
+ case GL_INDEX_ARRAY_COUNT_EXT:
+ params[0] = (GLfloat)(0);
+ break;
+ case GL_TEXTURE_COORD_ARRAY:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Array.TexCoord[ctx->Array.ActiveTexture].Enabled);
+ break;
+ case GL_TEXTURE_COORD_ARRAY_SIZE:
+ params[0] = (GLfloat)(ctx->Array.TexCoord[ctx->Array.ActiveTexture].Size);
+ break;
+ case GL_TEXTURE_COORD_ARRAY_TYPE:
+ params[0] = ENUM_TO_FLOAT(ctx->Array.TexCoord[ctx->Array.ActiveTexture].Type);
+ break;
+ case GL_TEXTURE_COORD_ARRAY_STRIDE:
+ params[0] = (GLfloat)(ctx->Array.TexCoord[ctx->Array.ActiveTexture].Stride);
+ break;
+ case GL_TEXTURE_COORD_ARRAY_COUNT_EXT:
+ params[0] = (GLfloat)(0);
+ break;
+ case GL_EDGE_FLAG_ARRAY:
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Array.EdgeFlag.Enabled);
+ break;
+ case GL_EDGE_FLAG_ARRAY_STRIDE:
+ params[0] = (GLfloat)(ctx->Array.EdgeFlag.Stride);
+ break;
+ case GL_EDGE_FLAG_ARRAY_COUNT_EXT:
+ params[0] = (GLfloat)(0);
+ break;
+ case GL_MAX_TEXTURE_UNITS_ARB:
+ CHECK_EXT1(ARB_multitexture, "GetFloatv");
+ params[0] = (GLfloat)(MIN2(ctx->Const.MaxTextureImageUnits, ctx->Const.MaxTextureCoordUnits));
+ break;
+ case GL_ACTIVE_TEXTURE_ARB:
+ CHECK_EXT1(ARB_multitexture, "GetFloatv");
+ params[0] = (GLfloat)(GL_TEXTURE0_ARB + ctx->Texture.CurrentUnit);
+ break;
+ case GL_CLIENT_ACTIVE_TEXTURE_ARB:
+ CHECK_EXT1(ARB_multitexture, "GetFloatv");
+ params[0] = (GLfloat)(GL_TEXTURE0_ARB + ctx->Array.ActiveTexture);
+ break;
+ case GL_TEXTURE_CUBE_MAP_ARB:
+ CHECK_EXT1(ARB_texture_cube_map, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(_mesa_IsEnabled(GL_TEXTURE_CUBE_MAP_ARB));
+ break;
+ case GL_TEXTURE_BINDING_CUBE_MAP_ARB:
+ CHECK_EXT1(ARB_texture_cube_map, "GetFloatv");
+ params[0] = (GLfloat)(ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentCubeMap->Name);
+ break;
+ case GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB:
+ CHECK_EXT1(ARB_texture_cube_map, "GetFloatv");
+ params[0] = (GLfloat)((1 << (ctx->Const.MaxCubeTextureLevels - 1)));
+ break;
+ case GL_TEXTURE_COMPRESSION_HINT_ARB:
+ CHECK_EXT1(ARB_texture_compression, "GetFloatv");
+ params[0] = (GLfloat)(ctx->Hint.TextureCompression);
+ break;
+ case GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB:
+ CHECK_EXT1(ARB_texture_compression, "GetFloatv");
+ params[0] = (GLfloat)(_mesa_get_compressed_formats(ctx, NULL));
+ break;
+ case GL_COMPRESSED_TEXTURE_FORMATS_ARB:
+ CHECK_EXT1(ARB_texture_compression, "GetFloatv");
+ {
+ GLint formats[100];
+ GLuint i, n = _mesa_get_compressed_formats(ctx, formats);
+ ASSERT(n <= 100);
+ for (i = 0; i < n; i++)
+ params[i] = ENUM_TO_INT(formats[i]);
+ }
+ break;
+ case GL_ARRAY_ELEMENT_LOCK_FIRST_EXT:
+ CHECK_EXT1(EXT_compiled_vertex_array, "GetFloatv");
+ params[0] = (GLfloat)(ctx->Array.LockFirst);
+ break;
+ case GL_ARRAY_ELEMENT_LOCK_COUNT_EXT:
+ CHECK_EXT1(EXT_compiled_vertex_array, "GetFloatv");
+ params[0] = (GLfloat)(ctx->Array.LockCount);
+ break;
+ case GL_TRANSPOSE_COLOR_MATRIX_ARB:
+ {
+ const GLfloat *matrix = ctx->ColorMatrixStack.Top->m;
+ params[0] = matrix[0];
+ params[1] = matrix[4];
+ params[2] = matrix[8];
+ params[3] = matrix[12];
+ params[4] = matrix[1];
+ params[5] = matrix[5];
+ params[6] = matrix[9];
+ params[7] = matrix[13];
+ params[8] = matrix[2];
+ params[9] = matrix[6];
+ params[10] = matrix[10];
+ params[11] = matrix[14];
+ params[12] = matrix[3];
+ params[13] = matrix[7];
+ params[14] = matrix[11];
+ params[15] = matrix[15];
+ }
+ break;
+ case GL_TRANSPOSE_MODELVIEW_MATRIX_ARB:
+ {
+ const GLfloat *matrix = ctx->ModelviewMatrixStack.Top->m;
+ params[0] = matrix[0];
+ params[1] = matrix[4];
+ params[2] = matrix[8];
+ params[3] = matrix[12];
+ params[4] = matrix[1];
+ params[5] = matrix[5];
+ params[6] = matrix[9];
+ params[7] = matrix[13];
+ params[8] = matrix[2];
+ params[9] = matrix[6];
+ params[10] = matrix[10];
+ params[11] = matrix[14];
+ params[12] = matrix[3];
+ params[13] = matrix[7];
+ params[14] = matrix[11];
+ params[15] = matrix[15];
+ }
+ break;
+ case GL_TRANSPOSE_PROJECTION_MATRIX_ARB:
+ {
+ const GLfloat *matrix = ctx->ProjectionMatrixStack.Top->m;
+ params[0] = matrix[0];
+ params[1] = matrix[4];
+ params[2] = matrix[8];
+ params[3] = matrix[12];
+ params[4] = matrix[1];
+ params[5] = matrix[5];
+ params[6] = matrix[9];
+ params[7] = matrix[13];
+ params[8] = matrix[2];
+ params[9] = matrix[6];
+ params[10] = matrix[10];
+ params[11] = matrix[14];
+ params[12] = matrix[3];
+ params[13] = matrix[7];
+ params[14] = matrix[11];
+ params[15] = matrix[15];
+ }
+ break;
+ case GL_TRANSPOSE_TEXTURE_MATRIX_ARB:
+ {
+ const GLfloat *matrix = ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Top->m;
+ params[0] = matrix[0];
+ params[1] = matrix[4];
+ params[2] = matrix[8];
+ params[3] = matrix[12];
+ params[4] = matrix[1];
+ params[5] = matrix[5];
+ params[6] = matrix[9];
+ params[7] = matrix[13];
+ params[8] = matrix[2];
+ params[9] = matrix[6];
+ params[10] = matrix[10];
+ params[11] = matrix[14];
+ params[12] = matrix[3];
+ params[13] = matrix[7];
+ params[14] = matrix[11];
+ params[15] = matrix[15];
+ }
+ break;
+ case GL_COLOR_MATRIX_SGI:
+ {
+ const GLfloat *matrix = ctx->ColorMatrixStack.Top->m;
+ params[0] = matrix[0];
+ params[1] = matrix[1];
+ params[2] = matrix[2];
+ params[3] = matrix[3];
+ params[4] = matrix[4];
+ params[5] = matrix[5];
+ params[6] = matrix[6];
+ params[7] = matrix[7];
+ params[8] = matrix[8];
+ params[9] = matrix[9];
+ params[10] = matrix[10];
+ params[11] = matrix[11];
+ params[12] = matrix[12];
+ params[13] = matrix[13];
+ params[14] = matrix[14];
+ params[15] = matrix[15];
+ }
+ break;
+ case GL_COLOR_MATRIX_STACK_DEPTH_SGI:
+ params[0] = (GLfloat)(ctx->ColorMatrixStack.Depth + 1);
+ break;
+ case GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI:
+ params[0] = (GLfloat)(MAX_COLOR_STACK_DEPTH);
+ break;
+ case GL_POST_COLOR_MATRIX_RED_SCALE_SGI:
+ params[0] = ctx->Pixel.PostColorMatrixScale[0];
+ break;
+ case GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI:
+ params[0] = ctx->Pixel.PostColorMatrixScale[1];
+ break;
+ case GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI:
+ params[0] = ctx->Pixel.PostColorMatrixScale[2];
+ break;
+ case GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI:
+ params[0] = ctx->Pixel.PostColorMatrixScale[3];
+ break;
+ case GL_POST_COLOR_MATRIX_RED_BIAS_SGI:
+ params[0] = ctx->Pixel.PostColorMatrixBias[0];
+ break;
+ case GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI:
+ params[0] = ctx->Pixel.PostColorMatrixBias[1];
+ break;
+ case GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI:
+ params[0] = ctx->Pixel.PostColorMatrixBias[2];
+ break;
+ case GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI:
+ params[0] = ctx->Pixel.PostColorMatrixBias[3];
+ break;
+ case GL_CONVOLUTION_1D_EXT:
+ CHECK_EXT1(EXT_convolution, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Pixel.Convolution1DEnabled);
+ break;
+ case GL_CONVOLUTION_2D_EXT:
+ CHECK_EXT1(EXT_convolution, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Pixel.Convolution2DEnabled);
+ break;
+ case GL_SEPARABLE_2D_EXT:
+ CHECK_EXT1(EXT_convolution, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Pixel.Separable2DEnabled);
+ break;
+ case GL_POST_CONVOLUTION_RED_SCALE_EXT:
+ CHECK_EXT1(EXT_convolution, "GetFloatv");
+ params[0] = ctx->Pixel.PostConvolutionScale[0];
+ break;
+ case GL_POST_CONVOLUTION_GREEN_SCALE_EXT:
+ CHECK_EXT1(EXT_convolution, "GetFloatv");
+ params[0] = ctx->Pixel.PostConvolutionScale[1];
+ break;
+ case GL_POST_CONVOLUTION_BLUE_SCALE_EXT:
+ CHECK_EXT1(EXT_convolution, "GetFloatv");
+ params[0] = ctx->Pixel.PostConvolutionScale[2];
+ break;
+ case GL_POST_CONVOLUTION_ALPHA_SCALE_EXT:
+ CHECK_EXT1(EXT_convolution, "GetFloatv");
+ params[0] = ctx->Pixel.PostConvolutionScale[3];
+ break;
+ case GL_POST_CONVOLUTION_RED_BIAS_EXT:
+ CHECK_EXT1(EXT_convolution, "GetFloatv");
+ params[0] = ctx->Pixel.PostConvolutionBias[0];
+ break;
+ case GL_POST_CONVOLUTION_GREEN_BIAS_EXT:
+ CHECK_EXT1(EXT_convolution, "GetFloatv");
+ params[0] = ctx->Pixel.PostConvolutionBias[1];
+ break;
+ case GL_POST_CONVOLUTION_BLUE_BIAS_EXT:
+ CHECK_EXT1(EXT_convolution, "GetFloatv");
+ params[0] = ctx->Pixel.PostConvolutionBias[2];
+ break;
+ case GL_POST_CONVOLUTION_ALPHA_BIAS_EXT:
+ CHECK_EXT1(EXT_convolution, "GetFloatv");
+ params[0] = ctx->Pixel.PostConvolutionBias[3];
+ break;
+ case GL_HISTOGRAM:
+ CHECK_EXT1(EXT_histogram, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Pixel.HistogramEnabled);
+ break;
+ case GL_MINMAX:
+ CHECK_EXT1(EXT_histogram, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Pixel.MinMaxEnabled);
+ break;
+ case GL_COLOR_TABLE_SGI:
+ CHECK_EXT1(SGI_color_table, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Pixel.ColorTableEnabled);
+ break;
+ case GL_POST_CONVOLUTION_COLOR_TABLE_SGI:
+ CHECK_EXT1(SGI_color_table, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Pixel.PostConvolutionColorTableEnabled);
+ break;
+ case GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI:
+ CHECK_EXT1(SGI_color_table, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Pixel.PostColorMatrixColorTableEnabled);
+ break;
+ case GL_TEXTURE_COLOR_TABLE_SGI:
+ CHECK_EXT1(SGI_texture_color_table, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Texture.Unit[ctx->Texture.CurrentUnit].ColorTableEnabled);
+ break;
+ case GL_COLOR_SUM_EXT:
+ CHECK_EXT2(EXT_secondary_color, ARB_vertex_program, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Fog.ColorSumEnabled);
+ break;
+ case GL_CURRENT_SECONDARY_COLOR_EXT:
+ CHECK_EXT1(EXT_secondary_color, "GetFloatv");
+ {
+ FLUSH_CURRENT(ctx, 0);
+ params[0] = ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0];
+ params[1] = ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1];
+ params[2] = ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2];
+ params[3] = ctx->Current.Attrib[VERT_ATTRIB_COLOR1][3];
+ }
+ break;
+ case GL_SECONDARY_COLOR_ARRAY_EXT:
+ CHECK_EXT1(EXT_secondary_color, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Array.SecondaryColor.Enabled);
+ break;
+ case GL_SECONDARY_COLOR_ARRAY_TYPE_EXT:
+ CHECK_EXT1(EXT_secondary_color, "GetFloatv");
+ params[0] = ENUM_TO_FLOAT(ctx->Array.SecondaryColor.Type);
+ break;
+ case GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT:
+ CHECK_EXT1(EXT_secondary_color, "GetFloatv");
+ params[0] = (GLfloat)(ctx->Array.SecondaryColor.Stride);
+ break;
+ case GL_SECONDARY_COLOR_ARRAY_SIZE_EXT:
+ CHECK_EXT1(EXT_secondary_color, "GetFloatv");
+ params[0] = (GLfloat)(ctx->Array.SecondaryColor.Size);
+ break;
+ case GL_CURRENT_FOG_COORDINATE_EXT:
+ CHECK_EXT1(EXT_fog_coord, "GetFloatv");
+ {
+ FLUSH_CURRENT(ctx, 0);
+ params[0] = ctx->Current.Attrib[VERT_ATTRIB_FOG][0];
+ }
+ break;
+ case GL_FOG_COORDINATE_ARRAY_EXT:
+ CHECK_EXT1(EXT_fog_coord, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Array.FogCoord.Enabled);
+ break;
+ case GL_FOG_COORDINATE_ARRAY_TYPE_EXT:
+ CHECK_EXT1(EXT_fog_coord, "GetFloatv");
+ params[0] = ENUM_TO_FLOAT(ctx->Array.FogCoord.Type);
+ break;
+ case GL_FOG_COORDINATE_ARRAY_STRIDE_EXT:
+ CHECK_EXT1(EXT_fog_coord, "GetFloatv");
+ params[0] = (GLfloat)(ctx->Array.FogCoord.Stride);
+ break;
+ case GL_FOG_COORDINATE_SOURCE_EXT:
+ CHECK_EXT1(EXT_fog_coord, "GetFloatv");
+ params[0] = ENUM_TO_FLOAT(ctx->Fog.FogCoordinateSource);
+ break;
+ case GL_MAX_TEXTURE_LOD_BIAS_EXT:
+ CHECK_EXT1(EXT_texture_lod_bias, "GetFloatv");
+ params[0] = ctx->Const.MaxTextureLodBias;
+ break;
+ case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
+ CHECK_EXT1(EXT_texture_filter_anisotropic, "GetFloatv");
+ params[0] = ctx->Const.MaxTextureMaxAnisotropy;
+ break;
+ case GL_MULTISAMPLE_ARB:
+ CHECK_EXT1(ARB_multisample, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Multisample.Enabled);
+ break;
+ case GL_SAMPLE_ALPHA_TO_COVERAGE_ARB:
+ CHECK_EXT1(ARB_multisample, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Multisample.SampleAlphaToCoverage);
+ break;
+ case GL_SAMPLE_ALPHA_TO_ONE_ARB:
+ CHECK_EXT1(ARB_multisample, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Multisample.SampleAlphaToOne);
+ break;
+ case GL_SAMPLE_COVERAGE_ARB:
+ CHECK_EXT1(ARB_multisample, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Multisample.SampleCoverage);
+ break;
+ case GL_SAMPLE_COVERAGE_VALUE_ARB:
+ CHECK_EXT1(ARB_multisample, "GetFloatv");
+ params[0] = ctx->Multisample.SampleCoverageValue;
+ break;
+ case GL_SAMPLE_COVERAGE_INVERT_ARB:
+ CHECK_EXT1(ARB_multisample, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Multisample.SampleCoverageInvert);
+ break;
+ case GL_SAMPLE_BUFFERS_ARB:
+ CHECK_EXT1(ARB_multisample, "GetFloatv");
+ params[0] = (GLfloat)(ctx->DrawBuffer->Visual.sampleBuffers);
+ break;
+ case GL_SAMPLES_ARB:
+ CHECK_EXT1(ARB_multisample, "GetFloatv");
+ params[0] = (GLfloat)(ctx->DrawBuffer->Visual.samples);
+ break;
+ case GL_RASTER_POSITION_UNCLIPPED_IBM:
+ CHECK_EXT1(IBM_rasterpos_clip, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Transform.RasterPositionUnclipped);
+ break;
+ case GL_POINT_SPRITE_NV:
+ CHECK_EXT2(NV_point_sprite, ARB_point_sprite, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Point.PointSprite);
+ break;
+ case GL_POINT_SPRITE_R_MODE_NV:
+ CHECK_EXT1(NV_point_sprite, "GetFloatv");
+ params[0] = ENUM_TO_FLOAT(ctx->Point.SpriteRMode);
+ break;
+ case GL_POINT_SPRITE_COORD_ORIGIN:
+ CHECK_EXT2(NV_point_sprite, ARB_point_sprite, "GetFloatv");
+ params[0] = ENUM_TO_FLOAT(ctx->Point.SpriteOrigin);
+ break;
+ case GL_GENERATE_MIPMAP_HINT_SGIS:
+ CHECK_EXT1(SGIS_generate_mipmap, "GetFloatv");
+ params[0] = ENUM_TO_FLOAT(ctx->Hint.GenerateMipmap);
+ break;
+ case GL_VERTEX_PROGRAM_BINDING_NV:
+ CHECK_EXT1(NV_vertex_program, "GetFloatv");
+ params[0] = (GLfloat)((ctx->VertexProgram.Current ? ctx->VertexProgram.Current->Base.Id : 0));
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY0_NV:
+ CHECK_EXT1(NV_vertex_program, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Array.VertexAttrib[0].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY1_NV:
+ CHECK_EXT1(NV_vertex_program, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Array.VertexAttrib[1].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY2_NV:
+ CHECK_EXT1(NV_vertex_program, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Array.VertexAttrib[2].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY3_NV:
+ CHECK_EXT1(NV_vertex_program, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Array.VertexAttrib[3].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Array.VertexAttrib[4].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY5_NV:
+ CHECK_EXT1(NV_vertex_program, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Array.VertexAttrib[5].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY6_NV:
+ CHECK_EXT1(NV_vertex_program, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Array.VertexAttrib[6].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY7_NV:
+ CHECK_EXT1(NV_vertex_program, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Array.VertexAttrib[7].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY8_NV:
+ CHECK_EXT1(NV_vertex_program, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Array.VertexAttrib[8].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY9_NV:
+ CHECK_EXT1(NV_vertex_program, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Array.VertexAttrib[9].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY10_NV:
+ CHECK_EXT1(NV_vertex_program, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Array.VertexAttrib[10].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY11_NV:
+ CHECK_EXT1(NV_vertex_program, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Array.VertexAttrib[11].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY12_NV:
+ CHECK_EXT1(NV_vertex_program, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Array.VertexAttrib[12].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY13_NV:
+ CHECK_EXT1(NV_vertex_program, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Array.VertexAttrib[13].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY14_NV:
+ CHECK_EXT1(NV_vertex_program, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Array.VertexAttrib[14].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY15_NV:
+ CHECK_EXT1(NV_vertex_program, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Array.VertexAttrib[15].Enabled);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB0_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Attrib[0]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB1_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Attrib[1]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB2_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Attrib[2]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB3_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Attrib[3]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB4_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Attrib[4]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB5_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Attrib[5]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB6_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Attrib[6]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB7_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Attrib[7]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB8_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Attrib[8]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB9_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Attrib[9]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB10_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Attrib[10]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB11_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Attrib[11]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB12_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Attrib[12]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB13_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Attrib[13]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB14_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Attrib[14]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB15_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Attrib[15]);
+ break;
+ case GL_FRAGMENT_PROGRAM_NV:
+ CHECK_EXT1(NV_fragment_program, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->FragmentProgram.Enabled);
+ break;
+ case GL_FRAGMENT_PROGRAM_BINDING_NV:
+ CHECK_EXT1(NV_fragment_program, "GetFloatv");
+ params[0] = (GLfloat)(ctx->FragmentProgram.Current ? ctx->FragmentProgram.Current->Base.Id : 0);
+ break;
+ case GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV:
+ CHECK_EXT1(NV_fragment_program, "GetFloatv");
+ params[0] = (GLfloat)(MAX_NV_FRAGMENT_PROGRAM_PARAMS);
+ break;
+ case GL_TEXTURE_RECTANGLE_NV:
+ CHECK_EXT1(NV_texture_rectangle, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(_mesa_IsEnabled(GL_TEXTURE_RECTANGLE_NV));
+ break;
+ case GL_TEXTURE_BINDING_RECTANGLE_NV:
+ CHECK_EXT1(NV_texture_rectangle, "GetFloatv");
+ params[0] = (GLfloat)(ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentRect->Name);
+ break;
+ case GL_MAX_RECTANGLE_TEXTURE_SIZE_NV:
+ CHECK_EXT1(NV_texture_rectangle, "GetFloatv");
+ params[0] = (GLfloat)(ctx->Const.MaxTextureRectSize);
+ break;
+ case GL_STENCIL_TEST_TWO_SIDE_EXT:
+ CHECK_EXT1(EXT_stencil_two_side, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Stencil.TestTwoSide);
+ break;
+ case GL_ACTIVE_STENCIL_FACE_EXT:
+ CHECK_EXT1(EXT_stencil_two_side, "GetFloatv");
+ params[0] = ENUM_TO_FLOAT(ctx->Stencil.ActiveFace ? GL_BACK : GL_FRONT);
+ break;
+ case GL_MAX_SHININESS_NV:
+ CHECK_EXT1(NV_light_max_exponent, "GetFloatv");
+ params[0] = ctx->Const.MaxShininess;
+ break;
+ case GL_MAX_SPOT_EXPONENT_NV:
+ CHECK_EXT1(NV_light_max_exponent, "GetFloatv");
+ params[0] = ctx->Const.MaxSpotExponent;
+ break;
+ case GL_ARRAY_BUFFER_BINDING_ARB:
+ CHECK_EXT1(ARB_vertex_buffer_object, "GetFloatv");
+ params[0] = (GLfloat)(ctx->Array.ArrayBufferObj->Name);
+ break;
+ case GL_VERTEX_ARRAY_BUFFER_BINDING_ARB:
+ CHECK_EXT1(ARB_vertex_buffer_object, "GetFloatv");
+ params[0] = (GLfloat)(ctx->Array.Vertex.BufferObj->Name);
+ break;
+ case GL_NORMAL_ARRAY_BUFFER_BINDING_ARB:
+ CHECK_EXT1(ARB_vertex_buffer_object, "GetFloatv");
+ params[0] = (GLfloat)(ctx->Array.Normal.BufferObj->Name);
+ break;
+ case GL_COLOR_ARRAY_BUFFER_BINDING_ARB:
+ CHECK_EXT1(ARB_vertex_buffer_object, "GetFloatv");
+ params[0] = (GLfloat)(ctx->Array.Color.BufferObj->Name);
+ break;
+ case GL_INDEX_ARRAY_BUFFER_BINDING_ARB:
+ CHECK_EXT1(ARB_vertex_buffer_object, "GetFloatv");
+ params[0] = (GLfloat)(ctx->Array.Index.BufferObj->Name);
+ break;
+ case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB:
+ CHECK_EXT1(ARB_vertex_buffer_object, "GetFloatv");
+ params[0] = (GLfloat)(ctx->Array.TexCoord[ctx->Array.ActiveTexture].BufferObj->Name);
+ break;
+ case GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB:
+ CHECK_EXT1(ARB_vertex_buffer_object, "GetFloatv");
+ params[0] = (GLfloat)(ctx->Array.EdgeFlag.BufferObj->Name);
+ break;
+ case GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB:
+ CHECK_EXT1(ARB_vertex_buffer_object, "GetFloatv");
+ params[0] = (GLfloat)(ctx->Array.SecondaryColor.BufferObj->Name);
+ break;
+ case GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB:
+ CHECK_EXT1(ARB_vertex_buffer_object, "GetFloatv");
+ params[0] = (GLfloat)(ctx->Array.FogCoord.BufferObj->Name);
+ break;
+ case GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB:
+ CHECK_EXT1(ARB_vertex_buffer_object, "GetFloatv");
+ params[0] = (GLfloat)(ctx->Array.ElementArrayBufferObj->Name);
+ break;
+ case GL_PIXEL_PACK_BUFFER_BINDING_EXT:
+ CHECK_EXT1(EXT_pixel_buffer_object, "GetFloatv");
+ params[0] = (GLfloat)(ctx->Pack.BufferObj->Name);
+ break;
+ case GL_PIXEL_UNPACK_BUFFER_BINDING_EXT:
+ CHECK_EXT1(EXT_pixel_buffer_object, "GetFloatv");
+ params[0] = (GLfloat)(ctx->Unpack.BufferObj->Name);
+ break;
+ case GL_VERTEX_PROGRAM_ARB:
+ CHECK_EXT2(ARB_vertex_program, NV_vertex_program, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->VertexProgram.Enabled);
+ break;
+ case GL_VERTEX_PROGRAM_POINT_SIZE_ARB:
+ CHECK_EXT2(ARB_vertex_program, NV_vertex_program, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->VertexProgram.PointSizeEnabled);
+ break;
+ case GL_VERTEX_PROGRAM_TWO_SIDE_ARB:
+ CHECK_EXT2(ARB_vertex_program, NV_vertex_program, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->VertexProgram.TwoSideEnabled);
+ break;
+ case GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB:
+ CHECK_EXT3(ARB_vertex_program, ARB_fragment_program, NV_vertex_program, "GetFloatv");
+ params[0] = (GLfloat)(ctx->Const.MaxProgramMatrixStackDepth);
+ break;
+ case GL_MAX_PROGRAM_MATRICES_ARB:
+ CHECK_EXT3(ARB_vertex_program, ARB_fragment_program, NV_vertex_program, "GetFloatv");
+ params[0] = (GLfloat)(ctx->Const.MaxProgramMatrices);
+ break;
+ case GL_CURRENT_MATRIX_STACK_DEPTH_ARB:
+ CHECK_EXT3(ARB_vertex_program, ARB_fragment_program, NV_vertex_program, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->CurrentStack->Depth + 1);
+ break;
+ case GL_CURRENT_MATRIX_ARB:
+ CHECK_EXT3(ARB_vertex_program, ARB_fragment_program, NV_fragment_program, "GetFloatv");
+ {
+ const GLfloat *matrix = ctx->CurrentStack->Top->m;
+ params[0] = matrix[0];
+ params[1] = matrix[1];
+ params[2] = matrix[2];
+ params[3] = matrix[3];
+ params[4] = matrix[4];
+ params[5] = matrix[5];
+ params[6] = matrix[6];
+ params[7] = matrix[7];
+ params[8] = matrix[8];
+ params[9] = matrix[9];
+ params[10] = matrix[10];
+ params[11] = matrix[11];
+ params[12] = matrix[12];
+ params[13] = matrix[13];
+ params[14] = matrix[14];
+ params[15] = matrix[15];
+ }
+ break;
+ case GL_TRANSPOSE_CURRENT_MATRIX_ARB:
+ CHECK_EXT2(ARB_vertex_program, ARB_fragment_program, "GetFloatv");
+ {
+ const GLfloat *matrix = ctx->CurrentStack->Top->m;
+ params[0] = matrix[0];
+ params[1] = matrix[4];
+ params[2] = matrix[8];
+ params[3] = matrix[12];
+ params[4] = matrix[1];
+ params[5] = matrix[5];
+ params[6] = matrix[9];
+ params[7] = matrix[13];
+ params[8] = matrix[2];
+ params[9] = matrix[6];
+ params[10] = matrix[10];
+ params[11] = matrix[14];
+ params[12] = matrix[3];
+ params[13] = matrix[7];
+ params[14] = matrix[11];
+ params[15] = matrix[15];
+ }
+ break;
+ case GL_MAX_VERTEX_ATTRIBS_ARB:
+ CHECK_EXT1(ARB_vertex_program, "GetFloatv");
+ params[0] = (GLfloat)(ctx->Const.VertexProgram.MaxAttribs);
+ break;
+ case GL_PROGRAM_ERROR_POSITION_ARB:
+ CHECK_EXT4(NV_vertex_program, ARB_vertex_program, NV_fragment_program, ARB_fragment_program, "GetFloatv");
+ params[0] = (GLfloat)(ctx->Program.ErrorPos);
+ break;
+ case GL_FRAGMENT_PROGRAM_ARB:
+ CHECK_EXT1(ARB_fragment_program, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->FragmentProgram.Enabled);
+ break;
+ case GL_MAX_TEXTURE_COORDS_ARB:
+ CHECK_EXT2(ARB_fragment_program, NV_fragment_program, "GetFloatv");
+ params[0] = (GLfloat)(ctx->Const.MaxTextureCoordUnits);
+ break;
+ case GL_MAX_TEXTURE_IMAGE_UNITS_ARB:
+ CHECK_EXT2(ARB_fragment_program, NV_fragment_program, "GetFloatv");
+ params[0] = (GLfloat)(ctx->Const.MaxTextureImageUnits);
+ break;
+ case GL_DEPTH_BOUNDS_TEST_EXT:
+ CHECK_EXT1(EXT_depth_bounds_test, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Depth.BoundsTest);
+ break;
+ case GL_DEPTH_BOUNDS_EXT:
+ CHECK_EXT1(EXT_depth_bounds_test, "GetFloatv");
+ params[0] = ctx->Depth.BoundsMin;
+ params[1] = ctx->Depth.BoundsMax;
+ break;
+ case GL_FRAGMENT_PROGRAM_CALLBACK_MESA:
+ CHECK_EXT1(MESA_program_debug, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->FragmentProgram.CallbackEnabled);
+ break;
+ case GL_VERTEX_PROGRAM_CALLBACK_MESA:
+ CHECK_EXT1(MESA_program_debug, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->VertexProgram.CallbackEnabled);
+ break;
+ case GL_FRAGMENT_PROGRAM_POSITION_MESA:
+ CHECK_EXT1(MESA_program_debug, "GetFloatv");
+ params[0] = (GLfloat)(ctx->FragmentProgram.CurrentPosition);
+ break;
+ case GL_VERTEX_PROGRAM_POSITION_MESA:
+ CHECK_EXT1(MESA_program_debug, "GetFloatv");
+ params[0] = (GLfloat)(ctx->VertexProgram.CurrentPosition);
+ break;
+ case GL_MAX_DRAW_BUFFERS_ARB:
+ CHECK_EXT1(ARB_draw_buffers, "GetFloatv");
+ params[0] = (GLfloat)(ctx->Const.MaxDrawBuffers);
+ break;
+ case GL_DRAW_BUFFER0_ARB:
+ CHECK_EXT1(ARB_draw_buffers, "GetFloatv");
+ params[0] = ENUM_TO_FLOAT(ctx->DrawBuffer->ColorDrawBuffer[0]);
+ break;
+ case GL_DRAW_BUFFER1_ARB:
+ CHECK_EXT1(ARB_draw_buffers, "GetFloatv");
+ {
+ GLenum buffer;
+ if (pname - GL_DRAW_BUFFER0_ARB >= ctx->Const.MaxDrawBuffers) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGet(GL_DRAW_BUFFERx_ARB)");
+ return;
+ }
+ buffer = ctx->DrawBuffer->ColorDrawBuffer[1];
+ params[0] = ENUM_TO_FLOAT(buffer);
+ }
+ break;
+ case GL_DRAW_BUFFER2_ARB:
+ CHECK_EXT1(ARB_draw_buffers, "GetFloatv");
+ {
+ GLenum buffer;
+ if (pname - GL_DRAW_BUFFER0_ARB >= ctx->Const.MaxDrawBuffers) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGet(GL_DRAW_BUFFERx_ARB)");
+ return;
+ }
+ buffer = ctx->DrawBuffer->ColorDrawBuffer[2];
+ params[0] = ENUM_TO_FLOAT(buffer);
+ }
+ break;
+ case GL_DRAW_BUFFER3_ARB:
+ CHECK_EXT1(ARB_draw_buffers, "GetFloatv");
+ {
+ GLenum buffer;
+ if (pname - GL_DRAW_BUFFER0_ARB >= ctx->Const.MaxDrawBuffers) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGet(GL_DRAW_BUFFERx_ARB)");
+ return;
+ }
+ buffer = ctx->DrawBuffer->ColorDrawBuffer[3];
+ params[0] = ENUM_TO_FLOAT(buffer);
+ }
+ break;
+ case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
+ CHECK_EXT1(OES_read_format, "GetFloatv");
+ params[0] = (GLfloat)(ctx->Const.ColorReadType);
+ break;
+ case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
+ CHECK_EXT1(OES_read_format, "GetFloatv");
+ params[0] = (GLfloat)(ctx->Const.ColorReadFormat);
+ break;
+ case GL_NUM_FRAGMENT_REGISTERS_ATI:
+ CHECK_EXT1(ATI_fragment_shader, "GetFloatv");
+ params[0] = (GLfloat)(6);
+ break;
+ case GL_NUM_FRAGMENT_CONSTANTS_ATI:
+ CHECK_EXT1(ATI_fragment_shader, "GetFloatv");
+ params[0] = (GLfloat)(8);
+ break;
+ case GL_NUM_PASSES_ATI:
+ CHECK_EXT1(ATI_fragment_shader, "GetFloatv");
+ params[0] = (GLfloat)(2);
+ break;
+ case GL_NUM_INSTRUCTIONS_PER_PASS_ATI:
+ CHECK_EXT1(ATI_fragment_shader, "GetFloatv");
+ params[0] = (GLfloat)(8);
+ break;
+ case GL_NUM_INSTRUCTIONS_TOTAL_ATI:
+ CHECK_EXT1(ATI_fragment_shader, "GetFloatv");
+ params[0] = (GLfloat)(16);
+ break;
+ case GL_COLOR_ALPHA_PAIRING_ATI:
+ CHECK_EXT1(ATI_fragment_shader, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(GL_TRUE);
+ break;
+ case GL_NUM_LOOPBACK_COMPONENTS_ATI:
+ CHECK_EXT1(ATI_fragment_shader, "GetFloatv");
+ params[0] = (GLfloat)(3);
+ break;
+ case GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI:
+ CHECK_EXT1(ATI_fragment_shader, "GetFloatv");
+ params[0] = (GLfloat)(3);
+ break;
+ case GL_STENCIL_BACK_FUNC:
+ params[0] = ENUM_TO_FLOAT(ctx->Stencil.Function[1]);
+ break;
+ case GL_STENCIL_BACK_VALUE_MASK:
+ params[0] = (GLfloat)(ctx->Stencil.ValueMask[1]);
+ break;
+ case GL_STENCIL_BACK_REF:
+ params[0] = (GLfloat)(ctx->Stencil.Ref[1]);
+ break;
+ case GL_STENCIL_BACK_FAIL:
+ params[0] = ENUM_TO_FLOAT(ctx->Stencil.FailFunc[1]);
+ break;
+ case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
+ params[0] = ENUM_TO_FLOAT(ctx->Stencil.ZFailFunc[1]);
+ break;
+ case GL_STENCIL_BACK_PASS_DEPTH_PASS:
+ params[0] = ENUM_TO_FLOAT(ctx->Stencil.ZPassFunc[1]);
+ break;
+ case GL_FRAMEBUFFER_BINDING_EXT:
+ CHECK_EXT1(EXT_framebuffer_object, "GetFloatv");
+ params[0] = (GLfloat)(ctx->DrawBuffer->Name);
+ break;
+ case GL_RENDERBUFFER_BINDING_EXT:
+ CHECK_EXT1(EXT_framebuffer_object, "GetFloatv");
+ params[0] = (GLfloat)(ctx->CurrentRenderbuffer ? ctx->CurrentRenderbuffer->Name : 0);
+ break;
+ case GL_MAX_COLOR_ATTACHMENTS_EXT:
+ CHECK_EXT1(EXT_framebuffer_object, "GetFloatv");
+ params[0] = (GLfloat)(ctx->Const.MaxColorAttachments);
+ break;
+ case GL_MAX_RENDERBUFFER_SIZE_EXT:
+ CHECK_EXT1(EXT_framebuffer_object, "GetFloatv");
+ params[0] = (GLfloat)(ctx->Const.MaxRenderbufferSize);
+ break;
+ case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB:
+ CHECK_EXT1(ARB_fragment_shader, "GetFloatv");
+ params[0] = (GLfloat)(MAX_FRAGMENT_UNIFORM_COMPONENTS);
+ break;
+ case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB:
+ CHECK_EXT1(ARB_fragment_shader, "GetFloatv");
+ params[0] = ENUM_TO_FLOAT(ctx->Hint.FragmentShaderDerivative);
+ break;
+ case GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB:
+ CHECK_EXT1(ARB_vertex_shader, "GetFloatv");
+ params[0] = (GLfloat)(MAX_VERTEX_UNIFORM_COMPONENTS);
+ break;
+ case GL_MAX_VARYING_FLOATS_ARB:
+ CHECK_EXT1(ARB_vertex_shader, "GetFloatv");
+ params[0] = (GLfloat)(MAX_VARYING_FLOATS);
+ break;
+ case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB:
+ CHECK_EXT1(ARB_vertex_shader, "GetFloatv");
+ params[0] = (GLfloat)(MAX_VERTEX_TEXTURE_IMAGE_UNITS);
+ break;
+ case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB:
+ CHECK_EXT1(ARB_vertex_shader, "GetFloatv");
+ params[0] = (GLfloat)(MAX_COMBINED_TEXTURE_IMAGE_UNITS);
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetFloatv(pname=0x%x)", pname);
+ }
+}
+
+void GLAPIENTRY
+_mesa_GetIntegerv( GLenum pname, GLint *params )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (!params)
+ return;
+
+ if (ctx->NewState)
+ _mesa_update_state(ctx);
+
+ if (ctx->Driver.GetIntegerv &&
+ ctx->Driver.GetIntegerv(ctx, pname, params))
+ return;
+
+ switch (pname) {
+ case GL_ACCUM_RED_BITS:
+ params[0] = ctx->DrawBuffer->Visual.accumRedBits;
+ break;
+ case GL_ACCUM_GREEN_BITS:
+ params[0] = ctx->DrawBuffer->Visual.accumGreenBits;
+ break;
+ case GL_ACCUM_BLUE_BITS:
+ params[0] = ctx->DrawBuffer->Visual.accumBlueBits;
+ break;
+ case GL_ACCUM_ALPHA_BITS:
+ params[0] = ctx->DrawBuffer->Visual.accumAlphaBits;
+ break;
+ case GL_ACCUM_CLEAR_VALUE:
+ params[0] = FLOAT_TO_INT(ctx->Accum.ClearColor[0]);
+ params[1] = FLOAT_TO_INT(ctx->Accum.ClearColor[1]);
+ params[2] = FLOAT_TO_INT(ctx->Accum.ClearColor[2]);
+ params[3] = FLOAT_TO_INT(ctx->Accum.ClearColor[3]);
+ break;
+ case GL_ALPHA_BIAS:
+ params[0] = IROUND(ctx->Pixel.AlphaBias);
+ break;
+ case GL_ALPHA_BITS:
+ params[0] = ctx->DrawBuffer->Visual.alphaBits;
+ break;
+ case GL_ALPHA_SCALE:
+ params[0] = IROUND(ctx->Pixel.AlphaScale);
+ break;
+ case GL_ALPHA_TEST:
+ params[0] = BOOLEAN_TO_INT(ctx->Color.AlphaEnabled);
+ break;
+ case GL_ALPHA_TEST_FUNC:
+ params[0] = ENUM_TO_INT(ctx->Color.AlphaFunc);
+ break;
+ case GL_ALPHA_TEST_REF:
+ params[0] = FLOAT_TO_INT(ctx->Color.AlphaRef);
+ break;
+ case GL_ATTRIB_STACK_DEPTH:
+ params[0] = ctx->AttribStackDepth;
+ break;
+ case GL_AUTO_NORMAL:
+ params[0] = BOOLEAN_TO_INT(ctx->Eval.AutoNormal);
+ break;
+ case GL_AUX_BUFFERS:
+ params[0] = ctx->DrawBuffer->Visual.numAuxBuffers;
+ break;
+ case GL_BLEND:
+ params[0] = BOOLEAN_TO_INT(ctx->Color.BlendEnabled);
+ break;
+ case GL_BLEND_DST:
+ params[0] = ENUM_TO_INT(ctx->Color.BlendDstRGB);
+ break;
+ case GL_BLEND_SRC:
+ params[0] = ENUM_TO_INT(ctx->Color.BlendSrcRGB);
+ break;
+ case GL_BLEND_SRC_RGB_EXT:
+ params[0] = ENUM_TO_INT(ctx->Color.BlendSrcRGB);
+ break;
+ case GL_BLEND_DST_RGB_EXT:
+ params[0] = ENUM_TO_INT(ctx->Color.BlendDstRGB);
+ break;
+ case GL_BLEND_SRC_ALPHA_EXT:
+ params[0] = ENUM_TO_INT(ctx->Color.BlendSrcA);
+ break;
+ case GL_BLEND_DST_ALPHA_EXT:
+ params[0] = ENUM_TO_INT(ctx->Color.BlendDstA);
+ break;
+ case GL_BLEND_EQUATION:
+ params[0] = ENUM_TO_INT(ctx->Color.BlendEquationRGB );
+ break;
+ case GL_BLEND_EQUATION_ALPHA_EXT:
+ params[0] = ENUM_TO_INT(ctx->Color.BlendEquationA );
+ break;
+ case GL_BLEND_COLOR_EXT:
+ params[0] = FLOAT_TO_INT(ctx->Color.BlendColor[0]);
+ params[1] = FLOAT_TO_INT(ctx->Color.BlendColor[1]);
+ params[2] = FLOAT_TO_INT(ctx->Color.BlendColor[2]);
+ params[3] = FLOAT_TO_INT(ctx->Color.BlendColor[3]);
+ break;
+ case GL_BLUE_BIAS:
+ params[0] = IROUND(ctx->Pixel.BlueBias);
+ break;
+ case GL_BLUE_BITS:
+ params[0] = ctx->DrawBuffer->Visual.blueBits;
+ break;
+ case GL_BLUE_SCALE:
+ params[0] = IROUND(ctx->Pixel.BlueScale);
+ break;
+ case GL_CLIENT_ATTRIB_STACK_DEPTH:
+ params[0] = ctx->ClientAttribStackDepth;
+ break;
+ case GL_CLIP_PLANE0:
+ params[0] = BOOLEAN_TO_INT((ctx->Transform.ClipPlanesEnabled >> 0) & 1);
+ break;
+ case GL_CLIP_PLANE1:
+ params[0] = BOOLEAN_TO_INT((ctx->Transform.ClipPlanesEnabled >> 1) & 1);
+ break;
+ case GL_CLIP_PLANE2:
+ params[0] = BOOLEAN_TO_INT((ctx->Transform.ClipPlanesEnabled >> 2) & 1);
+ break;
+ case GL_CLIP_PLANE3:
+ params[0] = BOOLEAN_TO_INT((ctx->Transform.ClipPlanesEnabled >> 3) & 1);
+ break;
+ case GL_CLIP_PLANE4:
+ params[0] = BOOLEAN_TO_INT((ctx->Transform.ClipPlanesEnabled >> 4) & 1);
+ break;
+ case GL_CLIP_PLANE5:
+ params[0] = BOOLEAN_TO_INT((ctx->Transform.ClipPlanesEnabled >> 5) & 1);
+ break;
+ case GL_COLOR_CLEAR_VALUE:
+ params[0] = FLOAT_TO_INT(ctx->Color.ClearColor[0]);
+ params[1] = FLOAT_TO_INT(ctx->Color.ClearColor[1]);
+ params[2] = FLOAT_TO_INT(ctx->Color.ClearColor[2]);
+ params[3] = FLOAT_TO_INT(ctx->Color.ClearColor[3]);
+ break;
+ case GL_COLOR_MATERIAL:
+ params[0] = BOOLEAN_TO_INT(ctx->Light.ColorMaterialEnabled);
+ break;
+ case GL_COLOR_MATERIAL_FACE:
+ params[0] = ENUM_TO_INT(ctx->Light.ColorMaterialFace);
+ break;
+ case GL_COLOR_MATERIAL_PARAMETER:
+ params[0] = ENUM_TO_INT(ctx->Light.ColorMaterialMode);
+ break;
+ case GL_COLOR_WRITEMASK:
+ params[0] = ctx->Color.ColorMask[RCOMP] ? 1 : 0;
+ params[1] = ctx->Color.ColorMask[GCOMP] ? 1 : 0;
+ params[2] = ctx->Color.ColorMask[BCOMP] ? 1 : 0;
+ params[3] = ctx->Color.ColorMask[ACOMP] ? 1 : 0;
+ break;
+ case GL_CULL_FACE:
+ params[0] = BOOLEAN_TO_INT(ctx->Polygon.CullFlag);
+ break;
+ case GL_CULL_FACE_MODE:
+ params[0] = ENUM_TO_INT(ctx->Polygon.CullFaceMode);
+ break;
+ case GL_CURRENT_COLOR:
+ {
+ FLUSH_CURRENT(ctx, 0);
+ params[0] = FLOAT_TO_INT(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0]);
+ params[1] = FLOAT_TO_INT(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1]);
+ params[2] = FLOAT_TO_INT(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2]);
+ params[3] = FLOAT_TO_INT(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3]);
+ }
+ break;
+ case GL_CURRENT_INDEX:
+ {
+ FLUSH_CURRENT(ctx, 0);
+ params[0] = IROUND(ctx->Current.Index);
+ }
+ break;
+ case GL_CURRENT_NORMAL:
+ {
+ FLUSH_CURRENT(ctx, 0);
+ params[0] = FLOAT_TO_INT(ctx->Current.Attrib[VERT_ATTRIB_NORMAL][0]);
+ params[1] = FLOAT_TO_INT(ctx->Current.Attrib[VERT_ATTRIB_NORMAL][1]);
+ params[2] = FLOAT_TO_INT(ctx->Current.Attrib[VERT_ATTRIB_NORMAL][2]);
+ }
+ break;
+ case GL_CURRENT_RASTER_COLOR:
+ params[0] = FLOAT_TO_INT(ctx->Current.RasterColor[0]);
+ params[1] = FLOAT_TO_INT(ctx->Current.RasterColor[1]);
+ params[2] = FLOAT_TO_INT(ctx->Current.RasterColor[2]);
+ params[3] = FLOAT_TO_INT(ctx->Current.RasterColor[3]);
+ break;
+ case GL_CURRENT_RASTER_DISTANCE:
+ params[0] = IROUND(ctx->Current.RasterDistance);
+ break;
+ case GL_CURRENT_RASTER_INDEX:
+ params[0] = IROUND(ctx->Current.RasterIndex);
+ break;
+ case GL_CURRENT_RASTER_POSITION:
+ params[0] = IROUND(ctx->Current.RasterPos[0]);
+ params[1] = IROUND(ctx->Current.RasterPos[1]);
+ params[2] = IROUND(ctx->Current.RasterPos[2]);
+ params[3] = IROUND(ctx->Current.RasterPos[3]);
+ break;
+ case GL_CURRENT_RASTER_TEXTURE_COORDS:
+ {
+ const GLuint texUnit = ctx->Texture.CurrentUnit;
+ params[0] = IROUND(ctx->Current.RasterTexCoords[texUnit][0]);
+ params[1] = IROUND(ctx->Current.RasterTexCoords[texUnit][1]);
+ params[2] = IROUND(ctx->Current.RasterTexCoords[texUnit][2]);
+ params[3] = IROUND(ctx->Current.RasterTexCoords[texUnit][3]);
+ }
+ break;
+ case GL_CURRENT_RASTER_POSITION_VALID:
+ params[0] = BOOLEAN_TO_INT(ctx->Current.RasterPosValid);
+ break;
+ case GL_CURRENT_TEXTURE_COORDS:
+ {
+ const GLuint texUnit = ctx->Texture.CurrentUnit;
+ params[0] = IROUND(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][0]);
+ params[1] = IROUND(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][1]);
+ params[2] = IROUND(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][2]);
+ params[3] = IROUND(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][3]);
+ }
+ break;
+ case GL_DEPTH_BIAS:
+ params[0] = IROUND(ctx->Pixel.DepthBias);
+ break;
+ case GL_DEPTH_BITS:
+ params[0] = ctx->DrawBuffer->Visual.depthBits;
+ break;
+ case GL_DEPTH_CLEAR_VALUE:
+ params[0] = IROUND(ctx->Depth.Clear);
+ break;
+ case GL_DEPTH_FUNC:
+ params[0] = ENUM_TO_INT(ctx->Depth.Func);
+ break;
+ case GL_DEPTH_RANGE:
+ params[0] = FLOAT_TO_INT(ctx->Viewport.Near);
+ params[1] = FLOAT_TO_INT(ctx->Viewport.Far);
+ break;
+ case GL_DEPTH_SCALE:
+ params[0] = IROUND(ctx->Pixel.DepthScale);
+ break;
+ case GL_DEPTH_TEST:
+ params[0] = BOOLEAN_TO_INT(ctx->Depth.Test);
+ break;
+ case GL_DEPTH_WRITEMASK:
+ params[0] = BOOLEAN_TO_INT(ctx->Depth.Mask);
+ break;
+ case GL_DITHER:
+ params[0] = BOOLEAN_TO_INT(ctx->Color.DitherFlag);
+ break;
+ case GL_DOUBLEBUFFER:
+ params[0] = BOOLEAN_TO_INT(ctx->DrawBuffer->Visual.doubleBufferMode);
+ break;
+ case GL_DRAW_BUFFER:
+ params[0] = ENUM_TO_INT(ctx->DrawBuffer->ColorDrawBuffer[0]);
+ break;
+ case GL_EDGE_FLAG:
+ {
+ FLUSH_CURRENT(ctx, 0);
+ params[0] = BOOLEAN_TO_INT(ctx->Current.EdgeFlag);
+ }
+ break;
+ case GL_FEEDBACK_BUFFER_SIZE:
+ params[0] = ctx->Feedback.BufferSize;
+ break;
+ case GL_FEEDBACK_BUFFER_TYPE:
+ params[0] = ENUM_TO_INT(ctx->Feedback.Type);
+ break;
+ case GL_FOG:
+ params[0] = BOOLEAN_TO_INT(ctx->Fog.Enabled);
+ break;
+ case GL_FOG_COLOR:
+ params[0] = FLOAT_TO_INT(ctx->Fog.Color[0]);
+ params[1] = FLOAT_TO_INT(ctx->Fog.Color[1]);
+ params[2] = FLOAT_TO_INT(ctx->Fog.Color[2]);
+ params[3] = FLOAT_TO_INT(ctx->Fog.Color[3]);
+ break;
+ case GL_FOG_DENSITY:
+ params[0] = IROUND(ctx->Fog.Density);
+ break;
+ case GL_FOG_END:
+ params[0] = IROUND(ctx->Fog.End);
+ break;
+ case GL_FOG_HINT:
+ params[0] = ENUM_TO_INT(ctx->Hint.Fog);
+ break;
+ case GL_FOG_INDEX:
+ params[0] = IROUND(ctx->Fog.Index);
+ break;
+ case GL_FOG_MODE:
+ params[0] = ENUM_TO_INT(ctx->Fog.Mode);
+ break;
+ case GL_FOG_START:
+ params[0] = IROUND(ctx->Fog.Start);
+ break;
+ case GL_FRONT_FACE:
+ params[0] = ENUM_TO_INT(ctx->Polygon.FrontFace);
+ break;
+ case GL_GREEN_BIAS:
+ params[0] = IROUND(ctx->Pixel.GreenBias);
+ break;
+ case GL_GREEN_BITS:
+ params[0] = ctx->DrawBuffer->Visual.greenBits;
+ break;
+ case GL_GREEN_SCALE:
+ params[0] = IROUND(ctx->Pixel.GreenScale);
+ break;
+ case GL_INDEX_BITS:
+ params[0] = ctx->DrawBuffer->Visual.indexBits;
+ break;
+ case GL_INDEX_CLEAR_VALUE:
+ params[0] = ctx->Color.ClearIndex;
+ break;
+ case GL_INDEX_MODE:
+ params[0] = BOOLEAN_TO_INT(!ctx->DrawBuffer->Visual.rgbMode);
+ break;
+ case GL_INDEX_OFFSET:
+ params[0] = ctx->Pixel.IndexOffset;
+ break;
+ case GL_INDEX_SHIFT:
+ params[0] = ctx->Pixel.IndexShift;
+ break;
+ case GL_INDEX_WRITEMASK:
+ params[0] = ctx->Color.IndexMask;
+ break;
+ case GL_LIGHT0:
+ params[0] = BOOLEAN_TO_INT(ctx->Light.Light[0].Enabled);
+ break;
+ case GL_LIGHT1:
+ params[0] = BOOLEAN_TO_INT(ctx->Light.Light[1].Enabled);
+ break;
+ case GL_LIGHT2:
+ params[0] = BOOLEAN_TO_INT(ctx->Light.Light[2].Enabled);
+ break;
+ case GL_LIGHT3:
+ params[0] = BOOLEAN_TO_INT(ctx->Light.Light[3].Enabled);
+ break;
+ case GL_LIGHT4:
+ params[0] = BOOLEAN_TO_INT(ctx->Light.Light[4].Enabled);
+ break;
+ case GL_LIGHT5:
+ params[0] = BOOLEAN_TO_INT(ctx->Light.Light[5].Enabled);
+ break;
+ case GL_LIGHT6:
+ params[0] = BOOLEAN_TO_INT(ctx->Light.Light[6].Enabled);
+ break;
+ case GL_LIGHT7:
+ params[0] = BOOLEAN_TO_INT(ctx->Light.Light[7].Enabled);
+ break;
+ case GL_LIGHTING:
+ params[0] = BOOLEAN_TO_INT(ctx->Light.Enabled);
+ break;
+ case GL_LIGHT_MODEL_AMBIENT:
+ params[0] = FLOAT_TO_INT(ctx->Light.Model.Ambient[0]);
+ params[1] = FLOAT_TO_INT(ctx->Light.Model.Ambient[1]);
+ params[2] = FLOAT_TO_INT(ctx->Light.Model.Ambient[2]);
+ params[3] = FLOAT_TO_INT(ctx->Light.Model.Ambient[3]);
+ break;
+ case GL_LIGHT_MODEL_COLOR_CONTROL:
+ params[0] = ENUM_TO_INT(ctx->Light.Model.ColorControl);
+ break;
+ case GL_LIGHT_MODEL_LOCAL_VIEWER:
+ params[0] = BOOLEAN_TO_INT(ctx->Light.Model.LocalViewer);
+ break;
+ case GL_LIGHT_MODEL_TWO_SIDE:
+ params[0] = BOOLEAN_TO_INT(ctx->Light.Model.TwoSide);
+ break;
+ case GL_LINE_SMOOTH:
+ params[0] = BOOLEAN_TO_INT(ctx->Line.SmoothFlag);
+ break;
+ case GL_LINE_SMOOTH_HINT:
+ params[0] = ENUM_TO_INT(ctx->Hint.LineSmooth);
+ break;
+ case GL_LINE_STIPPLE:
+ params[0] = BOOLEAN_TO_INT(ctx->Line.StippleFlag);
+ break;
+ case GL_LINE_STIPPLE_PATTERN:
+ params[0] = ctx->Line.StipplePattern;
+ break;
+ case GL_LINE_STIPPLE_REPEAT:
+ params[0] = ctx->Line.StippleFactor;
+ break;
+ case GL_LINE_WIDTH:
+ params[0] = IROUND(ctx->Line.Width);
+ break;
+ case GL_LINE_WIDTH_GRANULARITY:
+ params[0] = IROUND(ctx->Const.LineWidthGranularity);
+ break;
+ case GL_LINE_WIDTH_RANGE:
+ params[0] = IROUND(ctx->Const.MinLineWidthAA);
+ params[1] = IROUND(ctx->Const.MaxLineWidthAA);
+ break;
+ case GL_ALIASED_LINE_WIDTH_RANGE:
+ params[0] = IROUND(ctx->Const.MinLineWidth);
+ params[1] = IROUND(ctx->Const.MaxLineWidth);
+ break;
+ case GL_LIST_BASE:
+ params[0] = ctx->List.ListBase;
+ break;
+ case GL_LIST_INDEX:
+ params[0] = ctx->ListState.CurrentListNum;
+ break;
+ case GL_LIST_MODE:
+ {
+ GLenum mode;
+ if (!ctx->CompileFlag)
+ mode = 0;
+ else if (ctx->ExecuteFlag)
+ mode = GL_COMPILE_AND_EXECUTE;
+ else
+ mode = GL_COMPILE;
+ params[0] = ENUM_TO_INT(mode);
+ }
+ break;
+ case GL_INDEX_LOGIC_OP:
+ params[0] = BOOLEAN_TO_INT(ctx->Color.IndexLogicOpEnabled);
+ break;
+ case GL_COLOR_LOGIC_OP:
+ params[0] = BOOLEAN_TO_INT(ctx->Color.ColorLogicOpEnabled);
+ break;
+ case GL_LOGIC_OP_MODE:
+ params[0] = ENUM_TO_INT(ctx->Color.LogicOp);
+ break;
+ case GL_MAP1_COLOR_4:
+ params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Color4);
+ break;
+ case GL_MAP1_GRID_DOMAIN:
+ params[0] = IROUND(ctx->Eval.MapGrid1u1);
+ params[1] = IROUND(ctx->Eval.MapGrid1u2);
+ break;
+ case GL_MAP1_GRID_SEGMENTS:
+ params[0] = ctx->Eval.MapGrid1un;
+ break;
+ case GL_MAP1_INDEX:
+ params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Index);
+ break;
+ case GL_MAP1_NORMAL:
+ params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Normal);
+ break;
+ case GL_MAP1_TEXTURE_COORD_1:
+ params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1TextureCoord1);
+ break;
+ case GL_MAP1_TEXTURE_COORD_2:
+ params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1TextureCoord2);
+ break;
+ case GL_MAP1_TEXTURE_COORD_3:
+ params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1TextureCoord3);
+ break;
+ case GL_MAP1_TEXTURE_COORD_4:
+ params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1TextureCoord4);
+ break;
+ case GL_MAP1_VERTEX_3:
+ params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Vertex3);
+ break;
+ case GL_MAP1_VERTEX_4:
+ params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Vertex4);
+ break;
+ case GL_MAP2_COLOR_4:
+ params[0] = BOOLEAN_TO_INT(ctx->Eval.Map2Color4);
+ break;
+ case GL_MAP2_GRID_DOMAIN:
+ params[0] = IROUND(ctx->Eval.MapGrid2u1);
+ params[1] = IROUND(ctx->Eval.MapGrid2u2);
+ params[2] = IROUND(ctx->Eval.MapGrid2v1);
+ params[3] = IROUND(ctx->Eval.MapGrid2v2);
+ break;
+ case GL_MAP2_GRID_SEGMENTS:
+ params[0] = ctx->Eval.MapGrid2un;
+ params[1] = ctx->Eval.MapGrid2vn;
+ break;
+ case GL_MAP2_INDEX:
+ params[0] = BOOLEAN_TO_INT(ctx->Eval.Map2Index);
+ break;
+ case GL_MAP2_NORMAL:
+ params[0] = BOOLEAN_TO_INT(ctx->Eval.Map2Normal);
+ break;
+ case GL_MAP2_TEXTURE_COORD_1:
+ params[0] = BOOLEAN_TO_INT(ctx->Eval.Map2TextureCoord1);
+ break;
+ case GL_MAP2_TEXTURE_COORD_2:
+ params[0] = BOOLEAN_TO_INT(ctx->Eval.Map2TextureCoord2);
+ break;
+ case GL_MAP2_TEXTURE_COORD_3:
+ params[0] = BOOLEAN_TO_INT(ctx->Eval.Map2TextureCoord3);
+ break;
+ case GL_MAP2_TEXTURE_COORD_4:
+ params[0] = BOOLEAN_TO_INT(ctx->Eval.Map2TextureCoord4);
+ break;
+ case GL_MAP2_VERTEX_3:
+ params[0] = BOOLEAN_TO_INT(ctx->Eval.Map2Vertex3);
+ break;
+ case GL_MAP2_VERTEX_4:
+ params[0] = BOOLEAN_TO_INT(ctx->Eval.Map2Vertex4);
+ break;
+ case GL_MAP_COLOR:
+ params[0] = BOOLEAN_TO_INT(ctx->Pixel.MapColorFlag);
+ break;
+ case GL_MAP_STENCIL:
+ params[0] = BOOLEAN_TO_INT(ctx->Pixel.MapStencilFlag);
+ break;
+ case GL_MATRIX_MODE:
+ params[0] = ENUM_TO_INT(ctx->Transform.MatrixMode);
+ break;
+ case GL_MAX_ATTRIB_STACK_DEPTH:
+ params[0] = MAX_ATTRIB_STACK_DEPTH;
+ break;
+ case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH:
+ params[0] = MAX_CLIENT_ATTRIB_STACK_DEPTH;
+ break;
+ case GL_MAX_CLIP_PLANES:
+ params[0] = ctx->Const.MaxClipPlanes;
+ break;
+ case GL_MAX_ELEMENTS_VERTICES:
+ params[0] = ctx->Const.MaxArrayLockSize;
+ break;
+ case GL_MAX_ELEMENTS_INDICES:
+ params[0] = ctx->Const.MaxArrayLockSize;
+ break;
+ case GL_MAX_EVAL_ORDER:
+ params[0] = MAX_EVAL_ORDER;
+ break;
+ case GL_MAX_LIGHTS:
+ params[0] = ctx->Const.MaxLights;
+ break;
+ case GL_MAX_LIST_NESTING:
+ params[0] = MAX_LIST_NESTING;
+ break;
+ case GL_MAX_MODELVIEW_STACK_DEPTH:
+ params[0] = MAX_MODELVIEW_STACK_DEPTH;
+ break;
+ case GL_MAX_NAME_STACK_DEPTH:
+ params[0] = MAX_NAME_STACK_DEPTH;
+ break;
+ case GL_MAX_PIXEL_MAP_TABLE:
+ params[0] = MAX_PIXEL_MAP_TABLE;
+ break;
+ case GL_MAX_PROJECTION_STACK_DEPTH:
+ params[0] = MAX_PROJECTION_STACK_DEPTH;
+ break;
+ case GL_MAX_TEXTURE_SIZE:
+ params[0] = 1 << (ctx->Const.MaxTextureLevels - 1);
+ break;
+ case GL_MAX_3D_TEXTURE_SIZE:
+ params[0] = 1 << (ctx->Const.Max3DTextureLevels - 1);
+ break;
+ case GL_MAX_TEXTURE_STACK_DEPTH:
+ params[0] = MAX_TEXTURE_STACK_DEPTH;
+ break;
+ case GL_MAX_VIEWPORT_DIMS:
+ params[0] = ctx->Const.MaxViewportWidth;
+ params[1] = ctx->Const.MaxViewportHeight;
+ break;
+ case GL_MODELVIEW_MATRIX:
+ {
+ const GLfloat *matrix = ctx->ModelviewMatrixStack.Top->m;
+ params[0] = IROUND(matrix[0]);
+ params[1] = IROUND(matrix[1]);
+ params[2] = IROUND(matrix[2]);
+ params[3] = IROUND(matrix[3]);
+ params[4] = IROUND(matrix[4]);
+ params[5] = IROUND(matrix[5]);
+ params[6] = IROUND(matrix[6]);
+ params[7] = IROUND(matrix[7]);
+ params[8] = IROUND(matrix[8]);
+ params[9] = IROUND(matrix[9]);
+ params[10] = IROUND(matrix[10]);
+ params[11] = IROUND(matrix[11]);
+ params[12] = IROUND(matrix[12]);
+ params[13] = IROUND(matrix[13]);
+ params[14] = IROUND(matrix[14]);
+ params[15] = IROUND(matrix[15]);
+ }
+ break;
+ case GL_MODELVIEW_STACK_DEPTH:
+ params[0] = ctx->ModelviewMatrixStack.Depth + 1;
+ break;
+ case GL_NAME_STACK_DEPTH:
+ params[0] = ctx->Select.NameStackDepth;
+ break;
+ case GL_NORMALIZE:
+ params[0] = BOOLEAN_TO_INT(ctx->Transform.Normalize);
+ break;
+ case GL_PACK_ALIGNMENT:
+ params[0] = ctx->Pack.Alignment;
+ break;
+ case GL_PACK_LSB_FIRST:
+ params[0] = BOOLEAN_TO_INT(ctx->Pack.LsbFirst);
+ break;
+ case GL_PACK_ROW_LENGTH:
+ params[0] = ctx->Pack.RowLength;
+ break;
+ case GL_PACK_SKIP_PIXELS:
+ params[0] = ctx->Pack.SkipPixels;
+ break;
+ case GL_PACK_SKIP_ROWS:
+ params[0] = ctx->Pack.SkipRows;
+ break;
+ case GL_PACK_SWAP_BYTES:
+ params[0] = BOOLEAN_TO_INT(ctx->Pack.SwapBytes);
+ break;
+ case GL_PACK_SKIP_IMAGES_EXT:
+ params[0] = ctx->Pack.SkipImages;
+ break;
+ case GL_PACK_IMAGE_HEIGHT_EXT:
+ params[0] = ctx->Pack.ImageHeight;
+ break;
+ case GL_PACK_INVERT_MESA:
+ params[0] = BOOLEAN_TO_INT(ctx->Pack.Invert);
+ break;
+ case GL_PERSPECTIVE_CORRECTION_HINT:
+ params[0] = ENUM_TO_INT(ctx->Hint.PerspectiveCorrection);
+ break;
+ case GL_PIXEL_MAP_A_TO_A_SIZE:
+ params[0] = ctx->Pixel.MapAtoAsize;
+ break;
+ case GL_PIXEL_MAP_B_TO_B_SIZE:
+ params[0] = ctx->Pixel.MapBtoBsize;
+ break;
+ case GL_PIXEL_MAP_G_TO_G_SIZE:
+ params[0] = ctx->Pixel.MapGtoGsize;
+ break;
+ case GL_PIXEL_MAP_I_TO_A_SIZE:
+ params[0] = ctx->Pixel.MapItoAsize;
+ break;
+ case GL_PIXEL_MAP_I_TO_B_SIZE:
+ params[0] = ctx->Pixel.MapItoBsize;
+ break;
+ case GL_PIXEL_MAP_I_TO_G_SIZE:
+ params[0] = ctx->Pixel.MapItoGsize;
+ break;
+ case GL_PIXEL_MAP_I_TO_I_SIZE:
+ params[0] = ctx->Pixel.MapItoIsize;
+ break;
+ case GL_PIXEL_MAP_I_TO_R_SIZE:
+ params[0] = ctx->Pixel.MapItoRsize;
+ break;
+ case GL_PIXEL_MAP_R_TO_R_SIZE:
+ params[0] = ctx->Pixel.MapRtoRsize;
+ break;
+ case GL_PIXEL_MAP_S_TO_S_SIZE:
+ params[0] = ctx->Pixel.MapStoSsize;
+ break;
+ case GL_POINT_SIZE:
+ params[0] = IROUND(ctx->Point.Size);
+ break;
+ case GL_POINT_SIZE_GRANULARITY:
+ params[0] = IROUND(ctx->Const.PointSizeGranularity);
+ break;
+ case GL_POINT_SIZE_RANGE:
+ params[0] = IROUND(ctx->Const.MinPointSizeAA);
+ params[1] = IROUND(ctx->Const.MaxPointSizeAA);
+ break;
+ case GL_ALIASED_POINT_SIZE_RANGE:
+ params[0] = IROUND(ctx->Const.MinPointSize);
+ params[1] = IROUND(ctx->Const.MaxPointSize);
+ break;
+ case GL_POINT_SMOOTH:
+ params[0] = BOOLEAN_TO_INT(ctx->Point.SmoothFlag);
+ break;
+ case GL_POINT_SMOOTH_HINT:
+ params[0] = ENUM_TO_INT(ctx->Hint.PointSmooth);
+ break;
+ case GL_POINT_SIZE_MIN_EXT:
+ params[0] = IROUND(ctx->Point.MinSize);
+ break;
+ case GL_POINT_SIZE_MAX_EXT:
+ params[0] = IROUND(ctx->Point.MaxSize);
+ break;
+ case GL_POINT_FADE_THRESHOLD_SIZE_EXT:
+ params[0] = IROUND(ctx->Point.Threshold);
+ break;
+ case GL_DISTANCE_ATTENUATION_EXT:
+ params[0] = IROUND(ctx->Point.Params[0]);
+ params[1] = IROUND(ctx->Point.Params[1]);
+ params[2] = IROUND(ctx->Point.Params[2]);
+ break;
+ case GL_POLYGON_MODE:
+ params[0] = ENUM_TO_INT(ctx->Polygon.FrontMode);
+ params[1] = ENUM_TO_INT(ctx->Polygon.BackMode);
+ break;
+ case GL_POLYGON_OFFSET_BIAS_EXT:
+ params[0] = IROUND(ctx->Polygon.OffsetUnits);
+ break;
+ case GL_POLYGON_OFFSET_FACTOR:
+ params[0] = IROUND(ctx->Polygon.OffsetFactor );
+ break;
+ case GL_POLYGON_OFFSET_UNITS:
+ params[0] = IROUND(ctx->Polygon.OffsetUnits );
+ break;
+ case GL_POLYGON_SMOOTH:
+ params[0] = BOOLEAN_TO_INT(ctx->Polygon.SmoothFlag);
+ break;
+ case GL_POLYGON_SMOOTH_HINT:
+ params[0] = ENUM_TO_INT(ctx->Hint.PolygonSmooth);
+ break;
+ case GL_POLYGON_STIPPLE:
+ params[0] = BOOLEAN_TO_INT(ctx->Polygon.StippleFlag);
+ break;
+ case GL_PROJECTION_MATRIX:
+ {
+ const GLfloat *matrix = ctx->ProjectionMatrixStack.Top->m;
+ params[0] = IROUND(matrix[0]);
+ params[1] = IROUND(matrix[1]);
+ params[2] = IROUND(matrix[2]);
+ params[3] = IROUND(matrix[3]);
+ params[4] = IROUND(matrix[4]);
+ params[5] = IROUND(matrix[5]);
+ params[6] = IROUND(matrix[6]);
+ params[7] = IROUND(matrix[7]);
+ params[8] = IROUND(matrix[8]);
+ params[9] = IROUND(matrix[9]);
+ params[10] = IROUND(matrix[10]);
+ params[11] = IROUND(matrix[11]);
+ params[12] = IROUND(matrix[12]);
+ params[13] = IROUND(matrix[13]);
+ params[14] = IROUND(matrix[14]);
+ params[15] = IROUND(matrix[15]);
+ }
+ break;
+ case GL_PROJECTION_STACK_DEPTH:
+ params[0] = ctx->ProjectionMatrixStack.Depth + 1;
+ break;
+ case GL_READ_BUFFER:
+ params[0] = ENUM_TO_INT(ctx->ReadBuffer->ColorReadBuffer);
+ break;
+ case GL_RED_BIAS:
+ params[0] = IROUND(ctx->Pixel.RedBias);
+ break;
+ case GL_RED_BITS:
+ params[0] = ctx->DrawBuffer->Visual.redBits ;
+ break;
+ case GL_RED_SCALE:
+ params[0] = IROUND(ctx->Pixel.RedScale);
+ break;
+ case GL_RENDER_MODE:
+ params[0] = ENUM_TO_INT(ctx->RenderMode);
+ break;
+ case GL_RESCALE_NORMAL:
+ params[0] = BOOLEAN_TO_INT(ctx->Transform.RescaleNormals);
+ break;
+ case GL_RGBA_MODE:
+ params[0] = BOOLEAN_TO_INT(ctx->DrawBuffer->Visual.rgbMode);
+ break;
+ case GL_SCISSOR_BOX:
+ params[0] = ctx->Scissor.X;
+ params[1] = ctx->Scissor.Y;
+ params[2] = ctx->Scissor.Width;
+ params[3] = ctx->Scissor.Height;
+ break;
+ case GL_SCISSOR_TEST:
+ params[0] = BOOLEAN_TO_INT(ctx->Scissor.Enabled);
+ break;
+ case GL_SELECTION_BUFFER_SIZE:
+ params[0] = ctx->Select.BufferSize;
+ break;
+ case GL_SHADE_MODEL:
+ params[0] = ENUM_TO_INT(ctx->Light.ShadeModel);
+ break;
+ case GL_SHARED_TEXTURE_PALETTE_EXT:
+ params[0] = BOOLEAN_TO_INT(ctx->Texture.SharedPalette);
+ break;
+ case GL_STENCIL_BITS:
+ params[0] = ctx->DrawBuffer->Visual.stencilBits;
+ break;
+ case GL_STENCIL_CLEAR_VALUE:
+ params[0] = ctx->Stencil.Clear;
+ break;
+ case GL_STENCIL_FAIL:
+ params[0] = ENUM_TO_INT(ctx->Stencil.FailFunc[ctx->Stencil.ActiveFace]);
+ break;
+ case GL_STENCIL_FUNC:
+ params[0] = ENUM_TO_INT(ctx->Stencil.Function[ctx->Stencil.ActiveFace]);
+ break;
+ case GL_STENCIL_PASS_DEPTH_FAIL:
+ params[0] = ENUM_TO_INT(ctx->Stencil.ZFailFunc[ctx->Stencil.ActiveFace]);
+ break;
+ case GL_STENCIL_PASS_DEPTH_PASS:
+ params[0] = ENUM_TO_INT(ctx->Stencil.ZPassFunc[ctx->Stencil.ActiveFace]);
+ break;
+ case GL_STENCIL_REF:
+ params[0] = ctx->Stencil.Ref[ctx->Stencil.ActiveFace];
+ break;
+ case GL_STENCIL_TEST:
+ params[0] = BOOLEAN_TO_INT(ctx->Stencil.Enabled);
+ break;
+ case GL_STENCIL_VALUE_MASK:
+ params[0] = ctx->Stencil.ValueMask[ctx->Stencil.ActiveFace];
+ break;
+ case GL_STENCIL_WRITEMASK:
+ params[0] = ctx->Stencil.WriteMask[ctx->Stencil.ActiveFace];
+ break;
+ case GL_STEREO:
+ params[0] = BOOLEAN_TO_INT(ctx->DrawBuffer->Visual.stereoMode);
+ break;
+ case GL_SUBPIXEL_BITS:
+ params[0] = ctx->Const.SubPixelBits;
+ break;
+ case GL_TEXTURE_1D:
+ params[0] = BOOLEAN_TO_INT(_mesa_IsEnabled(GL_TEXTURE_1D));
+ break;
+ case GL_TEXTURE_2D:
+ params[0] = BOOLEAN_TO_INT(_mesa_IsEnabled(GL_TEXTURE_2D));
+ break;
+ case GL_TEXTURE_3D:
+ params[0] = BOOLEAN_TO_INT(_mesa_IsEnabled(GL_TEXTURE_3D));
+ break;
+ case GL_TEXTURE_BINDING_1D:
+ params[0] = ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current1D->Name;
+ break;
+ case GL_TEXTURE_BINDING_2D:
+ params[0] = ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current2D->Name;
+ break;
+ case GL_TEXTURE_BINDING_3D:
+ params[0] = ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current3D->Name;
+ break;
+ case GL_TEXTURE_ENV_COLOR:
+ {
+ const GLfloat *color = ctx->Texture.Unit[ctx->Texture.CurrentUnit].EnvColor;
+ params[0] = FLOAT_TO_INT(color[0]);
+ params[1] = FLOAT_TO_INT(color[1]);
+ params[2] = FLOAT_TO_INT(color[2]);
+ params[3] = FLOAT_TO_INT(color[3]);
+ }
+ break;
+ case GL_TEXTURE_ENV_MODE:
+ params[0] = ENUM_TO_INT(ctx->Texture.Unit[ctx->Texture.CurrentUnit].EnvMode);
+ break;
+ case GL_TEXTURE_GEN_S:
+ params[0] = BOOLEAN_TO_INT(((ctx->Texture.Unit[ctx->Texture.CurrentUnit].TexGenEnabled & S_BIT) ? 1 : 0));
+ break;
+ case GL_TEXTURE_GEN_T:
+ params[0] = BOOLEAN_TO_INT(((ctx->Texture.Unit[ctx->Texture.CurrentUnit].TexGenEnabled & T_BIT) ? 1 : 0));
+ break;
+ case GL_TEXTURE_GEN_R:
+ params[0] = BOOLEAN_TO_INT(((ctx->Texture.Unit[ctx->Texture.CurrentUnit].TexGenEnabled & R_BIT) ? 1 : 0));
+ break;
+ case GL_TEXTURE_GEN_Q:
+ params[0] = BOOLEAN_TO_INT(((ctx->Texture.Unit[ctx->Texture.CurrentUnit].TexGenEnabled & Q_BIT) ? 1 : 0));
+ break;
+ case GL_TEXTURE_MATRIX:
+ {
+ const GLfloat *matrix = ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Top->m;
+ params[0] = IROUND(matrix[0]);
+ params[1] = IROUND(matrix[1]);
+ params[2] = IROUND(matrix[2]);
+ params[3] = IROUND(matrix[3]);
+ params[4] = IROUND(matrix[4]);
+ params[5] = IROUND(matrix[5]);
+ params[6] = IROUND(matrix[6]);
+ params[7] = IROUND(matrix[7]);
+ params[8] = IROUND(matrix[8]);
+ params[9] = IROUND(matrix[9]);
+ params[10] = IROUND(matrix[10]);
+ params[11] = IROUND(matrix[11]);
+ params[12] = IROUND(matrix[12]);
+ params[13] = IROUND(matrix[13]);
+ params[14] = IROUND(matrix[14]);
+ params[15] = IROUND(matrix[15]);
+ }
+ break;
+ case GL_TEXTURE_STACK_DEPTH:
+ params[0] = ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Depth + 1;
+ break;
+ case GL_UNPACK_ALIGNMENT:
+ params[0] = ctx->Unpack.Alignment;
+ break;
+ case GL_UNPACK_LSB_FIRST:
+ params[0] = BOOLEAN_TO_INT(ctx->Unpack.LsbFirst);
+ break;
+ case GL_UNPACK_ROW_LENGTH:
+ params[0] = ctx->Unpack.RowLength;
+ break;
+ case GL_UNPACK_SKIP_PIXELS:
+ params[0] = ctx->Unpack.SkipPixels;
+ break;
+ case GL_UNPACK_SKIP_ROWS:
+ params[0] = ctx->Unpack.SkipRows;
+ break;
+ case GL_UNPACK_SWAP_BYTES:
+ params[0] = BOOLEAN_TO_INT(ctx->Unpack.SwapBytes);
+ break;
+ case GL_UNPACK_SKIP_IMAGES_EXT:
+ params[0] = ctx->Unpack.SkipImages;
+ break;
+ case GL_UNPACK_IMAGE_HEIGHT_EXT:
+ params[0] = ctx->Unpack.ImageHeight;
+ break;
+ case GL_UNPACK_CLIENT_STORAGE_APPLE:
+ params[0] = BOOLEAN_TO_INT(ctx->Unpack.ClientStorage);
+ break;
+ case GL_VIEWPORT:
+ params[0] = ctx->Viewport.X;
+ params[1] = ctx->Viewport.Y;
+ params[2] = ctx->Viewport.Width;
+ params[3] = ctx->Viewport.Height;
+ break;
+ case GL_ZOOM_X:
+ params[0] = IROUND(ctx->Pixel.ZoomX);
+ break;
+ case GL_ZOOM_Y:
+ params[0] = IROUND(ctx->Pixel.ZoomY);
+ break;
+ case GL_VERTEX_ARRAY:
+ params[0] = BOOLEAN_TO_INT(ctx->Array.Vertex.Enabled);
+ break;
+ case GL_VERTEX_ARRAY_SIZE:
+ params[0] = ctx->Array.Vertex.Size;
+ break;
+ case GL_VERTEX_ARRAY_TYPE:
+ params[0] = ENUM_TO_INT(ctx->Array.Vertex.Type);
+ break;
+ case GL_VERTEX_ARRAY_STRIDE:
+ params[0] = ctx->Array.Vertex.Stride;
+ break;
+ case GL_VERTEX_ARRAY_COUNT_EXT:
+ params[0] = 0;
+ break;
+ case GL_NORMAL_ARRAY:
+ params[0] = ENUM_TO_INT(ctx->Array.Normal.Enabled);
+ break;
+ case GL_NORMAL_ARRAY_TYPE:
+ params[0] = ENUM_TO_INT(ctx->Array.Normal.Type);
+ break;
+ case GL_NORMAL_ARRAY_STRIDE:
+ params[0] = ctx->Array.Normal.Stride;
+ break;
+ case GL_NORMAL_ARRAY_COUNT_EXT:
+ params[0] = 0;
+ break;
+ case GL_COLOR_ARRAY:
+ params[0] = BOOLEAN_TO_INT(ctx->Array.Color.Enabled);
+ break;
+ case GL_COLOR_ARRAY_SIZE:
+ params[0] = ctx->Array.Color.Size;
+ break;
+ case GL_COLOR_ARRAY_TYPE:
+ params[0] = ENUM_TO_INT(ctx->Array.Color.Type);
+ break;
+ case GL_COLOR_ARRAY_STRIDE:
+ params[0] = ctx->Array.Color.Stride;
+ break;
+ case GL_COLOR_ARRAY_COUNT_EXT:
+ params[0] = 0;
+ break;
+ case GL_INDEX_ARRAY:
+ params[0] = BOOLEAN_TO_INT(ctx->Array.Index.Enabled);
+ break;
+ case GL_INDEX_ARRAY_TYPE:
+ params[0] = ENUM_TO_INT(ctx->Array.Index.Type);
+ break;
+ case GL_INDEX_ARRAY_STRIDE:
+ params[0] = ctx->Array.Index.Stride;
+ break;
+ case GL_INDEX_ARRAY_COUNT_EXT:
+ params[0] = 0;
+ break;
+ case GL_TEXTURE_COORD_ARRAY:
+ params[0] = BOOLEAN_TO_INT(ctx->Array.TexCoord[ctx->Array.ActiveTexture].Enabled);
+ break;
+ case GL_TEXTURE_COORD_ARRAY_SIZE:
+ params[0] = ctx->Array.TexCoord[ctx->Array.ActiveTexture].Size;
+ break;
+ case GL_TEXTURE_COORD_ARRAY_TYPE:
+ params[0] = ENUM_TO_INT(ctx->Array.TexCoord[ctx->Array.ActiveTexture].Type);
+ break;
+ case GL_TEXTURE_COORD_ARRAY_STRIDE:
+ params[0] = ctx->Array.TexCoord[ctx->Array.ActiveTexture].Stride;
+ break;
+ case GL_TEXTURE_COORD_ARRAY_COUNT_EXT:
+ params[0] = 0;
+ break;
+ case GL_EDGE_FLAG_ARRAY:
+ params[0] = BOOLEAN_TO_INT(ctx->Array.EdgeFlag.Enabled);
+ break;
+ case GL_EDGE_FLAG_ARRAY_STRIDE:
+ params[0] = ctx->Array.EdgeFlag.Stride;
+ break;
+ case GL_EDGE_FLAG_ARRAY_COUNT_EXT:
+ params[0] = 0;
+ break;
+ case GL_MAX_TEXTURE_UNITS_ARB:
+ CHECK_EXT1(ARB_multitexture, "GetIntegerv");
+ params[0] = MIN2(ctx->Const.MaxTextureImageUnits, ctx->Const.MaxTextureCoordUnits);
+ break;
+ case GL_ACTIVE_TEXTURE_ARB:
+ CHECK_EXT1(ARB_multitexture, "GetIntegerv");
+ params[0] = GL_TEXTURE0_ARB + ctx->Texture.CurrentUnit;
+ break;
+ case GL_CLIENT_ACTIVE_TEXTURE_ARB:
+ CHECK_EXT1(ARB_multitexture, "GetIntegerv");
+ params[0] = GL_TEXTURE0_ARB + ctx->Array.ActiveTexture;
+ break;
+ case GL_TEXTURE_CUBE_MAP_ARB:
+ CHECK_EXT1(ARB_texture_cube_map, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(_mesa_IsEnabled(GL_TEXTURE_CUBE_MAP_ARB));
+ break;
+ case GL_TEXTURE_BINDING_CUBE_MAP_ARB:
+ CHECK_EXT1(ARB_texture_cube_map, "GetIntegerv");
+ params[0] = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentCubeMap->Name;
+ break;
+ case GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB:
+ CHECK_EXT1(ARB_texture_cube_map, "GetIntegerv");
+ params[0] = (1 << (ctx->Const.MaxCubeTextureLevels - 1));
+ break;
+ case GL_TEXTURE_COMPRESSION_HINT_ARB:
+ CHECK_EXT1(ARB_texture_compression, "GetIntegerv");
+ params[0] = ctx->Hint.TextureCompression;
+ break;
+ case GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB:
+ CHECK_EXT1(ARB_texture_compression, "GetIntegerv");
+ params[0] = _mesa_get_compressed_formats(ctx, NULL);
+ break;
+ case GL_COMPRESSED_TEXTURE_FORMATS_ARB:
+ CHECK_EXT1(ARB_texture_compression, "GetIntegerv");
+ {
+ GLint formats[100];
+ GLuint i, n = _mesa_get_compressed_formats(ctx, formats);
+ ASSERT(n <= 100);
+ for (i = 0; i < n; i++)
+ params[i] = ENUM_TO_INT(formats[i]);
+ }
+ break;
+ case GL_ARRAY_ELEMENT_LOCK_FIRST_EXT:
+ CHECK_EXT1(EXT_compiled_vertex_array, "GetIntegerv");
+ params[0] = ctx->Array.LockFirst;
+ break;
+ case GL_ARRAY_ELEMENT_LOCK_COUNT_EXT:
+ CHECK_EXT1(EXT_compiled_vertex_array, "GetIntegerv");
+ params[0] = ctx->Array.LockCount;
+ break;
+ case GL_TRANSPOSE_COLOR_MATRIX_ARB:
+ {
+ const GLfloat *matrix = ctx->ColorMatrixStack.Top->m;
+ params[0] = IROUND(matrix[0]);
+ params[1] = IROUND(matrix[4]);
+ params[2] = IROUND(matrix[8]);
+ params[3] = IROUND(matrix[12]);
+ params[4] = IROUND(matrix[1]);
+ params[5] = IROUND(matrix[5]);
+ params[6] = IROUND(matrix[9]);
+ params[7] = IROUND(matrix[13]);
+ params[8] = IROUND(matrix[2]);
+ params[9] = IROUND(matrix[6]);
+ params[10] = IROUND(matrix[10]);
+ params[11] = IROUND(matrix[14]);
+ params[12] = IROUND(matrix[3]);
+ params[13] = IROUND(matrix[7]);
+ params[14] = IROUND(matrix[11]);
+ params[15] = IROUND(matrix[15]);
+ }
+ break;
+ case GL_TRANSPOSE_MODELVIEW_MATRIX_ARB:
+ {
+ const GLfloat *matrix = ctx->ModelviewMatrixStack.Top->m;
+ params[0] = IROUND(matrix[0]);
+ params[1] = IROUND(matrix[4]);
+ params[2] = IROUND(matrix[8]);
+ params[3] = IROUND(matrix[12]);
+ params[4] = IROUND(matrix[1]);
+ params[5] = IROUND(matrix[5]);
+ params[6] = IROUND(matrix[9]);
+ params[7] = IROUND(matrix[13]);
+ params[8] = IROUND(matrix[2]);
+ params[9] = IROUND(matrix[6]);
+ params[10] = IROUND(matrix[10]);
+ params[11] = IROUND(matrix[14]);
+ params[12] = IROUND(matrix[3]);
+ params[13] = IROUND(matrix[7]);
+ params[14] = IROUND(matrix[11]);
+ params[15] = IROUND(matrix[15]);
+ }
+ break;
+ case GL_TRANSPOSE_PROJECTION_MATRIX_ARB:
+ {
+ const GLfloat *matrix = ctx->ProjectionMatrixStack.Top->m;
+ params[0] = IROUND(matrix[0]);
+ params[1] = IROUND(matrix[4]);
+ params[2] = IROUND(matrix[8]);
+ params[3] = IROUND(matrix[12]);
+ params[4] = IROUND(matrix[1]);
+ params[5] = IROUND(matrix[5]);
+ params[6] = IROUND(matrix[9]);
+ params[7] = IROUND(matrix[13]);
+ params[8] = IROUND(matrix[2]);
+ params[9] = IROUND(matrix[6]);
+ params[10] = IROUND(matrix[10]);
+ params[11] = IROUND(matrix[14]);
+ params[12] = IROUND(matrix[3]);
+ params[13] = IROUND(matrix[7]);
+ params[14] = IROUND(matrix[11]);
+ params[15] = IROUND(matrix[15]);
+ }
+ break;
+ case GL_TRANSPOSE_TEXTURE_MATRIX_ARB:
+ {
+ const GLfloat *matrix = ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Top->m;
+ params[0] = IROUND(matrix[0]);
+ params[1] = IROUND(matrix[4]);
+ params[2] = IROUND(matrix[8]);
+ params[3] = IROUND(matrix[12]);
+ params[4] = IROUND(matrix[1]);
+ params[5] = IROUND(matrix[5]);
+ params[6] = IROUND(matrix[9]);
+ params[7] = IROUND(matrix[13]);
+ params[8] = IROUND(matrix[2]);
+ params[9] = IROUND(matrix[6]);
+ params[10] = IROUND(matrix[10]);
+ params[11] = IROUND(matrix[14]);
+ params[12] = IROUND(matrix[3]);
+ params[13] = IROUND(matrix[7]);
+ params[14] = IROUND(matrix[11]);
+ params[15] = IROUND(matrix[15]);
+ }
+ break;
+ case GL_COLOR_MATRIX_SGI:
+ {
+ const GLfloat *matrix = ctx->ColorMatrixStack.Top->m;
+ params[0] = IROUND(matrix[0]);
+ params[1] = IROUND(matrix[1]);
+ params[2] = IROUND(matrix[2]);
+ params[3] = IROUND(matrix[3]);
+ params[4] = IROUND(matrix[4]);
+ params[5] = IROUND(matrix[5]);
+ params[6] = IROUND(matrix[6]);
+ params[7] = IROUND(matrix[7]);
+ params[8] = IROUND(matrix[8]);
+ params[9] = IROUND(matrix[9]);
+ params[10] = IROUND(matrix[10]);
+ params[11] = IROUND(matrix[11]);
+ params[12] = IROUND(matrix[12]);
+ params[13] = IROUND(matrix[13]);
+ params[14] = IROUND(matrix[14]);
+ params[15] = IROUND(matrix[15]);
+ }
+ break;
+ case GL_COLOR_MATRIX_STACK_DEPTH_SGI:
+ params[0] = ctx->ColorMatrixStack.Depth + 1;
+ break;
+ case GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI:
+ params[0] = MAX_COLOR_STACK_DEPTH;
+ break;
+ case GL_POST_COLOR_MATRIX_RED_SCALE_SGI:
+ params[0] = IROUND(ctx->Pixel.PostColorMatrixScale[0]);
+ break;
+ case GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI:
+ params[0] = IROUND(ctx->Pixel.PostColorMatrixScale[1]);
+ break;
+ case GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI:
+ params[0] = IROUND(ctx->Pixel.PostColorMatrixScale[2]);
+ break;
+ case GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI:
+ params[0] = IROUND(ctx->Pixel.PostColorMatrixScale[3]);
+ break;
+ case GL_POST_COLOR_MATRIX_RED_BIAS_SGI:
+ params[0] = IROUND(ctx->Pixel.PostColorMatrixBias[0]);
+ break;
+ case GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI:
+ params[0] = IROUND(ctx->Pixel.PostColorMatrixBias[1]);
+ break;
+ case GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI:
+ params[0] = IROUND(ctx->Pixel.PostColorMatrixBias[2]);
+ break;
+ case GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI:
+ params[0] = IROUND(ctx->Pixel.PostColorMatrixBias[3]);
+ break;
+ case GL_CONVOLUTION_1D_EXT:
+ CHECK_EXT1(EXT_convolution, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Pixel.Convolution1DEnabled);
+ break;
+ case GL_CONVOLUTION_2D_EXT:
+ CHECK_EXT1(EXT_convolution, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Pixel.Convolution2DEnabled);
+ break;
+ case GL_SEPARABLE_2D_EXT:
+ CHECK_EXT1(EXT_convolution, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Pixel.Separable2DEnabled);
+ break;
+ case GL_POST_CONVOLUTION_RED_SCALE_EXT:
+ CHECK_EXT1(EXT_convolution, "GetIntegerv");
+ params[0] = IROUND(ctx->Pixel.PostConvolutionScale[0]);
+ break;
+ case GL_POST_CONVOLUTION_GREEN_SCALE_EXT:
+ CHECK_EXT1(EXT_convolution, "GetIntegerv");
+ params[0] = IROUND(ctx->Pixel.PostConvolutionScale[1]);
+ break;
+ case GL_POST_CONVOLUTION_BLUE_SCALE_EXT:
+ CHECK_EXT1(EXT_convolution, "GetIntegerv");
+ params[0] = IROUND(ctx->Pixel.PostConvolutionScale[2]);
+ break;
+ case GL_POST_CONVOLUTION_ALPHA_SCALE_EXT:
+ CHECK_EXT1(EXT_convolution, "GetIntegerv");
+ params[0] = IROUND(ctx->Pixel.PostConvolutionScale[3]);
+ break;
+ case GL_POST_CONVOLUTION_RED_BIAS_EXT:
+ CHECK_EXT1(EXT_convolution, "GetIntegerv");
+ params[0] = IROUND(ctx->Pixel.PostConvolutionBias[0]);
+ break;
+ case GL_POST_CONVOLUTION_GREEN_BIAS_EXT:
+ CHECK_EXT1(EXT_convolution, "GetIntegerv");
+ params[0] = IROUND(ctx->Pixel.PostConvolutionBias[1]);
+ break;
+ case GL_POST_CONVOLUTION_BLUE_BIAS_EXT:
+ CHECK_EXT1(EXT_convolution, "GetIntegerv");
+ params[0] = IROUND(ctx->Pixel.PostConvolutionBias[2]);
+ break;
+ case GL_POST_CONVOLUTION_ALPHA_BIAS_EXT:
+ CHECK_EXT1(EXT_convolution, "GetIntegerv");
+ params[0] = IROUND(ctx->Pixel.PostConvolutionBias[3]);
+ break;
+ case GL_HISTOGRAM:
+ CHECK_EXT1(EXT_histogram, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Pixel.HistogramEnabled);
+ break;
+ case GL_MINMAX:
+ CHECK_EXT1(EXT_histogram, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Pixel.MinMaxEnabled);
+ break;
+ case GL_COLOR_TABLE_SGI:
+ CHECK_EXT1(SGI_color_table, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Pixel.ColorTableEnabled);
+ break;
+ case GL_POST_CONVOLUTION_COLOR_TABLE_SGI:
+ CHECK_EXT1(SGI_color_table, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Pixel.PostConvolutionColorTableEnabled);
+ break;
+ case GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI:
+ CHECK_EXT1(SGI_color_table, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Pixel.PostColorMatrixColorTableEnabled);
+ break;
+ case GL_TEXTURE_COLOR_TABLE_SGI:
+ CHECK_EXT1(SGI_texture_color_table, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Texture.Unit[ctx->Texture.CurrentUnit].ColorTableEnabled);
+ break;
+ case GL_COLOR_SUM_EXT:
+ CHECK_EXT2(EXT_secondary_color, ARB_vertex_program, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Fog.ColorSumEnabled);
+ break;
+ case GL_CURRENT_SECONDARY_COLOR_EXT:
+ CHECK_EXT1(EXT_secondary_color, "GetIntegerv");
+ {
+ FLUSH_CURRENT(ctx, 0);
+ params[0] = FLOAT_TO_INT(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0]);
+ params[1] = FLOAT_TO_INT(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1]);
+ params[2] = FLOAT_TO_INT(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2]);
+ params[3] = FLOAT_TO_INT(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][3]);
+ }
+ break;
+ case GL_SECONDARY_COLOR_ARRAY_EXT:
+ CHECK_EXT1(EXT_secondary_color, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Array.SecondaryColor.Enabled);
+ break;
+ case GL_SECONDARY_COLOR_ARRAY_TYPE_EXT:
+ CHECK_EXT1(EXT_secondary_color, "GetIntegerv");
+ params[0] = ENUM_TO_INT(ctx->Array.SecondaryColor.Type);
+ break;
+ case GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT:
+ CHECK_EXT1(EXT_secondary_color, "GetIntegerv");
+ params[0] = ctx->Array.SecondaryColor.Stride;
+ break;
+ case GL_SECONDARY_COLOR_ARRAY_SIZE_EXT:
+ CHECK_EXT1(EXT_secondary_color, "GetIntegerv");
+ params[0] = ctx->Array.SecondaryColor.Size;
+ break;
+ case GL_CURRENT_FOG_COORDINATE_EXT:
+ CHECK_EXT1(EXT_fog_coord, "GetIntegerv");
+ {
+ FLUSH_CURRENT(ctx, 0);
+ params[0] = IROUND(ctx->Current.Attrib[VERT_ATTRIB_FOG][0]);
+ }
+ break;
+ case GL_FOG_COORDINATE_ARRAY_EXT:
+ CHECK_EXT1(EXT_fog_coord, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Array.FogCoord.Enabled);
+ break;
+ case GL_FOG_COORDINATE_ARRAY_TYPE_EXT:
+ CHECK_EXT1(EXT_fog_coord, "GetIntegerv");
+ params[0] = ENUM_TO_INT(ctx->Array.FogCoord.Type);
+ break;
+ case GL_FOG_COORDINATE_ARRAY_STRIDE_EXT:
+ CHECK_EXT1(EXT_fog_coord, "GetIntegerv");
+ params[0] = ctx->Array.FogCoord.Stride;
+ break;
+ case GL_FOG_COORDINATE_SOURCE_EXT:
+ CHECK_EXT1(EXT_fog_coord, "GetIntegerv");
+ params[0] = ENUM_TO_INT(ctx->Fog.FogCoordinateSource);
+ break;
+ case GL_MAX_TEXTURE_LOD_BIAS_EXT:
+ CHECK_EXT1(EXT_texture_lod_bias, "GetIntegerv");
+ params[0] = IROUND(ctx->Const.MaxTextureLodBias);
+ break;
+ case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
+ CHECK_EXT1(EXT_texture_filter_anisotropic, "GetIntegerv");
+ params[0] = IROUND(ctx->Const.MaxTextureMaxAnisotropy);
+ break;
+ case GL_MULTISAMPLE_ARB:
+ CHECK_EXT1(ARB_multisample, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Multisample.Enabled);
+ break;
+ case GL_SAMPLE_ALPHA_TO_COVERAGE_ARB:
+ CHECK_EXT1(ARB_multisample, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Multisample.SampleAlphaToCoverage);
+ break;
+ case GL_SAMPLE_ALPHA_TO_ONE_ARB:
+ CHECK_EXT1(ARB_multisample, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Multisample.SampleAlphaToOne);
+ break;
+ case GL_SAMPLE_COVERAGE_ARB:
+ CHECK_EXT1(ARB_multisample, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Multisample.SampleCoverage);
+ break;
+ case GL_SAMPLE_COVERAGE_VALUE_ARB:
+ CHECK_EXT1(ARB_multisample, "GetIntegerv");
+ params[0] = IROUND(ctx->Multisample.SampleCoverageValue);
+ break;
+ case GL_SAMPLE_COVERAGE_INVERT_ARB:
+ CHECK_EXT1(ARB_multisample, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Multisample.SampleCoverageInvert);
+ break;
+ case GL_SAMPLE_BUFFERS_ARB:
+ CHECK_EXT1(ARB_multisample, "GetIntegerv");
+ params[0] = ctx->DrawBuffer->Visual.sampleBuffers;
+ break;
+ case GL_SAMPLES_ARB:
+ CHECK_EXT1(ARB_multisample, "GetIntegerv");
+ params[0] = ctx->DrawBuffer->Visual.samples;
+ break;
+ case GL_RASTER_POSITION_UNCLIPPED_IBM:
+ CHECK_EXT1(IBM_rasterpos_clip, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Transform.RasterPositionUnclipped);
+ break;
+ case GL_POINT_SPRITE_NV:
+ CHECK_EXT2(NV_point_sprite, ARB_point_sprite, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Point.PointSprite);
+ break;
+ case GL_POINT_SPRITE_R_MODE_NV:
+ CHECK_EXT1(NV_point_sprite, "GetIntegerv");
+ params[0] = ENUM_TO_INT(ctx->Point.SpriteRMode);
+ break;
+ case GL_POINT_SPRITE_COORD_ORIGIN:
+ CHECK_EXT2(NV_point_sprite, ARB_point_sprite, "GetIntegerv");
+ params[0] = ENUM_TO_INT(ctx->Point.SpriteOrigin);
+ break;
+ case GL_GENERATE_MIPMAP_HINT_SGIS:
+ CHECK_EXT1(SGIS_generate_mipmap, "GetIntegerv");
+ params[0] = ENUM_TO_INT(ctx->Hint.GenerateMipmap);
+ break;
+ case GL_VERTEX_PROGRAM_BINDING_NV:
+ CHECK_EXT1(NV_vertex_program, "GetIntegerv");
+ params[0] = (ctx->VertexProgram.Current ? ctx->VertexProgram.Current->Base.Id : 0);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY0_NV:
+ CHECK_EXT1(NV_vertex_program, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Array.VertexAttrib[0].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY1_NV:
+ CHECK_EXT1(NV_vertex_program, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Array.VertexAttrib[1].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY2_NV:
+ CHECK_EXT1(NV_vertex_program, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Array.VertexAttrib[2].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY3_NV:
+ CHECK_EXT1(NV_vertex_program, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Array.VertexAttrib[3].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Array.VertexAttrib[4].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY5_NV:
+ CHECK_EXT1(NV_vertex_program, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Array.VertexAttrib[5].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY6_NV:
+ CHECK_EXT1(NV_vertex_program, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Array.VertexAttrib[6].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY7_NV:
+ CHECK_EXT1(NV_vertex_program, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Array.VertexAttrib[7].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY8_NV:
+ CHECK_EXT1(NV_vertex_program, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Array.VertexAttrib[8].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY9_NV:
+ CHECK_EXT1(NV_vertex_program, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Array.VertexAttrib[9].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY10_NV:
+ CHECK_EXT1(NV_vertex_program, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Array.VertexAttrib[10].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY11_NV:
+ CHECK_EXT1(NV_vertex_program, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Array.VertexAttrib[11].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY12_NV:
+ CHECK_EXT1(NV_vertex_program, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Array.VertexAttrib[12].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY13_NV:
+ CHECK_EXT1(NV_vertex_program, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Array.VertexAttrib[13].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY14_NV:
+ CHECK_EXT1(NV_vertex_program, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Array.VertexAttrib[14].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY15_NV:
+ CHECK_EXT1(NV_vertex_program, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Array.VertexAttrib[15].Enabled);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB0_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Attrib[0]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB1_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Attrib[1]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB2_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Attrib[2]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB3_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Attrib[3]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB4_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Attrib[4]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB5_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Attrib[5]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB6_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Attrib[6]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB7_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Attrib[7]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB8_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Attrib[8]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB9_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Attrib[9]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB10_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Attrib[10]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB11_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Attrib[11]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB12_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Attrib[12]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB13_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Attrib[13]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB14_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Attrib[14]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB15_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Attrib[15]);
+ break;
+ case GL_FRAGMENT_PROGRAM_NV:
+ CHECK_EXT1(NV_fragment_program, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->FragmentProgram.Enabled);
+ break;
+ case GL_FRAGMENT_PROGRAM_BINDING_NV:
+ CHECK_EXT1(NV_fragment_program, "GetIntegerv");
+ params[0] = ctx->FragmentProgram.Current ? ctx->FragmentProgram.Current->Base.Id : 0;
+ break;
+ case GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV:
+ CHECK_EXT1(NV_fragment_program, "GetIntegerv");
+ params[0] = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
+ break;
+ case GL_TEXTURE_RECTANGLE_NV:
+ CHECK_EXT1(NV_texture_rectangle, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(_mesa_IsEnabled(GL_TEXTURE_RECTANGLE_NV));
+ break;
+ case GL_TEXTURE_BINDING_RECTANGLE_NV:
+ CHECK_EXT1(NV_texture_rectangle, "GetIntegerv");
+ params[0] = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentRect->Name;
+ break;
+ case GL_MAX_RECTANGLE_TEXTURE_SIZE_NV:
+ CHECK_EXT1(NV_texture_rectangle, "GetIntegerv");
+ params[0] = ctx->Const.MaxTextureRectSize;
+ break;
+ case GL_STENCIL_TEST_TWO_SIDE_EXT:
+ CHECK_EXT1(EXT_stencil_two_side, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Stencil.TestTwoSide);
+ break;
+ case GL_ACTIVE_STENCIL_FACE_EXT:
+ CHECK_EXT1(EXT_stencil_two_side, "GetIntegerv");
+ params[0] = ENUM_TO_INT(ctx->Stencil.ActiveFace ? GL_BACK : GL_FRONT);
+ break;
+ case GL_MAX_SHININESS_NV:
+ CHECK_EXT1(NV_light_max_exponent, "GetIntegerv");
+ params[0] = IROUND(ctx->Const.MaxShininess);
+ break;
+ case GL_MAX_SPOT_EXPONENT_NV:
+ CHECK_EXT1(NV_light_max_exponent, "GetIntegerv");
+ params[0] = IROUND(ctx->Const.MaxSpotExponent);
+ break;
+ case GL_ARRAY_BUFFER_BINDING_ARB:
+ CHECK_EXT1(ARB_vertex_buffer_object, "GetIntegerv");
+ params[0] = ctx->Array.ArrayBufferObj->Name;
+ break;
+ case GL_VERTEX_ARRAY_BUFFER_BINDING_ARB:
+ CHECK_EXT1(ARB_vertex_buffer_object, "GetIntegerv");
+ params[0] = ctx->Array.Vertex.BufferObj->Name;
+ break;
+ case GL_NORMAL_ARRAY_BUFFER_BINDING_ARB:
+ CHECK_EXT1(ARB_vertex_buffer_object, "GetIntegerv");
+ params[0] = ctx->Array.Normal.BufferObj->Name;
+ break;
+ case GL_COLOR_ARRAY_BUFFER_BINDING_ARB:
+ CHECK_EXT1(ARB_vertex_buffer_object, "GetIntegerv");
+ params[0] = ctx->Array.Color.BufferObj->Name;
+ break;
+ case GL_INDEX_ARRAY_BUFFER_BINDING_ARB:
+ CHECK_EXT1(ARB_vertex_buffer_object, "GetIntegerv");
+ params[0] = ctx->Array.Index.BufferObj->Name;
+ break;
+ case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB:
+ CHECK_EXT1(ARB_vertex_buffer_object, "GetIntegerv");
+ params[0] = ctx->Array.TexCoord[ctx->Array.ActiveTexture].BufferObj->Name;
+ break;
+ case GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB:
+ CHECK_EXT1(ARB_vertex_buffer_object, "GetIntegerv");
+ params[0] = ctx->Array.EdgeFlag.BufferObj->Name;
+ break;
+ case GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB:
+ CHECK_EXT1(ARB_vertex_buffer_object, "GetIntegerv");
+ params[0] = ctx->Array.SecondaryColor.BufferObj->Name;
+ break;
+ case GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB:
+ CHECK_EXT1(ARB_vertex_buffer_object, "GetIntegerv");
+ params[0] = ctx->Array.FogCoord.BufferObj->Name;
+ break;
+ case GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB:
+ CHECK_EXT1(ARB_vertex_buffer_object, "GetIntegerv");
+ params[0] = ctx->Array.ElementArrayBufferObj->Name;
+ break;
+ case GL_PIXEL_PACK_BUFFER_BINDING_EXT:
+ CHECK_EXT1(EXT_pixel_buffer_object, "GetIntegerv");
+ params[0] = ctx->Pack.BufferObj->Name;
+ break;
+ case GL_PIXEL_UNPACK_BUFFER_BINDING_EXT:
+ CHECK_EXT1(EXT_pixel_buffer_object, "GetIntegerv");
+ params[0] = ctx->Unpack.BufferObj->Name;
+ break;
+ case GL_VERTEX_PROGRAM_ARB:
+ CHECK_EXT2(ARB_vertex_program, NV_vertex_program, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->VertexProgram.Enabled);
+ break;
+ case GL_VERTEX_PROGRAM_POINT_SIZE_ARB:
+ CHECK_EXT2(ARB_vertex_program, NV_vertex_program, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->VertexProgram.PointSizeEnabled);
+ break;
+ case GL_VERTEX_PROGRAM_TWO_SIDE_ARB:
+ CHECK_EXT2(ARB_vertex_program, NV_vertex_program, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->VertexProgram.TwoSideEnabled);
+ break;
+ case GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB:
+ CHECK_EXT3(ARB_vertex_program, ARB_fragment_program, NV_vertex_program, "GetIntegerv");
+ params[0] = ctx->Const.MaxProgramMatrixStackDepth;
+ break;
+ case GL_MAX_PROGRAM_MATRICES_ARB:
+ CHECK_EXT3(ARB_vertex_program, ARB_fragment_program, NV_vertex_program, "GetIntegerv");
+ params[0] = ctx->Const.MaxProgramMatrices;
+ break;
+ case GL_CURRENT_MATRIX_STACK_DEPTH_ARB:
+ CHECK_EXT3(ARB_vertex_program, ARB_fragment_program, NV_vertex_program, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->CurrentStack->Depth + 1);
+ break;
+ case GL_CURRENT_MATRIX_ARB:
+ CHECK_EXT3(ARB_vertex_program, ARB_fragment_program, NV_fragment_program, "GetIntegerv");
+ {
+ const GLfloat *matrix = ctx->CurrentStack->Top->m;
+ params[0] = IROUND(matrix[0]);
+ params[1] = IROUND(matrix[1]);
+ params[2] = IROUND(matrix[2]);
+ params[3] = IROUND(matrix[3]);
+ params[4] = IROUND(matrix[4]);
+ params[5] = IROUND(matrix[5]);
+ params[6] = IROUND(matrix[6]);
+ params[7] = IROUND(matrix[7]);
+ params[8] = IROUND(matrix[8]);
+ params[9] = IROUND(matrix[9]);
+ params[10] = IROUND(matrix[10]);
+ params[11] = IROUND(matrix[11]);
+ params[12] = IROUND(matrix[12]);
+ params[13] = IROUND(matrix[13]);
+ params[14] = IROUND(matrix[14]);
+ params[15] = IROUND(matrix[15]);
+ }
+ break;
+ case GL_TRANSPOSE_CURRENT_MATRIX_ARB:
+ CHECK_EXT2(ARB_vertex_program, ARB_fragment_program, "GetIntegerv");
+ {
+ const GLfloat *matrix = ctx->CurrentStack->Top->m;
+ params[0] = IROUND(matrix[0]);
+ params[1] = IROUND(matrix[4]);
+ params[2] = IROUND(matrix[8]);
+ params[3] = IROUND(matrix[12]);
+ params[4] = IROUND(matrix[1]);
+ params[5] = IROUND(matrix[5]);
+ params[6] = IROUND(matrix[9]);
+ params[7] = IROUND(matrix[13]);
+ params[8] = IROUND(matrix[2]);
+ params[9] = IROUND(matrix[6]);
+ params[10] = IROUND(matrix[10]);
+ params[11] = IROUND(matrix[14]);
+ params[12] = IROUND(matrix[3]);
+ params[13] = IROUND(matrix[7]);
+ params[14] = IROUND(matrix[11]);
+ params[15] = IROUND(matrix[15]);
+ }
+ break;
+ case GL_MAX_VERTEX_ATTRIBS_ARB:
+ CHECK_EXT1(ARB_vertex_program, "GetIntegerv");
+ params[0] = ctx->Const.VertexProgram.MaxAttribs;
+ break;
+ case GL_PROGRAM_ERROR_POSITION_ARB:
+ CHECK_EXT4(NV_vertex_program, ARB_vertex_program, NV_fragment_program, ARB_fragment_program, "GetIntegerv");
+ params[0] = ctx->Program.ErrorPos;
+ break;
+ case GL_FRAGMENT_PROGRAM_ARB:
+ CHECK_EXT1(ARB_fragment_program, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->FragmentProgram.Enabled);
+ break;
+ case GL_MAX_TEXTURE_COORDS_ARB:
+ CHECK_EXT2(ARB_fragment_program, NV_fragment_program, "GetIntegerv");
+ params[0] = ctx->Const.MaxTextureCoordUnits;
+ break;
+ case GL_MAX_TEXTURE_IMAGE_UNITS_ARB:
+ CHECK_EXT2(ARB_fragment_program, NV_fragment_program, "GetIntegerv");
+ params[0] = ctx->Const.MaxTextureImageUnits;
+ break;
+ case GL_DEPTH_BOUNDS_TEST_EXT:
+ CHECK_EXT1(EXT_depth_bounds_test, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Depth.BoundsTest);
+ break;
+ case GL_DEPTH_BOUNDS_EXT:
+ CHECK_EXT1(EXT_depth_bounds_test, "GetIntegerv");
+ params[0] = IROUND(ctx->Depth.BoundsMin);
+ params[1] = IROUND(ctx->Depth.BoundsMax);
+ break;
+ case GL_FRAGMENT_PROGRAM_CALLBACK_MESA:
+ CHECK_EXT1(MESA_program_debug, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->FragmentProgram.CallbackEnabled);
+ break;
+ case GL_VERTEX_PROGRAM_CALLBACK_MESA:
+ CHECK_EXT1(MESA_program_debug, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->VertexProgram.CallbackEnabled);
+ break;
+ case GL_FRAGMENT_PROGRAM_POSITION_MESA:
+ CHECK_EXT1(MESA_program_debug, "GetIntegerv");
+ params[0] = ctx->FragmentProgram.CurrentPosition;
+ break;
+ case GL_VERTEX_PROGRAM_POSITION_MESA:
+ CHECK_EXT1(MESA_program_debug, "GetIntegerv");
+ params[0] = ctx->VertexProgram.CurrentPosition;
+ break;
+ case GL_MAX_DRAW_BUFFERS_ARB:
+ CHECK_EXT1(ARB_draw_buffers, "GetIntegerv");
+ params[0] = ctx->Const.MaxDrawBuffers;
+ break;
+ case GL_DRAW_BUFFER0_ARB:
+ CHECK_EXT1(ARB_draw_buffers, "GetIntegerv");
+ params[0] = ENUM_TO_INT(ctx->DrawBuffer->ColorDrawBuffer[0]);
+ break;
+ case GL_DRAW_BUFFER1_ARB:
+ CHECK_EXT1(ARB_draw_buffers, "GetIntegerv");
+ {
+ GLenum buffer;
+ if (pname - GL_DRAW_BUFFER0_ARB >= ctx->Const.MaxDrawBuffers) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGet(GL_DRAW_BUFFERx_ARB)");
+ return;
+ }
+ buffer = ctx->DrawBuffer->ColorDrawBuffer[1];
+ params[0] = ENUM_TO_INT(buffer);
+ }
+ break;
+ case GL_DRAW_BUFFER2_ARB:
+ CHECK_EXT1(ARB_draw_buffers, "GetIntegerv");
+ {
+ GLenum buffer;
+ if (pname - GL_DRAW_BUFFER0_ARB >= ctx->Const.MaxDrawBuffers) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGet(GL_DRAW_BUFFERx_ARB)");
+ return;
+ }
+ buffer = ctx->DrawBuffer->ColorDrawBuffer[2];
+ params[0] = ENUM_TO_INT(buffer);
+ }
+ break;
+ case GL_DRAW_BUFFER3_ARB:
+ CHECK_EXT1(ARB_draw_buffers, "GetIntegerv");
+ {
+ GLenum buffer;
+ if (pname - GL_DRAW_BUFFER0_ARB >= ctx->Const.MaxDrawBuffers) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGet(GL_DRAW_BUFFERx_ARB)");
+ return;
+ }
+ buffer = ctx->DrawBuffer->ColorDrawBuffer[3];
+ params[0] = ENUM_TO_INT(buffer);
+ }
+ break;
+ case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
+ CHECK_EXT1(OES_read_format, "GetIntegerv");
+ params[0] = ctx->Const.ColorReadType;
+ break;
+ case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
+ CHECK_EXT1(OES_read_format, "GetIntegerv");
+ params[0] = ctx->Const.ColorReadFormat;
+ break;
+ case GL_NUM_FRAGMENT_REGISTERS_ATI:
+ CHECK_EXT1(ATI_fragment_shader, "GetIntegerv");
+ params[0] = 6;
+ break;
+ case GL_NUM_FRAGMENT_CONSTANTS_ATI:
+ CHECK_EXT1(ATI_fragment_shader, "GetIntegerv");
+ params[0] = 8;
+ break;
+ case GL_NUM_PASSES_ATI:
+ CHECK_EXT1(ATI_fragment_shader, "GetIntegerv");
+ params[0] = 2;
+ break;
+ case GL_NUM_INSTRUCTIONS_PER_PASS_ATI:
+ CHECK_EXT1(ATI_fragment_shader, "GetIntegerv");
+ params[0] = 8;
+ break;
+ case GL_NUM_INSTRUCTIONS_TOTAL_ATI:
+ CHECK_EXT1(ATI_fragment_shader, "GetIntegerv");
+ params[0] = 16;
+ break;
+ case GL_COLOR_ALPHA_PAIRING_ATI:
+ CHECK_EXT1(ATI_fragment_shader, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(GL_TRUE);
+ break;
+ case GL_NUM_LOOPBACK_COMPONENTS_ATI:
+ CHECK_EXT1(ATI_fragment_shader, "GetIntegerv");
+ params[0] = 3;
+ break;
+ case GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI:
+ CHECK_EXT1(ATI_fragment_shader, "GetIntegerv");
+ params[0] = 3;
+ break;
+ case GL_STENCIL_BACK_FUNC:
+ params[0] = ENUM_TO_INT(ctx->Stencil.Function[1]);
+ break;
+ case GL_STENCIL_BACK_VALUE_MASK:
+ params[0] = ctx->Stencil.ValueMask[1];
+ break;
+ case GL_STENCIL_BACK_REF:
+ params[0] = ctx->Stencil.Ref[1];
+ break;
+ case GL_STENCIL_BACK_FAIL:
+ params[0] = ENUM_TO_INT(ctx->Stencil.FailFunc[1]);
+ break;
+ case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
+ params[0] = ENUM_TO_INT(ctx->Stencil.ZFailFunc[1]);
+ break;
+ case GL_STENCIL_BACK_PASS_DEPTH_PASS:
+ params[0] = ENUM_TO_INT(ctx->Stencil.ZPassFunc[1]);
+ break;
+ case GL_FRAMEBUFFER_BINDING_EXT:
+ CHECK_EXT1(EXT_framebuffer_object, "GetIntegerv");
+ params[0] = ctx->DrawBuffer->Name;
+ break;
+ case GL_RENDERBUFFER_BINDING_EXT:
+ CHECK_EXT1(EXT_framebuffer_object, "GetIntegerv");
+ params[0] = ctx->CurrentRenderbuffer ? ctx->CurrentRenderbuffer->Name : 0;
+ break;
+ case GL_MAX_COLOR_ATTACHMENTS_EXT:
+ CHECK_EXT1(EXT_framebuffer_object, "GetIntegerv");
+ params[0] = ctx->Const.MaxColorAttachments;
+ break;
+ case GL_MAX_RENDERBUFFER_SIZE_EXT:
+ CHECK_EXT1(EXT_framebuffer_object, "GetIntegerv");
+ params[0] = ctx->Const.MaxRenderbufferSize;
+ break;
+ case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB:
+ CHECK_EXT1(ARB_fragment_shader, "GetIntegerv");
+ params[0] = MAX_FRAGMENT_UNIFORM_COMPONENTS;
+ break;
+ case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB:
+ CHECK_EXT1(ARB_fragment_shader, "GetIntegerv");
+ params[0] = ENUM_TO_INT(ctx->Hint.FragmentShaderDerivative);
+ break;
+ case GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB:
+ CHECK_EXT1(ARB_vertex_shader, "GetIntegerv");
+ params[0] = MAX_VERTEX_UNIFORM_COMPONENTS;
+ break;
+ case GL_MAX_VARYING_FLOATS_ARB:
+ CHECK_EXT1(ARB_vertex_shader, "GetIntegerv");
+ params[0] = MAX_VARYING_FLOATS;
+ break;
+ case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB:
+ CHECK_EXT1(ARB_vertex_shader, "GetIntegerv");
+ params[0] = MAX_VERTEX_TEXTURE_IMAGE_UNITS;
+ break;
+ case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB:
+ CHECK_EXT1(ARB_vertex_shader, "GetIntegerv");
+ params[0] = MAX_COMBINED_TEXTURE_IMAGE_UNITS;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetIntegerv(pname=0x%x)", pname);
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_GetDoublev( GLenum pname, GLdouble *params )
+{
+ const GLfloat magic = -1234.5F;
+ GLfloat values[16];
+ GLuint i;
+
+ if (!params)
+ return;
+
+ /* Init temp array to magic numbers so we can figure out how many values
+ * are returned by the GetFloatv() call.
+ */
+ for (i = 0; i < 16; i++)
+ values[i] = magic;
+
+ _mesa_GetFloatv(pname, values);
+
+ for (i = 0; i < 16 && values[i] != magic; i++)
+ params[i] = (GLdouble) values[i];
+}
+
diff --git a/src/mesa/main/get.h b/src/mesa/main/get.h
new file mode 100644
index 00000000000..9b47b230a98
--- /dev/null
+++ b/src/mesa/main/get.h
@@ -0,0 +1,59 @@
+/**
+ * \file get.h
+ * State query functions.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.5
+ *
+ * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef GET_H
+#define GET_H
+
+
+#include "mtypes.h"
+
+
+extern void GLAPIENTRY
+_mesa_GetBooleanv( GLenum pname, GLboolean *params );
+
+extern void GLAPIENTRY
+_mesa_GetDoublev( GLenum pname, GLdouble *params );
+
+extern void GLAPIENTRY
+_mesa_GetFloatv( GLenum pname, GLfloat *params );
+
+extern void GLAPIENTRY
+_mesa_GetIntegerv( GLenum pname, GLint *params );
+
+extern void GLAPIENTRY
+_mesa_GetPointerv( GLenum pname, GLvoid **params );
+
+extern const GLubyte * GLAPIENTRY
+_mesa_GetString( GLenum name );
+
+extern GLenum GLAPIENTRY
+_mesa_GetError( void );
+
+#endif
diff --git a/src/mesa/main/getstring.c b/src/mesa/main/getstring.c
new file mode 100644
index 00000000000..5188a79c951
--- /dev/null
+++ b/src/mesa/main/getstring.c
@@ -0,0 +1,261 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.3
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+#include "glheader.h"
+#include "colormac.h"
+#include "context.h"
+#include "get.h"
+#include "version.h"
+#include "enums.h"
+#include "extensions.h"
+
+
+/**
+ * Query string-valued state. The return value should _not_ be freed by
+ * the caller.
+ *
+ * \param name the state variable to query.
+ *
+ * \sa glGetString().
+ *
+ * Tries to get the string from dd_function_table::GetString, otherwise returns
+ * the hardcoded strings.
+ */
+const GLubyte * GLAPIENTRY
+_mesa_GetString( GLenum name )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ static const char *vendor = "Brian Paul";
+ static const char *renderer = "Mesa";
+ static const char *version_1_2 = "1.2 Mesa " MESA_VERSION_STRING;
+ static const char *version_1_3 = "1.3 Mesa " MESA_VERSION_STRING;
+ static const char *version_1_4 = "1.4 Mesa " MESA_VERSION_STRING;
+ static const char *version_1_5 = "1.5 Mesa " MESA_VERSION_STRING;
+ static const char *version_2_0 = "1.5 Mesa " MESA_VERSION_STRING;/*XXX FIX*/
+
+ ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, NULL);
+
+ /* this is a required driver function */
+ assert(ctx->Driver.GetString);
+ {
+ /* Give the driver the chance to handle this query */
+ const GLubyte *str = (*ctx->Driver.GetString)(ctx, name);
+ if (str)
+ return str;
+ }
+
+ switch (name) {
+ case GL_VENDOR:
+ return (const GLubyte *) vendor;
+ case GL_RENDERER:
+ return (const GLubyte *) renderer;
+ case GL_VERSION:
+ if (ctx->Extensions.ARB_multisample &&
+ ctx->Extensions.ARB_multitexture &&
+ ctx->Extensions.ARB_texture_border_clamp &&
+ ctx->Extensions.ARB_texture_compression &&
+ ctx->Extensions.ARB_texture_cube_map &&
+ ctx->Extensions.EXT_texture_env_add &&
+ ctx->Extensions.ARB_texture_env_combine &&
+ ctx->Extensions.ARB_texture_env_dot3) {
+ if (ctx->Extensions.ARB_depth_texture &&
+ ctx->Extensions.ARB_shadow &&
+ ctx->Extensions.ARB_texture_env_crossbar &&
+ ctx->Extensions.ARB_texture_mirrored_repeat &&
+ ctx->Extensions.ARB_window_pos &&
+ ctx->Extensions.EXT_blend_color &&
+ ctx->Extensions.EXT_blend_func_separate &&
+ ctx->Extensions.EXT_blend_logic_op &&
+ ctx->Extensions.EXT_blend_minmax &&
+ ctx->Extensions.EXT_blend_subtract &&
+ ctx->Extensions.EXT_fog_coord &&
+ ctx->Extensions.EXT_multi_draw_arrays &&
+ ctx->Extensions.EXT_point_parameters && /*aka ARB*/
+ ctx->Extensions.EXT_secondary_color &&
+ ctx->Extensions.EXT_stencil_wrap &&
+ ctx->Extensions.EXT_texture_lod_bias &&
+ ctx->Extensions.SGIS_generate_mipmap) {
+ if (ctx->Extensions.ARB_occlusion_query &&
+ ctx->Extensions.ARB_vertex_buffer_object &&
+ ctx->Extensions.EXT_shadow_funcs) {
+ if (ctx->Extensions.ARB_draw_buffers &&
+ ctx->Extensions.ARB_point_sprite &&
+ ctx->Extensions.ARB_texture_non_power_of_two &&
+ ctx->Extensions.EXT_stencil_two_side) {
+ return (const GLubyte *) version_2_0;
+ }
+ else {
+ return (const GLubyte *) version_1_5;
+ }
+ }
+ else {
+ return (const GLubyte *) version_1_4;
+ }
+ }
+ else {
+ return (const GLubyte *) version_1_3;
+ }
+ }
+ else {
+ return (const GLubyte *) version_1_2;
+ }
+ case GL_EXTENSIONS:
+ if (!ctx->Extensions.String)
+ ctx->Extensions.String = _mesa_make_extension_string(ctx);
+ return (const GLubyte *) ctx->Extensions.String;
+#if FEATURE_NV_fragment_program || FEATURE_ARB_fragment_program || \
+ FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program
+ case GL_PROGRAM_ERROR_STRING_NV:
+ if (ctx->Extensions.NV_fragment_program ||
+ ctx->Extensions.ARB_fragment_program ||
+ ctx->Extensions.NV_vertex_program ||
+ ctx->Extensions.ARB_vertex_program) {
+ return (const GLubyte *) ctx->Program.ErrorString;
+ }
+ /* FALL-THROUGH */
+#endif
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetString" );
+ return (const GLubyte *) 0;
+ }
+}
+
+
+/**
+ * Return pointer-valued state, such as a vertex array pointer.
+ *
+ * \param pname names state to be queried
+ * \param params returns the pointer value
+ *
+ * \sa glGetPointerv().
+ *
+ * Tries to get the specified pointer via dd_function_table::GetPointerv,
+ * otherwise gets the specified pointer from the current context.
+ */
+void GLAPIENTRY
+_mesa_GetPointerv( GLenum pname, GLvoid **params )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ const GLuint clientUnit = ctx->Array.ActiveTexture;
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (!params)
+ return;
+
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx, "glGetPointerv %s\n", _mesa_lookup_enum_by_nr(pname));
+
+ if (ctx->Driver.GetPointerv
+ && (*ctx->Driver.GetPointerv)(ctx, pname, params))
+ return;
+
+ switch (pname) {
+ case GL_VERTEX_ARRAY_POINTER:
+ *params = (GLvoid *) ctx->Array.Vertex.Ptr;
+ break;
+ case GL_NORMAL_ARRAY_POINTER:
+ *params = (GLvoid *) ctx->Array.Normal.Ptr;
+ break;
+ case GL_COLOR_ARRAY_POINTER:
+ *params = (GLvoid *) ctx->Array.Color.Ptr;
+ break;
+ case GL_SECONDARY_COLOR_ARRAY_POINTER_EXT:
+ *params = (GLvoid *) ctx->Array.SecondaryColor.Ptr;
+ break;
+ case GL_FOG_COORDINATE_ARRAY_POINTER_EXT:
+ *params = (GLvoid *) ctx->Array.FogCoord.Ptr;
+ break;
+ case GL_INDEX_ARRAY_POINTER:
+ *params = (GLvoid *) ctx->Array.Index.Ptr;
+ break;
+ case GL_TEXTURE_COORD_ARRAY_POINTER:
+ *params = (GLvoid *) ctx->Array.TexCoord[clientUnit].Ptr;
+ break;
+ case GL_EDGE_FLAG_ARRAY_POINTER:
+ *params = (GLvoid *) ctx->Array.EdgeFlag.Ptr;
+ break;
+ case GL_FEEDBACK_BUFFER_POINTER:
+ *params = ctx->Feedback.Buffer;
+ break;
+ case GL_SELECTION_BUFFER_POINTER:
+ *params = ctx->Select.Buffer;
+ break;
+#if FEATURE_MESA_program_debug
+ case GL_FRAGMENT_PROGRAM_CALLBACK_FUNC_MESA:
+ if (!ctx->Extensions.MESA_program_debug) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetPointerv");
+ return;
+ }
+ *params = *(GLvoid **) &ctx->FragmentProgram.Callback;
+ break;
+ case GL_FRAGMENT_PROGRAM_CALLBACK_DATA_MESA:
+ if (!ctx->Extensions.MESA_program_debug) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetPointerv");
+ return;
+ }
+ *params = ctx->FragmentProgram.CallbackData;
+ break;
+ case GL_VERTEX_PROGRAM_CALLBACK_FUNC_MESA:
+ if (!ctx->Extensions.MESA_program_debug) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetPointerv");
+ return;
+ }
+ *params = *(GLvoid **) &ctx->VertexProgram.Callback;
+ break;
+ case GL_VERTEX_PROGRAM_CALLBACK_DATA_MESA:
+ if (!ctx->Extensions.MESA_program_debug) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetPointerv");
+ return;
+ }
+ *params = ctx->VertexProgram.CallbackData;
+ break;
+#endif
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetPointerv" );
+ return;
+ }
+}
+
+
+/**
+ * Returns the current GL error code, or GL_NO_ERROR.
+ * \return current error code
+ *
+ * Returns __GLcontextRec::ErrorValue.
+ */
+GLenum GLAPIENTRY
+_mesa_GetError( void )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLenum e = ctx->ErrorValue;
+ ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0);
+
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx, "glGetError <-- %s\n", _mesa_lookup_enum_by_nr(e));
+
+ ctx->ErrorValue = (GLenum) GL_NO_ERROR;
+ return e;
+}
diff --git a/src/mesa/main/glheader.h b/src/mesa/main/glheader.h
new file mode 100644
index 00000000000..0ebadaa9fa6
--- /dev/null
+++ b/src/mesa/main/glheader.h
@@ -0,0 +1,258 @@
+/**
+ * \file glheader.h
+ * Top-most include file.
+ *
+ * This is the top-most include file of the Mesa sources.
+ * It includes gl.h and all system headers which are needed.
+ * Other Mesa source files should \e not directly include any system
+ * headers. This allows Mesa to be integrated into XFree86 and
+ * allows system-dependent hacks/workarounds to be collected in one place.
+ *
+ * \note Actually, a lot of system-dependent stuff is now in imports.[ch].
+ *
+ * If you touch this file, everything gets recompiled!
+ *
+ * This file should be included before any other header in the .c files.
+ *
+ * Put compiler/OS/assembly pragmas and macros here to avoid
+ * cluttering other source files.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef GLHEADER_H
+#define GLHEADER_H
+
+#ifdef HAVE_DIX_CONFIG_H
+#include "dix-config.h"
+#endif
+
+#if defined(XFree86LOADER) && defined(IN_MODULE) && !defined(NO_LIBCWRAPPER)
+#include "xf86_ansic.h"
+#else
+#include <assert.h>
+#include <ctype.h>
+/* If we can use Compaq's Fast Math Library on Alpha */
+#if defined(__alpha__) && defined(CCPML)
+#include <cpml.h>
+#else
+#include <math.h>
+#endif
+#include <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#if defined(__linux__) && defined(__i386__)
+#include <fpu_control.h>
+#endif
+#endif
+#include <float.h>
+#include <stdarg.h>
+
+
+/* Get typedefs for uintptr_t and friends */
+#if defined(__MINGW32__) || defined(__NetBSD__)
+# include <stdint.h>
+#elif defined(_WIN32)
+# include <BaseTsd.h>
+# if _MSC_VER == 1200
+ typedef UINT_PTR uintptr_t;
+# endif
+#else
+# include <inttypes.h>
+#endif
+
+#if defined(_WIN32) && !defined(__WIN32__) && !defined(__CYGWIN__) && !defined(BUILD_FOR_SNAP)
+# define __WIN32__
+# define finite _finite
+#endif
+
+#if defined(__WATCOMC__)
+# define finite _finite
+# pragma disable_message(201) /* Disable unreachable code warnings */
+#endif
+
+
+#if !defined(OPENSTEP) && (defined(__WIN32__) && !defined(__CYGWIN__)) && !defined(BUILD_FOR_SNAP)
+# if !defined(__GNUC__) /* mingw environment */
+# pragma warning( disable : 4068 ) /* unknown pragma */
+# pragma warning( disable : 4710 ) /* function 'foo' not inlined */
+# pragma warning( disable : 4711 ) /* function 'foo' selected for automatic inline expansion */
+# pragma warning( disable : 4127 ) /* conditional expression is constant */
+# if defined(MESA_MINWARN)
+# pragma warning( disable : 4244 ) /* '=' : conversion from 'const double ' to 'float ', possible loss of data */
+# pragma warning( disable : 4018 ) /* '<' : signed/unsigned mismatch */
+# pragma warning( disable : 4305 ) /* '=' : truncation from 'const double ' to 'float ' */
+# pragma warning( disable : 4550 ) /* 'function' undefined; assuming extern returning int */
+# pragma warning( disable : 4761 ) /* integral size mismatch in argument; conversion supplied */
+# endif
+# endif
+# if (defined(_MSC_VER) || defined(__MINGW32__)) && defined(BUILD_GL32) /* tag specify we're building mesa as a DLL */
+# define WGLAPI __declspec(dllexport)
+# elif (defined(_MSC_VER) || defined(__MINGW32__)) && defined(_DLL) /* tag specifying we're building for DLL runtime support */
+# define WGLAPI __declspec(dllimport)
+# else /* for use with static link lib build of Win32 edition only */
+# define WGLAPI __declspec(dllimport)
+# endif /* _STATIC_MESA support */
+#endif /* WIN32 / CYGWIN bracket */
+
+
+/*
+ * Either define MESA_BIG_ENDIAN or MESA_LITTLE_ENDIAN.
+ * Do not use them unless absolutely necessary!
+ * Try to use a runtime test instead.
+ * For now, only used by some DRI hardware drivers for color/texel packing.
+ */
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN
+#if defined(__linux__)
+#include <byteswap.h>
+#define CPU_TO_LE32( x ) bswap_32( x )
+#else /*__linux__*/
+#define CPU_TO_LE32( x ) ( x ) /* fix me for non-Linux big-endian! */
+#endif /*__linux__*/
+#define MESA_BIG_ENDIAN 1
+#else
+#define CPU_TO_LE32( x ) ( x )
+#define MESA_LITTLE_ENDIAN 1
+#endif
+#define LE32_TO_CPU( x ) CPU_TO_LE32( x )
+
+
+#define GL_GLEXT_PROTOTYPES
+#include "GL/gl.h"
+#include "GL/glext.h"
+
+
+#if !defined(CAPI) && defined(WIN32) && !defined(BUILD_FOR_SNAP)
+#define CAPI _cdecl
+#endif
+
+
+/* This is a macro on IRIX */
+#ifdef _P
+#undef _P
+#endif
+
+
+/* Turn off macro checking systems used by other libraries */
+#ifdef CHECK
+#undef CHECK
+#endif
+
+
+/* Create a macro so that asm functions can be linked into compilers other
+ * than GNU C
+ */
+#ifndef _ASMAPI
+#if defined(WIN32) && !defined(BUILD_FOR_SNAP)/* was: !defined( __GNUC__ ) && !defined( VMS ) && !defined( __INTEL_COMPILER )*/
+#define _ASMAPI __cdecl
+#else
+#define _ASMAPI
+#endif
+#ifdef PTR_DECL_IN_FRONT
+#define _ASMAPIP * _ASMAPI
+#else
+#define _ASMAPIP _ASMAPI *
+#endif
+#endif
+
+#ifdef USE_X86_ASM
+#define _NORMAPI _ASMAPI
+#define _NORMAPIP _ASMAPIP
+#else
+#define _NORMAPI
+#define _NORMAPIP *
+#endif
+
+
+/* Function inlining */
+#if defined(__GNUC__)
+# define INLINE __inline__
+#elif defined(__MSC__)
+# define INLINE __inline
+#elif defined(_MSC_VER)
+# define INLINE __inline
+#elif defined(__ICL)
+# define INLINE __inline
+#elif defined(__INTEL_COMPILER)
+# define INLINE inline
+#elif defined(__WATCOMC__) && (__WATCOMC__ >= 1100)
+# define INLINE __inline
+#else
+# define INLINE
+#endif
+
+
+/* If we build the library with gcc's -fvisibility=hidden flag, we'll
+ * use the PUBLIC macro to mark functions that are to be exported.
+ *
+ * We also need to define a USED attribute, so the optimizer doesn't
+ * inline a static function that we later use in an alias. - ajax
+ */
+#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 303
+# define PUBLIC __attribute__((visibility("default")))
+# define USED __attribute__((used))
+#else
+# define PUBLIC
+# define USED
+#endif
+
+
+/* Some compilers don't like some of Mesa's const usage */
+#ifdef NO_CONST
+# define CONST
+#else
+# define CONST const
+#endif
+
+
+#if defined(BUILD_FOR_SNAP) && defined(CHECKED)
+# define ASSERT(X) _CHECK(X)
+#elif defined(DEBUG)
+# define ASSERT(X) assert(X)
+#else
+# define ASSERT(X)
+#endif
+
+
+#if !defined __GNUC__ || __GNUC__ < 3
+# define __builtin_expect(x, y) x
+#endif
+
+/* The __FUNCTION__ gcc variable is generally only used for debugging.
+ * If we're not using gcc, define __FUNCTION__ as a cpp symbol here.
+ * Don't define it if using a newer Windows compiler.
+ */
+#if defined(__VMS)
+#define __FUNCTION__ "VMS$NL:"
+#elif !(defined(__GNUC__) && __GNUC__ >= 2) && !(defined(_MSC_VER) && _MSC_VER >= 1300)
+#define __FUNCTION__ "unknown"
+#endif
+
+
+#include "config.h"
+
+#endif /* GLHEADER_H */
diff --git a/src/mesa/main/hash.c b/src/mesa/main/hash.c
new file mode 100644
index 00000000000..74ab57df0ac
--- /dev/null
+++ b/src/mesa/main/hash.c
@@ -0,0 +1,451 @@
+/**
+ * \file hash.c
+ * Generic hash table.
+ *
+ * Used for display lists, texture objects, vertex/fragment programs,
+ * buffer objects, etc. The hash functions are thread-safe.
+ *
+ * \note key=0 is illegal.
+ *
+ * \author Brian Paul
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.4
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include "glheader.h"
+#include "imports.h"
+#include "glthread.h"
+#include "hash.h"
+
+
+#define TABLE_SIZE 1023 /**< Size of lookup table/array */
+
+#define HASH_FUNC(K) ((K) % TABLE_SIZE)
+
+
+/**
+ * An entry in the hash table.
+ *
+ * This struct is private to this file.
+ */
+struct HashEntry {
+ GLuint Key; /**< the entry's key */
+ void *Data; /**< the entry's data */
+ struct HashEntry *Next; /**< pointer to next entry */
+};
+
+/**
+ * The hash table data structure.
+ *
+ * This is an opaque types (it's not defined in hash.h file).
+ */
+struct _mesa_HashTable {
+ struct HashEntry *Table[TABLE_SIZE]; /**< the lookup table */
+ GLuint MaxKey; /**< highest key inserted so far */
+ _glthread_Mutex Mutex; /**< mutual exclusion lock */
+};
+
+
+/**
+ * Create a new hash table.
+ *
+ * \return pointer to a new, empty hash table.
+ */
+struct _mesa_HashTable *
+_mesa_NewHashTable(void)
+{
+ struct _mesa_HashTable *table = CALLOC_STRUCT(_mesa_HashTable);
+ if (table) {
+ _glthread_INIT_MUTEX(table->Mutex);
+ }
+ return table;
+}
+
+
+
+/**
+ * Delete a hash table.
+ * Frees each entry on the hash table and then the hash table structure itself.
+ * Note that the caller should have already traversed the table and deleted
+ * the objects in the table (i.e. We don't free the entries' data pointer).
+ *
+ * \param table the hash table to delete.
+ */
+void
+_mesa_DeleteHashTable(struct _mesa_HashTable *table)
+{
+ GLuint i;
+ assert(table);
+ for (i = 0; i < TABLE_SIZE; i++) {
+ struct HashEntry *entry = table->Table[i];
+ while (entry) {
+ struct HashEntry *next = entry->Next;
+ FREE(entry);
+ entry = next;
+ }
+ }
+ _glthread_DESTROY_MUTEX(table->Mutex);
+ FREE(table);
+}
+
+
+
+/**
+ * Lookup an entry in the hash table.
+ *
+ * \param table the hash table.
+ * \param key the key.
+ *
+ * \return pointer to user's data or NULL if key not in table
+ */
+void *
+_mesa_HashLookup(const struct _mesa_HashTable *table, GLuint key)
+{
+ GLuint pos;
+ const struct HashEntry *entry;
+
+ assert(table);
+ assert(key);
+
+ pos = HASH_FUNC(key);
+ entry = table->Table[pos];
+ while (entry) {
+ if (entry->Key == key) {
+ return entry->Data;
+ }
+ entry = entry->Next;
+ }
+ return NULL;
+}
+
+
+
+/**
+ * Insert a key/pointer pair into the hash table.
+ * If an entry with this key already exists we'll replace the existing entry.
+ *
+ * \param table the hash table.
+ * \param key the key (not zero).
+ * \param data pointer to user data.
+ */
+void
+_mesa_HashInsert(struct _mesa_HashTable *table, GLuint key, void *data)
+{
+ /* search for existing entry with this key */
+ GLuint pos;
+ struct HashEntry *entry;
+
+ assert(table);
+ assert(key);
+
+ _glthread_LOCK_MUTEX(table->Mutex);
+
+ if (key > table->MaxKey)
+ table->MaxKey = key;
+
+ pos = HASH_FUNC(key);
+ entry = table->Table[pos];
+ while (entry) {
+ if (entry->Key == key) {
+ /* replace entry's data */
+ entry->Data = data;
+ _glthread_UNLOCK_MUTEX(table->Mutex);
+ return;
+ }
+ entry = entry->Next;
+ }
+
+ /* alloc and insert new table entry */
+ entry = MALLOC_STRUCT(HashEntry);
+ entry->Key = key;
+ entry->Data = data;
+ entry->Next = table->Table[pos];
+ table->Table[pos] = entry;
+
+ _glthread_UNLOCK_MUTEX(table->Mutex);
+}
+
+
+
+/**
+ * Remove an entry from the hash table.
+ *
+ * \param table the hash table.
+ * \param key key of entry to remove.
+ *
+ * While holding the hash table's lock, searches the entry with the matching
+ * key and unlinks it.
+ */
+void
+_mesa_HashRemove(struct _mesa_HashTable *table, GLuint key)
+{
+ GLuint pos;
+ struct HashEntry *entry, *prev;
+
+ assert(table);
+ assert(key);
+
+ _glthread_LOCK_MUTEX(table->Mutex);
+
+ pos = HASH_FUNC(key);
+ prev = NULL;
+ entry = table->Table[pos];
+ while (entry) {
+ if (entry->Key == key) {
+ /* found it! */
+ if (prev) {
+ prev->Next = entry->Next;
+ }
+ else {
+ table->Table[pos] = entry->Next;
+ }
+ FREE(entry);
+ _glthread_UNLOCK_MUTEX(table->Mutex);
+ return;
+ }
+ prev = entry;
+ entry = entry->Next;
+ }
+
+ _glthread_UNLOCK_MUTEX(table->Mutex);
+}
+
+
+
+/**
+ * Get the key of the "first" entry in the hash table.
+ *
+ * This is used in the course of deleting all display lists when
+ * a context is destroyed.
+ *
+ * \param table the hash table
+ *
+ * \return key for the "first" entry in the hash table.
+ *
+ * While holding the lock, walks through all table positions until finding
+ * the first entry of the first non-empty one.
+ */
+GLuint
+_mesa_HashFirstEntry(struct _mesa_HashTable *table)
+{
+ GLuint pos;
+ assert(table);
+ _glthread_LOCK_MUTEX(table->Mutex);
+ for (pos=0; pos < TABLE_SIZE; pos++) {
+ if (table->Table[pos]) {
+ _glthread_UNLOCK_MUTEX(table->Mutex);
+ return table->Table[pos]->Key;
+ }
+ }
+ _glthread_UNLOCK_MUTEX(table->Mutex);
+ return 0;
+}
+
+
+/**
+ * Given a hash table key, return the next key. This is used to walk
+ * over all entries in the table. Note that the keys returned during
+ * walking won't be in any particular order.
+ * \return next hash key or 0 if end of table.
+ */
+GLuint
+_mesa_HashNextEntry(const struct _mesa_HashTable *table, GLuint key)
+{
+ const struct HashEntry *entry;
+ GLuint pos;
+
+ assert(table);
+ assert(key);
+
+ /* Find the entry with given key */
+ pos = HASH_FUNC(key);
+ entry = table->Table[pos];
+ while (entry) {
+ if (entry->Key == key) {
+ break;
+ }
+ entry = entry->Next;
+ }
+
+ if (!entry) {
+ /* the key was not found, we can't find next entry */
+ return 0;
+ }
+
+ if (entry->Next) {
+ /* return next in linked list */
+ return entry->Next->Key;
+ }
+ else {
+ /* look for next non-empty table slot */
+ pos++;
+ while (pos < TABLE_SIZE) {
+ if (table->Table[pos]) {
+ return table->Table[pos]->Key;
+ }
+ pos++;
+ }
+ return 0;
+ }
+}
+
+
+/**
+ * Dump contents of hash table for debugging.
+ *
+ * \param table the hash table.
+ */
+void
+_mesa_HashPrint(const struct _mesa_HashTable *table)
+{
+ GLuint i;
+ assert(table);
+ for (i=0;i<TABLE_SIZE;i++) {
+ const struct HashEntry *entry = table->Table[i];
+ while (entry) {
+ _mesa_debug(NULL, "%u %p\n", entry->Key, entry->Data);
+ entry = entry->Next;
+ }
+ }
+}
+
+
+
+/**
+ * Find a block of adjacent unused hash keys.
+ *
+ * \param table the hash table.
+ * \param numKeys number of keys needed.
+ *
+ * \return Starting key of free block or 0 if failure.
+ *
+ * If there are enough free keys between the maximum key existing in the table
+ * (_mesa_HashTable::MaxKey) and the maximum key possible, then simply return
+ * the adjacent key. Otherwise do a full search for a free key block in the
+ * allowable key range.
+ */
+GLuint
+_mesa_HashFindFreeKeyBlock(struct _mesa_HashTable *table, GLuint numKeys)
+{
+ GLuint maxKey = ~((GLuint) 0);
+ _glthread_LOCK_MUTEX(table->Mutex);
+ if (maxKey - numKeys > table->MaxKey) {
+ /* the quick solution */
+ _glthread_UNLOCK_MUTEX(table->Mutex);
+ return table->MaxKey + 1;
+ }
+ else {
+ /* the slow solution */
+ GLuint freeCount = 0;
+ GLuint freeStart = 1;
+ GLuint key;
+ for (key=1; key!=maxKey; key++) {
+ if (_mesa_HashLookup(table, key)) {
+ /* darn, this key is already in use */
+ freeCount = 0;
+ freeStart = key+1;
+ }
+ else {
+ /* this key not in use, check if we've found enough */
+ freeCount++;
+ if (freeCount == numKeys) {
+ _glthread_UNLOCK_MUTEX(table->Mutex);
+ return freeStart;
+ }
+ }
+ }
+ /* cannot allocate a block of numKeys consecutive keys */
+ _glthread_UNLOCK_MUTEX(table->Mutex);
+ return 0;
+ }
+}
+
+
+#if 0 /* debug only */
+
+/**
+ * Test walking over all the entries in a hash table.
+ */
+static void
+test_hash_walking(void)
+{
+ struct _mesa_HashTable *t = _mesa_NewHashTable();
+ const GLuint limit = 50000;
+ GLuint i;
+
+ /* create some entries */
+ for (i = 0; i < limit; i++) {
+ GLuint dummy;
+ GLuint k = (rand() % (limit * 10)) + 1;
+ while (_mesa_HashLookup(t, k)) {
+ /* id already in use, try another */
+ k = (rand() % (limit * 10)) + 1;
+ }
+ _mesa_HashInsert(t, k, &dummy);
+ }
+
+ /* walk over all entries */
+ {
+ GLuint k = _mesa_HashFirstEntry(t);
+ GLuint count = 0;
+ while (k) {
+ GLuint knext = _mesa_HashNextEntry(t, k);
+ assert(knext != k);
+ _mesa_HashRemove(t, k);
+ count++;
+ k = knext;
+ }
+ assert(count == limit);
+ k = _mesa_HashFirstEntry(t);
+ assert(k==0);
+ }
+
+ _mesa_DeleteHashTable(t);
+}
+
+
+void
+_mesa_test_hash_functions(void)
+{
+ int a, b, c;
+ struct _mesa_HashTable *t;
+
+ t = _mesa_NewHashTable();
+ _mesa_HashInsert(t, 501, &a);
+ _mesa_HashInsert(t, 10, &c);
+ _mesa_HashInsert(t, 0xfffffff8, &b);
+ /*_mesa_HashPrint(t);*/
+
+ assert(_mesa_HashLookup(t,501));
+ assert(!_mesa_HashLookup(t,1313));
+ assert(_mesa_HashFindFreeKeyBlock(t, 100));
+
+ _mesa_DeleteHashTable(t);
+
+ test_hash_walking();
+}
+
+#endif
diff --git a/src/mesa/main/hash.h b/src/mesa/main/hash.h
new file mode 100644
index 00000000000..3cbe668e9ae
--- /dev/null
+++ b/src/mesa/main/hash.h
@@ -0,0 +1,59 @@
+/**
+ * \file hash.h
+ * Generic hash table.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.3
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef HASH_H
+#define HASH_H
+
+
+#include "glheader.h"
+
+
+extern struct _mesa_HashTable *_mesa_NewHashTable(void);
+
+extern void _mesa_DeleteHashTable(struct _mesa_HashTable *table);
+
+extern void *_mesa_HashLookup(const struct _mesa_HashTable *table, GLuint key);
+
+extern void _mesa_HashInsert(struct _mesa_HashTable *table, GLuint key, void *data);
+
+extern void _mesa_HashRemove(struct _mesa_HashTable *table, GLuint key);
+
+extern GLuint _mesa_HashFirstEntry(struct _mesa_HashTable *table);
+
+extern GLuint _mesa_HashNextEntry(const struct _mesa_HashTable *table, GLuint key);
+
+extern void _mesa_HashPrint(const struct _mesa_HashTable *table);
+
+extern GLuint _mesa_HashFindFreeKeyBlock(struct _mesa_HashTable *table, GLuint numKeys);
+
+extern void _mesa_test_hash_functions(void);
+
+
+#endif
diff --git a/src/mesa/main/hint.c b/src/mesa/main/hint.c
new file mode 100644
index 00000000000..dcfa9c7363f
--- /dev/null
+++ b/src/mesa/main/hint.c
@@ -0,0 +1,153 @@
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 4.1
+ *
+ * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include "glheader.h"
+#include "enums.h"
+#include "context.h"
+#include "hint.h"
+#include "imports.h"
+
+
+
+void GLAPIENTRY
+_mesa_Hint( GLenum target, GLenum mode )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx, "glHint %s %d\n",
+ _mesa_lookup_enum_by_nr(target), mode);
+
+ if (mode != GL_NICEST && mode != GL_FASTEST && mode != GL_DONT_CARE) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glHint(mode)");
+ return;
+ }
+
+ switch (target) {
+ case GL_FOG_HINT:
+ if (ctx->Hint.Fog == mode)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_HINT);
+ ctx->Hint.Fog = mode;
+ break;
+ case GL_LINE_SMOOTH_HINT:
+ if (ctx->Hint.LineSmooth == mode)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_HINT);
+ ctx->Hint.LineSmooth = mode;
+ break;
+ case GL_PERSPECTIVE_CORRECTION_HINT:
+ if (ctx->Hint.PerspectiveCorrection == mode)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_HINT);
+ ctx->Hint.PerspectiveCorrection = mode;
+ break;
+ case GL_POINT_SMOOTH_HINT:
+ if (ctx->Hint.PointSmooth == mode)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_HINT);
+ ctx->Hint.PointSmooth = mode;
+ break;
+ case GL_POLYGON_SMOOTH_HINT:
+ if (ctx->Hint.PolygonSmooth == mode)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_HINT);
+ ctx->Hint.PolygonSmooth = mode;
+ break;
+
+ /* GL_EXT_clip_volume_hint */
+ case GL_CLIP_VOLUME_CLIPPING_HINT_EXT:
+ if (ctx->Hint.ClipVolumeClipping == mode)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_HINT);
+ ctx->Hint.ClipVolumeClipping = mode;
+ break;
+
+ /* GL_ARB_texture_compression */
+ case GL_TEXTURE_COMPRESSION_HINT_ARB:
+ if (!ctx->Extensions.ARB_texture_compression) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glHint(target)");
+ return;
+ }
+ if (ctx->Hint.TextureCompression == mode)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_HINT);
+ ctx->Hint.TextureCompression = mode;
+ break;
+
+ /* GL_SGIS_generate_mipmap */
+ case GL_GENERATE_MIPMAP_HINT_SGIS:
+ if (!ctx->Extensions.SGIS_generate_mipmap) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glHint(target)");
+ return;
+ }
+ if (ctx->Hint.GenerateMipmap == mode)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_HINT);
+ ctx->Hint.GenerateMipmap = mode;
+ break;
+
+ /* GL_ARB_fragment_shader */
+ case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB:
+ if (!ctx->Extensions.ARB_fragment_shader) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glHint(target)");
+ return;
+ }
+ if (ctx->Hint.FragmentShaderDerivative == mode)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_HINT);
+ ctx->Hint.FragmentShaderDerivative = mode;
+ break;
+
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glHint(target)");
+ return;
+ }
+
+ if (ctx->Driver.Hint) {
+ (*ctx->Driver.Hint)( ctx, target, mode );
+ }
+}
+
+
+/**********************************************************************/
+/***** Initialization *****/
+/**********************************************************************/
+
+void _mesa_init_hint( GLcontext * ctx )
+{
+ /* Hint group */
+ ctx->Hint.PerspectiveCorrection = GL_DONT_CARE;
+ ctx->Hint.PointSmooth = GL_DONT_CARE;
+ ctx->Hint.LineSmooth = GL_DONT_CARE;
+ ctx->Hint.PolygonSmooth = GL_DONT_CARE;
+ ctx->Hint.Fog = GL_DONT_CARE;
+ ctx->Hint.ClipVolumeClipping = GL_DONT_CARE;
+ ctx->Hint.TextureCompression = GL_DONT_CARE;
+ ctx->Hint.GenerateMipmap = GL_DONT_CARE;
+ ctx->Hint.FragmentShaderDerivative = GL_DONT_CARE;
+}
diff --git a/src/mesa/main/hint.h b/src/mesa/main/hint.h
new file mode 100644
index 00000000000..bfc3887107d
--- /dev/null
+++ b/src/mesa/main/hint.h
@@ -0,0 +1,57 @@
+/**
+ * \file hint.h
+ * Hints operations.
+ *
+ * \if subset
+ * (No-op)
+ *
+ * \endif
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 4.1
+ *
+ * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef HINT_H
+#define HINT_H
+
+
+#include "mtypes.h"
+
+#if _HAVE_FULL_GL
+
+extern void GLAPIENTRY
+_mesa_Hint( GLenum target, GLenum mode );
+
+extern void
+_mesa_init_hint( GLcontext * ctx );
+
+#else
+
+/** No-op */
+#define _mesa_init_hint( c ) ((void) 0)
+
+#endif
+
+#endif
diff --git a/src/mesa/main/histogram.c b/src/mesa/main/histogram.c
new file mode 100644
index 00000000000..29aced0c7a7
--- /dev/null
+++ b/src/mesa/main/histogram.c
@@ -0,0 +1,1187 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.3
+ *
+ * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include "glheader.h"
+#include "bufferobj.h"
+#include "colormac.h"
+#include "context.h"
+#include "image.h"
+#include "histogram.h"
+
+
+/**********************************************************************
+ * Internal functions
+ */
+
+
+/*
+ * Update the min/max values from an array of fragment colors.
+ */
+void
+_mesa_update_minmax(GLcontext *ctx, GLuint n, const GLfloat rgba[][4])
+{
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ /* update mins */
+ if (rgba[i][RCOMP] < ctx->MinMax.Min[RCOMP])
+ ctx->MinMax.Min[RCOMP] = rgba[i][RCOMP];
+ if (rgba[i][GCOMP] < ctx->MinMax.Min[GCOMP])
+ ctx->MinMax.Min[GCOMP] = rgba[i][GCOMP];
+ if (rgba[i][BCOMP] < ctx->MinMax.Min[BCOMP])
+ ctx->MinMax.Min[BCOMP] = rgba[i][BCOMP];
+ if (rgba[i][ACOMP] < ctx->MinMax.Min[ACOMP])
+ ctx->MinMax.Min[ACOMP] = rgba[i][ACOMP];
+
+ /* update maxs */
+ if (rgba[i][RCOMP] > ctx->MinMax.Max[RCOMP])
+ ctx->MinMax.Max[RCOMP] = rgba[i][RCOMP];
+ if (rgba[i][GCOMP] > ctx->MinMax.Max[GCOMP])
+ ctx->MinMax.Max[GCOMP] = rgba[i][GCOMP];
+ if (rgba[i][BCOMP] > ctx->MinMax.Max[BCOMP])
+ ctx->MinMax.Max[BCOMP] = rgba[i][BCOMP];
+ if (rgba[i][ACOMP] > ctx->MinMax.Max[ACOMP])
+ ctx->MinMax.Max[ACOMP] = rgba[i][ACOMP];
+ }
+}
+
+
+/*
+ * Update the histogram values from an array of fragment colors.
+ */
+void
+_mesa_update_histogram(GLcontext *ctx, GLuint n, const GLfloat rgba[][4])
+{
+ const GLint max = ctx->Histogram.Width - 1;
+ GLfloat w = (GLfloat) max;
+ GLuint i;
+
+ if (ctx->Histogram.Width == 0)
+ return;
+
+ for (i = 0; i < n; i++) {
+ GLint ri = IROUND(rgba[i][RCOMP] * w);
+ GLint gi = IROUND(rgba[i][GCOMP] * w);
+ GLint bi = IROUND(rgba[i][BCOMP] * w);
+ GLint ai = IROUND(rgba[i][ACOMP] * w);
+ ri = CLAMP(ri, 0, max);
+ gi = CLAMP(gi, 0, max);
+ bi = CLAMP(bi, 0, max);
+ ai = CLAMP(ai, 0, max);
+ ctx->Histogram.Count[ri][RCOMP]++;
+ ctx->Histogram.Count[gi][GCOMP]++;
+ ctx->Histogram.Count[bi][BCOMP]++;
+ ctx->Histogram.Count[ai][ACOMP]++;
+ }
+}
+
+
+/*
+ * XXX the packed pixel formats haven't been tested.
+ */
+static void
+pack_histogram( GLcontext *ctx,
+ GLuint n, CONST GLuint rgba[][4],
+ GLenum format, GLenum type, GLvoid *destination,
+ const struct gl_pixelstore_attrib *packing )
+{
+ const GLint comps = _mesa_components_in_format(format);
+ GLuint luminance[MAX_WIDTH];
+
+ if (format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA) {
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ luminance[i] = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP];
+ }
+ }
+
+#define PACK_MACRO(TYPE) \
+ { \
+ GLuint i; \
+ switch (format) { \
+ case GL_RED: \
+ for (i=0;i<n;i++) \
+ dst[i] = (TYPE) rgba[i][RCOMP]; \
+ break; \
+ case GL_GREEN: \
+ for (i=0;i<n;i++) \
+ dst[i] = (TYPE) rgba[i][GCOMP]; \
+ break; \
+ case GL_BLUE: \
+ for (i=0;i<n;i++) \
+ dst[i] = (TYPE) rgba[i][BCOMP]; \
+ break; \
+ case GL_ALPHA: \
+ for (i=0;i<n;i++) \
+ dst[i] = (TYPE) rgba[i][ACOMP]; \
+ break; \
+ case GL_LUMINANCE: \
+ for (i=0;i<n;i++) \
+ dst[i] = (TYPE) luminance[i]; \
+ break; \
+ case GL_LUMINANCE_ALPHA: \
+ for (i=0;i<n;i++) { \
+ dst[i*2+0] = (TYPE) luminance[i]; \
+ dst[i*2+1] = (TYPE) rgba[i][ACOMP]; \
+ } \
+ break; \
+ case GL_RGB: \
+ for (i=0;i<n;i++) { \
+ dst[i*3+0] = (TYPE) rgba[i][RCOMP]; \
+ dst[i*3+1] = (TYPE) rgba[i][GCOMP]; \
+ dst[i*3+2] = (TYPE) rgba[i][BCOMP]; \
+ } \
+ break; \
+ case GL_RGBA: \
+ for (i=0;i<n;i++) { \
+ dst[i*4+0] = (TYPE) rgba[i][RCOMP]; \
+ dst[i*4+1] = (TYPE) rgba[i][GCOMP]; \
+ dst[i*4+2] = (TYPE) rgba[i][BCOMP]; \
+ dst[i*4+3] = (TYPE) rgba[i][ACOMP]; \
+ } \
+ break; \
+ case GL_BGR: \
+ for (i=0;i<n;i++) { \
+ dst[i*3+0] = (TYPE) rgba[i][BCOMP]; \
+ dst[i*3+1] = (TYPE) rgba[i][GCOMP]; \
+ dst[i*3+2] = (TYPE) rgba[i][RCOMP]; \
+ } \
+ break; \
+ case GL_BGRA: \
+ for (i=0;i<n;i++) { \
+ dst[i*4+0] = (TYPE) rgba[i][BCOMP]; \
+ dst[i*4+1] = (TYPE) rgba[i][GCOMP]; \
+ dst[i*4+2] = (TYPE) rgba[i][RCOMP]; \
+ dst[i*4+3] = (TYPE) rgba[i][ACOMP]; \
+ } \
+ break; \
+ case GL_ABGR_EXT: \
+ for (i=0;i<n;i++) { \
+ dst[i*4+0] = (TYPE) rgba[i][ACOMP]; \
+ dst[i*4+1] = (TYPE) rgba[i][BCOMP]; \
+ dst[i*4+2] = (TYPE) rgba[i][GCOMP]; \
+ dst[i*4+3] = (TYPE) rgba[i][RCOMP]; \
+ } \
+ break; \
+ default: \
+ _mesa_problem(ctx, "bad format in pack_histogram"); \
+ } \
+ }
+
+ switch (type) {
+ case GL_UNSIGNED_BYTE:
+ {
+ GLubyte *dst = (GLubyte *) destination;
+ PACK_MACRO(GLubyte);
+ }
+ break;
+ case GL_BYTE:
+ {
+ GLbyte *dst = (GLbyte *) destination;
+ PACK_MACRO(GLbyte);
+ }
+ break;
+ case GL_UNSIGNED_SHORT:
+ {
+ GLushort *dst = (GLushort *) destination;
+ PACK_MACRO(GLushort);
+ if (packing->SwapBytes) {
+ _mesa_swap2(dst, n * comps);
+ }
+ }
+ break;
+ case GL_SHORT:
+ {
+ GLshort *dst = (GLshort *) destination;
+ PACK_MACRO(GLshort);
+ if (packing->SwapBytes) {
+ _mesa_swap2((GLushort *) dst, n * comps);
+ }
+ }
+ break;
+ case GL_UNSIGNED_INT:
+ {
+ GLuint *dst = (GLuint *) destination;
+ PACK_MACRO(GLuint);
+ if (packing->SwapBytes) {
+ _mesa_swap4(dst, n * comps);
+ }
+ }
+ break;
+ case GL_INT:
+ {
+ GLint *dst = (GLint *) destination;
+ PACK_MACRO(GLint);
+ if (packing->SwapBytes) {
+ _mesa_swap4((GLuint *) dst, n * comps);
+ }
+ }
+ break;
+ case GL_FLOAT:
+ {
+ GLfloat *dst = (GLfloat *) destination;
+ PACK_MACRO(GLfloat);
+ if (packing->SwapBytes) {
+ _mesa_swap4((GLuint *) dst, n * comps);
+ }
+ }
+ break;
+ case GL_HALF_FLOAT_ARB:
+ {
+ /* temporarily store as GLuints */
+ GLuint temp[4*HISTOGRAM_TABLE_SIZE];
+ GLhalfARB *dst = (GLhalfARB *) destination;
+ GLuint i;
+ /* get GLuint values */
+ PACK_MACRO(GLuint);
+ /* convert to GLhalf */
+ for (i = 0; i < n * comps; i++) {
+ dst[i] = _mesa_float_to_half((GLfloat) temp[i]);
+ }
+ if (packing->SwapBytes) {
+ _mesa_swap2((GLushort *) dst, n * comps);
+ }
+ }
+ break;
+ case GL_UNSIGNED_BYTE_3_3_2:
+ if (format == GL_RGB) {
+ GLubyte *dst = (GLubyte *) destination;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i] = ((rgba[i][RCOMP] & 0x7) << 5)
+ | ((rgba[i][GCOMP] & 0x7) << 2)
+ | ((rgba[i][BCOMP] & 0x3) );
+ }
+ }
+ else {
+ GLubyte *dst = (GLubyte *) destination;
+ GLuint i;
+ ASSERT(format == GL_BGR);
+ for (i = 0; i < n; i++) {
+ dst[i] = ((rgba[i][BCOMP] & 0x7) << 5)
+ | ((rgba[i][GCOMP] & 0x7) << 2)
+ | ((rgba[i][RCOMP] & 0x3) );
+ }
+ }
+ break;
+ case GL_UNSIGNED_BYTE_2_3_3_REV:
+ if (format == GL_RGB) {
+ GLubyte *dst = (GLubyte *) destination;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i] = ((rgba[i][RCOMP] & 0x3) << 6)
+ | ((rgba[i][GCOMP] & 0x7) << 3)
+ | ((rgba[i][BCOMP] & 0x7) );
+ }
+ }
+ else {
+ GLubyte *dst = (GLubyte *) destination;
+ GLuint i;
+ ASSERT(format == GL_BGR);
+ for (i = 0; i < n; i++) {
+ dst[i] = ((rgba[i][BCOMP] & 0x3) << 6)
+ | ((rgba[i][GCOMP] & 0x7) << 3)
+ | ((rgba[i][RCOMP] & 0x7) );
+ }
+ }
+ break;
+ case GL_UNSIGNED_SHORT_5_6_5:
+ if (format == GL_RGB) {
+ GLushort *dst = (GLushort *) destination;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i] = ((rgba[i][RCOMP] & 0x1f) << 11)
+ | ((rgba[i][GCOMP] & 0x3f) << 5)
+ | ((rgba[i][BCOMP] & 0x1f) );
+ }
+ }
+ else {
+ GLushort *dst = (GLushort *) destination;
+ GLuint i;
+ ASSERT(format == GL_BGR);
+ for (i = 0; i < n; i++) {
+ dst[i] = ((rgba[i][BCOMP] & 0x1f) << 11)
+ | ((rgba[i][GCOMP] & 0x3f) << 5)
+ | ((rgba[i][RCOMP] & 0x1f) );
+ }
+ }
+ break;
+ case GL_UNSIGNED_SHORT_5_6_5_REV:
+ if (format == GL_RGB) {
+ GLushort *dst = (GLushort *) destination;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i] = ((rgba[i][BCOMP] & 0x1f) << 11)
+ | ((rgba[i][GCOMP] & 0x3f) << 5)
+ | ((rgba[i][RCOMP] & 0x1f) );
+ }
+ }
+ else {
+ GLushort *dst = (GLushort *) destination;
+ GLuint i;
+ ASSERT(format == GL_BGR);
+ for (i = 0; i < n; i++) {
+ dst[i] = ((rgba[i][RCOMP] & 0x1f) << 11)
+ | ((rgba[i][GCOMP] & 0x3f) << 5)
+ | ((rgba[i][BCOMP] & 0x1f) );
+ }
+ }
+ break;
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ if (format == GL_RGBA) {
+ GLushort *dst = (GLushort *) destination;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i] = ((rgba[i][RCOMP] & 0xf) << 12)
+ | ((rgba[i][GCOMP] & 0xf) << 8)
+ | ((rgba[i][BCOMP] & 0xf) << 4)
+ | ((rgba[i][ACOMP] & 0xf) );
+ }
+ }
+ else if (format == GL_BGRA) {
+ GLushort *dst = (GLushort *) destination;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i] = ((rgba[i][BCOMP] & 0xf) << 12)
+ | ((rgba[i][GCOMP] & 0xf) << 8)
+ | ((rgba[i][RCOMP] & 0xf) << 4)
+ | ((rgba[i][ACOMP] & 0xf) );
+ }
+ }
+ else {
+ GLushort *dst = (GLushort *) destination;
+ GLuint i;
+ ASSERT(format == GL_ABGR_EXT);
+ for (i = 0; i < n; i++) {
+ dst[i] = ((rgba[i][ACOMP] & 0xf) << 12)
+ | ((rgba[i][BCOMP] & 0xf) << 8)
+ | ((rgba[i][GCOMP] & 0xf) << 4)
+ | ((rgba[i][RCOMP] & 0xf) );
+ }
+ }
+ break;
+ case GL_UNSIGNED_SHORT_4_4_4_4_REV:
+ if (format == GL_RGBA) {
+ GLushort *dst = (GLushort *) destination;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i] = ((rgba[i][ACOMP] & 0xf) << 12)
+ | ((rgba[i][BCOMP] & 0xf) << 8)
+ | ((rgba[i][GCOMP] & 0xf) << 4)
+ | ((rgba[i][RCOMP] & 0xf) );
+ }
+ }
+ else if (format == GL_BGRA) {
+ GLushort *dst = (GLushort *) destination;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i] = ((rgba[i][ACOMP] & 0xf) << 12)
+ | ((rgba[i][RCOMP] & 0xf) << 8)
+ | ((rgba[i][GCOMP] & 0xf) << 4)
+ | ((rgba[i][BCOMP] & 0xf) );
+ }
+ }
+ else {
+ GLushort *dst = (GLushort *) destination;
+ GLuint i;
+ ASSERT(format == GL_ABGR_EXT);
+ for (i = 0; i < n; i++) {
+ dst[i] = ((rgba[i][RCOMP] & 0xf) << 12)
+ | ((rgba[i][GCOMP] & 0xf) << 8)
+ | ((rgba[i][BCOMP] & 0xf) << 4)
+ | ((rgba[i][ACOMP] & 0xf) );
+ }
+ }
+ break;
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ if (format == GL_RGBA) {
+ GLushort *dst = (GLushort *) destination;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i] = ((rgba[i][RCOMP] & 0x1f) << 11)
+ | ((rgba[i][GCOMP] & 0x1f) << 6)
+ | ((rgba[i][BCOMP] & 0x1f) << 1)
+ | ((rgba[i][ACOMP] & 0x1) );
+ }
+ }
+ else if (format == GL_BGRA) {
+ GLushort *dst = (GLushort *) destination;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i] = ((rgba[i][BCOMP] & 0x1f) << 11)
+ | ((rgba[i][GCOMP] & 0x1f) << 6)
+ | ((rgba[i][RCOMP] & 0x1f) << 1)
+ | ((rgba[i][ACOMP] & 0x1) );
+ }
+ }
+ else {
+ GLushort *dst = (GLushort *) destination;
+ GLuint i;
+ ASSERT(format == GL_ABGR_EXT);
+ for (i = 0; i < n; i++) {
+ dst[i] = ((rgba[i][ACOMP] & 0x1f) << 11)
+ | ((rgba[i][BCOMP] & 0x1f) << 6)
+ | ((rgba[i][GCOMP] & 0x1f) << 1)
+ | ((rgba[i][RCOMP] & 0x1) );
+ }
+ }
+ break;
+ case GL_UNSIGNED_SHORT_1_5_5_5_REV:
+ if (format == GL_RGBA) {
+ GLushort *dst = (GLushort *) destination;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i] = ((rgba[i][ACOMP] & 0x1f) << 11)
+ | ((rgba[i][BCOMP] & 0x1f) << 6)
+ | ((rgba[i][GCOMP] & 0x1f) << 1)
+ | ((rgba[i][RCOMP] & 0x1) );
+ }
+ }
+ else if (format == GL_BGRA) {
+ GLushort *dst = (GLushort *) destination;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i] = ((rgba[i][ACOMP] & 0x1f) << 11)
+ | ((rgba[i][RCOMP] & 0x1f) << 6)
+ | ((rgba[i][GCOMP] & 0x1f) << 1)
+ | ((rgba[i][BCOMP] & 0x1) );
+ }
+ }
+ else {
+ GLushort *dst = (GLushort *) destination;
+ GLuint i;
+ ASSERT(format == GL_ABGR_EXT);
+ for (i = 0; i < n; i++) {
+ dst[i] = ((rgba[i][RCOMP] & 0x1f) << 11)
+ | ((rgba[i][GCOMP] & 0x1f) << 6)
+ | ((rgba[i][BCOMP] & 0x1f) << 1)
+ | ((rgba[i][ACOMP] & 0x1) );
+ }
+ }
+ break;
+ case GL_UNSIGNED_INT_8_8_8_8:
+ if (format == GL_RGBA) {
+ GLuint *dst = (GLuint *) destination;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i] = ((rgba[i][RCOMP] & 0xff) << 24)
+ | ((rgba[i][GCOMP] & 0xff) << 16)
+ | ((rgba[i][BCOMP] & 0xff) << 8)
+ | ((rgba[i][ACOMP] & 0xff) );
+ }
+ }
+ else if (format == GL_BGRA) {
+ GLuint *dst = (GLuint *) destination;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i] = ((rgba[i][BCOMP] & 0xff) << 24)
+ | ((rgba[i][GCOMP] & 0xff) << 16)
+ | ((rgba[i][RCOMP] & 0xff) << 8)
+ | ((rgba[i][ACOMP] & 0xff) );
+ }
+ }
+ else {
+ GLuint *dst = (GLuint *) destination;
+ GLuint i;
+ ASSERT(format == GL_ABGR_EXT);
+ for (i = 0; i < n; i++) {
+ dst[i] = ((rgba[i][ACOMP] & 0xff) << 24)
+ | ((rgba[i][BCOMP] & 0xff) << 16)
+ | ((rgba[i][GCOMP] & 0xff) << 8)
+ | ((rgba[i][RCOMP] & 0xff) );
+ }
+ }
+ break;
+ case GL_UNSIGNED_INT_8_8_8_8_REV:
+ if (format == GL_RGBA) {
+ GLuint *dst = (GLuint *) destination;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i] = ((rgba[i][ACOMP] & 0xff) << 24)
+ | ((rgba[i][BCOMP] & 0xff) << 16)
+ | ((rgba[i][GCOMP] & 0xff) << 8)
+ | ((rgba[i][RCOMP] & 0xff) );
+ }
+ }
+ else if (format == GL_BGRA) {
+ GLuint *dst = (GLuint *) destination;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i] = ((rgba[i][ACOMP] & 0xff) << 24)
+ | ((rgba[i][RCOMP] & 0xff) << 16)
+ | ((rgba[i][GCOMP] & 0xff) << 8)
+ | ((rgba[i][BCOMP] & 0xff) );
+ }
+ }
+ else {
+ GLuint *dst = (GLuint *) destination;
+ GLuint i;
+ ASSERT(format == GL_ABGR_EXT);
+ for (i = 0; i < n; i++) {
+ dst[i] = ((rgba[i][RCOMP] & 0xff) << 24)
+ | ((rgba[i][GCOMP] & 0xff) << 16)
+ | ((rgba[i][BCOMP] & 0xff) << 8)
+ | ((rgba[i][ACOMP] & 0xff) );
+ }
+ }
+ break;
+ case GL_UNSIGNED_INT_10_10_10_2:
+ if (format == GL_RGBA) {
+ GLuint *dst = (GLuint *) destination;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i] = ((rgba[i][RCOMP] & 0x3ff) << 22)
+ | ((rgba[i][GCOMP] & 0x3ff) << 12)
+ | ((rgba[i][BCOMP] & 0x3ff) << 2)
+ | ((rgba[i][ACOMP] & 0x3) );
+ }
+ }
+ else if (format == GL_BGRA) {
+ GLuint *dst = (GLuint *) destination;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i] = ((rgba[i][BCOMP] & 0x3ff) << 22)
+ | ((rgba[i][GCOMP] & 0x3ff) << 12)
+ | ((rgba[i][RCOMP] & 0x3ff) << 2)
+ | ((rgba[i][ACOMP] & 0x3) );
+ }
+ }
+ else {
+ GLuint *dst = (GLuint *) destination;
+ GLuint i;
+ ASSERT(format == GL_ABGR_EXT);
+ for (i = 0; i < n; i++) {
+ dst[i] = ((rgba[i][ACOMP] & 0x3ff) << 22)
+ | ((rgba[i][BCOMP] & 0x3ff) << 12)
+ | ((rgba[i][GCOMP] & 0x3ff) << 2)
+ | ((rgba[i][RCOMP] & 0x3) );
+ }
+ }
+ break;
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ if (format == GL_RGBA) {
+ GLuint *dst = (GLuint *) destination;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i] = ((rgba[i][ACOMP] & 0x3ff) << 22)
+ | ((rgba[i][BCOMP] & 0x3ff) << 12)
+ | ((rgba[i][GCOMP] & 0x3ff) << 2)
+ | ((rgba[i][RCOMP] & 0x3) );
+ }
+ }
+ else if (format == GL_BGRA) {
+ GLuint *dst = (GLuint *) destination;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i] = ((rgba[i][ACOMP] & 0x3ff) << 22)
+ | ((rgba[i][RCOMP] & 0x3ff) << 12)
+ | ((rgba[i][GCOMP] & 0x3ff) << 2)
+ | ((rgba[i][BCOMP] & 0x3) );
+ }
+ }
+ else {
+ GLuint *dst = (GLuint *) destination;
+ GLuint i;
+ ASSERT(format == GL_ABGR_EXT);
+ for (i = 0; i < n; i++) {
+ dst[i] = ((rgba[i][RCOMP] & 0x3ff) << 22)
+ | ((rgba[i][GCOMP] & 0x3ff) << 12)
+ | ((rgba[i][BCOMP] & 0x3ff) << 2)
+ | ((rgba[i][ACOMP] & 0x3) );
+ }
+ }
+ break;
+ default:
+ _mesa_problem(ctx, "Bad type in pack_histogram");
+ }
+
+#undef PACK_MACRO
+}
+
+
+/*
+ * Given an internalFormat token passed to glHistogram or glMinMax,
+ * return the corresponding base format.
+ * Return -1 if invalid token.
+ */
+static GLint
+base_histogram_format( GLenum format )
+{
+ switch (format) {
+ case GL_ALPHA:
+ case GL_ALPHA4:
+ case GL_ALPHA8:
+ case GL_ALPHA12:
+ case GL_ALPHA16:
+ return GL_ALPHA;
+ case GL_LUMINANCE:
+ case GL_LUMINANCE4:
+ case GL_LUMINANCE8:
+ case GL_LUMINANCE12:
+ case GL_LUMINANCE16:
+ return GL_LUMINANCE;
+ case GL_LUMINANCE_ALPHA:
+ case GL_LUMINANCE4_ALPHA4:
+ case GL_LUMINANCE6_ALPHA2:
+ case GL_LUMINANCE8_ALPHA8:
+ case GL_LUMINANCE12_ALPHA4:
+ case GL_LUMINANCE12_ALPHA12:
+ case GL_LUMINANCE16_ALPHA16:
+ return GL_LUMINANCE_ALPHA;
+ case GL_RGB:
+ case GL_R3_G3_B2:
+ case GL_RGB4:
+ case GL_RGB5:
+ case GL_RGB8:
+ case GL_RGB10:
+ case GL_RGB12:
+ case GL_RGB16:
+ return GL_RGB;
+ case GL_RGBA:
+ case GL_RGBA2:
+ case GL_RGBA4:
+ case GL_RGB5_A1:
+ case GL_RGBA8:
+ case GL_RGB10_A2:
+ case GL_RGBA12:
+ case GL_RGBA16:
+ return GL_RGBA;
+ default:
+ return -1; /* error */
+ }
+}
+
+
+
+/**********************************************************************
+ * API functions
+ */
+
+
+void GLAPIENTRY
+_mesa_GetMinmax(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetMinmax");
+ return;
+ }
+
+ if (target != GL_MINMAX) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetMinmax(target)");
+ return;
+ }
+
+ if (format != GL_RED &&
+ format != GL_GREEN &&
+ format != GL_BLUE &&
+ format != GL_ALPHA &&
+ format != GL_RGB &&
+ format != GL_BGR &&
+ format != GL_RGBA &&
+ format != GL_BGRA &&
+ format != GL_ABGR_EXT &&
+ format != GL_LUMINANCE &&
+ format != GL_LUMINANCE_ALPHA) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetMinMax(format)");
+ }
+
+ if (!_mesa_is_legal_format_and_type(ctx, format, type)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetMinmax(format or type)");
+ return;
+ }
+
+ if (ctx->Pack.BufferObj->Name) {
+ /* pack min/max values into a PBO */
+ GLubyte *buf;
+ if (!_mesa_validate_pbo_access(1, &ctx->Pack, 2, 1, 1,
+ format, type, values)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetMinMax(invalid PBO access)");
+ return;
+ }
+ buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
+ GL_WRITE_ONLY_ARB,
+ ctx->Pack.BufferObj);
+ if (!buf) {
+ /* buffer is already mapped - that's an error */
+ _mesa_error(ctx, GL_INVALID_OPERATION,"glGetMinMax(PBO is mapped)");
+ return;
+ }
+ values = ADD_POINTERS(buf, values);
+ }
+ else if (!values) {
+ /* not an error */
+ return;
+ }
+
+ {
+ GLfloat minmax[2][4];
+ minmax[0][RCOMP] = CLAMP(ctx->MinMax.Min[RCOMP], 0.0F, 1.0F);
+ minmax[0][GCOMP] = CLAMP(ctx->MinMax.Min[GCOMP], 0.0F, 1.0F);
+ minmax[0][BCOMP] = CLAMP(ctx->MinMax.Min[BCOMP], 0.0F, 1.0F);
+ minmax[0][ACOMP] = CLAMP(ctx->MinMax.Min[ACOMP], 0.0F, 1.0F);
+ minmax[1][RCOMP] = CLAMP(ctx->MinMax.Max[RCOMP], 0.0F, 1.0F);
+ minmax[1][GCOMP] = CLAMP(ctx->MinMax.Max[GCOMP], 0.0F, 1.0F);
+ minmax[1][BCOMP] = CLAMP(ctx->MinMax.Max[BCOMP], 0.0F, 1.0F);
+ minmax[1][ACOMP] = CLAMP(ctx->MinMax.Max[ACOMP], 0.0F, 1.0F);
+ _mesa_pack_rgba_span_float(ctx, 2, (CONST GLfloat (*)[4]) minmax,
+ format, type, values, &ctx->Pack, 0);
+ }
+
+ if (ctx->Pack.BufferObj->Name) {
+ ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
+ ctx->Pack.BufferObj);
+ }
+
+ if (reset) {
+ _mesa_ResetMinmax(GL_MINMAX);
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_GetHistogram(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetHistogram");
+ return;
+ }
+
+ if (target != GL_HISTOGRAM) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetHistogram(target)");
+ return;
+ }
+
+ if (format != GL_RED &&
+ format != GL_GREEN &&
+ format != GL_BLUE &&
+ format != GL_ALPHA &&
+ format != GL_RGB &&
+ format != GL_BGR &&
+ format != GL_RGBA &&
+ format != GL_BGRA &&
+ format != GL_ABGR_EXT &&
+ format != GL_LUMINANCE &&
+ format != GL_LUMINANCE_ALPHA) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetHistogram(format)");
+ }
+
+ if (!_mesa_is_legal_format_and_type(ctx, format, type)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetHistogram(format or type)");
+ return;
+ }
+
+ if (ctx->Pack.BufferObj->Name) {
+ /* pack min/max values into a PBO */
+ GLubyte *buf;
+ if (!_mesa_validate_pbo_access(1, &ctx->Pack, ctx->Histogram.Width, 1, 1,
+ format, type, values)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetHistogram(invalid PBO access)");
+ return;
+ }
+ buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
+ GL_WRITE_ONLY_ARB,
+ ctx->Pack.BufferObj);
+ if (!buf) {
+ /* buffer is already mapped - that's an error */
+ _mesa_error(ctx,GL_INVALID_OPERATION,"glGetHistogram(PBO is mapped)");
+ return;
+ }
+ values = ADD_POINTERS(buf, values);
+ }
+ else if (!values) {
+ /* not an error */
+ return;
+ }
+
+ pack_histogram(ctx, ctx->Histogram.Width,
+ (CONST GLuint (*)[4]) ctx->Histogram.Count,
+ format, type, values, &ctx->Pack);
+
+ if (ctx->Pack.BufferObj->Name) {
+ ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
+ ctx->Pack.BufferObj);
+ }
+
+ if (reset) {
+ GLuint i;
+ for (i = 0; i < HISTOGRAM_TABLE_SIZE; i++) {
+ ctx->Histogram.Count[i][0] = 0;
+ ctx->Histogram.Count[i][1] = 0;
+ ctx->Histogram.Count[i][2] = 0;
+ ctx->Histogram.Count[i][3] = 0;
+ }
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_GetHistogramParameterfv(GLenum target, GLenum pname, GLfloat *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetHistogramParameterfv");
+ return;
+ }
+
+ if (target != GL_HISTOGRAM && target != GL_PROXY_HISTOGRAM) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetHistogramParameterfv(target)");
+ return;
+ }
+
+ switch (pname) {
+ case GL_HISTOGRAM_WIDTH:
+ *params = (GLfloat) ctx->Histogram.Width;
+ break;
+ case GL_HISTOGRAM_FORMAT:
+ *params = (GLfloat) ctx->Histogram.Format;
+ break;
+ case GL_HISTOGRAM_RED_SIZE:
+ *params = (GLfloat) ctx->Histogram.RedSize;
+ break;
+ case GL_HISTOGRAM_GREEN_SIZE:
+ *params = (GLfloat) ctx->Histogram.GreenSize;
+ break;
+ case GL_HISTOGRAM_BLUE_SIZE:
+ *params = (GLfloat) ctx->Histogram.BlueSize;
+ break;
+ case GL_HISTOGRAM_ALPHA_SIZE:
+ *params = (GLfloat) ctx->Histogram.AlphaSize;
+ break;
+ case GL_HISTOGRAM_LUMINANCE_SIZE:
+ *params = (GLfloat) ctx->Histogram.LuminanceSize;
+ break;
+ case GL_HISTOGRAM_SINK:
+ *params = (GLfloat) ctx->Histogram.Sink;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetHistogramParameterfv(pname)");
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_GetHistogramParameteriv(GLenum target, GLenum pname, GLint *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetHistogramParameteriv");
+ return;
+ }
+
+ if (target != GL_HISTOGRAM && target != GL_PROXY_HISTOGRAM) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetHistogramParameteriv(target)");
+ return;
+ }
+
+ switch (pname) {
+ case GL_HISTOGRAM_WIDTH:
+ *params = (GLint) ctx->Histogram.Width;
+ break;
+ case GL_HISTOGRAM_FORMAT:
+ *params = (GLint) ctx->Histogram.Format;
+ break;
+ case GL_HISTOGRAM_RED_SIZE:
+ *params = (GLint) ctx->Histogram.RedSize;
+ break;
+ case GL_HISTOGRAM_GREEN_SIZE:
+ *params = (GLint) ctx->Histogram.GreenSize;
+ break;
+ case GL_HISTOGRAM_BLUE_SIZE:
+ *params = (GLint) ctx->Histogram.BlueSize;
+ break;
+ case GL_HISTOGRAM_ALPHA_SIZE:
+ *params = (GLint) ctx->Histogram.AlphaSize;
+ break;
+ case GL_HISTOGRAM_LUMINANCE_SIZE:
+ *params = (GLint) ctx->Histogram.LuminanceSize;
+ break;
+ case GL_HISTOGRAM_SINK:
+ *params = (GLint) ctx->Histogram.Sink;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetHistogramParameteriv(pname)");
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_GetMinmaxParameterfv(GLenum target, GLenum pname, GLfloat *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetMinmaxParameterfv");
+ return;
+ }
+ if (target != GL_MINMAX) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetMinmaxParameterfv(target)");
+ return;
+ }
+ if (pname == GL_MINMAX_FORMAT) {
+ *params = (GLfloat) ctx->MinMax.Format;
+ }
+ else if (pname == GL_MINMAX_SINK) {
+ *params = (GLfloat) ctx->MinMax.Sink;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetMinMaxParameterfv(pname)");
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_GetMinmaxParameteriv(GLenum target, GLenum pname, GLint *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetMinmaxParameteriv");
+ return;
+ }
+ if (target != GL_MINMAX) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetMinmaxParameteriv(target)");
+ return;
+ }
+ if (pname == GL_MINMAX_FORMAT) {
+ *params = (GLint) ctx->MinMax.Format;
+ }
+ else if (pname == GL_MINMAX_SINK) {
+ *params = (GLint) ctx->MinMax.Sink;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetMinMaxParameteriv(pname)");
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_Histogram(GLenum target, GLsizei width, GLenum internalFormat, GLboolean sink)
+{
+ GLuint i;
+ GLboolean error = GL_FALSE;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* sideeffects */
+
+ if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glHistogram");
+ return;
+ }
+
+ if (target != GL_HISTOGRAM && target != GL_PROXY_HISTOGRAM) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glHistogram(target)");
+ return;
+ }
+
+ if (width < 0 || width > HISTOGRAM_TABLE_SIZE) {
+ if (target == GL_PROXY_HISTOGRAM) {
+ error = GL_TRUE;
+ }
+ else {
+ if (width < 0)
+ _mesa_error(ctx, GL_INVALID_VALUE, "glHistogram(width)");
+ else
+ _mesa_error(ctx, GL_TABLE_TOO_LARGE, "glHistogram(width)");
+ return;
+ }
+ }
+
+ if (width != 0 && _mesa_bitcount(width) != 1) {
+ if (target == GL_PROXY_HISTOGRAM) {
+ error = GL_TRUE;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glHistogram(width)");
+ return;
+ }
+ }
+
+ if (base_histogram_format(internalFormat) < 0) {
+ if (target == GL_PROXY_HISTOGRAM) {
+ error = GL_TRUE;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glHistogram(internalFormat)");
+ return;
+ }
+ }
+
+ /* reset histograms */
+ for (i = 0; i < HISTOGRAM_TABLE_SIZE; i++) {
+ ctx->Histogram.Count[i][0] = 0;
+ ctx->Histogram.Count[i][1] = 0;
+ ctx->Histogram.Count[i][2] = 0;
+ ctx->Histogram.Count[i][3] = 0;
+ }
+
+ if (error) {
+ ctx->Histogram.Width = 0;
+ ctx->Histogram.Format = 0;
+ ctx->Histogram.RedSize = 0;
+ ctx->Histogram.GreenSize = 0;
+ ctx->Histogram.BlueSize = 0;
+ ctx->Histogram.AlphaSize = 0;
+ ctx->Histogram.LuminanceSize = 0;
+ }
+ else {
+ ctx->Histogram.Width = width;
+ ctx->Histogram.Format = internalFormat;
+ ctx->Histogram.Sink = sink;
+ ctx->Histogram.RedSize = 8 * sizeof(GLuint);
+ ctx->Histogram.GreenSize = 8 * sizeof(GLuint);
+ ctx->Histogram.BlueSize = 8 * sizeof(GLuint);
+ ctx->Histogram.AlphaSize = 8 * sizeof(GLuint);
+ ctx->Histogram.LuminanceSize = 8 * sizeof(GLuint);
+ }
+
+ ctx->NewState |= _NEW_PIXEL;
+}
+
+
+void GLAPIENTRY
+_mesa_Minmax(GLenum target, GLenum internalFormat, GLboolean sink)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glMinmax");
+ return;
+ }
+
+ if (target != GL_MINMAX) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glMinMax(target)");
+ return;
+ }
+
+ if (base_histogram_format(internalFormat) < 0) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glMinMax(internalFormat)");
+ return;
+ }
+
+ if (ctx->MinMax.Sink == sink)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->MinMax.Sink = sink;
+}
+
+
+void GLAPIENTRY
+_mesa_ResetHistogram(GLenum target)
+{
+ GLuint i;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* sideeffects */
+
+ if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glResetHistogram");
+ return;
+ }
+
+ if (target != GL_HISTOGRAM) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glResetHistogram(target)");
+ return;
+ }
+
+ for (i = 0; i < HISTOGRAM_TABLE_SIZE; i++) {
+ ctx->Histogram.Count[i][0] = 0;
+ ctx->Histogram.Count[i][1] = 0;
+ ctx->Histogram.Count[i][2] = 0;
+ ctx->Histogram.Count[i][3] = 0;
+ }
+
+ ctx->NewState |= _NEW_PIXEL;
+}
+
+
+void GLAPIENTRY
+_mesa_ResetMinmax(GLenum target)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glResetMinmax");
+ return;
+ }
+
+ if (target != GL_MINMAX) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glResetMinMax(target)");
+ return;
+ }
+
+ ctx->MinMax.Min[RCOMP] = 1000; ctx->MinMax.Max[RCOMP] = -1000;
+ ctx->MinMax.Min[GCOMP] = 1000; ctx->MinMax.Max[GCOMP] = -1000;
+ ctx->MinMax.Min[BCOMP] = 1000; ctx->MinMax.Max[BCOMP] = -1000;
+ ctx->MinMax.Min[ACOMP] = 1000; ctx->MinMax.Max[ACOMP] = -1000;
+ ctx->NewState |= _NEW_PIXEL;
+}
+
+
+
+/**********************************************************************/
+/***** Initialization *****/
+/**********************************************************************/
+
+void _mesa_init_histogram( GLcontext * ctx )
+{
+ int i;
+
+ /* Histogram group */
+ ctx->Histogram.Width = 0;
+ ctx->Histogram.Format = GL_RGBA;
+ ctx->Histogram.Sink = GL_FALSE;
+ ctx->Histogram.RedSize = 0;
+ ctx->Histogram.GreenSize = 0;
+ ctx->Histogram.BlueSize = 0;
+ ctx->Histogram.AlphaSize = 0;
+ ctx->Histogram.LuminanceSize = 0;
+ for (i = 0; i < HISTOGRAM_TABLE_SIZE; i++) {
+ ctx->Histogram.Count[i][0] = 0;
+ ctx->Histogram.Count[i][1] = 0;
+ ctx->Histogram.Count[i][2] = 0;
+ ctx->Histogram.Count[i][3] = 0;
+ }
+
+ /* Min/Max group */
+ ctx->MinMax.Format = GL_RGBA;
+ ctx->MinMax.Sink = GL_FALSE;
+ ctx->MinMax.Min[RCOMP] = 1000; ctx->MinMax.Max[RCOMP] = -1000;
+ ctx->MinMax.Min[GCOMP] = 1000; ctx->MinMax.Max[GCOMP] = -1000;
+ ctx->MinMax.Min[BCOMP] = 1000; ctx->MinMax.Max[BCOMP] = -1000;
+ ctx->MinMax.Min[ACOMP] = 1000; ctx->MinMax.Max[ACOMP] = -1000;
+}
diff --git a/src/mesa/main/histogram.h b/src/mesa/main/histogram.h
new file mode 100644
index 00000000000..974447231dd
--- /dev/null
+++ b/src/mesa/main/histogram.h
@@ -0,0 +1,89 @@
+/**
+ * \file histogram.h
+ * Histogram.
+ *
+ * \if subset
+ * (No-op)
+ *
+ * \endif
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 5.1
+ *
+ * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef HISTOGRAM_H
+#define HISTOGRAM_H
+
+#include "glheader.h"
+#include "mtypes.h"
+
+#if _HAVE_FULL_GL
+
+extern void GLAPIENTRY
+_mesa_GetMinmax(GLenum target, GLboolean reset, GLenum format, GLenum types, GLvoid *values);
+
+extern void GLAPIENTRY
+_mesa_GetHistogram(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+
+extern void GLAPIENTRY
+_mesa_GetHistogramParameterfv(GLenum target, GLenum pname, GLfloat *params);
+
+extern void GLAPIENTRY
+_mesa_GetHistogramParameteriv(GLenum target, GLenum pname, GLint *params);
+
+extern void GLAPIENTRY
+_mesa_GetMinmaxParameterfv(GLenum target, GLenum pname, GLfloat *params);
+
+extern void GLAPIENTRY
+_mesa_GetMinmaxParameteriv(GLenum target, GLenum pname, GLint *params);
+
+extern void GLAPIENTRY
+_mesa_Histogram(GLenum target, GLsizei width, GLenum internalformat, GLboolean sink);
+
+extern void GLAPIENTRY
+_mesa_Minmax(GLenum target, GLenum internalformat, GLboolean sink);
+
+extern void GLAPIENTRY
+_mesa_ResetHistogram(GLenum target);
+
+extern void GLAPIENTRY
+_mesa_ResetMinmax(GLenum target);
+
+extern void
+_mesa_update_minmax(GLcontext *ctx, GLuint n, const GLfloat rgba[][4]);
+
+extern void
+_mesa_update_histogram(GLcontext *ctx, GLuint n, const GLfloat rgba[][4]);
+
+extern void _mesa_init_histogram( GLcontext * ctx );
+
+#else
+
+/** No-op */
+#define _mesa_init_histogram( c ) ((void) 0)
+
+#endif
+
+#endif
diff --git a/src/mesa/main/image.c b/src/mesa/main/image.c
new file mode 100644
index 00000000000..a82b540ed60
--- /dev/null
+++ b/src/mesa/main/image.c
@@ -0,0 +1,4355 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/**
+ * \file image.c
+ * Image handling.
+ */
+
+
+#include "glheader.h"
+#include "colormac.h"
+#include "context.h"
+#include "image.h"
+#include "imports.h"
+#include "histogram.h"
+#include "macros.h"
+#include "pixel.h"
+
+
+/** Compute ceiling of integer quotient of A divided by B. */
+#define CEILING( A, B ) ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 )
+
+
+/**
+ * Flip the 8 bits in each byte of the given array.
+ *
+ * \param p array.
+ * \param n number of bytes.
+ *
+ * \todo try this trick to flip bytes someday:
+ * \code
+ * v = ((v & 0x55555555) << 1) | ((v >> 1) & 0x55555555);
+ * v = ((v & 0x33333333) << 2) | ((v >> 2) & 0x33333333);
+ * v = ((v & 0x0f0f0f0f) << 4) | ((v >> 4) & 0x0f0f0f0f);
+ * \endcode
+ */
+static void
+flip_bytes( GLubyte *p, GLuint n )
+{
+ register GLuint i, a, b;
+
+ for (i=0;i<n;i++) {
+ b = (GLuint) p[i]; /* words are often faster than bytes */
+ a = ((b & 0x01) << 7) |
+ ((b & 0x02) << 5) |
+ ((b & 0x04) << 3) |
+ ((b & 0x08) << 1) |
+ ((b & 0x10) >> 1) |
+ ((b & 0x20) >> 3) |
+ ((b & 0x40) >> 5) |
+ ((b & 0x80) >> 7);
+ p[i] = (GLubyte) a;
+ }
+}
+
+
+/**
+ * Flip the order of the 2 bytes in each word in the given array.
+ *
+ * \param p array.
+ * \param n number of words.
+ */
+void
+_mesa_swap2( GLushort *p, GLuint n )
+{
+ register GLuint i;
+
+ for (i=0;i<n;i++) {
+ p[i] = (p[i] >> 8) | ((p[i] << 8) & 0xff00);
+ }
+}
+
+
+
+/*
+ * Flip the order of the 4 bytes in each word in the given array.
+ */
+void
+_mesa_swap4( GLuint *p, GLuint n )
+{
+ register GLuint i, a, b;
+
+ for (i=0;i<n;i++) {
+ b = p[i];
+ a = (b >> 24)
+ | ((b >> 8) & 0xff00)
+ | ((b << 8) & 0xff0000)
+ | ((b << 24) & 0xff000000);
+ p[i] = a;
+ }
+}
+
+
+/**
+ * Get the size of a GL data type.
+ *
+ * \param type GL data type.
+ *
+ * \return the size, in bytes, of the given data type, 0 if a GL_BITMAP, or -1
+ * if an invalid type enum.
+ */
+GLint _mesa_sizeof_type( GLenum type )
+{
+ switch (type) {
+ case GL_BITMAP:
+ return 0;
+ case GL_UNSIGNED_BYTE:
+ return sizeof(GLubyte);
+ case GL_BYTE:
+ return sizeof(GLbyte);
+ case GL_UNSIGNED_SHORT:
+ return sizeof(GLushort);
+ case GL_SHORT:
+ return sizeof(GLshort);
+ case GL_UNSIGNED_INT:
+ return sizeof(GLuint);
+ case GL_INT:
+ return sizeof(GLint);
+ case GL_FLOAT:
+ return sizeof(GLfloat);
+ case GL_HALF_FLOAT_ARB:
+ return sizeof(GLhalfARB);
+ default:
+ return -1;
+ }
+}
+
+
+/**
+ * Same as _mesa_sizeof_type() but also accepting the packed pixel
+ * format data types.
+ */
+GLint _mesa_sizeof_packed_type( GLenum type )
+{
+ switch (type) {
+ case GL_BITMAP:
+ return 0;
+ case GL_UNSIGNED_BYTE:
+ return sizeof(GLubyte);
+ case GL_BYTE:
+ return sizeof(GLbyte);
+ case GL_UNSIGNED_SHORT:
+ return sizeof(GLushort);
+ case GL_SHORT:
+ return sizeof(GLshort);
+ case GL_UNSIGNED_INT:
+ return sizeof(GLuint);
+ case GL_INT:
+ return sizeof(GLint);
+ case GL_HALF_FLOAT_ARB:
+ return sizeof(GLhalfARB);
+ case GL_FLOAT:
+ return sizeof(GLfloat);
+ case GL_UNSIGNED_BYTE_3_3_2:
+ return sizeof(GLubyte);
+ case GL_UNSIGNED_BYTE_2_3_3_REV:
+ return sizeof(GLubyte);
+ case GL_UNSIGNED_SHORT_5_6_5:
+ return sizeof(GLushort);
+ case GL_UNSIGNED_SHORT_5_6_5_REV:
+ return sizeof(GLushort);
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ return sizeof(GLushort);
+ case GL_UNSIGNED_SHORT_4_4_4_4_REV:
+ return sizeof(GLushort);
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ return sizeof(GLushort);
+ case GL_UNSIGNED_SHORT_1_5_5_5_REV:
+ return sizeof(GLushort);
+ case GL_UNSIGNED_INT_8_8_8_8:
+ return sizeof(GLuint);
+ case GL_UNSIGNED_INT_8_8_8_8_REV:
+ return sizeof(GLuint);
+ case GL_UNSIGNED_INT_10_10_10_2:
+ return sizeof(GLuint);
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ return sizeof(GLuint);
+ case GL_UNSIGNED_SHORT_8_8_MESA:
+ case GL_UNSIGNED_SHORT_8_8_REV_MESA:
+ return sizeof(GLushort);
+ case GL_UNSIGNED_INT_24_8_EXT:
+ return sizeof(GLuint);
+ default:
+ return -1;
+ }
+}
+
+
+/**
+ * Get the number of components in a pixel format.
+ *
+ * \param format pixel format.
+ *
+ * \return the number of components in the given format, or -1 if a bad format.
+ */
+GLint _mesa_components_in_format( GLenum format )
+{
+ switch (format) {
+ case GL_COLOR_INDEX:
+ case GL_COLOR_INDEX1_EXT:
+ case GL_COLOR_INDEX2_EXT:
+ case GL_COLOR_INDEX4_EXT:
+ case GL_COLOR_INDEX8_EXT:
+ case GL_COLOR_INDEX12_EXT:
+ case GL_COLOR_INDEX16_EXT:
+ case GL_STENCIL_INDEX:
+ case GL_DEPTH_COMPONENT:
+ case GL_RED:
+ case GL_GREEN:
+ case GL_BLUE:
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_INTENSITY:
+ return 1;
+ case GL_LUMINANCE_ALPHA:
+ return 2;
+ case GL_RGB:
+ return 3;
+ case GL_RGBA:
+ return 4;
+ case GL_BGR:
+ return 3;
+ case GL_BGRA:
+ return 4;
+ case GL_ABGR_EXT:
+ return 4;
+ case GL_YCBCR_MESA:
+ return 2;
+ case GL_DEPTH_STENCIL_EXT:
+ return 2;
+ default:
+ return -1;
+ }
+}
+
+
+/**
+ * Get the bytes per pixel of pixel format type pair.
+ *
+ * \param format pixel format.
+ * \param type pixel type.
+ *
+ * \return bytes per pixel, or -1 if a bad format or type was given.
+ */
+GLint _mesa_bytes_per_pixel( GLenum format, GLenum type )
+{
+ GLint comps = _mesa_components_in_format( format );
+ if (comps < 0)
+ return -1;
+
+ switch (type) {
+ case GL_BITMAP:
+ return 0; /* special case */
+ case GL_BYTE:
+ case GL_UNSIGNED_BYTE:
+ return comps * sizeof(GLubyte);
+ case GL_SHORT:
+ case GL_UNSIGNED_SHORT:
+ return comps * sizeof(GLshort);
+ case GL_INT:
+ case GL_UNSIGNED_INT:
+ return comps * sizeof(GLint);
+ case GL_FLOAT:
+ return comps * sizeof(GLfloat);
+ case GL_HALF_FLOAT_ARB:
+ return comps * sizeof(GLhalfARB);
+ case GL_UNSIGNED_BYTE_3_3_2:
+ case GL_UNSIGNED_BYTE_2_3_3_REV:
+ if (format == GL_RGB || format == GL_BGR)
+ return sizeof(GLubyte);
+ else
+ return -1; /* error */
+ case GL_UNSIGNED_SHORT_5_6_5:
+ case GL_UNSIGNED_SHORT_5_6_5_REV:
+ if (format == GL_RGB || format == GL_BGR)
+ return sizeof(GLushort);
+ else
+ return -1; /* error */
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ case GL_UNSIGNED_SHORT_4_4_4_4_REV:
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ case GL_UNSIGNED_SHORT_1_5_5_5_REV:
+ if (format == GL_RGBA || format == GL_BGRA || format == GL_ABGR_EXT)
+ return sizeof(GLushort);
+ else
+ return -1;
+ case GL_UNSIGNED_INT_8_8_8_8:
+ case GL_UNSIGNED_INT_8_8_8_8_REV:
+ case GL_UNSIGNED_INT_10_10_10_2:
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ if (format == GL_RGBA || format == GL_BGRA || format == GL_ABGR_EXT)
+ return sizeof(GLuint);
+ else
+ return -1;
+ case GL_UNSIGNED_SHORT_8_8_MESA:
+ case GL_UNSIGNED_SHORT_8_8_REV_MESA:
+ if (format == GL_YCBCR_MESA)
+ return sizeof(GLushort);
+ else
+ return -1;
+ case GL_UNSIGNED_INT_24_8_EXT:
+ if (format == GL_DEPTH_STENCIL_EXT)
+ return sizeof(GLuint);
+ else
+ return -1;
+ default:
+ return -1;
+ }
+}
+
+
+/**
+ * Test for a legal pixel format and type.
+ *
+ * \param format pixel format.
+ * \param type pixel type.
+ *
+ * \return GL_TRUE if the given pixel format and type are legal, or GL_FALSE
+ * otherwise.
+ */
+GLboolean
+_mesa_is_legal_format_and_type( GLcontext *ctx, GLenum format, GLenum type )
+{
+ switch (format) {
+ case GL_COLOR_INDEX:
+ case GL_STENCIL_INDEX:
+ switch (type) {
+ case GL_BITMAP:
+ case GL_BYTE:
+ case GL_UNSIGNED_BYTE:
+ case GL_SHORT:
+ case GL_UNSIGNED_SHORT:
+ case GL_INT:
+ case GL_UNSIGNED_INT:
+ case GL_FLOAT:
+ return GL_TRUE;
+ case GL_HALF_FLOAT_ARB:
+ return ctx->Extensions.ARB_half_float_pixel;
+ default:
+ return GL_FALSE;
+ }
+ case GL_RED:
+ case GL_GREEN:
+ case GL_BLUE:
+ case GL_ALPHA:
+#if 0 /* not legal! see table 3.6 of the 1.5 spec */
+ case GL_INTENSITY:
+#endif
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ case GL_DEPTH_COMPONENT:
+ switch (type) {
+ case GL_BYTE:
+ case GL_UNSIGNED_BYTE:
+ case GL_SHORT:
+ case GL_UNSIGNED_SHORT:
+ case GL_INT:
+ case GL_UNSIGNED_INT:
+ case GL_FLOAT:
+ return GL_TRUE;
+ case GL_HALF_FLOAT_ARB:
+ return ctx->Extensions.ARB_half_float_pixel;
+ default:
+ return GL_FALSE;
+ }
+ case GL_RGB:
+ switch (type) {
+ case GL_BYTE:
+ case GL_UNSIGNED_BYTE:
+ case GL_SHORT:
+ case GL_UNSIGNED_SHORT:
+ case GL_INT:
+ case GL_UNSIGNED_INT:
+ case GL_FLOAT:
+ case GL_UNSIGNED_BYTE_3_3_2:
+ case GL_UNSIGNED_BYTE_2_3_3_REV:
+ case GL_UNSIGNED_SHORT_5_6_5:
+ case GL_UNSIGNED_SHORT_5_6_5_REV:
+ return GL_TRUE;
+ case GL_HALF_FLOAT_ARB:
+ return ctx->Extensions.ARB_half_float_pixel;
+ default:
+ return GL_FALSE;
+ }
+ case GL_BGR:
+ switch (type) {
+ case GL_BYTE:
+ case GL_UNSIGNED_BYTE:
+ case GL_SHORT:
+ case GL_UNSIGNED_SHORT:
+ case GL_INT:
+ case GL_UNSIGNED_INT:
+ case GL_FLOAT:
+ return GL_TRUE;
+ case GL_HALF_FLOAT_ARB:
+ return ctx->Extensions.ARB_half_float_pixel;
+ default:
+ return GL_FALSE;
+ }
+ case GL_RGBA:
+ case GL_BGRA:
+ case GL_ABGR_EXT:
+ switch (type) {
+ case GL_BYTE:
+ case GL_UNSIGNED_BYTE:
+ case GL_SHORT:
+ case GL_UNSIGNED_SHORT:
+ case GL_INT:
+ case GL_UNSIGNED_INT:
+ case GL_FLOAT:
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ case GL_UNSIGNED_SHORT_4_4_4_4_REV:
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ case GL_UNSIGNED_SHORT_1_5_5_5_REV:
+ case GL_UNSIGNED_INT_8_8_8_8:
+ case GL_UNSIGNED_INT_8_8_8_8_REV:
+ case GL_UNSIGNED_INT_10_10_10_2:
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ return GL_TRUE;
+ case GL_HALF_FLOAT_ARB:
+ return ctx->Extensions.ARB_half_float_pixel;
+ default:
+ return GL_FALSE;
+ }
+ case GL_YCBCR_MESA:
+ if (type == GL_UNSIGNED_SHORT_8_8_MESA ||
+ type == GL_UNSIGNED_SHORT_8_8_REV_MESA)
+ return GL_TRUE;
+ else
+ return GL_FALSE;
+ case GL_DEPTH_STENCIL_EXT:
+ if (ctx->Extensions.EXT_packed_depth_stencil
+ && type == GL_UNSIGNED_INT_24_8_EXT)
+ return GL_TRUE;
+ else
+ return GL_FALSE;
+ default:
+ ; /* fall-through */
+ }
+ return GL_FALSE;
+}
+
+
+/**
+ * Return the address of a specific pixel in an image (1D, 2D or 3D).
+ *
+ * Pixel unpacking/packing parameters are observed according to \p packing.
+ *
+ * \param dimensions either 1, 2 or 3 to indicate dimensionality of image
+ * \param image starting address of image data
+ * \param width the image width
+ * \param height theimage height
+ * \param format the pixel format
+ * \param type the pixel data type
+ * \param packing the pixelstore attributes
+ * \param img which image in the volume (0 for 1D or 2D images)
+ * \param row row of pixel in the image (0 for 1D images)
+ * \param column column of pixel in the image
+ *
+ * \return address of pixel on success, or NULL on error.
+ *
+ * \sa gl_pixelstore_attrib.
+ */
+GLvoid *
+_mesa_image_address( GLuint dimensions,
+ const struct gl_pixelstore_attrib *packing,
+ const GLvoid *image,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ GLint img, GLint row, GLint column )
+{
+ GLint alignment; /* 1, 2 or 4 */
+ GLint pixels_per_row;
+ GLint rows_per_image;
+ GLint skiprows;
+ GLint skippixels;
+ GLint skipimages; /* for 3-D volume images */
+ GLubyte *pixel_addr;
+
+ ASSERT(dimensions >= 1 && dimensions <= 3);
+
+ alignment = packing->Alignment;
+ if (packing->RowLength > 0) {
+ pixels_per_row = packing->RowLength;
+ }
+ else {
+ pixels_per_row = width;
+ }
+ if (packing->ImageHeight > 0) {
+ rows_per_image = packing->ImageHeight;
+ }
+ else {
+ rows_per_image = height;
+ }
+
+ skippixels = packing->SkipPixels;
+ /* Note: SKIP_ROWS _is_ used for 1D images */
+ skiprows = packing->SkipRows;
+ /* Note: SKIP_IMAGES is only used for 3D images */
+ skipimages = (dimensions == 3) ? packing->SkipImages : 0;
+
+ if (type == GL_BITMAP) {
+ /* BITMAP data */
+ GLint comp_per_pixel; /* components per pixel */
+ GLint bytes_per_comp; /* bytes per component */
+ GLint bytes_per_row;
+ GLint bytes_per_image;
+
+ /* Compute bytes per component */
+ bytes_per_comp = _mesa_sizeof_packed_type( type );
+ if (bytes_per_comp < 0) {
+ return NULL;
+ }
+
+ /* Compute number of components per pixel */
+ comp_per_pixel = _mesa_components_in_format( format );
+ if (comp_per_pixel < 0) {
+ return NULL;
+ }
+
+ bytes_per_row = alignment
+ * CEILING( comp_per_pixel*pixels_per_row, 8*alignment );
+
+ bytes_per_image = bytes_per_row * rows_per_image;
+
+ pixel_addr = (GLubyte *) image
+ + (skipimages + img) * bytes_per_image
+ + (skiprows + row) * bytes_per_row
+ + (skippixels + column) / 8;
+ }
+ else {
+ /* Non-BITMAP data */
+ GLint bytes_per_pixel, bytes_per_row, remainder, bytes_per_image;
+ GLint topOfImage;
+
+ bytes_per_pixel = _mesa_bytes_per_pixel( format, type );
+
+ /* The pixel type and format should have been error checked earlier */
+ assert(bytes_per_pixel > 0);
+
+ bytes_per_row = pixels_per_row * bytes_per_pixel;
+ remainder = bytes_per_row % alignment;
+ if (remainder > 0)
+ bytes_per_row += (alignment - remainder);
+
+ ASSERT(bytes_per_row % alignment == 0);
+
+ bytes_per_image = bytes_per_row * rows_per_image;
+
+ if (packing->Invert) {
+ /* set pixel_addr to the last row */
+ topOfImage = bytes_per_row * (height - 1);
+ bytes_per_row = -bytes_per_row;
+ }
+ else {
+ topOfImage = 0;
+ }
+
+ /* compute final pixel address */
+ pixel_addr = (GLubyte *) image
+ + (skipimages + img) * bytes_per_image
+ + topOfImage
+ + (skiprows + row) * bytes_per_row
+ + (skippixels + column) * bytes_per_pixel;
+ }
+
+ return (GLvoid *) pixel_addr;
+}
+
+
+GLvoid *
+_mesa_image_address1d( const struct gl_pixelstore_attrib *packing,
+ const GLvoid *image,
+ GLsizei width,
+ GLenum format, GLenum type,
+ GLint column )
+{
+ return _mesa_image_address(1, packing, image, width, 1,
+ format, type, 0, 0, column);
+}
+
+
+GLvoid *
+_mesa_image_address2d( const struct gl_pixelstore_attrib *packing,
+ const GLvoid *image,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ GLint row, GLint column )
+{
+ return _mesa_image_address(2, packing, image, width, height,
+ format, type, 0, row, column);
+}
+
+
+GLvoid *
+_mesa_image_address3d( const struct gl_pixelstore_attrib *packing,
+ const GLvoid *image,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ GLint img, GLint row, GLint column )
+{
+ return _mesa_image_address(3, packing, image, width, height,
+ format, type, img, row, column);
+}
+
+
+
+/**
+ * Compute the stride between image rows.
+ *
+ * \param packing the pixelstore attributes
+ * \param width image width.
+ * \param format pixel format.
+ * \param type pixel data type.
+ *
+ * \return the stride in bytes for the given parameters.
+ *
+ * Computes the number of bytes per pixel and row and compensates for alignment.
+ *
+ * \sa gl_pixelstore_attrib.
+ */
+GLint
+_mesa_image_row_stride( const struct gl_pixelstore_attrib *packing,
+ GLint width, GLenum format, GLenum type )
+{
+ ASSERT(packing);
+ if (type == GL_BITMAP) {
+ /* BITMAP data */
+ GLint bytes;
+ if (packing->RowLength == 0) {
+ bytes = (width + 7) / 8;
+ }
+ else {
+ bytes = (packing->RowLength + 7) / 8;
+ }
+ if (packing->Invert) {
+ /* negate the bytes per row (negative row stride) */
+ bytes = -bytes;
+ }
+ return bytes;
+ }
+ else {
+ /* Non-BITMAP data */
+ const GLint bytesPerPixel = _mesa_bytes_per_pixel(format, type);
+ GLint bytesPerRow, remainder;
+ if (bytesPerPixel <= 0)
+ return -1; /* error */
+ if (packing->RowLength == 0) {
+ bytesPerRow = bytesPerPixel * width;
+ }
+ else {
+ bytesPerRow = bytesPerPixel * packing->RowLength;
+ }
+ remainder = bytesPerRow % packing->Alignment;
+ if (remainder > 0)
+ bytesPerRow += (packing->Alignment - remainder);
+ if (packing->Invert)
+ bytesPerRow = -bytesPerRow;
+ return bytesPerRow;
+ }
+}
+
+
+#if _HAVE_FULL_GL
+
+/*
+ * Compute the stride between images in a 3D texture (in bytes) for the given
+ * pixel packing parameters and image width, format and type.
+ */
+GLint
+_mesa_image_image_stride( const struct gl_pixelstore_attrib *packing,
+ GLint width, GLint height,
+ GLenum format, GLenum type )
+{
+ ASSERT(packing);
+ ASSERT(type != GL_BITMAP);
+
+ {
+ const GLint bytesPerPixel = _mesa_bytes_per_pixel(format, type);
+ GLint bytesPerRow, bytesPerImage, remainder;
+
+ if (bytesPerPixel <= 0)
+ return -1; /* error */
+ if (packing->RowLength == 0) {
+ bytesPerRow = bytesPerPixel * width;
+ }
+ else {
+ bytesPerRow = bytesPerPixel * packing->RowLength;
+ }
+ remainder = bytesPerRow % packing->Alignment;
+ if (remainder > 0)
+ bytesPerRow += (packing->Alignment - remainder);
+
+ if (packing->ImageHeight == 0)
+ bytesPerImage = bytesPerRow * height;
+ else
+ bytesPerImage = bytesPerRow * packing->ImageHeight;
+
+ return bytesPerImage;
+ }
+}
+
+
+/*
+ * Unpack a 32x32 pixel polygon stipple from user memory using the
+ * current pixel unpack settings.
+ */
+void
+_mesa_unpack_polygon_stipple( const GLubyte *pattern, GLuint dest[32],
+ const struct gl_pixelstore_attrib *unpacking )
+{
+ GLubyte *ptrn = (GLubyte *) _mesa_unpack_bitmap( 32, 32, pattern, unpacking );
+ if (ptrn) {
+ /* Convert pattern from GLubytes to GLuints and handle big/little
+ * endian differences
+ */
+ GLubyte *p = ptrn;
+ GLint i;
+ for (i = 0; i < 32; i++) {
+ dest[i] = (p[0] << 24)
+ | (p[1] << 16)
+ | (p[2] << 8)
+ | (p[3] );
+ p += 4;
+ }
+ FREE(ptrn);
+ }
+}
+
+
+/*
+ * Pack polygon stipple into user memory given current pixel packing
+ * settings.
+ */
+void
+_mesa_pack_polygon_stipple( const GLuint pattern[32], GLubyte *dest,
+ const struct gl_pixelstore_attrib *packing )
+{
+ /* Convert pattern from GLuints to GLubytes to handle big/little
+ * endian differences.
+ */
+ GLubyte ptrn[32*4];
+ GLint i;
+ for (i = 0; i < 32; i++) {
+ ptrn[i * 4 + 0] = (GLubyte) ((pattern[i] >> 24) & 0xff);
+ ptrn[i * 4 + 1] = (GLubyte) ((pattern[i] >> 16) & 0xff);
+ ptrn[i * 4 + 2] = (GLubyte) ((pattern[i] >> 8 ) & 0xff);
+ ptrn[i * 4 + 3] = (GLubyte) ((pattern[i] ) & 0xff);
+ }
+
+ _mesa_pack_bitmap(32, 32, ptrn, dest, packing);
+}
+
+
+/*
+ * Unpack bitmap data. Resulting data will be in most-significant-bit-first
+ * order with row alignment = 1 byte.
+ */
+GLvoid *
+_mesa_unpack_bitmap( GLint width, GLint height, const GLubyte *pixels,
+ const struct gl_pixelstore_attrib *packing )
+{
+ GLint bytes, row, width_in_bytes;
+ GLubyte *buffer, *dst;
+
+ if (!pixels)
+ return NULL;
+
+ /* Alloc dest storage */
+ bytes = ((width + 7) / 8 * height);
+ buffer = (GLubyte *) MALLOC( bytes );
+ if (!buffer)
+ return NULL;
+
+
+ width_in_bytes = CEILING( width, 8 );
+ dst = buffer;
+ for (row = 0; row < height; row++) {
+ const GLubyte *src = (const GLubyte *)
+ _mesa_image_address2d(packing, pixels, width, height,
+ GL_COLOR_INDEX, GL_BITMAP, row, 0);
+ if (!src) {
+ FREE(buffer);
+ return NULL;
+ }
+
+ if (packing->SkipPixels == 0) {
+ MEMCPY( dst, src, width_in_bytes );
+ if (packing->LsbFirst) {
+ flip_bytes( dst, width_in_bytes );
+ }
+ }
+ else {
+ /* handling SkipPixels is a bit tricky (no pun intended!) */
+ GLint i;
+ if (packing->LsbFirst) {
+ GLubyte srcMask = 1 << (packing->SkipPixels & 0x7);
+ GLubyte dstMask = 128;
+ const GLubyte *s = src;
+ GLubyte *d = dst;
+ *d = 0;
+ for (i = 0; i < width; i++) {
+ if (*s & srcMask) {
+ *d |= dstMask;
+ }
+ if (srcMask == 128) {
+ srcMask = 1;
+ s++;
+ }
+ else {
+ srcMask = srcMask << 1;
+ }
+ if (dstMask == 1) {
+ dstMask = 128;
+ d++;
+ *d = 0;
+ }
+ else {
+ dstMask = dstMask >> 1;
+ }
+ }
+ }
+ else {
+ GLubyte srcMask = 128 >> (packing->SkipPixels & 0x7);
+ GLubyte dstMask = 128;
+ const GLubyte *s = src;
+ GLubyte *d = dst;
+ *d = 0;
+ for (i = 0; i < width; i++) {
+ if (*s & srcMask) {
+ *d |= dstMask;
+ }
+ if (srcMask == 1) {
+ srcMask = 128;
+ s++;
+ }
+ else {
+ srcMask = srcMask >> 1;
+ }
+ if (dstMask == 1) {
+ dstMask = 128;
+ d++;
+ *d = 0;
+ }
+ else {
+ dstMask = dstMask >> 1;
+ }
+ }
+ }
+ }
+ dst += width_in_bytes;
+ }
+
+ return buffer;
+}
+
+
+/*
+ * Pack bitmap data.
+ */
+void
+_mesa_pack_bitmap( GLint width, GLint height, const GLubyte *source,
+ GLubyte *dest, const struct gl_pixelstore_attrib *packing )
+{
+ GLint row, width_in_bytes;
+ const GLubyte *src;
+
+ if (!source)
+ return;
+
+ width_in_bytes = CEILING( width, 8 );
+ src = source;
+ for (row = 0; row < height; row++) {
+ GLubyte *dst = (GLubyte *) _mesa_image_address2d(packing, dest,
+ width, height, GL_COLOR_INDEX, GL_BITMAP, row, 0);
+ if (!dst)
+ return;
+
+ if (packing->SkipPixels == 0) {
+ MEMCPY( dst, src, width_in_bytes );
+ if (packing->LsbFirst) {
+ flip_bytes( dst, width_in_bytes );
+ }
+ }
+ else {
+ /* handling SkipPixels is a bit tricky (no pun intended!) */
+ GLint i;
+ if (packing->LsbFirst) {
+ GLubyte srcMask = 1 << (packing->SkipPixels & 0x7);
+ GLubyte dstMask = 128;
+ const GLubyte *s = src;
+ GLubyte *d = dst;
+ *d = 0;
+ for (i = 0; i < width; i++) {
+ if (*s & srcMask) {
+ *d |= dstMask;
+ }
+ if (srcMask == 128) {
+ srcMask = 1;
+ s++;
+ }
+ else {
+ srcMask = srcMask << 1;
+ }
+ if (dstMask == 1) {
+ dstMask = 128;
+ d++;
+ *d = 0;
+ }
+ else {
+ dstMask = dstMask >> 1;
+ }
+ }
+ }
+ else {
+ GLubyte srcMask = 128 >> (packing->SkipPixels & 0x7);
+ GLubyte dstMask = 128;
+ const GLubyte *s = src;
+ GLubyte *d = dst;
+ *d = 0;
+ for (i = 0; i < width; i++) {
+ if (*s & srcMask) {
+ *d |= dstMask;
+ }
+ if (srcMask == 1) {
+ srcMask = 128;
+ s++;
+ }
+ else {
+ srcMask = srcMask >> 1;
+ }
+ if (dstMask == 1) {
+ dstMask = 128;
+ d++;
+ *d = 0;
+ }
+ else {
+ dstMask = dstMask >> 1;
+ }
+ }
+ }
+ }
+ src += width_in_bytes;
+ }
+}
+
+
+/**
+ * Apply various pixel transfer operations to an array of RGBA pixels
+ * as indicated by the transferOps bitmask
+ */
+void
+_mesa_apply_rgba_transfer_ops(GLcontext *ctx, GLuint transferOps,
+ GLuint n, GLfloat rgba[][4])
+{
+ /* scale & bias */
+ if (transferOps & IMAGE_SCALE_BIAS_BIT) {
+ _mesa_scale_and_bias_rgba(n, rgba,
+ ctx->Pixel.RedScale, ctx->Pixel.GreenScale,
+ ctx->Pixel.BlueScale, ctx->Pixel.AlphaScale,
+ ctx->Pixel.RedBias, ctx->Pixel.GreenBias,
+ ctx->Pixel.BlueBias, ctx->Pixel.AlphaBias);
+ }
+ /* color map lookup */
+ if (transferOps & IMAGE_MAP_COLOR_BIT) {
+ _mesa_map_rgba( ctx, n, rgba );
+ }
+ /* GL_COLOR_TABLE lookup */
+ if (transferOps & IMAGE_COLOR_TABLE_BIT) {
+ _mesa_lookup_rgba_float(&ctx->ColorTable, n, rgba);
+ }
+ /* convolution */
+ if (transferOps & IMAGE_CONVOLUTION_BIT) {
+ /* this has to be done in the calling code */
+ _mesa_problem(ctx, "IMAGE_CONVOLUTION_BIT set in _mesa_apply_transfer_ops");
+ }
+ /* GL_POST_CONVOLUTION_RED/GREEN/BLUE/ALPHA_SCALE/BIAS */
+ if (transferOps & IMAGE_POST_CONVOLUTION_SCALE_BIAS) {
+ _mesa_scale_and_bias_rgba(n, rgba,
+ ctx->Pixel.PostConvolutionScale[RCOMP],
+ ctx->Pixel.PostConvolutionScale[GCOMP],
+ ctx->Pixel.PostConvolutionScale[BCOMP],
+ ctx->Pixel.PostConvolutionScale[ACOMP],
+ ctx->Pixel.PostConvolutionBias[RCOMP],
+ ctx->Pixel.PostConvolutionBias[GCOMP],
+ ctx->Pixel.PostConvolutionBias[BCOMP],
+ ctx->Pixel.PostConvolutionBias[ACOMP]);
+ }
+ /* GL_POST_CONVOLUTION_COLOR_TABLE lookup */
+ if (transferOps & IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT) {
+ _mesa_lookup_rgba_float(&ctx->PostConvolutionColorTable, n, rgba);
+ }
+ /* color matrix transform */
+ if (transferOps & IMAGE_COLOR_MATRIX_BIT) {
+ _mesa_transform_rgba(ctx, n, rgba);
+ }
+ /* GL_POST_COLOR_MATRIX_COLOR_TABLE lookup */
+ if (transferOps & IMAGE_POST_COLOR_MATRIX_COLOR_TABLE_BIT) {
+ _mesa_lookup_rgba_float(&ctx->PostColorMatrixColorTable, n, rgba);
+ }
+ /* update histogram count */
+ if (transferOps & IMAGE_HISTOGRAM_BIT) {
+ _mesa_update_histogram(ctx, n, (CONST GLfloat (*)[4]) rgba);
+ }
+ /* update min/max values */
+ if (transferOps & IMAGE_MIN_MAX_BIT) {
+ _mesa_update_minmax(ctx, n, (CONST GLfloat (*)[4]) rgba);
+ }
+ /* clamping to [0,1] */
+ if (transferOps & IMAGE_CLAMP_BIT) {
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ rgba[i][RCOMP] = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F);
+ rgba[i][GCOMP] = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F);
+ rgba[i][BCOMP] = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F);
+ rgba[i][ACOMP] = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F);
+ }
+ }
+}
+
+
+
+/**
+ * Used to pack an array [][4] of RGBA float colors as specified
+ * by the dstFormat, dstType and dstPacking. Used by glReadPixels,
+ * glGetConvolutionFilter(), etc.
+ * NOTE: it's assumed the incoming float colors are all in [0,1].
+ */
+void
+_mesa_pack_rgba_span_float( GLcontext *ctx,
+ GLuint n, CONST GLfloat rgbaIn[][4],
+ GLenum dstFormat, GLenum dstType,
+ GLvoid *dstAddr,
+ const struct gl_pixelstore_attrib *dstPacking,
+ GLuint transferOps )
+{
+ const GLint comps = _mesa_components_in_format(dstFormat);
+ GLfloat luminance[MAX_WIDTH];
+ const GLfloat (*rgba)[4];
+ GLuint i;
+
+ if (transferOps) {
+ /* make copy of incoming data */
+ GLfloat rgbaCopy[MAX_WIDTH][4];
+ _mesa_memcpy(rgbaCopy, rgbaIn, n * 4 * sizeof(GLfloat));
+ _mesa_apply_rgba_transfer_ops(ctx, transferOps, n, rgbaCopy);
+ rgba = (const GLfloat (*)[4]) rgbaCopy;
+
+ if ((transferOps & IMAGE_MIN_MAX_BIT) && ctx->MinMax.Sink) {
+ return;
+ }
+ }
+ else {
+ /* use incoming data, not a copy */
+ rgba = (const GLfloat (*)[4]) rgbaIn;
+ }
+
+ if (dstFormat == GL_LUMINANCE || dstFormat == GL_LUMINANCE_ALPHA) {
+ /* compute luminance values */
+ if (ctx->Color.ClampReadColor == GL_TRUE) {
+ for (i = 0; i < n; i++) {
+ GLfloat sum = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP];
+ luminance[i] = CLAMP(sum, 0.0F, 1.0F);
+ }
+ }
+ else {
+ for (i = 0; i < n; i++) {
+ luminance[i] = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP];
+ }
+ }
+ }
+
+ /*
+ * Pack/store the pixels. Ugh! Lots of cases!!!
+ */
+ switch (dstType) {
+ case GL_UNSIGNED_BYTE:
+ {
+ GLubyte *dst = (GLubyte *) dstAddr;
+ switch (dstFormat) {
+ case GL_RED:
+ for (i=0;i<n;i++)
+ dst[i] = FLOAT_TO_UBYTE(rgba[i][RCOMP]);
+ break;
+ case GL_GREEN:
+ for (i=0;i<n;i++)
+ dst[i] = FLOAT_TO_UBYTE(rgba[i][GCOMP]);
+ break;
+ case GL_BLUE:
+ for (i=0;i<n;i++)
+ dst[i] = FLOAT_TO_UBYTE(rgba[i][BCOMP]);
+ break;
+ case GL_ALPHA:
+ for (i=0;i<n;i++)
+ dst[i] = FLOAT_TO_UBYTE(rgba[i][ACOMP]);
+ break;
+ case GL_LUMINANCE:
+ for (i=0;i<n;i++)
+ dst[i] = FLOAT_TO_UBYTE(luminance[i]);
+ break;
+ case GL_LUMINANCE_ALPHA:
+ for (i=0;i<n;i++) {
+ dst[i*2+0] = FLOAT_TO_UBYTE(luminance[i]);
+ dst[i*2+1] = FLOAT_TO_UBYTE(rgba[i][ACOMP]);
+ }
+ break;
+ case GL_RGB:
+ for (i=0;i<n;i++) {
+ dst[i*3+0] = FLOAT_TO_UBYTE(rgba[i][RCOMP]);
+ dst[i*3+1] = FLOAT_TO_UBYTE(rgba[i][GCOMP]);
+ dst[i*3+2] = FLOAT_TO_UBYTE(rgba[i][BCOMP]);
+ }
+ break;
+ case GL_RGBA:
+ for (i=0;i<n;i++) {
+ dst[i*4+0] = FLOAT_TO_UBYTE(rgba[i][RCOMP]);
+ dst[i*4+1] = FLOAT_TO_UBYTE(rgba[i][GCOMP]);
+ dst[i*4+2] = FLOAT_TO_UBYTE(rgba[i][BCOMP]);
+ dst[i*4+3] = FLOAT_TO_UBYTE(rgba[i][ACOMP]);
+ }
+ break;
+ case GL_BGR:
+ for (i=0;i<n;i++) {
+ dst[i*3+0] = FLOAT_TO_UBYTE(rgba[i][BCOMP]);
+ dst[i*3+1] = FLOAT_TO_UBYTE(rgba[i][GCOMP]);
+ dst[i*3+2] = FLOAT_TO_UBYTE(rgba[i][RCOMP]);
+ }
+ break;
+ case GL_BGRA:
+ for (i=0;i<n;i++) {
+ dst[i*4+0] = FLOAT_TO_UBYTE(rgba[i][BCOMP]);
+ dst[i*4+1] = FLOAT_TO_UBYTE(rgba[i][GCOMP]);
+ dst[i*4+2] = FLOAT_TO_UBYTE(rgba[i][RCOMP]);
+ dst[i*4+3] = FLOAT_TO_UBYTE(rgba[i][ACOMP]);
+ }
+ break;
+ case GL_ABGR_EXT:
+ for (i=0;i<n;i++) {
+ dst[i*4+0] = FLOAT_TO_UBYTE(rgba[i][ACOMP]);
+ dst[i*4+1] = FLOAT_TO_UBYTE(rgba[i][BCOMP]);
+ dst[i*4+2] = FLOAT_TO_UBYTE(rgba[i][GCOMP]);
+ dst[i*4+3] = FLOAT_TO_UBYTE(rgba[i][RCOMP]);
+ }
+ break;
+ default:
+ _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
+ }
+ }
+ break;
+ case GL_BYTE:
+ {
+ GLbyte *dst = (GLbyte *) dstAddr;
+ switch (dstFormat) {
+ case GL_RED:
+ for (i=0;i<n;i++)
+ dst[i] = FLOAT_TO_BYTE(rgba[i][RCOMP]);
+ break;
+ case GL_GREEN:
+ for (i=0;i<n;i++)
+ dst[i] = FLOAT_TO_BYTE(rgba[i][GCOMP]);
+ break;
+ case GL_BLUE:
+ for (i=0;i<n;i++)
+ dst[i] = FLOAT_TO_BYTE(rgba[i][BCOMP]);
+ break;
+ case GL_ALPHA:
+ for (i=0;i<n;i++)
+ dst[i] = FLOAT_TO_BYTE(rgba[i][ACOMP]);
+ break;
+ case GL_LUMINANCE:
+ for (i=0;i<n;i++)
+ dst[i] = FLOAT_TO_BYTE(luminance[i]);
+ break;
+ case GL_LUMINANCE_ALPHA:
+ for (i=0;i<n;i++) {
+ dst[i*2+0] = FLOAT_TO_BYTE(luminance[i]);
+ dst[i*2+1] = FLOAT_TO_BYTE(rgba[i][ACOMP]);
+ }
+ break;
+ case GL_RGB:
+ for (i=0;i<n;i++) {
+ dst[i*3+0] = FLOAT_TO_BYTE(rgba[i][RCOMP]);
+ dst[i*3+1] = FLOAT_TO_BYTE(rgba[i][GCOMP]);
+ dst[i*3+2] = FLOAT_TO_BYTE(rgba[i][BCOMP]);
+ }
+ break;
+ case GL_RGBA:
+ for (i=0;i<n;i++) {
+ dst[i*4+0] = FLOAT_TO_BYTE(rgba[i][RCOMP]);
+ dst[i*4+1] = FLOAT_TO_BYTE(rgba[i][GCOMP]);
+ dst[i*4+2] = FLOAT_TO_BYTE(rgba[i][BCOMP]);
+ dst[i*4+3] = FLOAT_TO_BYTE(rgba[i][ACOMP]);
+ }
+ break;
+ case GL_BGR:
+ for (i=0;i<n;i++) {
+ dst[i*3+0] = FLOAT_TO_BYTE(rgba[i][BCOMP]);
+ dst[i*3+1] = FLOAT_TO_BYTE(rgba[i][GCOMP]);
+ dst[i*3+2] = FLOAT_TO_BYTE(rgba[i][RCOMP]);
+ }
+ break;
+ case GL_BGRA:
+ for (i=0;i<n;i++) {
+ dst[i*4+0] = FLOAT_TO_BYTE(rgba[i][BCOMP]);
+ dst[i*4+1] = FLOAT_TO_BYTE(rgba[i][GCOMP]);
+ dst[i*4+2] = FLOAT_TO_BYTE(rgba[i][RCOMP]);
+ dst[i*4+3] = FLOAT_TO_BYTE(rgba[i][ACOMP]);
+ }
+ case GL_ABGR_EXT:
+ for (i=0;i<n;i++) {
+ dst[i*4+0] = FLOAT_TO_BYTE(rgba[i][ACOMP]);
+ dst[i*4+1] = FLOAT_TO_BYTE(rgba[i][BCOMP]);
+ dst[i*4+2] = FLOAT_TO_BYTE(rgba[i][GCOMP]);
+ dst[i*4+3] = FLOAT_TO_BYTE(rgba[i][RCOMP]);
+ }
+ break;
+ default:
+ _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
+ }
+ }
+ break;
+ case GL_UNSIGNED_SHORT:
+ {
+ GLushort *dst = (GLushort *) dstAddr;
+ switch (dstFormat) {
+ case GL_RED:
+ for (i=0;i<n;i++)
+ CLAMPED_FLOAT_TO_USHORT(dst[i], rgba[i][RCOMP]);
+ break;
+ case GL_GREEN:
+ for (i=0;i<n;i++)
+ CLAMPED_FLOAT_TO_USHORT(dst[i], rgba[i][GCOMP]);
+ break;
+ case GL_BLUE:
+ for (i=0;i<n;i++)
+ CLAMPED_FLOAT_TO_USHORT(dst[i], rgba[i][BCOMP]);
+ break;
+ case GL_ALPHA:
+ for (i=0;i<n;i++)
+ CLAMPED_FLOAT_TO_USHORT(dst[i], rgba[i][ACOMP]);
+ break;
+ case GL_LUMINANCE:
+ for (i=0;i<n;i++)
+ UNCLAMPED_FLOAT_TO_USHORT(dst[i], luminance[i]);
+ break;
+ case GL_LUMINANCE_ALPHA:
+ for (i=0;i<n;i++) {
+ UNCLAMPED_FLOAT_TO_USHORT(dst[i*2+0], luminance[i]);
+ CLAMPED_FLOAT_TO_USHORT(dst[i*2+1], rgba[i][ACOMP]);
+ }
+ break;
+ case GL_RGB:
+ for (i=0;i<n;i++) {
+ CLAMPED_FLOAT_TO_USHORT(dst[i*3+0], rgba[i][RCOMP]);
+ CLAMPED_FLOAT_TO_USHORT(dst[i*3+1], rgba[i][GCOMP]);
+ CLAMPED_FLOAT_TO_USHORT(dst[i*3+2], rgba[i][BCOMP]);
+ }
+ break;
+ case GL_RGBA:
+ for (i=0;i<n;i++) {
+ CLAMPED_FLOAT_TO_USHORT(dst[i*4+0], rgba[i][RCOMP]);
+ CLAMPED_FLOAT_TO_USHORT(dst[i*4+1], rgba[i][GCOMP]);
+ CLAMPED_FLOAT_TO_USHORT(dst[i*4+2], rgba[i][BCOMP]);
+ CLAMPED_FLOAT_TO_USHORT(dst[i*4+3], rgba[i][ACOMP]);
+ }
+ break;
+ case GL_BGR:
+ for (i=0;i<n;i++) {
+ CLAMPED_FLOAT_TO_USHORT(dst[i*3+0], rgba[i][BCOMP]);
+ CLAMPED_FLOAT_TO_USHORT(dst[i*3+1], rgba[i][GCOMP]);
+ CLAMPED_FLOAT_TO_USHORT(dst[i*3+2], rgba[i][RCOMP]);
+ }
+ break;
+ case GL_BGRA:
+ for (i=0;i<n;i++) {
+ CLAMPED_FLOAT_TO_USHORT(dst[i*4+0], rgba[i][BCOMP]);
+ CLAMPED_FLOAT_TO_USHORT(dst[i*4+1], rgba[i][GCOMP]);
+ CLAMPED_FLOAT_TO_USHORT(dst[i*4+2], rgba[i][RCOMP]);
+ CLAMPED_FLOAT_TO_USHORT(dst[i*4+3], rgba[i][ACOMP]);
+ }
+ break;
+ case GL_ABGR_EXT:
+ for (i=0;i<n;i++) {
+ CLAMPED_FLOAT_TO_USHORT(dst[i*4+0], rgba[i][ACOMP]);
+ CLAMPED_FLOAT_TO_USHORT(dst[i*4+1], rgba[i][BCOMP]);
+ CLAMPED_FLOAT_TO_USHORT(dst[i*4+2], rgba[i][GCOMP]);
+ CLAMPED_FLOAT_TO_USHORT(dst[i*4+3], rgba[i][RCOMP]);
+ }
+ break;
+ default:
+ _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
+ }
+ if (dstPacking->SwapBytes) {
+ _mesa_swap2( (GLushort *) dst, n * comps);
+ }
+ }
+ break;
+ case GL_SHORT:
+ {
+ GLshort *dst = (GLshort *) dstAddr;
+ switch (dstFormat) {
+ case GL_RED:
+ for (i=0;i<n;i++)
+ dst[i] = FLOAT_TO_SHORT(rgba[i][RCOMP]);
+ break;
+ case GL_GREEN:
+ for (i=0;i<n;i++)
+ dst[i] = FLOAT_TO_SHORT(rgba[i][GCOMP]);
+ break;
+ case GL_BLUE:
+ for (i=0;i<n;i++)
+ dst[i] = FLOAT_TO_SHORT(rgba[i][BCOMP]);
+ break;
+ case GL_ALPHA:
+ for (i=0;i<n;i++)
+ dst[i] = FLOAT_TO_SHORT(rgba[i][ACOMP]);
+ break;
+ case GL_LUMINANCE:
+ for (i=0;i<n;i++)
+ dst[i] = FLOAT_TO_SHORT(luminance[i]);
+ break;
+ case GL_LUMINANCE_ALPHA:
+ for (i=0;i<n;i++) {
+ dst[i*2+0] = FLOAT_TO_SHORT(luminance[i]);
+ dst[i*2+1] = FLOAT_TO_SHORT(rgba[i][ACOMP]);
+ }
+ break;
+ case GL_RGB:
+ for (i=0;i<n;i++) {
+ dst[i*3+0] = FLOAT_TO_SHORT(rgba[i][RCOMP]);
+ dst[i*3+1] = FLOAT_TO_SHORT(rgba[i][GCOMP]);
+ dst[i*3+2] = FLOAT_TO_SHORT(rgba[i][BCOMP]);
+ }
+ break;
+ case GL_RGBA:
+ for (i=0;i<n;i++) {
+ dst[i*4+0] = FLOAT_TO_SHORT(rgba[i][RCOMP]);
+ dst[i*4+1] = FLOAT_TO_SHORT(rgba[i][GCOMP]);
+ dst[i*4+2] = FLOAT_TO_SHORT(rgba[i][BCOMP]);
+ dst[i*4+3] = FLOAT_TO_SHORT(rgba[i][ACOMP]);
+ }
+ break;
+ case GL_BGR:
+ for (i=0;i<n;i++) {
+ dst[i*3+0] = FLOAT_TO_SHORT(rgba[i][BCOMP]);
+ dst[i*3+1] = FLOAT_TO_SHORT(rgba[i][GCOMP]);
+ dst[i*3+2] = FLOAT_TO_SHORT(rgba[i][RCOMP]);
+ }
+ break;
+ case GL_BGRA:
+ for (i=0;i<n;i++) {
+ dst[i*4+0] = FLOAT_TO_SHORT(rgba[i][BCOMP]);
+ dst[i*4+1] = FLOAT_TO_SHORT(rgba[i][GCOMP]);
+ dst[i*4+2] = FLOAT_TO_SHORT(rgba[i][RCOMP]);
+ dst[i*4+3] = FLOAT_TO_SHORT(rgba[i][ACOMP]);
+ }
+ case GL_ABGR_EXT:
+ for (i=0;i<n;i++) {
+ dst[i*4+0] = FLOAT_TO_SHORT(rgba[i][ACOMP]);
+ dst[i*4+1] = FLOAT_TO_SHORT(rgba[i][BCOMP]);
+ dst[i*4+2] = FLOAT_TO_SHORT(rgba[i][GCOMP]);
+ dst[i*4+3] = FLOAT_TO_SHORT(rgba[i][RCOMP]);
+ }
+ break;
+ default:
+ _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
+ }
+ if (dstPacking->SwapBytes) {
+ _mesa_swap2( (GLushort *) dst, n * comps );
+ }
+ }
+ break;
+ case GL_UNSIGNED_INT:
+ {
+ GLuint *dst = (GLuint *) dstAddr;
+ switch (dstFormat) {
+ case GL_RED:
+ for (i=0;i<n;i++)
+ dst[i] = FLOAT_TO_UINT(rgba[i][RCOMP]);
+ break;
+ case GL_GREEN:
+ for (i=0;i<n;i++)
+ dst[i] = FLOAT_TO_UINT(rgba[i][GCOMP]);
+ break;
+ case GL_BLUE:
+ for (i=0;i<n;i++)
+ dst[i] = FLOAT_TO_UINT(rgba[i][BCOMP]);
+ break;
+ case GL_ALPHA:
+ for (i=0;i<n;i++)
+ dst[i] = FLOAT_TO_UINT(rgba[i][ACOMP]);
+ break;
+ case GL_LUMINANCE:
+ for (i=0;i<n;i++)
+ dst[i] = FLOAT_TO_UINT(luminance[i]);
+ break;
+ case GL_LUMINANCE_ALPHA:
+ for (i=0;i<n;i++) {
+ dst[i*2+0] = FLOAT_TO_UINT(luminance[i]);
+ dst[i*2+1] = FLOAT_TO_UINT(rgba[i][ACOMP]);
+ }
+ break;
+ case GL_RGB:
+ for (i=0;i<n;i++) {
+ dst[i*3+0] = FLOAT_TO_UINT(rgba[i][RCOMP]);
+ dst[i*3+1] = FLOAT_TO_UINT(rgba[i][GCOMP]);
+ dst[i*3+2] = FLOAT_TO_UINT(rgba[i][BCOMP]);
+ }
+ break;
+ case GL_RGBA:
+ for (i=0;i<n;i++) {
+ dst[i*4+0] = FLOAT_TO_UINT(rgba[i][RCOMP]);
+ dst[i*4+1] = FLOAT_TO_UINT(rgba[i][GCOMP]);
+ dst[i*4+2] = FLOAT_TO_UINT(rgba[i][BCOMP]);
+ dst[i*4+3] = FLOAT_TO_UINT(rgba[i][ACOMP]);
+ }
+ break;
+ case GL_BGR:
+ for (i=0;i<n;i++) {
+ dst[i*3+0] = FLOAT_TO_UINT(rgba[i][BCOMP]);
+ dst[i*3+1] = FLOAT_TO_UINT(rgba[i][GCOMP]);
+ dst[i*3+2] = FLOAT_TO_UINT(rgba[i][RCOMP]);
+ }
+ break;
+ case GL_BGRA:
+ for (i=0;i<n;i++) {
+ dst[i*4+0] = FLOAT_TO_UINT(rgba[i][BCOMP]);
+ dst[i*4+1] = FLOAT_TO_UINT(rgba[i][GCOMP]);
+ dst[i*4+2] = FLOAT_TO_UINT(rgba[i][RCOMP]);
+ dst[i*4+3] = FLOAT_TO_UINT(rgba[i][ACOMP]);
+ }
+ break;
+ case GL_ABGR_EXT:
+ for (i=0;i<n;i++) {
+ dst[i*4+0] = FLOAT_TO_UINT(rgba[i][ACOMP]);
+ dst[i*4+1] = FLOAT_TO_UINT(rgba[i][BCOMP]);
+ dst[i*4+2] = FLOAT_TO_UINT(rgba[i][GCOMP]);
+ dst[i*4+3] = FLOAT_TO_UINT(rgba[i][RCOMP]);
+ }
+ break;
+ default:
+ _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
+ }
+ if (dstPacking->SwapBytes) {
+ _mesa_swap4( (GLuint *) dst, n * comps );
+ }
+ }
+ break;
+ case GL_INT:
+ {
+ GLint *dst = (GLint *) dstAddr;
+ switch (dstFormat) {
+ case GL_RED:
+ for (i=0;i<n;i++)
+ dst[i] = FLOAT_TO_INT(rgba[i][RCOMP]);
+ break;
+ case GL_GREEN:
+ for (i=0;i<n;i++)
+ dst[i] = FLOAT_TO_INT(rgba[i][GCOMP]);
+ break;
+ case GL_BLUE:
+ for (i=0;i<n;i++)
+ dst[i] = FLOAT_TO_INT(rgba[i][BCOMP]);
+ break;
+ case GL_ALPHA:
+ for (i=0;i<n;i++)
+ dst[i] = FLOAT_TO_INT(rgba[i][ACOMP]);
+ break;
+ case GL_LUMINANCE:
+ for (i=0;i<n;i++)
+ dst[i] = FLOAT_TO_INT(luminance[i]);
+ break;
+ case GL_LUMINANCE_ALPHA:
+ for (i=0;i<n;i++) {
+ dst[i*2+0] = FLOAT_TO_INT(luminance[i]);
+ dst[i*2+1] = FLOAT_TO_INT(rgba[i][ACOMP]);
+ }
+ break;
+ case GL_RGB:
+ for (i=0;i<n;i++) {
+ dst[i*3+0] = FLOAT_TO_INT(rgba[i][RCOMP]);
+ dst[i*3+1] = FLOAT_TO_INT(rgba[i][GCOMP]);
+ dst[i*3+2] = FLOAT_TO_INT(rgba[i][BCOMP]);
+ }
+ break;
+ case GL_RGBA:
+ for (i=0;i<n;i++) {
+ dst[i*4+0] = FLOAT_TO_INT(rgba[i][RCOMP]);
+ dst[i*4+1] = FLOAT_TO_INT(rgba[i][GCOMP]);
+ dst[i*4+2] = FLOAT_TO_INT(rgba[i][BCOMP]);
+ dst[i*4+3] = FLOAT_TO_INT(rgba[i][ACOMP]);
+ }
+ break;
+ case GL_BGR:
+ for (i=0;i<n;i++) {
+ dst[i*3+0] = FLOAT_TO_INT(rgba[i][BCOMP]);
+ dst[i*3+1] = FLOAT_TO_INT(rgba[i][GCOMP]);
+ dst[i*3+2] = FLOAT_TO_INT(rgba[i][RCOMP]);
+ }
+ break;
+ case GL_BGRA:
+ for (i=0;i<n;i++) {
+ dst[i*4+0] = FLOAT_TO_INT(rgba[i][BCOMP]);
+ dst[i*4+1] = FLOAT_TO_INT(rgba[i][GCOMP]);
+ dst[i*4+2] = FLOAT_TO_INT(rgba[i][RCOMP]);
+ dst[i*4+3] = FLOAT_TO_INT(rgba[i][ACOMP]);
+ }
+ break;
+ case GL_ABGR_EXT:
+ for (i=0;i<n;i++) {
+ dst[i*4+0] = FLOAT_TO_INT(rgba[i][ACOMP]);
+ dst[i*4+1] = FLOAT_TO_INT(rgba[i][BCOMP]);
+ dst[i*4+2] = FLOAT_TO_INT(rgba[i][GCOMP]);
+ dst[i*4+3] = FLOAT_TO_INT(rgba[i][RCOMP]);
+ }
+ break;
+ default:
+ _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
+ }
+ if (dstPacking->SwapBytes) {
+ _mesa_swap4( (GLuint *) dst, n * comps );
+ }
+ }
+ break;
+ case GL_FLOAT:
+ {
+ GLfloat *dst = (GLfloat *) dstAddr;
+ switch (dstFormat) {
+ case GL_RED:
+ for (i=0;i<n;i++)
+ dst[i] = rgba[i][RCOMP];
+ break;
+ case GL_GREEN:
+ for (i=0;i<n;i++)
+ dst[i] = rgba[i][GCOMP];
+ break;
+ case GL_BLUE:
+ for (i=0;i<n;i++)
+ dst[i] = rgba[i][BCOMP];
+ break;
+ case GL_ALPHA:
+ for (i=0;i<n;i++)
+ dst[i] = rgba[i][ACOMP];
+ break;
+ case GL_LUMINANCE:
+ for (i=0;i<n;i++)
+ dst[i] = luminance[i];
+ break;
+ case GL_LUMINANCE_ALPHA:
+ for (i=0;i<n;i++) {
+ dst[i*2+0] = luminance[i];
+ dst[i*2+1] = rgba[i][ACOMP];
+ }
+ break;
+ case GL_RGB:
+ for (i=0;i<n;i++) {
+ dst[i*3+0] = rgba[i][RCOMP];
+ dst[i*3+1] = rgba[i][GCOMP];
+ dst[i*3+2] = rgba[i][BCOMP];
+ }
+ break;
+ case GL_RGBA:
+ for (i=0;i<n;i++) {
+ dst[i*4+0] = rgba[i][RCOMP];
+ dst[i*4+1] = rgba[i][GCOMP];
+ dst[i*4+2] = rgba[i][BCOMP];
+ dst[i*4+3] = rgba[i][ACOMP];
+ }
+ break;
+ case GL_BGR:
+ for (i=0;i<n;i++) {
+ dst[i*3+0] = rgba[i][BCOMP];
+ dst[i*3+1] = rgba[i][GCOMP];
+ dst[i*3+2] = rgba[i][RCOMP];
+ }
+ break;
+ case GL_BGRA:
+ for (i=0;i<n;i++) {
+ dst[i*4+0] = rgba[i][BCOMP];
+ dst[i*4+1] = rgba[i][GCOMP];
+ dst[i*4+2] = rgba[i][RCOMP];
+ dst[i*4+3] = rgba[i][ACOMP];
+ }
+ break;
+ case GL_ABGR_EXT:
+ for (i=0;i<n;i++) {
+ dst[i*4+0] = rgba[i][ACOMP];
+ dst[i*4+1] = rgba[i][BCOMP];
+ dst[i*4+2] = rgba[i][GCOMP];
+ dst[i*4+3] = rgba[i][RCOMP];
+ }
+ break;
+ default:
+ _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
+ }
+ if (dstPacking->SwapBytes) {
+ _mesa_swap4( (GLuint *) dst, n * comps );
+ }
+ }
+ break;
+ case GL_HALF_FLOAT_ARB:
+ {
+ GLhalfARB *dst = (GLhalfARB *) dstAddr;
+ switch (dstFormat) {
+ case GL_RED:
+ for (i=0;i<n;i++)
+ dst[i] = _mesa_float_to_half(rgba[i][RCOMP]);
+ break;
+ case GL_GREEN:
+ for (i=0;i<n;i++)
+ dst[i] = _mesa_float_to_half(rgba[i][GCOMP]);
+ break;
+ case GL_BLUE:
+ for (i=0;i<n;i++)
+ dst[i] = _mesa_float_to_half(rgba[i][BCOMP]);
+ break;
+ case GL_ALPHA:
+ for (i=0;i<n;i++)
+ dst[i] = _mesa_float_to_half(rgba[i][ACOMP]);
+ break;
+ case GL_LUMINANCE:
+ for (i=0;i<n;i++)
+ dst[i] = _mesa_float_to_half(luminance[i]);
+ break;
+ case GL_LUMINANCE_ALPHA:
+ for (i=0;i<n;i++) {
+ dst[i*2+0] = _mesa_float_to_half(luminance[i]);
+ dst[i*2+1] = _mesa_float_to_half(rgba[i][ACOMP]);
+ }
+ break;
+ case GL_RGB:
+ for (i=0;i<n;i++) {
+ dst[i*3+0] = _mesa_float_to_half(rgba[i][RCOMP]);
+ dst[i*3+1] = _mesa_float_to_half(rgba[i][GCOMP]);
+ dst[i*3+2] = _mesa_float_to_half(rgba[i][BCOMP]);
+ }
+ break;
+ case GL_RGBA:
+ for (i=0;i<n;i++) {
+ dst[i*4+0] = _mesa_float_to_half(rgba[i][RCOMP]);
+ dst[i*4+1] = _mesa_float_to_half(rgba[i][GCOMP]);
+ dst[i*4+2] = _mesa_float_to_half(rgba[i][BCOMP]);
+ dst[i*4+3] = _mesa_float_to_half(rgba[i][ACOMP]);
+ }
+ break;
+ case GL_BGR:
+ for (i=0;i<n;i++) {
+ dst[i*3+0] = _mesa_float_to_half(rgba[i][BCOMP]);
+ dst[i*3+1] = _mesa_float_to_half(rgba[i][GCOMP]);
+ dst[i*3+2] = _mesa_float_to_half(rgba[i][RCOMP]);
+ }
+ break;
+ case GL_BGRA:
+ for (i=0;i<n;i++) {
+ dst[i*4+0] = _mesa_float_to_half(rgba[i][BCOMP]);
+ dst[i*4+1] = _mesa_float_to_half(rgba[i][GCOMP]);
+ dst[i*4+2] = _mesa_float_to_half(rgba[i][RCOMP]);
+ dst[i*4+3] = _mesa_float_to_half(rgba[i][ACOMP]);
+ }
+ break;
+ case GL_ABGR_EXT:
+ for (i=0;i<n;i++) {
+ dst[i*4+0] = _mesa_float_to_half(rgba[i][ACOMP]);
+ dst[i*4+1] = _mesa_float_to_half(rgba[i][BCOMP]);
+ dst[i*4+2] = _mesa_float_to_half(rgba[i][GCOMP]);
+ dst[i*4+3] = _mesa_float_to_half(rgba[i][RCOMP]);
+ }
+ break;
+ default:
+ _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
+ }
+ if (dstPacking->SwapBytes) {
+ _mesa_swap2( (GLushort *) dst, n * comps );
+ }
+ }
+ break;
+ case GL_UNSIGNED_BYTE_3_3_2:
+ if (dstFormat == GL_RGB) {
+ GLubyte *dst = (GLubyte *) dstAddr;
+ for (i=0;i<n;i++) {
+ dst[i] = (((GLint) (rgba[i][RCOMP] * 7.0F)) << 5)
+ | (((GLint) (rgba[i][GCOMP] * 7.0F)) << 2)
+ | (((GLint) (rgba[i][BCOMP] * 3.0F)) );
+ }
+ }
+ break;
+ case GL_UNSIGNED_BYTE_2_3_3_REV:
+ if (dstFormat == GL_RGB) {
+ GLubyte *dst = (GLubyte *) dstAddr;
+ for (i=0;i<n;i++) {
+ dst[i] = (((GLint) (rgba[i][RCOMP] * 7.0F)) )
+ | (((GLint) (rgba[i][GCOMP] * 7.0F)) << 3)
+ | (((GLint) (rgba[i][BCOMP] * 3.0F)) << 5);
+ }
+ }
+ break;
+ case GL_UNSIGNED_SHORT_5_6_5:
+ if (dstFormat == GL_RGB) {
+ GLushort *dst = (GLushort *) dstAddr;
+ for (i=0;i<n;i++) {
+ dst[i] = (((GLint) (rgba[i][RCOMP] * 31.0F)) << 11)
+ | (((GLint) (rgba[i][GCOMP] * 63.0F)) << 5)
+ | (((GLint) (rgba[i][BCOMP] * 31.0F)) );
+ }
+ }
+ break;
+ case GL_UNSIGNED_SHORT_5_6_5_REV:
+ if (dstFormat == GL_RGB) {
+ GLushort *dst = (GLushort *) dstAddr;
+ for (i=0;i<n;i++) {
+ dst[i] = (((GLint) (rgba[i][RCOMP] * 31.0F)) )
+ | (((GLint) (rgba[i][GCOMP] * 63.0F)) << 5)
+ | (((GLint) (rgba[i][BCOMP] * 31.0F)) << 11);
+ }
+ }
+ break;
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ if (dstFormat == GL_RGBA) {
+ GLushort *dst = (GLushort *) dstAddr;
+ for (i=0;i<n;i++) {
+ dst[i] = (((GLint) (rgba[i][RCOMP] * 15.0F)) << 12)
+ | (((GLint) (rgba[i][GCOMP] * 15.0F)) << 8)
+ | (((GLint) (rgba[i][BCOMP] * 15.0F)) << 4)
+ | (((GLint) (rgba[i][ACOMP] * 15.0F)) );
+ }
+ }
+ else if (dstFormat == GL_BGRA) {
+ GLushort *dst = (GLushort *) dstAddr;
+ for (i=0;i<n;i++) {
+ dst[i] = (((GLint) (rgba[i][BCOMP] * 15.0F)) << 12)
+ | (((GLint) (rgba[i][GCOMP] * 15.0F)) << 8)
+ | (((GLint) (rgba[i][RCOMP] * 15.0F)) << 4)
+ | (((GLint) (rgba[i][ACOMP] * 15.0F)) );
+ }
+ }
+ else if (dstFormat == GL_ABGR_EXT) {
+ GLushort *dst = (GLushort *) dstAddr;
+ for (i=0;i<n;i++) {
+ dst[i] = (((GLint) (rgba[i][ACOMP] * 15.0F)) << 4)
+ | (((GLint) (rgba[i][BCOMP] * 15.0F)) << 8)
+ | (((GLint) (rgba[i][GCOMP] * 15.0F)) << 12)
+ | (((GLint) (rgba[i][RCOMP] * 15.0F)) );
+ }
+ }
+ break;
+ case GL_UNSIGNED_SHORT_4_4_4_4_REV:
+ if (dstFormat == GL_RGBA) {
+ GLushort *dst = (GLushort *) dstAddr;
+ for (i=0;i<n;i++) {
+ dst[i] = (((GLint) (rgba[i][RCOMP] * 15.0F)) )
+ | (((GLint) (rgba[i][GCOMP] * 15.0F)) << 4)
+ | (((GLint) (rgba[i][BCOMP] * 15.0F)) << 8)
+ | (((GLint) (rgba[i][ACOMP] * 15.0F)) << 12);
+ }
+ }
+ else if (dstFormat == GL_BGRA) {
+ GLushort *dst = (GLushort *) dstAddr;
+ for (i=0;i<n;i++) {
+ dst[i] = (((GLint) (rgba[i][BCOMP] * 15.0F)) )
+ | (((GLint) (rgba[i][GCOMP] * 15.0F)) << 4)
+ | (((GLint) (rgba[i][RCOMP] * 15.0F)) << 8)
+ | (((GLint) (rgba[i][ACOMP] * 15.0F)) << 12);
+ }
+ }
+ else if (dstFormat == GL_ABGR_EXT) {
+ GLushort *dst = (GLushort *) dstAddr;
+ for (i=0;i<n;i++) {
+ dst[i] = (((GLint) (rgba[i][ACOMP] * 15.0F)) )
+ | (((GLint) (rgba[i][BCOMP] * 15.0F)) << 4)
+ | (((GLint) (rgba[i][GCOMP] * 15.0F)) << 8)
+ | (((GLint) (rgba[i][RCOMP] * 15.0F)) << 12);
+ }
+ }
+ break;
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ if (dstFormat == GL_RGBA) {
+ GLushort *dst = (GLushort *) dstAddr;
+ for (i=0;i<n;i++) {
+ dst[i] = (((GLint) (rgba[i][RCOMP] * 31.0F)) << 11)
+ | (((GLint) (rgba[i][GCOMP] * 31.0F)) << 6)
+ | (((GLint) (rgba[i][BCOMP] * 31.0F)) << 1)
+ | (((GLint) (rgba[i][ACOMP] * 1.0F)) );
+ }
+ }
+ else if (dstFormat == GL_BGRA) {
+ GLushort *dst = (GLushort *) dstAddr;
+ for (i=0;i<n;i++) {
+ dst[i] = (((GLint) (rgba[i][BCOMP] * 31.0F)) << 11)
+ | (((GLint) (rgba[i][GCOMP] * 31.0F)) << 6)
+ | (((GLint) (rgba[i][RCOMP] * 31.0F)) << 1)
+ | (((GLint) (rgba[i][ACOMP] * 1.0F)) );
+ }
+ }
+ else if (dstFormat == GL_ABGR_EXT) {
+ GLushort *dst = (GLushort *) dstAddr;
+ for (i=0;i<n;i++) {
+ dst[i] = (((GLint) (rgba[i][ACOMP] * 31.0F)) << 11)
+ | (((GLint) (rgba[i][BCOMP] * 31.0F)) << 6)
+ | (((GLint) (rgba[i][GCOMP] * 31.0F)) << 1)
+ | (((GLint) (rgba[i][RCOMP] * 1.0F)) );
+ }
+ }
+ break;
+ case GL_UNSIGNED_SHORT_1_5_5_5_REV:
+ if (dstFormat == GL_RGBA) {
+ GLushort *dst = (GLushort *) dstAddr;
+ for (i=0;i<n;i++) {
+ dst[i] = (((GLint) (rgba[i][RCOMP] * 31.0F)) )
+ | (((GLint) (rgba[i][GCOMP] * 31.0F)) << 5)
+ | (((GLint) (rgba[i][BCOMP] * 31.0F)) << 10)
+ | (((GLint) (rgba[i][ACOMP] * 1.0F)) << 15);
+ }
+ }
+ else if (dstFormat == GL_BGRA) {
+ GLushort *dst = (GLushort *) dstAddr;
+ for (i=0;i<n;i++) {
+ dst[i] = (((GLint) (rgba[i][BCOMP] * 31.0F)) )
+ | (((GLint) (rgba[i][GCOMP] * 31.0F)) << 5)
+ | (((GLint) (rgba[i][RCOMP] * 31.0F)) << 10)
+ | (((GLint) (rgba[i][ACOMP] * 1.0F)) << 15);
+ }
+ }
+ else if (dstFormat == GL_ABGR_EXT) {
+ GLushort *dst = (GLushort *) dstAddr;
+ for (i=0;i<n;i++) {
+ dst[i] = (((GLint) (rgba[i][ACOMP] * 31.0F)) )
+ | (((GLint) (rgba[i][BCOMP] * 31.0F)) << 5)
+ | (((GLint) (rgba[i][GCOMP] * 31.0F)) << 10)
+ | (((GLint) (rgba[i][RCOMP] * 1.0F)) << 15);
+ }
+ }
+ break;
+ case GL_UNSIGNED_INT_8_8_8_8:
+ if (dstFormat == GL_RGBA) {
+ GLuint *dst = (GLuint *) dstAddr;
+ for (i=0;i<n;i++) {
+ dst[i] = (((GLuint) (rgba[i][RCOMP] * 255.0F)) << 24)
+ | (((GLuint) (rgba[i][GCOMP] * 255.0F)) << 16)
+ | (((GLuint) (rgba[i][BCOMP] * 255.0F)) << 8)
+ | (((GLuint) (rgba[i][ACOMP] * 255.0F)) );
+ }
+ }
+ else if (dstFormat == GL_BGRA) {
+ GLuint *dst = (GLuint *) dstAddr;
+ for (i=0;i<n;i++) {
+ dst[i] = (((GLuint) (rgba[i][BCOMP] * 255.0F)) << 24)
+ | (((GLuint) (rgba[i][GCOMP] * 255.0F)) << 16)
+ | (((GLuint) (rgba[i][RCOMP] * 255.0F)) << 8)
+ | (((GLuint) (rgba[i][ACOMP] * 255.0F)) );
+ }
+ }
+ else if (dstFormat == GL_ABGR_EXT) {
+ GLuint *dst = (GLuint *) dstAddr;
+ for (i=0;i<n;i++) {
+ dst[i] = (((GLuint) (rgba[i][ACOMP] * 255.0F)) << 24)
+ | (((GLuint) (rgba[i][BCOMP] * 255.0F)) << 16)
+ | (((GLuint) (rgba[i][GCOMP] * 255.0F)) << 8)
+ | (((GLuint) (rgba[i][RCOMP] * 255.0F)) );
+ }
+ }
+ break;
+ case GL_UNSIGNED_INT_8_8_8_8_REV:
+ if (dstFormat == GL_RGBA) {
+ GLuint *dst = (GLuint *) dstAddr;
+ for (i=0;i<n;i++) {
+ dst[i] = (((GLuint) (rgba[i][RCOMP] * 255.0F)) )
+ | (((GLuint) (rgba[i][GCOMP] * 255.0F)) << 8)
+ | (((GLuint) (rgba[i][BCOMP] * 255.0F)) << 16)
+ | (((GLuint) (rgba[i][ACOMP] * 255.0F)) << 24);
+ }
+ }
+ else if (dstFormat == GL_BGRA) {
+ GLuint *dst = (GLuint *) dstAddr;
+ for (i=0;i<n;i++) {
+ dst[i] = (((GLuint) (rgba[i][BCOMP] * 255.0F)) )
+ | (((GLuint) (rgba[i][GCOMP] * 255.0F)) << 8)
+ | (((GLuint) (rgba[i][RCOMP] * 255.0F)) << 16)
+ | (((GLuint) (rgba[i][ACOMP] * 255.0F)) << 24);
+ }
+ }
+ else if (dstFormat == GL_ABGR_EXT) {
+ GLuint *dst = (GLuint *) dstAddr;
+ for (i=0;i<n;i++) {
+ dst[i] = (((GLuint) (rgba[i][ACOMP] * 255.0F)) )
+ | (((GLuint) (rgba[i][BCOMP] * 255.0F)) << 8)
+ | (((GLuint) (rgba[i][GCOMP] * 255.0F)) << 16)
+ | (((GLuint) (rgba[i][RCOMP] * 255.0F)) << 24);
+ }
+ }
+ break;
+ case GL_UNSIGNED_INT_10_10_10_2:
+ if (dstFormat == GL_RGBA) {
+ GLuint *dst = (GLuint *) dstAddr;
+ for (i=0;i<n;i++) {
+ dst[i] = (((GLuint) (rgba[i][RCOMP] * 1023.0F)) << 22)
+ | (((GLuint) (rgba[i][GCOMP] * 1023.0F)) << 12)
+ | (((GLuint) (rgba[i][BCOMP] * 1023.0F)) << 2)
+ | (((GLuint) (rgba[i][ACOMP] * 3.0F)) );
+ }
+ }
+ else if (dstFormat == GL_BGRA) {
+ GLuint *dst = (GLuint *) dstAddr;
+ for (i=0;i<n;i++) {
+ dst[i] = (((GLuint) (rgba[i][BCOMP] * 1023.0F)) << 22)
+ | (((GLuint) (rgba[i][GCOMP] * 1023.0F)) << 12)
+ | (((GLuint) (rgba[i][RCOMP] * 1023.0F)) << 2)
+ | (((GLuint) (rgba[i][ACOMP] * 3.0F)) );
+ }
+ }
+ else if (dstFormat == GL_ABGR_EXT) {
+ GLuint *dst = (GLuint *) dstAddr;
+ for (i=0;i<n;i++) {
+ dst[i] = (((GLuint) (rgba[i][ACOMP] * 1023.0F)) << 22)
+ | (((GLuint) (rgba[i][BCOMP] * 1023.0F)) << 12)
+ | (((GLuint) (rgba[i][GCOMP] * 1023.0F)) << 2)
+ | (((GLuint) (rgba[i][RCOMP] * 3.0F)) );
+ }
+ }
+ break;
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ if (dstFormat == GL_RGBA) {
+ GLuint *dst = (GLuint *) dstAddr;
+ for (i=0;i<n;i++) {
+ dst[i] = (((GLuint) (rgba[i][RCOMP] * 1023.0F)) )
+ | (((GLuint) (rgba[i][GCOMP] * 1023.0F)) << 10)
+ | (((GLuint) (rgba[i][BCOMP] * 1023.0F)) << 20)
+ | (((GLuint) (rgba[i][ACOMP] * 3.0F)) << 30);
+ }
+ }
+ else if (dstFormat == GL_BGRA) {
+ GLuint *dst = (GLuint *) dstAddr;
+ for (i=0;i<n;i++) {
+ dst[i] = (((GLuint) (rgba[i][BCOMP] * 1023.0F)) )
+ | (((GLuint) (rgba[i][GCOMP] * 1023.0F)) << 10)
+ | (((GLuint) (rgba[i][RCOMP] * 1023.0F)) << 20)
+ | (((GLuint) (rgba[i][ACOMP] * 3.0F)) << 30);
+ }
+ }
+ else if (dstFormat == GL_ABGR_EXT) {
+ GLuint *dst = (GLuint *) dstAddr;
+ for (i=0;i<n;i++) {
+ dst[i] = (((GLuint) (rgba[i][ACOMP] * 1023.0F)) )
+ | (((GLuint) (rgba[i][BCOMP] * 1023.0F)) << 10)
+ | (((GLuint) (rgba[i][GCOMP] * 1023.0F)) << 20)
+ | (((GLuint) (rgba[i][RCOMP] * 3.0F)) << 30);
+ }
+ }
+ break;
+ default:
+ _mesa_problem(ctx, "bad type in _mesa_pack_rgba_span_float");
+ }
+}
+
+
+/*
+ * Pack the given RGBA span into client memory at 'dest' address
+ * in the given pixel format and type.
+ * Optionally apply the enabled pixel transfer ops.
+ * Pack into memory using the given packing params struct.
+ * This is used by glReadPixels and glGetTexImage?D()
+ * \param ctx - the context
+ * n - number of pixels in the span
+ * rgba - the pixels
+ * format - dest packing format
+ * type - dest packing data type
+ * destination - destination packing address
+ * packing - pixel packing parameters
+ * transferOps - bitmask of IMAGE_*_BIT operations to apply
+ */
+void
+_mesa_pack_rgba_span_chan( GLcontext *ctx,
+ GLuint n, CONST GLchan srcRgba[][4],
+ GLenum dstFormat, GLenum dstType,
+ GLvoid *dstAddr,
+ const struct gl_pixelstore_attrib *dstPacking,
+ GLuint transferOps)
+{
+ ASSERT((ctx->NewState & _NEW_PIXEL) == 0 || transferOps == 0);
+
+ /* Test for optimized case first */
+ if (transferOps == 0 && dstFormat == GL_RGBA && dstType == CHAN_TYPE) {
+ /* common simple case */
+ MEMCPY(dstAddr, srcRgba, n * 4 * sizeof(GLchan));
+ }
+ else if (transferOps == 0 && dstFormat == GL_RGB && dstType == CHAN_TYPE) {
+ /* common simple case */
+ GLuint i;
+ GLchan *dest = (GLchan *) dstAddr;
+ for (i = 0; i < n; i++) {
+ dest[0] = srcRgba[i][RCOMP];
+ dest[1] = srcRgba[i][GCOMP];
+ dest[2] = srcRgba[i][BCOMP];
+ dest += 3;
+ }
+ }
+ else if (transferOps == 0 && dstFormat == GL_RGBA && dstType == GL_UNSIGNED_BYTE) {
+ /* common simple case */
+ GLuint i;
+ GLubyte *dest = (GLubyte *) dstAddr;
+ for (i = 0; i < n; i++) {
+ dest[0] = CHAN_TO_UBYTE(srcRgba[i][RCOMP]);
+ dest[1] = CHAN_TO_UBYTE(srcRgba[i][GCOMP]);
+ dest[2] = CHAN_TO_UBYTE(srcRgba[i][BCOMP]);
+ dest[3] = CHAN_TO_UBYTE(srcRgba[i][ACOMP]);
+ dest += 4;
+ }
+ }
+ else {
+ /* general solution */
+ GLuint i;
+ GLfloat rgba[MAX_WIDTH][4];
+ assert(n <= MAX_WIDTH);
+ /* convert color components to floating point */
+ for (i = 0; i < n; i++) {
+ rgba[i][RCOMP] = CHAN_TO_FLOAT(srcRgba[i][RCOMP]);
+ rgba[i][GCOMP] = CHAN_TO_FLOAT(srcRgba[i][GCOMP]);
+ rgba[i][BCOMP] = CHAN_TO_FLOAT(srcRgba[i][BCOMP]);
+ rgba[i][ACOMP] = CHAN_TO_FLOAT(srcRgba[i][ACOMP]);
+ }
+ _mesa_pack_rgba_span_float(ctx, n, (const GLfloat (*)[4]) rgba,
+ dstFormat, dstType, dstAddr,
+ dstPacking, transferOps);
+ }
+}
+
+
+#define SWAP2BYTE(VALUE) \
+ { \
+ GLubyte *bytes = (GLubyte *) &(VALUE); \
+ GLubyte tmp = bytes[0]; \
+ bytes[0] = bytes[1]; \
+ bytes[1] = tmp; \
+ }
+
+#define SWAP4BYTE(VALUE) \
+ { \
+ GLubyte *bytes = (GLubyte *) &(VALUE); \
+ GLubyte tmp = bytes[0]; \
+ bytes[0] = bytes[3]; \
+ bytes[3] = tmp; \
+ tmp = bytes[1]; \
+ bytes[1] = bytes[2]; \
+ bytes[2] = tmp; \
+ }
+
+
+static void
+extract_uint_indexes(GLuint n, GLuint indexes[],
+ GLenum srcFormat, GLenum srcType, const GLvoid *src,
+ const struct gl_pixelstore_attrib *unpack )
+{
+ assert(srcFormat == GL_COLOR_INDEX);
+
+ ASSERT(srcType == GL_BITMAP ||
+ srcType == GL_UNSIGNED_BYTE ||
+ srcType == GL_BYTE ||
+ srcType == GL_UNSIGNED_SHORT ||
+ srcType == GL_SHORT ||
+ srcType == GL_UNSIGNED_INT ||
+ srcType == GL_INT ||
+ srcType == GL_UNSIGNED_INT_24_8_EXT ||
+ srcType == GL_HALF_FLOAT_ARB ||
+ srcType == GL_FLOAT);
+
+ switch (srcType) {
+ case GL_BITMAP:
+ {
+ GLubyte *ubsrc = (GLubyte *) src;
+ if (unpack->LsbFirst) {
+ GLubyte mask = 1 << (unpack->SkipPixels & 0x7);
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ indexes[i] = (*ubsrc & mask) ? 1 : 0;
+ if (mask == 128) {
+ mask = 1;
+ ubsrc++;
+ }
+ else {
+ mask = mask << 1;
+ }
+ }
+ }
+ else {
+ GLubyte mask = 128 >> (unpack->SkipPixels & 0x7);
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ indexes[i] = (*ubsrc & mask) ? 1 : 0;
+ if (mask == 1) {
+ mask = 128;
+ ubsrc++;
+ }
+ else {
+ mask = mask >> 1;
+ }
+ }
+ }
+ }
+ break;
+ case GL_UNSIGNED_BYTE:
+ {
+ GLuint i;
+ const GLubyte *s = (const GLubyte *) src;
+ for (i = 0; i < n; i++)
+ indexes[i] = s[i];
+ }
+ break;
+ case GL_BYTE:
+ {
+ GLuint i;
+ const GLbyte *s = (const GLbyte *) src;
+ for (i = 0; i < n; i++)
+ indexes[i] = s[i];
+ }
+ break;
+ case GL_UNSIGNED_SHORT:
+ {
+ GLuint i;
+ const GLushort *s = (const GLushort *) src;
+ if (unpack->SwapBytes) {
+ for (i = 0; i < n; i++) {
+ GLushort value = s[i];
+ SWAP2BYTE(value);
+ indexes[i] = value;
+ }
+ }
+ else {
+ for (i = 0; i < n; i++)
+ indexes[i] = s[i];
+ }
+ }
+ break;
+ case GL_SHORT:
+ {
+ GLuint i;
+ const GLshort *s = (const GLshort *) src;
+ if (unpack->SwapBytes) {
+ for (i = 0; i < n; i++) {
+ GLshort value = s[i];
+ SWAP2BYTE(value);
+ indexes[i] = value;
+ }
+ }
+ else {
+ for (i = 0; i < n; i++)
+ indexes[i] = s[i];
+ }
+ }
+ break;
+ case GL_UNSIGNED_INT:
+ {
+ GLuint i;
+ const GLuint *s = (const GLuint *) src;
+ if (unpack->SwapBytes) {
+ for (i = 0; i < n; i++) {
+ GLuint value = s[i];
+ SWAP4BYTE(value);
+ indexes[i] = value;
+ }
+ }
+ else {
+ for (i = 0; i < n; i++)
+ indexes[i] = s[i];
+ }
+ }
+ break;
+ case GL_INT:
+ {
+ GLuint i;
+ const GLint *s = (const GLint *) src;
+ if (unpack->SwapBytes) {
+ for (i = 0; i < n; i++) {
+ GLint value = s[i];
+ SWAP4BYTE(value);
+ indexes[i] = value;
+ }
+ }
+ else {
+ for (i = 0; i < n; i++)
+ indexes[i] = s[i];
+ }
+ }
+ break;
+ case GL_FLOAT:
+ {
+ GLuint i;
+ const GLfloat *s = (const GLfloat *) src;
+ if (unpack->SwapBytes) {
+ for (i = 0; i < n; i++) {
+ GLfloat value = s[i];
+ SWAP4BYTE(value);
+ indexes[i] = (GLuint) value;
+ }
+ }
+ else {
+ for (i = 0; i < n; i++)
+ indexes[i] = (GLuint) s[i];
+ }
+ }
+ break;
+ case GL_HALF_FLOAT_ARB:
+ {
+ GLuint i;
+ const GLhalfARB *s = (const GLhalfARB *) src;
+ if (unpack->SwapBytes) {
+ for (i = 0; i < n; i++) {
+ GLhalfARB value = s[i];
+ SWAP2BYTE(value);
+ indexes[i] = (GLuint) _mesa_half_to_float(value);
+ }
+ }
+ else {
+ for (i = 0; i < n; i++)
+ indexes[i] = (GLuint) _mesa_half_to_float(s[i]);
+ }
+ }
+ break;
+ case GL_UNSIGNED_INT_24_8_EXT:
+ {
+ GLuint i;
+ const GLuint *s = (const GLuint *) src;
+ if (unpack->SwapBytes) {
+ for (i = 0; i < n; i++) {
+ GLuint value = s[i];
+ SWAP4BYTE(value);
+ indexes[i] = value & 0xff; /* lower 8 bits */
+ }
+ }
+ else {
+ for (i = 0; i < n; i++)
+ indexes[i] = s[i] & 0xfff; /* lower 8 bits */
+ }
+ }
+ break;
+
+ default:
+ _mesa_problem(NULL, "bad srcType in extract_uint_indexes");
+ return;
+ }
+}
+
+
+/*
+ * This function extracts floating point RGBA values from arbitrary
+ * image data. srcFormat and srcType are the format and type parameters
+ * passed to glDrawPixels, glTexImage[123]D, glTexSubImage[123]D, etc.
+ *
+ * Refering to section 3.6.4 of the OpenGL 1.2 spec, this function
+ * implements the "Conversion to floating point", "Conversion to RGB",
+ * and "Final Expansion to RGBA" operations.
+ *
+ * Args: n - number of pixels
+ * rgba - output colors
+ * srcFormat - format of incoming data
+ * srcType - data type of incoming data
+ * src - source data pointer
+ * swapBytes - perform byteswapping of incoming data?
+ */
+static void
+extract_float_rgba(GLuint n, GLfloat rgba[][4],
+ GLenum srcFormat, GLenum srcType, const GLvoid *src,
+ GLboolean swapBytes)
+{
+ GLint redIndex, greenIndex, blueIndex, alphaIndex;
+ GLint stride;
+ GLint rComp, bComp, gComp, aComp;
+
+ ASSERT(srcFormat == GL_RED ||
+ srcFormat == GL_GREEN ||
+ srcFormat == GL_BLUE ||
+ srcFormat == GL_ALPHA ||
+ srcFormat == GL_LUMINANCE ||
+ srcFormat == GL_LUMINANCE_ALPHA ||
+ srcFormat == GL_INTENSITY ||
+ srcFormat == GL_RGB ||
+ srcFormat == GL_BGR ||
+ srcFormat == GL_RGBA ||
+ srcFormat == GL_BGRA ||
+ srcFormat == GL_ABGR_EXT);
+
+ ASSERT(srcType == GL_UNSIGNED_BYTE ||
+ srcType == GL_BYTE ||
+ srcType == GL_UNSIGNED_SHORT ||
+ srcType == GL_SHORT ||
+ srcType == GL_UNSIGNED_INT ||
+ srcType == GL_INT ||
+ srcType == GL_HALF_FLOAT_ARB ||
+ srcType == GL_FLOAT ||
+ srcType == GL_UNSIGNED_BYTE_3_3_2 ||
+ srcType == GL_UNSIGNED_BYTE_2_3_3_REV ||
+ srcType == GL_UNSIGNED_SHORT_5_6_5 ||
+ srcType == GL_UNSIGNED_SHORT_5_6_5_REV ||
+ srcType == GL_UNSIGNED_SHORT_4_4_4_4 ||
+ srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
+ srcType == GL_UNSIGNED_SHORT_5_5_5_1 ||
+ srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV ||
+ srcType == GL_UNSIGNED_INT_8_8_8_8 ||
+ srcType == GL_UNSIGNED_INT_8_8_8_8_REV ||
+ srcType == GL_UNSIGNED_INT_10_10_10_2 ||
+ srcType == GL_UNSIGNED_INT_2_10_10_10_REV);
+
+ rComp = gComp = bComp = aComp = -1;
+
+ switch (srcFormat) {
+ case GL_RED:
+ redIndex = 0;
+ greenIndex = blueIndex = alphaIndex = -1;
+ stride = 1;
+ break;
+ case GL_GREEN:
+ greenIndex = 0;
+ redIndex = blueIndex = alphaIndex = -1;
+ stride = 1;
+ break;
+ case GL_BLUE:
+ blueIndex = 0;
+ redIndex = greenIndex = alphaIndex = -1;
+ stride = 1;
+ break;
+ case GL_ALPHA:
+ redIndex = greenIndex = blueIndex = -1;
+ alphaIndex = 0;
+ stride = 1;
+ break;
+ case GL_LUMINANCE:
+ redIndex = greenIndex = blueIndex = 0;
+ alphaIndex = -1;
+ stride = 1;
+ break;
+ case GL_LUMINANCE_ALPHA:
+ redIndex = greenIndex = blueIndex = 0;
+ alphaIndex = 1;
+ stride = 2;
+ break;
+ case GL_INTENSITY:
+ redIndex = greenIndex = blueIndex = alphaIndex = 0;
+ stride = 1;
+ break;
+ case GL_RGB:
+ redIndex = 0;
+ greenIndex = 1;
+ blueIndex = 2;
+ alphaIndex = -1;
+ rComp = 0;
+ gComp = 1;
+ bComp = 2;
+ aComp = 3;
+ stride = 3;
+ break;
+ case GL_BGR:
+ redIndex = 2;
+ greenIndex = 1;
+ blueIndex = 0;
+ alphaIndex = -1;
+ rComp = 2;
+ gComp = 1;
+ bComp = 0;
+ aComp = 3;
+ stride = 3;
+ break;
+ case GL_RGBA:
+ redIndex = 0;
+ greenIndex = 1;
+ blueIndex = 2;
+ alphaIndex = 3;
+ rComp = 0;
+ gComp = 1;
+ bComp = 2;
+ aComp = 3;
+ stride = 4;
+ break;
+ case GL_BGRA:
+ redIndex = 2;
+ greenIndex = 1;
+ blueIndex = 0;
+ alphaIndex = 3;
+ rComp = 2;
+ gComp = 1;
+ bComp = 0;
+ aComp = 3;
+ stride = 4;
+ break;
+ case GL_ABGR_EXT:
+ redIndex = 3;
+ greenIndex = 2;
+ blueIndex = 1;
+ alphaIndex = 0;
+ rComp = 3;
+ gComp = 2;
+ bComp = 1;
+ aComp = 0;
+ stride = 4;
+ break;
+ default:
+ _mesa_problem(NULL, "bad srcFormat in extract float data");
+ return;
+ }
+
+
+#define PROCESS(INDEX, CHANNEL, DEFAULT, TYPE, CONVERSION) \
+ if ((INDEX) < 0) { \
+ GLuint i; \
+ for (i = 0; i < n; i++) { \
+ rgba[i][CHANNEL] = DEFAULT; \
+ } \
+ } \
+ else if (swapBytes) { \
+ const TYPE *s = (const TYPE *) src; \
+ GLuint i; \
+ for (i = 0; i < n; i++) { \
+ TYPE value = s[INDEX]; \
+ if (sizeof(TYPE) == 2) { \
+ SWAP2BYTE(value); \
+ } \
+ else if (sizeof(TYPE) == 4) { \
+ SWAP4BYTE(value); \
+ } \
+ rgba[i][CHANNEL] = (GLfloat) CONVERSION(value); \
+ s += stride; \
+ } \
+ } \
+ else { \
+ const TYPE *s = (const TYPE *) src; \
+ GLuint i; \
+ for (i = 0; i < n; i++) { \
+ rgba[i][CHANNEL] = (GLfloat) CONVERSION(s[INDEX]); \
+ s += stride; \
+ } \
+ }
+
+ switch (srcType) {
+ case GL_UNSIGNED_BYTE:
+ PROCESS(redIndex, RCOMP, 0.0F, GLubyte, UBYTE_TO_FLOAT);
+ PROCESS(greenIndex, GCOMP, 0.0F, GLubyte, UBYTE_TO_FLOAT);
+ PROCESS(blueIndex, BCOMP, 0.0F, GLubyte, UBYTE_TO_FLOAT);
+ PROCESS(alphaIndex, ACOMP, 1.0F, GLubyte, UBYTE_TO_FLOAT);
+ break;
+ case GL_BYTE:
+ PROCESS(redIndex, RCOMP, 0.0F, GLbyte, BYTE_TO_FLOAT);
+ PROCESS(greenIndex, GCOMP, 0.0F, GLbyte, BYTE_TO_FLOAT);
+ PROCESS(blueIndex, BCOMP, 0.0F, GLbyte, BYTE_TO_FLOAT);
+ PROCESS(alphaIndex, ACOMP, 1.0F, GLbyte, BYTE_TO_FLOAT);
+ break;
+ case GL_UNSIGNED_SHORT:
+ PROCESS(redIndex, RCOMP, 0.0F, GLushort, USHORT_TO_FLOAT);
+ PROCESS(greenIndex, GCOMP, 0.0F, GLushort, USHORT_TO_FLOAT);
+ PROCESS(blueIndex, BCOMP, 0.0F, GLushort, USHORT_TO_FLOAT);
+ PROCESS(alphaIndex, ACOMP, 1.0F, GLushort, USHORT_TO_FLOAT);
+ break;
+ case GL_SHORT:
+ PROCESS(redIndex, RCOMP, 0.0F, GLshort, SHORT_TO_FLOAT);
+ PROCESS(greenIndex, GCOMP, 0.0F, GLshort, SHORT_TO_FLOAT);
+ PROCESS(blueIndex, BCOMP, 0.0F, GLshort, SHORT_TO_FLOAT);
+ PROCESS(alphaIndex, ACOMP, 1.0F, GLshort, SHORT_TO_FLOAT);
+ break;
+ case GL_UNSIGNED_INT:
+ PROCESS(redIndex, RCOMP, 0.0F, GLuint, UINT_TO_FLOAT);
+ PROCESS(greenIndex, GCOMP, 0.0F, GLuint, UINT_TO_FLOAT);
+ PROCESS(blueIndex, BCOMP, 0.0F, GLuint, UINT_TO_FLOAT);
+ PROCESS(alphaIndex, ACOMP, 1.0F, GLuint, UINT_TO_FLOAT);
+ break;
+ case GL_INT:
+ PROCESS(redIndex, RCOMP, 0.0F, GLint, INT_TO_FLOAT);
+ PROCESS(greenIndex, GCOMP, 0.0F, GLint, INT_TO_FLOAT);
+ PROCESS(blueIndex, BCOMP, 0.0F, GLint, INT_TO_FLOAT);
+ PROCESS(alphaIndex, ACOMP, 1.0F, GLint, INT_TO_FLOAT);
+ break;
+ case GL_FLOAT:
+ PROCESS(redIndex, RCOMP, 0.0F, GLfloat, (GLfloat));
+ PROCESS(greenIndex, GCOMP, 0.0F, GLfloat, (GLfloat));
+ PROCESS(blueIndex, BCOMP, 0.0F, GLfloat, (GLfloat));
+ PROCESS(alphaIndex, ACOMP, 1.0F, GLfloat, (GLfloat));
+ break;
+ case GL_HALF_FLOAT_ARB:
+ PROCESS(redIndex, RCOMP, 0.0F, GLhalfARB, _mesa_half_to_float);
+ PROCESS(greenIndex, GCOMP, 0.0F, GLhalfARB, _mesa_half_to_float);
+ PROCESS(blueIndex, BCOMP, 0.0F, GLhalfARB, _mesa_half_to_float);
+ PROCESS(alphaIndex, ACOMP, 1.0F, GLhalfARB, _mesa_half_to_float);
+ break;
+ case GL_UNSIGNED_BYTE_3_3_2:
+ {
+ const GLubyte *ubsrc = (const GLubyte *) src;
+ GLuint i;
+ for (i = 0; i < n; i ++) {
+ GLubyte p = ubsrc[i];
+ rgba[i][rComp] = ((p >> 5) ) * (1.0F / 7.0F);
+ rgba[i][gComp] = ((p >> 2) & 0x7) * (1.0F / 7.0F);
+ rgba[i][bComp] = ((p ) & 0x3) * (1.0F / 3.0F);
+ rgba[i][aComp] = 1.0F;
+ }
+ }
+ break;
+ case GL_UNSIGNED_BYTE_2_3_3_REV:
+ {
+ const GLubyte *ubsrc = (const GLubyte *) src;
+ GLuint i;
+ for (i = 0; i < n; i ++) {
+ GLubyte p = ubsrc[i];
+ rgba[i][rComp] = ((p ) & 0x7) * (1.0F / 7.0F);
+ rgba[i][gComp] = ((p >> 3) & 0x7) * (1.0F / 7.0F);
+ rgba[i][bComp] = ((p >> 6) ) * (1.0F / 3.0F);
+ rgba[i][aComp] = 1.0F;
+ }
+ }
+ break;
+ case GL_UNSIGNED_SHORT_5_6_5:
+ if (swapBytes) {
+ const GLushort *ussrc = (const GLushort *) src;
+ GLuint i;
+ for (i = 0; i < n; i ++) {
+ GLushort p = ussrc[i];
+ SWAP2BYTE(p);
+ rgba[i][rComp] = ((p >> 11) ) * (1.0F / 31.0F);
+ rgba[i][gComp] = ((p >> 5) & 0x3f) * (1.0F / 63.0F);
+ rgba[i][bComp] = ((p ) & 0x1f) * (1.0F / 31.0F);
+ rgba[i][aComp] = 1.0F;
+ }
+ }
+ else {
+ const GLushort *ussrc = (const GLushort *) src;
+ GLuint i;
+ for (i = 0; i < n; i ++) {
+ GLushort p = ussrc[i];
+ rgba[i][rComp] = ((p >> 11) ) * (1.0F / 31.0F);
+ rgba[i][gComp] = ((p >> 5) & 0x3f) * (1.0F / 63.0F);
+ rgba[i][bComp] = ((p ) & 0x1f) * (1.0F / 31.0F);
+ rgba[i][aComp] = 1.0F;
+ }
+ }
+ break;
+ case GL_UNSIGNED_SHORT_5_6_5_REV:
+ if (swapBytes) {
+ const GLushort *ussrc = (const GLushort *) src;
+ GLuint i;
+ for (i = 0; i < n; i ++) {
+ GLushort p = ussrc[i];
+ SWAP2BYTE(p);
+ rgba[i][rComp] = ((p ) & 0x1f) * (1.0F / 31.0F);
+ rgba[i][gComp] = ((p >> 5) & 0x3f) * (1.0F / 63.0F);
+ rgba[i][bComp] = ((p >> 11) ) * (1.0F / 31.0F);
+ rgba[i][aComp] = 1.0F;
+ }
+ }
+ else {
+ const GLushort *ussrc = (const GLushort *) src;
+ GLuint i;
+ for (i = 0; i < n; i ++) {
+ GLushort p = ussrc[i];
+ rgba[i][rComp] = ((p ) & 0x1f) * (1.0F / 31.0F);
+ rgba[i][gComp] = ((p >> 5) & 0x3f) * (1.0F / 63.0F);
+ rgba[i][bComp] = ((p >> 11) ) * (1.0F / 31.0F);
+ rgba[i][aComp] = 1.0F;
+ }
+ }
+ break;
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ if (swapBytes) {
+ const GLushort *ussrc = (const GLushort *) src;
+ GLuint i;
+ for (i = 0; i < n; i ++) {
+ GLushort p = ussrc[i];
+ SWAP2BYTE(p);
+ rgba[i][rComp] = ((p >> 12) ) * (1.0F / 15.0F);
+ rgba[i][gComp] = ((p >> 8) & 0xf) * (1.0F / 15.0F);
+ rgba[i][bComp] = ((p >> 4) & 0xf) * (1.0F / 15.0F);
+ rgba[i][aComp] = ((p ) & 0xf) * (1.0F / 15.0F);
+ }
+ }
+ else {
+ const GLushort *ussrc = (const GLushort *) src;
+ GLuint i;
+ for (i = 0; i < n; i ++) {
+ GLushort p = ussrc[i];
+ rgba[i][rComp] = ((p >> 12) ) * (1.0F / 15.0F);
+ rgba[i][gComp] = ((p >> 8) & 0xf) * (1.0F / 15.0F);
+ rgba[i][bComp] = ((p >> 4) & 0xf) * (1.0F / 15.0F);
+ rgba[i][aComp] = ((p ) & 0xf) * (1.0F / 15.0F);
+ }
+ }
+ break;
+ case GL_UNSIGNED_SHORT_4_4_4_4_REV:
+ if (swapBytes) {
+ const GLushort *ussrc = (const GLushort *) src;
+ GLuint i;
+ for (i = 0; i < n; i ++) {
+ GLushort p = ussrc[i];
+ SWAP2BYTE(p);
+ rgba[i][rComp] = ((p ) & 0xf) * (1.0F / 15.0F);
+ rgba[i][gComp] = ((p >> 4) & 0xf) * (1.0F / 15.0F);
+ rgba[i][bComp] = ((p >> 8) & 0xf) * (1.0F / 15.0F);
+ rgba[i][aComp] = ((p >> 12) ) * (1.0F / 15.0F);
+ }
+ }
+ else {
+ const GLushort *ussrc = (const GLushort *) src;
+ GLuint i;
+ for (i = 0; i < n; i ++) {
+ GLushort p = ussrc[i];
+ rgba[i][rComp] = ((p ) & 0xf) * (1.0F / 15.0F);
+ rgba[i][gComp] = ((p >> 4) & 0xf) * (1.0F / 15.0F);
+ rgba[i][bComp] = ((p >> 8) & 0xf) * (1.0F / 15.0F);
+ rgba[i][aComp] = ((p >> 12) ) * (1.0F / 15.0F);
+ }
+ }
+ break;
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ if (swapBytes) {
+ const GLushort *ussrc = (const GLushort *) src;
+ GLuint i;
+ for (i = 0; i < n; i ++) {
+ GLushort p = ussrc[i];
+ SWAP2BYTE(p);
+ rgba[i][rComp] = ((p >> 11) ) * (1.0F / 31.0F);
+ rgba[i][gComp] = ((p >> 6) & 0x1f) * (1.0F / 31.0F);
+ rgba[i][bComp] = ((p >> 1) & 0x1f) * (1.0F / 31.0F);
+ rgba[i][aComp] = ((p ) & 0x1) * (1.0F / 1.0F);
+ }
+ }
+ else {
+ const GLushort *ussrc = (const GLushort *) src;
+ GLuint i;
+ for (i = 0; i < n; i ++) {
+ GLushort p = ussrc[i];
+ rgba[i][rComp] = ((p >> 11) ) * (1.0F / 31.0F);
+ rgba[i][gComp] = ((p >> 6) & 0x1f) * (1.0F / 31.0F);
+ rgba[i][bComp] = ((p >> 1) & 0x1f) * (1.0F / 31.0F);
+ rgba[i][aComp] = ((p ) & 0x1) * (1.0F / 1.0F);
+ }
+ }
+ break;
+ case GL_UNSIGNED_SHORT_1_5_5_5_REV:
+ if (swapBytes) {
+ const GLushort *ussrc = (const GLushort *) src;
+ GLuint i;
+ for (i = 0; i < n; i ++) {
+ GLushort p = ussrc[i];
+ SWAP2BYTE(p);
+ rgba[i][rComp] = ((p ) & 0x1f) * (1.0F / 31.0F);
+ rgba[i][gComp] = ((p >> 5) & 0x1f) * (1.0F / 31.0F);
+ rgba[i][bComp] = ((p >> 10) & 0x1f) * (1.0F / 31.0F);
+ rgba[i][aComp] = ((p >> 15) ) * (1.0F / 1.0F);
+ }
+ }
+ else {
+ const GLushort *ussrc = (const GLushort *) src;
+ GLuint i;
+ for (i = 0; i < n; i ++) {
+ GLushort p = ussrc[i];
+ rgba[i][rComp] = ((p ) & 0x1f) * (1.0F / 31.0F);
+ rgba[i][gComp] = ((p >> 5) & 0x1f) * (1.0F / 31.0F);
+ rgba[i][bComp] = ((p >> 10) & 0x1f) * (1.0F / 31.0F);
+ rgba[i][aComp] = ((p >> 15) ) * (1.0F / 1.0F);
+ }
+ }
+ break;
+ case GL_UNSIGNED_INT_8_8_8_8:
+ if (swapBytes) {
+ const GLuint *uisrc = (const GLuint *) src;
+ GLuint i;
+ for (i = 0; i < n; i ++) {
+ GLuint p = uisrc[i];
+ rgba[i][rComp] = UBYTE_TO_FLOAT((p ) & 0xff);
+ rgba[i][gComp] = UBYTE_TO_FLOAT((p >> 8) & 0xff);
+ rgba[i][bComp] = UBYTE_TO_FLOAT((p >> 16) & 0xff);
+ rgba[i][aComp] = UBYTE_TO_FLOAT((p >> 24) );
+ }
+ }
+ else {
+ const GLuint *uisrc = (const GLuint *) src;
+ GLuint i;
+ for (i = 0; i < n; i ++) {
+ GLuint p = uisrc[i];
+ rgba[i][rComp] = UBYTE_TO_FLOAT((p >> 24) );
+ rgba[i][gComp] = UBYTE_TO_FLOAT((p >> 16) & 0xff);
+ rgba[i][bComp] = UBYTE_TO_FLOAT((p >> 8) & 0xff);
+ rgba[i][aComp] = UBYTE_TO_FLOAT((p ) & 0xff);
+ }
+ }
+ break;
+ case GL_UNSIGNED_INT_8_8_8_8_REV:
+ if (swapBytes) {
+ const GLuint *uisrc = (const GLuint *) src;
+ GLuint i;
+ for (i = 0; i < n; i ++) {
+ GLuint p = uisrc[i];
+ rgba[i][rComp] = UBYTE_TO_FLOAT((p >> 24) );
+ rgba[i][gComp] = UBYTE_TO_FLOAT((p >> 16) & 0xff);
+ rgba[i][bComp] = UBYTE_TO_FLOAT((p >> 8) & 0xff);
+ rgba[i][aComp] = UBYTE_TO_FLOAT((p ) & 0xff);
+ }
+ }
+ else {
+ const GLuint *uisrc = (const GLuint *) src;
+ GLuint i;
+ for (i = 0; i < n; i ++) {
+ GLuint p = uisrc[i];
+ rgba[i][rComp] = UBYTE_TO_FLOAT((p ) & 0xff);
+ rgba[i][gComp] = UBYTE_TO_FLOAT((p >> 8) & 0xff);
+ rgba[i][bComp] = UBYTE_TO_FLOAT((p >> 16) & 0xff);
+ rgba[i][aComp] = UBYTE_TO_FLOAT((p >> 24) );
+ }
+ }
+ break;
+ case GL_UNSIGNED_INT_10_10_10_2:
+ if (swapBytes) {
+ const GLuint *uisrc = (const GLuint *) src;
+ GLuint i;
+ for (i = 0; i < n; i ++) {
+ GLuint p = uisrc[i];
+ SWAP4BYTE(p);
+ rgba[i][rComp] = ((p >> 22) ) * (1.0F / 1023.0F);
+ rgba[i][gComp] = ((p >> 12) & 0x3ff) * (1.0F / 1023.0F);
+ rgba[i][bComp] = ((p >> 2) & 0x3ff) * (1.0F / 1023.0F);
+ rgba[i][aComp] = ((p ) & 0x3 ) * (1.0F / 3.0F);
+ }
+ }
+ else {
+ const GLuint *uisrc = (const GLuint *) src;
+ GLuint i;
+ for (i = 0; i < n; i ++) {
+ GLuint p = uisrc[i];
+ rgba[i][rComp] = ((p >> 22) ) * (1.0F / 1023.0F);
+ rgba[i][gComp] = ((p >> 12) & 0x3ff) * (1.0F / 1023.0F);
+ rgba[i][bComp] = ((p >> 2) & 0x3ff) * (1.0F / 1023.0F);
+ rgba[i][aComp] = ((p ) & 0x3 ) * (1.0F / 3.0F);
+ }
+ }
+ break;
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ if (swapBytes) {
+ const GLuint *uisrc = (const GLuint *) src;
+ GLuint i;
+ for (i = 0; i < n; i ++) {
+ GLuint p = uisrc[i];
+ SWAP4BYTE(p);
+ rgba[i][rComp] = ((p ) & 0x3ff) * (1.0F / 1023.0F);
+ rgba[i][gComp] = ((p >> 10) & 0x3ff) * (1.0F / 1023.0F);
+ rgba[i][bComp] = ((p >> 20) & 0x3ff) * (1.0F / 1023.0F);
+ rgba[i][aComp] = ((p >> 30) ) * (1.0F / 3.0F);
+ }
+ }
+ else {
+ const GLuint *uisrc = (const GLuint *) src;
+ GLuint i;
+ for (i = 0; i < n; i ++) {
+ GLuint p = uisrc[i];
+ rgba[i][rComp] = ((p ) & 0x3ff) * (1.0F / 1023.0F);
+ rgba[i][gComp] = ((p >> 10) & 0x3ff) * (1.0F / 1023.0F);
+ rgba[i][bComp] = ((p >> 20) & 0x3ff) * (1.0F / 1023.0F);
+ rgba[i][aComp] = ((p >> 30) ) * (1.0F / 3.0F);
+ }
+ }
+ break;
+ default:
+ _mesa_problem(NULL, "bad srcType in extract float data");
+ break;
+ }
+}
+
+
+/*
+ * Unpack a row of color image data from a client buffer according to
+ * the pixel unpacking parameters.
+ * Return GLchan values in the specified dest image format.
+ * This is used by glDrawPixels and glTexImage?D().
+ * \param ctx - the context
+ * n - number of pixels in the span
+ * dstFormat - format of destination color array
+ * dest - the destination color array
+ * srcFormat - source image format
+ * srcType - source image data type
+ * source - source image pointer
+ * srcPacking - pixel unpacking parameters
+ * transferOps - bitmask of IMAGE_*_BIT values of operations to apply
+ *
+ * XXX perhaps expand this to process whole images someday.
+ */
+void
+_mesa_unpack_color_span_chan( GLcontext *ctx,
+ GLuint n, GLenum dstFormat, GLchan dest[],
+ GLenum srcFormat, GLenum srcType,
+ const GLvoid *source,
+ const struct gl_pixelstore_attrib *srcPacking,
+ GLuint transferOps )
+{
+ ASSERT(dstFormat == GL_ALPHA ||
+ dstFormat == GL_LUMINANCE ||
+ dstFormat == GL_LUMINANCE_ALPHA ||
+ dstFormat == GL_INTENSITY ||
+ dstFormat == GL_RGB ||
+ dstFormat == GL_RGBA ||
+ dstFormat == GL_COLOR_INDEX);
+
+ ASSERT(srcFormat == GL_RED ||
+ srcFormat == GL_GREEN ||
+ srcFormat == GL_BLUE ||
+ srcFormat == GL_ALPHA ||
+ srcFormat == GL_LUMINANCE ||
+ srcFormat == GL_LUMINANCE_ALPHA ||
+ srcFormat == GL_INTENSITY ||
+ srcFormat == GL_RGB ||
+ srcFormat == GL_BGR ||
+ srcFormat == GL_RGBA ||
+ srcFormat == GL_BGRA ||
+ srcFormat == GL_ABGR_EXT ||
+ srcFormat == GL_COLOR_INDEX);
+
+ ASSERT(srcType == GL_BITMAP ||
+ srcType == GL_UNSIGNED_BYTE ||
+ srcType == GL_BYTE ||
+ srcType == GL_UNSIGNED_SHORT ||
+ srcType == GL_SHORT ||
+ srcType == GL_UNSIGNED_INT ||
+ srcType == GL_INT ||
+ srcType == GL_HALF_FLOAT_ARB ||
+ srcType == GL_FLOAT ||
+ srcType == GL_UNSIGNED_BYTE_3_3_2 ||
+ srcType == GL_UNSIGNED_BYTE_2_3_3_REV ||
+ srcType == GL_UNSIGNED_SHORT_5_6_5 ||
+ srcType == GL_UNSIGNED_SHORT_5_6_5_REV ||
+ srcType == GL_UNSIGNED_SHORT_4_4_4_4 ||
+ srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
+ srcType == GL_UNSIGNED_SHORT_5_5_5_1 ||
+ srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV ||
+ srcType == GL_UNSIGNED_INT_8_8_8_8 ||
+ srcType == GL_UNSIGNED_INT_8_8_8_8_REV ||
+ srcType == GL_UNSIGNED_INT_10_10_10_2 ||
+ srcType == GL_UNSIGNED_INT_2_10_10_10_REV);
+
+ /* Try simple cases first */
+ if (transferOps == 0) {
+ if (srcType == CHAN_TYPE) {
+ if (dstFormat == GL_RGBA) {
+ if (srcFormat == GL_RGBA) {
+ MEMCPY( dest, source, n * 4 * sizeof(GLchan) );
+ return;
+ }
+ else if (srcFormat == GL_RGB) {
+ GLuint i;
+ const GLchan *src = (const GLchan *) source;
+ GLchan *dst = dest;
+ for (i = 0; i < n; i++) {
+ dst[0] = src[0];
+ dst[1] = src[1];
+ dst[2] = src[2];
+ dst[3] = CHAN_MAX;
+ src += 3;
+ dst += 4;
+ }
+ return;
+ }
+ }
+ else if (dstFormat == GL_RGB) {
+ if (srcFormat == GL_RGB) {
+ MEMCPY( dest, source, n * 3 * sizeof(GLchan) );
+ return;
+ }
+ else if (srcFormat == GL_RGBA) {
+ GLuint i;
+ const GLchan *src = (const GLchan *) source;
+ GLchan *dst = dest;
+ for (i = 0; i < n; i++) {
+ dst[0] = src[0];
+ dst[1] = src[1];
+ dst[2] = src[2];
+ src += 4;
+ dst += 3;
+ }
+ return;
+ }
+ }
+ else if (dstFormat == srcFormat) {
+ GLint comps = _mesa_components_in_format(srcFormat);
+ assert(comps > 0);
+ MEMCPY( dest, source, n * comps * sizeof(GLchan) );
+ return;
+ }
+ }
+ /*
+ * Common situation, loading 8bit RGBA/RGB source images
+ * into 16/32 bit destination. (OSMesa16/32)
+ */
+ else if (srcType == GL_UNSIGNED_BYTE) {
+ if (dstFormat == GL_RGBA) {
+ if (srcFormat == GL_RGB) {
+ GLuint i;
+ const GLubyte *src = (const GLubyte *) source;
+ GLchan *dst = dest;
+ for (i = 0; i < n; i++) {
+ dst[0] = UBYTE_TO_CHAN(src[0]);
+ dst[1] = UBYTE_TO_CHAN(src[1]);
+ dst[2] = UBYTE_TO_CHAN(src[2]);
+ dst[3] = CHAN_MAX;
+ src += 3;
+ dst += 4;
+ }
+ return;
+ }
+ else if (srcFormat == GL_RGBA) {
+ GLuint i;
+ const GLubyte *src = (const GLubyte *) source;
+ GLchan *dst = dest;
+ for (i = 0; i < n; i++) {
+ dst[0] = UBYTE_TO_CHAN(src[0]);
+ dst[1] = UBYTE_TO_CHAN(src[1]);
+ dst[2] = UBYTE_TO_CHAN(src[2]);
+ dst[3] = UBYTE_TO_CHAN(src[3]);
+ src += 4;
+ dst += 4;
+ }
+ return;
+ }
+ }
+ else if (dstFormat == GL_RGB) {
+ if (srcFormat == GL_RGB) {
+ GLuint i;
+ const GLubyte *src = (const GLubyte *) source;
+ GLchan *dst = dest;
+ for (i = 0; i < n; i++) {
+ dst[0] = UBYTE_TO_CHAN(src[0]);
+ dst[1] = UBYTE_TO_CHAN(src[1]);
+ dst[2] = UBYTE_TO_CHAN(src[2]);
+ src += 3;
+ dst += 3;
+ }
+ return;
+ }
+ else if (srcFormat == GL_RGBA) {
+ GLuint i;
+ const GLubyte *src = (const GLubyte *) source;
+ GLchan *dst = dest;
+ for (i = 0; i < n; i++) {
+ dst[0] = UBYTE_TO_CHAN(src[0]);
+ dst[1] = UBYTE_TO_CHAN(src[1]);
+ dst[2] = UBYTE_TO_CHAN(src[2]);
+ src += 4;
+ dst += 3;
+ }
+ return;
+ }
+ }
+ }
+ }
+
+
+ /* general solution begins here */
+ {
+ GLint dstComponents;
+ GLint dstRedIndex, dstGreenIndex, dstBlueIndex, dstAlphaIndex;
+ GLint dstLuminanceIndex, dstIntensityIndex;
+ GLfloat rgba[MAX_WIDTH][4];
+
+ dstComponents = _mesa_components_in_format( dstFormat );
+ /* source & dest image formats should have been error checked by now */
+ assert(dstComponents > 0);
+
+ /*
+ * Extract image data and convert to RGBA floats
+ */
+ assert(n <= MAX_WIDTH);
+ if (srcFormat == GL_COLOR_INDEX) {
+ GLuint indexes[MAX_WIDTH];
+ extract_uint_indexes(n, indexes, srcFormat, srcType, source,
+ srcPacking);
+
+ if (dstFormat == GL_COLOR_INDEX
+ && (transferOps & IMAGE_MAP_COLOR_BIT)) {
+ _mesa_map_ci(ctx, n, indexes);
+ }
+ if (transferOps & IMAGE_SHIFT_OFFSET_BIT) {
+ _mesa_shift_and_offset_ci(ctx, n, indexes);
+ }
+
+ if (dstFormat == GL_COLOR_INDEX) {
+ /* convert to GLchan and return */
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dest[i] = (GLchan) (indexes[i] & 0xff);
+ }
+ return;
+ }
+ else {
+ /* Convert indexes to RGBA */
+ _mesa_map_ci_to_rgba(ctx, n, indexes, rgba);
+ }
+
+ /* Don't do RGBA scale/bias or RGBA->RGBA mapping if starting
+ * with color indexes.
+ */
+ transferOps &= ~(IMAGE_SCALE_BIAS_BIT | IMAGE_MAP_COLOR_BIT);
+ }
+ else {
+ /* non-color index data */
+ extract_float_rgba(n, rgba, srcFormat, srcType, source,
+ srcPacking->SwapBytes);
+ }
+
+ /* Need to clamp if returning GLubytes or GLushorts */
+#if CHAN_TYPE != GL_FLOAT
+ transferOps |= IMAGE_CLAMP_BIT;
+#endif
+
+ if (transferOps) {
+ _mesa_apply_rgba_transfer_ops(ctx, transferOps, n, rgba);
+ }
+
+ /* Now determine which color channels we need to produce.
+ * And determine the dest index (offset) within each color tuple.
+ */
+ switch (dstFormat) {
+ case GL_ALPHA:
+ dstAlphaIndex = 0;
+ dstRedIndex = dstGreenIndex = dstBlueIndex = -1;
+ dstLuminanceIndex = dstIntensityIndex = -1;
+ break;
+ case GL_LUMINANCE:
+ dstLuminanceIndex = 0;
+ dstRedIndex = dstGreenIndex = dstBlueIndex = dstAlphaIndex = -1;
+ dstIntensityIndex = -1;
+ break;
+ case GL_LUMINANCE_ALPHA:
+ dstLuminanceIndex = 0;
+ dstAlphaIndex = 1;
+ dstRedIndex = dstGreenIndex = dstBlueIndex = -1;
+ dstIntensityIndex = -1;
+ break;
+ case GL_INTENSITY:
+ dstIntensityIndex = 0;
+ dstRedIndex = dstGreenIndex = dstBlueIndex = dstAlphaIndex = -1;
+ dstLuminanceIndex = -1;
+ break;
+ case GL_RGB:
+ dstRedIndex = 0;
+ dstGreenIndex = 1;
+ dstBlueIndex = 2;
+ dstAlphaIndex = dstLuminanceIndex = dstIntensityIndex = -1;
+ break;
+ case GL_RGBA:
+ dstRedIndex = 0;
+ dstGreenIndex = 1;
+ dstBlueIndex = 2;
+ dstAlphaIndex = 3;
+ dstLuminanceIndex = dstIntensityIndex = -1;
+ break;
+ default:
+ _mesa_problem(ctx, "bad dstFormat in _mesa_unpack_chan_span()");
+ return;
+ }
+
+
+ /* Now return the GLchan data in the requested dstFormat */
+
+ if (dstRedIndex >= 0) {
+ GLchan *dst = dest;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ CLAMPED_FLOAT_TO_CHAN(dst[dstRedIndex], rgba[i][RCOMP]);
+ dst += dstComponents;
+ }
+ }
+
+ if (dstGreenIndex >= 0) {
+ GLchan *dst = dest;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ CLAMPED_FLOAT_TO_CHAN(dst[dstGreenIndex], rgba[i][GCOMP]);
+ dst += dstComponents;
+ }
+ }
+
+ if (dstBlueIndex >= 0) {
+ GLchan *dst = dest;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ CLAMPED_FLOAT_TO_CHAN(dst[dstBlueIndex], rgba[i][BCOMP]);
+ dst += dstComponents;
+ }
+ }
+
+ if (dstAlphaIndex >= 0) {
+ GLchan *dst = dest;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ CLAMPED_FLOAT_TO_CHAN(dst[dstAlphaIndex], rgba[i][ACOMP]);
+ dst += dstComponents;
+ }
+ }
+
+ if (dstIntensityIndex >= 0) {
+ GLchan *dst = dest;
+ GLuint i;
+ assert(dstIntensityIndex == 0);
+ assert(dstComponents == 1);
+ for (i = 0; i < n; i++) {
+ /* Intensity comes from red channel */
+ CLAMPED_FLOAT_TO_CHAN(dst[i], rgba[i][RCOMP]);
+ }
+ }
+
+ if (dstLuminanceIndex >= 0) {
+ GLchan *dst = dest;
+ GLuint i;
+ assert(dstLuminanceIndex == 0);
+ for (i = 0; i < n; i++) {
+ /* Luminance comes from red channel */
+ CLAMPED_FLOAT_TO_CHAN(dst[0], rgba[i][RCOMP]);
+ dst += dstComponents;
+ }
+ }
+ }
+}
+
+
+/**
+ * Same as _mesa_unpack_color_span_chan(), but return GLfloat data
+ * instead of GLchan.
+ */
+void
+_mesa_unpack_color_span_float( GLcontext *ctx,
+ GLuint n, GLenum dstFormat, GLfloat dest[],
+ GLenum srcFormat, GLenum srcType,
+ const GLvoid *source,
+ const struct gl_pixelstore_attrib *srcPacking,
+ GLuint transferOps )
+{
+ ASSERT(dstFormat == GL_ALPHA ||
+ dstFormat == GL_LUMINANCE ||
+ dstFormat == GL_LUMINANCE_ALPHA ||
+ dstFormat == GL_INTENSITY ||
+ dstFormat == GL_RGB ||
+ dstFormat == GL_RGBA ||
+ dstFormat == GL_COLOR_INDEX);
+
+ ASSERT(srcFormat == GL_RED ||
+ srcFormat == GL_GREEN ||
+ srcFormat == GL_BLUE ||
+ srcFormat == GL_ALPHA ||
+ srcFormat == GL_LUMINANCE ||
+ srcFormat == GL_LUMINANCE_ALPHA ||
+ srcFormat == GL_INTENSITY ||
+ srcFormat == GL_RGB ||
+ srcFormat == GL_BGR ||
+ srcFormat == GL_RGBA ||
+ srcFormat == GL_BGRA ||
+ srcFormat == GL_ABGR_EXT ||
+ srcFormat == GL_COLOR_INDEX);
+
+ ASSERT(srcType == GL_BITMAP ||
+ srcType == GL_UNSIGNED_BYTE ||
+ srcType == GL_BYTE ||
+ srcType == GL_UNSIGNED_SHORT ||
+ srcType == GL_SHORT ||
+ srcType == GL_UNSIGNED_INT ||
+ srcType == GL_INT ||
+ srcType == GL_HALF_FLOAT_ARB ||
+ srcType == GL_FLOAT ||
+ srcType == GL_UNSIGNED_BYTE_3_3_2 ||
+ srcType == GL_UNSIGNED_BYTE_2_3_3_REV ||
+ srcType == GL_UNSIGNED_SHORT_5_6_5 ||
+ srcType == GL_UNSIGNED_SHORT_5_6_5_REV ||
+ srcType == GL_UNSIGNED_SHORT_4_4_4_4 ||
+ srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
+ srcType == GL_UNSIGNED_SHORT_5_5_5_1 ||
+ srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV ||
+ srcType == GL_UNSIGNED_INT_8_8_8_8 ||
+ srcType == GL_UNSIGNED_INT_8_8_8_8_REV ||
+ srcType == GL_UNSIGNED_INT_10_10_10_2 ||
+ srcType == GL_UNSIGNED_INT_2_10_10_10_REV);
+
+ /* general solution, no special cases, yet */
+ {
+ GLint dstComponents;
+ GLint dstRedIndex, dstGreenIndex, dstBlueIndex, dstAlphaIndex;
+ GLint dstLuminanceIndex, dstIntensityIndex;
+ GLfloat rgba[MAX_WIDTH][4];
+
+ dstComponents = _mesa_components_in_format( dstFormat );
+ /* source & dest image formats should have been error checked by now */
+ assert(dstComponents > 0);
+
+ /*
+ * Extract image data and convert to RGBA floats
+ */
+ assert(n <= MAX_WIDTH);
+ if (srcFormat == GL_COLOR_INDEX) {
+ GLuint indexes[MAX_WIDTH];
+ extract_uint_indexes(n, indexes, srcFormat, srcType, source,
+ srcPacking);
+
+ if (dstFormat == GL_COLOR_INDEX
+ && (transferOps & IMAGE_MAP_COLOR_BIT)) {
+ _mesa_map_ci(ctx, n, indexes);
+ }
+ if (transferOps & IMAGE_SHIFT_OFFSET_BIT) {
+ _mesa_shift_and_offset_ci(ctx, n, indexes);
+ }
+
+ if (dstFormat == GL_COLOR_INDEX) {
+ /* convert to GLchan and return */
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dest[i] = (GLchan) (indexes[i] & 0xff);
+ }
+ return;
+ }
+ else {
+ /* Convert indexes to RGBA */
+ _mesa_map_ci_to_rgba(ctx, n, indexes, rgba);
+ }
+
+ /* Don't do RGBA scale/bias or RGBA->RGBA mapping if starting
+ * with color indexes.
+ */
+ transferOps &= ~(IMAGE_SCALE_BIAS_BIT | IMAGE_MAP_COLOR_BIT);
+ }
+ else {
+ /* non-color index data */
+ extract_float_rgba(n, rgba, srcFormat, srcType, source,
+ srcPacking->SwapBytes);
+ }
+
+ if (transferOps) {
+ _mesa_apply_rgba_transfer_ops(ctx, transferOps, n, rgba);
+ }
+
+ /* Now determine which color channels we need to produce.
+ * And determine the dest index (offset) within each color tuple.
+ */
+ switch (dstFormat) {
+ case GL_ALPHA:
+ dstAlphaIndex = 0;
+ dstRedIndex = dstGreenIndex = dstBlueIndex = -1;
+ dstLuminanceIndex = dstIntensityIndex = -1;
+ break;
+ case GL_LUMINANCE:
+ dstLuminanceIndex = 0;
+ dstRedIndex = dstGreenIndex = dstBlueIndex = dstAlphaIndex = -1;
+ dstIntensityIndex = -1;
+ break;
+ case GL_LUMINANCE_ALPHA:
+ dstLuminanceIndex = 0;
+ dstAlphaIndex = 1;
+ dstRedIndex = dstGreenIndex = dstBlueIndex = -1;
+ dstIntensityIndex = -1;
+ break;
+ case GL_INTENSITY:
+ dstIntensityIndex = 0;
+ dstRedIndex = dstGreenIndex = dstBlueIndex = dstAlphaIndex = -1;
+ dstLuminanceIndex = -1;
+ break;
+ case GL_RGB:
+ dstRedIndex = 0;
+ dstGreenIndex = 1;
+ dstBlueIndex = 2;
+ dstAlphaIndex = dstLuminanceIndex = dstIntensityIndex = -1;
+ break;
+ case GL_RGBA:
+ dstRedIndex = 0;
+ dstGreenIndex = 1;
+ dstBlueIndex = 2;
+ dstAlphaIndex = 3;
+ dstLuminanceIndex = dstIntensityIndex = -1;
+ break;
+ default:
+ _mesa_problem(ctx, "bad dstFormat in _mesa_unpack_color_span_float()");
+ return;
+ }
+
+ /* Now pack results in the requested dstFormat */
+ if (dstRedIndex >= 0) {
+ GLfloat *dst = dest;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[dstRedIndex] = rgba[i][RCOMP];
+ dst += dstComponents;
+ }
+ }
+
+ if (dstGreenIndex >= 0) {
+ GLfloat *dst = dest;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[dstGreenIndex] = rgba[i][GCOMP];
+ dst += dstComponents;
+ }
+ }
+
+ if (dstBlueIndex >= 0) {
+ GLfloat *dst = dest;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[dstBlueIndex] = rgba[i][BCOMP];
+ dst += dstComponents;
+ }
+ }
+
+ if (dstAlphaIndex >= 0) {
+ GLfloat *dst = dest;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[dstAlphaIndex] = rgba[i][ACOMP];
+ dst += dstComponents;
+ }
+ }
+
+ if (dstIntensityIndex >= 0) {
+ GLfloat *dst = dest;
+ GLuint i;
+ assert(dstIntensityIndex == 0);
+ assert(dstComponents == 1);
+ for (i = 0; i < n; i++) {
+ /* Intensity comes from red channel */
+ dst[i] = rgba[i][RCOMP];
+ }
+ }
+
+ if (dstLuminanceIndex >= 0) {
+ GLfloat *dst = dest;
+ GLuint i;
+ assert(dstLuminanceIndex == 0);
+ for (i = 0; i < n; i++) {
+ /* Luminance comes from red channel */
+ dst[0] = rgba[i][RCOMP];
+ dst += dstComponents;
+ }
+ }
+ }
+}
+
+
+/*
+ * Unpack a row of color index data from a client buffer according to
+ * the pixel unpacking parameters.
+ * This is (or will be) used by glDrawPixels, glTexImage[123]D, etc.
+ *
+ * Args: ctx - the context
+ * n - number of pixels
+ * dstType - destination data type
+ * dest - destination array
+ * srcType - source pixel type
+ * source - source data pointer
+ * srcPacking - pixel unpacking parameters
+ * transferOps - the pixel transfer operations to apply
+ */
+void
+_mesa_unpack_index_span( const GLcontext *ctx, GLuint n,
+ GLenum dstType, GLvoid *dest,
+ GLenum srcType, const GLvoid *source,
+ const struct gl_pixelstore_attrib *srcPacking,
+ GLuint transferOps )
+{
+ ASSERT(srcType == GL_BITMAP ||
+ srcType == GL_UNSIGNED_BYTE ||
+ srcType == GL_BYTE ||
+ srcType == GL_UNSIGNED_SHORT ||
+ srcType == GL_SHORT ||
+ srcType == GL_UNSIGNED_INT ||
+ srcType == GL_INT ||
+ srcType == GL_HALF_FLOAT_ARB ||
+ srcType == GL_FLOAT);
+
+ ASSERT(dstType == GL_UNSIGNED_BYTE ||
+ dstType == GL_UNSIGNED_SHORT ||
+ dstType == GL_UNSIGNED_INT);
+
+
+ transferOps &= (IMAGE_MAP_COLOR_BIT | IMAGE_SHIFT_OFFSET_BIT);
+
+ /*
+ * Try simple cases first
+ */
+ if (transferOps == 0 && srcType == GL_UNSIGNED_BYTE
+ && dstType == GL_UNSIGNED_BYTE) {
+ MEMCPY(dest, source, n * sizeof(GLubyte));
+ }
+ else if (transferOps == 0 && srcType == GL_UNSIGNED_INT
+ && dstType == GL_UNSIGNED_INT && !srcPacking->SwapBytes) {
+ MEMCPY(dest, source, n * sizeof(GLuint));
+ }
+ else {
+ /*
+ * general solution
+ */
+ GLuint indexes[MAX_WIDTH];
+ assert(n <= MAX_WIDTH);
+
+ extract_uint_indexes(n, indexes, GL_COLOR_INDEX, srcType, source,
+ srcPacking);
+
+ if (transferOps & IMAGE_SHIFT_OFFSET_BIT) {
+ /* shift and offset indexes */
+ _mesa_shift_and_offset_ci(ctx, n, indexes);
+ }
+ if (transferOps & IMAGE_MAP_COLOR_BIT) {
+ /* Apply lookup table */
+ _mesa_map_ci(ctx, n, indexes);
+ }
+
+ /* convert to dest type */
+ switch (dstType) {
+ case GL_UNSIGNED_BYTE:
+ {
+ GLubyte *dst = (GLubyte *) dest;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i] = (GLubyte) (indexes[i] & 0xff);
+ }
+ }
+ break;
+ case GL_UNSIGNED_SHORT:
+ {
+ GLuint *dst = (GLuint *) dest;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i] = (GLushort) (indexes[i] & 0xffff);
+ }
+ }
+ break;
+ case GL_UNSIGNED_INT:
+ MEMCPY(dest, indexes, n * sizeof(GLuint));
+ break;
+ default:
+ _mesa_problem(ctx, "bad dstType in _mesa_unpack_index_span");
+ }
+ }
+}
+
+
+void
+_mesa_pack_index_span( const GLcontext *ctx, GLuint n,
+ GLenum dstType, GLvoid *dest, const GLuint *source,
+ const struct gl_pixelstore_attrib *dstPacking,
+ GLuint transferOps )
+{
+ GLuint indexes[MAX_WIDTH];
+
+ ASSERT(n <= MAX_WIDTH);
+
+ transferOps &= (IMAGE_MAP_COLOR_BIT | IMAGE_SHIFT_OFFSET_BIT);
+
+ if (transferOps & (IMAGE_MAP_COLOR_BIT | IMAGE_SHIFT_OFFSET_BIT)) {
+ /* make a copy of input */
+ MEMCPY(indexes, source, n * sizeof(GLuint));
+ if (transferOps & IMAGE_SHIFT_OFFSET_BIT) {
+ _mesa_shift_and_offset_ci( ctx, n, indexes);
+ }
+ if (transferOps & IMAGE_MAP_COLOR_BIT) {
+ _mesa_map_ci(ctx, n, indexes);
+ }
+ source = indexes;
+ }
+
+ switch (dstType) {
+ case GL_UNSIGNED_BYTE:
+ {
+ GLubyte *dst = (GLubyte *) dest;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ *dst++ = (GLubyte) source[i];
+ }
+ }
+ break;
+ case GL_BYTE:
+ {
+ GLbyte *dst = (GLbyte *) dest;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i] = (GLbyte) source[i];
+ }
+ }
+ break;
+ case GL_UNSIGNED_SHORT:
+ {
+ GLushort *dst = (GLushort *) dest;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i] = (GLushort) source[i];
+ }
+ if (dstPacking->SwapBytes) {
+ _mesa_swap2( (GLushort *) dst, n );
+ }
+ }
+ break;
+ case GL_SHORT:
+ {
+ GLshort *dst = (GLshort *) dest;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i] = (GLshort) source[i];
+ }
+ if (dstPacking->SwapBytes) {
+ _mesa_swap2( (GLushort *) dst, n );
+ }
+ }
+ break;
+ case GL_UNSIGNED_INT:
+ {
+ GLuint *dst = (GLuint *) dest;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i] = (GLuint) source[i];
+ }
+ if (dstPacking->SwapBytes) {
+ _mesa_swap4( (GLuint *) dst, n );
+ }
+ }
+ break;
+ case GL_INT:
+ {
+ GLint *dst = (GLint *) dest;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i] = (GLint) source[i];
+ }
+ if (dstPacking->SwapBytes) {
+ _mesa_swap4( (GLuint *) dst, n );
+ }
+ }
+ break;
+ case GL_FLOAT:
+ {
+ GLfloat *dst = (GLfloat *) dest;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i] = (GLfloat) source[i];
+ }
+ if (dstPacking->SwapBytes) {
+ _mesa_swap4( (GLuint *) dst, n );
+ }
+ }
+ break;
+ case GL_HALF_FLOAT_ARB:
+ {
+ GLhalfARB *dst = (GLhalfARB *) dest;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i] = _mesa_float_to_half((GLfloat) source[i]);
+ }
+ if (dstPacking->SwapBytes) {
+ _mesa_swap2( (GLushort *) dst, n );
+ }
+ }
+ break;
+ default:
+ _mesa_problem(ctx, "bad type in _mesa_pack_index_span");
+ }
+}
+
+
+/*
+ * Unpack a row of stencil data from a client buffer according to
+ * the pixel unpacking parameters.
+ * This is (or will be) used by glDrawPixels
+ *
+ * Args: ctx - the context
+ * n - number of pixels
+ * dstType - destination data type
+ * dest - destination array
+ * srcType - source pixel type
+ * source - source data pointer
+ * srcPacking - pixel unpacking parameters
+ * transferOps - apply offset/bias/lookup ops?
+ */
+void
+_mesa_unpack_stencil_span( const GLcontext *ctx, GLuint n,
+ GLenum dstType, GLvoid *dest,
+ GLenum srcType, const GLvoid *source,
+ const struct gl_pixelstore_attrib *srcPacking,
+ GLuint transferOps )
+{
+ ASSERT(srcType == GL_BITMAP ||
+ srcType == GL_UNSIGNED_BYTE ||
+ srcType == GL_BYTE ||
+ srcType == GL_UNSIGNED_SHORT ||
+ srcType == GL_SHORT ||
+ srcType == GL_UNSIGNED_INT ||
+ srcType == GL_INT ||
+ srcType == GL_UNSIGNED_INT_24_8_EXT ||
+ srcType == GL_HALF_FLOAT_ARB ||
+ srcType == GL_FLOAT);
+
+ ASSERT(dstType == GL_UNSIGNED_BYTE ||
+ dstType == GL_UNSIGNED_SHORT ||
+ dstType == GL_UNSIGNED_INT);
+
+ /* only shift and offset apply to stencil */
+ transferOps &= IMAGE_SHIFT_OFFSET_BIT;
+
+ /*
+ * Try simple cases first
+ */
+ if (transferOps == 0 &&
+ srcType == GL_UNSIGNED_BYTE &&
+ dstType == GL_UNSIGNED_BYTE) {
+ MEMCPY(dest, source, n * sizeof(GLubyte));
+ }
+ else if (transferOps == 0 &&
+ srcType == GL_UNSIGNED_INT &&
+ dstType == GL_UNSIGNED_INT &&
+ !srcPacking->SwapBytes) {
+ MEMCPY(dest, source, n * sizeof(GLuint));
+ }
+ else {
+ /*
+ * general solution
+ */
+ GLuint indexes[MAX_WIDTH];
+ assert(n <= MAX_WIDTH);
+
+ extract_uint_indexes(n, indexes, GL_COLOR_INDEX, srcType, source,
+ srcPacking);
+
+ if (transferOps) {
+ if (transferOps & IMAGE_SHIFT_OFFSET_BIT) {
+ /* shift and offset indexes */
+ _mesa_shift_and_offset_ci(ctx, n, indexes);
+ }
+
+ if (ctx->Pixel.MapStencilFlag) {
+ /* Apply stencil lookup table */
+ GLuint mask = ctx->Pixel.MapStoSsize - 1;
+ GLuint i;
+ for (i=0;i<n;i++) {
+ indexes[i] = ctx->Pixel.MapStoS[ indexes[i] & mask ];
+ }
+ }
+ }
+
+ /* convert to dest type */
+ switch (dstType) {
+ case GL_UNSIGNED_BYTE:
+ {
+ GLubyte *dst = (GLubyte *) dest;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i] = (GLubyte) (indexes[i] & 0xff);
+ }
+ }
+ break;
+ case GL_UNSIGNED_SHORT:
+ {
+ GLuint *dst = (GLuint *) dest;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i] = (GLushort) (indexes[i] & 0xffff);
+ }
+ }
+ break;
+ case GL_UNSIGNED_INT:
+ MEMCPY(dest, indexes, n * sizeof(GLuint));
+ break;
+ default:
+ _mesa_problem(ctx, "bad dstType in _mesa_unpack_stencil_span");
+ }
+ }
+}
+
+
+void
+_mesa_pack_stencil_span( const GLcontext *ctx, GLuint n,
+ GLenum dstType, GLvoid *dest, const GLstencil *source,
+ const struct gl_pixelstore_attrib *dstPacking )
+{
+ GLstencil stencil[MAX_WIDTH];
+
+ ASSERT(n <= MAX_WIDTH);
+
+ if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset ||
+ ctx->Pixel.MapStencilFlag) {
+ /* make a copy of input */
+ MEMCPY(stencil, source, n * sizeof(GLstencil));
+ if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset) {
+ _mesa_shift_and_offset_stencil( ctx, n, stencil );
+ }
+ if (ctx->Pixel.MapStencilFlag) {
+ _mesa_map_stencil( ctx, n, stencil );
+ }
+ source = stencil;
+ }
+
+ switch (dstType) {
+ case GL_UNSIGNED_BYTE:
+ if (sizeof(GLstencil) == 8) {
+ MEMCPY( dest, source, n );
+ }
+ else {
+ GLubyte *dst = (GLubyte *) dest;
+ GLuint i;
+ for (i=0;i<n;i++) {
+ dst[i] = (GLubyte) source[i];
+ }
+ }
+ break;
+ case GL_BYTE:
+ if (sizeof(GLstencil) == 8) {
+ MEMCPY( dest, source, n );
+ }
+ else {
+ GLbyte *dst = (GLbyte *) dest;
+ GLuint i;
+ for (i=0;i<n;i++) {
+ dst[i] = (GLbyte) source[i];
+ }
+ }
+ break;
+ case GL_UNSIGNED_SHORT:
+ {
+ GLushort *dst = (GLushort *) dest;
+ GLuint i;
+ for (i=0;i<n;i++) {
+ dst[i] = (GLushort) source[i];
+ }
+ if (dstPacking->SwapBytes) {
+ _mesa_swap2( (GLushort *) dst, n );
+ }
+ }
+ break;
+ case GL_SHORT:
+ {
+ GLshort *dst = (GLshort *) dest;
+ GLuint i;
+ for (i=0;i<n;i++) {
+ dst[i] = (GLshort) source[i];
+ }
+ if (dstPacking->SwapBytes) {
+ _mesa_swap2( (GLushort *) dst, n );
+ }
+ }
+ break;
+ case GL_UNSIGNED_INT:
+ {
+ GLuint *dst = (GLuint *) dest;
+ GLuint i;
+ for (i=0;i<n;i++) {
+ dst[i] = (GLuint) source[i];
+ }
+ if (dstPacking->SwapBytes) {
+ _mesa_swap4( (GLuint *) dst, n );
+ }
+ }
+ break;
+ case GL_INT:
+ {
+ GLint *dst = (GLint *) dest;
+ GLuint i;
+ for (i=0;i<n;i++) {
+ *dst++ = (GLint) source[i];
+ }
+ if (dstPacking->SwapBytes) {
+ _mesa_swap4( (GLuint *) dst, n );
+ }
+ }
+ break;
+ case GL_FLOAT:
+ {
+ GLfloat *dst = (GLfloat *) dest;
+ GLuint i;
+ for (i=0;i<n;i++) {
+ dst[i] = (GLfloat) source[i];
+ }
+ if (dstPacking->SwapBytes) {
+ _mesa_swap4( (GLuint *) dst, n );
+ }
+ }
+ break;
+ case GL_HALF_FLOAT_ARB:
+ {
+ GLhalfARB *dst = (GLhalfARB *) dest;
+ GLuint i;
+ for (i=0;i<n;i++) {
+ dst[i] = _mesa_float_to_half( (float) source[i] );
+ }
+ if (dstPacking->SwapBytes) {
+ _mesa_swap2( (GLushort *) dst, n );
+ }
+ }
+ break;
+ case GL_BITMAP:
+ if (dstPacking->LsbFirst) {
+ GLubyte *dst = (GLubyte *) dest;
+ GLint shift = 0;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ if (shift == 0)
+ *dst = 0;
+ *dst |= ((source[i] != 0) << shift);
+ shift++;
+ if (shift == 8) {
+ shift = 0;
+ dst++;
+ }
+ }
+ }
+ else {
+ GLubyte *dst = (GLubyte *) dest;
+ GLint shift = 7;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ if (shift == 7)
+ *dst = 0;
+ *dst |= ((source[i] != 0) << shift);
+ shift--;
+ if (shift < 0) {
+ shift = 7;
+ dst++;
+ }
+ }
+ }
+ break;
+ default:
+ _mesa_problem(ctx, "bad type in _mesa_pack_index_span");
+ }
+}
+
+
+void
+_mesa_unpack_depth_span( const GLcontext *ctx, GLuint n,
+ GLenum dstType, GLvoid *dest, GLfloat depthScale,
+ GLenum srcType, const GLvoid *source,
+ const struct gl_pixelstore_attrib *srcPacking )
+{
+ GLfloat depthTemp[MAX_WIDTH], *depthValues;
+
+ if (dstType == GL_FLOAT) {
+ depthValues = (GLfloat *) dest;
+ }
+ else {
+ depthValues = depthTemp;
+ }
+
+ /* XXX we need to obey srcPacking->SwapBytes here!!! */
+ (void) srcPacking;
+
+ switch (srcType) {
+ case GL_BYTE:
+ {
+ GLuint i;
+ const GLubyte *src = (const GLubyte *) source;
+ for (i = 0; i < n; i++) {
+ depthValues[i] = BYTE_TO_FLOAT(src[i]);
+ }
+ }
+ break;
+ case GL_UNSIGNED_BYTE:
+ {
+ GLuint i;
+ const GLubyte *src = (const GLubyte *) source;
+ for (i = 0; i < n; i++) {
+ depthValues[i] = UBYTE_TO_FLOAT(src[i]);
+ }
+ }
+ break;
+ case GL_SHORT:
+ {
+ GLuint i;
+ const GLshort *src = (const GLshort *) source;
+ for (i = 0; i < n; i++) {
+ depthValues[i] = SHORT_TO_FLOAT(src[i]);
+ }
+ }
+ break;
+ case GL_UNSIGNED_SHORT:
+ {
+ GLuint i;
+ const GLushort *src = (const GLushort *) source;
+ for (i = 0; i < n; i++) {
+ depthValues[i] = USHORT_TO_FLOAT(src[i]);
+ }
+ }
+ break;
+ case GL_INT:
+ {
+ GLuint i;
+ const GLint *src = (const GLint *) source;
+ for (i = 0; i < n; i++) {
+ depthValues[i] = INT_TO_FLOAT(src[i]);
+ }
+ }
+ break;
+ case GL_UNSIGNED_INT:
+ {
+ GLuint i;
+ const GLuint *src = (const GLuint *) source;
+ for (i = 0; i < n; i++) {
+ depthValues[i] = UINT_TO_FLOAT(src[i]);
+ }
+ }
+ break;
+ case GL_UNSIGNED_INT_24_8_EXT: /* GL_EXT_packed_depth_stencil */
+ if (dstType == GL_UNSIGNED_INT && ctx->Pixel.DepthScale == 1.0 &&
+ ctx->Pixel.DepthBias == 0.0 && depthScale == (GLfloat) 0xffffff) {
+ const GLuint *src = (const GLuint *) source;
+ GLuint *zValues = (GLuint *) dest;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ zValues[i] = src[i] & 0xffffff00;
+ }
+ return;
+ }
+ else {
+ const GLuint *src = (const GLuint *) source;
+ const GLfloat scale = 1.0f / 0xffffff;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ depthValues[i] = (src[i] >> 8) * scale;
+ }
+ }
+ break;
+ case GL_FLOAT:
+ MEMCPY(depthValues, source, n * sizeof(GLfloat));
+ break;
+ case GL_HALF_FLOAT_ARB:
+ {
+ GLuint i;
+ const GLhalfARB *src = (const GLhalfARB *) source;
+ for (i = 0; i < n; i++) {
+ depthValues[i] = _mesa_half_to_float(src[i]);
+ }
+ }
+ break;
+ default:
+ _mesa_problem(NULL, "bad type in _mesa_unpack_depth_span()");
+ return;
+ }
+
+
+ /* apply depth scale and bias and clamp to [0,1] */
+ if (ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0) {
+ _mesa_scale_and_bias_depth(ctx, n, depthValues);
+ }
+
+ if (dstType == GL_UNSIGNED_INT) {
+ GLuint *zValues = (GLuint *) dest;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ zValues[i] = (GLuint) (depthValues[i] * depthScale);
+ }
+ }
+ else if (dstType == GL_UNSIGNED_SHORT) {
+ GLushort *zValues = (GLushort *) dest;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ zValues[i] = (GLushort) (depthValues[i] * depthScale);
+ }
+ }
+ else {
+ ASSERT(dstType == GL_FLOAT);
+ ASSERT(depthScale == 1.0F);
+ }
+}
+
+
+/*
+ * Pack an array of depth values. The values are floats in [0,1].
+ */
+void
+_mesa_pack_depth_span( const GLcontext *ctx, GLuint n, GLvoid *dest,
+ GLenum dstType, const GLfloat *depthSpan,
+ const struct gl_pixelstore_attrib *dstPacking )
+{
+ GLfloat depthCopy[MAX_WIDTH];
+
+ ASSERT(n <= MAX_WIDTH);
+
+ if (ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0) {
+ _mesa_memcpy(depthCopy, depthSpan, n * sizeof(GLfloat));
+ _mesa_scale_and_bias_depth(ctx, n, depthCopy);
+ depthSpan = depthCopy;
+ }
+
+ switch (dstType) {
+ case GL_UNSIGNED_BYTE:
+ {
+ GLubyte *dst = (GLubyte *) dest;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i] = FLOAT_TO_UBYTE( depthSpan[i] );
+ }
+ }
+ break;
+ case GL_BYTE:
+ {
+ GLbyte *dst = (GLbyte *) dest;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i] = FLOAT_TO_BYTE( depthSpan[i] );
+ }
+ }
+ break;
+ case GL_UNSIGNED_SHORT:
+ {
+ GLushort *dst = (GLushort *) dest;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ CLAMPED_FLOAT_TO_USHORT(dst[i], depthSpan[i]);
+ }
+ if (dstPacking->SwapBytes) {
+ _mesa_swap2( (GLushort *) dst, n );
+ }
+ }
+ break;
+ case GL_SHORT:
+ {
+ GLshort *dst = (GLshort *) dest;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i] = FLOAT_TO_SHORT( depthSpan[i] );
+ }
+ if (dstPacking->SwapBytes) {
+ _mesa_swap2( (GLushort *) dst, n );
+ }
+ }
+ break;
+ case GL_UNSIGNED_INT:
+ {
+ GLuint *dst = (GLuint *) dest;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i] = FLOAT_TO_UINT( depthSpan[i] );
+ }
+ if (dstPacking->SwapBytes) {
+ _mesa_swap4( (GLuint *) dst, n );
+ }
+ }
+ break;
+ case GL_INT:
+ {
+ GLint *dst = (GLint *) dest;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i] = FLOAT_TO_INT( depthSpan[i] );
+ }
+ if (dstPacking->SwapBytes) {
+ _mesa_swap4( (GLuint *) dst, n );
+ }
+ }
+ break;
+ case GL_FLOAT:
+ {
+ GLfloat *dst = (GLfloat *) dest;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i] = depthSpan[i];
+ }
+ if (dstPacking->SwapBytes) {
+ _mesa_swap4( (GLuint *) dst, n );
+ }
+ }
+ break;
+ case GL_HALF_FLOAT_ARB:
+ {
+ GLhalfARB *dst = (GLhalfARB *) dest;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i] = _mesa_float_to_half(depthSpan[i]);
+ }
+ if (dstPacking->SwapBytes) {
+ _mesa_swap2( (GLushort *) dst, n );
+ }
+ }
+ break;
+ default:
+ _mesa_problem(ctx, "bad type in _mesa_pack_depth_span");
+ }
+}
+
+
+
+/**
+ * Pack depth and stencil values as GL_DEPTH_STENCIL/GL_UNSIGNED_INT_24_8.
+ */
+void
+_mesa_pack_depth_stencil_span(const GLcontext *ctx, GLuint n, GLuint *dest,
+ const GLfloat *depthVals,
+ const GLstencil *stencilVals,
+ const struct gl_pixelstore_attrib *dstPacking)
+{
+ GLfloat depthCopy[MAX_WIDTH];
+ GLstencil stencilCopy[MAX_WIDTH];
+ GLuint i;
+
+ ASSERT(n <= MAX_WIDTH);
+
+ if (ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0) {
+ _mesa_memcpy(depthCopy, depthVals, n * sizeof(GLfloat));
+ _mesa_scale_and_bias_depth(ctx, n, depthCopy);
+ depthVals = depthCopy;
+ }
+
+ if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset) {
+ _mesa_memcpy(stencilCopy, stencilVals, n * sizeof(GLstencil));
+ _mesa_shift_and_offset_stencil(ctx, n, stencilCopy);
+ stencilVals = stencilCopy;
+ }
+ if (ctx->Pixel.MapStencilFlag) {
+ if (stencilVals != stencilCopy)
+ _mesa_memcpy(stencilCopy, stencilVals, n * sizeof(GLstencil));
+ _mesa_map_stencil(ctx, n, stencilCopy);
+ stencilVals = stencilCopy;
+ }
+
+ for (i = 0; i < n; i++) {
+ GLuint z = (GLuint) (depthVals[i] * 0xffffff);
+ dest[i] = (z << 8) | (stencilVals[i] & 0xff);
+ }
+
+ if (dstPacking->SwapBytes) {
+ _mesa_swap4(dest, n);
+ }
+}
+
+
+
+
+/**
+ * Unpack image data. Apply byte swapping, byte flipping (bitmap).
+ * Return all image data in a contiguous block. This is used when we
+ * compile glDrawPixels, glTexImage, etc into a display list. We
+ * need a copy of the data in a standard format.
+ */
+void *
+_mesa_unpack_image( GLuint dimensions,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type, const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *unpack )
+{
+ GLint bytesPerRow, compsPerRow;
+ GLboolean flipBytes, swap2, swap4;
+
+ if (!pixels)
+ return NULL; /* not necessarily an error */
+
+ if (width <= 0 || height <= 0 || depth <= 0)
+ return NULL; /* generate error later */
+
+ if (format == GL_BITMAP) {
+ bytesPerRow = (width + 7) >> 3;
+ flipBytes = !unpack->LsbFirst;
+ swap2 = swap4 = GL_FALSE;
+ compsPerRow = 0;
+ }
+ else {
+ const GLint bytesPerPixel = _mesa_bytes_per_pixel(format, type);
+ const GLint components = _mesa_components_in_format(format);
+ GLint bytesPerComp;
+ if (bytesPerPixel <= 0 || components <= 0)
+ return NULL; /* bad format or type. generate error later */
+ bytesPerRow = bytesPerPixel * width;
+ bytesPerComp = bytesPerPixel / components;
+ flipBytes = GL_FALSE;
+ swap2 = (bytesPerComp == 2) && unpack->SwapBytes;
+ swap4 = (bytesPerComp == 4) && unpack->SwapBytes;
+ compsPerRow = components * width;
+ assert(compsPerRow >= width);
+ }
+
+ {
+ GLubyte *destBuffer = (GLubyte *) MALLOC(bytesPerRow * height * depth);
+ GLubyte *dst;
+ GLint img, row;
+ if (!destBuffer)
+ return NULL; /* generate GL_OUT_OF_MEMORY later */
+
+ dst = destBuffer;
+ for (img = 0; img < depth; img++) {
+ for (row = 0; row < height; row++) {
+ const GLvoid *src = _mesa_image_address(dimensions, unpack, pixels,
+ width, height, format, type, img, row, 0);
+ MEMCPY(dst, src, bytesPerRow);
+ /* byte flipping/swapping */
+ if (flipBytes) {
+ flip_bytes((GLubyte *) dst, bytesPerRow);
+ }
+ else if (swap2) {
+ _mesa_swap2((GLushort*) dst, compsPerRow);
+ }
+ else if (swap4) {
+ _mesa_swap4((GLuint*) dst, compsPerRow);
+ }
+ dst += bytesPerRow;
+ }
+ }
+ return destBuffer;
+ }
+}
+
+#endif
+
+
+/**
+ * Perform clipping for glDrawPixels. The image's window position
+ * and size, and the unpack SkipPixels and SkipRows are adjusted so
+ * that the image region is entirely within the window and scissor bounds.
+ * NOTE: this will only work when glPixelZoom is (1, 1).
+ *
+ * \return GL_TRUE if image is ready for drawing or
+ * GL_FALSE if image was completely clipped away (draw nothing)
+ */
+GLboolean
+_mesa_clip_drawpixels(const GLcontext *ctx,
+ GLint *destX, GLint *destY,
+ GLsizei *width, GLsizei *height,
+ struct gl_pixelstore_attrib *unpack)
+{
+ const GLframebuffer *buffer = ctx->DrawBuffer;
+
+ if (unpack->RowLength == 0) {
+ unpack->RowLength = *width;
+ }
+
+ ASSERT(ctx->Pixel.ZoomX == 1.0F && ctx->Pixel.ZoomY == 1.0F);
+
+ /* left clipping */
+ if (*destX < buffer->_Xmin) {
+ unpack->SkipPixels += (buffer->_Xmin - *destX);
+ *width -= (buffer->_Xmin - *destX);
+ *destX = buffer->_Xmin;
+ }
+ /* right clipping */
+ if (*destX + *width > buffer->_Xmax)
+ *width -= (*destX + *width - buffer->_Xmax);
+
+ if (*width <= 0)
+ return GL_FALSE;
+
+ /* bottom clipping */
+ if (*destY < buffer->_Ymin) {
+ unpack->SkipRows += (buffer->_Ymin - *destY);
+ *height -= (buffer->_Ymin - *destY);
+ *destY = buffer->_Ymin;
+ }
+ /* top clipping */
+ if (*destY + *height > buffer->_Ymax)
+ *height -= (*destY + *height - buffer->_Ymax);
+
+ if (*height <= 0)
+ return GL_TRUE;
+
+ return GL_TRUE;
+}
+
+
+/**
+ * Perform clipping for glReadPixels. The image's window position
+ * and size, and the pack skipPixels, skipRows and rowLength are adjusted
+ * so that the image region is entirely within the window bounds.
+ * Note: this is different from _mesa_clip_drawpixels() in that the
+ * scissor box is ignored, and we use the bounds of the current readbuffer
+ * surface.
+ *
+ * \return GL_TRUE if image is ready for drawing or
+ * GL_FALSE if image was completely clipped away (draw nothing)
+ */
+GLboolean
+_mesa_clip_readpixels(const GLcontext *ctx,
+ GLint *srcX, GLint *srcY,
+ GLsizei *width, GLsizei *height,
+ struct gl_pixelstore_attrib *pack)
+{
+ const GLframebuffer *buffer = ctx->ReadBuffer;
+
+ if (pack->RowLength == 0) {
+ pack->RowLength = *width;
+ }
+
+ /* left clipping */
+ if (*srcX < 0) {
+ pack->SkipPixels += (0 - *srcX);
+ *width -= (0 - *srcX);
+ *srcX = 0;
+ }
+ /* right clipping */
+ if (*srcX + *width > (GLsizei) buffer->Width)
+ *width -= (*srcX + *width - buffer->Width);
+
+ if (*width <= 0)
+ return GL_FALSE;
+
+ /* bottom clipping */
+ if (*srcY < 0) {
+ pack->SkipRows += (0 - *srcY);
+ *height -= (0 - *srcY);
+ *srcY = 0;
+ }
+ /* top clipping */
+ if (*srcY + *height > (GLsizei) buffer->Height)
+ *height -= (*srcY + *height - buffer->Height);
+
+ if (*height <= 0)
+ return GL_TRUE;
+
+ return GL_TRUE;
+}
+
+
+/**
+ * Clip the rectangle defined by (x, y, width, height) against the bounds
+ * specified by [xmin, xmax) and [ymin, ymax).
+ * \return GL_FALSE if rect is totally clipped, GL_TRUE otherwise.
+ */
+GLboolean
+_mesa_clip_to_region(GLint xmin, GLint ymin,
+ GLint xmax, GLint ymax,
+ GLint *x, GLint *y,
+ GLsizei *width, GLsizei *height )
+{
+ /* left clipping */
+ if (*x < xmin) {
+ *width -= (xmin - *x);
+ *x = xmin;
+ }
+
+ /* right clipping */
+ if (*x + *width > xmax)
+ *width -= (*x + *width - xmax - 1);
+
+ if (*width <= 0)
+ return GL_FALSE;
+
+ /* bottom (or top) clipping */
+ if (*y < ymin) {
+ *height -= (ymin - *y);
+ *y = ymin;
+ }
+
+ /* top (or bottom) clipping */
+ if (*y + *height > ymax)
+ *height -= (*y + *height - ymax - 1);
+
+ if (*height <= 0)
+ return GL_FALSE;
+
+ return GL_TRUE;
+}
diff --git a/src/mesa/main/image.h b/src/mesa/main/image.h
new file mode 100644
index 00000000000..84faa03255e
--- /dev/null
+++ b/src/mesa/main/image.h
@@ -0,0 +1,225 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef IMAGE_H
+#define IMAGE_H
+
+
+#include "mtypes.h"
+
+
+extern void
+_mesa_swap2( GLushort *p, GLuint n );
+
+extern void
+_mesa_swap4( GLuint *p, GLuint n );
+
+extern GLint
+_mesa_sizeof_type( GLenum type );
+
+extern GLint
+_mesa_sizeof_packed_type( GLenum type );
+
+extern GLint
+_mesa_components_in_format( GLenum format );
+
+extern GLint
+_mesa_bytes_per_pixel( GLenum format, GLenum type );
+
+extern GLboolean
+_mesa_is_legal_format_and_type( GLcontext *ctx, GLenum format, GLenum type );
+
+
+extern GLvoid *
+_mesa_image_address( GLuint dimensions,
+ const struct gl_pixelstore_attrib *packing,
+ const GLvoid *image,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ GLint img, GLint row, GLint column );
+
+extern GLvoid *
+_mesa_image_address1d( const struct gl_pixelstore_attrib *packing,
+ const GLvoid *image,
+ GLsizei width,
+ GLenum format, GLenum type,
+ GLint column );
+
+extern GLvoid *
+_mesa_image_address2d( const struct gl_pixelstore_attrib *packing,
+ const GLvoid *image,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ GLint row, GLint column );
+
+extern GLvoid *
+_mesa_image_address3d( const struct gl_pixelstore_attrib *packing,
+ const GLvoid *image,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ GLint img, GLint row, GLint column );
+
+
+extern GLint
+_mesa_image_row_stride( const struct gl_pixelstore_attrib *packing,
+ GLint width, GLenum format, GLenum type );
+
+
+extern GLint
+_mesa_image_image_stride( const struct gl_pixelstore_attrib *packing,
+ GLint width, GLint height,
+ GLenum format, GLenum type );
+
+extern void
+_mesa_unpack_polygon_stipple( const GLubyte *pattern, GLuint dest[32],
+ const struct gl_pixelstore_attrib *unpacking );
+
+
+extern void
+_mesa_pack_polygon_stipple( const GLuint pattern[32], GLubyte *dest,
+ const struct gl_pixelstore_attrib *packing );
+
+
+extern GLvoid *
+_mesa_unpack_bitmap( GLint width, GLint height, const GLubyte *pixels,
+ const struct gl_pixelstore_attrib *packing );
+
+extern void
+_mesa_pack_bitmap( GLint width, GLint height, const GLubyte *source,
+ GLubyte *dest, const struct gl_pixelstore_attrib *packing );
+
+
+extern void
+_mesa_apply_rgba_transfer_ops(GLcontext *ctx, GLuint transferOps,
+ GLuint n, GLfloat rgba[][4]);
+
+extern void
+_mesa_pack_rgba_span_float( GLcontext *ctx,
+ GLuint n, CONST GLfloat rgba[][4],
+ GLenum dstFormat, GLenum dstType, GLvoid *dstAddr,
+ const struct gl_pixelstore_attrib *dstPacking,
+ GLuint transferOps );
+
+
+extern void
+_mesa_pack_rgba_span_chan( GLcontext *ctx,
+ GLuint n, CONST GLchan rgba[][4],
+ GLenum dstFormat, GLenum dstType, GLvoid *dstAddr,
+ const struct gl_pixelstore_attrib *dstPacking,
+ GLuint transferOps );
+
+
+extern void
+_mesa_unpack_color_span_chan( GLcontext *ctx,
+ GLuint n, GLenum dstFormat, GLchan dest[],
+ GLenum srcFormat, GLenum srcType,
+ const GLvoid *source,
+ const struct gl_pixelstore_attrib *srcPacking,
+ GLuint transferOps );
+
+
+extern void
+_mesa_unpack_color_span_float( GLcontext *ctx,
+ GLuint n, GLenum dstFormat, GLfloat dest[],
+ GLenum srcFormat, GLenum srcType,
+ const GLvoid *source,
+ const struct gl_pixelstore_attrib *srcPacking,
+ GLuint transferOps );
+
+
+extern void
+_mesa_unpack_index_span( const GLcontext *ctx, GLuint n,
+ GLenum dstType, GLvoid *dest,
+ GLenum srcType, const GLvoid *source,
+ const struct gl_pixelstore_attrib *srcPacking,
+ GLuint transferOps );
+
+
+extern void
+_mesa_pack_index_span( const GLcontext *ctx, GLuint n,
+ GLenum dstType, GLvoid *dest, const GLuint *source,
+ const struct gl_pixelstore_attrib *dstPacking,
+ GLuint transferOps );
+
+
+extern void
+_mesa_unpack_stencil_span( const GLcontext *ctx, GLuint n,
+ GLenum dstType, GLvoid *dest,
+ GLenum srcType, const GLvoid *source,
+ const struct gl_pixelstore_attrib *srcPacking,
+ GLuint transferOps );
+
+extern void
+_mesa_pack_stencil_span( const GLcontext *ctx, GLuint n,
+ GLenum dstType, GLvoid *dest, const GLstencil *source,
+ const struct gl_pixelstore_attrib *dstPacking );
+
+
+extern void
+_mesa_unpack_depth_span( const GLcontext *ctx, GLuint n,
+ GLenum dstType, GLvoid *dest, GLfloat depthScale,
+ GLenum srcType, const GLvoid *source,
+ const struct gl_pixelstore_attrib *srcPacking );
+
+extern void
+_mesa_pack_depth_span( const GLcontext *ctx, GLuint n, GLvoid *dest,
+ GLenum dstType, const GLfloat *depthSpan,
+ const struct gl_pixelstore_attrib *dstPacking );
+
+
+extern void
+_mesa_pack_depth_stencil_span(const GLcontext *ctx, GLuint n, GLuint *dest,
+ const GLfloat *depthVals,
+ const GLstencil *stencilVals,
+ const struct gl_pixelstore_attrib *dstPacking);
+
+
+extern void *
+_mesa_unpack_image( GLuint dimensions,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type, const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *unpack );
+
+
+extern GLboolean
+_mesa_clip_drawpixels(const GLcontext *ctx,
+ GLint *destX, GLint *destY,
+ GLsizei *width, GLsizei *height,
+ struct gl_pixelstore_attrib *unpack);
+
+
+extern GLboolean
+_mesa_clip_readpixels(const GLcontext *ctx,
+ GLint *destX, GLint *destY,
+ GLsizei *width, GLsizei *height,
+ struct gl_pixelstore_attrib *pack);
+
+extern GLboolean
+_mesa_clip_to_region(GLint xmin, GLint ymin,
+ GLint xmax, GLint ymax,
+ GLint *x, GLint *y,
+ GLsizei *width, GLsizei *height );
+
+#endif
diff --git a/src/mesa/main/imports.c b/src/mesa/main/imports.c
new file mode 100644
index 00000000000..afa5fc1c7f4
--- /dev/null
+++ b/src/mesa/main/imports.c
@@ -0,0 +1,1329 @@
+/**
+ * \file imports.c
+ * Standard C library function wrappers.
+ *
+ * Imports are services which the device driver or window system or
+ * operating system provides to the core renderer. The core renderer (Mesa)
+ * will call these functions in order to do memory allocation, simple I/O,
+ * etc.
+ *
+ * Some drivers will want to override/replace this file with something
+ * specialized, but that'll be rare.
+ *
+ * Eventually, I want to move roll the glheader.h file into this.
+ *
+ * The OpenGL SI's __GLimports structure allows per-context specification of
+ * replacements for the standard C lib functions. In practice that's probably
+ * never needed; compile-time replacements are far more likely.
+ *
+ * The _mesa_*() functions defined here don't in general take a context
+ * parameter. I guess we can change that someday, if need be.
+ * So for now, the __GLimports stuff really isn't used.
+ *
+ * \todo Functions still needed:
+ * - scanf
+ * - qsort
+ * - rand and RAND_MAX
+ *
+ * \note When compiled into a XFree86 module these functions wrap around
+ * XFree86 own wrappers.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+#include "imports.h"
+#include "context.h"
+#include "version.h"
+
+
+#define MAXSTRING 4000 /* for vsnprintf() */
+
+#ifdef WIN32
+#define vsnprintf _vsnprintf
+#elif defined(__IBMC__) || defined(__IBMCPP__) || ( defined(__VMS) && __CRTL_VER < 70312000 )
+extern int vsnprintf(char *str, size_t count, const char *fmt, va_list arg);
+#ifdef __VMS
+#include "vsnprintf.c"
+#endif
+#endif
+
+/* If we don't actually want to use the libcwrapper junk (even though we're
+ * building an Xorg server module), then just undef IN_MODULE to signal that to
+ * the following code. It's left around for now to allow compiling of newish
+ * Mesa with older servers, but this whole mess should go away at some point.
+ */
+#ifdef NO_LIBCWRAPPER
+#undef IN_MODULE
+#endif
+
+/**********************************************************************/
+/** \name Memory */
+/*@{*/
+
+/** Wrapper around either malloc() or xf86malloc() */
+void *
+_mesa_malloc(size_t bytes)
+{
+#if defined(XFree86LOADER) && defined(IN_MODULE)
+ return xf86malloc(bytes);
+#else
+ return malloc(bytes);
+#endif
+}
+
+/** Wrapper around either calloc() or xf86calloc() */
+void *
+_mesa_calloc(size_t bytes)
+{
+#if defined(XFree86LOADER) && defined(IN_MODULE)
+ return xf86calloc(1, bytes);
+#else
+ return calloc(1, bytes);
+#endif
+}
+
+/** Wrapper around either free() or xf86free() */
+void
+_mesa_free(void *ptr)
+{
+#if defined(XFree86LOADER) && defined(IN_MODULE)
+ xf86free(ptr);
+#else
+ free(ptr);
+#endif
+}
+
+/**
+ * Allocate aligned memory.
+ *
+ * \param bytes number of bytes to allocate.
+ * \param alignment alignment (must be greater than zero).
+ *
+ * Allocates extra memory to accommodate rounding up the address for
+ * alignment and to record the real malloc address.
+ *
+ * \sa _mesa_align_free().
+ */
+void *
+_mesa_align_malloc(size_t bytes, unsigned long alignment)
+{
+ uintptr_t ptr, buf;
+
+ ASSERT( alignment > 0 );
+
+ ptr = (uintptr_t) _mesa_malloc(bytes + alignment + sizeof(void *));
+ if (!ptr)
+ return NULL;
+
+ buf = (ptr + alignment + sizeof(void *)) & ~(uintptr_t)(alignment - 1);
+ *(uintptr_t *)(buf - sizeof(void *)) = ptr;
+
+#ifdef DEBUG
+ /* mark the non-aligned area */
+ while ( ptr < buf - sizeof(void *) ) {
+ *(unsigned long *)ptr = 0xcdcdcdcd;
+ ptr += sizeof(unsigned long);
+ }
+#endif
+
+ return (void *) buf;
+}
+
+/**
+ * Same as _mesa_align_malloc(), but using _mesa_calloc() instead of
+ * _mesa_malloc()
+ */
+void *
+_mesa_align_calloc(size_t bytes, unsigned long alignment)
+{
+ uintptr_t ptr, buf;
+
+ ASSERT( alignment > 0 );
+
+ ptr = (uintptr_t) _mesa_calloc(bytes + alignment + sizeof(void *));
+ if (!ptr)
+ return NULL;
+
+ buf = (ptr + alignment + sizeof(void *)) & ~(uintptr_t)(alignment - 1);
+ *(uintptr_t *)(buf - sizeof(void *)) = ptr;
+
+#ifdef DEBUG
+ /* mark the non-aligned area */
+ while ( ptr < buf - sizeof(void *) ) {
+ *(unsigned long *)ptr = 0xcdcdcdcd;
+ ptr += sizeof(unsigned long);
+ }
+#endif
+
+ return (void *)buf;
+}
+
+/**
+ * Free memory which was allocated with either _mesa_align_malloc()
+ * or _mesa_align_calloc().
+ * \param ptr pointer to the memory to be freed.
+ * The actual address to free is stored in the word immediately before the
+ * address the client sees.
+ */
+void
+_mesa_align_free(void *ptr)
+{
+#if 0
+ _mesa_free( (void *)(*(unsigned long *)((unsigned long)ptr - sizeof(void *))) );
+#else
+ void **cubbyHole = (void **) ((char *) ptr - sizeof(void *));
+ void *realAddr = *cubbyHole;
+ _mesa_free(realAddr);
+#endif
+}
+
+/** Reallocate memory */
+void *
+_mesa_realloc(void *oldBuffer, size_t oldSize, size_t newSize)
+{
+ const size_t copySize = (oldSize < newSize) ? oldSize : newSize;
+ void *newBuffer = _mesa_malloc(newSize);
+ if (newBuffer && oldBuffer && copySize > 0)
+ _mesa_memcpy(newBuffer, oldBuffer, copySize);
+ if (oldBuffer)
+ _mesa_free(oldBuffer);
+ return newBuffer;
+}
+
+/** memcpy wrapper */
+void *
+_mesa_memcpy(void *dest, const void *src, size_t n)
+{
+#if defined(XFree86LOADER) && defined(IN_MODULE)
+ return xf86memcpy(dest, src, n);
+#elif defined(SUNOS4)
+ return memcpy((char *) dest, (char *) src, (int) n);
+#else
+ return memcpy(dest, src, n);
+#endif
+}
+
+/** Wrapper around either memset() or xf86memset() */
+void
+_mesa_memset( void *dst, int val, size_t n )
+{
+#if defined(XFree86LOADER) && defined(IN_MODULE)
+ xf86memset( dst, val, n );
+#elif defined(SUNOS4)
+ memset( (char *) dst, (int) val, (int) n );
+#else
+ memset(dst, val, n);
+#endif
+}
+
+/**
+ * Fill memory with a constant 16bit word.
+ * \param dst destination pointer.
+ * \param val value.
+ * \param n number of words.
+ */
+void
+_mesa_memset16( unsigned short *dst, unsigned short val, size_t n )
+{
+ while (n-- > 0)
+ *dst++ = val;
+}
+
+/** Wrapper around either memcpy() or xf86memcpy() or bzero() */
+void
+_mesa_bzero( void *dst, size_t n )
+{
+#if defined(XFree86LOADER) && defined(IN_MODULE)
+ xf86memset( dst, 0, n );
+#elif defined(__FreeBSD__)
+ bzero( dst, n );
+#else
+ memset( dst, 0, n );
+#endif
+}
+
+/** Wrapper around either memcmp() or xf86memcmp() */
+int
+_mesa_memcmp( const void *s1, const void *s2, size_t n )
+{
+#if defined(XFree86LOADER) && defined(IN_MODULE)
+ return xf86memcmp( s1, s2, n );
+#elif defined(SUNOS4)
+ return memcmp( (char *) s1, (char *) s2, (int) n );
+#else
+ return memcmp(s1, s2, n);
+#endif
+}
+
+/*@}*/
+
+
+/**********************************************************************/
+/** \name Math */
+/*@{*/
+
+/** Wrapper around either sin() or xf86sin() */
+double
+_mesa_sin(double a)
+{
+#if defined(XFree86LOADER) && defined(IN_MODULE)
+ return xf86sin(a);
+#else
+ return sin(a);
+#endif
+}
+
+/** Single precision wrapper around either sin() or xf86sin() */
+float
+_mesa_sinf(float a)
+{
+#if defined(XFree86LOADER) && defined(IN_MODULE)
+ return (float) xf86sin((double) a);
+#else
+ return (float) sin((double) a);
+#endif
+}
+
+/** Wrapper around either cos() or xf86cos() */
+double
+_mesa_cos(double a)
+{
+#if defined(XFree86LOADER) && defined(IN_MODULE)
+ return xf86cos(a);
+#else
+ return cos(a);
+#endif
+}
+
+/** Single precision wrapper around either asin() or xf86asin() */
+float
+_mesa_asinf(float x)
+{
+#if defined(XFree86LOADER) && defined(IN_MODULE)
+ return (float) xf86asin((double) x);
+#else
+ return (float) asin((double) x);
+#endif
+}
+
+/** Single precision wrapper around either atan() or xf86atan() */
+float
+_mesa_atanf(float x)
+{
+#if defined(XFree86LOADER) && defined(IN_MODULE)
+ return (float) xf86atan((double) x);
+#else
+ return (float) atan((double) x);
+#endif
+}
+
+/** Wrapper around either sqrt() or xf86sqrt() */
+double
+_mesa_sqrtd(double x)
+{
+#if defined(XFree86LOADER) && defined(IN_MODULE)
+ return xf86sqrt(x);
+#else
+ return sqrt(x);
+#endif
+}
+
+
+/*
+ * A High Speed, Low Precision Square Root
+ * by Paul Lalonde and Robert Dawson
+ * from "Graphics Gems", Academic Press, 1990
+ *
+ * SPARC implementation of a fast square root by table
+ * lookup.
+ * SPARC floating point format is as follows:
+ *
+ * BIT 31 30 23 22 0
+ * sign exponent mantissa
+ */
+static short sqrttab[0x100]; /* declare table of square roots */
+
+static void init_sqrt_table(void)
+{
+#if defined(USE_IEEE) && !defined(DEBUG)
+ unsigned short i;
+ fi_type fi; /* to access the bits of a float in C quickly */
+ /* we use a union defined in glheader.h */
+
+ for(i=0; i<= 0x7f; i++) {
+ fi.i = 0;
+
+ /*
+ * Build a float with the bit pattern i as mantissa
+ * and an exponent of 0, stored as 127
+ */
+
+ fi.i = (i << 16) | (127 << 23);
+ fi.f = _mesa_sqrtd(fi.f);
+
+ /*
+ * Take the square root then strip the first 7 bits of
+ * the mantissa into the table
+ */
+
+ sqrttab[i] = (fi.i & 0x7fffff) >> 16;
+
+ /*
+ * Repeat the process, this time with an exponent of
+ * 1, stored as 128
+ */
+
+ fi.i = 0;
+ fi.i = (i << 16) | (128 << 23);
+ fi.f = sqrt(fi.f);
+ sqrttab[i+0x80] = (fi.i & 0x7fffff) >> 16;
+ }
+#else
+ (void) sqrttab; /* silence compiler warnings */
+#endif /*HAVE_FAST_MATH*/
+}
+
+
+/**
+ * Single precision square root.
+ */
+float
+_mesa_sqrtf( float x )
+{
+#if defined(USE_IEEE) && !defined(DEBUG)
+ fi_type num;
+ /* to access the bits of a float in C
+ * we use a union from glheader.h */
+
+ short e; /* the exponent */
+ if (x == 0.0F) return 0.0F; /* check for square root of 0 */
+ num.f = x;
+ e = (num.i >> 23) - 127; /* get the exponent - on a SPARC the */
+ /* exponent is stored with 127 added */
+ num.i &= 0x7fffff; /* leave only the mantissa */
+ if (e & 0x01) num.i |= 0x800000;
+ /* the exponent is odd so we have to */
+ /* look it up in the second half of */
+ /* the lookup table, so we set the */
+ /* high bit */
+ e >>= 1; /* divide the exponent by two */
+ /* note that in C the shift */
+ /* operators are sign preserving */
+ /* for signed operands */
+ /* Do the table lookup, based on the quaternary mantissa,
+ * then reconstruct the result back into a float
+ */
+ num.i = ((sqrttab[num.i >> 16]) << 16) | ((e + 127) << 23);
+
+ return num.f;
+#else
+ return (float) _mesa_sqrtd((double) x);
+#endif
+}
+
+
+/**
+ inv_sqrt - A single precision 1/sqrt routine for IEEE format floats.
+ written by Josh Vanderhoof, based on newsgroup posts by James Van Buskirk
+ and Vesa Karvonen.
+*/
+float
+_mesa_inv_sqrtf(float n)
+{
+#if defined(USE_IEEE) && !defined(DEBUG)
+ float r0, x0, y0;
+ float r1, x1, y1;
+ float r2, x2, y2;
+#if 0 /* not used, see below -BP */
+ float r3, x3, y3;
+#endif
+ union { float f; unsigned int i; } u;
+ unsigned int magic;
+
+ /*
+ Exponent part of the magic number -
+
+ We want to:
+ 1. subtract the bias from the exponent,
+ 2. negate it
+ 3. divide by two (rounding towards -inf)
+ 4. add the bias back
+
+ Which is the same as subtracting the exponent from 381 and dividing
+ by 2.
+
+ floor(-(x - 127) / 2) + 127 = floor((381 - x) / 2)
+ */
+
+ magic = 381 << 23;
+
+ /*
+ Significand part of magic number -
+
+ With the current magic number, "(magic - u.i) >> 1" will give you:
+
+ for 1 <= u.f <= 2: 1.25 - u.f / 4
+ for 2 <= u.f <= 4: 1.00 - u.f / 8
+
+ This isn't a bad approximation of 1/sqrt. The maximum difference from
+ 1/sqrt will be around .06. After three Newton-Raphson iterations, the
+ maximum difference is less than 4.5e-8. (Which is actually close
+ enough to make the following bias academic...)
+
+ To get a better approximation you can add a bias to the magic
+ number. For example, if you subtract 1/2 of the maximum difference in
+ the first approximation (.03), you will get the following function:
+
+ for 1 <= u.f <= 2: 1.22 - u.f / 4
+ for 2 <= u.f <= 3.76: 0.97 - u.f / 8
+ for 3.76 <= u.f <= 4: 0.72 - u.f / 16
+ (The 3.76 to 4 range is where the result is < .5.)
+
+ This is the closest possible initial approximation, but with a maximum
+ error of 8e-11 after three NR iterations, it is still not perfect. If
+ you subtract 0.0332281 instead of .03, the maximum error will be
+ 2.5e-11 after three NR iterations, which should be about as close as
+ is possible.
+
+ for 1 <= u.f <= 2: 1.2167719 - u.f / 4
+ for 2 <= u.f <= 3.73: 0.9667719 - u.f / 8
+ for 3.73 <= u.f <= 4: 0.7167719 - u.f / 16
+
+ */
+
+ magic -= (int)(0.0332281 * (1 << 25));
+
+ u.f = n;
+ u.i = (magic - u.i) >> 1;
+
+ /*
+ Instead of Newton-Raphson, we use Goldschmidt's algorithm, which
+ allows more parallelism. From what I understand, the parallelism
+ comes at the cost of less precision, because it lets error
+ accumulate across iterations.
+ */
+ x0 = 1.0f;
+ y0 = 0.5f * n;
+ r0 = u.f;
+
+ x1 = x0 * r0;
+ y1 = y0 * r0 * r0;
+ r1 = 1.5f - y1;
+
+ x2 = x1 * r1;
+ y2 = y1 * r1 * r1;
+ r2 = 1.5f - y2;
+
+#if 1
+ return x2 * r2; /* we can stop here, and be conformant -BP */
+#else
+ x3 = x2 * r2;
+ y3 = y2 * r2 * r2;
+ r3 = 1.5f - y3;
+
+ return x3 * r3;
+#endif
+#elif defined(XFree86LOADER) && defined(IN_MODULE)
+ return 1.0F / xf86sqrt(n);
+#else
+ return (float) (1.0 / sqrt(n));
+#endif
+}
+
+
+/**
+ * Wrapper around either pow() or xf86pow().
+ */
+double
+_mesa_pow(double x, double y)
+{
+#if defined(XFree86LOADER) && defined(IN_MODULE)
+ return xf86pow(x, y);
+#else
+ return pow(x, y);
+#endif
+}
+
+
+/**
+ * Find the first bit set in a word.
+ */
+int
+_mesa_ffs(int i)
+{
+#if (defined(_WIN32) && !defined(__MINGW32__) ) || defined(__IBMC__) || defined(__IBMCPP__)
+ register int bit = 0;
+ if (i != 0) {
+ if ((i & 0xffff) == 0) {
+ bit += 16;
+ i >>= 16;
+ }
+ if ((i & 0xff) == 0) {
+ bit += 8;
+ i >>= 8;
+ }
+ if ((i & 0xf) == 0) {
+ bit += 4;
+ i >>= 4;
+ }
+ while ((i & 1) == 0) {
+ bit++;
+ i >>= 1;
+ }
+ }
+ return bit;
+#elif defined(XFree86LOADER) && defined(IN_MODULE)
+ return xf86ffs(i);
+#else
+ return ffs(i);
+#endif
+}
+
+
+/**
+ * Return number of bits set in given GLuint.
+ */
+unsigned int
+_mesa_bitcount(unsigned int n)
+{
+ unsigned int bits;
+ for (bits = 0; n > 0; n = n >> 1) {
+ bits += (n & 1);
+ }
+ return bits;
+}
+
+
+/**
+ * Convert a 4-byte float to a 2-byte half float.
+ * Based on code from:
+ * http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/008786.html
+ */
+GLhalfARB
+_mesa_float_to_half(float val)
+{
+ const int flt = *((int *) (void *) &val);
+ const int flt_m = flt & 0x7fffff;
+ const int flt_e = (flt >> 23) & 0xff;
+ const int flt_s = (flt >> 31) & 0x1;
+ int s, e, m = 0;
+ GLhalfARB result;
+
+ /* sign bit */
+ s = flt_s;
+
+ /* handle special cases */
+ if ((flt_e == 0) && (flt_m == 0)) {
+ /* zero */
+ /* m = 0; - already set */
+ e = 0;
+ }
+ else if ((flt_e == 0) && (flt_m != 0)) {
+ /* denorm -- denorm float maps to 0 half */
+ /* m = 0; - already set */
+ e = 0;
+ }
+ else if ((flt_e == 0xff) && (flt_m == 0)) {
+ /* infinity */
+ /* m = 0; - already set */
+ e = 31;
+ }
+ else if ((flt_e == 0xff) && (flt_m != 0)) {
+ /* NaN */
+ m = 1;
+ e = 31;
+ }
+ else {
+ /* regular number */
+ const int new_exp = flt_e - 127;
+ if (new_exp < -24) {
+ /* this maps to 0 */
+ /* m = 0; - already set */
+ e = 0;
+ }
+ else if (new_exp < -14) {
+ /* this maps to a denorm */
+ unsigned int exp_val = (unsigned int) (-14 - new_exp); /* 2^-exp_val*/
+ e = 0;
+ switch (exp_val) {
+ case 0:
+ _mesa_warning(NULL,
+ "float_to_half: logical error in denorm creation!\n");
+ /* m = 0; - already set */
+ break;
+ case 1: m = 512 + (flt_m >> 14); break;
+ case 2: m = 256 + (flt_m >> 15); break;
+ case 3: m = 128 + (flt_m >> 16); break;
+ case 4: m = 64 + (flt_m >> 17); break;
+ case 5: m = 32 + (flt_m >> 18); break;
+ case 6: m = 16 + (flt_m >> 19); break;
+ case 7: m = 8 + (flt_m >> 20); break;
+ case 8: m = 4 + (flt_m >> 21); break;
+ case 9: m = 2 + (flt_m >> 22); break;
+ case 10: m = 1; break;
+ }
+ }
+ else if (new_exp > 15) {
+ /* map this value to infinity */
+ /* m = 0; - already set */
+ e = 31;
+ }
+ else {
+ /* regular */
+ e = new_exp + 15;
+ m = flt_m >> 13;
+ }
+ }
+
+ result = (s << 15) | (e << 10) | m;
+ return result;
+}
+
+
+/**
+ * Convert a 2-byte half float to a 4-byte float.
+ * Based on code from:
+ * http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/008786.html
+ */
+float
+_mesa_half_to_float(GLhalfARB val)
+{
+ /* XXX could also use a 64K-entry lookup table */
+ const int m = val & 0x3ff;
+ const int e = (val >> 10) & 0x1f;
+ const int s = (val >> 15) & 0x1;
+ int flt_m, flt_e, flt_s, flt;
+ float result;
+
+ /* sign bit */
+ flt_s = s;
+
+ /* handle special cases */
+ if ((e == 0) && (m == 0)) {
+ /* zero */
+ flt_m = 0;
+ flt_e = 0;
+ }
+ else if ((e == 0) && (m != 0)) {
+ /* denorm -- denorm half will fit in non-denorm single */
+ const float half_denorm = 1.0f / 16384.0f; /* 2^-14 */
+ float mantissa = ((float) (m)) / 1024.0f;
+ float sign = s ? -1.0f : 1.0f;
+ return sign * mantissa * half_denorm;
+ }
+ else if ((e == 31) && (m == 0)) {
+ /* infinity */
+ flt_e = 0xff;
+ flt_m = 0;
+ }
+ else if ((e == 31) && (m != 0)) {
+ /* NaN */
+ flt_e = 0xff;
+ flt_m = 1;
+ }
+ else {
+ /* regular */
+ flt_e = e + 112;
+ flt_m = m << 13;
+ }
+
+ flt = (flt_s << 31) | (flt_e << 23) | flt_m;
+ result = *((float *) (void *) &flt);
+ return result;
+}
+
+/*@}*/
+
+
+/**********************************************************************/
+/** \name Sort & Search */
+/*@{*/
+
+/**
+ * Wrapper for bsearch().
+ */
+void *
+_mesa_bsearch( const void *key, const void *base, size_t nmemb, size_t size,
+ int (*compar)(const void *, const void *) )
+{
+#if defined(XFree86LOADER) && defined(IN_MODULE)
+ return xf86bsearch(key, base, nmemb, size, compar);
+#else
+ return bsearch(key, base, nmemb, size, compar);
+#endif
+}
+
+/*@}*/
+
+
+/**********************************************************************/
+/** \name Environment vars */
+/*@{*/
+
+/**
+ * Wrapper for getenv().
+ */
+char *
+_mesa_getenv( const char *var )
+{
+#if defined(XFree86LOADER) && defined(IN_MODULE)
+ return xf86getenv(var);
+#elif defined(_XBOX)
+ return NULL;
+#else
+ return getenv(var);
+#endif
+}
+
+/*@}*/
+
+
+/**********************************************************************/
+/** \name String */
+/*@{*/
+
+/** Wrapper around either strstr() or xf86strstr() */
+char *
+_mesa_strstr( const char *haystack, const char *needle )
+{
+#if defined(XFree86LOADER) && defined(IN_MODULE)
+ return xf86strstr(haystack, needle);
+#else
+ return strstr(haystack, needle);
+#endif
+}
+
+/** Wrapper around either strncat() or xf86strncat() */
+char *
+_mesa_strncat( char *dest, const char *src, size_t n )
+{
+#if defined(XFree86LOADER) && defined(IN_MODULE)
+ return xf86strncat(dest, src, n);
+#else
+ return strncat(dest, src, n);
+#endif
+}
+
+/** Wrapper around either strcpy() or xf86strcpy() */
+char *
+_mesa_strcpy( char *dest, const char *src )
+{
+#if defined(XFree86LOADER) && defined(IN_MODULE)
+ return xf86strcpy(dest, src);
+#else
+ return strcpy(dest, src);
+#endif
+}
+
+/** Wrapper around either strncpy() or xf86strncpy() */
+char *
+_mesa_strncpy( char *dest, const char *src, size_t n )
+{
+#if defined(XFree86LOADER) && defined(IN_MODULE)
+ return xf86strncpy(dest, src, n);
+#else
+ return strncpy(dest, src, n);
+#endif
+}
+
+/** Wrapper around either strlen() or xf86strlen() */
+size_t
+_mesa_strlen( const char *s )
+{
+#if defined(XFree86LOADER) && defined(IN_MODULE)
+ return xf86strlen(s);
+#else
+ return strlen(s);
+#endif
+}
+
+/** Wrapper around either strcmp() or xf86strcmp() */
+int
+_mesa_strcmp( const char *s1, const char *s2 )
+{
+#if defined(XFree86LOADER) && defined(IN_MODULE)
+ return xf86strcmp(s1, s2);
+#else
+ return strcmp(s1, s2);
+#endif
+}
+
+/** Wrapper around either strncmp() or xf86strncmp() */
+int
+_mesa_strncmp( const char *s1, const char *s2, size_t n )
+{
+#if defined(XFree86LOADER) && defined(IN_MODULE)
+ return xf86strncmp(s1, s2, n);
+#else
+ return strncmp(s1, s2, n);
+#endif
+}
+
+/** Implemented using _mesa_malloc() and _mesa_strcpy */
+char *
+_mesa_strdup( const char *s )
+{
+ size_t l = _mesa_strlen(s);
+ char *s2 = (char *) _mesa_malloc(l + 1);
+ if (s2)
+ _mesa_strcpy(s2, s);
+ return s2;
+}
+
+/** Wrapper around either atoi() or xf86atoi() */
+int
+_mesa_atoi(const char *s)
+{
+#if defined(XFree86LOADER) && defined(IN_MODULE)
+ return xf86atoi(s);
+#else
+ return atoi(s);
+#endif
+}
+
+/** Wrapper around either strtod() or xf86strtod() */
+double
+_mesa_strtod( const char *s, char **end )
+{
+#if defined(XFree86LOADER) && defined(IN_MODULE)
+ return xf86strtod(s, end);
+#else
+ return strtod(s, end);
+#endif
+}
+
+/*@}*/
+
+
+/**********************************************************************/
+/** \name I/O */
+/*@{*/
+
+/** Wrapper around either vsprintf() or xf86vsprintf() */
+int
+_mesa_sprintf( char *str, const char *fmt, ... )
+{
+ int r;
+ va_list args;
+ va_start( args, fmt );
+#if defined(XFree86LOADER) && defined(IN_MODULE)
+ r = xf86vsprintf( str, fmt, args );
+#else
+ r = vsprintf( str, fmt, args );
+#endif
+ va_end( args );
+ return r;
+}
+
+/** Wrapper around either printf() or xf86printf(), using vsprintf() for
+ * the formatting. */
+void
+_mesa_printf( const char *fmtString, ... )
+{
+ char s[MAXSTRING];
+ va_list args;
+ va_start( args, fmtString );
+ vsnprintf(s, MAXSTRING, fmtString, args);
+ va_end( args );
+#if defined(XFree86LOADER) && defined(IN_MODULE)
+ xf86printf("%s", s);
+#else
+ fprintf(stderr,"%s", s);
+#endif
+}
+
+/** Wrapper around either vsprintf() or xf86vsprintf() */
+int
+_mesa_vsprintf( char *str, const char *fmt, va_list args )
+{
+#if defined(XFree86LOADER) && defined(IN_MODULE)
+ return xf86vsprintf( str, fmt, args );
+#else
+ return vsprintf( str, fmt, args );
+#endif
+}
+
+/*@}*/
+
+
+/**********************************************************************/
+/** \name Diagnostics */
+/*@{*/
+
+/**
+ * Display a warning.
+ *
+ * \param ctx GL context.
+ * \param fmtString printf() alike format string.
+ *
+ * If debugging is enabled (either at compile-time via the DEBUG macro, or
+ * run-time via the MESA_DEBUG environment variable), prints the warning to
+ * stderr, either via fprintf() or xf86printf().
+ */
+void
+_mesa_warning( GLcontext *ctx, const char *fmtString, ... )
+{
+ GLboolean debug;
+ char str[MAXSTRING];
+ va_list args;
+ (void) ctx;
+ va_start( args, fmtString );
+ (void) vsnprintf( str, MAXSTRING, fmtString, args );
+ va_end( args );
+#ifdef DEBUG
+ debug = GL_TRUE; /* always print warning */
+#else
+ debug = _mesa_getenv("MESA_DEBUG") ? GL_TRUE : GL_FALSE;
+#endif
+ if (debug) {
+#if defined(XFree86LOADER) && defined(IN_MODULE)
+ xf86fprintf(stderr, "Mesa warning: %s\n", str);
+#else
+ fprintf(stderr, "Mesa warning: %s\n", str);
+#endif
+ }
+}
+
+/**
+ * This function is called when the Mesa user has stumbled into a code
+ * path which may not be implemented fully or correctly.
+ *
+ * \param ctx GL context.
+ * \param s problem description string.
+ *
+ * Prints the message to stderr, either via fprintf() or xf86fprintf().
+ */
+void
+_mesa_problem( const GLcontext *ctx, const char *fmtString, ... )
+{
+ va_list args;
+ char str[MAXSTRING];
+ (void) ctx;
+
+ va_start( args, fmtString );
+ vsnprintf( str, MAXSTRING, fmtString, args );
+ va_end( args );
+
+#if defined(XFree86LOADER) && defined(IN_MODULE)
+ xf86fprintf(stderr, "Mesa %s implementation error: %s\n", MESA_VERSION_STRING, str);
+ xf86fprintf(stderr, "Please report at bugzilla.freedesktop.org\n");
+#else
+ fprintf(stderr, "Mesa %s implementation error: %s\n", MESA_VERSION_STRING, str);
+ fprintf(stderr, "Please report at bugzilla.freedesktop.org\n");
+#endif
+}
+
+/**
+ * Display an error message.
+ *
+ * If in debug mode, print error message.
+ * Also, record the error code by calling _mesa_record_error().
+ *
+ * \param ctx the GL context.
+ * \param error the error value.
+ * \param fmtString printf() style format string, followed by optional args
+ *
+ * If debugging is enabled (either at compile-time via the DEBUG macro, or
+ * run-time via the MESA_DEBUG environment variable), interperts the error code and
+ * prints the error message via _mesa_debug().
+ */
+void
+_mesa_error( GLcontext *ctx, GLenum error, const char *fmtString, ... )
+{
+ const char *debugEnv;
+ GLboolean debug;
+
+ debugEnv = _mesa_getenv("MESA_DEBUG");
+
+#ifdef DEBUG
+ if (debugEnv && _mesa_strstr(debugEnv, "silent"))
+ debug = GL_FALSE;
+ else
+ debug = GL_TRUE;
+#else
+ if (debugEnv)
+ debug = GL_TRUE;
+ else
+ debug = GL_FALSE;
+#endif
+
+ if (debug) {
+ va_list args;
+ char where[MAXSTRING];
+ const char *errstr;
+
+ va_start( args, fmtString );
+ vsnprintf( where, MAXSTRING, fmtString, args );
+ va_end( args );
+
+ switch (error) {
+ case GL_NO_ERROR:
+ errstr = "GL_NO_ERROR";
+ break;
+ case GL_INVALID_VALUE:
+ errstr = "GL_INVALID_VALUE";
+ break;
+ case GL_INVALID_ENUM:
+ errstr = "GL_INVALID_ENUM";
+ break;
+ case GL_INVALID_OPERATION:
+ errstr = "GL_INVALID_OPERATION";
+ break;
+ case GL_STACK_OVERFLOW:
+ errstr = "GL_STACK_OVERFLOW";
+ break;
+ case GL_STACK_UNDERFLOW:
+ errstr = "GL_STACK_UNDERFLOW";
+ break;
+ case GL_OUT_OF_MEMORY:
+ errstr = "GL_OUT_OF_MEMORY";
+ break;
+ case GL_TABLE_TOO_LARGE:
+ errstr = "GL_TABLE_TOO_LARGE";
+ break;
+ case GL_INVALID_FRAMEBUFFER_OPERATION_EXT:
+ errstr = "GL_INVALID_FRAMEBUFFER_OPERATION";
+ break;
+ default:
+ errstr = "unknown";
+ break;
+ }
+ _mesa_debug(ctx, "User error: %s in %s\n", errstr, where);
+ }
+
+ _mesa_record_error(ctx, error);
+}
+
+/**
+ * Report debug information.
+ *
+ * \param ctx GL context.
+ * \param fmtString printf() alike format string.
+ *
+ * Prints the message to stderr, either via fprintf() or xf86printf().
+ */
+void
+_mesa_debug( const GLcontext *ctx, const char *fmtString, ... )
+{
+ char s[MAXSTRING];
+ va_list args;
+ (void) ctx;
+ va_start(args, fmtString);
+ vsnprintf(s, MAXSTRING, fmtString, args);
+ va_end(args);
+#if defined(XFree86LOADER) && defined(IN_MODULE)
+ xf86fprintf(stderr, "Mesa: %s", s);
+#else
+ fprintf(stderr, "Mesa: %s", s);
+#endif
+}
+
+/*@}*/
+
+
+/**********************************************************************/
+/** \name Exit */
+/*@{*/
+
+/**
+ * Wrapper for exit().
+ */
+void
+_mesa_exit( int status )
+{
+#if defined(XFree86LOADER) && defined(IN_MODULE)
+ xf86exit(status);
+#else
+ exit(status);
+#endif
+}
+
+/*@}*/
+
+
+/**********************************************************************/
+/** \name Default Imports Wrapper */
+/*@{*/
+
+/** Wrapper around _mesa_malloc() */
+static void *
+default_malloc(__GLcontext *gc, size_t size)
+{
+ (void) gc;
+ return _mesa_malloc(size);
+}
+
+/** Wrapper around _mesa_malloc() */
+static void *
+default_calloc(__GLcontext *gc, size_t numElem, size_t elemSize)
+{
+ (void) gc;
+ return _mesa_calloc(numElem * elemSize);
+}
+
+/** Wrapper around either realloc() or xf86realloc() */
+static void *
+default_realloc(__GLcontext *gc, void *oldAddr, size_t newSize)
+{
+ (void) gc;
+#if defined(XFree86LOADER) && defined(IN_MODULE)
+ return xf86realloc(oldAddr, newSize);
+#else
+ return realloc(oldAddr, newSize);
+#endif
+}
+
+/** Wrapper around _mesa_free() */
+static void
+default_free(__GLcontext *gc, void *addr)
+{
+ (void) gc;
+ _mesa_free(addr);
+}
+
+/** Wrapper around _mesa_getenv() */
+static char * CAPI
+default_getenv( __GLcontext *gc, const char *var )
+{
+ (void) gc;
+ return _mesa_getenv(var);
+}
+
+/** Wrapper around _mesa_warning() */
+static void
+default_warning(__GLcontext *gc, char *str)
+{
+ _mesa_warning(gc, str);
+}
+
+/** Wrapper around _mesa_problem() */
+static void
+default_fatal(__GLcontext *gc, char *str)
+{
+ _mesa_problem(gc, str);
+ abort();
+}
+
+/** Wrapper around atoi() */
+static int CAPI
+default_atoi(__GLcontext *gc, const char *str)
+{
+ (void) gc;
+ return atoi(str);
+}
+
+/** Wrapper around vsprintf() */
+static int CAPI
+default_sprintf(__GLcontext *gc, char *str, const char *fmt, ...)
+{
+ int r;
+ va_list args;
+ (void) gc;
+ va_start( args, fmt );
+ r = vsprintf( str, fmt, args );
+ va_end( args );
+ return r;
+}
+
+/** Wrapper around fopen() */
+static void * CAPI
+default_fopen(__GLcontext *gc, const char *path, const char *mode)
+{
+ (void) gc;
+ return fopen(path, mode);
+}
+
+/** Wrapper around fclose() */
+static int CAPI
+default_fclose(__GLcontext *gc, void *stream)
+{
+ (void) gc;
+ return fclose((FILE *) stream);
+}
+
+/** Wrapper around vfprintf() */
+static int CAPI
+default_fprintf(__GLcontext *gc, void *stream, const char *fmt, ...)
+{
+ int r;
+ va_list args;
+ (void) gc;
+ va_start( args, fmt );
+ r = vfprintf( (FILE *) stream, fmt, args );
+ va_end( args );
+ return r;
+}
+
+/**
+ * \todo this really is driver-specific and can't be here
+ */
+static __GLdrawablePrivate *
+default_GetDrawablePrivate(__GLcontext *gc)
+{
+ (void) gc;
+ return NULL;
+}
+
+/*@}*/
+
+
+/**
+ * Initialize a __GLimports object to point to the functions in this
+ * file.
+ *
+ * This is to be called from device drivers.
+ *
+ * Also, do some one-time initializations.
+ *
+ * \param imports the object to initialize.
+ * \param driverCtx pointer to device driver-specific data.
+ */
+void
+_mesa_init_default_imports(__GLimports *imports, void *driverCtx)
+{
+ /* XXX maybe move this one-time init stuff into context.c */
+ static GLboolean initialized = GL_FALSE;
+ if (!initialized) {
+ init_sqrt_table();
+ initialized = GL_TRUE;
+ }
+
+ imports->malloc = default_malloc;
+ imports->calloc = default_calloc;
+ imports->realloc = default_realloc;
+ imports->free = default_free;
+ imports->warning = default_warning;
+ imports->fatal = default_fatal;
+ imports->getenv = default_getenv; /* not used for now */
+ imports->atoi = default_atoi;
+ imports->sprintf = default_sprintf;
+ imports->fopen = default_fopen;
+ imports->fclose = default_fclose;
+ imports->fprintf = default_fprintf;
+ imports->getDrawablePrivate = default_GetDrawablePrivate;
+ imports->other = driverCtx;
+}
diff --git a/src/mesa/main/imports.h b/src/mesa/main/imports.h
new file mode 100644
index 00000000000..2827264a3ac
--- /dev/null
+++ b/src/mesa/main/imports.h
@@ -0,0 +1,763 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/**
+ * \file imports.h
+ * Standard C library function wrappers.
+ *
+ * This file provides wrappers for all the standard C library functions
+ * like malloc(), free(), printf(), getenv(), etc.
+ */
+
+
+#ifndef IMPORTS_H
+#define IMPORTS_H
+
+
+/* XXX some of the stuff in glheader.h should be moved into this file.
+ */
+#include "glheader.h"
+#include <GL/internal/glcore.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**********************************************************************/
+/** \name General macros */
+/*@{*/
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+/*@}*/
+
+
+/**********************************************************************/
+/** Memory macros */
+/*@{*/
+
+/** Allocate \p BYTES bytes */
+#define MALLOC(BYTES) _mesa_malloc(BYTES)
+/** Allocate and zero \p BYTES bytes */
+#define CALLOC(BYTES) _mesa_calloc(BYTES)
+/** Allocate a structure of type \p T */
+#define MALLOC_STRUCT(T) (struct T *) _mesa_malloc(sizeof(struct T))
+/** Allocate and zero a structure of type \p T */
+#define CALLOC_STRUCT(T) (struct T *) _mesa_calloc(sizeof(struct T))
+/** Free memory */
+#define FREE(PTR) _mesa_free(PTR)
+
+/** Allocate \p BYTES aligned at \p N bytes */
+#define ALIGN_MALLOC(BYTES, N) _mesa_align_malloc(BYTES, N)
+/** Allocate and zero \p BYTES bytes aligned at \p N bytes */
+#define ALIGN_CALLOC(BYTES, N) _mesa_align_calloc(BYTES, N)
+/** Allocate a structure of type \p T aligned at \p N bytes */
+#define ALIGN_MALLOC_STRUCT(T, N) (struct T *) _mesa_align_malloc(sizeof(struct T), N)
+/** Allocate and zero a structure of type \p T aligned at \p N bytes */
+#define ALIGN_CALLOC_STRUCT(T, N) (struct T *) _mesa_align_calloc(sizeof(struct T), N)
+/** Free aligned memory */
+#define ALIGN_FREE(PTR) _mesa_align_free(PTR)
+
+/** Copy \p BYTES bytes from \p SRC into \p DST */
+#define MEMCPY( DST, SRC, BYTES) _mesa_memcpy(DST, SRC, BYTES)
+/** Set \p N bytes in \p DST to \p VAL */
+#define MEMSET( DST, VAL, N ) _mesa_memset(DST, VAL, N)
+
+/*@}*/
+
+
+/*
+ * For GL_ARB_vertex_buffer_object we need to treat vertex array pointers
+ * as offsets into buffer stores. Since the vertex array pointer and
+ * buffer store pointer are both pointers and we need to add them, we use
+ * this macro.
+ * Both pointers/offsets are expressed in bytes.
+ */
+#define ADD_POINTERS(A, B) ( (GLubyte *) (A) + (uintptr_t) (B) )
+
+
+/**
+ * Sometimes we treat GLfloats as GLints. On x86 systems, moving a float
+ * as a int (thereby using integer registers instead of FP registers) is
+ * a performance win. Typically, this can be done with ordinary casts.
+ * But with gcc's -fstrict-aliasing flag (which defaults to on in gcc 3.0)
+ * these casts generate warnings.
+ * The following union typedef is used to solve that.
+ */
+typedef union { GLfloat f; GLint i; } fi_type;
+
+
+
+/**********************************************************************
+ * Math macros
+ */
+
+#define MAX_GLUSHORT 0xffff
+#define MAX_GLUINT 0xffffffff
+
+#ifndef M_PI
+#define M_PI (3.1415926536)
+#endif
+
+#ifndef M_E
+#define M_E (2.7182818284590452354)
+#endif
+
+
+/* XXX this is a bit of a hack needed for compilation within XFree86 */
+#ifndef FLT_MIN
+#define FLT_MIN (1.0e-37)
+#endif
+
+/* Degrees to radians conversion: */
+#define DEG2RAD (M_PI/180.0)
+
+
+/***
+ *** USE_IEEE: Determine if we're using IEEE floating point
+ ***/
+#if defined(__i386__) || defined(__386__) || defined(__sparc__) || \
+ defined(__s390x__) || defined(__powerpc__) || \
+ defined(__amd64__) || \
+ defined(ia64) || defined(__ia64__) || \
+ defined(__hppa__) || defined(hpux) || \
+ defined(__mips) || defined(_MIPS_ARCH) || \
+ defined(__arm__) || \
+ defined(__sh__) || \
+ (defined(__alpha__) && (defined(__IEEE_FLOAT) || !defined(VMS)))
+#define USE_IEEE
+#define IEEE_ONE 0x3f800000
+#endif
+
+
+/***
+ *** SQRTF: single-precision square root
+ ***/
+#if 0 /* _mesa_sqrtf() not accurate enough - temporarily disabled */
+# define SQRTF(X) _mesa_sqrtf(X)
+#elif defined(XFree86LOADER) && defined(IN_MODULE) && !defined(NO_LIBCWRAPPER)
+# define SQRTF(X) (float) xf86sqrt((float) (X))
+#else
+# define SQRTF(X) (float) sqrt((float) (X))
+#endif
+
+
+/***
+ *** INV_SQRTF: single-precision inverse square root
+ ***/
+#if 0
+#define INV_SQRTF(X) _mesa_inv_sqrt(X)
+#else
+#define INV_SQRTF(X) (1.0F / SQRTF(X)) /* this is faster on a P4 */
+#endif
+
+
+/***
+ *** LOG2: Log base 2 of float
+ ***/
+#ifdef USE_IEEE
+#if 0
+/* This is pretty fast, but not accurate enough (only 2 fractional bits).
+ * Based on code from http://www.stereopsis.com/log2.html
+ */
+static INLINE GLfloat LOG2(GLfloat x)
+{
+ const GLfloat y = x * x * x * x;
+ const GLuint ix = *((GLuint *) &y);
+ const GLuint exp = (ix >> 23) & 0xFF;
+ const GLint log2 = ((GLint) exp) - 127;
+ return (GLfloat) log2 * (1.0 / 4.0); /* 4, because of x^4 above */
+}
+#endif
+/* Pretty fast, and accurate.
+ * Based on code from http://www.flipcode.com/totd/
+ */
+static INLINE GLfloat LOG2(GLfloat val)
+{
+ fi_type num;
+ GLint log_2;
+ num.f = val;
+ log_2 = ((num.i >> 23) & 255) - 128;
+ num.i &= ~(255 << 23);
+ num.i += 127 << 23;
+ num.f = ((-1.0f/3) * num.f + 2) * num.f - 2.0f/3;
+ return num.f + log_2;
+}
+#elif defined(XFree86LOADER) && defined(IN_MODULE) && !defined(NO_LIBCWRAPPER)
+#define LOG2(x) ((GLfloat) (xf86log(x) * 1.442695))
+#else
+/*
+ * NOTE: log_base_2(x) = log(x) / log(2)
+ * NOTE: 1.442695 = 1/log(2).
+ */
+#define LOG2(x) ((GLfloat) (log(x) * 1.442695F))
+#endif
+
+
+/***
+ *** IS_INF_OR_NAN: test if float is infinite or NaN
+ ***/
+#ifdef USE_IEEE
+static INLINE int IS_INF_OR_NAN( float x )
+{
+ fi_type tmp;
+ tmp.f = x;
+ return !(int)((unsigned int)((tmp.i & 0x7fffffff)-0x7f800000) >> 31);
+}
+#elif defined(isfinite)
+#define IS_INF_OR_NAN(x) (!isfinite(x))
+#elif defined(finite)
+#define IS_INF_OR_NAN(x) (!finite(x))
+#elif defined(__VMS)
+#define IS_INF_OR_NAN(x) (!finite(x))
+#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+#define IS_INF_OR_NAN(x) (!isfinite(x))
+#else
+#define IS_INF_OR_NAN(x) (!finite(x))
+#endif
+
+
+/***
+ *** IS_NEGATIVE: test if float is negative
+ ***/
+#if defined(USE_IEEE)
+static INLINE int GET_FLOAT_BITS( float x )
+{
+ fi_type fi;
+ fi.f = x;
+ return fi.i;
+}
+#define IS_NEGATIVE(x) (GET_FLOAT_BITS(x) < 0)
+#else
+#define IS_NEGATIVE(x) (x < 0.0F)
+#endif
+
+
+/***
+ *** DIFFERENT_SIGNS: test if two floats have opposite signs
+ ***/
+#if defined(USE_IEEE)
+#define DIFFERENT_SIGNS(x,y) ((GET_FLOAT_BITS(x) ^ GET_FLOAT_BITS(y)) & (1<<31))
+#else
+/* Could just use (x*y<0) except for the flatshading requirements.
+ * Maybe there's a better way?
+ */
+#define DIFFERENT_SIGNS(x,y) ((x) * (y) <= 0.0F && (x) - (y) != 0.0F)
+#endif
+
+
+/***
+ *** CEILF: ceiling of float
+ *** FLOORF: floor of float
+ *** FABSF: absolute value of float
+ *** LOGF: the natural logarithm (base e) of the value
+ *** EXPF: raise e to the value
+ *** LDEXPF: multiply value by an integral power of two
+ *** FREXPF: extract mantissa and exponent from value
+ ***/
+#if defined(XFree86LOADER) && defined(IN_MODULE) && !defined(NO_LIBCWRAPPER)
+#define CEILF(x) ((GLfloat) xf86ceil(x))
+#define FLOORF(x) ((GLfloat) xf86floor(x))
+#define FABSF(x) ((GLfloat) xf86fabs(x))
+#define LOGF(x) ((GLfloat) xf86log(x))
+#define EXPF(x) ((GLfloat) xf86exp(x))
+#define LDEXPF(x,y) ((GLfloat) xf86ldexp(x,y))
+#define FREXPF(x,y) ((GLfloat) xf86frexp(x,y))
+#elif defined(__gnu_linux__)
+/* C99 functions */
+#define CEILF(x) ceilf(x)
+#define FLOORF(x) floorf(x)
+#define FABSF(x) fabsf(x)
+#define LOGF(x) logf(x)
+#define EXPF(x) expf(x)
+#define LDEXPF(x,y) ldexpf(x,y)
+#define FREXPF(x,y) frexpf(x,y)
+#else
+#define CEILF(x) ((GLfloat) ceil(x))
+#define FLOORF(x) ((GLfloat) floor(x))
+#define FABSF(x) ((GLfloat) fabs(x))
+#define LOGF(x) ((GLfloat) log(x))
+#define EXPF(x) ((GLfloat) exp(x))
+#define LDEXPF(x,y) ((GLfloat) ldexp(x,y))
+#define FREXPF(x,y) ((GLfloat) frexp(x,y))
+#endif
+
+
+/***
+ *** IROUND: return (as an integer) float rounded to nearest integer
+ ***/
+#if defined(USE_SPARC_ASM) && defined(__GNUC__) && defined(__sparc__)
+static INLINE int iround(float f)
+{
+ int r;
+ __asm__ ("fstoi %1, %0" : "=f" (r) : "f" (f));
+ return r;
+}
+#define IROUND(x) iround(x)
+#elif defined(USE_X86_ASM) && defined(__GNUC__) && defined(__i386__) && \
+ (!defined(__BEOS__) || (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95)))
+static INLINE int iround(float f)
+{
+ int r;
+ __asm__ ("fistpl %0" : "=m" (r) : "t" (f) : "st");
+ return r;
+}
+#define IROUND(x) iround(x)
+#elif defined(USE_X86_ASM) && defined(__MSC__) && defined(__WIN32__)
+static INLINE int iround(float f)
+{
+ int r;
+ _asm {
+ fld f
+ fistp r
+ }
+ return r;
+}
+#define IROUND(x) iround(x)
+#elif defined(__WATCOMC__) && defined(__386__)
+long iround(float f);
+#pragma aux iround = \
+ "push eax" \
+ "fistp dword ptr [esp]" \
+ "pop eax" \
+ parm [8087] \
+ value [eax] \
+ modify exact [eax];
+#define IROUND(x) iround(x)
+#else
+#define IROUND(f) ((int) (((f) >= 0.0F) ? ((f) + 0.5F) : ((f) - 0.5F)))
+#endif
+
+
+/***
+ *** IROUND_POS: return (as an integer) positive float rounded to nearest int
+ ***/
+#ifdef DEBUG
+#define IROUND_POS(f) (assert((f) >= 0.0F), IROUND(f))
+#else
+#define IROUND_POS(f) (IROUND(f))
+#endif
+
+
+/***
+ *** IFLOOR: return (as an integer) floor of float
+ ***/
+#if defined(USE_X86_ASM) && defined(__GNUC__) && defined(__i386__)
+/*
+ * IEEE floor for computers that round to nearest or even.
+ * 'f' must be between -4194304 and 4194303.
+ * This floor operation is done by "(iround(f + .5) + iround(f - .5)) >> 1",
+ * but uses some IEEE specific tricks for better speed.
+ * Contributed by Josh Vanderhoof
+ */
+static INLINE int ifloor(float f)
+{
+ int ai, bi;
+ double af, bf;
+ af = (3 << 22) + 0.5 + (double)f;
+ bf = (3 << 22) + 0.5 - (double)f;
+ /* GCC generates an extra fstp/fld without this. */
+ __asm__ ("fstps %0" : "=m" (ai) : "t" (af) : "st");
+ __asm__ ("fstps %0" : "=m" (bi) : "t" (bf) : "st");
+ return (ai - bi) >> 1;
+}
+#define IFLOOR(x) ifloor(x)
+#elif defined(USE_IEEE)
+static INLINE int ifloor(float f)
+{
+ int ai, bi;
+ double af, bf;
+ fi_type u;
+
+ af = (3 << 22) + 0.5 + (double)f;
+ bf = (3 << 22) + 0.5 - (double)f;
+ u.f = (float) af; ai = u.i;
+ u.f = (float) bf; bi = u.i;
+ return (ai - bi) >> 1;
+}
+#define IFLOOR(x) ifloor(x)
+#else
+static INLINE int ifloor(float f)
+{
+ int i = IROUND(f);
+ return (i > f) ? i - 1 : i;
+}
+#define IFLOOR(x) ifloor(x)
+#endif
+
+
+/***
+ *** ICEIL: return (as an integer) ceiling of float
+ ***/
+#if defined(USE_X86_ASM) && defined(__GNUC__) && defined(__i386__)
+/*
+ * IEEE ceil for computers that round to nearest or even.
+ * 'f' must be between -4194304 and 4194303.
+ * This ceil operation is done by "(iround(f + .5) + iround(f - .5) + 1) >> 1",
+ * but uses some IEEE specific tricks for better speed.
+ * Contributed by Josh Vanderhoof
+ */
+static INLINE int iceil(float f)
+{
+ int ai, bi;
+ double af, bf;
+ af = (3 << 22) + 0.5 + (double)f;
+ bf = (3 << 22) + 0.5 - (double)f;
+ /* GCC generates an extra fstp/fld without this. */
+ __asm__ ("fstps %0" : "=m" (ai) : "t" (af) : "st");
+ __asm__ ("fstps %0" : "=m" (bi) : "t" (bf) : "st");
+ return (ai - bi + 1) >> 1;
+}
+#define ICEIL(x) iceil(x)
+#elif defined(USE_IEEE)
+static INLINE int iceil(float f)
+{
+ int ai, bi;
+ double af, bf;
+ fi_type u;
+ af = (3 << 22) + 0.5 + (double)f;
+ bf = (3 << 22) + 0.5 - (double)f;
+ u.f = (float) af; ai = u.i;
+ u.f = (float) bf; bi = u.i;
+ return (ai - bi + 1) >> 1;
+}
+#define ICEIL(x) iceil(x)
+#else
+static INLINE int iceil(float f)
+{
+ int i = IROUND(f);
+ return (i < f) ? i + 1 : i;
+}
+#define ICEIL(x) iceil(x)
+#endif
+
+
+/***
+ *** UNCLAMPED_FLOAT_TO_UBYTE: clamp float to [0,1] and map to ubyte in [0,255]
+ *** CLAMPED_FLOAT_TO_UBYTE: map float known to be in [0,1] to ubyte in [0,255]
+ ***/
+#if defined(USE_IEEE) && !defined(DEBUG)
+#define IEEE_0996 0x3f7f0000 /* 0.996 or so */
+/* This function/macro is sensitive to precision. Test very carefully
+ * if you change it!
+ */
+#define UNCLAMPED_FLOAT_TO_UBYTE(UB, F) \
+ do { \
+ fi_type __tmp; \
+ __tmp.f = (F); \
+ if (__tmp.i < 0) \
+ UB = (GLubyte) 0; \
+ else if (__tmp.i >= IEEE_0996) \
+ UB = (GLubyte) 255; \
+ else { \
+ __tmp.f = __tmp.f * (255.0F/256.0F) + 32768.0F; \
+ UB = (GLubyte) __tmp.i; \
+ } \
+ } while (0)
+#define CLAMPED_FLOAT_TO_UBYTE(UB, F) \
+ do { \
+ fi_type __tmp; \
+ __tmp.f = (F) * (255.0F/256.0F) + 32768.0F; \
+ UB = (GLubyte) __tmp.i; \
+ } while (0)
+#else
+#define UNCLAMPED_FLOAT_TO_UBYTE(ub, f) \
+ ub = ((GLubyte) IROUND(CLAMP((f), 0.0F, 1.0F) * 255.0F))
+#define CLAMPED_FLOAT_TO_UBYTE(ub, f) \
+ ub = ((GLubyte) IROUND((f) * 255.0F))
+#endif
+
+
+/***
+ *** START_FAST_MATH: Set x86 FPU to faster, 32-bit precision mode (and save
+ *** original mode to a temporary).
+ *** END_FAST_MATH: Restore x86 FPU to original mode.
+ ***/
+#if defined(__GNUC__) && defined(__i386__)
+/*
+ * Set the x86 FPU control word to guarentee only 32 bits of precision
+ * are stored in registers. Allowing the FPU to store more introduces
+ * differences between situations where numbers are pulled out of memory
+ * vs. situations where the compiler is able to optimize register usage.
+ *
+ * In the worst case, we force the compiler to use a memory access to
+ * truncate the float, by specifying the 'volatile' keyword.
+ */
+/* Hardware default: All exceptions masked, extended double precision,
+ * round to nearest (IEEE compliant):
+ */
+#define DEFAULT_X86_FPU 0x037f
+/* All exceptions masked, single precision, round to nearest:
+ */
+#define FAST_X86_FPU 0x003f
+/* The fldcw instruction will cause any pending FP exceptions to be
+ * raised prior to entering the block, and we clear any pending
+ * exceptions before exiting the block. Hence, asm code has free
+ * reign over the FPU while in the fast math block.
+ */
+#if defined(NO_FAST_MATH)
+#define START_FAST_MATH(x) \
+do { \
+ static GLuint mask = DEFAULT_X86_FPU; \
+ __asm__ ( "fnstcw %0" : "=m" (*&(x)) ); \
+ __asm__ ( "fldcw %0" : : "m" (mask) ); \
+} while (0)
+#else
+#define START_FAST_MATH(x) \
+do { \
+ static GLuint mask = FAST_X86_FPU; \
+ __asm__ ( "fnstcw %0" : "=m" (*&(x)) ); \
+ __asm__ ( "fldcw %0" : : "m" (mask) ); \
+} while (0)
+#endif
+/* Restore original FPU mode, and clear any exceptions that may have
+ * occurred in the FAST_MATH block.
+ */
+#define END_FAST_MATH(x) \
+do { \
+ __asm__ ( "fnclex ; fldcw %0" : : "m" (*&(x)) ); \
+} while (0)
+
+#elif defined(__WATCOMC__) && defined(__386__)
+#define DEFAULT_X86_FPU 0x037f /* See GCC comments above */
+#define FAST_X86_FPU 0x003f /* See GCC comments above */
+void _watcom_start_fast_math(unsigned short *x,unsigned short *mask);
+#pragma aux _watcom_start_fast_math = \
+ "fnstcw word ptr [eax]" \
+ "fldcw word ptr [ecx]" \
+ parm [eax] [ecx] \
+ modify exact [];
+void _watcom_end_fast_math(unsigned short *x);
+#pragma aux _watcom_end_fast_math = \
+ "fnclex" \
+ "fldcw word ptr [eax]" \
+ parm [eax] \
+ modify exact [];
+#if defined(NO_FAST_MATH)
+#define START_FAST_MATH(x) \
+do { \
+ static GLushort mask = DEFAULT_X86_FPU; \
+ _watcom_start_fast_math(&x,&mask); \
+} while (0)
+#else
+#define START_FAST_MATH(x) \
+do { \
+ static GLushort mask = FAST_X86_FPU; \
+ _watcom_start_fast_math(&x,&mask); \
+} while (0)
+#endif
+#define END_FAST_MATH(x) _watcom_end_fast_math(&x)
+
+#elif defined(_MSC_VER) && defined(_M_IX86)
+#define DEFAULT_X86_FPU 0x037f /* See GCC comments above */
+#define FAST_X86_FPU 0x003f /* See GCC comments above */
+#if defined(NO_FAST_MATH)
+#define START_FAST_MATH(x) do {\
+ static GLuint mask = DEFAULT_X86_FPU;\
+ __asm fnstcw word ptr [x]\
+ __asm fldcw word ptr [mask]\
+} while(0)
+#else
+#define START_FAST_MATH(x) do {\
+ static GLuint mask = FAST_X86_FPU;\
+ __asm fnstcw word ptr [x]\
+ __asm fldcw word ptr [mask]\
+} while(0)
+#endif
+#define END_FAST_MATH(x) do {\
+ __asm fnclex\
+ __asm fldcw word ptr [x]\
+} while(0)
+
+#else
+#define START_FAST_MATH(x) x = 0
+#define END_FAST_MATH(x) (void)(x)
+#endif
+
+
+
+/**********************************************************************
+ * Functions
+ */
+
+extern void *
+_mesa_malloc( size_t bytes );
+
+extern void *
+_mesa_calloc( size_t bytes );
+
+extern void
+_mesa_free( void *ptr );
+
+extern void *
+_mesa_align_malloc( size_t bytes, unsigned long alignment );
+
+extern void *
+_mesa_align_calloc( size_t bytes, unsigned long alignment );
+
+extern void
+_mesa_align_free( void *ptr );
+
+extern void *
+_mesa_exec_malloc( GLuint size );
+
+extern void
+_mesa_exec_free( void *addr );
+
+extern void *
+_mesa_realloc( void *oldBuffer, size_t oldSize, size_t newSize );
+
+extern void *
+_mesa_memcpy( void *dest, const void *src, size_t n );
+
+extern void
+_mesa_memset( void *dst, int val, size_t n );
+
+extern void
+_mesa_memset16( unsigned short *dst, unsigned short val, size_t n );
+
+extern void
+_mesa_bzero( void *dst, size_t n );
+
+extern int
+_mesa_memcmp( const void *s1, const void *s2, size_t n );
+
+extern double
+_mesa_sin(double a);
+
+extern float
+_mesa_sinf(float a);
+
+extern double
+_mesa_cos(double a);
+
+extern float
+_mesa_asinf(float x);
+
+extern float
+_mesa_atanf(float x);
+
+extern double
+_mesa_sqrtd(double x);
+
+extern float
+_mesa_sqrtf(float x);
+
+extern float
+_mesa_inv_sqrtf(float x);
+
+extern double
+_mesa_pow(double x, double y);
+
+extern int
+_mesa_ffs(int i);
+
+extern unsigned int
+_mesa_bitcount(unsigned int n);
+
+extern GLhalfARB
+_mesa_float_to_half(float f);
+
+extern float
+_mesa_half_to_float(GLhalfARB h);
+
+
+extern void *
+_mesa_bsearch( const void *key, const void *base, size_t nmemb, size_t size,
+ int (*compar)(const void *, const void *) );
+
+extern char *
+_mesa_getenv( const char *var );
+
+extern char *
+_mesa_strstr( const char *haystack, const char *needle );
+
+extern char *
+_mesa_strncat( char *dest, const char *src, size_t n );
+
+extern char *
+_mesa_strcpy( char *dest, const char *src );
+
+extern char *
+_mesa_strncpy( char *dest, const char *src, size_t n );
+
+extern size_t
+_mesa_strlen( const char *s );
+
+extern int
+_mesa_strcmp( const char *s1, const char *s2 );
+
+extern int
+_mesa_strncmp( const char *s1, const char *s2, size_t n );
+
+extern char *
+_mesa_strdup( const char *s );
+
+extern int
+_mesa_atoi( const char *s );
+
+extern double
+_mesa_strtod( const char *s, char **end );
+
+extern int
+_mesa_sprintf( char *str, const char *fmt, ... );
+
+extern void
+_mesa_printf( const char *fmtString, ... );
+
+extern int
+_mesa_vsprintf( char *str, const char *fmt, va_list args );
+
+
+extern void
+_mesa_warning( __GLcontext *gc, const char *fmtString, ... );
+
+extern void
+_mesa_problem( const __GLcontext *ctx, const char *fmtString, ... );
+
+extern void
+_mesa_error( __GLcontext *ctx, GLenum error, const char *fmtString, ... );
+
+extern void
+_mesa_debug( const __GLcontext *ctx, const char *fmtString, ... );
+
+extern void
+_mesa_exit( int status );
+
+
+extern void
+_mesa_init_default_imports( __GLimports *imports, void *driverCtx );
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* IMPORTS_H */
diff --git a/src/mesa/main/light.c b/src/mesa/main/light.c
new file mode 100644
index 00000000000..35ec1547e98
--- /dev/null
+++ b/src/mesa/main/light.c
@@ -0,0 +1,1375 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include "glheader.h"
+#include "imports.h"
+#include "context.h"
+#include "enums.h"
+#include "light.h"
+#include "macros.h"
+#include "simple_list.h"
+#include "mtypes.h"
+#include "math/m_matrix.h"
+
+
+void GLAPIENTRY
+_mesa_ShadeModel( GLenum mode )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx, "glShadeModel %s\n", _mesa_lookup_enum_by_nr(mode));
+
+ if (mode != GL_FLAT && mode != GL_SMOOTH) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glShadeModel" );
+ return;
+ }
+
+ if (ctx->Light.ShadeModel == mode)
+ return;
+
+ FLUSH_VERTICES(ctx, _NEW_LIGHT);
+ ctx->Light.ShadeModel = mode;
+ ctx->_TriangleCaps ^= DD_FLATSHADE;
+ if (ctx->Driver.ShadeModel)
+ (*ctx->Driver.ShadeModel)( ctx, mode );
+}
+
+
+/**
+ * Helper function called by _mesa_Lightfv and _mesa_PopAttrib to set
+ * per-light state.
+ * For GL_POSITION and GL_SPOT_DIRECTION the params position/direction
+ * will have already been transformed by the modelview matrix!
+ * Also, all error checking should have already been done.
+ */
+void
+_mesa_light(GLcontext *ctx, GLuint lnum, GLenum pname, const GLfloat *params)
+{
+ struct gl_light *light;
+
+ ASSERT(lnum < MAX_LIGHTS);
+ light = &ctx->Light.Light[lnum];
+
+ switch (pname) {
+ case GL_AMBIENT:
+ if (TEST_EQ_4V(light->Ambient, params))
+ return;
+ FLUSH_VERTICES(ctx, _NEW_LIGHT);
+ COPY_4V( light->Ambient, params );
+ break;
+ case GL_DIFFUSE:
+ if (TEST_EQ_4V(light->Diffuse, params))
+ return;
+ FLUSH_VERTICES(ctx, _NEW_LIGHT);
+ COPY_4V( light->Diffuse, params );
+ break;
+ case GL_SPECULAR:
+ if (TEST_EQ_4V(light->Specular, params))
+ return;
+ FLUSH_VERTICES(ctx, _NEW_LIGHT);
+ COPY_4V( light->Specular, params );
+ break;
+ case GL_POSITION:
+ /* NOTE: position has already been transformed by ModelView! */
+ if (TEST_EQ_4V(light->EyePosition, params))
+ return;
+ FLUSH_VERTICES(ctx, _NEW_LIGHT);
+ COPY_4V(light->EyePosition, params);
+ if (light->EyePosition[3] != 0.0F)
+ light->_Flags |= LIGHT_POSITIONAL;
+ else
+ light->_Flags &= ~LIGHT_POSITIONAL;
+ break;
+ case GL_SPOT_DIRECTION:
+ /* NOTE: Direction already transformed by inverse ModelView! */
+ if (TEST_EQ_3V(light->EyeDirection, params))
+ return;
+ FLUSH_VERTICES(ctx, _NEW_LIGHT);
+ COPY_3V(light->EyeDirection, params);
+ break;
+ case GL_SPOT_EXPONENT:
+ ASSERT(params[0] >= 0.0);
+ ASSERT(params[0] <= ctx->Const.MaxSpotExponent);
+ if (light->SpotExponent == params[0])
+ return;
+ FLUSH_VERTICES(ctx, _NEW_LIGHT);
+ light->SpotExponent = params[0];
+ _mesa_invalidate_spot_exp_table(light);
+ break;
+ case GL_SPOT_CUTOFF:
+ ASSERT(params[0] == 180.0 || (params[0] >= 0.0 && params[0] <= 90.0));
+ if (light->SpotCutoff == params[0])
+ return;
+ FLUSH_VERTICES(ctx, _NEW_LIGHT);
+ light->SpotCutoff = params[0];
+ light->_CosCutoffNeg = (GLfloat) (_mesa_cos(light->SpotCutoff * DEG2RAD));
+ if (light->_CosCutoffNeg < 0)
+ light->_CosCutoff = 0;
+ else
+ light->_CosCutoff = light->_CosCutoffNeg;
+ if (light->SpotCutoff != 180.0F)
+ light->_Flags |= LIGHT_SPOT;
+ else
+ light->_Flags &= ~LIGHT_SPOT;
+ break;
+ case GL_CONSTANT_ATTENUATION:
+ ASSERT(params[0] >= 0.0);
+ if (light->ConstantAttenuation == params[0])
+ return;
+ FLUSH_VERTICES(ctx, _NEW_LIGHT);
+ light->ConstantAttenuation = params[0];
+ break;
+ case GL_LINEAR_ATTENUATION:
+ ASSERT(params[0] >= 0.0);
+ if (light->LinearAttenuation == params[0])
+ return;
+ FLUSH_VERTICES(ctx, _NEW_LIGHT);
+ light->LinearAttenuation = params[0];
+ break;
+ case GL_QUADRATIC_ATTENUATION:
+ ASSERT(params[0] >= 0.0);
+ if (light->QuadraticAttenuation == params[0])
+ return;
+ FLUSH_VERTICES(ctx, _NEW_LIGHT);
+ light->QuadraticAttenuation = params[0];
+ break;
+ default:
+ _mesa_problem(ctx, "Unexpected pname in _mesa_light()");
+ return;
+ }
+
+ if (ctx->Driver.Lightfv)
+ ctx->Driver.Lightfv( ctx, GL_LIGHT0 + lnum, pname, params );
+}
+
+
+void GLAPIENTRY
+_mesa_Lightf( GLenum light, GLenum pname, GLfloat param )
+{
+ _mesa_Lightfv( light, pname, &param );
+}
+
+
+void GLAPIENTRY
+_mesa_Lightfv( GLenum light, GLenum pname, const GLfloat *params )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint i = (GLint) (light - GL_LIGHT0);
+ GLfloat temp[4];
+
+ if (i < 0 || i >= (GLint) ctx->Const.MaxLights) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glLight(light=0x%x)", light );
+ return;
+ }
+
+ /* do particular error checks, transformations */
+ switch (pname) {
+ case GL_AMBIENT:
+ case GL_DIFFUSE:
+ case GL_SPECULAR:
+ /* nothing */
+ break;
+ case GL_POSITION:
+ /* transform position by ModelView matrix */
+ TRANSFORM_POINT(temp, ctx->ModelviewMatrixStack.Top->m, params);
+ params = temp;
+ break;
+ case GL_SPOT_DIRECTION:
+ /* transform direction by inverse modelview */
+ if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) {
+ _math_matrix_analyse(ctx->ModelviewMatrixStack.Top);
+ }
+ TRANSFORM_NORMAL(temp, params, ctx->ModelviewMatrixStack.Top->inv);
+ params = temp;
+ break;
+ case GL_SPOT_EXPONENT:
+ if (params[0] < 0.0 || params[0] > ctx->Const.MaxSpotExponent) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glLight");
+ return;
+ }
+ break;
+ case GL_SPOT_CUTOFF:
+ if ((params[0] < 0.0 || params[0] > 90.0) && params[0] != 180.0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glLight");
+ return;
+ }
+ break;
+ case GL_CONSTANT_ATTENUATION:
+ if (params[0] < 0.0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glLight");
+ return;
+ }
+ break;
+ case GL_LINEAR_ATTENUATION:
+ if (params[0] < 0.0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glLight");
+ return;
+ }
+ break;
+ case GL_QUADRATIC_ATTENUATION:
+ if (params[0] < 0.0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glLight");
+ return;
+ }
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glLight(pname=0x%x)", pname);
+ return;
+ }
+
+ _mesa_light(ctx, i, pname, params);
+}
+
+
+void GLAPIENTRY
+_mesa_Lighti( GLenum light, GLenum pname, GLint param )
+{
+ _mesa_Lightiv( light, pname, &param );
+}
+
+
+void GLAPIENTRY
+_mesa_Lightiv( GLenum light, GLenum pname, const GLint *params )
+{
+ GLfloat fparam[4];
+
+ switch (pname) {
+ case GL_AMBIENT:
+ case GL_DIFFUSE:
+ case GL_SPECULAR:
+ fparam[0] = INT_TO_FLOAT( params[0] );
+ fparam[1] = INT_TO_FLOAT( params[1] );
+ fparam[2] = INT_TO_FLOAT( params[2] );
+ fparam[3] = INT_TO_FLOAT( params[3] );
+ break;
+ case GL_POSITION:
+ fparam[0] = (GLfloat) params[0];
+ fparam[1] = (GLfloat) params[1];
+ fparam[2] = (GLfloat) params[2];
+ fparam[3] = (GLfloat) params[3];
+ break;
+ case GL_SPOT_DIRECTION:
+ fparam[0] = (GLfloat) params[0];
+ fparam[1] = (GLfloat) params[1];
+ fparam[2] = (GLfloat) params[2];
+ break;
+ case GL_SPOT_EXPONENT:
+ case GL_SPOT_CUTOFF:
+ case GL_CONSTANT_ATTENUATION:
+ case GL_LINEAR_ATTENUATION:
+ case GL_QUADRATIC_ATTENUATION:
+ fparam[0] = (GLfloat) params[0];
+ break;
+ default:
+ /* error will be caught later in gl_Lightfv */
+ ;
+ }
+
+ _mesa_Lightfv( light, pname, fparam );
+}
+
+
+
+void GLAPIENTRY
+_mesa_GetLightfv( GLenum light, GLenum pname, GLfloat *params )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint l = (GLint) (light - GL_LIGHT0);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (l < 0 || l >= (GLint) ctx->Const.MaxLights) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetLightfv" );
+ return;
+ }
+
+ switch (pname) {
+ case GL_AMBIENT:
+ COPY_4V( params, ctx->Light.Light[l].Ambient );
+ break;
+ case GL_DIFFUSE:
+ COPY_4V( params, ctx->Light.Light[l].Diffuse );
+ break;
+ case GL_SPECULAR:
+ COPY_4V( params, ctx->Light.Light[l].Specular );
+ break;
+ case GL_POSITION:
+ COPY_4V( params, ctx->Light.Light[l].EyePosition );
+ break;
+ case GL_SPOT_DIRECTION:
+ COPY_3V( params, ctx->Light.Light[l].EyeDirection );
+ break;
+ case GL_SPOT_EXPONENT:
+ params[0] = ctx->Light.Light[l].SpotExponent;
+ break;
+ case GL_SPOT_CUTOFF:
+ params[0] = ctx->Light.Light[l].SpotCutoff;
+ break;
+ case GL_CONSTANT_ATTENUATION:
+ params[0] = ctx->Light.Light[l].ConstantAttenuation;
+ break;
+ case GL_LINEAR_ATTENUATION:
+ params[0] = ctx->Light.Light[l].LinearAttenuation;
+ break;
+ case GL_QUADRATIC_ATTENUATION:
+ params[0] = ctx->Light.Light[l].QuadraticAttenuation;
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetLightfv" );
+ break;
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_GetLightiv( GLenum light, GLenum pname, GLint *params )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint l = (GLint) (light - GL_LIGHT0);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (l < 0 || l >= (GLint) ctx->Const.MaxLights) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetLightiv" );
+ return;
+ }
+
+ switch (pname) {
+ case GL_AMBIENT:
+ params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[0]);
+ params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[1]);
+ params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[2]);
+ params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[3]);
+ break;
+ case GL_DIFFUSE:
+ params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[0]);
+ params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[1]);
+ params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[2]);
+ params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[3]);
+ break;
+ case GL_SPECULAR:
+ params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[0]);
+ params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[1]);
+ params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[2]);
+ params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[3]);
+ break;
+ case GL_POSITION:
+ params[0] = (GLint) ctx->Light.Light[l].EyePosition[0];
+ params[1] = (GLint) ctx->Light.Light[l].EyePosition[1];
+ params[2] = (GLint) ctx->Light.Light[l].EyePosition[2];
+ params[3] = (GLint) ctx->Light.Light[l].EyePosition[3];
+ break;
+ case GL_SPOT_DIRECTION:
+ params[0] = (GLint) ctx->Light.Light[l].EyeDirection[0];
+ params[1] = (GLint) ctx->Light.Light[l].EyeDirection[1];
+ params[2] = (GLint) ctx->Light.Light[l].EyeDirection[2];
+ break;
+ case GL_SPOT_EXPONENT:
+ params[0] = (GLint) ctx->Light.Light[l].SpotExponent;
+ break;
+ case GL_SPOT_CUTOFF:
+ params[0] = (GLint) ctx->Light.Light[l].SpotCutoff;
+ break;
+ case GL_CONSTANT_ATTENUATION:
+ params[0] = (GLint) ctx->Light.Light[l].ConstantAttenuation;
+ break;
+ case GL_LINEAR_ATTENUATION:
+ params[0] = (GLint) ctx->Light.Light[l].LinearAttenuation;
+ break;
+ case GL_QUADRATIC_ATTENUATION:
+ params[0] = (GLint) ctx->Light.Light[l].QuadraticAttenuation;
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetLightiv" );
+ break;
+ }
+}
+
+
+
+/**********************************************************************/
+/*** Light Model ***/
+/**********************************************************************/
+
+
+void GLAPIENTRY
+_mesa_LightModelfv( GLenum pname, const GLfloat *params )
+{
+ GLenum newenum;
+ GLboolean newbool;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ switch (pname) {
+ case GL_LIGHT_MODEL_AMBIENT:
+ if (TEST_EQ_4V( ctx->Light.Model.Ambient, params ))
+ return;
+ FLUSH_VERTICES(ctx, _NEW_LIGHT);
+ COPY_4V( ctx->Light.Model.Ambient, params );
+ break;
+ case GL_LIGHT_MODEL_LOCAL_VIEWER:
+ newbool = (params[0]!=0.0);
+ if (ctx->Light.Model.LocalViewer == newbool)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_LIGHT);
+ ctx->Light.Model.LocalViewer = newbool;
+ break;
+ case GL_LIGHT_MODEL_TWO_SIDE:
+ newbool = (params[0]!=0.0);
+ if (ctx->Light.Model.TwoSide == newbool)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_LIGHT);
+ ctx->Light.Model.TwoSide = newbool;
+
+ if (ctx->Light.Enabled && ctx->Light.Model.TwoSide)
+ ctx->_TriangleCaps |= DD_TRI_LIGHT_TWOSIDE;
+ else
+ ctx->_TriangleCaps &= ~DD_TRI_LIGHT_TWOSIDE;
+ break;
+ case GL_LIGHT_MODEL_COLOR_CONTROL:
+ if (params[0] == (GLfloat) GL_SINGLE_COLOR)
+ newenum = GL_SINGLE_COLOR;
+ else if (params[0] == (GLfloat) GL_SEPARATE_SPECULAR_COLOR)
+ newenum = GL_SEPARATE_SPECULAR_COLOR;
+ else {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glLightModel(param=0x0%x)",
+ (GLint) params[0] );
+ return;
+ }
+ if (ctx->Light.Model.ColorControl == newenum)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_LIGHT);
+ ctx->Light.Model.ColorControl = newenum;
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glLightModel(pname=0x%x)", pname );
+ break;
+ }
+
+ if (ctx->Driver.LightModelfv)
+ ctx->Driver.LightModelfv( ctx, pname, params );
+}
+
+
+void GLAPIENTRY
+_mesa_LightModeliv( GLenum pname, const GLint *params )
+{
+ GLfloat fparam[4];
+
+ switch (pname) {
+ case GL_LIGHT_MODEL_AMBIENT:
+ fparam[0] = INT_TO_FLOAT( params[0] );
+ fparam[1] = INT_TO_FLOAT( params[1] );
+ fparam[2] = INT_TO_FLOAT( params[2] );
+ fparam[3] = INT_TO_FLOAT( params[3] );
+ break;
+ case GL_LIGHT_MODEL_LOCAL_VIEWER:
+ case GL_LIGHT_MODEL_TWO_SIDE:
+ case GL_LIGHT_MODEL_COLOR_CONTROL:
+ fparam[0] = (GLfloat) params[0];
+ break;
+ default:
+ /* Error will be caught later in gl_LightModelfv */
+ ;
+ }
+ _mesa_LightModelfv( pname, fparam );
+}
+
+
+void GLAPIENTRY
+_mesa_LightModeli( GLenum pname, GLint param )
+{
+ _mesa_LightModeliv( pname, &param );
+}
+
+
+void GLAPIENTRY
+_mesa_LightModelf( GLenum pname, GLfloat param )
+{
+ _mesa_LightModelfv( pname, &param );
+}
+
+
+
+/********** MATERIAL **********/
+
+
+/*
+ * Given a face and pname value (ala glColorMaterial), compute a bitmask
+ * of the targeted material values.
+ */
+GLuint
+_mesa_material_bitmask( GLcontext *ctx, GLenum face, GLenum pname,
+ GLuint legal, const char *where )
+{
+ GLuint bitmask = 0;
+
+ /* Make a bitmask indicating what material attribute(s) we're updating */
+ switch (pname) {
+ case GL_EMISSION:
+ bitmask |= MAT_BIT_FRONT_EMISSION | MAT_BIT_BACK_EMISSION;
+ break;
+ case GL_AMBIENT:
+ bitmask |= MAT_BIT_FRONT_AMBIENT | MAT_BIT_BACK_AMBIENT;
+ break;
+ case GL_DIFFUSE:
+ bitmask |= MAT_BIT_FRONT_DIFFUSE | MAT_BIT_BACK_DIFFUSE;
+ break;
+ case GL_SPECULAR:
+ bitmask |= MAT_BIT_FRONT_SPECULAR | MAT_BIT_BACK_SPECULAR;
+ break;
+ case GL_SHININESS:
+ bitmask |= MAT_BIT_FRONT_SHININESS | MAT_BIT_BACK_SHININESS;
+ break;
+ case GL_AMBIENT_AND_DIFFUSE:
+ bitmask |= MAT_BIT_FRONT_AMBIENT | MAT_BIT_BACK_AMBIENT;
+ bitmask |= MAT_BIT_FRONT_DIFFUSE | MAT_BIT_BACK_DIFFUSE;
+ break;
+ case GL_COLOR_INDEXES:
+ bitmask |= MAT_BIT_FRONT_INDEXES | MAT_BIT_BACK_INDEXES;
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, where );
+ return 0;
+ }
+
+ if (face==GL_FRONT) {
+ bitmask &= FRONT_MATERIAL_BITS;
+ }
+ else if (face==GL_BACK) {
+ bitmask &= BACK_MATERIAL_BITS;
+ }
+ else if (face != GL_FRONT_AND_BACK) {
+ _mesa_error( ctx, GL_INVALID_ENUM, where );
+ return 0;
+ }
+
+ if (bitmask & ~legal) {
+ _mesa_error( ctx, GL_INVALID_ENUM, where );
+ return 0;
+ }
+
+ return bitmask;
+}
+
+
+
+/* Perform a straight copy between materials.
+ */
+void
+_mesa_copy_materials( struct gl_material *dst,
+ const struct gl_material *src,
+ GLuint bitmask )
+{
+ int i;
+
+ for (i = 0 ; i < MAT_ATTRIB_MAX ; i++)
+ if (bitmask & (1<<i))
+ COPY_4FV( dst->Attrib[i], src->Attrib[i] );
+}
+
+
+
+/* Update derived values following a change in ctx->Light.Material
+ */
+void
+_mesa_update_material( GLcontext *ctx, GLuint bitmask )
+{
+ struct gl_light *light, *list = &ctx->Light.EnabledList;
+ GLfloat (*mat)[4] = ctx->Light.Material.Attrib;
+
+ if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
+ _mesa_debug(ctx, "_mesa_update_material, mask 0x%x\n", bitmask);
+
+ if (!bitmask)
+ return;
+
+ /* update material ambience */
+ if (bitmask & MAT_BIT_FRONT_AMBIENT) {
+ foreach (light, list) {
+ SCALE_3V( light->_MatAmbient[0], light->Ambient,
+ mat[MAT_ATTRIB_FRONT_AMBIENT]);
+ }
+ }
+
+ if (bitmask & MAT_BIT_BACK_AMBIENT) {
+ foreach (light, list) {
+ SCALE_3V( light->_MatAmbient[1], light->Ambient,
+ mat[MAT_ATTRIB_BACK_AMBIENT]);
+ }
+ }
+
+ /* update BaseColor = emission + scene's ambience * material's ambience */
+ if (bitmask & (MAT_BIT_FRONT_EMISSION | MAT_BIT_FRONT_AMBIENT)) {
+ COPY_3V( ctx->Light._BaseColor[0], mat[MAT_ATTRIB_FRONT_EMISSION] );
+ ACC_SCALE_3V( ctx->Light._BaseColor[0], mat[MAT_ATTRIB_FRONT_AMBIENT],
+ ctx->Light.Model.Ambient );
+ }
+
+ if (bitmask & (MAT_BIT_BACK_EMISSION | MAT_BIT_BACK_AMBIENT)) {
+ COPY_3V( ctx->Light._BaseColor[1], mat[MAT_ATTRIB_BACK_EMISSION] );
+ ACC_SCALE_3V( ctx->Light._BaseColor[1], mat[MAT_ATTRIB_BACK_AMBIENT],
+ ctx->Light.Model.Ambient );
+ }
+
+ /* update material diffuse values */
+ if (bitmask & MAT_BIT_FRONT_DIFFUSE) {
+ foreach (light, list) {
+ SCALE_3V( light->_MatDiffuse[0], light->Diffuse,
+ mat[MAT_ATTRIB_FRONT_DIFFUSE] );
+ }
+ }
+
+ if (bitmask & MAT_BIT_BACK_DIFFUSE) {
+ foreach (light, list) {
+ SCALE_3V( light->_MatDiffuse[1], light->Diffuse,
+ mat[MAT_ATTRIB_BACK_DIFFUSE] );
+ }
+ }
+
+ /* update material specular values */
+ if (bitmask & MAT_BIT_FRONT_SPECULAR) {
+ foreach (light, list) {
+ SCALE_3V( light->_MatSpecular[0], light->Specular,
+ mat[MAT_ATTRIB_FRONT_SPECULAR]);
+ }
+ }
+
+ if (bitmask & MAT_BIT_BACK_SPECULAR) {
+ foreach (light, list) {
+ SCALE_3V( light->_MatSpecular[1], light->Specular,
+ mat[MAT_ATTRIB_BACK_SPECULAR]);
+ }
+ }
+
+ if (bitmask & MAT_BIT_FRONT_SHININESS) {
+ _mesa_invalidate_shine_table( ctx, 0 );
+ }
+
+ if (bitmask & MAT_BIT_BACK_SHININESS) {
+ _mesa_invalidate_shine_table( ctx, 1 );
+ }
+}
+
+
+/*
+ * Update the current materials from the given rgba color
+ * according to the bitmask in ColorMaterialBitmask, which is
+ * set by glColorMaterial().
+ */
+void
+_mesa_update_color_material( GLcontext *ctx, const GLfloat color[4] )
+{
+ GLuint bitmask = ctx->Light.ColorMaterialBitmask;
+ struct gl_material *mat = &ctx->Light.Material;
+ int i;
+
+ for (i = 0 ; i < MAT_ATTRIB_MAX ; i++)
+ if (bitmask & (1<<i))
+ COPY_4FV( mat->Attrib[i], color );
+
+ _mesa_update_material( ctx, bitmask );
+}
+
+
+void GLAPIENTRY
+_mesa_ColorMaterial( GLenum face, GLenum mode )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLuint bitmask;
+ GLuint legal = (MAT_BIT_FRONT_EMISSION | MAT_BIT_BACK_EMISSION |
+ MAT_BIT_FRONT_SPECULAR | MAT_BIT_BACK_SPECULAR |
+ MAT_BIT_FRONT_DIFFUSE | MAT_BIT_BACK_DIFFUSE |
+ MAT_BIT_FRONT_AMBIENT | MAT_BIT_BACK_AMBIENT);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (MESA_VERBOSE&VERBOSE_API)
+ _mesa_debug(ctx, "glColorMaterial %s %s\n",
+ _mesa_lookup_enum_by_nr(face),
+ _mesa_lookup_enum_by_nr(mode));
+
+ bitmask = _mesa_material_bitmask(ctx, face, mode, legal, "glColorMaterial");
+
+ if (ctx->Light.ColorMaterialBitmask == bitmask &&
+ ctx->Light.ColorMaterialFace == face &&
+ ctx->Light.ColorMaterialMode == mode)
+ return;
+
+ FLUSH_VERTICES(ctx, _NEW_LIGHT);
+ ctx->Light.ColorMaterialBitmask = bitmask;
+ ctx->Light.ColorMaterialFace = face;
+ ctx->Light.ColorMaterialMode = mode;
+
+ if (ctx->Light.ColorMaterialEnabled) {
+ FLUSH_CURRENT( ctx, 0 );
+ _mesa_update_color_material(ctx,ctx->Current.Attrib[VERT_ATTRIB_COLOR0]);
+ }
+
+ if (ctx->Driver.ColorMaterial)
+ (*ctx->Driver.ColorMaterial)( ctx, face, mode );
+}
+
+
+void GLAPIENTRY
+_mesa_GetMaterialfv( GLenum face, GLenum pname, GLfloat *params )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLuint f;
+ GLfloat (*mat)[4] = ctx->Light.Material.Attrib;
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* update materials */
+
+ FLUSH_CURRENT(ctx, 0); /* update ctx->Light.Material from vertex buffer */
+
+ if (face==GL_FRONT) {
+ f = 0;
+ }
+ else if (face==GL_BACK) {
+ f = 1;
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(face)" );
+ return;
+ }
+
+ switch (pname) {
+ case GL_AMBIENT:
+ COPY_4FV( params, mat[MAT_ATTRIB_AMBIENT(f)] );
+ break;
+ case GL_DIFFUSE:
+ COPY_4FV( params, mat[MAT_ATTRIB_DIFFUSE(f)] );
+ break;
+ case GL_SPECULAR:
+ COPY_4FV( params, mat[MAT_ATTRIB_SPECULAR(f)] );
+ break;
+ case GL_EMISSION:
+ COPY_4FV( params, mat[MAT_ATTRIB_EMISSION(f)] );
+ break;
+ case GL_SHININESS:
+ *params = mat[MAT_ATTRIB_SHININESS(f)][0];
+ break;
+ case GL_COLOR_INDEXES:
+ params[0] = mat[MAT_ATTRIB_INDEXES(f)][0];
+ params[1] = mat[MAT_ATTRIB_INDEXES(f)][1];
+ params[2] = mat[MAT_ATTRIB_INDEXES(f)][2];
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" );
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_GetMaterialiv( GLenum face, GLenum pname, GLint *params )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLuint f;
+ GLfloat (*mat)[4] = ctx->Light.Material.Attrib;
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* update materials */
+
+ FLUSH_CURRENT(ctx, 0); /* update ctx->Light.Material from vertex buffer */
+
+ if (face==GL_FRONT) {
+ f = 0;
+ }
+ else if (face==GL_BACK) {
+ f = 1;
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialiv(face)" );
+ return;
+ }
+ switch (pname) {
+ case GL_AMBIENT:
+ params[0] = FLOAT_TO_INT( mat[MAT_ATTRIB_AMBIENT(f)][0] );
+ params[1] = FLOAT_TO_INT( mat[MAT_ATTRIB_AMBIENT(f)][1] );
+ params[2] = FLOAT_TO_INT( mat[MAT_ATTRIB_AMBIENT(f)][2] );
+ params[3] = FLOAT_TO_INT( mat[MAT_ATTRIB_AMBIENT(f)][3] );
+ break;
+ case GL_DIFFUSE:
+ params[0] = FLOAT_TO_INT( mat[MAT_ATTRIB_DIFFUSE(f)][0] );
+ params[1] = FLOAT_TO_INT( mat[MAT_ATTRIB_DIFFUSE(f)][1] );
+ params[2] = FLOAT_TO_INT( mat[MAT_ATTRIB_DIFFUSE(f)][2] );
+ params[3] = FLOAT_TO_INT( mat[MAT_ATTRIB_DIFFUSE(f)][3] );
+ break;
+ case GL_SPECULAR:
+ params[0] = FLOAT_TO_INT( mat[MAT_ATTRIB_SPECULAR(f)][0] );
+ params[1] = FLOAT_TO_INT( mat[MAT_ATTRIB_SPECULAR(f)][1] );
+ params[2] = FLOAT_TO_INT( mat[MAT_ATTRIB_SPECULAR(f)][2] );
+ params[3] = FLOAT_TO_INT( mat[MAT_ATTRIB_SPECULAR(f)][3] );
+ break;
+ case GL_EMISSION:
+ params[0] = FLOAT_TO_INT( mat[MAT_ATTRIB_EMISSION(f)][0] );
+ params[1] = FLOAT_TO_INT( mat[MAT_ATTRIB_EMISSION(f)][1] );
+ params[2] = FLOAT_TO_INT( mat[MAT_ATTRIB_EMISSION(f)][2] );
+ params[3] = FLOAT_TO_INT( mat[MAT_ATTRIB_EMISSION(f)][3] );
+ break;
+ case GL_SHININESS:
+ *params = IROUND( mat[MAT_ATTRIB_SHININESS(f)][0] );
+ break;
+ case GL_COLOR_INDEXES:
+ params[0] = IROUND( mat[MAT_ATTRIB_INDEXES(f)][0] );
+ params[1] = IROUND( mat[MAT_ATTRIB_INDEXES(f)][1] );
+ params[2] = IROUND( mat[MAT_ATTRIB_INDEXES(f)][2] );
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" );
+ }
+}
+
+
+
+/**********************************************************************/
+/***** Lighting computation *****/
+/**********************************************************************/
+
+
+/*
+ * Notes:
+ * When two-sided lighting is enabled we compute the color (or index)
+ * for both the front and back side of the primitive. Then, when the
+ * orientation of the facet is later learned, we can determine which
+ * color (or index) to use for rendering.
+ *
+ * KW: We now know orientation in advance and only shade for
+ * the side or sides which are actually required.
+ *
+ * Variables:
+ * n = normal vector
+ * V = vertex position
+ * P = light source position
+ * Pe = (0,0,0,1)
+ *
+ * Precomputed:
+ * IF P[3]==0 THEN
+ * // light at infinity
+ * IF local_viewer THEN
+ * _VP_inf_norm = unit vector from V to P // Precompute
+ * ELSE
+ * // eye at infinity
+ * _h_inf_norm = Normalize( VP + <0,0,1> ) // Precompute
+ * ENDIF
+ * ENDIF
+ *
+ * Functions:
+ * Normalize( v ) = normalized vector v
+ * Magnitude( v ) = length of vector v
+ */
+
+
+
+/*
+ * Whenever the spotlight exponent for a light changes we must call
+ * this function to recompute the exponent lookup table.
+ */
+void
+_mesa_invalidate_spot_exp_table( struct gl_light *l )
+{
+ l->_SpotExpTable[0][0] = -1;
+}
+
+
+static void
+validate_spot_exp_table( struct gl_light *l )
+{
+ GLint i;
+ GLdouble exponent = l->SpotExponent;
+ GLdouble tmp = 0;
+ GLint clamp = 0;
+
+ l->_SpotExpTable[0][0] = 0.0;
+
+ for (i = EXP_TABLE_SIZE - 1; i > 0 ;i--) {
+ if (clamp == 0) {
+ tmp = _mesa_pow(i / (GLdouble) (EXP_TABLE_SIZE - 1), exponent);
+ if (tmp < FLT_MIN * 100.0) {
+ tmp = 0.0;
+ clamp = 1;
+ }
+ }
+ l->_SpotExpTable[i][0] = (GLfloat) tmp;
+ }
+ for (i = 0; i < EXP_TABLE_SIZE - 1; i++) {
+ l->_SpotExpTable[i][1] = (l->_SpotExpTable[i+1][0] -
+ l->_SpotExpTable[i][0]);
+ }
+ l->_SpotExpTable[EXP_TABLE_SIZE-1][1] = 0.0;
+}
+
+
+
+/* Calculate a new shine table. Doing this here saves a branch in
+ * lighting, and the cost of doing it early may be partially offset
+ * by keeping a MRU cache of shine tables for various shine values.
+ */
+void
+_mesa_invalidate_shine_table( GLcontext *ctx, GLuint side )
+{
+ ASSERT(side < 2);
+ if (ctx->_ShineTable[side])
+ ctx->_ShineTable[side]->refcount--;
+ ctx->_ShineTable[side] = NULL;
+}
+
+
+static void
+validate_shine_table( GLcontext *ctx, GLuint side, GLfloat shininess )
+{
+ struct gl_shine_tab *list = ctx->_ShineTabList;
+ struct gl_shine_tab *s;
+
+ ASSERT(side < 2);
+
+ foreach(s, list)
+ if ( s->shininess == shininess )
+ break;
+
+ if (s == list) {
+ GLint j;
+ GLfloat *m;
+
+ foreach(s, list)
+ if (s->refcount == 0)
+ break;
+
+ m = s->tab;
+ m[0] = 0.0;
+ if (shininess == 0.0) {
+ for (j = 1 ; j <= SHINE_TABLE_SIZE ; j++)
+ m[j] = 1.0;
+ }
+ else {
+ for (j = 1 ; j < SHINE_TABLE_SIZE ; j++) {
+ GLdouble t, x = j / (GLfloat) (SHINE_TABLE_SIZE - 1);
+ if (x < 0.005) /* underflow check */
+ x = 0.005;
+ t = _mesa_pow(x, shininess);
+ if (t > 1e-20)
+ m[j] = (GLfloat) t;
+ else
+ m[j] = 0.0;
+ }
+ m[SHINE_TABLE_SIZE] = 1.0;
+ }
+
+ s->shininess = shininess;
+ }
+
+ if (ctx->_ShineTable[side])
+ ctx->_ShineTable[side]->refcount--;
+
+ ctx->_ShineTable[side] = s;
+ move_to_tail( list, s );
+ s->refcount++;
+}
+
+
+void
+_mesa_validate_all_lighting_tables( GLcontext *ctx )
+{
+ GLuint i;
+ GLfloat shininess;
+
+ shininess = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SHININESS][0];
+ if (!ctx->_ShineTable[0] || ctx->_ShineTable[0]->shininess != shininess)
+ validate_shine_table( ctx, 0, shininess );
+
+ shininess = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_SHININESS][0];
+ if (!ctx->_ShineTable[1] || ctx->_ShineTable[1]->shininess != shininess)
+ validate_shine_table( ctx, 1, shininess );
+
+ for (i = 0; i < ctx->Const.MaxLights; i++)
+ if (ctx->Light.Light[i]._SpotExpTable[0][0] == -1)
+ validate_spot_exp_table( &ctx->Light.Light[i] );
+}
+
+
+/**
+ * Examine current lighting parameters to determine if the optimized lighting
+ * function can be used.
+ * Also, precompute some lighting values such as the products of light
+ * source and material ambient, diffuse and specular coefficients.
+ */
+void
+_mesa_update_lighting( GLcontext *ctx )
+{
+ struct gl_light *light;
+ ctx->Light._NeedEyeCoords = GL_FALSE;
+ ctx->Light._Flags = 0;
+
+ if (!ctx->Light.Enabled)
+ return;
+
+ foreach(light, &ctx->Light.EnabledList) {
+ ctx->Light._Flags |= light->_Flags;
+ }
+
+ ctx->Light._NeedVertices =
+ ((ctx->Light._Flags & (LIGHT_POSITIONAL|LIGHT_SPOT)) ||
+ ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR ||
+ ctx->Light.Model.LocalViewer);
+
+ ctx->Light._NeedEyeCoords = ((ctx->Light._Flags & LIGHT_POSITIONAL) ||
+ ctx->Light.Model.LocalViewer);
+
+ /* XXX: This test is overkill & needs to be fixed both for software and
+ * hardware t&l drivers. The above should be sufficient & should
+ * be tested to verify this.
+ */
+ if (ctx->Light._NeedVertices)
+ ctx->Light._NeedEyeCoords = GL_TRUE;
+
+ /* Precompute some shading values. Although we reference
+ * Light.Material here, we can get away without flushing
+ * FLUSH_UPDATE_CURRENT, as when any outstanding material changes
+ * are flushed, they will update the derived state at that time.
+ */
+ if (ctx->Visual.rgbMode) {
+ if (ctx->Light.Model.TwoSide)
+ _mesa_update_material( ctx,
+ MAT_BIT_FRONT_EMISSION |
+ MAT_BIT_FRONT_AMBIENT |
+ MAT_BIT_FRONT_DIFFUSE |
+ MAT_BIT_FRONT_SPECULAR |
+ MAT_BIT_BACK_EMISSION |
+ MAT_BIT_BACK_AMBIENT |
+ MAT_BIT_BACK_DIFFUSE |
+ MAT_BIT_BACK_SPECULAR);
+ else
+ _mesa_update_material( ctx,
+ MAT_BIT_FRONT_EMISSION |
+ MAT_BIT_FRONT_AMBIENT |
+ MAT_BIT_FRONT_DIFFUSE |
+ MAT_BIT_FRONT_SPECULAR);
+ }
+ else {
+ static const GLfloat ci[3] = { .30F, .59F, .11F };
+ foreach(light, &ctx->Light.EnabledList) {
+ light->_dli = DOT3(ci, light->Diffuse);
+ light->_sli = DOT3(ci, light->Specular);
+ }
+ }
+}
+
+
+/**
+ * Update state derived from light position, spot direction.
+ * Called upon:
+ * _NEW_MODELVIEW
+ * _NEW_LIGHT
+ * _TNL_NEW_NEED_EYE_COORDS
+ *
+ * Update on (_NEW_MODELVIEW | _NEW_LIGHT) when lighting is enabled.
+ * Also update on lighting space changes.
+ */
+static void
+compute_light_positions( GLcontext *ctx )
+{
+ struct gl_light *light;
+ static const GLfloat eye_z[3] = { 0, 0, 1 };
+
+ if (!ctx->Light.Enabled)
+ return;
+
+ if (ctx->_NeedEyeCoords) {
+ COPY_3V( ctx->_EyeZDir, eye_z );
+ }
+ else {
+ TRANSFORM_NORMAL( ctx->_EyeZDir, eye_z, ctx->ModelviewMatrixStack.Top->m );
+ }
+
+ foreach (light, &ctx->Light.EnabledList) {
+
+ if (ctx->_NeedEyeCoords) {
+ /* _Position is in eye coordinate space */
+ COPY_4FV( light->_Position, light->EyePosition );
+ }
+ else {
+ /* _Position is in object coordinate space */
+ TRANSFORM_POINT( light->_Position, ctx->ModelviewMatrixStack.Top->inv,
+ light->EyePosition );
+ }
+
+ if (!(light->_Flags & LIGHT_POSITIONAL)) {
+ /* VP (VP) = Normalize( Position ) */
+ COPY_3V( light->_VP_inf_norm, light->_Position );
+ NORMALIZE_3FV( light->_VP_inf_norm );
+
+ if (!ctx->Light.Model.LocalViewer) {
+ /* _h_inf_norm = Normalize( V_to_P + <0,0,1> ) */
+ ADD_3V( light->_h_inf_norm, light->_VP_inf_norm, ctx->_EyeZDir);
+ NORMALIZE_3FV( light->_h_inf_norm );
+ }
+ light->_VP_inf_spot_attenuation = 1.0;
+ }
+
+ if (light->_Flags & LIGHT_SPOT) {
+ if (ctx->_NeedEyeCoords) {
+ COPY_3V( light->_NormDirection, light->EyeDirection );
+ }
+ else {
+ TRANSFORM_NORMAL( light->_NormDirection,
+ light->EyeDirection,
+ ctx->ModelviewMatrixStack.Top->m);
+ }
+
+ NORMALIZE_3FV( light->_NormDirection );
+
+ if (!(light->_Flags & LIGHT_POSITIONAL)) {
+ GLfloat PV_dot_dir = - DOT3(light->_VP_inf_norm,
+ light->_NormDirection);
+
+ if (PV_dot_dir > light->_CosCutoff) {
+ double x = PV_dot_dir * (EXP_TABLE_SIZE-1);
+ int k = (int) x;
+ light->_VP_inf_spot_attenuation =
+ (GLfloat) (light->_SpotExpTable[k][0] +
+ (x-k)*light->_SpotExpTable[k][1]);
+ }
+ else {
+ light->_VP_inf_spot_attenuation = 0;
+ }
+ }
+ }
+ }
+}
+
+
+
+static void
+update_modelview_scale( GLcontext *ctx )
+{
+ ctx->_ModelViewInvScale = 1.0F;
+ if (!_math_matrix_is_length_preserving(ctx->ModelviewMatrixStack.Top)) {
+ const GLfloat *m = ctx->ModelviewMatrixStack.Top->inv;
+ GLfloat f = m[2] * m[2] + m[6] * m[6] + m[10] * m[10];
+ if (f < 1e-12) f = 1.0;
+ if (ctx->_NeedEyeCoords)
+ ctx->_ModelViewInvScale = (GLfloat) INV_SQRTF(f);
+ else
+ ctx->_ModelViewInvScale = (GLfloat) SQRTF(f);
+ }
+}
+
+
+/**
+ * Bring up to date any state that relies on _NeedEyeCoords.
+ */
+void
+_mesa_update_tnl_spaces( GLcontext *ctx, GLuint new_state )
+{
+ const GLuint oldneedeyecoords = ctx->_NeedEyeCoords;
+
+ (void) new_state;
+ ctx->_NeedEyeCoords = GL_FALSE;
+
+ if (ctx->_ForceEyeCoords ||
+ (ctx->Texture._GenFlags & TEXGEN_NEED_EYE_COORD) ||
+ ctx->Point._Attenuated ||
+ ctx->Light._NeedEyeCoords)
+ ctx->_NeedEyeCoords = GL_TRUE;
+
+ if (ctx->Light.Enabled &&
+ !_math_matrix_is_length_preserving(ctx->ModelviewMatrixStack.Top))
+ ctx->_NeedEyeCoords = GL_TRUE;
+
+ /* Check if the truth-value interpretations of the bitfields have
+ * changed:
+ */
+ if (oldneedeyecoords != ctx->_NeedEyeCoords) {
+ /* Recalculate all state that depends on _NeedEyeCoords.
+ */
+ update_modelview_scale(ctx);
+ compute_light_positions( ctx );
+
+ if (ctx->Driver.LightingSpaceChange)
+ ctx->Driver.LightingSpaceChange( ctx );
+ }
+ else {
+ GLuint new_state = ctx->NewState;
+
+ /* Recalculate that same state only if it has been invalidated
+ * by other statechanges.
+ */
+ if (new_state & _NEW_MODELVIEW)
+ update_modelview_scale(ctx);
+
+ if (new_state & (_NEW_LIGHT|_NEW_MODELVIEW))
+ compute_light_positions( ctx );
+ }
+}
+
+
+/**
+ * Drivers may need this if the hardware tnl unit doesn't support the
+ * light-in-modelspace optimization. It's also useful for debugging.
+ */
+void
+_mesa_allow_light_in_model( GLcontext *ctx, GLboolean flag )
+{
+ ctx->_ForceEyeCoords = !flag;
+ ctx->NewState |= _NEW_POINT; /* one of the bits from
+ * _MESA_NEW_NEED_EYE_COORDS.
+ */
+}
+
+
+
+/**********************************************************************/
+/***** Initialization *****/
+/**********************************************************************/
+
+/**
+ * Initialize the n-th light data structure.
+ *
+ * \param l pointer to the gl_light structure to be initialized.
+ * \param n number of the light.
+ * \note The defaults for light 0 are different than the other lights.
+ */
+static void
+init_light( struct gl_light *l, GLuint n )
+{
+ make_empty_list( l );
+
+ ASSIGN_4V( l->Ambient, 0.0, 0.0, 0.0, 1.0 );
+ if (n==0) {
+ ASSIGN_4V( l->Diffuse, 1.0, 1.0, 1.0, 1.0 );
+ ASSIGN_4V( l->Specular, 1.0, 1.0, 1.0, 1.0 );
+ }
+ else {
+ ASSIGN_4V( l->Diffuse, 0.0, 0.0, 0.0, 1.0 );
+ ASSIGN_4V( l->Specular, 0.0, 0.0, 0.0, 1.0 );
+ }
+ ASSIGN_4V( l->EyePosition, 0.0, 0.0, 1.0, 0.0 );
+ ASSIGN_3V( l->EyeDirection, 0.0, 0.0, -1.0 );
+ l->SpotExponent = 0.0;
+ _mesa_invalidate_spot_exp_table( l );
+ l->SpotCutoff = 180.0;
+ l->_CosCutoffNeg = -1.0f;
+ l->_CosCutoff = 0.0; /* KW: -ve values not admitted */
+ l->ConstantAttenuation = 1.0;
+ l->LinearAttenuation = 0.0;
+ l->QuadraticAttenuation = 0.0;
+ l->Enabled = GL_FALSE;
+}
+
+
+/**
+ * Initialize the light model data structure.
+ *
+ * \param lm pointer to the gl_lightmodel structure to be initialized.
+ */
+static void
+init_lightmodel( struct gl_lightmodel *lm )
+{
+ ASSIGN_4V( lm->Ambient, 0.2F, 0.2F, 0.2F, 1.0F );
+ lm->LocalViewer = GL_FALSE;
+ lm->TwoSide = GL_FALSE;
+ lm->ColorControl = GL_SINGLE_COLOR;
+}
+
+
+/**
+ * Initialize the material data structure.
+ *
+ * \param m pointer to the gl_material structure to be initialized.
+ */
+static void
+init_material( struct gl_material *m )
+{
+ ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_AMBIENT], 0.2F, 0.2F, 0.2F, 1.0F );
+ ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_DIFFUSE], 0.8F, 0.8F, 0.8F, 1.0F );
+ ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_SPECULAR], 0.0F, 0.0F, 0.0F, 1.0F );
+ ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_EMISSION], 0.0F, 0.0F, 0.0F, 1.0F );
+ ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_SHININESS], 0.0F, 0.0F, 0.0F, 0.0F );
+ ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_INDEXES], 0.0F, 1.0F, 1.0F, 0.0F );
+
+ ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_AMBIENT], 0.2F, 0.2F, 0.2F, 1.0F );
+ ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_DIFFUSE], 0.8F, 0.8F, 0.8F, 1.0F );
+ ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_SPECULAR], 0.0F, 0.0F, 0.0F, 1.0F );
+ ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_EMISSION], 0.0F, 0.0F, 0.0F, 1.0F );
+ ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_SHININESS], 0.0F, 0.0F, 0.0F, 0.0F );
+ ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_INDEXES], 0.0F, 1.0F, 1.0F, 0.0F );
+}
+
+
+/**
+ * Initialize all lighting state for the given context.
+ */
+void
+_mesa_init_lighting( GLcontext *ctx )
+{
+ GLuint i;
+
+ /* Lighting group */
+ for (i = 0; i < MAX_LIGHTS; i++) {
+ init_light( &ctx->Light.Light[i], i );
+ }
+ make_empty_list( &ctx->Light.EnabledList );
+
+ init_lightmodel( &ctx->Light.Model );
+ init_material( &ctx->Light.Material );
+ ctx->Light.ShadeModel = GL_SMOOTH;
+ ctx->Light.Enabled = GL_FALSE;
+ ctx->Light.ColorMaterialFace = GL_FRONT_AND_BACK;
+ ctx->Light.ColorMaterialMode = GL_AMBIENT_AND_DIFFUSE;
+ ctx->Light.ColorMaterialBitmask = _mesa_material_bitmask( ctx,
+ GL_FRONT_AND_BACK,
+ GL_AMBIENT_AND_DIFFUSE, ~0,
+ NULL );
+
+ ctx->Light.ColorMaterialEnabled = GL_FALSE;
+
+ /* Lighting miscellaneous */
+ ctx->_ShineTabList = MALLOC_STRUCT( gl_shine_tab );
+ make_empty_list( ctx->_ShineTabList );
+ /* Allocate 10 (arbitrary) shininess lookup tables */
+ for (i = 0 ; i < 10 ; i++) {
+ struct gl_shine_tab *s = MALLOC_STRUCT( gl_shine_tab );
+ s->shininess = -1;
+ s->refcount = 0;
+ insert_at_tail( ctx->_ShineTabList, s );
+ }
+
+ /* Miscellaneous */
+ ctx->Light._NeedEyeCoords = GL_FALSE;
+ ctx->_NeedEyeCoords = GL_FALSE;
+ ctx->_ModelViewInvScale = 1.0;
+}
+
+
+/**
+ * Deallocate malloc'd lighting state attached to given context.
+ */
+void
+_mesa_free_lighting_data( GLcontext *ctx )
+{
+ struct gl_shine_tab *s, *tmps;
+
+ /* Free lighting shininess exponentiation table */
+ foreach_s( s, tmps, ctx->_ShineTabList ) {
+ _mesa_free( s );
+ }
+ _mesa_free( ctx->_ShineTabList );
+}
diff --git a/src/mesa/main/light.h b/src/mesa/main/light.h
new file mode 100644
index 00000000000..f47fe58a839
--- /dev/null
+++ b/src/mesa/main/light.h
@@ -0,0 +1,145 @@
+/**
+ * \file light.h
+ * Lighting.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.5
+ *
+ * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef LIGHT_H
+#define LIGHT_H
+
+
+#include "mtypes.h"
+
+extern void GLAPIENTRY
+_mesa_ShadeModel( GLenum mode );
+
+#if _HAVE_FULL_GL
+extern void GLAPIENTRY
+_mesa_ColorMaterial( GLenum face, GLenum mode );
+
+extern void GLAPIENTRY
+_mesa_Lightf( GLenum light, GLenum pname, GLfloat param );
+
+extern void GLAPIENTRY
+_mesa_Lightfv( GLenum light, GLenum pname, const GLfloat *params );
+
+extern void GLAPIENTRY
+_mesa_Lightiv( GLenum light, GLenum pname, const GLint *params );
+
+extern void GLAPIENTRY
+_mesa_Lighti( GLenum light, GLenum pname, GLint param );
+
+extern void GLAPIENTRY
+_mesa_LightModelf( GLenum pname, GLfloat param );
+
+extern void GLAPIENTRY
+_mesa_LightModelfv( GLenum pname, const GLfloat *params );
+
+extern void GLAPIENTRY
+_mesa_LightModeli( GLenum pname, GLint param );
+
+extern void GLAPIENTRY
+_mesa_LightModeliv( GLenum pname, const GLint *params );
+
+extern void GLAPIENTRY
+_mesa_GetLightfv( GLenum light, GLenum pname, GLfloat *params );
+
+extern void GLAPIENTRY
+_mesa_GetLightiv( GLenum light, GLenum pname, GLint *params );
+
+extern void GLAPIENTRY
+_mesa_GetMaterialfv( GLenum face, GLenum pname, GLfloat *params );
+
+extern void GLAPIENTRY
+_mesa_GetMaterialiv( GLenum face, GLenum pname, GLint *params );
+
+
+extern void
+_mesa_light(GLcontext *ctx, GLuint lnum, GLenum pname, const GLfloat *params);
+
+
+/* Lerp between adjacent values in the f(x) lookup table, giving a
+ * continuous function, with adequeate overall accuracy. (Though
+ * still pretty good compared to a straight lookup).
+ * Result should be a GLfloat.
+ */
+#define GET_SHINE_TAB_ENTRY( table, dp, result ) \
+do { \
+ struct gl_shine_tab *_tab = table; \
+ float f = (dp * (SHINE_TABLE_SIZE-1)); \
+ int k = (int) f; \
+ if (k > SHINE_TABLE_SIZE-2) \
+ result = (GLfloat) _mesa_pow( dp, _tab->shininess ); \
+ else \
+ result = _tab->tab[k] + (f-k)*(_tab->tab[k+1]-_tab->tab[k]); \
+} while (0)
+
+
+extern GLuint _mesa_material_bitmask( GLcontext *ctx,
+ GLenum face, GLenum pname,
+ GLuint legal,
+ const char * );
+
+extern void _mesa_invalidate_spot_exp_table( struct gl_light *l );
+
+extern void _mesa_invalidate_shine_table( GLcontext *ctx, GLuint i );
+
+extern void _mesa_validate_all_lighting_tables( GLcontext *ctx );
+
+extern void _mesa_update_lighting( GLcontext *ctx );
+
+extern void _mesa_update_tnl_spaces( GLcontext *ctx, GLuint new_state );
+
+extern void _mesa_update_material( GLcontext *ctx,
+ GLuint bitmask );
+
+extern void _mesa_copy_materials( struct gl_material *dst,
+ const struct gl_material *src,
+ GLuint bitmask );
+
+extern void _mesa_update_color_material( GLcontext *ctx,
+ const GLfloat rgba[4] );
+
+extern void _mesa_init_lighting( GLcontext *ctx );
+
+extern void _mesa_free_lighting_data( GLcontext *ctx );
+
+extern void _mesa_allow_light_in_model( GLcontext *ctx, GLboolean flag );
+
+#else
+#define _mesa_update_color_material( c, r ) ((void)0)
+#define _mesa_validate_all_lighting_tables( c ) ((void)0)
+#define _mesa_invalidate_spot_exp_table( l ) ((void)0)
+#define _mesa_material_bitmask( c, f, p, l, s ) 0
+#define _mesa_init_lighting( c ) ((void)0)
+#define _mesa_free_lighting_data( c ) ((void)0)
+#define _mesa_update_lighting( c ) ((void)0)
+#define _mesa_update_tnl_spaces( c, n ) ((void)0)
+#define GET_SHINE_TAB_ENTRY( table, dp, result ) ((result)=0)
+#endif
+
+#endif
diff --git a/src/mesa/main/lines.c b/src/mesa/main/lines.c
new file mode 100644
index 00000000000..c30d9ac109e
--- /dev/null
+++ b/src/mesa/main/lines.c
@@ -0,0 +1,134 @@
+/**
+ * \file lines.c
+ * Line operations.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 5.1
+ *
+ * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include "glheader.h"
+#include "context.h"
+#include "depth.h"
+#include "lines.h"
+#include "macros.h"
+#include "texstate.h"
+#include "mtypes.h"
+
+
+/**
+ * Set the line width.
+ *
+ * \param width line width in pixels.
+ *
+ * \sa glLineWidth().
+ *
+ * Verifies the parameter and updates gl_line_attrib::Width. On a change,
+ * flushes the vertices, updates the clamped line width and marks the
+ * DD_LINE_WIDTH flag in __GLcontextRec::_TriangleCaps for the drivers if the
+ * width is different from one. Notifies the driver via the
+ * dd_function_table::LineWidth callback.
+ */
+void GLAPIENTRY
+_mesa_LineWidth( GLfloat width )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (width<=0.0) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glLineWidth" );
+ return;
+ }
+
+ if (ctx->Line.Width == width)
+ return;
+
+ FLUSH_VERTICES(ctx, _NEW_LINE);
+ ctx->Line.Width = width;
+ ctx->Line._Width = CLAMP(width,
+ ctx->Const.MinLineWidth,
+ ctx->Const.MaxLineWidth);
+
+
+ if (width != 1.0)
+ ctx->_TriangleCaps |= DD_LINE_WIDTH;
+ else
+ ctx->_TriangleCaps &= ~DD_LINE_WIDTH;
+
+ if (ctx->Driver.LineWidth)
+ (*ctx->Driver.LineWidth)(ctx, width);
+}
+
+
+/**
+ * Set the line stipple pattern.
+ *
+ * \param factor pattern scale factor.
+ * \param pattern bit pattern.
+ *
+ * \sa glLineStipple().
+ *
+ * Updates gl_line_attrib::StippleFactor and gl_line_attrib::StipplePattern. On
+ * change flushes the vertices and notifies the driver via
+ * the dd_function_table::LineStipple callback.
+ */
+void GLAPIENTRY
+_mesa_LineStipple( GLint factor, GLushort pattern )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ factor = CLAMP( factor, 1, 256 );
+
+ if (ctx->Line.StippleFactor == factor &&
+ ctx->Line.StipplePattern == pattern)
+ return;
+
+ FLUSH_VERTICES(ctx, _NEW_LINE);
+ ctx->Line.StippleFactor = factor;
+ ctx->Line.StipplePattern = pattern;
+
+ if (ctx->Driver.LineStipple)
+ ctx->Driver.LineStipple( ctx, factor, pattern );
+}
+
+
+/**
+ * Initialize the context line state.
+ *
+ * \param ctx GL context.
+ *
+ * Initializes __GLcontextRec::Line and line related constants in
+ * __GLcontextRec::Const.
+ */
+void GLAPIENTRY _mesa_init_line( GLcontext * ctx )
+{
+ /* Line group */
+ ctx->Line.SmoothFlag = GL_FALSE;
+ ctx->Line.StippleFlag = GL_FALSE;
+ ctx->Line.Width = 1.0;
+ ctx->Line._Width = 1.0;
+ ctx->Line.StipplePattern = 0xffff;
+ ctx->Line.StippleFactor = 1;
+}
diff --git a/src/mesa/main/lines.h b/src/mesa/main/lines.h
new file mode 100644
index 00000000000..5a47e9858d5
--- /dev/null
+++ b/src/mesa/main/lines.h
@@ -0,0 +1,48 @@
+/**
+ * \file lines.h
+ * Line operations.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.5
+ *
+ * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+#ifndef LINES_H
+#define LINES_H
+
+
+#include "mtypes.h"
+
+
+extern void GLAPIENTRY
+_mesa_LineWidth( GLfloat width );
+
+extern void GLAPIENTRY
+_mesa_LineStipple( GLint factor, GLushort pattern );
+
+extern void GLAPIENTRY
+_mesa_init_line( GLcontext * ctx );
+
+#endif
diff --git a/src/mesa/main/macros.h b/src/mesa/main/macros.h
new file mode 100644
index 00000000000..672a2f8bd2f
--- /dev/null
+++ b/src/mesa/main/macros.h
@@ -0,0 +1,658 @@
+/**
+ * \file macros.h
+ * A collection of useful macros.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef MACROS_H
+#define MACROS_H
+
+#include "imports.h"
+
+
+/**
+ * \name Integer / float conversion for colors, normals, etc.
+ */
+/*@{*/
+
+/** Convert GLubyte in [0,255] to GLfloat in [0.0,1.0] */
+extern GLfloat _mesa_ubyte_to_float_color_tab[256];
+#define UBYTE_TO_FLOAT(u) _mesa_ubyte_to_float_color_tab[(unsigned int)(u)]
+
+/** Convert GLfloat in [0.0,1.0] to GLubyte in [0,255] */
+#define FLOAT_TO_UBYTE(X) ((GLubyte) (GLint) ((X) * 255.0F))
+
+
+/** Convert GLbyte in [-128,127] to GLfloat in [-1.0,1.0] */
+#define BYTE_TO_FLOAT(B) ((2.0F * (B) + 1.0F) * (1.0F/255.0F))
+
+/** Convert GLfloat in [-1.0,1.0] to GLbyte in [-128,127] */
+#define FLOAT_TO_BYTE(X) ( (((GLint) (255.0F * (X))) - 1) / 2 )
+
+
+/** Convert GLushort in [0,65536] to GLfloat in [0.0,1.0] */
+#define USHORT_TO_FLOAT(S) ((GLfloat) (S) * (1.0F / 65535.0F))
+
+/** Convert GLshort in [-32768,32767] to GLfloat in [-1.0,1.0] */
+#define SHORT_TO_FLOAT(S) ((2.0F * (S) + 1.0F) * (1.0F/65535.0F))
+
+/** Convert GLfloat in [0.0,1.0] to GLshort in [-32768,32767] */
+#define FLOAT_TO_SHORT(X) ( (((GLint) (65535.0F * (X))) - 1) / 2 )
+
+
+/** Convert GLuint in [0,4294967295] to GLfloat in [0.0,1.0] */
+#define UINT_TO_FLOAT(U) ((GLfloat) (U) * (1.0F / 4294967295.0F))
+
+/** Convert GLfloat in [0.0,1.0] to GLuint in [0,4294967295] */
+#define FLOAT_TO_UINT(X) ((GLuint) ((X) * 4294967295.0))
+
+
+/** Convert GLint in [-2147483648,2147483647] to GLfloat in [-1.0,1.0] */
+#define INT_TO_FLOAT(I) ((2.0F * (I) + 1.0F) * (1.0F/4294967294.0F))
+
+/** Convert GLfloat in [-1.0,1.0] to GLint in [-2147483648,2147483647] */
+/* causes overflow:
+#define FLOAT_TO_INT(X) ( (((GLint) (4294967294.0F * (X))) - 1) / 2 )
+*/
+/* a close approximation: */
+#define FLOAT_TO_INT(X) ( (GLint) (2147483647.0 * (X)) )
+
+
+#define BYTE_TO_UBYTE(b) ((GLubyte) ((b) < 0 ? 0 : (GLubyte) (b)))
+#define SHORT_TO_UBYTE(s) ((GLubyte) ((s) < 0 ? 0 : (GLubyte) ((s) >> 7)))
+#define USHORT_TO_UBYTE(s) ((GLubyte) ((s) >> 8))
+#define INT_TO_UBYTE(i) ((GLubyte) ((i) < 0 ? 0 : (GLubyte) ((i) >> 23)))
+#define UINT_TO_UBYTE(i) ((GLubyte) ((i) >> 24))
+
+
+#define BYTE_TO_USHORT(b) ((b) < 0 ? 0 : ((GLushort) (((b) * 65535) / 255)))
+#define UBYTE_TO_USHORT(b) (((GLushort) (b) << 8) | (GLushort) (b))
+#define SHORT_TO_USHORT(s) ((s) < 0 ? 0 : ((GLushort) (((s) * 65535 / 32767))))
+#define INT_TO_USHORT(i) ((i) < 0 ? 0 : ((GLushort) ((i) >> 15)))
+#define UINT_TO_USHORT(i) ((i) < 0 ? 0 : ((GLushort) ((i) >> 16)))
+#define UNCLAMPED_FLOAT_TO_USHORT(us, f) \
+ us = ( (GLushort) IROUND( CLAMP((f), 0.0, 1.0) * 65535.0F) )
+#define CLAMPED_FLOAT_TO_USHORT(us, f) \
+ us = ( (GLushort) IROUND( (f) * 65535.0F) )
+
+/*@}*/
+
+
+/** Stepping a GLfloat pointer by a byte stride */
+#define STRIDE_F(p, i) (p = (GLfloat *)((GLubyte *)p + i))
+/** Stepping a GLuint pointer by a byte stride */
+#define STRIDE_UI(p, i) (p = (GLuint *)((GLubyte *)p + i))
+/** Stepping a GLubyte[4] pointer by a byte stride */
+#define STRIDE_4UB(p, i) (p = (GLubyte (*)[4])((GLubyte *)p + i))
+/** Stepping a GLfloat[4] pointer by a byte stride */
+#define STRIDE_4F(p, i) (p = (GLfloat (*)[4])((GLubyte *)p + i))
+/** Stepping a GLchan[4] pointer by a byte stride */
+#define STRIDE_4CHAN(p, i) (p = (GLchan (*)[4])((GLubyte *)p + i))
+/** Stepping a GLchan pointer by a byte stride */
+#define STRIDE_CHAN(p, i) (p = (GLchan *)((GLubyte *)p + i))
+/** Stepping a \p t pointer by a byte stride */
+#define STRIDE_T(p, t, i) (p = (t)((GLubyte *)p + i))
+
+
+/**********************************************************************/
+/** \name 4-element vector operations */
+/*@{*/
+
+/** Zero */
+#define ZERO_4V( DST ) (DST)[0] = (DST)[1] = (DST)[2] = (DST)[3] = 0
+
+/** Test for equality */
+#define TEST_EQ_4V(a,b) ((a)[0] == (b)[0] && \
+ (a)[1] == (b)[1] && \
+ (a)[2] == (b)[2] && \
+ (a)[3] == (b)[3])
+
+/** Test for equality (unsigned bytes) */
+#if defined(__i386__)
+#define TEST_EQ_4UBV(DST, SRC) *((GLuint*)(DST)) == *((GLuint*)(SRC))
+#else
+#define TEST_EQ_4UBV(DST, SRC) TEST_EQ_4V(DST, SRC)
+#endif
+
+/** Copy a 4-element vector */
+#define COPY_4V( DST, SRC ) \
+do { \
+ (DST)[0] = (SRC)[0]; \
+ (DST)[1] = (SRC)[1]; \
+ (DST)[2] = (SRC)[2]; \
+ (DST)[3] = (SRC)[3]; \
+} while (0)
+
+/** Copy a 4-element vector with cast */
+#define COPY_4V_CAST( DST, SRC, CAST ) \
+do { \
+ (DST)[0] = (CAST)(SRC)[0]; \
+ (DST)[1] = (CAST)(SRC)[1]; \
+ (DST)[2] = (CAST)(SRC)[2]; \
+ (DST)[3] = (CAST)(SRC)[3]; \
+} while (0)
+
+/** Copy a 4-element unsigned byte vector */
+#if defined(__i386__)
+#define COPY_4UBV(DST, SRC) \
+do { \
+ *((GLuint*)(DST)) = *((GLuint*)(SRC)); \
+} while (0)
+#else
+/* The GLuint cast might fail if DST or SRC are not dword-aligned (RISC) */
+#define COPY_4UBV(DST, SRC) \
+do { \
+ (DST)[0] = (SRC)[0]; \
+ (DST)[1] = (SRC)[1]; \
+ (DST)[2] = (SRC)[2]; \
+ (DST)[3] = (SRC)[3]; \
+} while (0)
+#endif
+
+/**
+ * Copy a 4-element float vector (avoid using FPU registers)
+ * XXX Could use two 64-bit moves on 64-bit systems
+ */
+#define COPY_4FV( DST, SRC ) \
+do { \
+ const GLuint *_s = (const GLuint *) (SRC); \
+ GLuint *_d = (GLuint *) (DST); \
+ _d[0] = _s[0]; \
+ _d[1] = _s[1]; \
+ _d[2] = _s[2]; \
+ _d[3] = _s[3]; \
+} while (0)
+
+/** Copy \p SZ elements into a 4-element vector */
+#define COPY_SZ_4V(DST, SZ, SRC) \
+do { \
+ switch (SZ) { \
+ case 4: (DST)[3] = (SRC)[3]; \
+ case 3: (DST)[2] = (SRC)[2]; \
+ case 2: (DST)[1] = (SRC)[1]; \
+ case 1: (DST)[0] = (SRC)[0]; \
+ } \
+} while(0)
+
+/** Copy \p SZ elements into a homegeneous (4-element) vector, giving
+ * default values to the remaining */
+#define COPY_CLEAN_4V(DST, SZ, SRC) \
+do { \
+ ASSIGN_4V( DST, 0, 0, 0, 1 ); \
+ COPY_SZ_4V( DST, SZ, SRC ); \
+} while (0)
+
+/** Subtraction */
+#define SUB_4V( DST, SRCA, SRCB ) \
+do { \
+ (DST)[0] = (SRCA)[0] - (SRCB)[0]; \
+ (DST)[1] = (SRCA)[1] - (SRCB)[1]; \
+ (DST)[2] = (SRCA)[2] - (SRCB)[2]; \
+ (DST)[3] = (SRCA)[3] - (SRCB)[3]; \
+} while (0)
+
+/** Addition */
+#define ADD_4V( DST, SRCA, SRCB ) \
+do { \
+ (DST)[0] = (SRCA)[0] + (SRCB)[0]; \
+ (DST)[1] = (SRCA)[1] + (SRCB)[1]; \
+ (DST)[2] = (SRCA)[2] + (SRCB)[2]; \
+ (DST)[3] = (SRCA)[3] + (SRCB)[3]; \
+} while (0)
+
+/** Element-wise multiplication */
+#define SCALE_4V( DST, SRCA, SRCB ) \
+do { \
+ (DST)[0] = (SRCA)[0] * (SRCB)[0]; \
+ (DST)[1] = (SRCA)[1] * (SRCB)[1]; \
+ (DST)[2] = (SRCA)[2] * (SRCB)[2]; \
+ (DST)[3] = (SRCA)[3] * (SRCB)[3]; \
+} while (0)
+
+/** In-place addition */
+#define ACC_4V( DST, SRC ) \
+do { \
+ (DST)[0] += (SRC)[0]; \
+ (DST)[1] += (SRC)[1]; \
+ (DST)[2] += (SRC)[2]; \
+ (DST)[3] += (SRC)[3]; \
+} while (0)
+
+/** Element-wise multiplication and addition */
+#define ACC_SCALE_4V( DST, SRCA, SRCB ) \
+do { \
+ (DST)[0] += (SRCA)[0] * (SRCB)[0]; \
+ (DST)[1] += (SRCA)[1] * (SRCB)[1]; \
+ (DST)[2] += (SRCA)[2] * (SRCB)[2]; \
+ (DST)[3] += (SRCA)[3] * (SRCB)[3]; \
+} while (0)
+
+/** In-place scalar multiplication and addition */
+#define ACC_SCALE_SCALAR_4V( DST, S, SRCB ) \
+do { \
+ (DST)[0] += S * (SRCB)[0]; \
+ (DST)[1] += S * (SRCB)[1]; \
+ (DST)[2] += S * (SRCB)[2]; \
+ (DST)[3] += S * (SRCB)[3]; \
+} while (0)
+
+/** Scalar multiplication */
+#define SCALE_SCALAR_4V( DST, S, SRCB ) \
+do { \
+ (DST)[0] = S * (SRCB)[0]; \
+ (DST)[1] = S * (SRCB)[1]; \
+ (DST)[2] = S * (SRCB)[2]; \
+ (DST)[3] = S * (SRCB)[3]; \
+} while (0)
+
+/** In-place scalar multiplication */
+#define SELF_SCALE_SCALAR_4V( DST, S ) \
+do { \
+ (DST)[0] *= S; \
+ (DST)[1] *= S; \
+ (DST)[2] *= S; \
+ (DST)[3] *= S; \
+} while (0)
+
+/** Assignment */
+#define ASSIGN_4V( V, V0, V1, V2, V3 ) \
+do { \
+ V[0] = V0; \
+ V[1] = V1; \
+ V[2] = V2; \
+ V[3] = V3; \
+} while(0)
+
+/*@}*/
+
+
+/**********************************************************************/
+/** \name 3-element vector operations*/
+/*@{*/
+
+/** Zero */
+#define ZERO_3V( DST ) (DST)[0] = (DST)[1] = (DST)[2] = 0
+
+/** Test for equality */
+#define TEST_EQ_3V(a,b) \
+ ((a)[0] == (b)[0] && \
+ (a)[1] == (b)[1] && \
+ (a)[2] == (b)[2])
+
+/** Copy a 3-element vector */
+#define COPY_3V( DST, SRC ) \
+do { \
+ (DST)[0] = (SRC)[0]; \
+ (DST)[1] = (SRC)[1]; \
+ (DST)[2] = (SRC)[2]; \
+} while (0)
+
+/** Copy a 3-element vector with cast */
+#define COPY_3V_CAST( DST, SRC, CAST ) \
+do { \
+ (DST)[0] = (CAST)(SRC)[0]; \
+ (DST)[1] = (CAST)(SRC)[1]; \
+ (DST)[2] = (CAST)(SRC)[2]; \
+} while (0)
+
+/** Copy a 3-element float vector */
+#define COPY_3FV( DST, SRC ) \
+do { \
+ const GLfloat *_tmp = (SRC); \
+ (DST)[0] = _tmp[0]; \
+ (DST)[1] = _tmp[1]; \
+ (DST)[2] = _tmp[2]; \
+} while (0)
+
+/** Subtraction */
+#define SUB_3V( DST, SRCA, SRCB ) \
+do { \
+ (DST)[0] = (SRCA)[0] - (SRCB)[0]; \
+ (DST)[1] = (SRCA)[1] - (SRCB)[1]; \
+ (DST)[2] = (SRCA)[2] - (SRCB)[2]; \
+} while (0)
+
+/** Addition */
+#define ADD_3V( DST, SRCA, SRCB ) \
+do { \
+ (DST)[0] = (SRCA)[0] + (SRCB)[0]; \
+ (DST)[1] = (SRCA)[1] + (SRCB)[1]; \
+ (DST)[2] = (SRCA)[2] + (SRCB)[2]; \
+} while (0)
+
+/** In-place scalar multiplication */
+#define SCALE_3V( DST, SRCA, SRCB ) \
+do { \
+ (DST)[0] = (SRCA)[0] * (SRCB)[0]; \
+ (DST)[1] = (SRCA)[1] * (SRCB)[1]; \
+ (DST)[2] = (SRCA)[2] * (SRCB)[2]; \
+} while (0)
+
+/** In-place element-wise multiplication */
+#define SELF_SCALE_3V( DST, SRC ) \
+do { \
+ (DST)[0] *= (SRC)[0]; \
+ (DST)[1] *= (SRC)[1]; \
+ (DST)[2] *= (SRC)[2]; \
+} while (0)
+
+/** In-place addition */
+#define ACC_3V( DST, SRC ) \
+do { \
+ (DST)[0] += (SRC)[0]; \
+ (DST)[1] += (SRC)[1]; \
+ (DST)[2] += (SRC)[2]; \
+} while (0)
+
+/** Element-wise multiplication and addition */
+#define ACC_SCALE_3V( DST, SRCA, SRCB ) \
+do { \
+ (DST)[0] += (SRCA)[0] * (SRCB)[0]; \
+ (DST)[1] += (SRCA)[1] * (SRCB)[1]; \
+ (DST)[2] += (SRCA)[2] * (SRCB)[2]; \
+} while (0)
+
+/** Scalar multiplication */
+#define SCALE_SCALAR_3V( DST, S, SRCB ) \
+do { \
+ (DST)[0] = S * (SRCB)[0]; \
+ (DST)[1] = S * (SRCB)[1]; \
+ (DST)[2] = S * (SRCB)[2]; \
+} while (0)
+
+/** In-place scalar multiplication and addition */
+#define ACC_SCALE_SCALAR_3V( DST, S, SRCB ) \
+do { \
+ (DST)[0] += S * (SRCB)[0]; \
+ (DST)[1] += S * (SRCB)[1]; \
+ (DST)[2] += S * (SRCB)[2]; \
+} while (0)
+
+/** In-place scalar multiplication */
+#define SELF_SCALE_SCALAR_3V( DST, S ) \
+do { \
+ (DST)[0] *= S; \
+ (DST)[1] *= S; \
+ (DST)[2] *= S; \
+} while (0)
+
+/** In-place scalar addition */
+#define ACC_SCALAR_3V( DST, S ) \
+do { \
+ (DST)[0] += S; \
+ (DST)[1] += S; \
+ (DST)[2] += S; \
+} while (0)
+
+/** Assignment */
+#define ASSIGN_3V( V, V0, V1, V2 ) \
+do { \
+ V[0] = V0; \
+ V[1] = V1; \
+ V[2] = V2; \
+} while(0)
+
+/*@}*/
+
+
+/**********************************************************************/
+/** \name 2-element vector operations*/
+/*@{*/
+
+/** Zero */
+#define ZERO_2V( DST ) (DST)[0] = (DST)[1] = 0
+
+/** Copy a 2-element vector */
+#define COPY_2V( DST, SRC ) \
+do { \
+ (DST)[0] = (SRC)[0]; \
+ (DST)[1] = (SRC)[1]; \
+} while (0)
+
+/** Copy a 2-element vector with cast */
+#define COPY_2V_CAST( DST, SRC, CAST ) \
+do { \
+ (DST)[0] = (CAST)(SRC)[0]; \
+ (DST)[1] = (CAST)(SRC)[1]; \
+} while (0)
+
+/** Copy a 2-element float vector */
+#define COPY_2FV( DST, SRC ) \
+do { \
+ const GLfloat *_tmp = (SRC); \
+ (DST)[0] = _tmp[0]; \
+ (DST)[1] = _tmp[1]; \
+} while (0)
+
+/** Subtraction */
+#define SUB_2V( DST, SRCA, SRCB ) \
+do { \
+ (DST)[0] = (SRCA)[0] - (SRCB)[0]; \
+ (DST)[1] = (SRCA)[1] - (SRCB)[1]; \
+} while (0)
+
+/** Addition */
+#define ADD_2V( DST, SRCA, SRCB ) \
+do { \
+ (DST)[0] = (SRCA)[0] + (SRCB)[0]; \
+ (DST)[1] = (SRCA)[1] + (SRCB)[1]; \
+} while (0)
+
+/** In-place scalar multiplication */
+#define SCALE_2V( DST, SRCA, SRCB ) \
+do { \
+ (DST)[0] = (SRCA)[0] * (SRCB)[0]; \
+ (DST)[1] = (SRCA)[1] * (SRCB)[1]; \
+} while (0)
+
+/** In-place addition */
+#define ACC_2V( DST, SRC ) \
+do { \
+ (DST)[0] += (SRC)[0]; \
+ (DST)[1] += (SRC)[1]; \
+} while (0)
+
+/** Element-wise multiplication and addition */
+#define ACC_SCALE_2V( DST, SRCA, SRCB ) \
+do { \
+ (DST)[0] += (SRCA)[0] * (SRCB)[0]; \
+ (DST)[1] += (SRCA)[1] * (SRCB)[1]; \
+} while (0)
+
+/** Scalar multiplication */
+#define SCALE_SCALAR_2V( DST, S, SRCB ) \
+do { \
+ (DST)[0] = S * (SRCB)[0]; \
+ (DST)[1] = S * (SRCB)[1]; \
+} while (0)
+
+/** In-place scalar multiplication and addition */
+#define ACC_SCALE_SCALAR_2V( DST, S, SRCB ) \
+do { \
+ (DST)[0] += S * (SRCB)[0]; \
+ (DST)[1] += S * (SRCB)[1]; \
+} while (0)
+
+/** In-place scalar multiplication */
+#define SELF_SCALE_SCALAR_2V( DST, S ) \
+do { \
+ (DST)[0] *= S; \
+ (DST)[1] *= S; \
+} while (0)
+
+/** In-place scalar addition */
+#define ACC_SCALAR_2V( DST, S ) \
+do { \
+ (DST)[0] += S; \
+ (DST)[1] += S; \
+} while (0)
+
+
+
+/**
+ * Linear interpolation
+ *
+ * \note \p OUT argument is evaluated twice!
+ * \note Be wary of using *coord++ as an argument to any of these macros!
+ */
+#define LINTERP(T, OUT, IN) ((OUT) + (T) * ((IN) - (OUT)))
+
+/* Can do better with integer math
+ */
+#define INTERP_UB( t, dstub, outub, inub ) \
+do { \
+ GLfloat inf = UBYTE_TO_FLOAT( inub ); \
+ GLfloat outf = UBYTE_TO_FLOAT( outub ); \
+ GLfloat dstf = LINTERP( t, outf, inf ); \
+ UNCLAMPED_FLOAT_TO_UBYTE( dstub, dstf ); \
+} while (0)
+
+#define INTERP_CHAN( t, dstc, outc, inc ) \
+do { \
+ GLfloat inf = CHAN_TO_FLOAT( inc ); \
+ GLfloat outf = CHAN_TO_FLOAT( outc ); \
+ GLfloat dstf = LINTERP( t, outf, inf ); \
+ UNCLAMPED_FLOAT_TO_CHAN( dstc, dstf ); \
+} while (0)
+
+#define INTERP_UI( t, dstui, outui, inui ) \
+ dstui = (GLuint) (GLint) LINTERP( (t), (GLfloat) (outui), (GLfloat) (inui) )
+
+#define INTERP_F( t, dstf, outf, inf ) \
+ dstf = LINTERP( t, outf, inf )
+
+#define INTERP_4F( t, dst, out, in ) \
+do { \
+ dst[0] = LINTERP( (t), (out)[0], (in)[0] ); \
+ dst[1] = LINTERP( (t), (out)[1], (in)[1] ); \
+ dst[2] = LINTERP( (t), (out)[2], (in)[2] ); \
+ dst[3] = LINTERP( (t), (out)[3], (in)[3] ); \
+} while (0)
+
+#define INTERP_3F( t, dst, out, in ) \
+do { \
+ dst[0] = LINTERP( (t), (out)[0], (in)[0] ); \
+ dst[1] = LINTERP( (t), (out)[1], (in)[1] ); \
+ dst[2] = LINTERP( (t), (out)[2], (in)[2] ); \
+} while (0)
+
+#define INTERP_4CHAN( t, dst, out, in ) \
+do { \
+ INTERP_CHAN( (t), (dst)[0], (out)[0], (in)[0] ); \
+ INTERP_CHAN( (t), (dst)[1], (out)[1], (in)[1] ); \
+ INTERP_CHAN( (t), (dst)[2], (out)[2], (in)[2] ); \
+ INTERP_CHAN( (t), (dst)[3], (out)[3], (in)[3] ); \
+} while (0)
+
+#define INTERP_3CHAN( t, dst, out, in ) \
+do { \
+ INTERP_CHAN( (t), (dst)[0], (out)[0], (in)[0] ); \
+ INTERP_CHAN( (t), (dst)[1], (out)[1], (in)[1] ); \
+ INTERP_CHAN( (t), (dst)[2], (out)[2], (in)[2] ); \
+} while (0)
+
+#define INTERP_SZ( t, vec, to, out, in, sz ) \
+do { \
+ switch (sz) { \
+ case 4: vec[to][3] = LINTERP( (t), (vec)[out][3], (vec)[in][3] ); \
+ case 3: vec[to][2] = LINTERP( (t), (vec)[out][2], (vec)[in][2] ); \
+ case 2: vec[to][1] = LINTERP( (t), (vec)[out][1], (vec)[in][1] ); \
+ case 1: vec[to][0] = LINTERP( (t), (vec)[out][0], (vec)[in][0] ); \
+ } \
+} while(0)
+
+
+
+/** Assign scalers to short vectors */
+#define ASSIGN_2V( V, V0, V1 ) \
+do { \
+ V[0] = V0; \
+ V[1] = V1; \
+} while(0)
+
+/*@}*/
+
+
+
+/** Clamp X to [MIN,MAX] */
+#define CLAMP( X, MIN, MAX ) ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) )
+
+/** Assign X to CLAMP(X, MIN, MAX) */
+#define CLAMP_SELF(x, mn, mx) \
+ ( (x)<(mn) ? ((x) = (mn)) : ((x)>(mx) ? ((x)=(mx)) : (x)) )
+
+
+
+/** Minimum of two values: */
+#define MIN2( A, B ) ( (A)<(B) ? (A) : (B) )
+
+/** Maximum of two values: */
+#define MAX2( A, B ) ( (A)>(B) ? (A) : (B) )
+
+/** Dot product of two 2-element vectors */
+#define DOT2( a, b ) ( (a)[0]*(b)[0] + (a)[1]*(b)[1] )
+
+/** Dot product of two 3-element vectors */
+#define DOT3( a, b ) ( (a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2] )
+
+/** Dot product of two 4-element vectors */
+#define DOT4( a, b ) ( (a)[0]*(b)[0] + (a)[1]*(b)[1] + \
+ (a)[2]*(b)[2] + (a)[3]*(b)[3] )
+
+/** Dot product of two 4-element vectors */
+#define DOT4V(v,a,b,c,d) (v[0]*(a) + v[1]*(b) + v[2]*(c) + v[3]*(d))
+
+
+/** Cross product of two 3-element vectors */
+#define CROSS3(n, u, v) \
+do { \
+ (n)[0] = (u)[1]*(v)[2] - (u)[2]*(v)[1]; \
+ (n)[1] = (u)[2]*(v)[0] - (u)[0]*(v)[2]; \
+ (n)[2] = (u)[0]*(v)[1] - (u)[1]*(v)[0]; \
+} while (0)
+
+
+/* Normalize a 3-element vector to unit length. */
+#define NORMALIZE_3FV( V ) \
+do { \
+ GLfloat len = (GLfloat) LEN_SQUARED_3FV(V); \
+ if (len) { \
+ len = INV_SQRTF(len); \
+ (V)[0] = (GLfloat) ((V)[0] * len); \
+ (V)[1] = (GLfloat) ((V)[1] * len); \
+ (V)[2] = (GLfloat) ((V)[2] * len); \
+ } \
+} while(0)
+
+#define LEN_3FV( V ) (SQRTF((V)[0]*(V)[0]+(V)[1]*(V)[1]+(V)[2]*(V)[2]))
+#define LEN_2FV( V ) (SQRTF((V)[0]*(V)[0]+(V)[1]*(V)[1]))
+
+#define LEN_SQUARED_3FV( V ) ((V)[0]*(V)[0]+(V)[1]*(V)[1]+(V)[2]*(V)[2])
+#define LEN_SQUARED_2FV( V ) ((V)[0]*(V)[0]+(V)[1]*(V)[1])
+
+
+#endif
diff --git a/src/mesa/main/matrix.c b/src/mesa/main/matrix.c
new file mode 100644
index 00000000000..ecd3732c933
--- /dev/null
+++ b/src/mesa/main/matrix.c
@@ -0,0 +1,929 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.3
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/**
+ * \file matrix.c
+ * Matrix operations.
+ *
+ * \note
+ * -# 4x4 transformation matrices are stored in memory in column major order.
+ * -# Points/vertices are to be thought of as column vectors.
+ * -# Transformation of a point p by a matrix M is: p' = M * p
+ */
+
+
+#include "glheader.h"
+#include "imports.h"
+#include "context.h"
+#include "enums.h"
+#include "macros.h"
+#include "matrix.h"
+#include "mtypes.h"
+#include "math/m_matrix.h"
+#include "math/m_xform.h"
+
+
+/**
+ * Apply a perspective projection matrix.
+ *
+ * \param left left clipping plane coordinate.
+ * \param right right clipping plane coordinate.
+ * \param bottom bottom clipping plane coordinate.
+ * \param top top clipping plane coordinate.
+ * \param nearval distance to the near clipping plane.
+ * \param farval distance to the far clipping plane.
+ *
+ * \sa glFrustum().
+ *
+ * Flushes vertices and validates parameters. Calls _math_matrix_frustum() with
+ * the top matrix of the current matrix stack and sets
+ * __GLcontextRec::NewState.
+ */
+void GLAPIENTRY
+_mesa_Frustum( GLdouble left, GLdouble right,
+ GLdouble bottom, GLdouble top,
+ GLdouble nearval, GLdouble farval )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (nearval <= 0.0 ||
+ farval <= 0.0 ||
+ nearval == farval ||
+ left == right ||
+ top == bottom)
+ {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glFrustum" );
+ return;
+ }
+
+ _math_matrix_frustum( ctx->CurrentStack->Top,
+ (GLfloat) left, (GLfloat) right,
+ (GLfloat) bottom, (GLfloat) top,
+ (GLfloat) nearval, (GLfloat) farval );
+ ctx->NewState |= ctx->CurrentStack->DirtyFlag;
+}
+
+
+/**
+ * Apply an orthographic projection matrix.
+ *
+ * \param left left clipping plane coordinate.
+ * \param right right clipping plane coordinate.
+ * \param bottom bottom clipping plane coordinate.
+ * \param top top clipping plane coordinate.
+ * \param nearval distance to the near clipping plane.
+ * \param farval distance to the far clipping plane.
+ *
+ * \sa glOrtho().
+ *
+ * Flushes vertices and validates parameters. Calls _math_matrix_ortho() with
+ * the top matrix of the current matrix stack and sets
+ * __GLcontextRec::NewState.
+ */
+void GLAPIENTRY
+_mesa_Ortho( GLdouble left, GLdouble right,
+ GLdouble bottom, GLdouble top,
+ GLdouble nearval, GLdouble farval )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx, "glOrtho(%f, %f, %f, %f, %f, %f)\n",
+ left, right, bottom, top, nearval, farval);
+
+ if (left == right ||
+ bottom == top ||
+ nearval == farval)
+ {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glOrtho" );
+ return;
+ }
+
+ _math_matrix_ortho( ctx->CurrentStack->Top,
+ (GLfloat) left, (GLfloat) right,
+ (GLfloat) bottom, (GLfloat) top,
+ (GLfloat) nearval, (GLfloat) farval );
+ ctx->NewState |= ctx->CurrentStack->DirtyFlag;
+}
+
+
+/**
+ * Set the current matrix stack.
+ *
+ * \param mode matrix stack.
+ *
+ * \sa glMatrixMode().
+ *
+ * Flushes the vertices, validates the parameter and updates
+ * __GLcontextRec::CurrentStack and gl_transform_attrib::MatrixMode with the
+ * specified matrix stack.
+ */
+void GLAPIENTRY
+_mesa_MatrixMode( GLenum mode )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (ctx->Transform.MatrixMode == mode && mode != GL_TEXTURE)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
+
+ switch (mode) {
+ case GL_MODELVIEW:
+ ctx->CurrentStack = &ctx->ModelviewMatrixStack;
+ break;
+ case GL_PROJECTION:
+ ctx->CurrentStack = &ctx->ProjectionMatrixStack;
+ break;
+ case GL_TEXTURE:
+ ctx->CurrentStack = &ctx->TextureMatrixStack[ctx->Texture.CurrentUnit];
+ break;
+ case GL_COLOR:
+ ctx->CurrentStack = &ctx->ColorMatrixStack;
+ break;
+ case GL_MATRIX0_NV:
+ case GL_MATRIX1_NV:
+ case GL_MATRIX2_NV:
+ case GL_MATRIX3_NV:
+ case GL_MATRIX4_NV:
+ case GL_MATRIX5_NV:
+ case GL_MATRIX6_NV:
+ case GL_MATRIX7_NV:
+ if (ctx->Extensions.NV_vertex_program) {
+ ctx->CurrentStack = &ctx->ProgramMatrixStack[mode - GL_MATRIX0_NV];
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glMatrixMode(mode)" );
+ return;
+ }
+ break;
+ case GL_MATRIX0_ARB:
+ case GL_MATRIX1_ARB:
+ case GL_MATRIX2_ARB:
+ case GL_MATRIX3_ARB:
+ case GL_MATRIX4_ARB:
+ case GL_MATRIX5_ARB:
+ case GL_MATRIX6_ARB:
+ case GL_MATRIX7_ARB:
+ if (ctx->Extensions.ARB_vertex_program ||
+ ctx->Extensions.ARB_fragment_program) {
+ const GLuint m = mode - GL_MATRIX0_ARB;
+ if (m > ctx->Const.MaxProgramMatrices) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glMatrixMode(GL_MATRIX%d_ARB)", m);
+ return;
+ }
+ ctx->CurrentStack = &ctx->ProgramMatrixStack[m];
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glMatrixMode(mode)" );
+ return;
+ }
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glMatrixMode(mode)" );
+ return;
+ }
+
+ ctx->Transform.MatrixMode = mode;
+}
+
+
+/**
+ * Push the current matrix stack.
+ *
+ * \sa glPushMatrix().
+ *
+ * Verifies the current matrix stack is not full, and duplicates the top-most
+ * matrix in the stack. Marks __GLcontextRec::NewState with the stack dirty
+ * flag.
+ */
+void GLAPIENTRY
+_mesa_PushMatrix( void )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct matrix_stack *stack = ctx->CurrentStack;
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (MESA_VERBOSE&VERBOSE_API)
+ _mesa_debug(ctx, "glPushMatrix %s\n",
+ _mesa_lookup_enum_by_nr(ctx->Transform.MatrixMode));
+
+ if (stack->Depth + 1 >= stack->MaxDepth) {
+ if (ctx->Transform.MatrixMode == GL_TEXTURE) {
+ _mesa_error(ctx, GL_STACK_OVERFLOW,
+ "glPushMatrix(mode=GL_TEXTURE, unit=%d)",
+ ctx->Texture.CurrentUnit);
+ }
+ else {
+ _mesa_error(ctx, GL_STACK_OVERFLOW, "glPushMatrix(mode=%s)",
+ _mesa_lookup_enum_by_nr(ctx->Transform.MatrixMode));
+ }
+ return;
+ }
+ _math_matrix_copy( &stack->Stack[stack->Depth + 1],
+ &stack->Stack[stack->Depth] );
+ stack->Depth++;
+ stack->Top = &(stack->Stack[stack->Depth]);
+ ctx->NewState |= stack->DirtyFlag;
+}
+
+
+/**
+ * Pop the current matrix stack.
+ *
+ * \sa glPopMatrix().
+ *
+ * Flushes the vertices, verifies the current matrix stack is not empty, and
+ * moves the stack head down. Marks __GLcontextRec::NewState with the dirty
+ * stack flag.
+ */
+void GLAPIENTRY
+_mesa_PopMatrix( void )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct matrix_stack *stack = ctx->CurrentStack;
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (MESA_VERBOSE&VERBOSE_API)
+ _mesa_debug(ctx, "glPopMatrix %s\n",
+ _mesa_lookup_enum_by_nr(ctx->Transform.MatrixMode));
+
+ if (stack->Depth == 0) {
+ if (ctx->Transform.MatrixMode == GL_TEXTURE) {
+ _mesa_error(ctx, GL_STACK_UNDERFLOW,
+ "glPopMatrix(mode=GL_TEXTURE, unit=%d)",
+ ctx->Texture.CurrentUnit);
+ }
+ else {
+ _mesa_error(ctx, GL_STACK_UNDERFLOW, "glPopMatrix(mode=%s)",
+ _mesa_lookup_enum_by_nr(ctx->Transform.MatrixMode));
+ }
+ return;
+ }
+ stack->Depth--;
+ stack->Top = &(stack->Stack[stack->Depth]);
+ ctx->NewState |= stack->DirtyFlag;
+}
+
+
+/**
+ * Replace the current matrix with the identity matrix.
+ *
+ * \sa glLoadIdentity().
+ *
+ * Flushes the vertices and calls _math_matrix_set_identity() with the top-most
+ * matrix in the current stack. Marks __GLcontextRec::NewState with the stack
+ * dirty flag.
+ */
+void GLAPIENTRY
+_mesa_LoadIdentity( void )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx, "glLoadIdentity()");
+
+ _math_matrix_set_identity( ctx->CurrentStack->Top );
+ ctx->NewState |= ctx->CurrentStack->DirtyFlag;
+}
+
+
+/**
+ * Replace the current matrix with a given matrix.
+ *
+ * \param m matrix.
+ *
+ * \sa glLoadMatrixf().
+ *
+ * Flushes the vertices and calls _math_matrix_loadf() with the top-most matrix
+ * in the current stack and the given matrix. Marks __GLcontextRec::NewState
+ * with the dirty stack flag.
+ */
+void GLAPIENTRY
+_mesa_LoadMatrixf( const GLfloat *m )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ if (!m) return;
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx,
+ "glLoadMatrix(%f %f %f %f, %f %f %f %f, %f %f %f %f, %f %f %f %f\n",
+ m[0], m[4], m[8], m[12],
+ m[1], m[5], m[9], m[13],
+ m[2], m[6], m[10], m[14],
+ m[3], m[7], m[11], m[15]);
+
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+ _math_matrix_loadf( ctx->CurrentStack->Top, m );
+ ctx->NewState |= ctx->CurrentStack->DirtyFlag;
+}
+
+
+/**
+ * Multiply the current matrix with a given matrix.
+ *
+ * \param m matrix.
+ *
+ * \sa glMultMatrixf().
+ *
+ * Flushes the vertices and calls _math_matrix_mul_floats() with the top-most
+ * matrix in the current stack and the given matrix. Marks
+ * __GLcontextRec::NewState with the dirty stack flag.
+ */
+void GLAPIENTRY
+_mesa_MultMatrixf( const GLfloat *m )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ if (!m) return;
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx,
+ "glMultMatrix(%f %f %f %f, %f %f %f %f, %f %f %f %f, %f %f %f %f\n",
+ m[0], m[4], m[8], m[12],
+ m[1], m[5], m[9], m[13],
+ m[2], m[6], m[10], m[14],
+ m[3], m[7], m[11], m[15]);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+ _math_matrix_mul_floats( ctx->CurrentStack->Top, m );
+ ctx->NewState |= ctx->CurrentStack->DirtyFlag;
+}
+
+
+/**
+ * Multiply the current matrix with a rotation matrix.
+ *
+ * \param angle angle of rotation, in degrees.
+ * \param x rotation vector x coordinate.
+ * \param y rotation vector y coordinate.
+ * \param z rotation vector z coordinate.
+ *
+ * \sa glRotatef().
+ *
+ * Flushes the vertices and calls _math_matrix_rotate() with the top-most
+ * matrix in the current stack and the given parameters. Marks
+ * __GLcontextRec::NewState with the dirty stack flag.
+ */
+void GLAPIENTRY
+_mesa_Rotatef( GLfloat angle, GLfloat x, GLfloat y, GLfloat z )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+ if (angle != 0.0F) {
+ _math_matrix_rotate( ctx->CurrentStack->Top, angle, x, y, z);
+ ctx->NewState |= ctx->CurrentStack->DirtyFlag;
+ }
+}
+
+
+/**
+ * Multiply the current matrix with a general scaling matrix.
+ *
+ * \param x x axis scale factor.
+ * \param y y axis scale factor.
+ * \param z z axis scale factor.
+ *
+ * \sa glScalef().
+ *
+ * Flushes the vertices and calls _math_matrix_scale() with the top-most
+ * matrix in the current stack and the given parameters. Marks
+ * __GLcontextRec::NewState with the dirty stack flag.
+ */
+void GLAPIENTRY
+_mesa_Scalef( GLfloat x, GLfloat y, GLfloat z )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+ _math_matrix_scale( ctx->CurrentStack->Top, x, y, z);
+ ctx->NewState |= ctx->CurrentStack->DirtyFlag;
+}
+
+
+/**
+ * Multiply the current matrix with a general scaling matrix.
+ *
+ * \param x translation vector x coordinate.
+ * \param y translation vector y coordinate.
+ * \param z translation vector z coordinate.
+ *
+ * \sa glTranslatef().
+ *
+ * Flushes the vertices and calls _math_matrix_translate() with the top-most
+ * matrix in the current stack and the given parameters. Marks
+ * __GLcontextRec::NewState with the dirty stack flag.
+ */
+void GLAPIENTRY
+_mesa_Translatef( GLfloat x, GLfloat y, GLfloat z )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+ _math_matrix_translate( ctx->CurrentStack->Top, x, y, z);
+ ctx->NewState |= ctx->CurrentStack->DirtyFlag;
+}
+
+
+#if _HAVE_FULL_GL
+void GLAPIENTRY
+_mesa_LoadMatrixd( const GLdouble *m )
+{
+ GLint i;
+ GLfloat f[16];
+ if (!m) return;
+ for (i = 0; i < 16; i++)
+ f[i] = (GLfloat) m[i];
+ _mesa_LoadMatrixf(f);
+}
+
+void GLAPIENTRY
+_mesa_MultMatrixd( const GLdouble *m )
+{
+ GLint i;
+ GLfloat f[16];
+ if (!m) return;
+ for (i = 0; i < 16; i++)
+ f[i] = (GLfloat) m[i];
+ _mesa_MultMatrixf( f );
+}
+
+
+void GLAPIENTRY
+_mesa_Rotated( GLdouble angle, GLdouble x, GLdouble y, GLdouble z )
+{
+ _mesa_Rotatef((GLfloat) angle, (GLfloat) x, (GLfloat) y, (GLfloat) z);
+}
+
+
+void GLAPIENTRY
+_mesa_Scaled( GLdouble x, GLdouble y, GLdouble z )
+{
+ _mesa_Scalef((GLfloat) x, (GLfloat) y, (GLfloat) z);
+}
+
+
+void GLAPIENTRY
+_mesa_Translated( GLdouble x, GLdouble y, GLdouble z )
+{
+ _mesa_Translatef((GLfloat) x, (GLfloat) y, (GLfloat) z);
+}
+#endif
+
+
+#if _HAVE_FULL_GL
+void GLAPIENTRY
+_mesa_LoadTransposeMatrixfARB( const GLfloat *m )
+{
+ GLfloat tm[16];
+ if (!m) return;
+ _math_transposef(tm, m);
+ _mesa_LoadMatrixf(tm);
+}
+
+
+void GLAPIENTRY
+_mesa_LoadTransposeMatrixdARB( const GLdouble *m )
+{
+ GLfloat tm[16];
+ if (!m) return;
+ _math_transposefd(tm, m);
+ _mesa_LoadMatrixf(tm);
+}
+
+
+void GLAPIENTRY
+_mesa_MultTransposeMatrixfARB( const GLfloat *m )
+{
+ GLfloat tm[16];
+ if (!m) return;
+ _math_transposef(tm, m);
+ _mesa_MultMatrixf(tm);
+}
+
+
+void GLAPIENTRY
+_mesa_MultTransposeMatrixdARB( const GLdouble *m )
+{
+ GLfloat tm[16];
+ if (!m) return;
+ _math_transposefd(tm, m);
+ _mesa_MultMatrixf(tm);
+}
+#endif
+
+/**
+ * Set the viewport.
+ *
+ * \param x, y coordinates of the lower-left corner of the viewport rectangle.
+ * \param width width of the viewport rectangle.
+ * \param height height of the viewport rectangle.
+ *
+ * \sa Called via glViewport() or display list execution.
+ *
+ * Flushes the vertices and calls _mesa_set_viewport() with the given
+ * parameters.
+ */
+void GLAPIENTRY
+_mesa_Viewport( GLint x, GLint y, GLsizei width, GLsizei height )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+ _mesa_set_viewport(ctx, x, y, width, height);
+}
+
+
+/**
+ * Set new viewport parameters and update derived state (the _WindowMap
+ * matrix). Usually called from _mesa_Viewport().
+ *
+ * \param ctx GL context.
+ * \param x, y coordinates of the lower left corner of the viewport rectangle.
+ * \param width width of the viewport rectangle.
+ * \param height height of the viewport rectangle.
+ */
+void
+_mesa_set_viewport( GLcontext *ctx, GLint x, GLint y,
+ GLsizei width, GLsizei height )
+{
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx, "glViewport %d %d %d %d\n", x, y, width, height);
+
+ if (width < 0 || height < 0) {
+ _mesa_error( ctx, GL_INVALID_VALUE,
+ "glViewport(%d, %d, %d, %d)", x, y, width, height );
+ return;
+ }
+
+ /* clamp width and height to the implementation dependent range */
+ width = CLAMP(width, 1, ctx->Const.MaxViewportWidth);
+ height = CLAMP(height, 1, ctx->Const.MaxViewportHeight);
+
+ ctx->Viewport.X = x;
+ ctx->Viewport.Width = width;
+ ctx->Viewport.Y = y;
+ ctx->Viewport.Height = height;
+ ctx->NewState |= _NEW_VIEWPORT;
+
+#if 1
+ /* XXX remove this someday. Currently the DRI drivers rely on
+ * the WindowMap matrix being up to date in the driver's Viewport
+ * and DepthRange functions.
+ */
+ _math_matrix_viewport(&ctx->Viewport._WindowMap,
+ ctx->Viewport.X, ctx->Viewport.Y,
+ ctx->Viewport.Width, ctx->Viewport.Height,
+ ctx->Viewport.Near, ctx->Viewport.Far,
+ ctx->DrawBuffer->_DepthMaxF);
+#endif
+
+ if (ctx->Driver.Viewport) {
+ /* Many drivers will use this call to check for window size changes
+ * and reallocate the z/stencil/accum/etc buffers if needed.
+ */
+ (*ctx->Driver.Viewport)( ctx, x, y, width, height );
+ }
+}
+
+
+#if _HAVE_FULL_GL
+/**
+ * Called by glDepthRange
+ *
+ * \param nearval specifies the Z buffer value which should correspond to
+ * the near clip plane
+ * \param farval specifies the Z buffer value which should correspond to
+ * the far clip plane
+ */
+void GLAPIENTRY
+_mesa_DepthRange( GLclampd nearval, GLclampd farval )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (MESA_VERBOSE&VERBOSE_API)
+ _mesa_debug(ctx, "glDepthRange %f %f\n", nearval, farval);
+
+ ctx->Viewport.Near = (GLfloat) CLAMP( nearval, 0.0, 1.0 );
+ ctx->Viewport.Far = (GLfloat) CLAMP( farval, 0.0, 1.0 );
+ ctx->NewState |= _NEW_VIEWPORT;
+
+#if 1
+ /* XXX remove this someday. Currently the DRI drivers rely on
+ * the WindowMap matrix being up to date in the driver's Viewport
+ * and DepthRange functions.
+ */
+ _math_matrix_viewport(&ctx->Viewport._WindowMap,
+ ctx->Viewport.X, ctx->Viewport.Y,
+ ctx->Viewport.Width, ctx->Viewport.Height,
+ ctx->Viewport.Near, ctx->Viewport.Far,
+ ctx->DrawBuffer->_DepthMaxF);
+#endif
+
+ if (ctx->Driver.DepthRange) {
+ (*ctx->Driver.DepthRange)( ctx, nearval, farval );
+ }
+}
+#endif
+
+
+
+/**********************************************************************/
+/** \name State management */
+/*@{*/
+
+
+/**
+ * Update the projection matrix stack.
+ *
+ * \param ctx GL context.
+ *
+ * Calls _math_matrix_analyse() with the top-matrix of the projection matrix
+ * stack, and recomputes user clip positions if necessary.
+ *
+ * \note This routine references __GLcontextRec::Tranform attribute values to
+ * compute userclip positions in clip space, but is only called on
+ * _NEW_PROJECTION. The _mesa_ClipPlane() function keeps these values up to
+ * date across changes to the __GLcontextRec::Transform attributes.
+ */
+static void
+update_projection( GLcontext *ctx )
+{
+ _math_matrix_analyse( ctx->ProjectionMatrixStack.Top );
+
+#if FEATURE_userclip
+ /* Recompute clip plane positions in clipspace. This is also done
+ * in _mesa_ClipPlane().
+ */
+ if (ctx->Transform.ClipPlanesEnabled) {
+ GLuint p;
+ for (p = 0; p < ctx->Const.MaxClipPlanes; p++) {
+ if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
+ _mesa_transform_vector( ctx->Transform._ClipUserPlane[p],
+ ctx->Transform.EyeUserPlane[p],
+ ctx->ProjectionMatrixStack.Top->inv );
+ }
+ }
+ }
+#endif
+}
+
+
+/**
+ * Calculate the combined modelview-projection matrix.
+ *
+ * \param ctx GL context.
+ *
+ * Multiplies the top matrices of the projection and model view stacks into
+ * __GLcontextRec::_ModelProjectMatrix via _math_matrix_mul_matrix() and
+ * analyzes the resulting matrix via _math_matrix_analyse().
+ */
+static void
+calculate_model_project_matrix( GLcontext *ctx )
+{
+ _math_matrix_mul_matrix( &ctx->_ModelProjectMatrix,
+ ctx->ProjectionMatrixStack.Top,
+ ctx->ModelviewMatrixStack.Top );
+
+ _math_matrix_analyse( &ctx->_ModelProjectMatrix );
+}
+
+
+/**
+ * Updates the combined modelview-projection matrix.
+ *
+ * \param ctx GL context.
+ * \param new_state new state bit mask.
+ *
+ * If there is a new model view matrix then analyzes it. If there is a new
+ * projection matrix, updates it. Finally calls
+ * calculate_model_project_matrix() to recalculate the modelview-projection
+ * matrix.
+ */
+void _mesa_update_modelview_project( GLcontext *ctx, GLuint new_state )
+{
+ if (new_state & _NEW_MODELVIEW) {
+ _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
+
+ /* Bring cull position uptodate.
+ */
+ TRANSFORM_POINT3( ctx->Transform.CullObjPos,
+ ctx->ModelviewMatrixStack.Top->inv,
+ ctx->Transform.CullEyePos );
+ }
+
+
+ if (new_state & _NEW_PROJECTION)
+ update_projection( ctx );
+
+ /* Keep ModelviewProject uptodate always to allow tnl
+ * implementations that go model->clip even when eye is required.
+ */
+ calculate_model_project_matrix(ctx);
+}
+
+/*@}*/
+
+
+/**********************************************************************/
+/** Matrix stack initialization */
+/*@{*/
+
+
+/**
+ * Initialize a matrix stack.
+ *
+ * \param stack matrix stack.
+ * \param maxDepth maximum stack depth.
+ * \param dirtyFlag dirty flag.
+ *
+ * Allocates an array of \p maxDepth elements for the matrix stack and calls
+ * _math_matrix_ctr() and _math_matrix_alloc_inv() for each element to
+ * initialize it.
+ */
+static void
+init_matrix_stack( struct matrix_stack *stack,
+ GLuint maxDepth, GLuint dirtyFlag )
+{
+ GLuint i;
+
+ stack->Depth = 0;
+ stack->MaxDepth = maxDepth;
+ stack->DirtyFlag = dirtyFlag;
+ /* The stack */
+ stack->Stack = (GLmatrix *) CALLOC(maxDepth * sizeof(GLmatrix));
+ for (i = 0; i < maxDepth; i++) {
+ _math_matrix_ctr(&stack->Stack[i]);
+ _math_matrix_alloc_inv(&stack->Stack[i]);
+ }
+ stack->Top = stack->Stack;
+}
+
+/**
+ * Free matrix stack.
+ *
+ * \param stack matrix stack.
+ *
+ * Calls _math_matrix_dtr() for each element of the matrix stack and
+ * frees the array.
+ */
+static void
+free_matrix_stack( struct matrix_stack *stack )
+{
+ GLuint i;
+ for (i = 0; i < stack->MaxDepth; i++) {
+ _math_matrix_dtr(&stack->Stack[i]);
+ }
+ FREE(stack->Stack);
+ stack->Stack = stack->Top = NULL;
+}
+
+/*@}*/
+
+
+/**********************************************************************/
+/** \name Initialization */
+/*@{*/
+
+
+/**
+ * Initialize the context matrix data.
+ *
+ * \param ctx GL context.
+ *
+ * Initializes each of the matrix stacks and the combined modelview-projection
+ * matrix.
+ */
+void _mesa_init_matrix( GLcontext * ctx )
+{
+ GLint i;
+
+ /* Initialize matrix stacks */
+ init_matrix_stack(&ctx->ModelviewMatrixStack, MAX_MODELVIEW_STACK_DEPTH,
+ _NEW_MODELVIEW);
+ init_matrix_stack(&ctx->ProjectionMatrixStack, MAX_PROJECTION_STACK_DEPTH,
+ _NEW_PROJECTION);
+ init_matrix_stack(&ctx->ColorMatrixStack, MAX_COLOR_STACK_DEPTH,
+ _NEW_COLOR_MATRIX);
+ for (i = 0; i < MAX_TEXTURE_UNITS; i++)
+ init_matrix_stack(&ctx->TextureMatrixStack[i], MAX_TEXTURE_STACK_DEPTH,
+ _NEW_TEXTURE_MATRIX);
+ for (i = 0; i < MAX_PROGRAM_MATRICES; i++)
+ init_matrix_stack(&ctx->ProgramMatrixStack[i],
+ MAX_PROGRAM_MATRIX_STACK_DEPTH, _NEW_TRACK_MATRIX);
+ ctx->CurrentStack = &ctx->ModelviewMatrixStack;
+
+ /* Init combined Modelview*Projection matrix */
+ _math_matrix_ctr( &ctx->_ModelProjectMatrix );
+}
+
+
+/**
+ * Free the context matrix data.
+ *
+ * \param ctx GL context.
+ *
+ * Frees each of the matrix stacks and the combined modelview-projection
+ * matrix.
+ */
+void _mesa_free_matrix_data( GLcontext *ctx )
+{
+ GLint i;
+
+ free_matrix_stack(&ctx->ModelviewMatrixStack);
+ free_matrix_stack(&ctx->ProjectionMatrixStack);
+ free_matrix_stack(&ctx->ColorMatrixStack);
+ for (i = 0; i < MAX_TEXTURE_UNITS; i++)
+ free_matrix_stack(&ctx->TextureMatrixStack[i]);
+ for (i = 0; i < MAX_PROGRAM_MATRICES; i++)
+ free_matrix_stack(&ctx->ProgramMatrixStack[i]);
+ /* combined Modelview*Projection matrix */
+ _math_matrix_dtr( &ctx->_ModelProjectMatrix );
+
+}
+
+
+/**
+ * Initialize the context transform attribute group.
+ *
+ * \param ctx GL context.
+ *
+ * \todo Move this to a new file with other 'transform' routines.
+ */
+void _mesa_init_transform( GLcontext *ctx )
+{
+ GLint i;
+
+ /* Transformation group */
+ ctx->Transform.MatrixMode = GL_MODELVIEW;
+ ctx->Transform.Normalize = GL_FALSE;
+ ctx->Transform.RescaleNormals = GL_FALSE;
+ ctx->Transform.RasterPositionUnclipped = GL_FALSE;
+ for (i=0;i<MAX_CLIP_PLANES;i++) {
+ ASSIGN_4V( ctx->Transform.EyeUserPlane[i], 0.0, 0.0, 0.0, 0.0 );
+ }
+ ctx->Transform.ClipPlanesEnabled = 0;
+
+ ASSIGN_4V( ctx->Transform.CullObjPos, 0.0, 0.0, 1.0, 0.0 );
+ ASSIGN_4V( ctx->Transform.CullEyePos, 0.0, 0.0, 1.0, 0.0 );
+}
+
+
+/**
+ * Initialize the context viewport attribute group.
+ *
+ * \param ctx GL context.
+ *
+ * \todo Move this to a new file with other 'viewport' routines.
+ */
+void _mesa_init_viewport( GLcontext *ctx )
+{
+ GLfloat depthMax = 65535.0F; /* sorf of arbitrary */
+
+ /* Viewport group */
+ ctx->Viewport.X = 0;
+ ctx->Viewport.Y = 0;
+ ctx->Viewport.Width = 0;
+ ctx->Viewport.Height = 0;
+ ctx->Viewport.Near = 0.0;
+ ctx->Viewport.Far = 1.0;
+ _math_matrix_ctr(&ctx->Viewport._WindowMap);
+
+ _math_matrix_viewport(&ctx->Viewport._WindowMap, 0, 0, 0, 0,
+ 0.0F, 1.0F, depthMax);
+}
+
+
+/**
+ * Free the context viewport attribute group data.
+ *
+ * \param ctx GL context.
+ *
+ * \todo Move this to a new file with other 'viewport' routines.
+ */
+void _mesa_free_viewport_data( GLcontext *ctx )
+{
+ _math_matrix_dtr(&ctx->Viewport._WindowMap);
+}
+
+/*@}*/
diff --git a/src/mesa/main/matrix.h b/src/mesa/main/matrix.h
new file mode 100644
index 00000000000..38769867a75
--- /dev/null
+++ b/src/mesa/main/matrix.h
@@ -0,0 +1,131 @@
+/**
+ * \file matrix.h
+ * Matrix operations.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.5
+ *
+ * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef MATRIX_H
+#define MATRIX_H
+
+
+#include "mtypes.h"
+
+
+extern void GLAPIENTRY
+_mesa_Frustum( GLdouble left, GLdouble right,
+ GLdouble bottom, GLdouble top,
+ GLdouble nearval, GLdouble farval );
+
+extern void GLAPIENTRY
+_mesa_Ortho( GLdouble left, GLdouble right,
+ GLdouble bottom, GLdouble top,
+ GLdouble nearval, GLdouble farval );
+
+extern void GLAPIENTRY
+_mesa_PushMatrix( void );
+
+extern void GLAPIENTRY
+_mesa_PopMatrix( void );
+
+extern void GLAPIENTRY
+_mesa_LoadIdentity( void );
+
+extern void GLAPIENTRY
+_mesa_LoadMatrixf( const GLfloat *m );
+
+extern void GLAPIENTRY
+_mesa_LoadMatrixd( const GLdouble *m );
+
+extern void GLAPIENTRY
+_mesa_MatrixMode( GLenum mode );
+
+extern void GLAPIENTRY
+_mesa_MultMatrixf( const GLfloat *m );
+
+extern void GLAPIENTRY
+_mesa_MultMatrixd( const GLdouble *m );
+
+extern void GLAPIENTRY
+_mesa_Rotatef( GLfloat angle, GLfloat x, GLfloat y, GLfloat z );
+
+extern void GLAPIENTRY
+_mesa_Rotated( GLdouble angle, GLdouble x, GLdouble y, GLdouble z );
+
+extern void GLAPIENTRY
+_mesa_Scalef( GLfloat x, GLfloat y, GLfloat z );
+
+extern void GLAPIENTRY
+_mesa_Scaled( GLdouble x, GLdouble y, GLdouble z );
+
+extern void GLAPIENTRY
+_mesa_Translatef( GLfloat x, GLfloat y, GLfloat z );
+
+extern void GLAPIENTRY
+_mesa_Translated( GLdouble x, GLdouble y, GLdouble z );
+
+extern void GLAPIENTRY
+_mesa_LoadTransposeMatrixfARB( const GLfloat *m );
+
+extern void GLAPIENTRY
+_mesa_LoadTransposeMatrixdARB( const GLdouble *m );
+
+extern void GLAPIENTRY
+_mesa_MultTransposeMatrixfARB( const GLfloat *m );
+
+extern void GLAPIENTRY
+_mesa_MultTransposeMatrixdARB( const GLdouble *m );
+
+extern void GLAPIENTRY
+_mesa_Viewport( GLint x, GLint y, GLsizei width, GLsizei height );
+
+extern void
+_mesa_set_viewport( GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height );
+
+extern void GLAPIENTRY
+_mesa_DepthRange( GLclampd nearval, GLclampd farval );
+
+
+extern void
+_mesa_init_matrix( GLcontext * ctx );
+
+extern void
+_mesa_init_transform( GLcontext *ctx );
+
+extern void
+_mesa_init_viewport( GLcontext *ctx );
+
+extern void
+_mesa_free_matrix_data( GLcontext *ctx );
+
+extern void
+_mesa_free_viewport_data( GLcontext *ctx );
+
+extern void
+_mesa_update_modelview_project( GLcontext *ctx, GLuint newstate );
+
+
+#endif
diff --git a/src/mesa/main/mm.c b/src/mesa/main/mm.c
new file mode 100644
index 00000000000..0a71c4d8514
--- /dev/null
+++ b/src/mesa/main/mm.c
@@ -0,0 +1,220 @@
+/*
+ * GLX Hardware Device Driver common code
+ * Copyright (C) 1999 Wittawat Yamwong
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "mm.h"
+
+
+void
+mmDumpMemInfo(const struct mem_block *heap)
+{
+ const struct mem_block *p;
+
+ fprintf(stderr, "Memory heap %p:\n", (void *)heap);
+ if (heap == 0) {
+ fprintf(stderr, " heap == 0\n");
+ } else {
+ p = (struct mem_block *)heap;
+ while (p) {
+ fprintf(stderr, " Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size,
+ p->free ? '.':'U',
+ p->reserved ? 'R':'.');
+ p = p->next;
+ }
+ }
+ fprintf(stderr, "End of memory blocks\n");
+}
+
+struct mem_block *
+mmInit(int ofs, int size)
+{
+ struct mem_block *blocks;
+
+ if (size <= 0) {
+ return NULL;
+ }
+ blocks = (struct mem_block *) _mesa_calloc(sizeof(struct mem_block));
+ if (blocks) {
+ blocks->ofs = ofs;
+ blocks->size = size;
+ blocks->free = 1;
+ return (struct mem_block *)blocks;
+ }
+ else {
+ return NULL;
+ }
+}
+
+
+static struct mem_block *
+SliceBlock(struct mem_block *p,
+ int startofs, int size,
+ int reserved, int alignment)
+{
+ struct mem_block *newblock;
+
+ /* break left */
+ if (startofs > p->ofs) {
+ newblock = (struct mem_block*) _mesa_calloc(sizeof(struct mem_block));
+ if (!newblock)
+ return NULL;
+ newblock->ofs = startofs;
+ newblock->size = p->size - (startofs - p->ofs);
+ newblock->free = 1;
+ newblock->next = p->next;
+ p->size -= newblock->size;
+ p->next = newblock;
+ p = newblock;
+ }
+
+ /* break right */
+ if (size < p->size) {
+ newblock = (struct mem_block*) _mesa_calloc(sizeof(struct mem_block));
+ if (!newblock)
+ return NULL;
+ newblock->ofs = startofs + size;
+ newblock->size = p->size - size;
+ newblock->free = 1;
+ newblock->next = p->next;
+ p->size = size;
+ p->next = newblock;
+ }
+
+ /* p = middle block */
+ p->align = alignment;
+ p->free = 0;
+ p->reserved = reserved;
+ return p;
+}
+
+
+struct mem_block *
+mmAllocMem(struct mem_block *heap, int size, int align2, int startSearch)
+{
+ struct mem_block *p = heap;
+ int mask = (1 << align2)-1;
+ int startofs = 0;
+ int endofs;
+
+ if (!heap || align2 < 0 || size <= 0)
+ return NULL;
+
+ while (p) {
+ if ((p)->free) {
+ startofs = (p->ofs + mask) & ~mask;
+ if ( startofs < startSearch ) {
+ startofs = startSearch;
+ }
+ endofs = startofs+size;
+ if (endofs <= (p->ofs+p->size))
+ break;
+ }
+ p = p->next;
+ }
+ if (!p)
+ return NULL;
+ p = SliceBlock(p,startofs,size,0,mask+1);
+ p->heap = heap;
+ return p;
+}
+
+
+struct mem_block *
+mmFindBlock(struct mem_block *heap, int start)
+{
+ struct mem_block *p = (struct mem_block *)heap;
+
+ while (p) {
+ if (p->ofs == start && p->free)
+ return p;
+
+ p = p->next;
+ }
+
+ return NULL;
+}
+
+
+static int
+Join2Blocks(struct mem_block *p)
+{
+ /* XXX there should be some assertions here */
+ if (p->free && p->next && p->next->free) {
+ struct mem_block *q = p->next;
+ p->size += q->size;
+ p->next = q->next;
+ _mesa_free(q);
+ return 1;
+ }
+ return 0;
+}
+
+int
+mmFreeMem(struct mem_block *b)
+{
+ struct mem_block *p,*prev;
+
+ if (!b)
+ return 0;
+ if (!b->heap) {
+ fprintf(stderr, "no heap\n");
+ return -1;
+ }
+ p = b->heap;
+ prev = NULL;
+ while (p && p != b) {
+ prev = p;
+ p = p->next;
+ }
+ if (!p || p->free || p->reserved) {
+ if (!p)
+ fprintf(stderr, "block not found in heap\n");
+ else if (p->free)
+ fprintf(stderr, "block already free\n");
+ else
+ fprintf(stderr, "block is reserved\n");
+ return -1;
+ }
+ p->free = 1;
+ Join2Blocks(p);
+ if (prev)
+ Join2Blocks(prev);
+ return 0;
+}
+
+
+void
+mmDestroy(struct mem_block *heap)
+{
+ struct mem_block *p;
+
+ if (!heap)
+ return;
+
+ p = (struct mem_block *) heap;
+ while (p) {
+ struct mem_block *next = p->next;
+ _mesa_free(p);
+ p = next;
+ }
+}
diff --git a/src/mesa/main/mm.h b/src/mesa/main/mm.h
new file mode 100644
index 00000000000..9213b2ad34e
--- /dev/null
+++ b/src/mesa/main/mm.h
@@ -0,0 +1,92 @@
+/*
+ * GLX Hardware Device Driver common code
+ * Copyright (C) 1999 Wittawat Yamwong
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/**
+ * Memory manager code. Primarily used by device drivers to manage texture
+ * heaps, etc.
+ */
+
+
+#ifndef MM_H
+#define MM_H
+
+
+#include "imports.h"
+
+
+struct mem_block {
+ struct mem_block *next;
+ struct mem_block *heap;
+ int ofs,size;
+ int align;
+ unsigned int free:1;
+ unsigned int reserved:1;
+};
+
+
+
+/**
+ * input: total size in bytes
+ * return: a heap pointer if OK, NULL if error
+ */
+extern struct mem_block *mmInit(int ofs, int size);
+
+/**
+ * Allocate 'size' bytes with 2^align2 bytes alignment,
+ * restrict the search to free memory after 'startSearch'
+ * depth and back buffers should be in different 4mb banks
+ * to get better page hits if possible
+ * input: size = size of block
+ * align2 = 2^align2 bytes alignment
+ * startSearch = linear offset from start of heap to begin search
+ * return: pointer to the allocated block, 0 if error
+ */
+extern struct mem_block *mmAllocMem(struct mem_block *heap, int size, int align2,
+ int startSearch);
+
+/**
+ * Free block starts at offset
+ * input: pointer to a block
+ * return: 0 if OK, -1 if error
+ */
+extern int mmFreeMem(struct mem_block *b);
+
+/**
+ * Free block starts at offset
+ * input: pointer to a heap, start offset
+ * return: pointer to a block
+ */
+extern struct mem_block *mmFindBlock(struct mem_block *heap, int start);
+
+/**
+ * destroy MM
+ */
+extern void mmDestroy(struct mem_block *mmInit);
+
+/**
+ * For debuging purpose.
+ */
+extern void mmDumpMemInfo(const struct mem_block *mmInit);
+
+#endif
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
new file mode 100644
index 00000000000..7876cff2ed5
--- /dev/null
+++ b/src/mesa/main/mtypes.h
@@ -0,0 +1,2947 @@
+/**
+ * \file mtypes.h
+ * Main Mesa data structures.
+ *
+ * Please try to mark derived values with a leading underscore ('_').
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+#ifndef TYPES_H
+#define TYPES_H
+
+
+#include "glheader.h"
+#include <GL/internal/glcore.h> /* GLimports/GLexports/GLcontextModes */
+#include "config.h" /* Hardwired parameters */
+#include "glapitable.h"
+#include "glthread.h"
+#include "math/m_matrix.h" /* GLmatrix */
+
+
+/**
+ * Color channel data type.
+ */
+#if CHAN_BITS == 8
+ typedef GLubyte GLchan;
+#define CHAN_MAX 255
+#define CHAN_MAXF 255.0F
+#define CHAN_TYPE GL_UNSIGNED_BYTE
+#elif CHAN_BITS == 16
+ typedef GLushort GLchan;
+#define CHAN_MAX 65535
+#define CHAN_MAXF 65535.0F
+#define CHAN_TYPE GL_UNSIGNED_SHORT
+#elif CHAN_BITS == 32
+ typedef GLfloat GLchan;
+#define CHAN_MAX 1.0
+#define CHAN_MAXF 1.0F
+#define CHAN_TYPE GL_FLOAT
+#else
+#error "illegal number of color channel bits"
+#endif
+
+
+/**
+ * Stencil buffer data type.
+ */
+#if STENCIL_BITS==8
+ typedef GLubyte GLstencil;
+#elif STENCIL_BITS==16
+ typedef GLushort GLstencil;
+#else
+# error "illegal number of stencil bits"
+#endif
+
+
+/**
+ * Fixed point data type.
+ */
+typedef int GLfixed;
+/*
+ * Fixed point arithmetic macros
+ */
+#ifndef FIXED_FRAC_BITS
+#define FIXED_FRAC_BITS 11
+#endif
+
+#define FIXED_SHIFT FIXED_FRAC_BITS
+#define FIXED_ONE (1 << FIXED_SHIFT)
+#define FIXED_HALF (1 << (FIXED_SHIFT-1))
+#define FIXED_FRAC_MASK (FIXED_ONE - 1)
+#define FIXED_INT_MASK (~FIXED_FRAC_MASK)
+#define FIXED_EPSILON 1
+#define FIXED_SCALE ((float) FIXED_ONE)
+#define FIXED_DBL_SCALE ((double) FIXED_ONE)
+#define FloatToFixed(X) (IROUND((X) * FIXED_SCALE))
+#define FixedToDouble(X) ((X) * (1.0 / FIXED_DBL_SCALE))
+#define IntToFixed(I) ((I) << FIXED_SHIFT)
+#define FixedToInt(X) ((X) >> FIXED_SHIFT)
+#define FixedToUns(X) (((unsigned int)(X)) >> FIXED_SHIFT)
+#define FixedCeil(X) (((X) + FIXED_ONE - FIXED_EPSILON) & FIXED_INT_MASK)
+#define FixedFloor(X) ((X) & FIXED_INT_MASK)
+#define FixedToFloat(X) ((X) * (1.0F / FIXED_SCALE))
+#define PosFloatToFixed(X) FloatToFixed(X)
+#define SignedFloatToFixed(X) FloatToFixed(X)
+
+
+
+/**
+ * \name Some forward type declarations
+ */
+/*@{*/
+struct _mesa_HashTable;
+struct gl_pixelstore_attrib;
+struct gl_texture_format;
+struct gl_texture_image;
+struct gl_texture_object;
+typedef struct __GLcontextRec GLcontext;
+typedef struct __GLcontextModesRec GLvisual;
+typedef struct gl_framebuffer GLframebuffer;
+/*@}*/
+
+
+
+/**
+ * Indexes for vertex program attributes.
+ * GL_NV_vertex_program aliases generic attributes over the conventional
+ * attributes. In GL_ARB_vertex_program shader the aliasing is optional.
+ * In GL_ARB_vertex_shader / OpenGL 2.0 the aliasing is disallowed (the
+ * generic attributes are distinct/separate).
+ */
+enum
+{
+ VERT_ATTRIB_POS = 0,
+ VERT_ATTRIB_WEIGHT = 1,
+ VERT_ATTRIB_NORMAL = 2,
+ VERT_ATTRIB_COLOR0 = 3,
+ VERT_ATTRIB_COLOR1 = 4,
+ VERT_ATTRIB_FOG = 5,
+ VERT_ATTRIB_SIX = 6,
+ VERT_ATTRIB_SEVEN = 7,
+ VERT_ATTRIB_TEX0 = 8,
+ VERT_ATTRIB_TEX1 = 9,
+ VERT_ATTRIB_TEX2 = 10,
+ VERT_ATTRIB_TEX3 = 11,
+ VERT_ATTRIB_TEX4 = 12,
+ VERT_ATTRIB_TEX5 = 13,
+ VERT_ATTRIB_TEX6 = 14,
+ VERT_ATTRIB_TEX7 = 15,
+ VERT_ATTRIB_GENERIC0 = 16,
+ VERT_ATTRIB_GENERIC1 = 17,
+ VERT_ATTRIB_GENERIC2 = 18,
+ VERT_ATTRIB_GENERIC3 = 19,
+ VERT_ATTRIB_MAX = 16 /* XXX not counting generic attribs yet */
+};
+
+/**
+ * Bitflags for vertex attributes.
+ * These are used in bitfields in many places.
+ */
+/*@{*/
+#define VERT_BIT_POS (1 << VERT_ATTRIB_POS)
+#define VERT_BIT_WEIGHT (1 << VERT_ATTRIB_WEIGHT)
+#define VERT_BIT_NORMAL (1 << VERT_ATTRIB_NORMAL)
+#define VERT_BIT_COLOR0 (1 << VERT_ATTRIB_COLOR0)
+#define VERT_BIT_COLOR1 (1 << VERT_ATTRIB_COLOR1)
+#define VERT_BIT_FOG (1 << VERT_ATTRIB_FOG)
+#define VERT_BIT_SIX (1 << VERT_ATTRIB_SIX)
+#define VERT_BIT_SEVEN (1 << VERT_ATTRIB_SEVEN)
+#define VERT_BIT_TEX0 (1 << VERT_ATTRIB_TEX0)
+#define VERT_BIT_TEX1 (1 << VERT_ATTRIB_TEX1)
+#define VERT_BIT_TEX2 (1 << VERT_ATTRIB_TEX2)
+#define VERT_BIT_TEX3 (1 << VERT_ATTRIB_TEX3)
+#define VERT_BIT_TEX4 (1 << VERT_ATTRIB_TEX4)
+#define VERT_BIT_TEX5 (1 << VERT_ATTRIB_TEX5)
+#define VERT_BIT_TEX6 (1 << VERT_ATTRIB_TEX6)
+#define VERT_BIT_TEX7 (1 << VERT_ATTRIB_TEX7)
+#define VERT_BIT_GENERIC0 (1 << VERT_ATTRIB_GENERIC0)
+#define VERT_BIT_GENERIC1 (1 << VERT_ATTRIB_GENERIC1)
+#define VERT_BIT_GENERIC2 (1 << VERT_ATTRIB_GENERIC2)
+#define VERT_BIT_GENERIC3 (1 << VERT_ATTRIB_GENERIC3)
+
+#define VERT_BIT_TEX(u) (1 << (VERT_ATTRIB_TEX0 + (u)))
+#define VERT_BIT_GENERIC(g) (1 << (VERT_ATTRIB_GENERIC0 + (g)))
+/*@}*/
+
+/**
+ * Indexes for vertex program result attributes
+ */
+/*@{*/
+#define VERT_RESULT_HPOS 0
+#define VERT_RESULT_COL0 1
+#define VERT_RESULT_COL1 2
+#define VERT_RESULT_FOGC 3
+#define VERT_RESULT_TEX0 4
+#define VERT_RESULT_TEX1 5
+#define VERT_RESULT_TEX2 6
+#define VERT_RESULT_TEX3 7
+#define VERT_RESULT_TEX4 8
+#define VERT_RESULT_TEX5 9
+#define VERT_RESULT_TEX6 10
+#define VERT_RESULT_TEX7 11
+#define VERT_RESULT_PSIZ 12
+#define VERT_RESULT_BFC0 13
+#define VERT_RESULT_BFC1 14
+#define VERT_RESULT_MAX 15
+/*@}*/
+
+
+/**
+ * Indexes for fragment program input attributes.
+ */
+enum
+{
+ FRAG_ATTRIB_WPOS = 0,
+ FRAG_ATTRIB_COL0 = 1,
+ FRAG_ATTRIB_COL1 = 2,
+ FRAG_ATTRIB_FOGC = 3,
+ FRAG_ATTRIB_TEX0 = 4,
+ FRAG_ATTRIB_TEX1 = 5,
+ FRAG_ATTRIB_TEX2 = 6,
+ FRAG_ATTRIB_TEX3 = 7,
+ FRAG_ATTRIB_TEX4 = 8,
+ FRAG_ATTRIB_TEX5 = 9,
+ FRAG_ATTRIB_TEX6 = 10,
+ FRAG_ATTRIB_TEX7 = 11,
+ FRAG_ATTRIB_MAX = 12
+};
+
+/**
+ * Bitflags for fragment program input attributes.
+ */
+/*@{*/
+#define FRAG_BIT_WPOS (1 << FRAG_ATTRIB_WPOS)
+#define FRAG_BIT_COL0 (1 << FRAG_ATTRIB_COL0)
+#define FRAG_BIT_COL1 (1 << FRAG_ATTRIB_COL1)
+#define FRAG_BIT_FOGC (1 << FRAG_ATTRIB_FOGC)
+#define FRAG_BIT_TEX0 (1 << FRAG_ATTRIB_TEX0)
+#define FRAG_BIT_TEX1 (1 << FRAG_ATTRIB_TEX1)
+#define FRAG_BIT_TEX2 (1 << FRAG_ATTRIB_TEX2)
+#define FRAG_BIT_TEX3 (1 << FRAG_ATTRIB_TEX3)
+#define FRAG_BIT_TEX4 (1 << FRAG_ATTRIB_TEX4)
+#define FRAG_BIT_TEX5 (1 << FRAG_ATTRIB_TEX5)
+#define FRAG_BIT_TEX6 (1 << FRAG_ATTRIB_TEX6)
+#define FRAG_BIT_TEX7 (1 << FRAG_ATTRIB_TEX7)
+
+#define FRAG_BITS_TEX_ANY (FRAG_BIT_TEX0| \
+ FRAG_BIT_TEX1| \
+ FRAG_BIT_TEX2| \
+ FRAG_BIT_TEX3| \
+ FRAG_BIT_TEX4| \
+ FRAG_BIT_TEX5| \
+ FRAG_BIT_TEX6| \
+ FRAG_BIT_TEX7)
+/*@}*/
+
+
+/**
+ * Fragment program results
+ */
+/*@{*/
+#define FRAG_RESULT_COLR 0
+#define FRAG_RESULT_COLH 1
+#define FRAG_RESULT_DEPR 2
+#define FRAG_RESULT_MAX 3
+/*@}*/
+
+
+/**
+ * Indexes for all renderbuffers
+ */
+enum {
+ BUFFER_FRONT_LEFT = 0, /* the four standard color buffers */
+ BUFFER_BACK_LEFT = 1,
+ BUFFER_FRONT_RIGHT = 2,
+ BUFFER_BACK_RIGHT = 3,
+ BUFFER_AUX0 = 4, /* optional aux buffer */
+ BUFFER_AUX1 = 5,
+ BUFFER_AUX2 = 6,
+ BUFFER_AUX3 = 7,
+ BUFFER_DEPTH = 8,
+ BUFFER_STENCIL = 9,
+ BUFFER_ACCUM = 10,
+ BUFFER_COLOR0 = 11, /* generic renderbuffers */
+ BUFFER_COLOR1 = 12,
+ BUFFER_COLOR2 = 13,
+ BUFFER_COLOR3 = 14,
+ BUFFER_COLOR4 = 15,
+ BUFFER_COLOR5 = 16,
+ BUFFER_COLOR6 = 17,
+ BUFFER_COLOR7 = 18,
+ BUFFER_COUNT = 19
+};
+
+/**
+ * Bit flags for all renderbuffers
+ */
+#define BUFFER_BIT_FRONT_LEFT (1 << BUFFER_FRONT_LEFT)
+#define BUFFER_BIT_BACK_LEFT (1 << BUFFER_BACK_LEFT)
+#define BUFFER_BIT_FRONT_RIGHT (1 << BUFFER_FRONT_RIGHT)
+#define BUFFER_BIT_BACK_RIGHT (1 << BUFFER_BACK_RIGHT)
+#define BUFFER_BIT_AUX0 (1 << BUFFER_AUX0)
+#define BUFFER_BIT_AUX1 (1 << BUFFER_AUX1)
+#define BUFFER_BIT_AUX2 (1 << BUFFER_AUX2)
+#define BUFFER_BIT_AUX3 (1 << BUFFER_AUX3)
+#define BUFFER_BIT_DEPTH (1 << BUFFER_DEPTH)
+#define BUFFER_BIT_STENCIL (1 << BUFFER_STENCIL)
+#define BUFFER_BIT_ACCUM (1 << BUFFER_ACCUM)
+#define BUFFER_BIT_COLOR0 (1 << BUFFER_COLOR0)
+#define BUFFER_BIT_COLOR1 (1 << BUFFER_COLOR1)
+#define BUFFER_BIT_COLOR2 (1 << BUFFER_COLOR2)
+#define BUFFER_BIT_COLOR3 (1 << BUFFER_COLOR3)
+#define BUFFER_BIT_COLOR4 (1 << BUFFER_COLOR4)
+#define BUFFER_BIT_COLOR5 (1 << BUFFER_COLOR5)
+#define BUFFER_BIT_COLOR6 (1 << BUFFER_COLOR6)
+#define BUFFER_BIT_COLOR7 (1 << BUFFER_COLOR7)
+
+/**
+ * Mask of all the color buffer bits (but not accum).
+ */
+#define BUFFER_BITS_COLOR (BUFFER_BIT_FRONT_LEFT | \
+ BUFFER_BIT_BACK_LEFT | \
+ BUFFER_BIT_FRONT_RIGHT | \
+ BUFFER_BIT_BACK_RIGHT | \
+ BUFFER_BIT_AUX0 | \
+ BUFFER_BIT_AUX1 | \
+ BUFFER_BIT_AUX2 | \
+ BUFFER_BIT_AUX3 | \
+ BUFFER_BIT_COLOR0 | \
+ BUFFER_BIT_COLOR1 | \
+ BUFFER_BIT_COLOR2 | \
+ BUFFER_BIT_COLOR3 | \
+ BUFFER_BIT_COLOR4 | \
+ BUFFER_BIT_COLOR5 | \
+ BUFFER_BIT_COLOR6 | \
+ BUFFER_BIT_COLOR7)
+
+
+
+
+/**
+ * Data structure for color tables
+ */
+struct gl_color_table
+{
+ GLenum InternalFormat; /**< The user-specified format */
+ GLenum _BaseFormat; /**< GL_ALPHA, GL_RGBA, GL_RGB, etc */
+ GLuint Size; /**< number of entries (rows) in table */
+ GLvoid *Table; /**< points to data of <Type> */
+ GLenum Type; /**< GL_UNSIGNED_BYTE or GL_FLOAT */
+ GLubyte RedSize;
+ GLubyte GreenSize;
+ GLubyte BlueSize;
+ GLubyte AlphaSize;
+ GLubyte LuminanceSize;
+ GLubyte IntensitySize;
+};
+
+
+/**
+ * \name Bit flags used for updating material values.
+ */
+/*@{*/
+#define MAT_ATTRIB_FRONT_AMBIENT 0
+#define MAT_ATTRIB_BACK_AMBIENT 1
+#define MAT_ATTRIB_FRONT_DIFFUSE 2
+#define MAT_ATTRIB_BACK_DIFFUSE 3
+#define MAT_ATTRIB_FRONT_SPECULAR 4
+#define MAT_ATTRIB_BACK_SPECULAR 5
+#define MAT_ATTRIB_FRONT_EMISSION 6
+#define MAT_ATTRIB_BACK_EMISSION 7
+#define MAT_ATTRIB_FRONT_SHININESS 8
+#define MAT_ATTRIB_BACK_SHININESS 9
+#define MAT_ATTRIB_FRONT_INDEXES 10
+#define MAT_ATTRIB_BACK_INDEXES 11
+#define MAT_ATTRIB_MAX 12
+
+#define MAT_ATTRIB_AMBIENT(f) (MAT_ATTRIB_FRONT_AMBIENT+(f))
+#define MAT_ATTRIB_DIFFUSE(f) (MAT_ATTRIB_FRONT_DIFFUSE+(f))
+#define MAT_ATTRIB_SPECULAR(f) (MAT_ATTRIB_FRONT_SPECULAR+(f))
+#define MAT_ATTRIB_EMISSION(f) (MAT_ATTRIB_FRONT_EMISSION+(f))
+#define MAT_ATTRIB_SHININESS(f)(MAT_ATTRIB_FRONT_SHININESS+(f))
+#define MAT_ATTRIB_INDEXES(f) (MAT_ATTRIB_FRONT_INDEXES+(f))
+
+#define MAT_INDEX_AMBIENT 0
+#define MAT_INDEX_DIFFUSE 1
+#define MAT_INDEX_SPECULAR 2
+
+#define MAT_BIT_FRONT_AMBIENT (1<<MAT_ATTRIB_FRONT_AMBIENT)
+#define MAT_BIT_BACK_AMBIENT (1<<MAT_ATTRIB_BACK_AMBIENT)
+#define MAT_BIT_FRONT_DIFFUSE (1<<MAT_ATTRIB_FRONT_DIFFUSE)
+#define MAT_BIT_BACK_DIFFUSE (1<<MAT_ATTRIB_BACK_DIFFUSE)
+#define MAT_BIT_FRONT_SPECULAR (1<<MAT_ATTRIB_FRONT_SPECULAR)
+#define MAT_BIT_BACK_SPECULAR (1<<MAT_ATTRIB_BACK_SPECULAR)
+#define MAT_BIT_FRONT_EMISSION (1<<MAT_ATTRIB_FRONT_EMISSION)
+#define MAT_BIT_BACK_EMISSION (1<<MAT_ATTRIB_BACK_EMISSION)
+#define MAT_BIT_FRONT_SHININESS (1<<MAT_ATTRIB_FRONT_SHININESS)
+#define MAT_BIT_BACK_SHININESS (1<<MAT_ATTRIB_BACK_SHININESS)
+#define MAT_BIT_FRONT_INDEXES (1<<MAT_ATTRIB_FRONT_INDEXES)
+#define MAT_BIT_BACK_INDEXES (1<<MAT_ATTRIB_BACK_INDEXES)
+
+
+#define FRONT_MATERIAL_BITS (MAT_BIT_FRONT_EMISSION | \
+ MAT_BIT_FRONT_AMBIENT | \
+ MAT_BIT_FRONT_DIFFUSE | \
+ MAT_BIT_FRONT_SPECULAR | \
+ MAT_BIT_FRONT_SHININESS | \
+ MAT_BIT_FRONT_INDEXES)
+
+#define BACK_MATERIAL_BITS (MAT_BIT_BACK_EMISSION | \
+ MAT_BIT_BACK_AMBIENT | \
+ MAT_BIT_BACK_DIFFUSE | \
+ MAT_BIT_BACK_SPECULAR | \
+ MAT_BIT_BACK_SHININESS | \
+ MAT_BIT_BACK_INDEXES)
+
+#define ALL_MATERIAL_BITS (FRONT_MATERIAL_BITS | BACK_MATERIAL_BITS)
+/*@}*/
+
+
+#define EXP_TABLE_SIZE 512 /**< Specular exponent lookup table sizes */
+#define SHINE_TABLE_SIZE 256 /**< Material shininess lookup table sizes */
+
+/**
+ * Material shininess lookup table.
+ */
+struct gl_shine_tab
+{
+ struct gl_shine_tab *next, *prev;
+ GLfloat tab[SHINE_TABLE_SIZE+1];
+ GLfloat shininess;
+ GLuint refcount;
+};
+
+
+/**
+ * Light source state.
+ */
+struct gl_light
+{
+ struct gl_light *next; /**< double linked list with sentinel */
+ struct gl_light *prev;
+
+ GLfloat Ambient[4]; /**< ambient color */
+ GLfloat Diffuse[4]; /**< diffuse color */
+ GLfloat Specular[4]; /**< specular color */
+ GLfloat EyePosition[4]; /**< position in eye coordinates */
+ GLfloat EyeDirection[4]; /**< spotlight dir in eye coordinates */
+ GLfloat SpotExponent;
+ GLfloat SpotCutoff; /**< in degrees */
+ GLfloat _CosCutoffNeg; /**< = cos(SpotCutoff) */
+ GLfloat _CosCutoff; /**< = MAX(0, cos(SpotCutoff)) */
+ GLfloat ConstantAttenuation;
+ GLfloat LinearAttenuation;
+ GLfloat QuadraticAttenuation;
+ GLboolean Enabled; /**< On/off flag */
+
+ /**
+ * \name Derived fields
+ */
+ /*@{*/
+ GLbitfield _Flags; /**< State */
+
+ GLfloat _Position[4]; /**< position in eye/obj coordinates */
+ GLfloat _VP_inf_norm[3]; /**< Norm direction to infinite light */
+ GLfloat _h_inf_norm[3]; /**< Norm( _VP_inf_norm + <0,0,1> ) */
+ GLfloat _NormDirection[4]; /**< normalized spotlight direction */
+ GLfloat _VP_inf_spot_attenuation;
+
+ GLfloat _SpotExpTable[EXP_TABLE_SIZE][2]; /**< to replace a pow() call */
+ GLfloat _MatAmbient[2][3]; /**< material ambient * light ambient */
+ GLfloat _MatDiffuse[2][3]; /**< material diffuse * light diffuse */
+ GLfloat _MatSpecular[2][3]; /**< material spec * light specular */
+ GLfloat _dli; /**< CI diffuse light intensity */
+ GLfloat _sli; /**< CI specular light intensity */
+ /*@}*/
+};
+
+
+/**
+ * Light model state.
+ */
+struct gl_lightmodel
+{
+ GLfloat Ambient[4]; /**< ambient color */
+ GLboolean LocalViewer; /**< Local (or infinite) view point? */
+ GLboolean TwoSide; /**< Two (or one) sided lighting? */
+ GLenum ColorControl; /**< either GL_SINGLE_COLOR
+ * or GL_SEPARATE_SPECULAR_COLOR */
+};
+
+
+/**
+ * Material state.
+ */
+struct gl_material
+{
+ GLfloat Attrib[MAT_ATTRIB_MAX][4];
+};
+
+
+/**
+ * Accumulation buffer attribute group (GL_ACCUM_BUFFER_BIT)
+ */
+struct gl_accum_attrib
+{
+ GLfloat ClearColor[4]; /**< Accumulation buffer clear color */
+};
+
+
+/**
+ * Color buffer attribute group (GL_COLOR_BUFFER_BIT).
+ */
+struct gl_colorbuffer_attrib
+{
+ GLuint ClearIndex; /**< Index to use for glClear */
+ GLclampf ClearColor[4]; /**< Color to use for glClear */
+
+ GLuint IndexMask; /**< Color index write mask */
+ GLubyte ColorMask[4]; /**< Each flag is 0xff or 0x0 */
+
+ GLenum DrawBuffer[MAX_DRAW_BUFFERS]; /**< Which buffer to draw into */
+
+ /**
+ * \name alpha testing
+ */
+ /*@{*/
+ GLboolean AlphaEnabled; /**< Alpha test enabled flag */
+ GLenum AlphaFunc; /**< Alpha test function */
+ GLclampf AlphaRef; /**< Alpha reference value */
+ /*@}*/
+
+ /**
+ * \name Blending
+ */
+ /*@{*/
+ GLboolean BlendEnabled; /**< Blending enabled flag */
+ GLenum BlendSrcRGB; /**< Blending source operator */
+ GLenum BlendDstRGB; /**< Blending destination operator */
+ GLenum BlendSrcA; /**< GL_INGR_blend_func_separate */
+ GLenum BlendDstA; /**< GL_INGR_blend_func_separate */
+ GLenum BlendEquationRGB; /**< Blending equation */
+ GLenum BlendEquationA; /**< GL_EXT_blend_equation_separate */
+ GLfloat BlendColor[4]; /**< Blending color */
+ /*@}*/
+
+ /**
+ * \name Logic op
+ */
+ /*@{*/
+ GLenum LogicOp; /**< Logic operator */
+ GLboolean IndexLogicOpEnabled; /**< Color index logic op enabled flag */
+ GLboolean ColorLogicOpEnabled; /**< RGBA logic op enabled flag */
+ GLboolean _LogicOpEnabled; /**< RGBA logic op + EXT_blend_logic_op enabled flag */
+ /*@}*/
+
+ GLboolean DitherFlag; /**< Dither enable flag */
+
+ GLenum ClampFragmentColor; /**< GL_TRUE, GL_FALSE or GL_FIXED_ONLY_ARB */
+ GLenum ClampReadColor; /**< GL_TRUE, GL_FALSE or GL_FIXED_ONLY_ARB */
+};
+
+
+/**
+ * Current attribute group (GL_CURRENT_BIT).
+ */
+struct gl_current_attrib
+{
+ /**
+ * \name Values valid only when FLUSH_VERTICES has been called.
+ */
+ /*@{*/
+ GLfloat Attrib[VERT_ATTRIB_MAX][4]; /**< Current vertex attributes
+ * indexed by VERT_ATTRIB_* */
+ GLfloat Index; /**< Current color index */
+ GLboolean EdgeFlag; /**< Current edge flag */
+ /*@}*/
+
+ /**
+ * \name Values are always valid.
+ *
+ * \note BTW, note how similar this set of attributes is to the SWvertex
+ * data type in the software rasterizer...
+ */
+ /*@{*/
+ GLfloat RasterPos[4]; /**< Current raster position */
+ GLfloat RasterDistance; /**< Current raster distance */
+ GLfloat RasterColor[4]; /**< Current raster color */
+ GLfloat RasterSecondaryColor[4]; /**< Current raster secondary color */
+ GLfloat RasterIndex; /**< Current raster index */
+ GLfloat RasterTexCoords[MAX_TEXTURE_UNITS][4];/**< Current raster texcoords */
+ GLboolean RasterPosValid; /**< Raster pos valid flag */
+ /*@}*/
+};
+
+
+/**
+ * Depth buffer attribute group (GL_DEPTH_BUFFER_BIT).
+ */
+struct gl_depthbuffer_attrib
+{
+ GLenum Func; /**< Function for depth buffer compare */
+ GLclampd Clear; /**< Value to clear depth buffer to */
+ GLboolean Test; /**< Depth buffering enabled flag */
+ GLboolean Mask; /**< Depth buffer writable? */
+ GLboolean BoundsTest; /**< GL_EXT_depth_bounds_test */
+ GLfloat BoundsMin, BoundsMax;/**< GL_EXT_depth_bounds_test */
+};
+
+
+/**
+ * glEnable()/glDisable() attribute group (GL_ENABLE_BIT).
+ */
+struct gl_enable_attrib
+{
+ GLboolean AlphaTest;
+ GLboolean AutoNormal;
+ GLboolean Blend;
+ GLbitfield ClipPlanes;
+ GLboolean ColorMaterial;
+ GLboolean ColorTable; /* SGI_color_table */
+ GLboolean PostColorMatrixColorTable; /* SGI_color_table */
+ GLboolean PostConvolutionColorTable; /* SGI_color_table */
+ GLboolean Convolution1D;
+ GLboolean Convolution2D;
+ GLboolean Separable2D;
+ GLboolean CullFace;
+ GLboolean DepthTest;
+ GLboolean Dither;
+ GLboolean Fog;
+ GLboolean Histogram;
+ GLboolean Light[MAX_LIGHTS];
+ GLboolean Lighting;
+ GLboolean LineSmooth;
+ GLboolean LineStipple;
+ GLboolean IndexLogicOp;
+ GLboolean ColorLogicOp;
+ GLboolean Map1Color4;
+ GLboolean Map1Index;
+ GLboolean Map1Normal;
+ GLboolean Map1TextureCoord1;
+ GLboolean Map1TextureCoord2;
+ GLboolean Map1TextureCoord3;
+ GLboolean Map1TextureCoord4;
+ GLboolean Map1Vertex3;
+ GLboolean Map1Vertex4;
+ GLboolean Map1Attrib[16]; /* GL_NV_vertex_program */
+ GLboolean Map2Color4;
+ GLboolean Map2Index;
+ GLboolean Map2Normal;
+ GLboolean Map2TextureCoord1;
+ GLboolean Map2TextureCoord2;
+ GLboolean Map2TextureCoord3;
+ GLboolean Map2TextureCoord4;
+ GLboolean Map2Vertex3;
+ GLboolean Map2Vertex4;
+ GLboolean Map2Attrib[16]; /* GL_NV_vertex_program */
+ GLboolean MinMax;
+ GLboolean Normalize;
+ GLboolean PixelTexture;
+ GLboolean PointSmooth;
+ GLboolean PolygonOffsetPoint;
+ GLboolean PolygonOffsetLine;
+ GLboolean PolygonOffsetFill;
+ GLboolean PolygonSmooth;
+ GLboolean PolygonStipple;
+ GLboolean RescaleNormals;
+ GLboolean Scissor;
+ GLboolean Stencil;
+ GLboolean StencilTwoSide; /* GL_EXT_stencil_two_side */
+ GLboolean MultisampleEnabled; /* GL_ARB_multisample */
+ GLboolean SampleAlphaToCoverage; /* GL_ARB_multisample */
+ GLboolean SampleAlphaToOne; /* GL_ARB_multisample */
+ GLboolean SampleCoverage; /* GL_ARB_multisample */
+ GLboolean SampleCoverageInvert; /* GL_ARB_multisample */
+ GLboolean RasterPositionUnclipped; /* GL_IBM_rasterpos_clip */
+ GLuint Texture[MAX_TEXTURE_IMAGE_UNITS];
+ GLuint TexGen[MAX_TEXTURE_COORD_UNITS];
+ /* SGI_texture_color_table */
+ GLboolean TextureColorTable[MAX_TEXTURE_IMAGE_UNITS];
+ /* GL_ARB_vertex_program / GL_NV_vertex_program */
+ GLboolean VertexProgram;
+ GLboolean VertexProgramPointSize;
+ GLboolean VertexProgramTwoSide;
+ /* GL_ARB_point_sprite / GL_NV_point_sprite */
+ GLboolean PointSprite;
+ GLboolean FragmentShaderATI;
+};
+
+
+/**
+ * Evaluator attribute group (GL_EVAL_BIT).
+ */
+struct gl_eval_attrib
+{
+ /**
+ * \name Enable bits
+ */
+ /*@{*/
+ GLboolean Map1Color4;
+ GLboolean Map1Index;
+ GLboolean Map1Normal;
+ GLboolean Map1TextureCoord1;
+ GLboolean Map1TextureCoord2;
+ GLboolean Map1TextureCoord3;
+ GLboolean Map1TextureCoord4;
+ GLboolean Map1Vertex3;
+ GLboolean Map1Vertex4;
+ GLboolean Map1Attrib[16]; /* GL_NV_vertex_program */
+ GLboolean Map2Color4;
+ GLboolean Map2Index;
+ GLboolean Map2Normal;
+ GLboolean Map2TextureCoord1;
+ GLboolean Map2TextureCoord2;
+ GLboolean Map2TextureCoord3;
+ GLboolean Map2TextureCoord4;
+ GLboolean Map2Vertex3;
+ GLboolean Map2Vertex4;
+ GLboolean Map2Attrib[16]; /* GL_NV_vertex_program */
+ GLboolean AutoNormal;
+ /*@}*/
+
+ /**
+ * \name Map Grid endpoints and divisions and calculated du values
+ */
+ /*@{*/
+ GLint MapGrid1un;
+ GLfloat MapGrid1u1, MapGrid1u2, MapGrid1du;
+ GLint MapGrid2un, MapGrid2vn;
+ GLfloat MapGrid2u1, MapGrid2u2, MapGrid2du;
+ GLfloat MapGrid2v1, MapGrid2v2, MapGrid2dv;
+ /*@}*/
+};
+
+
+/**
+ * Fog attribute group (GL_FOG_BIT).
+ */
+struct gl_fog_attrib
+{
+ GLboolean Enabled; /**< Fog enabled flag */
+ GLfloat Color[4]; /**< Fog color */
+ GLfloat Density; /**< Density >= 0.0 */
+ GLfloat Start; /**< Start distance in eye coords */
+ GLfloat End; /**< End distance in eye coords */
+ GLfloat Index; /**< Fog index */
+ GLenum Mode; /**< Fog mode */
+ GLboolean ColorSumEnabled;
+ GLenum FogCoordinateSource; /**< GL_EXT_fog_coord */
+ GLfloat _Scale; /**< (End == Start) ? 1.0 : 1.0 / (End - Start) */
+};
+
+
+/**
+ * Hint attribute group (GL_HINT_BIT).
+ *
+ * Values are always one of GL_FASTEST, GL_NICEST, or GL_DONT_CARE.
+ */
+struct gl_hint_attrib
+{
+ GLenum PerspectiveCorrection;
+ GLenum PointSmooth;
+ GLenum LineSmooth;
+ GLenum PolygonSmooth;
+ GLenum Fog;
+ GLenum ClipVolumeClipping; /**< GL_EXT_clip_volume_hint */
+ GLenum TextureCompression; /**< GL_ARB_texture_compression */
+ GLenum GenerateMipmap; /**< GL_SGIS_generate_mipmap */
+ GLenum FragmentShaderDerivative; /**< GL_ARB_fragment_shader */
+};
+
+
+/**
+ * Histogram attributes.
+ */
+struct gl_histogram_attrib
+{
+ GLuint Width; /**< number of table entries */
+ GLint Format; /**< GL_ALPHA, GL_RGB, etc */
+ GLuint Count[HISTOGRAM_TABLE_SIZE][4]; /**< the histogram */
+ GLboolean Sink; /**< terminate image transfer? */
+ GLubyte RedSize; /**< Bits per counter */
+ GLubyte GreenSize;
+ GLubyte BlueSize;
+ GLubyte AlphaSize;
+ GLubyte LuminanceSize;
+};
+
+
+/**
+ * Color Min/max state.
+ */
+struct gl_minmax_attrib
+{
+ GLenum Format;
+ GLboolean Sink;
+ GLfloat Min[4], Max[4]; /**< RGBA */
+};
+
+
+/**
+ * Image convolution state.
+ */
+struct gl_convolution_attrib
+{
+ GLenum Format;
+ GLenum InternalFormat;
+ GLuint Width;
+ GLuint Height;
+ GLfloat Filter[MAX_CONVOLUTION_WIDTH * MAX_CONVOLUTION_HEIGHT * 4];
+};
+
+
+/**
+ * Light state flags.
+ */
+/*@{*/
+#define LIGHT_SPOT 0x1
+#define LIGHT_LOCAL_VIEWER 0x2
+#define LIGHT_POSITIONAL 0x4
+#define LIGHT_NEED_VERTICES (LIGHT_POSITIONAL|LIGHT_LOCAL_VIEWER)
+/*@}*/
+
+
+/**
+ * Lighting attribute group (GL_LIGHT_BIT).
+ */
+struct gl_light_attrib
+{
+ struct gl_light Light[MAX_LIGHTS]; /**< Array of light sources */
+ struct gl_lightmodel Model; /**< Lighting model */
+
+ /**
+ * Must flush FLUSH_VERTICES before referencing:
+ */
+ /*@{*/
+ struct gl_material Material; /**< Includes front & back values */
+ /*@}*/
+
+ GLboolean Enabled; /**< Lighting enabled flag */
+ GLenum ShadeModel; /**< GL_FLAT or GL_SMOOTH */
+ GLenum ColorMaterialFace; /**< GL_FRONT, BACK or FRONT_AND_BACK */
+ GLenum ColorMaterialMode; /**< GL_AMBIENT, GL_DIFFUSE, etc */
+ GLbitfield ColorMaterialBitmask; /**< bitmask formed from Face and Mode */
+ GLboolean ColorMaterialEnabled;
+
+ struct gl_light EnabledList; /**< List sentinel */
+
+ /**
+ * Derived state for optimizations:
+ */
+ /*@{*/
+ GLboolean _NeedEyeCoords;
+ GLboolean _NeedVertices; /**< Use fast shader? */
+ GLbitfield _Flags; /**< LIGHT_* flags, see above */
+ GLfloat _BaseColor[2][3];
+ /*@}*/
+};
+
+
+/**
+ * Line attribute group (GL_LINE_BIT).
+ */
+struct gl_line_attrib
+{
+ GLboolean SmoothFlag; /**< GL_LINE_SMOOTH enabled? */
+ GLboolean StippleFlag; /**< GL_LINE_STIPPLE enabled? */
+ GLushort StipplePattern; /**< Stipple pattern */
+ GLint StippleFactor; /**< Stipple repeat factor */
+ GLfloat Width; /**< Line width */
+ GLfloat _Width; /**< Clamped Line width */
+};
+
+
+/**
+ * Display list attribute group (GL_LIST_BIT).
+ */
+struct gl_list_attrib
+{
+ GLuint ListBase;
+};
+
+
+/**
+ * Used by device drivers to hook new commands into display lists.
+ */
+struct gl_list_instruction
+{
+ GLuint Size;
+ void (*Execute)( GLcontext *ctx, void *data );
+ void (*Destroy)( GLcontext *ctx, void *data );
+ void (*Print)( GLcontext *ctx, void *data );
+};
+
+#define MAX_DLIST_EXT_OPCODES 16
+
+/**
+ * Used by device drivers to hook new commands into display lists.
+ */
+struct gl_list_extensions
+{
+ struct gl_list_instruction Opcode[MAX_DLIST_EXT_OPCODES];
+ GLuint NumOpcodes;
+};
+
+
+/**
+ * Multisample attribute group (GL_MULTISAMPLE_BIT).
+ */
+struct gl_multisample_attrib
+{
+ GLboolean Enabled;
+ GLboolean SampleAlphaToCoverage;
+ GLboolean SampleAlphaToOne;
+ GLboolean SampleCoverage;
+ GLfloat SampleCoverageValue;
+ GLboolean SampleCoverageInvert;
+};
+
+
+/**
+ * Pixel attribute group (GL_PIXEL_MODE_BIT).
+ */
+struct gl_pixel_attrib
+{
+ GLenum ReadBuffer; /**< source buffer for glRead/CopyPixels() */
+ GLfloat RedBias, RedScale;
+ GLfloat GreenBias, GreenScale;
+ GLfloat BlueBias, BlueScale;
+ GLfloat AlphaBias, AlphaScale;
+ GLfloat DepthBias, DepthScale;
+ GLint IndexShift, IndexOffset;
+ GLboolean MapColorFlag;
+ GLboolean MapStencilFlag;
+ GLfloat ZoomX, ZoomY;
+ /* XXX move these out of gl_pixel_attrib */
+ GLint MapStoSsize; /**< Size of each pixel map */
+ GLint MapItoIsize;
+ GLint MapItoRsize;
+ GLint MapItoGsize;
+ GLint MapItoBsize;
+ GLint MapItoAsize;
+ GLint MapRtoRsize;
+ GLint MapGtoGsize;
+ GLint MapBtoBsize;
+ GLint MapAtoAsize;
+ GLint MapStoS[MAX_PIXEL_MAP_TABLE]; /**< Pixel map tables */
+ GLfloat MapItoI[MAX_PIXEL_MAP_TABLE];
+ GLfloat MapItoR[MAX_PIXEL_MAP_TABLE];
+ GLfloat MapItoG[MAX_PIXEL_MAP_TABLE];
+ GLfloat MapItoB[MAX_PIXEL_MAP_TABLE];
+ GLfloat MapItoA[MAX_PIXEL_MAP_TABLE];
+ GLubyte MapItoR8[MAX_PIXEL_MAP_TABLE]; /**< converted to 8-bit color */
+ GLubyte MapItoG8[MAX_PIXEL_MAP_TABLE];
+ GLubyte MapItoB8[MAX_PIXEL_MAP_TABLE];
+ GLubyte MapItoA8[MAX_PIXEL_MAP_TABLE];
+ GLfloat MapRtoR[MAX_PIXEL_MAP_TABLE];
+ GLfloat MapGtoG[MAX_PIXEL_MAP_TABLE];
+ GLfloat MapBtoB[MAX_PIXEL_MAP_TABLE];
+ GLfloat MapAtoA[MAX_PIXEL_MAP_TABLE];
+ /** GL_EXT_histogram */
+ GLboolean HistogramEnabled;
+ GLboolean MinMaxEnabled;
+ /** GL_SGI_color_matrix */
+ GLfloat PostColorMatrixScale[4]; /**< RGBA */
+ GLfloat PostColorMatrixBias[4]; /**< RGBA */
+ /** GL_SGI_color_table */
+ GLfloat ColorTableScale[4];
+ GLfloat ColorTableBias[4];
+ GLboolean ColorTableEnabled;
+ GLfloat PCCTscale[4];
+ GLfloat PCCTbias[4];
+ GLboolean PostConvolutionColorTableEnabled;
+ GLfloat PCMCTscale[4];
+ GLfloat PCMCTbias[4];
+ GLboolean PostColorMatrixColorTableEnabled;
+ /** GL_SGI_texture_color_table */
+ GLfloat TextureColorTableScale[4];
+ GLfloat TextureColorTableBias[4];
+ /** Convolution */
+ GLboolean Convolution1DEnabled;
+ GLboolean Convolution2DEnabled;
+ GLboolean Separable2DEnabled;
+ GLfloat ConvolutionBorderColor[3][4];
+ GLenum ConvolutionBorderMode[3];
+ GLfloat ConvolutionFilterScale[3][4];
+ GLfloat ConvolutionFilterBias[3][4];
+ GLfloat PostConvolutionScale[4]; /**< RGBA */
+ GLfloat PostConvolutionBias[4]; /**< RGBA */
+};
+
+
+/**
+ * Point attribute group (GL_POINT_BIT).
+ */
+struct gl_point_attrib
+{
+ GLboolean SmoothFlag; /**< True if GL_POINT_SMOOTH is enabled */
+ GLfloat Size; /**< User-specified point size */
+ GLfloat _Size; /**< Size clamped to Const.Min/MaxPointSize */
+ GLfloat Params[3]; /**< GL_EXT_point_parameters */
+ GLfloat MinSize, MaxSize; /**< GL_EXT_point_parameters */
+ GLfloat Threshold; /**< GL_EXT_point_parameters */
+ GLboolean _Attenuated; /**< True if Params != [1, 0, 0] */
+ GLboolean PointSprite; /**< GL_NV_point_sprite / GL_NV_point_sprite */
+ GLboolean CoordReplace[MAX_TEXTURE_UNITS]; /**< GL_NV/ARB_point_sprite */
+ GLenum SpriteRMode; /**< GL_NV_point_sprite (only!) */
+ GLenum SpriteOrigin; /**< GL_ARB_point_sprite */
+};
+
+
+/**
+ * Polygon attribute group (GL_POLYGON_BIT).
+ */
+struct gl_polygon_attrib
+{
+ GLenum FrontFace; /**< Either GL_CW or GL_CCW */
+ GLenum FrontMode; /**< Either GL_POINT, GL_LINE or GL_FILL */
+ GLenum BackMode; /**< Either GL_POINT, GL_LINE or GL_FILL */
+ GLboolean _FrontBit; /**< 0=GL_CCW, 1=GL_CW */
+ GLboolean CullFlag; /**< Culling on/off flag */
+ GLboolean SmoothFlag; /**< True if GL_POLYGON_SMOOTH is enabled */
+ GLboolean StippleFlag; /**< True if GL_POLYGON_STIPPLE is enabled */
+ GLenum CullFaceMode; /**< Culling mode GL_FRONT or GL_BACK */
+ GLfloat OffsetFactor; /**< Polygon offset factor, from user */
+ GLfloat OffsetUnits; /**< Polygon offset units, from user */
+ GLboolean OffsetPoint; /**< Offset in GL_POINT mode */
+ GLboolean OffsetLine; /**< Offset in GL_LINE mode */
+ GLboolean OffsetFill; /**< Offset in GL_FILL mode */
+};
+
+
+/**
+ * Scissor attributes (GL_SCISSOR_BIT).
+ */
+struct gl_scissor_attrib
+{
+ GLboolean Enabled; /**< Scissor test enabled? */
+ GLint X, Y; /**< Lower left corner of box */
+ GLsizei Width, Height; /**< Size of box */
+};
+
+
+/**
+ * Stencil attribute group (GL_STENCIL_BUFFER_BIT).
+ */
+struct gl_stencil_attrib
+{
+ GLboolean Enabled; /**< Enabled flag */
+ GLboolean TestTwoSide; /**< GL_EXT_stencil_two_side */
+ GLubyte ActiveFace; /**< GL_EXT_stencil_two_side (0 or 1) */
+ GLboolean _TestTwoSide;
+ GLenum Function[2]; /**< Stencil function */
+ GLenum FailFunc[2]; /**< Fail function */
+ GLenum ZPassFunc[2]; /**< Depth buffer pass function */
+ GLenum ZFailFunc[2]; /**< Depth buffer fail function */
+ GLint Ref[2]; /**< Reference value */
+ GLuint ValueMask[2]; /**< Value mask */
+ GLuint WriteMask[2]; /**< Write mask */
+ GLuint Clear; /**< Clear value */
+};
+
+
+#define NUM_TEXTURE_TARGETS 5 /* 1D, 2D, 3D, CUBE and RECT */
+
+/**
+ * An index for each type of texture object
+ */
+/*@{*/
+#define TEXTURE_1D_INDEX 0
+#define TEXTURE_2D_INDEX 1
+#define TEXTURE_3D_INDEX 2
+#define TEXTURE_CUBE_INDEX 3
+#define TEXTURE_RECT_INDEX 4
+/*@}*/
+
+/**
+ * Bit flags for each type of texture object
+ * Used for Texture.Unit[]._ReallyEnabled flags.
+ */
+/*@{*/
+#define TEXTURE_1D_BIT (1 << TEXTURE_1D_INDEX)
+#define TEXTURE_2D_BIT (1 << TEXTURE_2D_INDEX)
+#define TEXTURE_3D_BIT (1 << TEXTURE_3D_INDEX)
+#define TEXTURE_CUBE_BIT (1 << TEXTURE_CUBE_INDEX)
+#define TEXTURE_RECT_BIT (1 << TEXTURE_RECT_INDEX)
+/*@}*/
+
+
+/**
+ * TexGenEnabled flags.
+ */
+/*@{*/
+#define S_BIT 1
+#define T_BIT 2
+#define R_BIT 4
+#define Q_BIT 8
+/*@}*/
+
+
+/**
+ * Bit flag versions of the corresponding GL_ constants.
+ */
+/*@{*/
+#define TEXGEN_SPHERE_MAP 0x1
+#define TEXGEN_OBJ_LINEAR 0x2
+#define TEXGEN_EYE_LINEAR 0x4
+#define TEXGEN_REFLECTION_MAP_NV 0x8
+#define TEXGEN_NORMAL_MAP_NV 0x10
+
+#define TEXGEN_NEED_NORMALS (TEXGEN_SPHERE_MAP | \
+ TEXGEN_REFLECTION_MAP_NV | \
+ TEXGEN_NORMAL_MAP_NV)
+#define TEXGEN_NEED_EYE_COORD (TEXGEN_SPHERE_MAP | \
+ TEXGEN_REFLECTION_MAP_NV | \
+ TEXGEN_NORMAL_MAP_NV | \
+ TEXGEN_EYE_LINEAR)
+/*@}*/
+
+
+/* A selection of state flags to make driver and module's lives easier. */
+#define ENABLE_TEXGEN0 0x1
+#define ENABLE_TEXGEN1 0x2
+#define ENABLE_TEXGEN2 0x4
+#define ENABLE_TEXGEN3 0x8
+#define ENABLE_TEXGEN4 0x10
+#define ENABLE_TEXGEN5 0x20
+#define ENABLE_TEXGEN6 0x40
+#define ENABLE_TEXGEN7 0x80
+
+#define ENABLE_TEXMAT0 0x1 /* Ie. not the identity matrix */
+#define ENABLE_TEXMAT1 0x2
+#define ENABLE_TEXMAT2 0x4
+#define ENABLE_TEXMAT3 0x8
+#define ENABLE_TEXMAT4 0x10
+#define ENABLE_TEXMAT5 0x20
+#define ENABLE_TEXMAT6 0x40
+#define ENABLE_TEXMAT7 0x80
+
+#define ENABLE_TEXGEN(i) (ENABLE_TEXGEN0 << (i))
+#define ENABLE_TEXMAT(i) (ENABLE_TEXMAT0 << (i))
+
+
+/**
+ * Texel fetch function prototype. We use texel fetch functions to
+ * extract RGBA, color indexes and depth components out of 1D, 2D and 3D
+ * texture images. These functions help to isolate us from the gritty
+ * details of all the various texture image encodings.
+ *
+ * \param texImage texture image.
+ * \param col texel column.
+ * \param row texel row.
+ * \param img texel image level/layer.
+ * \param texelOut output texel (up to 4 GLchans)
+ */
+typedef void (*FetchTexelFuncC)( const struct gl_texture_image *texImage,
+ GLint col, GLint row, GLint img,
+ GLchan *texelOut );
+
+/**
+ * As above, but returns floats.
+ * Used for depth component images and for upcoming signed/float
+ * texture images.
+ */
+typedef void (*FetchTexelFuncF)( const struct gl_texture_image *texImage,
+ GLint col, GLint row, GLint img,
+ GLfloat *texelOut );
+
+
+typedef void (*StoreTexelFunc)(struct gl_texture_image *texImage,
+ GLint col, GLint row, GLint img,
+ const void *texel);
+
+/**
+ * TexImage store function. This is called by the glTex[Sub]Image
+ * functions and is responsible for converting the user-specified texture
+ * image into a specific (hardware) image format.
+ */
+typedef GLboolean (*StoreTexImageFunc)(GLcontext *ctx, GLuint dims,
+ GLenum baseInternalFormat,
+ const struct gl_texture_format *dstFormat,
+ GLvoid *dstAddr,
+ GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
+ GLint dstRowStride, GLint dstImageStride,
+ GLint srcWidth, GLint srcHeight, GLint srcDepth,
+ GLenum srcFormat, GLenum srcType,
+ const GLvoid *srcAddr,
+ const struct gl_pixelstore_attrib *srcPacking);
+
+
+
+/**
+ * Texture format record
+ */
+struct gl_texture_format
+{
+ GLint MesaFormat; /**< One of the MESA_FORMAT_* values */
+
+ GLenum BaseFormat; /**< Either GL_RGB, GL_RGBA, GL_ALPHA,
+ * GL_LUMINANCE, GL_LUMINANCE_ALPHA,
+ * GL_INTENSITY, GL_COLOR_INDEX or
+ * GL_DEPTH_COMPONENT.
+ */
+ GLenum DataType; /**< GL_FLOAT or GL_UNSIGNED_NORMALIZED_ARB */
+ GLubyte RedBits; /**< Bits per texel component */
+ GLubyte GreenBits; /**< These are just rough approximations for */
+ GLubyte BlueBits; /**< compressed texture formats. */
+ GLubyte AlphaBits;
+ GLubyte LuminanceBits;
+ GLubyte IntensityBits;
+ GLubyte IndexBits;
+ GLubyte DepthBits;
+ GLubyte StencilBits; /**< GL_EXT_packed_depth_stencil */
+
+ GLuint TexelBytes; /**< Bytes per texel, 0 if compressed format */
+
+ StoreTexImageFunc StoreImage;
+
+ /**
+ * \name Texel fetch function pointers
+ */
+ /*@{*/
+ FetchTexelFuncC FetchTexel1D;
+ FetchTexelFuncC FetchTexel2D;
+ FetchTexelFuncC FetchTexel3D;
+ FetchTexelFuncF FetchTexel1Df;
+ FetchTexelFuncF FetchTexel2Df;
+ FetchTexelFuncF FetchTexel3Df;
+ /*@}*/
+
+ StoreTexelFunc StoreTexel;
+};
+
+
+/**
+ * Texture image state. Describes the dimensions of a texture image,
+ * the texel format and pointers to Texel Fetch functions.
+ */
+struct gl_texture_image
+{
+ GLenum _BaseFormat; /**< Either GL_RGB, GL_RGBA, GL_ALPHA,
+ * GL_LUMINANCE, GL_LUMINANCE_ALPHA,
+ * GL_INTENSITY, GL_COLOR_INDEX,
+ * GL_DEPTH_COMPONENT or GL_DEPTH_STENCIL_EXT
+ * only. Used for choosing TexEnv arithmetic.
+ */
+ GLint InternalFormat; /**< Internal format as given by the user */
+ GLuint Border; /**< 0 or 1 */
+ GLuint Width; /**< = 2^WidthLog2 + 2*Border */
+ GLuint Height; /**< = 2^HeightLog2 + 2*Border */
+ GLuint Depth; /**< = 2^DepthLog2 + 2*Border */
+ GLuint RowStride; /**< == Width unless IsClientData and padded */
+ GLuint ImageStride; /**< Stride between images, in texels */
+ GLuint Width2; /**< = Width - 2*Border */
+ GLuint Height2; /**< = Height - 2*Border */
+ GLuint Depth2; /**< = Depth - 2*Border */
+ GLuint WidthLog2; /**< = log2(Width2) */
+ GLuint HeightLog2; /**< = log2(Height2) */
+ GLuint DepthLog2; /**< = log2(Depth2) */
+ GLuint MaxLog2; /**< = MAX(WidthLog2, HeightLog2) */
+ GLfloat WidthScale; /**< used for mipmap LOD computation */
+ GLfloat HeightScale; /**< used for mipmap LOD computation */
+ GLfloat DepthScale; /**< used for mipmap LOD computation */
+ GLvoid *Data; /**< Image data, accessed via FetchTexel() */
+ GLboolean IsClientData; /**< Data owned by client? */
+ GLboolean _IsPowerOfTwo; /**< Are all dimensions powers of two? */
+
+ const struct gl_texture_format *TexFormat;
+
+ struct gl_texture_object *TexObject; /**< Pointer back to parent object */
+
+ FetchTexelFuncC FetchTexelc; /**< GLchan texel fetch function pointer */
+ FetchTexelFuncF FetchTexelf; /**< Float texel fetch function pointer */
+
+ GLboolean IsCompressed; /**< GL_ARB_texture_compression */
+ GLuint CompressedSize; /**< GL_ARB_texture_compression */
+
+ /**
+ * \name For device driver:
+ */
+ /*@{*/
+ void *DriverData; /**< Arbitrary device driver data */
+ /*@}*/
+};
+
+
+/**
+ * Indexes for cube map faces.
+ */
+/*@{*/
+#define FACE_POS_X 0
+#define FACE_NEG_X 1
+#define FACE_POS_Y 2
+#define FACE_NEG_Y 3
+#define FACE_POS_Z 4
+#define FACE_NEG_Z 5
+#define MAX_FACES 6
+/*@}*/
+
+
+/**
+ * Texture object state. Contains the array of mipmap images, border color,
+ * wrap modes, filter modes, shadow/texcompare state, and the per-texture
+ * color palette.
+ */
+struct gl_texture_object
+{
+ _glthread_Mutex Mutex; /**< for thread safety */
+ GLint RefCount; /**< reference count */
+ GLuint Name; /**< the user-visible texture object ID */
+ GLenum Target; /**< GL_TEXTURE_1D, GL_TEXTURE_2D, etc. */
+ GLfloat Priority; /**< in [0,1] */
+ GLfloat BorderColor[4]; /**< unclamped */
+ GLchan _BorderChan[4]; /**< clamped, as GLchan */
+ GLenum WrapS; /**< S-axis texture image wrap mode */
+ GLenum WrapT; /**< T-axis texture image wrap mode */
+ GLenum WrapR; /**< R-axis texture image wrap mode */
+ GLenum MinFilter; /**< minification filter */
+ GLenum MagFilter; /**< magnification filter */
+ GLfloat MinLod; /**< min lambda, OpenGL 1.2 */
+ GLfloat MaxLod; /**< max lambda, OpenGL 1.2 */
+ GLfloat LodBias; /**< OpenGL 1.4 */
+ GLint BaseLevel; /**< min mipmap level, OpenGL 1.2 */
+ GLint MaxLevel; /**< max mipmap level, OpenGL 1.2 */
+ GLfloat MaxAnisotropy; /**< GL_EXT_texture_filter_anisotropic */
+ GLboolean CompareFlag; /**< GL_SGIX_shadow */
+ GLenum CompareOperator; /**< GL_SGIX_shadow */
+ GLfloat ShadowAmbient; /**< GL_ARB_shadow_ambient */
+ GLenum CompareMode; /**< GL_ARB_shadow */
+ GLenum CompareFunc; /**< GL_ARB_shadow */
+ GLenum DepthMode; /**< GL_ARB_depth_texture */
+ GLint _MaxLevel; /**< actual max mipmap level (q in the spec) */
+ GLfloat _MaxLambda; /**< = _MaxLevel - BaseLevel (q - b in spec) */
+ GLboolean GenerateMipmap; /**< GL_SGIS_generate_mipmap */
+ GLboolean Complete; /**< Is texture object complete? */
+
+ /** Actual texture images, indexed by [cube face] and [mipmap level] */
+ struct gl_texture_image *Image[MAX_FACES][MAX_TEXTURE_LEVELS];
+
+ /** GL_EXT_paletted_texture */
+ struct gl_color_table Palette;
+
+
+ /**
+ * \name For device driver.
+ * Note: instead of attaching driver data to this pointer, it's preferable
+ * to instead use this struct as a base class for your own texture object
+ * class. Driver->NewTextureObject() can be used to implement the
+ * allocation.
+ */
+ void *DriverData; /**< Arbitrary device driver data */
+};
+
+
+/**
+ * Texture combine environment state.
+ *
+ * \todo
+ * If GL_NV_texture_env_combine4 is ever supported, the arrays in this
+ * structure will need to be expanded for 4 elements.
+ */
+struct gl_tex_env_combine_state
+{
+ GLenum ModeRGB; /**< GL_REPLACE, GL_DECAL, GL_ADD, etc. */
+ GLenum ModeA; /**< GL_REPLACE, GL_DECAL, GL_ADD, etc. */
+ GLenum SourceRGB[3]; /**< GL_PRIMARY_COLOR, GL_TEXTURE, etc. */
+ GLenum SourceA[3]; /**< GL_PRIMARY_COLOR, GL_TEXTURE, etc. */
+ GLenum OperandRGB[3]; /**< SRC_COLOR, ONE_MINUS_SRC_COLOR, etc */
+ GLenum OperandA[3]; /**< SRC_ALPHA, ONE_MINUS_SRC_ALPHA, etc */
+ GLuint ScaleShiftRGB; /**< 0, 1 or 2 */
+ GLuint ScaleShiftA; /**< 0, 1 or 2 */
+ GLuint _NumArgsRGB; /**< Number of inputs used for the combine mode. */
+ GLuint _NumArgsA; /**< Number of inputs used for the combine mode. */
+};
+
+
+/**
+ * Texture unit state. Contains enable flags, texture environment/function/
+ * combiners, texgen state, pointers to current texture objects and
+ * post-filter color tables.
+ */
+struct gl_texture_unit
+{
+ GLbitfield Enabled; /**< bitmask of TEXTURE_*_BIT flags */
+ GLbitfield _ReallyEnabled; /**< 0 or exactly one of TEXTURE_*_BIT flags */
+
+ GLenum EnvMode; /**< GL_MODULATE, GL_DECAL, GL_BLEND, etc. */
+ GLfloat EnvColor[4];
+ GLbitfield TexGenEnabled; /**< Bitwise-OR of [STRQ]_BIT values */
+ /** \name Tex coord generation mode
+ * Either GL_OBJECT_LINEAR, GL_EYE_LINEAR or GL_SPHERE_MAP. */
+ /*@{*/
+ GLenum GenModeS;
+ GLenum GenModeT;
+ GLenum GenModeR;
+ GLenum GenModeQ;
+ /*@}*/
+ GLbitfield _GenBitS;
+ GLbitfield _GenBitT;
+ GLbitfield _GenBitR;
+ GLbitfield _GenBitQ;
+ GLbitfield _GenFlags; /**< bitwise or of GenBit[STRQ] */
+ GLfloat ObjectPlaneS[4];
+ GLfloat ObjectPlaneT[4];
+ GLfloat ObjectPlaneR[4];
+ GLfloat ObjectPlaneQ[4];
+ GLfloat EyePlaneS[4];
+ GLfloat EyePlaneT[4];
+ GLfloat EyePlaneR[4];
+ GLfloat EyePlaneQ[4];
+ GLfloat LodBias; /**< for biasing mipmap levels */
+
+ /**
+ * \name GL_EXT_texture_env_combine
+ */
+ struct gl_tex_env_combine_state Combine;
+
+ /**
+ * Derived state based on \c EnvMode and the \c BaseFormat of the
+ * currently enabled texture.
+ */
+ struct gl_tex_env_combine_state _EnvMode;
+
+ /**
+ * Currently enabled combiner state. This will point to either
+ * \c Combine or \c _EnvMode.
+ */
+ struct gl_tex_env_combine_state *_CurrentCombine;
+
+ struct gl_texture_object *Current1D;
+ struct gl_texture_object *Current2D;
+ struct gl_texture_object *Current3D;
+ struct gl_texture_object *CurrentCubeMap; /**< GL_ARB_texture_cube_map */
+ struct gl_texture_object *CurrentRect; /**< GL_NV_texture_rectangle */
+
+ struct gl_texture_object *_Current; /**< Points to really enabled tex obj */
+
+ struct gl_texture_object Saved1D; /**< only used by glPush/PopAttrib */
+ struct gl_texture_object Saved2D;
+ struct gl_texture_object Saved3D;
+ struct gl_texture_object SavedCubeMap;
+ struct gl_texture_object SavedRect;
+
+ /* GL_SGI_texture_color_table */
+ struct gl_color_table ColorTable;
+ struct gl_color_table ProxyColorTable;
+ GLboolean ColorTableEnabled;
+};
+
+struct texenvprog_cache {
+ GLuint hash;
+ void *key;
+ void *data;
+ struct texenvprog_cache *next;
+};
+
+/**
+ * Texture attribute group (GL_TEXTURE_BIT).
+ */
+struct gl_texture_attrib
+{
+ /**
+ * name multitexture
+ */
+ /**@{*/
+ GLuint CurrentUnit; /**< Active texture unit */
+ GLbitfield _EnabledUnits; /**< one bit set for each really-enabled unit */
+ GLbitfield _EnabledCoordUnits; /**< one bit per enabled coordinate unit */
+ GLbitfield _GenFlags; /**< for texgen */
+ GLbitfield _TexGenEnabled;
+ GLbitfield _TexMatEnabled;
+ /**@}*/
+
+ struct gl_texture_unit Unit[MAX_TEXTURE_UNITS];
+
+ struct gl_texture_object *Proxy1D;
+ struct gl_texture_object *Proxy2D;
+ struct gl_texture_object *Proxy3D;
+ struct gl_texture_object *ProxyCubeMap;
+ struct gl_texture_object *ProxyRect;
+
+ /** GL_EXT_shared_texture_palette */
+ GLboolean SharedPalette;
+ struct gl_color_table Palette;
+
+ /** Cached texenv fragment programs */
+ struct texenvprog_cache *env_fp_cache;
+};
+
+
+/**
+ * Transformation attribute group (GL_TRANSFORM_BIT).
+ */
+struct gl_transform_attrib
+{
+ GLenum MatrixMode; /**< Matrix mode */
+ GLfloat EyeUserPlane[MAX_CLIP_PLANES][4]; /**< User clip planes */
+ GLfloat _ClipUserPlane[MAX_CLIP_PLANES][4]; /**< derived */
+ GLbitfield ClipPlanesEnabled; /**< on/off bitmask */
+ GLboolean Normalize; /**< Normalize all normals? */
+ GLboolean RescaleNormals; /**< GL_EXT_rescale_normal */
+ GLboolean RasterPositionUnclipped; /**< GL_IBM_rasterpos_clip */
+
+ GLboolean CullVertexFlag; /**< True if GL_CULL_VERTEX_EXT is enabled */
+ GLfloat CullEyePos[4];
+ GLfloat CullObjPos[4];
+};
+
+
+/**
+ * Viewport attribute group (GL_VIEWPORT_BIT).
+ */
+struct gl_viewport_attrib
+{
+ GLint X, Y; /**< position */
+ GLsizei Width, Height; /**< size */
+ GLfloat Near, Far; /**< Depth buffer range */
+ GLmatrix _WindowMap; /**< Mapping transformation as a matrix. */
+};
+
+
+/**
+ * Node for the attribute stack.
+ */
+struct gl_attrib_node
+{
+ GLbitfield kind;
+ void *data;
+ struct gl_attrib_node *next;
+};
+
+
+/**
+ * GL_ARB_vertex/pixel_buffer_object buffer object
+ */
+struct gl_buffer_object
+{
+ GLint RefCount;
+ GLuint Name;
+ GLenum Usage;
+ GLenum Access;
+ GLvoid *Pointer; /**< Only valid while buffer is mapped */
+ GLsizeiptrARB Size; /**< Size of storage in bytes */
+ GLubyte *Data; /**< Location of storage either in RAM or VRAM. */
+ GLboolean OnCard; /**< Is buffer in VRAM? (hardware drivers) */
+};
+
+
+
+/**
+ * Client pixel packing/unpacking attributes
+ */
+struct gl_pixelstore_attrib
+{
+ GLint Alignment;
+ GLint RowLength;
+ GLint SkipPixels;
+ GLint SkipRows;
+ GLint ImageHeight; /**< for GL_EXT_texture3D */
+ GLint SkipImages; /**< for GL_EXT_texture3D */
+ GLboolean SwapBytes;
+ GLboolean LsbFirst;
+ GLboolean ClientStorage; /**< GL_APPLE_client_storage */
+ GLboolean Invert; /**< GL_MESA_pack_invert */
+ struct gl_buffer_object *BufferObj; /**< GL_ARB_pixel_buffer_object */
+};
+
+
+#define CA_CLIENT_DATA 0x1 /**< Data not allocated by mesa */
+
+
+/**
+ * Client vertex array attributes
+ */
+struct gl_client_array
+{
+ GLint Size; /**< components per element (1,2,3,4) */
+ GLenum Type; /**< datatype: GL_FLOAT, GL_INT, etc */
+ GLsizei Stride; /**< user-specified stride */
+ GLsizei StrideB; /**< actual stride in bytes */
+ const GLubyte *Ptr; /**< Points to array data */
+ GLbitfield Enabled; /**< one of the _NEW_ARRAY_ bits */
+ GLboolean Normalized; /**< GL_ARB_vertex_program */
+
+ /**< GL_ARB_vertex_buffer_object */
+ struct gl_buffer_object *BufferObj;
+ GLuint _MaxElement;
+
+ GLbitfield Flags;
+};
+
+
+/**
+ * Vertex array state
+ */
+struct gl_array_attrib
+{
+ struct gl_client_array Vertex; /**< client data descriptors */
+ struct gl_client_array Normal;
+ struct gl_client_array Color;
+ struct gl_client_array SecondaryColor;
+ struct gl_client_array FogCoord;
+ struct gl_client_array Index;
+ struct gl_client_array TexCoord[MAX_TEXTURE_COORD_UNITS];
+ struct gl_client_array EdgeFlag;
+
+ struct gl_client_array VertexAttrib[VERT_ATTRIB_MAX]; /**< GL_NV_vertex_program */
+
+ GLint ActiveTexture; /**< Client Active Texture */
+ GLuint LockFirst; /**< GL_EXT_compiled_vertex_array */
+ GLuint LockCount; /**< GL_EXT_compiled_vertex_array */
+
+ GLbitfield _Enabled; /**< _NEW_ARRAY_* - bit set if array enabled */
+ GLbitfield NewState; /**< _NEW_ARRAY_* */
+
+#if FEATURE_ARB_vertex_buffer_object
+ struct gl_buffer_object *NullBufferObj;
+ struct gl_buffer_object *ArrayBufferObj;
+ struct gl_buffer_object *ElementArrayBufferObj;
+#endif
+ GLuint _MaxElement; /* Min of all enabled array's maxes */
+};
+
+
+/**
+ * Feedback buffer state
+ */
+struct gl_feedback
+{
+ GLenum Type;
+ GLbitfield _Mask; /* FB_* bits */
+ GLfloat *Buffer;
+ GLuint BufferSize;
+ GLuint Count;
+};
+
+
+/**
+ * Selection buffer state
+ */
+struct gl_selection
+{
+ GLuint *Buffer; /**< selection buffer */
+ GLuint BufferSize; /**< size of the selection buffer */
+ GLuint BufferCount; /**< number of values in the selection buffer */
+ GLuint Hits; /**< number of records in the selection buffer */
+ GLuint NameStackDepth; /**< name stack depth */
+ GLuint NameStack[MAX_NAME_STACK_DEPTH]; /**< name stack */
+ GLboolean HitFlag; /**< hit flag */
+ GLfloat HitMinZ; /**< minimum hit depth */
+ GLfloat HitMaxZ; /**< maximum hit depth */
+};
+
+
+/**
+ * 1-D Evaluator control points
+ */
+struct gl_1d_map
+{
+ GLuint Order; /**< Number of control points */
+ GLfloat u1, u2, du; /**< u1, u2, 1.0/(u2-u1) */
+ GLfloat *Points; /**< Points to contiguous control points */
+};
+
+
+/**
+ * 2-D Evaluator control points
+ */
+struct gl_2d_map
+{
+ GLuint Uorder; /**< Number of control points in U dimension */
+ GLuint Vorder; /**< Number of control points in V dimension */
+ GLfloat u1, u2, du;
+ GLfloat v1, v2, dv;
+ GLfloat *Points; /**< Points to contiguous control points */
+};
+
+
+/**
+ * All evaluator control point state
+ */
+struct gl_evaluators
+{
+ /**
+ * \name 1-D maps
+ */
+ /*@{*/
+ struct gl_1d_map Map1Vertex3;
+ struct gl_1d_map Map1Vertex4;
+ struct gl_1d_map Map1Index;
+ struct gl_1d_map Map1Color4;
+ struct gl_1d_map Map1Normal;
+ struct gl_1d_map Map1Texture1;
+ struct gl_1d_map Map1Texture2;
+ struct gl_1d_map Map1Texture3;
+ struct gl_1d_map Map1Texture4;
+ struct gl_1d_map Map1Attrib[16]; /**< GL_NV_vertex_program */
+ /*@}*/
+
+ /**
+ * \name 2-D maps
+ */
+ /*@{*/
+ struct gl_2d_map Map2Vertex3;
+ struct gl_2d_map Map2Vertex4;
+ struct gl_2d_map Map2Index;
+ struct gl_2d_map Map2Color4;
+ struct gl_2d_map Map2Normal;
+ struct gl_2d_map Map2Texture1;
+ struct gl_2d_map Map2Texture2;
+ struct gl_2d_map Map2Texture3;
+ struct gl_2d_map Map2Texture4;
+ struct gl_2d_map Map2Attrib[16]; /**< GL_NV_vertex_program */
+ /*@}*/
+};
+
+
+/**
+ * State used during execution of fragment programs.
+ */
+struct fp_machine
+{
+ GLfloat Temporaries[MAX_NV_FRAGMENT_PROGRAM_TEMPS][4];
+ GLfloat Inputs[MAX_NV_FRAGMENT_PROGRAM_INPUTS][4];
+ GLfloat Outputs[MAX_NV_FRAGMENT_PROGRAM_OUTPUTS][4];
+ GLuint CondCodes[4];
+};
+
+
+/**
+ * Names of the various vertex/fragment program register files, etc.
+ * NOTE: first four tokens must fit into 2 bits (see t_vb_arbprogram.c)
+ * All values should fit in a 4-bit field.
+ */
+enum register_file
+{
+ PROGRAM_TEMPORARY = 0,
+ PROGRAM_LOCAL_PARAM = 1,
+ PROGRAM_ENV_PARAM = 2,
+ PROGRAM_STATE_VAR = 3,
+ PROGRAM_INPUT = 4,
+ PROGRAM_OUTPUT = 5,
+ PROGRAM_NAMED_PARAM = 6,
+ PROGRAM_CONSTANT = 7,
+ PROGRAM_WRITE_ONLY = 8,
+ PROGRAM_ADDRESS = 9,
+ PROGRAM_UNDEFINED = 15 /* invalid value */
+};
+
+
+/** Vertex and fragment instructions */
+struct prog_instruction;
+struct program_parameter_list;
+
+
+/**
+ * Base class for any kind of program object
+ */
+struct program
+{
+ GLuint Id;
+ GLubyte *String; /**< Null-terminated program text */
+ GLint RefCount;
+ GLenum Target;
+ GLenum Format; /**< String encoding format */
+ GLboolean Resident;
+
+ struct prog_instruction *Instructions;
+
+ GLbitfield InputsRead; /* Bitmask of which input regs are read */
+ GLbitfield OutputsWritten; /* Bitmask of which output regs are written to */
+
+ /** Named parameters, constants, etc. from program text */
+ struct program_parameter_list *Parameters;
+ /** Numbered local parameters */
+ GLfloat LocalParams[MAX_PROGRAM_LOCAL_PARAMS][4];
+
+ /** Logical counts */
+ /*@{*/
+ GLuint NumInstructions;
+ GLuint NumTemporaries;
+ GLuint NumParameters;
+ GLuint NumAttributes;
+ GLuint NumAddressRegs;
+ /*@}*/
+ /** Native, actual h/w counts */
+ /*@{*/
+ GLuint NumNativeInstructions;
+ GLuint NumNativeTemporaries;
+ GLuint NumNativeParameters;
+ GLuint NumNativeAttributes;
+ GLuint NumNativeAddressRegs;
+ /*@}*/
+};
+
+
+/** Vertex program object */
+struct vertex_program
+{
+ struct program Base; /* base class */
+ GLboolean IsNVProgram; /* GL_NV_vertex_program ? */
+ GLboolean IsPositionInvariant; /* GL_ARB_vertex_program / GL_NV_vertex_program1_1 */
+ void *TnlData; /* should probably use Base.DriverData */
+};
+
+
+/** Fragment program object */
+struct fragment_program
+{
+ struct program Base; /**< base class */
+ GLbitfield TexturesUsed[MAX_TEXTURE_IMAGE_UNITS]; /**< TEXTURE_x_BIT bitmask */
+ GLuint NumAluInstructions; /**< GL_ARB_fragment_program */
+ GLuint NumTexInstructions;
+ GLuint NumTexIndirections;
+ GLuint NumNativeAluInstructions; /**< GL_ARB_fragment_program */
+ GLuint NumNativeTexInstructions;
+ GLuint NumNativeTexIndirections;
+ GLenum FogOption;
+ GLboolean UsesKill;
+};
+
+
+/**
+ * State common to vertex and fragment programs.
+ */
+struct gl_program_state
+{
+ GLint ErrorPos; /* GL_PROGRAM_ERROR_POSITION_ARB/NV */
+ const char *ErrorString; /* GL_PROGRAM_ERROR_STRING_ARB/NV */
+};
+
+
+/**
+ * State vars for GL_ARB/GL_NV_vertex_program
+ */
+struct gl_vertex_program_state
+{
+ GLboolean Enabled; /**< GL_VERTEX_PROGRAM_ARB/NV */
+ GLboolean _Enabled; /**< Enabled and valid program? */
+ GLboolean PointSizeEnabled; /**< GL_VERTEX_PROGRAM_POINT_SIZE_ARB/NV */
+ GLboolean TwoSideEnabled; /**< GL_VERTEX_PROGRAM_TWO_SIDE_ARB/NV */
+ struct vertex_program *Current; /**< ptr to currently bound program */
+ struct vertex_program *_Current; /**< ptr to currently bound
+ program, including internal
+ (t_vp_build.c) programs */
+
+ GLenum TrackMatrix[MAX_NV_VERTEX_PROGRAM_PARAMS / 4];
+ GLenum TrackMatrixTransform[MAX_NV_VERTEX_PROGRAM_PARAMS / 4];
+
+ GLfloat Parameters[MAX_NV_VERTEX_PROGRAM_PARAMS][4]; /* Env params */
+ /* Only used during program execution (may be moved someday): */
+ GLfloat Temporaries[MAX_NV_VERTEX_PROGRAM_TEMPS][4];
+ GLfloat Inputs[MAX_NV_VERTEX_PROGRAM_INPUTS][4];
+ GLuint InputsSize[MAX_NV_VERTEX_PROGRAM_INPUTS];
+ GLfloat Outputs[MAX_NV_VERTEX_PROGRAM_OUTPUTS][4];
+ GLint AddressReg[4];
+
+#if FEATURE_MESA_program_debug
+ GLprogramcallbackMESA Callback;
+ GLvoid *CallbackData;
+ GLboolean CallbackEnabled;
+ GLuint CurrentPosition;
+#endif
+};
+
+
+/**
+ * Context state for GL_ARB/NV_fragment_program
+ */
+struct gl_fragment_program_state
+{
+ GLboolean Enabled; /* GL_VERTEX_PROGRAM_NV */
+ GLboolean _Enabled; /* Enabled and valid program? */
+ GLboolean _Active;
+ struct fragment_program *Current; /* ptr to currently bound program */
+ struct fragment_program *_Current; /* ptr to currently active program
+ (including internal programs) */
+ struct fp_machine Machine; /* machine state */
+ GLfloat Parameters[MAX_NV_FRAGMENT_PROGRAM_PARAMS][4]; /* Env params */
+
+#if FEATURE_MESA_program_debug
+ GLprogramcallbackMESA Callback;
+ GLvoid *CallbackData;
+ GLboolean CallbackEnabled;
+ GLuint CurrentPosition;
+#endif
+};
+
+
+/**
+ * ATI_fragment_shader runtime state
+ */
+#define ATI_FS_INPUT_PRIMARY 0
+#define ATI_FS_INPUT_SECONDARY 1
+
+struct atifs_instruction;
+struct atifs_setupinst;
+
+/**
+ * State for executing ATI fragment shader.
+ */
+struct atifs_machine
+{
+ GLfloat Registers[6][4]; /** six temporary registers */
+ GLfloat PrevPassRegisters[6][4];
+ GLfloat Inputs[2][4]; /** Primary, secondary input colors */
+};
+
+
+/**
+ * ATI fragment shader
+ */
+struct ati_fragment_shader
+{
+ GLuint Id;
+ GLint RefCount;
+ struct atifs_instruction *Instructions[2];
+ struct atifs_setupinst *SetupInst[2];
+ GLfloat Constants[8][4];
+ GLbitfield LocalConstDef; /** Indicates which constants have been set */
+ GLubyte numArithInstr[2];
+ GLubyte regsAssigned[2];
+ GLubyte NumPasses; /** 1 or 2 */
+ GLubyte cur_pass;
+ GLubyte last_optype;
+ GLboolean interpinp1;
+ GLboolean isValid;
+ GLuint swizzlerq;
+};
+
+/**
+ * Context state for GL_ATI_fragment_shader
+ */
+struct gl_ati_fragment_shader_state
+{
+ GLboolean Enabled;
+ GLboolean _Enabled; /** enabled and valid shader? */
+ GLboolean Compiling;
+ GLfloat GlobalConstants[8][4];
+ struct atifs_machine Machine; /* machine state */
+ struct ati_fragment_shader *Current;
+};
+
+
+/**
+ * Occlusion/timer query object.
+ */
+struct gl_query_object
+{
+ GLuint Id;
+ GLuint64EXT Result; /* the counter */
+ GLboolean Active; /* inside Begin/EndQuery */
+ GLboolean Ready; /* result is ready */
+};
+
+
+/**
+ * Context state for query objects.
+ */
+struct gl_query_state
+{
+ struct _mesa_HashTable *QueryObjects;
+ struct gl_query_object *CurrentOcclusionObject; /* GL_ARB_occlusion_query */
+ struct gl_query_object *CurrentTimerObject; /* GL_EXT_timer_query */
+};
+
+
+/**
+ * Context state for vertex/fragment shaders.
+ */
+struct gl_shader_objects_state
+{
+ struct gl2_program_intf **CurrentProgram;
+ GLboolean _VertexShaderPresent;
+ GLboolean _FragmentShaderPresent;
+};
+
+
+/**
+ * State which can be shared by multiple contexts:
+ */
+struct gl_shared_state
+{
+ _glthread_Mutex Mutex; /**< for thread safety */
+ GLint RefCount; /**< Reference count */
+ struct _mesa_HashTable *DisplayList; /**< Display lists hash table */
+ struct _mesa_HashTable *TexObjects; /**< Texture objects hash table */
+
+ /**
+ * \name Default texture objects (shared by all multi-texture units)
+ */
+ /*@{*/
+ struct gl_texture_object *Default1D;
+ struct gl_texture_object *Default2D;
+ struct gl_texture_object *Default3D;
+ struct gl_texture_object *DefaultCubeMap;
+ struct gl_texture_object *DefaultRect;
+ /*@}*/
+
+ /**
+ * \name Vertex/fragment programs
+ */
+ /*@{*/
+ struct _mesa_HashTable *Programs; /**< All vertex/fragment programs */
+#if FEATURE_ARB_vertex_program
+ struct program *DefaultVertexProgram;
+#endif
+#if FEATURE_ARB_fragment_program
+ struct program *DefaultFragmentProgram;
+#endif
+ /*@}*/
+
+#if FEATURE_ATI_fragment_shader
+ struct _mesa_HashTable *ATIShaders;
+ struct ati_fragment_shader *DefaultFragmentShader;
+#endif
+
+#if FEATURE_ARB_vertex_buffer_object || FEATURE_ARB_pixel_buffer_object
+ struct _mesa_HashTable *BufferObjects;
+#endif
+
+ struct _mesa_HashTable *GL2Objects;
+
+#if FEATURE_EXT_framebuffer_object
+ struct _mesa_HashTable *RenderBuffers;
+ struct _mesa_HashTable *FrameBuffers;
+#endif
+
+ void *DriverData; /**< Device driver shared state */
+};
+
+
+
+
+/**
+ * A renderbuffer stores colors or depth values or stencil values.
+ * A framebuffer object will have a collection of these.
+ * Data are read/written to the buffer with a handful of Get/Put functions.
+ *
+ * Instances of this object are allocated with the Driver's NewRenderbuffer
+ * hook. Drivers will likely wrap this class inside a driver-specific
+ * class to simulate inheritance.
+ */
+struct gl_renderbuffer
+{
+ _glthread_Mutex Mutex; /**< for thread safety */
+ GLuint ClassID; /**< Useful for drivers */
+ GLuint Name;
+ GLint RefCount;
+ GLuint Width, Height;
+ GLenum InternalFormat; /**< The user-specified format */
+ GLenum _ActualFormat; /**< The driver-chosen format */
+ GLenum _BaseFormat; /**< Either GL_RGB, GL_RGBA, GL_DEPTH_COMPONENT or
+ GL_STENCIL_INDEX. */
+ GLenum DataType; /**< Type of values passed to the Get/Put functions */
+ GLubyte RedBits; /**< Bits of red per pixel */
+ GLubyte GreenBits;
+ GLubyte BlueBits;
+ GLubyte AlphaBits;
+ GLubyte IndexBits;
+ GLubyte DepthBits;
+ GLubyte StencilBits;
+ GLvoid *Data;
+
+ /* Used to wrap one renderbuffer around another: */
+ struct gl_renderbuffer *Wrapped;
+
+ /* Delete this renderbuffer */
+ void (*Delete)(struct gl_renderbuffer *rb);
+
+ /* Allocate new storage for this renderbuffer */
+ GLboolean (*AllocStorage)(GLcontext *ctx, struct gl_renderbuffer *rb,
+ GLenum internalFormat,
+ GLuint width, GLuint height);
+
+ /* Lock/Unlock are called before/after calling the Get/Put functions.
+ * Not sure this is the right place for these yet.
+ void (*Lock)(GLcontext *ctx, struct gl_renderbuffer *rb);
+ void (*Unlock)(GLcontext *ctx, struct gl_renderbuffer *rb);
+ */
+
+ /* Return a pointer to the element/pixel at (x,y).
+ * Should return NULL if the buffer memory can't be directly addressed.
+ */
+ void *(*GetPointer)(GLcontext *ctx, struct gl_renderbuffer *rb,
+ GLint x, GLint y);
+
+ /* Get/Read a row of values.
+ * The values will be of format _BaseFormat and type DataType.
+ */
+ void (*GetRow)(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ GLint x, GLint y, void *values);
+
+ /* Get/Read values at arbitrary locations.
+ * The values will be of format _BaseFormat and type DataType.
+ */
+ void (*GetValues)(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ const GLint x[], const GLint y[], void *values);
+
+ /* Put/Write a row of values.
+ * The values will be of format _BaseFormat and type DataType.
+ */
+ void (*PutRow)(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ GLint x, GLint y, const void *values, const GLubyte *mask);
+
+ /* Put/Write a row of RGB values. This is a special-case routine that's
+ * only used for RGBA renderbuffers when the source data is GL_RGB. That's
+ * a common case for glDrawPixels and some triangle routines.
+ * The values will be of format GL_RGB and type DataType.
+ */
+ void (*PutRowRGB)(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ GLint x, GLint y, const void *values, const GLubyte *mask);
+
+
+ /* Put/Write a row of identical values.
+ * The values will be of format _BaseFormat and type DataType.
+ */
+ void (*PutMonoRow)(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ GLint x, GLint y, const void *value, const GLubyte *mask);
+
+ /* Put/Write values at arbitrary locations.
+ * The values will be of format _BaseFormat and type DataType.
+ */
+ void (*PutValues)(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ const GLint x[], const GLint y[], const void *values,
+ const GLubyte *mask);
+ /* Put/Write identical values at arbitrary locations.
+ * The values will be of format _BaseFormat and type DataType.
+ */
+ void (*PutMonoValues)(GLcontext *ctx, struct gl_renderbuffer *rb,
+ GLuint count, const GLint x[], const GLint y[],
+ const void *value, const GLubyte *mask);
+};
+
+
+/**
+ * A renderbuffer attachment point points to either a texture object
+ * (and specifies a mipmap level, cube face or 3D texture slice) or
+ * points to a renderbuffer.
+ */
+struct gl_renderbuffer_attachment
+{
+ GLenum Type; /* GL_NONE or GL_TEXTURE or GL_RENDERBUFFER_EXT */
+ GLboolean Complete;
+
+ /* IF Type == GL_RENDERBUFFER_EXT: */
+ struct gl_renderbuffer *Renderbuffer;
+
+ /* IF Type == GL_TEXTURE: */
+ struct gl_texture_object *Texture;
+ GLuint TextureLevel;
+ GLuint CubeMapFace; /* 0 .. 5, for cube map textures */
+ GLuint Zoffset; /* for 3D textures */
+};
+
+
+/**
+ * A framebuffer is a collection of renderbuffers (color, depth, stencil, etc).
+ * In C++ terms, think of this as a base class from which device drivers
+ * will make derived classes.
+ */
+struct gl_framebuffer
+{
+ _glthread_Mutex Mutex; /**< for thread safety */
+ GLuint Name; /* if zero, this is a window system framebuffer */
+ GLint RefCount;
+
+ GLvisual Visual; /**< The framebuffer's visual.
+ Immutable if this is a window system buffer.
+ Computed from attachments if user-made FBO. */
+
+ GLboolean Initialized;
+
+ GLuint Width, Height; /**< size of frame buffer in pixels */
+
+ /** \name Drawing bounds (Intersection of buffer size and scissor box) */
+ /*@{*/
+ GLint _Xmin, _Xmax; /**< inclusive */
+ GLint _Ymin, _Ymax; /**< exclusive */
+ /*@}*/
+
+ /** \name Derived Z buffer stuff */
+ /*@{*/
+ GLuint _DepthMax; /**< Max depth buffer value */
+ GLfloat _DepthMaxF; /**< Float max depth buffer value */
+ GLfloat _MRD; /**< minimum resolvable difference in Z values */
+ /*@}*/
+
+ GLenum _Status; /* One of the GL_FRAMEBUFFER_(IN)COMPLETE_* tokens */
+
+ /* Array of all renderbuffer attachments, indexed by BUFFER_* tokens. */
+ struct gl_renderbuffer_attachment Attachment[BUFFER_COUNT];
+
+ /* In unextended OpenGL these vars are part of the GL_COLOR_BUFFER
+ * attribute group and GL_PIXEL attribute group, respectively.
+ */
+ GLenum ColorDrawBuffer[MAX_DRAW_BUFFERS];
+ GLenum ColorReadBuffer;
+
+ /* These are computed from ColorDrawBuffer and ColorReadBuffer */
+ GLbitfield _ColorDrawBufferMask[MAX_DRAW_BUFFERS]; /* Mask of BUFFER_BIT_* flags */
+ GLint _ColorReadBufferIndex; /* -1 = None */
+
+ /* These are computed from _ColorDrawBufferMask and _ColorReadBufferIndex */
+ GLuint _NumColorDrawBuffers[MAX_DRAW_BUFFERS];
+ struct gl_renderbuffer *_ColorDrawBuffers[MAX_DRAW_BUFFERS][4];
+ struct gl_renderbuffer *_ColorReadBuffer;
+
+ /** The Actual depth/stencil buffers to use. May be wrappers around the
+ * depth/stencil buffers attached above. */
+ struct gl_renderbuffer *_DepthBuffer;
+ struct gl_renderbuffer *_StencilBuffer;
+
+ /** Delete this framebuffer */
+ void (*Delete)(struct gl_framebuffer *fb);
+};
+
+
+/**
+ * Limits for vertex and fragment programs.
+ */
+struct gl_program_constants
+{
+ /* logical limits */
+ GLuint MaxInstructions;
+ GLuint MaxAluInstructions; /* fragment programs only, for now */
+ GLuint MaxTexInstructions; /* fragment programs only, for now */
+ GLuint MaxTexIndirections; /* fragment programs only, for now */
+ GLuint MaxAttribs;
+ GLuint MaxTemps;
+ GLuint MaxAddressRegs; /* vertex program only, for now */
+ GLuint MaxParameters;
+ GLuint MaxLocalParams;
+ GLuint MaxEnvParams;
+ /* native/hardware limits */
+ GLuint MaxNativeInstructions;
+ GLuint MaxNativeAluInstructions; /* fragment programs only, for now */
+ GLuint MaxNativeTexInstructions; /* fragment programs only, for now */
+ GLuint MaxNativeTexIndirections; /* fragment programs only, for now */
+ GLuint MaxNativeAttribs;
+ GLuint MaxNativeTemps;
+ GLuint MaxNativeAddressRegs; /* vertex program only, for now */
+ GLuint MaxNativeParameters;
+};
+
+
+/**
+ * Constants which may be overridden by device driver during context creation
+ * but are never changed after that.
+ */
+struct gl_constants
+{
+ GLint MaxTextureLevels; /**< Maximum number of allowed mipmap levels. */
+ GLint Max3DTextureLevels; /**< Maximum number of allowed mipmap levels for 3D texture targets. */
+ GLint MaxCubeTextureLevels; /**< Maximum number of allowed mipmap levels for GL_ARB_texture_cube_map */
+ GLint MaxTextureRectSize; /* GL_NV_texture_rectangle */
+ GLuint MaxTextureCoordUnits;
+ GLuint MaxTextureImageUnits;
+ GLuint MaxTextureUnits; /* = MAX(CoordUnits, ImageUnits) */
+ GLfloat MaxTextureMaxAnisotropy; /* GL_EXT_texture_filter_anisotropic */
+ GLfloat MaxTextureLodBias; /* GL_EXT_texture_lod_bias */
+ GLuint MaxArrayLockSize;
+ GLint SubPixelBits;
+ GLfloat MinPointSize, MaxPointSize; /* aliased */
+ GLfloat MinPointSizeAA, MaxPointSizeAA; /* antialiased */
+ GLfloat PointSizeGranularity;
+ GLfloat MinLineWidth, MaxLineWidth; /* aliased */
+ GLfloat MinLineWidthAA, MaxLineWidthAA; /* antialiased */
+ GLfloat LineWidthGranularity;
+ GLuint MaxColorTableSize;
+ GLuint MaxConvolutionWidth;
+ GLuint MaxConvolutionHeight;
+ GLuint MaxClipPlanes;
+ GLuint MaxLights;
+ GLfloat MaxShininess; /* GL_NV_light_max_exponent */
+ GLfloat MaxSpotExponent; /* GL_NV_light_max_exponent */
+ GLuint MaxViewportWidth, MaxViewportHeight;
+ struct gl_program_constants VertexProgram; /* GL_ARB_vertex_program */
+ struct gl_program_constants FragmentProgram; /* GL_ARB_fragment_program */
+ /* shared by vertex and fragment program: */
+ GLuint MaxProgramMatrices;
+ GLuint MaxProgramMatrixStackDepth;
+ /* vertex array / buffer object bounds checking */
+ GLboolean CheckArrayBounds;
+ /* GL_ARB_draw_buffers */
+ GLuint MaxDrawBuffers;
+ /* GL_OES_read_format */
+ GLenum ColorReadFormat;
+ GLenum ColorReadType;
+ /* GL_EXT_framebuffer_object */
+ GLuint MaxColorAttachments;
+ GLuint MaxRenderbufferSize;
+};
+
+
+/**
+ * Enable flag for each OpenGL extension. Different device drivers will
+ * enable different extensions at runtime.
+ */
+struct gl_extensions
+{
+ /**
+ * \name Flags to quickly test if certain extensions are available.
+ *
+ * Not every extension needs to have such a flag, but it's encouraged.
+ */
+ /*@{*/
+ GLboolean dummy; /* don't remove this! */
+ GLboolean ARB_depth_texture;
+ GLboolean ARB_draw_buffers;
+ GLboolean ARB_fragment_program;
+ GLboolean ARB_fragment_shader;
+ GLboolean ARB_half_float_pixel;
+ GLboolean ARB_imaging;
+ GLboolean ARB_multisample;
+ GLboolean ARB_multitexture;
+ GLboolean ARB_occlusion_query;
+ GLboolean ARB_point_sprite;
+ GLboolean ARB_shader_objects;
+ GLboolean ARB_shading_language_100;
+ GLboolean ARB_shadow;
+ GLboolean ARB_texture_border_clamp;
+ GLboolean ARB_texture_compression;
+ GLboolean ARB_texture_cube_map;
+ GLboolean ARB_texture_env_combine;
+ GLboolean ARB_texture_env_crossbar;
+ GLboolean ARB_texture_env_dot3;
+ GLboolean ARB_texture_float;
+ GLboolean ARB_texture_mirrored_repeat;
+ GLboolean ARB_texture_non_power_of_two;
+ GLboolean ARB_transpose_matrix;
+ GLboolean ARB_vertex_buffer_object;
+ GLboolean ARB_vertex_program;
+ GLboolean ARB_vertex_shader;
+ GLboolean ARB_window_pos;
+ GLboolean EXT_abgr;
+ GLboolean EXT_bgra;
+ GLboolean EXT_blend_color;
+ GLboolean EXT_blend_equation_separate;
+ GLboolean EXT_blend_func_separate;
+ GLboolean EXT_blend_logic_op;
+ GLboolean EXT_blend_minmax;
+ GLboolean EXT_blend_subtract;
+ GLboolean EXT_clip_volume_hint;
+ GLboolean EXT_cull_vertex;
+ GLboolean EXT_convolution;
+ GLboolean EXT_compiled_vertex_array;
+ GLboolean EXT_copy_texture;
+ GLboolean EXT_depth_bounds_test;
+ GLboolean EXT_draw_range_elements;
+ GLboolean EXT_framebuffer_object;
+ GLboolean EXT_fog_coord;
+ GLboolean EXT_framebuffer_blit;
+ GLboolean EXT_histogram;
+ GLboolean EXT_multi_draw_arrays;
+ GLboolean EXT_paletted_texture;
+ GLboolean EXT_packed_depth_stencil;
+ GLboolean EXT_packed_pixels;
+ GLboolean EXT_pixel_buffer_object;
+ GLboolean EXT_point_parameters;
+ GLboolean EXT_polygon_offset;
+ GLboolean EXT_rescale_normal;
+ GLboolean EXT_shadow_funcs;
+ GLboolean EXT_secondary_color;
+ GLboolean EXT_separate_specular_color;
+ GLboolean EXT_shared_texture_palette;
+ GLboolean EXT_stencil_wrap;
+ GLboolean EXT_stencil_two_side;
+ GLboolean EXT_subtexture;
+ GLboolean EXT_texture;
+ GLboolean EXT_texture_object;
+ GLboolean EXT_texture3D;
+ GLboolean EXT_texture_compression_s3tc;
+ GLboolean EXT_texture_env_add;
+ GLboolean EXT_texture_env_combine;
+ GLboolean EXT_texture_env_dot3;
+ GLboolean EXT_texture_filter_anisotropic;
+ GLboolean EXT_texture_lod_bias;
+ GLboolean EXT_texture_mirror_clamp;
+ GLboolean EXT_timer_query;
+ GLboolean EXT_vertex_array;
+ GLboolean EXT_vertex_array_set;
+ /* vendor extensions */
+ GLboolean APPLE_client_storage;
+ GLboolean APPLE_packed_pixels;
+ GLboolean ATI_texture_mirror_once;
+ GLboolean ATI_texture_env_combine3;
+ GLboolean ATI_fragment_shader;
+ GLboolean IBM_rasterpos_clip;
+ GLboolean IBM_multimode_draw_arrays;
+ GLboolean MESA_pack_invert;
+ GLboolean MESA_packed_depth_stencil;
+ GLboolean MESA_program_debug;
+ GLboolean MESA_resize_buffers;
+ GLboolean MESA_ycbcr_texture;
+ GLboolean NV_blend_square;
+ GLboolean NV_fragment_program;
+ GLboolean NV_light_max_exponent;
+ GLboolean NV_point_sprite;
+ GLboolean NV_texgen_reflection;
+ GLboolean NV_texture_rectangle;
+ GLboolean NV_vertex_program;
+ GLboolean NV_vertex_program1_1;
+ GLboolean OES_read_format;
+ GLboolean SGI_color_matrix;
+ GLboolean SGI_color_table;
+ GLboolean SGI_texture_color_table;
+ GLboolean SGIS_generate_mipmap;
+ GLboolean SGIS_texture_edge_clamp;
+ GLboolean SGIS_texture_lod;
+ GLboolean SGIX_depth_texture;
+ GLboolean SGIX_shadow;
+ GLboolean SGIX_shadow_ambient; /* or GL_ARB_shadow_ambient */
+ GLboolean TDFX_texture_compression_FXT1;
+ GLboolean S3_s3tc;
+ /*@}*/
+ /* The extension string */
+ const GLubyte *String;
+};
+
+
+/**
+ * A stack of matrices (projection, modelview, color, texture, etc).
+ */
+struct matrix_stack
+{
+ GLmatrix *Top; /**< points into Stack */
+ GLmatrix *Stack; /**< array [MaxDepth] of GLmatrix */
+ GLuint Depth; /**< 0 <= Depth < MaxDepth */
+ GLuint MaxDepth; /**< size of Stack[] array */
+ GLuint DirtyFlag; /**< _NEW_MODELVIEW or _NEW_PROJECTION, for example */
+};
+
+
+/**
+ * \name Bits for image transfer operations
+ *
+ * \sa __GLcontextRec::ImageTransferState.
+ */
+/*@{*/
+#define IMAGE_SCALE_BIAS_BIT 0x1
+#define IMAGE_SHIFT_OFFSET_BIT 0x2
+#define IMAGE_MAP_COLOR_BIT 0x4
+#define IMAGE_COLOR_TABLE_BIT 0x8
+#define IMAGE_CONVOLUTION_BIT 0x10
+#define IMAGE_POST_CONVOLUTION_SCALE_BIAS 0x20
+#define IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT 0x40
+#define IMAGE_COLOR_MATRIX_BIT 0x80
+#define IMAGE_POST_COLOR_MATRIX_COLOR_TABLE_BIT 0x100
+#define IMAGE_HISTOGRAM_BIT 0x200
+#define IMAGE_MIN_MAX_BIT 0x400
+#define IMAGE_CLAMP_BIT 0x800 /* extra */
+
+
+/** Pixel Transfer ops up to convolution */
+#define IMAGE_PRE_CONVOLUTION_BITS (IMAGE_SCALE_BIAS_BIT | \
+ IMAGE_SHIFT_OFFSET_BIT | \
+ IMAGE_MAP_COLOR_BIT | \
+ IMAGE_COLOR_TABLE_BIT)
+
+/** Pixel transfer ops after convolution */
+#define IMAGE_POST_CONVOLUTION_BITS (IMAGE_POST_CONVOLUTION_SCALE_BIAS | \
+ IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT | \
+ IMAGE_COLOR_MATRIX_BIT | \
+ IMAGE_POST_COLOR_MATRIX_COLOR_TABLE_BIT |\
+ IMAGE_HISTOGRAM_BIT | \
+ IMAGE_MIN_MAX_BIT)
+/*@}*/
+
+
+/**
+ * \name Bits to indicate what state has changed.
+ *
+ * 4 unused flags.
+ */
+/*@{*/
+#define _NEW_MODELVIEW 0x1 /**< __GLcontextRec::ModelView */
+#define _NEW_PROJECTION 0x2 /**< __GLcontextRec::Projection */
+#define _NEW_TEXTURE_MATRIX 0x4 /**< __GLcontextRec::TextureMatrix */
+#define _NEW_COLOR_MATRIX 0x8 /**< __GLcontextRec::ColorMatrix */
+#define _NEW_ACCUM 0x10 /**< __GLcontextRec::Accum */
+#define _NEW_COLOR 0x20 /**< __GLcontextRec::Color */
+#define _NEW_DEPTH 0x40 /**< __GLcontextRec::Depth */
+#define _NEW_EVAL 0x80 /**< __GLcontextRec::Eval, __GLcontextRec::EvalMap */
+#define _NEW_FOG 0x100 /**< __GLcontextRec::Fog */
+#define _NEW_HINT 0x200 /**< __GLcontextRec::Hint */
+#define _NEW_LIGHT 0x400 /**< __GLcontextRec::Light */
+#define _NEW_LINE 0x800 /**< __GLcontextRec::Line */
+#define _NEW_PIXEL 0x1000 /**< __GLcontextRec::Pixel */
+#define _NEW_POINT 0x2000 /**< __GLcontextRec::Point */
+#define _NEW_POLYGON 0x4000 /**< __GLcontextRec::Polygon */
+#define _NEW_POLYGONSTIPPLE 0x8000 /**< __GLcontextRec::PolygonStipple */
+#define _NEW_SCISSOR 0x10000 /**< __GLcontextRec::Scissor */
+#define _NEW_STENCIL 0x20000 /**< __GLcontextRec::Stencil */
+#define _NEW_TEXTURE 0x40000 /**< __GLcontextRec::Texture */
+#define _NEW_TRANSFORM 0x80000 /**< __GLcontextRec::Transform */
+#define _NEW_VIEWPORT 0x100000 /**< __GLcontextRec::Viewport */
+#define _NEW_PACKUNPACK 0x200000 /**< __GLcontextRec::Pack, __GLcontextRec::Unpack */
+#define _NEW_ARRAY 0x400000 /**< __GLcontextRec::Array */
+#define _NEW_RENDERMODE 0x800000 /**< __GLcontextRec::RenderMode, __GLcontextRec::Feedback, __GLcontextRec::Select */
+#define _NEW_BUFFERS 0x1000000 /**< __GLcontextRec::Visual, __GLcontextRec::DrawBuffer, */
+#define _NEW_MULTISAMPLE 0x2000000 /**< __GLcontextRec::Multisample */
+#define _NEW_TRACK_MATRIX 0x4000000 /**< __GLcontextRec::VertexProgram */
+#define _NEW_PROGRAM 0x8000000 /**< __GLcontextRec::VertexProgram */
+#define _NEW_ALL ~0
+/*@}*/
+
+
+/**
+ * \name Bits to track array state changes
+ *
+ * Also used to summarize array enabled.
+ */
+/*@{*/
+#define _NEW_ARRAY_VERTEX VERT_BIT_POS
+#define _NEW_ARRAY_WEIGHT VERT_BIT_WEIGHT
+#define _NEW_ARRAY_NORMAL VERT_BIT_NORMAL
+#define _NEW_ARRAY_COLOR0 VERT_BIT_COLOR0
+#define _NEW_ARRAY_COLOR1 VERT_BIT_COLOR1
+#define _NEW_ARRAY_FOGCOORD VERT_BIT_FOG
+#define _NEW_ARRAY_INDEX VERT_BIT_SIX
+#define _NEW_ARRAY_EDGEFLAG VERT_BIT_SEVEN
+#define _NEW_ARRAY_TEXCOORD_0 VERT_BIT_TEX0
+#define _NEW_ARRAY_TEXCOORD_1 VERT_BIT_TEX1
+#define _NEW_ARRAY_TEXCOORD_2 VERT_BIT_TEX2
+#define _NEW_ARRAY_TEXCOORD_3 VERT_BIT_TEX3
+#define _NEW_ARRAY_TEXCOORD_4 VERT_BIT_TEX4
+#define _NEW_ARRAY_TEXCOORD_5 VERT_BIT_TEX5
+#define _NEW_ARRAY_TEXCOORD_6 VERT_BIT_TEX6
+#define _NEW_ARRAY_TEXCOORD_7 VERT_BIT_TEX7
+#define _NEW_ARRAY_ATTRIB_0 0x10000 /* start at bit 16 */
+#define _NEW_ARRAY_ALL 0xffffffff
+
+
+#define _NEW_ARRAY_TEXCOORD(i) (_NEW_ARRAY_TEXCOORD_0 << (i))
+#define _NEW_ARRAY_ATTRIB(i) (_NEW_ARRAY_ATTRIB_0 << (i))
+/*@}*/
+
+
+/**
+ * \name A bunch of flags that we think might be useful to drivers.
+ *
+ * Set in the __GLcontextRec::_TriangleCaps bitfield.
+ */
+/*@{*/
+#define DD_FLATSHADE 0x1
+#define DD_SEPARATE_SPECULAR 0x2
+#define DD_TRI_CULL_FRONT_BACK 0x4 /* special case on some hw */
+#define DD_TRI_LIGHT_TWOSIDE 0x8
+#define DD_TRI_UNFILLED 0x10
+#define DD_TRI_SMOOTH 0x20
+#define DD_TRI_STIPPLE 0x40
+#define DD_TRI_OFFSET 0x80
+#define DD_LINE_SMOOTH 0x100
+#define DD_LINE_STIPPLE 0x200
+#define DD_LINE_WIDTH 0x400
+#define DD_POINT_SMOOTH 0x800
+#define DD_POINT_SIZE 0x1000
+#define DD_POINT_ATTEN 0x2000
+#define DD_TRI_TWOSTENCIL 0x4000
+/*@}*/
+
+
+/**
+ * \name Define the state changes under which each of these bits might change
+ */
+/*@{*/
+#define _DD_NEW_FLATSHADE _NEW_LIGHT
+#define _DD_NEW_SEPARATE_SPECULAR (_NEW_LIGHT | _NEW_FOG | _NEW_PROGRAM)
+#define _DD_NEW_TRI_CULL_FRONT_BACK _NEW_POLYGON
+#define _DD_NEW_TRI_LIGHT_TWOSIDE _NEW_LIGHT
+#define _DD_NEW_TRI_UNFILLED _NEW_POLYGON
+#define _DD_NEW_TRI_SMOOTH _NEW_POLYGON
+#define _DD_NEW_TRI_STIPPLE _NEW_POLYGON
+#define _DD_NEW_TRI_OFFSET _NEW_POLYGON
+#define _DD_NEW_LINE_SMOOTH _NEW_LINE
+#define _DD_NEW_LINE_STIPPLE _NEW_LINE
+#define _DD_NEW_LINE_WIDTH _NEW_LINE
+#define _DD_NEW_POINT_SMOOTH _NEW_POINT
+#define _DD_NEW_POINT_SIZE _NEW_POINT
+#define _DD_NEW_POINT_ATTEN _NEW_POINT
+/*@}*/
+
+
+#define _MESA_NEW_NEED_EYE_COORDS (_NEW_LIGHT | \
+ _NEW_TEXTURE | \
+ _NEW_POINT | \
+ _NEW_MODELVIEW)
+
+#define _MESA_NEW_NEED_NORMALS (_NEW_LIGHT | \
+ _NEW_TEXTURE)
+
+#define _IMAGE_NEW_TRANSFER_STATE (_NEW_PIXEL | _NEW_COLOR_MATRIX)
+
+
+
+
+/*
+ * Forward declaration of display list data types:
+ */
+union node;
+typedef union node Node;
+
+
+/* This has to be included here. */
+#include "dd.h"
+
+
+#define NUM_VERTEX_FORMAT_ENTRIES (sizeof(GLvertexformat) / sizeof(void *))
+
+/**
+ * Core Mesa's support for tnl modules:
+ */
+struct gl_tnl_module
+{
+ /**
+ * Vertex format to be lazily swapped into current dispatch.
+ */
+ const GLvertexformat *Current;
+
+ /**
+ * \name Record of functions swapped out.
+ * On restore, only need to swap these functions back in.
+ */
+ /*@{*/
+ struct {
+ _glapi_proc * location;
+ _glapi_proc function;
+ } Swapped[NUM_VERTEX_FORMAT_ENTRIES];
+ GLuint SwapCount;
+ /*@}*/
+};
+
+/* Strictly this is a tnl/ private concept, but it doesn't seem
+ * worthwhile adding a tnl private structure just to hold this one bit
+ * of information:
+ */
+#define MESA_DLIST_DANGLING_REFS 0x1
+
+/* Provide a location where information about a display list can be
+ * collected. Could be extended with driverPrivate structures,
+ * etc. in the future.
+ */
+struct mesa_display_list
+{
+ Node *node;
+ GLuint id;
+ GLbitfield flags;
+};
+
+
+/**
+ * State used during display list compilation and execution.
+ */
+struct mesa_list_state
+{
+ struct mesa_display_list *CallStack[MAX_LIST_NESTING];
+ GLuint CallDepth; /**< Current recursion calling depth */
+
+ struct mesa_display_list *CurrentList;
+ Node *CurrentListPtr; /**< Head of list being compiled */
+ GLuint CurrentListNum; /**< Number of the list being compiled */
+ Node *CurrentBlock; /**< Pointer to current block of nodes */
+ GLuint CurrentPos; /**< Index into current block of nodes */
+
+ GLvertexformat ListVtxfmt;
+
+ GLubyte ActiveAttribSize[VERT_ATTRIB_MAX];
+ GLfloat CurrentAttrib[VERT_ATTRIB_MAX][4];
+
+ GLubyte ActiveMaterialSize[MAT_ATTRIB_MAX];
+ GLfloat CurrentMaterial[MAT_ATTRIB_MAX][4];
+
+ GLubyte ActiveIndex;
+ GLfloat CurrentIndex;
+
+ GLubyte ActiveEdgeFlag;
+ GLboolean CurrentEdgeFlag;
+};
+
+
+/**
+ * Mesa rendering context.
+ *
+ * This is the central context data structure for Mesa. Almost all
+ * OpenGL state is contained in this structure.
+ * Think of this as a base class from which device drivers will derive
+ * sub classes.
+ *
+ * The GLcontext typedef names this structure.
+ */
+struct __GLcontextRec
+{
+ /**
+ * \name OS related interfaces.
+ *
+ * These \b must be the first members of this structure, because they are
+ * exposed to the outside world (i.e. GLX extension).
+ */
+ /*@{*/
+ __GLimports imports;
+ __GLexports exports;
+ /*@}*/
+
+ /** State possibly shared with other contexts in the address space */
+ struct gl_shared_state *Shared;
+
+ /** \name API function pointer tables */
+ /*@{*/
+ struct _glapi_table *Save; /**< Display list save functions */
+ struct _glapi_table *Exec; /**< Execute functions */
+ struct _glapi_table *CurrentDispatch; /**< == Save or Exec !! */
+ /*@}*/
+
+ GLvisual Visual;
+ GLframebuffer *DrawBuffer; /**< buffer for writing */
+ GLframebuffer *ReadBuffer; /**< buffer for reading */
+ GLframebuffer *WinSysDrawBuffer; /**< set with MakeCurrent */
+ GLframebuffer *WinSysReadBuffer; /**< set with MakeCurrent */
+
+ /**
+ * Device driver function pointer table
+ */
+ struct dd_function_table Driver;
+
+ void *DriverCtx; /**< Points to device driver context/state */
+ void *DriverMgrCtx; /**< Points to device driver manager (optional)*/
+
+ /** Core/Driver constants */
+ struct gl_constants Const;
+
+ /** \name The various 4x4 matrix stacks */
+ /*@{*/
+ struct matrix_stack ModelviewMatrixStack;
+ struct matrix_stack ProjectionMatrixStack;
+ struct matrix_stack ColorMatrixStack;
+ struct matrix_stack TextureMatrixStack[MAX_TEXTURE_COORD_UNITS];
+ struct matrix_stack ProgramMatrixStack[MAX_PROGRAM_MATRICES];
+ struct matrix_stack *CurrentStack; /**< Points to one of the above stacks */
+ /*@}*/
+
+ /** Combined modelview and projection matrix */
+ GLmatrix _ModelProjectMatrix;
+
+ /** \name Display lists */
+ struct mesa_list_state ListState;
+
+ GLboolean ExecuteFlag; /**< Execute GL commands? */
+ GLboolean CompileFlag; /**< Compile GL commands into display list? */
+
+ /** Extension information */
+ struct gl_extensions Extensions;
+
+ /** \name State attribute stack (for glPush/PopAttrib) */
+ /*@{*/
+ GLuint AttribStackDepth;
+ struct gl_attrib_node *AttribStack[MAX_ATTRIB_STACK_DEPTH];
+ /*@}*/
+
+ /** \name Renderer attribute groups
+ *
+ * We define a struct for each attribute group to make pushing and popping
+ * attributes easy. Also it's a good organization.
+ */
+ /*@{*/
+ struct gl_accum_attrib Accum; /**< Accum buffer attributes */
+ struct gl_colorbuffer_attrib Color; /**< Color buffer attributes */
+ struct gl_current_attrib Current; /**< Current attributes */
+ struct gl_depthbuffer_attrib Depth; /**< Depth buffer attributes */
+ struct gl_eval_attrib Eval; /**< Eval attributes */
+ struct gl_fog_attrib Fog; /**< Fog attributes */
+ struct gl_hint_attrib Hint; /**< Hint attributes */
+ struct gl_light_attrib Light; /**< Light attributes */
+ struct gl_line_attrib Line; /**< Line attributes */
+ struct gl_list_attrib List; /**< List attributes */
+ struct gl_multisample_attrib Multisample;
+ struct gl_pixel_attrib Pixel; /**< Pixel attributes */
+ struct gl_point_attrib Point; /**< Point attributes */
+ struct gl_polygon_attrib Polygon; /**< Polygon attributes */
+ GLuint PolygonStipple[32]; /**< Polygon stipple */
+ struct gl_scissor_attrib Scissor; /**< Scissor attributes */
+ struct gl_stencil_attrib Stencil; /**< Stencil buffer attributes */
+ struct gl_texture_attrib Texture; /**< Texture attributes */
+ struct gl_transform_attrib Transform; /**< Transformation attributes */
+ struct gl_viewport_attrib Viewport; /**< Viewport attributes */
+ /*@}*/
+
+ /** \name Client attribute stack */
+ /*@{*/
+ GLuint ClientAttribStackDepth;
+ struct gl_attrib_node *ClientAttribStack[MAX_CLIENT_ATTRIB_STACK_DEPTH];
+ /*@}*/
+
+ /** \name Client attribute groups */
+ /*@{*/
+ struct gl_array_attrib Array; /**< Vertex arrays */
+ struct gl_pixelstore_attrib Pack; /**< Pixel packing */
+ struct gl_pixelstore_attrib Unpack; /**< Pixel unpacking */
+ struct gl_pixelstore_attrib DefaultPacking; /**< Default params */
+ /*@}*/
+
+ /** \name Other assorted state (not pushed/popped on attribute stack) */
+ /*@{*/
+ struct gl_histogram_attrib Histogram;
+ struct gl_minmax_attrib MinMax;
+ struct gl_convolution_attrib Convolution1D;
+ struct gl_convolution_attrib Convolution2D;
+ struct gl_convolution_attrib Separable2D;
+
+ struct gl_evaluators EvalMap; /**< All evaluators */
+ struct gl_feedback Feedback; /**< Feedback */
+ struct gl_selection Select; /**< Selection */
+
+ struct gl_color_table ColorTable; /**< Pre-convolution */
+ struct gl_color_table ProxyColorTable; /**< Pre-convolution */
+ struct gl_color_table PostConvolutionColorTable;
+ struct gl_color_table ProxyPostConvolutionColorTable;
+ struct gl_color_table PostColorMatrixColorTable;
+ struct gl_color_table ProxyPostColorMatrixColorTable;
+
+ struct gl_program_state Program; /**< for vertex or fragment progs */
+ struct gl_vertex_program_state VertexProgram; /**< GL_ARB/NV_vertex_program */
+ struct gl_fragment_program_state FragmentProgram; /**< GL_ARB/NV_vertex_program */
+ struct gl_ati_fragment_shader_state ATIFragmentShader; /**< GL_ATI_fragment_shader */
+
+ struct fragment_program *_TexEnvProgram; /**< Texture state as fragment program */
+ struct vertex_program *_TnlProgram; /**< Fixed func TNL state as vertex program */
+
+ GLboolean _MaintainTnlProgram;
+ GLboolean _MaintainTexEnvProgram;
+ GLboolean _UseTexEnvProgram;
+
+ struct gl_query_state Query; /**< GL_ARB_occlusion_query */
+
+ struct gl_shader_objects_state ShaderObjects; /* GL_ARB_shader_objects */
+ /*@}*/
+
+#if FEATURE_EXT_framebuffer_object
+ struct gl_renderbuffer *CurrentRenderbuffer;
+#endif
+
+ GLenum ErrorValue; /**< Last error code */
+ GLenum RenderMode; /**< either GL_RENDER, GL_SELECT, GL_FEEDBACK */
+ GLbitfield NewState; /**< bitwise-or of _NEW_* flags */
+
+ /** \name Derived state */
+ /*@{*/
+ GLbitfield _TriangleCaps; /**< bitwise-or of DD_* flags */
+ GLbitfield _ImageTransferState;/**< bitwise-or of IMAGE_*_BIT flags */
+ GLfloat _EyeZDir[3];
+ GLfloat _ModelViewInvScale;
+ GLboolean _NeedEyeCoords;
+ GLboolean _ForceEyeCoords;
+ GLenum _CurrentProgram; /* currently executing program */
+
+ struct gl_shine_tab *_ShineTable[2]; /**< Active shine tables */
+ struct gl_shine_tab *_ShineTabList; /**< MRU list of inactive shine tables */
+ /**@}*/
+
+ struct gl_list_extensions ListExt; /**< driver dlist extensions */
+
+
+ GLuint _Facing; /**< This is a hack for 2-sided stencil test.
+ *
+ * We don't have a better way to communicate this value from
+ * swrast_setup to swrast. */
+
+ /** \name For debugging/development only */
+ /*@{*/
+ GLboolean FirstTimeCurrent;
+ /*@}*/
+
+ /** Dither disable via MESA_NO_DITHER env var */
+ GLboolean NoDither;
+
+ /** software compression/decompression supported or not */
+ GLboolean Mesa_DXTn;
+
+ /** Core tnl module support */
+ struct gl_tnl_module TnlModule;
+
+ /**
+ * \name Hooks for module contexts.
+ *
+ * These will eventually live in the driver or elsewhere.
+ */
+ /*@{*/
+ void *swrast_context;
+ void *swsetup_context;
+ void *swtnl_context;
+ void *swtnl_im;
+ void *acache_context;
+ void *aelt_context;
+ /*@}*/
+};
+
+
+/** The string names for GL_POINT, GL_LINE_LOOP, etc */
+extern const char *_mesa_prim_name[GL_POLYGON+4];
+
+
+#ifdef DEBUG
+extern int MESA_VERBOSE;
+extern int MESA_DEBUG_FLAGS;
+# define MESA_FUNCTION __FUNCTION__
+#else
+# define MESA_VERBOSE 0
+# define MESA_DEBUG_FLAGS 0
+# define MESA_FUNCTION "a function"
+# ifndef NDEBUG
+# define NDEBUG
+# endif
+#endif
+
+
+enum _verbose
+{
+ VERBOSE_VARRAY = 0x0001,
+ VERBOSE_TEXTURE = 0x0002,
+ VERBOSE_IMMEDIATE = 0x0004,
+ VERBOSE_PIPELINE = 0x0008,
+ VERBOSE_DRIVER = 0x0010,
+ VERBOSE_STATE = 0x0020,
+ VERBOSE_API = 0x0040,
+ VERBOSE_DISPLAY_LIST = 0x0100,
+ VERBOSE_LIGHTING = 0x0200,
+ VERBOSE_PRIMS = 0x0400,
+ VERBOSE_VERTS = 0x0800,
+ VERBOSE_DISASSEM = 0x1000
+};
+
+
+enum _debug
+{
+ DEBUG_ALWAYS_FLUSH = 0x1
+};
+
+
+
+#define Elements(x) sizeof(x)/sizeof(*(x))
+
+
+#endif /* TYPES_H */
diff --git a/src/mesa/main/occlude.c b/src/mesa/main/occlude.c
new file mode 100644
index 00000000000..483ca5d0c41
--- /dev/null
+++ b/src/mesa/main/occlude.c
@@ -0,0 +1,524 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include "glheader.h"
+#include "context.h"
+#include "hash.h"
+#include "imports.h"
+#include "occlude.h"
+#include "mtypes.h"
+
+
+/**
+ * Allocate a new query object. This is a fallback routine called via
+ * ctx->Driver.NewQueryObject().
+ * \param ctx - rendering context
+ * \param id - the new object's ID
+ * \return pointer to new query_object object or NULL if out of memory.
+ */
+struct gl_query_object *
+_mesa_new_query_object(GLcontext *ctx, GLuint id)
+{
+ struct gl_query_object *q = MALLOC_STRUCT(gl_query_object);
+ if (q) {
+ q->Id = id;
+ q->Result = 0;
+ q->Active = GL_FALSE;
+ q->Ready = GL_TRUE; /* correct, see spec */
+ }
+ return q;
+}
+
+
+/**
+ * Delete an occlusion query object.
+ * Not removed from hash table here.
+ * XXX maybe add Delete() method to gl_query_object class and call that instead
+ */
+static void
+delete_query_object(struct gl_query_object *q)
+{
+ FREE(q);
+}
+
+
+static struct gl_query_object *
+lookup_query_object(GLcontext *ctx, GLuint id)
+{
+ return (struct gl_query_object *)
+ _mesa_HashLookup(ctx->Query.QueryObjects, id);
+}
+
+
+
+void GLAPIENTRY
+_mesa_GenQueriesARB(GLsizei n, GLuint *ids)
+{
+ GLuint first;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (n < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glGenQueriesARB(n < 0)");
+ return;
+ }
+
+ /* No query objects can be active at this time! */
+ if (ctx->Query.CurrentOcclusionObject ||
+ ctx->Query.CurrentTimerObject) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGenQueriesARB");
+ return;
+ }
+
+ first = _mesa_HashFindFreeKeyBlock(ctx->Query.QueryObjects, n);
+ if (first) {
+ GLsizei i;
+ for (i = 0; i < n; i++) {
+ struct gl_query_object *q
+ = ctx->Driver.NewQueryObject(ctx, first + i);
+ if (!q) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenQueriesARB");
+ return;
+ }
+ ids[i] = first + i;
+ _mesa_HashInsert(ctx->Query.QueryObjects, first + i, q);
+ }
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_DeleteQueriesARB(GLsizei n, const GLuint *ids)
+{
+ GLint i;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (n < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteQueriesARB(n < 0)");
+ return;
+ }
+
+ /* No query objects can be active at this time! */
+ if (ctx->Query.CurrentOcclusionObject ||
+ ctx->Query.CurrentTimerObject) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glDeleteQueriesARB");
+ return;
+ }
+
+ for (i = 0; i < n; i++) {
+ if (ids[i] > 0) {
+ struct gl_query_object *q = lookup_query_object(ctx, ids[i]);
+ if (q) {
+ ASSERT(!q->Active); /* should be caught earlier */
+ _mesa_HashRemove(ctx->Query.QueryObjects, ids[i]);
+ delete_query_object(q);
+ }
+ }
+ }
+}
+
+
+GLboolean GLAPIENTRY
+_mesa_IsQueryARB(GLuint id)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
+
+ if (id && lookup_query_object(ctx, id))
+ return GL_TRUE;
+ else
+ return GL_FALSE;
+}
+
+
+void GLAPIENTRY
+_mesa_BeginQueryARB(GLenum target, GLuint id)
+{
+ struct gl_query_object *q;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ FLUSH_VERTICES(ctx, _NEW_DEPTH);
+
+ switch (target) {
+ case GL_SAMPLES_PASSED_ARB:
+ if (!ctx->Extensions.ARB_occlusion_query) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glBeginQueryARB(target)");
+ return;
+ }
+ if (ctx->Query.CurrentOcclusionObject) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginQueryARB");
+ return;
+ }
+ break;
+ case GL_TIME_ELAPSED_EXT:
+ if (!ctx->Extensions.EXT_timer_query) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glBeginQueryARB(target)");
+ return;
+ }
+ if (ctx->Query.CurrentTimerObject) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginQueryARB");
+ return;
+ }
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glBeginQueryARB(target)");
+ return;
+ }
+
+ if (id == 0) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginQueryARB(id==0)");
+ return;
+ }
+
+ q = lookup_query_object(ctx, id);
+ if (!q) {
+ /* create new object */
+ q = ctx->Driver.NewQueryObject(ctx, id);
+ if (!q) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBeginQueryARB");
+ return;
+ }
+ _mesa_HashInsert(ctx->Query.QueryObjects, id, q);
+ }
+ else {
+ /* pre-existing object */
+ if (q->Active) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glBeginQueryARB(query already active)");
+ return;
+ }
+ }
+
+ q->Active = GL_TRUE;
+ q->Result = 0;
+ q->Ready = GL_FALSE;
+
+ if (target == GL_SAMPLES_PASSED_ARB) {
+ ctx->Query.CurrentOcclusionObject = q;
+ }
+ else if (target == GL_TIME_ELAPSED_EXT) {
+ ctx->Query.CurrentTimerObject = q;
+ }
+
+ if (ctx->Driver.BeginQuery) {
+ ctx->Driver.BeginQuery(ctx, target, q);
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_EndQueryARB(GLenum target)
+{
+ struct gl_query_object *q;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ FLUSH_VERTICES(ctx, _NEW_DEPTH);
+
+ switch (target) {
+ case GL_SAMPLES_PASSED_ARB:
+ if (!ctx->Extensions.ARB_occlusion_query) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glEndQueryARB(target)");
+ return;
+ }
+ q = ctx->Query.CurrentOcclusionObject;
+ ctx->Query.CurrentOcclusionObject = NULL;
+ break;
+ case GL_TIME_ELAPSED_EXT:
+ if (!ctx->Extensions.EXT_timer_query) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glEndQueryARB(target)");
+ return;
+ }
+ q = ctx->Query.CurrentTimerObject;
+ ctx->Query.CurrentTimerObject = NULL;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glEndQueryARB(target)");
+ return;
+ }
+
+ if (!q || !q->Active) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glEndQueryARB(no matching glBeginQueryARB)");
+ return;
+ }
+
+ q->Active = GL_FALSE;
+ if (ctx->Driver.EndQuery) {
+ ctx->Driver.EndQuery(ctx, target, q);
+ }
+ else {
+ /* if we're using software rendering/querying */
+ q->Ready = GL_TRUE;
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_GetQueryivARB(GLenum target, GLenum pname, GLint *params)
+{
+ struct gl_query_object *q;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ switch (target) {
+ case GL_SAMPLES_PASSED_ARB:
+ if (!ctx->Extensions.ARB_occlusion_query) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glEndQueryARB(target)");
+ return;
+ }
+ q = ctx->Query.CurrentOcclusionObject;
+ break;
+ case GL_TIME_ELAPSED_EXT:
+ if (!ctx->Extensions.EXT_timer_query) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glEndQueryARB(target)");
+ return;
+ }
+ q = ctx->Query.CurrentTimerObject;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryivARB(target)");
+ return;
+ }
+
+ switch (pname) {
+ case GL_QUERY_COUNTER_BITS_ARB:
+ *params = 8 * sizeof(q->Result);
+ break;
+ case GL_CURRENT_QUERY_ARB:
+ *params = q ? q->Id : 0;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryivARB(pname)");
+ return;
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_GetQueryObjectivARB(GLuint id, GLenum pname, GLint *params)
+{
+ struct gl_query_object *q = NULL;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (id)
+ q = lookup_query_object(ctx, id);
+
+ if (!q || q->Active) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetQueryObjectivARB(id=%d is invalid or active)", id);
+ return;
+ }
+
+ switch (pname) {
+ case GL_QUERY_RESULT_ARB:
+ while (!q->Ready) {
+ /* Wait for the query to finish! */
+ /* If using software rendering, the result will always be ready
+ * by time we get here. Otherwise, we must be using hardware!
+ */
+ ASSERT(ctx->Driver.EndQuery);
+ }
+ /* if result is too large for returned type, clamp to max value */
+ if (q->Result > 0x7fffffff) {
+ *params = 0x7fffffff;
+ }
+ else {
+ *params = q->Result;
+ }
+ break;
+ case GL_QUERY_RESULT_AVAILABLE_ARB:
+ /* XXX revisit when we have a hardware implementation! */
+ *params = q->Ready;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjectivARB(pname)");
+ return;
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_GetQueryObjectuivARB(GLuint id, GLenum pname, GLuint *params)
+{
+ struct gl_query_object *q = NULL;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (id)
+ q = lookup_query_object(ctx, id);
+
+ if (!q || q->Active) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetQueryObjectuivARB(id=%d is invalid or active)", id);
+ return;
+ }
+
+ switch (pname) {
+ case GL_QUERY_RESULT_ARB:
+ while (!q->Ready) {
+ /* Wait for the query to finish! */
+ /* If using software rendering, the result will always be ready
+ * by time we get here. Otherwise, we must be using hardware!
+ */
+ ASSERT(ctx->Driver.EndQuery);
+ }
+ /* if result is too large for returned type, clamp to max value */
+ if (q->Result > 0xffffffff) {
+ *params = 0xffffffff;
+ }
+ else {
+ *params = q->Result;
+ }
+ break;
+ case GL_QUERY_RESULT_AVAILABLE_ARB:
+ /* XXX revisit when we have a hardware implementation! */
+ *params = q->Ready;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjectuivARB(pname)");
+ return;
+ }
+}
+
+
+/**
+ * New with GL_EXT_timer_query
+ */
+void GLAPIENTRY
+_mesa_GetQueryObjecti64vEXT(GLuint id, GLenum pname, GLint64EXT *params)
+{
+ struct gl_query_object *q = NULL;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (id)
+ q = lookup_query_object(ctx, id);
+
+ if (!q || q->Active) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetQueryObjectui64vARB(id=%d is invalid or active)", id);
+ return;
+ }
+
+ switch (pname) {
+ case GL_QUERY_RESULT_ARB:
+ while (!q->Ready) {
+ /* Wait for the query to finish! */
+ /* If using software rendering, the result will always be ready
+ * by time we get here. Otherwise, we must be using hardware!
+ */
+ ASSERT(ctx->Driver.EndQuery);
+ }
+ *params = q->Result;
+ break;
+ case GL_QUERY_RESULT_AVAILABLE_ARB:
+ /* XXX revisit when we have a hardware implementation! */
+ *params = q->Ready;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjecti64vARB(pname)");
+ return;
+ }
+}
+
+
+/**
+ * New with GL_EXT_timer_query
+ */
+void GLAPIENTRY
+_mesa_GetQueryObjectui64vEXT(GLuint id, GLenum pname, GLuint64EXT *params)
+{
+ struct gl_query_object *q = NULL;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (id)
+ q = lookup_query_object(ctx, id);
+
+ if (!q || q->Active) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetQueryObjectuui64vARB(id=%d is invalid or active)", id);
+ return;
+ }
+
+ switch (pname) {
+ case GL_QUERY_RESULT_ARB:
+ while (!q->Ready) {
+ /* Wait for the query to finish! */
+ /* If using software rendering, the result will always be ready
+ * by time we get here. Otherwise, we must be using hardware!
+ */
+ ASSERT(ctx->Driver.EndQuery);
+ }
+ *params = q->Result;
+ break;
+ case GL_QUERY_RESULT_AVAILABLE_ARB:
+ /* XXX revisit when we have a hardware implementation! */
+ *params = q->Ready;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjectui64vARB(pname)");
+ return;
+ }
+}
+
+
+/**
+ * Allocate/init the context state related to query objects.
+ */
+void
+_mesa_init_query(GLcontext *ctx)
+{
+#if FEATURE_ARB_occlusion_query
+ ctx->Query.QueryObjects = _mesa_NewHashTable();
+ ctx->Query.CurrentOcclusionObject = NULL;
+#endif
+}
+
+
+/**
+ * Free the context state related to query objects.
+ */
+void
+_mesa_free_query_data(GLcontext *ctx)
+{
+ while (1) {
+ GLuint id = _mesa_HashFirstEntry(ctx->Query.QueryObjects);
+ if (id) {
+ struct gl_query_object *q = lookup_query_object(ctx, id);
+ ASSERT(q);
+ delete_query_object(q);
+ _mesa_HashRemove(ctx->Query.QueryObjects, id);
+ }
+ else {
+ break;
+ }
+ }
+ _mesa_DeleteHashTable(ctx->Query.QueryObjects);
+}
diff --git a/src/mesa/main/occlude.h b/src/mesa/main/occlude.h
new file mode 100644
index 00000000000..ada8cf83560
--- /dev/null
+++ b/src/mesa/main/occlude.h
@@ -0,0 +1,70 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef OCCLUDE_H
+#define OCCLUDE_H
+
+
+extern struct gl_query_object *
+_mesa_new_query_object(GLcontext *ctx, GLuint id);
+
+extern void
+_mesa_init_query(GLcontext *ctx);
+
+extern void
+_mesa_free_query_data(GLcontext *ctx);
+
+extern void GLAPIENTRY
+_mesa_GenQueriesARB(GLsizei n, GLuint *ids);
+
+extern void GLAPIENTRY
+_mesa_DeleteQueriesARB(GLsizei n, const GLuint *ids);
+
+extern GLboolean GLAPIENTRY
+_mesa_IsQueryARB(GLuint id);
+
+extern void GLAPIENTRY
+_mesa_BeginQueryARB(GLenum target, GLuint id);
+
+extern void GLAPIENTRY
+_mesa_EndQueryARB(GLenum target);
+
+extern void GLAPIENTRY
+_mesa_GetQueryivARB(GLenum target, GLenum pname, GLint *params);
+
+extern void GLAPIENTRY
+_mesa_GetQueryObjectivARB(GLuint id, GLenum pname, GLint *params);
+
+extern void GLAPIENTRY
+_mesa_GetQueryObjectuivARB(GLuint id, GLenum pname, GLuint *params);
+
+extern void GLAPIENTRY
+_mesa_GetQueryObjecti64vEXT(GLuint id, GLenum pname, GLint64EXT *params);
+
+extern void GLAPIENTRY
+_mesa_GetQueryObjectui64vEXT(GLuint id, GLenum pname, GLuint64EXT *params);
+
+
+#endif /* OCCLUDE_H */
diff --git a/src/mesa/main/pixel.c b/src/mesa/main/pixel.c
new file mode 100644
index 00000000000..3b1f848e8c3
--- /dev/null
+++ b/src/mesa/main/pixel.c
@@ -0,0 +1,2129 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "glheader.h"
+#include "bufferobj.h"
+#include "colormac.h"
+#include "context.h"
+#include "image.h"
+#include "macros.h"
+#include "pixel.h"
+#include "mtypes.h"
+
+
+/**********************************************************************/
+/***** glPixelZoom *****/
+/**********************************************************************/
+
+
+
+void GLAPIENTRY
+_mesa_PixelZoom( GLfloat xfactor, GLfloat yfactor )
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (ctx->Pixel.ZoomX == xfactor &&
+ ctx->Pixel.ZoomY == yfactor)
+ return;
+
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->Pixel.ZoomX = xfactor;
+ ctx->Pixel.ZoomY = yfactor;
+}
+
+
+
+/**********************************************************************/
+/***** glPixelStore *****/
+/**********************************************************************/
+
+
+void GLAPIENTRY
+_mesa_PixelStorei( GLenum pname, GLint param )
+{
+ /* NOTE: this call can't be compiled into the display list */
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ switch (pname) {
+ case GL_PACK_SWAP_BYTES:
+ if (param == (GLint)ctx->Pack.SwapBytes)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
+ ctx->Pack.SwapBytes = param ? GL_TRUE : GL_FALSE;
+ break;
+ case GL_PACK_LSB_FIRST:
+ if (param == (GLint)ctx->Pack.LsbFirst)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
+ ctx->Pack.LsbFirst = param ? GL_TRUE : GL_FALSE;
+ break;
+ case GL_PACK_ROW_LENGTH:
+ if (param<0) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
+ return;
+ }
+ if (ctx->Pack.RowLength == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
+ ctx->Pack.RowLength = param;
+ break;
+ case GL_PACK_IMAGE_HEIGHT:
+ if (param<0) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
+ return;
+ }
+ if (ctx->Pack.ImageHeight == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
+ ctx->Pack.ImageHeight = param;
+ break;
+ case GL_PACK_SKIP_PIXELS:
+ if (param<0) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
+ return;
+ }
+ if (ctx->Pack.SkipPixels == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
+ ctx->Pack.SkipPixels = param;
+ break;
+ case GL_PACK_SKIP_ROWS:
+ if (param<0) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
+ return;
+ }
+ if (ctx->Pack.SkipRows == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
+ ctx->Pack.SkipRows = param;
+ break;
+ case GL_PACK_SKIP_IMAGES:
+ if (param<0) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
+ return;
+ }
+ if (ctx->Pack.SkipImages == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
+ ctx->Pack.SkipImages = param;
+ break;
+ case GL_PACK_ALIGNMENT:
+ if (param!=1 && param!=2 && param!=4 && param!=8) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
+ return;
+ }
+ if (ctx->Pack.Alignment == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
+ ctx->Pack.Alignment = param;
+ break;
+ case GL_PACK_INVERT_MESA:
+ if (!ctx->Extensions.MESA_pack_invert) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glPixelstore(pname)" );
+ return;
+ }
+ if (ctx->Pack.Invert == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
+ ctx->Pack.Invert = param;
+ break;
+
+ case GL_UNPACK_SWAP_BYTES:
+ if (param == (GLint)ctx->Unpack.SwapBytes)
+ return;
+ if ((GLint)ctx->Unpack.SwapBytes == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
+ ctx->Unpack.SwapBytes = param ? GL_TRUE : GL_FALSE;
+ break;
+ case GL_UNPACK_LSB_FIRST:
+ if (param == (GLint)ctx->Unpack.LsbFirst)
+ return;
+ if ((GLint)ctx->Unpack.LsbFirst == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
+ ctx->Unpack.LsbFirst = param ? GL_TRUE : GL_FALSE;
+ break;
+ case GL_UNPACK_ROW_LENGTH:
+ if (param<0) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
+ return;
+ }
+ if (ctx->Unpack.RowLength == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
+ ctx->Unpack.RowLength = param;
+ break;
+ case GL_UNPACK_IMAGE_HEIGHT:
+ if (param<0) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
+ return;
+ }
+ if (ctx->Unpack.ImageHeight == param)
+ return;
+
+ FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
+ ctx->Unpack.ImageHeight = param;
+ break;
+ case GL_UNPACK_SKIP_PIXELS:
+ if (param<0) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
+ return;
+ }
+ if (ctx->Unpack.SkipPixels == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
+ ctx->Unpack.SkipPixels = param;
+ break;
+ case GL_UNPACK_SKIP_ROWS:
+ if (param<0) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
+ return;
+ }
+ if (ctx->Unpack.SkipRows == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
+ ctx->Unpack.SkipRows = param;
+ break;
+ case GL_UNPACK_SKIP_IMAGES:
+ if (param < 0) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
+ return;
+ }
+ if (ctx->Unpack.SkipImages == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
+ ctx->Unpack.SkipImages = param;
+ break;
+ case GL_UNPACK_ALIGNMENT:
+ if (param!=1 && param!=2 && param!=4 && param!=8) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore" );
+ return;
+ }
+ if (ctx->Unpack.Alignment == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
+ ctx->Unpack.Alignment = param;
+ break;
+ case GL_UNPACK_CLIENT_STORAGE_APPLE:
+ if (param == (GLint)ctx->Unpack.ClientStorage)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
+ ctx->Unpack.ClientStorage = param ? GL_TRUE : GL_FALSE;
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glPixelStore" );
+ return;
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_PixelStoref( GLenum pname, GLfloat param )
+{
+ _mesa_PixelStorei( pname, (GLint) param );
+}
+
+
+
+/**********************************************************************/
+/***** glPixelMap *****/
+/**********************************************************************/
+
+
+/**
+ * Helper routine used by the other _mesa_PixelMap() functions.
+ */
+static void
+pixelmap(GLcontext *ctx, GLenum map, GLsizei mapsize, const GLfloat *values)
+{
+ GLint i;
+ switch (map) {
+ case GL_PIXEL_MAP_S_TO_S:
+ ctx->Pixel.MapStoSsize = mapsize;
+ for (i = 0; i < mapsize; i++) {
+ ctx->Pixel.MapStoS[i] = IROUND(values[i]);
+ }
+ break;
+ case GL_PIXEL_MAP_I_TO_I:
+ ctx->Pixel.MapItoIsize = mapsize;
+ for (i = 0; i < mapsize; i++) {
+ ctx->Pixel.MapItoI[i] = values[i];
+ }
+ break;
+ case GL_PIXEL_MAP_I_TO_R:
+ ctx->Pixel.MapItoRsize = mapsize;
+ for (i = 0; i < mapsize; i++) {
+ GLfloat val = CLAMP( values[i], 0.0F, 1.0F );
+ ctx->Pixel.MapItoR[i] = val;
+ ctx->Pixel.MapItoR8[i] = (GLint) (val * 255.0F);
+ }
+ break;
+ case GL_PIXEL_MAP_I_TO_G:
+ ctx->Pixel.MapItoGsize = mapsize;
+ for (i = 0; i < mapsize; i++) {
+ GLfloat val = CLAMP( values[i], 0.0F, 1.0F );
+ ctx->Pixel.MapItoG[i] = val;
+ ctx->Pixel.MapItoG8[i] = (GLint) (val * 255.0F);
+ }
+ break;
+ case GL_PIXEL_MAP_I_TO_B:
+ ctx->Pixel.MapItoBsize = mapsize;
+ for (i = 0; i < mapsize; i++) {
+ GLfloat val = CLAMP( values[i], 0.0F, 1.0F );
+ ctx->Pixel.MapItoB[i] = val;
+ ctx->Pixel.MapItoB8[i] = (GLint) (val * 255.0F);
+ }
+ break;
+ case GL_PIXEL_MAP_I_TO_A:
+ ctx->Pixel.MapItoAsize = mapsize;
+ for (i = 0; i < mapsize; i++) {
+ GLfloat val = CLAMP( values[i], 0.0F, 1.0F );
+ ctx->Pixel.MapItoA[i] = val;
+ ctx->Pixel.MapItoA8[i] = (GLint) (val * 255.0F);
+ }
+ break;
+ case GL_PIXEL_MAP_R_TO_R:
+ ctx->Pixel.MapRtoRsize = mapsize;
+ for (i = 0; i < mapsize; i++) {
+ ctx->Pixel.MapRtoR[i] = CLAMP( values[i], 0.0F, 1.0F );
+ }
+ break;
+ case GL_PIXEL_MAP_G_TO_G:
+ ctx->Pixel.MapGtoGsize = mapsize;
+ for (i = 0; i < mapsize; i++) {
+ ctx->Pixel.MapGtoG[i] = CLAMP( values[i], 0.0F, 1.0F );
+ }
+ break;
+ case GL_PIXEL_MAP_B_TO_B:
+ ctx->Pixel.MapBtoBsize = mapsize;
+ for (i = 0; i < mapsize; i++) {
+ ctx->Pixel.MapBtoB[i] = CLAMP( values[i], 0.0F, 1.0F );
+ }
+ break;
+ case GL_PIXEL_MAP_A_TO_A:
+ ctx->Pixel.MapAtoAsize = mapsize;
+ for (i = 0; i < mapsize; i++) {
+ ctx->Pixel.MapAtoA[i] = CLAMP( values[i], 0.0F, 1.0F );
+ }
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glPixelMap(map)" );
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_PixelMapfv( GLenum map, GLsizei mapsize, const GLfloat *values )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ /* XXX someday, test against ctx->Const.MaxPixelMapTableSize */
+ if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" );
+ return;
+ }
+
+ if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) {
+ /* test that mapsize is a power of two */
+ if (_mesa_bitcount((GLuint) mapsize) != 1) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" );
+ return;
+ }
+ }
+
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+
+ if (ctx->Unpack.BufferObj->Name) {
+ /* unpack pixelmap from PBO */
+ GLubyte *buf;
+ /* Note, need to use DefaultPacking and Unpack's buffer object */
+ ctx->DefaultPacking.BufferObj = ctx->Unpack.BufferObj;
+ if (!_mesa_validate_pbo_access(1, &ctx->DefaultPacking, mapsize, 1, 1,
+ GL_INTENSITY, GL_FLOAT, values)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glPixelMapfv(invalid PBO access)");
+ return;
+ }
+ /* restore */
+ ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj;
+ buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+ GL_READ_ONLY_ARB,
+ ctx->Unpack.BufferObj);
+ if (!buf) {
+ /* buffer is already mapped - that's an error */
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glPixelMapfv(PBO is mapped)");
+ return;
+ }
+ values = (const GLfloat *) ADD_POINTERS(buf, values);
+ }
+ else if (!values) {
+ return;
+ }
+
+ pixelmap(ctx, map, mapsize, values);
+
+ if (ctx->Unpack.BufferObj->Name) {
+ ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+ ctx->Unpack.BufferObj);
+ }
+}
+
+
+
+void GLAPIENTRY
+_mesa_PixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values )
+{
+ GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapuiv(mapsize)" );
+ return;
+ }
+
+ if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) {
+ /* test that mapsize is a power of two */
+ if (_mesa_bitcount((GLuint) mapsize) != 1) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapuiv(mapsize)" );
+ return;
+ }
+ }
+
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+
+ if (ctx->Unpack.BufferObj->Name) {
+ /* unpack pixelmap from PBO */
+ GLubyte *buf;
+ /* Note, need to use DefaultPacking and Unpack's buffer object */
+ ctx->DefaultPacking.BufferObj = ctx->Unpack.BufferObj;
+ if (!_mesa_validate_pbo_access(1, &ctx->DefaultPacking, mapsize, 1, 1,
+ GL_INTENSITY, GL_UNSIGNED_INT, values)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glPixelMapuiv(invalid PBO access)");
+ return;
+ }
+ /* restore */
+ ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj;
+ buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+ GL_READ_ONLY_ARB,
+ ctx->Unpack.BufferObj);
+ if (!buf) {
+ /* buffer is already mapped - that's an error */
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glPixelMapuiv(PBO is mapped)");
+ return;
+ }
+ values = (const GLuint *) ADD_POINTERS(buf, values);
+ }
+ else if (!values) {
+ return;
+ }
+
+ /* convert to floats */
+ if (map == GL_PIXEL_MAP_I_TO_I || map == GL_PIXEL_MAP_S_TO_S) {
+ GLint i;
+ for (i = 0; i < mapsize; i++) {
+ fvalues[i] = (GLfloat) values[i];
+ }
+ }
+ else {
+ GLint i;
+ for (i = 0; i < mapsize; i++) {
+ fvalues[i] = UINT_TO_FLOAT( values[i] );
+ }
+ }
+
+ if (ctx->Unpack.BufferObj->Name) {
+ ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+ ctx->Unpack.BufferObj);
+ }
+
+ pixelmap(ctx, map, mapsize, fvalues);
+}
+
+
+
+void GLAPIENTRY
+_mesa_PixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values )
+{
+ GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapusv(mapsize)" );
+ return;
+ }
+
+ if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) {
+ /* test that mapsize is a power of two */
+ if (_mesa_bitcount((GLuint) mapsize) != 1) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapuiv(mapsize)" );
+ return;
+ }
+ }
+
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+
+ if (ctx->Unpack.BufferObj->Name) {
+ /* unpack pixelmap from PBO */
+ GLubyte *buf;
+ /* Note, need to use DefaultPacking and Unpack's buffer object */
+ ctx->DefaultPacking.BufferObj = ctx->Unpack.BufferObj;
+ if (!_mesa_validate_pbo_access(1, &ctx->DefaultPacking, mapsize, 1, 1,
+ GL_INTENSITY, GL_UNSIGNED_SHORT,
+ values)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glPixelMapusv(invalid PBO access)");
+ return;
+ }
+ /* restore */
+ ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj;
+ buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+ GL_READ_ONLY_ARB,
+ ctx->Unpack.BufferObj);
+ if (!buf) {
+ /* buffer is already mapped - that's an error */
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glPixelMapusv(PBO is mapped)");
+ return;
+ }
+ values = (const GLushort *) ADD_POINTERS(buf, values);
+ }
+ else if (!values) {
+ return;
+ }
+
+ /* convert to floats */
+ if (map == GL_PIXEL_MAP_I_TO_I || map == GL_PIXEL_MAP_S_TO_S) {
+ GLint i;
+ for (i = 0; i < mapsize; i++) {
+ fvalues[i] = (GLfloat) values[i];
+ }
+ }
+ else {
+ GLint i;
+ for (i = 0; i < mapsize; i++) {
+ fvalues[i] = USHORT_TO_FLOAT( values[i] );
+ }
+ }
+
+ if (ctx->Unpack.BufferObj->Name) {
+ ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+ ctx->Unpack.BufferObj);
+ }
+
+ pixelmap(ctx, map, mapsize, fvalues);
+}
+
+
+/**
+ * Return size of the named map.
+ */
+static GLuint
+get_map_size(GLcontext *ctx, GLenum map)
+{
+ switch (map) {
+ case GL_PIXEL_MAP_I_TO_I:
+ return ctx->Pixel.MapItoIsize;
+ case GL_PIXEL_MAP_S_TO_S:
+ return ctx->Pixel.MapStoSsize;
+ case GL_PIXEL_MAP_I_TO_R:
+ return ctx->Pixel.MapItoRsize;
+ case GL_PIXEL_MAP_I_TO_G:
+ return ctx->Pixel.MapItoGsize;
+ case GL_PIXEL_MAP_I_TO_B:
+ return ctx->Pixel.MapItoBsize;
+ case GL_PIXEL_MAP_I_TO_A:
+ return ctx->Pixel.MapItoAsize;
+ case GL_PIXEL_MAP_R_TO_R:
+ return ctx->Pixel.MapRtoRsize;
+ case GL_PIXEL_MAP_G_TO_G:
+ return ctx->Pixel.MapGtoGsize;
+ case GL_PIXEL_MAP_B_TO_B:
+ return ctx->Pixel.MapBtoBsize;
+ case GL_PIXEL_MAP_A_TO_A:
+ return ctx->Pixel.MapAtoAsize;
+ default:
+ return 0;
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_GetPixelMapfv( GLenum map, GLfloat *values )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLuint mapsize, i;
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ mapsize = get_map_size(ctx, map);
+
+ if (ctx->Pack.BufferObj->Name) {
+ /* pack pixelmap into PBO */
+ GLubyte *buf;
+ /* Note, need to use DefaultPacking and Pack's buffer object */
+ ctx->DefaultPacking.BufferObj = ctx->Pack.BufferObj;
+ if (!_mesa_validate_pbo_access(1, &ctx->DefaultPacking, mapsize, 1, 1,
+ GL_INTENSITY, GL_FLOAT, values)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetPixelMapfv(invalid PBO access)");
+ return;
+ }
+ /* restore */
+ ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj;
+ buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
+ GL_WRITE_ONLY_ARB,
+ ctx->Pack.BufferObj);
+ if (!buf) {
+ /* buffer is already mapped - that's an error */
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetPixelMapfv(PBO is mapped)");
+ return;
+ }
+ values = (GLfloat *) ADD_POINTERS(buf, values);
+ }
+ else if (!values) {
+ return;
+ }
+
+ switch (map) {
+ case GL_PIXEL_MAP_I_TO_I:
+ MEMCPY(values, ctx->Pixel.MapItoI, mapsize * sizeof(GLfloat));
+ break;
+ case GL_PIXEL_MAP_S_TO_S:
+ for (i = 0; i < mapsize; i++) {
+ values[i] = (GLfloat) ctx->Pixel.MapStoS[i];
+ }
+ break;
+ case GL_PIXEL_MAP_I_TO_R:
+ MEMCPY(values, ctx->Pixel.MapItoR, mapsize * sizeof(GLfloat));
+ break;
+ case GL_PIXEL_MAP_I_TO_G:
+ MEMCPY(values, ctx->Pixel.MapItoG, mapsize * sizeof(GLfloat));
+ break;
+ case GL_PIXEL_MAP_I_TO_B:
+ MEMCPY(values, ctx->Pixel.MapItoB, mapsize * sizeof(GLfloat));
+ break;
+ case GL_PIXEL_MAP_I_TO_A:
+ MEMCPY(values, ctx->Pixel.MapItoA, mapsize * sizeof(GLfloat));
+ break;
+ case GL_PIXEL_MAP_R_TO_R:
+ MEMCPY(values, ctx->Pixel.MapRtoR, mapsize * sizeof(GLfloat));
+ break;
+ case GL_PIXEL_MAP_G_TO_G:
+ MEMCPY(values, ctx->Pixel.MapGtoG, mapsize * sizeof(GLfloat));
+ break;
+ case GL_PIXEL_MAP_B_TO_B:
+ MEMCPY(values, ctx->Pixel.MapBtoB, mapsize * sizeof(GLfloat));
+ break;
+ case GL_PIXEL_MAP_A_TO_A:
+ MEMCPY(values, ctx->Pixel.MapAtoA, mapsize * sizeof(GLfloat));
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" );
+ }
+
+ if (ctx->Pack.BufferObj->Name) {
+ ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
+ ctx->Pack.BufferObj);
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_GetPixelMapuiv( GLenum map, GLuint *values )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint mapsize, i;
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ mapsize = get_map_size(ctx, map);
+
+ if (ctx->Pack.BufferObj->Name) {
+ /* pack pixelmap into PBO */
+ GLubyte *buf;
+ /* Note, need to use DefaultPacking and Pack's buffer object */
+ ctx->DefaultPacking.BufferObj = ctx->Pack.BufferObj;
+ if (!_mesa_validate_pbo_access(1, &ctx->DefaultPacking, mapsize, 1, 1,
+ GL_INTENSITY, GL_UNSIGNED_INT, values)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetPixelMapuiv(invalid PBO access)");
+ return;
+ }
+ /* restore */
+ ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj;
+ buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
+ GL_WRITE_ONLY_ARB,
+ ctx->Pack.BufferObj);
+ if (!buf) {
+ /* buffer is already mapped - that's an error */
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetPixelMapuiv(PBO is mapped)");
+ return;
+ }
+ values = (GLuint *) ADD_POINTERS(buf, values);
+ }
+ else if (!values) {
+ return;
+ }
+
+ switch (map) {
+ case GL_PIXEL_MAP_I_TO_I:
+ for (i = 0; i < mapsize; i++) {
+ values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoI[i] );
+ }
+ break;
+ case GL_PIXEL_MAP_S_TO_S:
+ MEMCPY(values, ctx->Pixel.MapStoS, mapsize * sizeof(GLint));
+ break;
+ case GL_PIXEL_MAP_I_TO_R:
+ for (i = 0; i < mapsize; i++) {
+ values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoR[i] );
+ }
+ break;
+ case GL_PIXEL_MAP_I_TO_G:
+ for (i = 0; i < mapsize; i++) {
+ values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoG[i] );
+ }
+ break;
+ case GL_PIXEL_MAP_I_TO_B:
+ for (i = 0; i < mapsize; i++) {
+ values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoB[i] );
+ }
+ break;
+ case GL_PIXEL_MAP_I_TO_A:
+ for (i = 0; i < mapsize; i++) {
+ values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoA[i] );
+ }
+ break;
+ case GL_PIXEL_MAP_R_TO_R:
+ for (i = 0; i < mapsize; i++) {
+ values[i] = FLOAT_TO_UINT( ctx->Pixel.MapRtoR[i] );
+ }
+ break;
+ case GL_PIXEL_MAP_G_TO_G:
+ for (i = 0; i < mapsize; i++) {
+ values[i] = FLOAT_TO_UINT( ctx->Pixel.MapGtoG[i] );
+ }
+ break;
+ case GL_PIXEL_MAP_B_TO_B:
+ for (i = 0; i < mapsize; i++) {
+ values[i] = FLOAT_TO_UINT( ctx->Pixel.MapBtoB[i] );
+ }
+ break;
+ case GL_PIXEL_MAP_A_TO_A:
+ for (i = 0; i < mapsize; i++) {
+ values[i] = FLOAT_TO_UINT( ctx->Pixel.MapAtoA[i] );
+ }
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" );
+ }
+
+ if (ctx->Pack.BufferObj->Name) {
+ ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
+ ctx->Pack.BufferObj);
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_GetPixelMapusv( GLenum map, GLushort *values )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint mapsize, i;
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ mapsize = get_map_size(ctx, map);
+
+ if (ctx->Pack.BufferObj->Name) {
+ /* pack pixelmap into PBO */
+ GLubyte *buf;
+ /* Note, need to use DefaultPacking and Pack's buffer object */
+ ctx->DefaultPacking.BufferObj = ctx->Pack.BufferObj;
+ if (!_mesa_validate_pbo_access(1, &ctx->DefaultPacking, mapsize, 1, 1,
+ GL_INTENSITY, GL_UNSIGNED_SHORT,
+ values)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetPixelMapusv(invalid PBO access)");
+ return;
+ }
+ /* restore */
+ ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj;
+ buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
+ GL_WRITE_ONLY_ARB,
+ ctx->Pack.BufferObj);
+ if (!buf) {
+ /* buffer is already mapped - that's an error */
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetPixelMapusv(PBO is mapped)");
+ return;
+ }
+ values = (GLushort *) ADD_POINTERS(buf, values);
+ }
+ else if (!values) {
+ return;
+ }
+
+ switch (map) {
+ case GL_PIXEL_MAP_I_TO_I:
+ for (i = 0; i < mapsize; i++) {
+ values[i] = (GLushort) CLAMP(ctx->Pixel.MapItoI[i], 0.0, 65535.0);
+ }
+ break;
+ case GL_PIXEL_MAP_S_TO_S:
+ for (i = 0; i < mapsize; i++) {
+ values[i] = (GLushort) CLAMP(ctx->Pixel.MapStoS[i], 0.0, 65535.0);
+ }
+ break;
+ case GL_PIXEL_MAP_I_TO_R:
+ for (i = 0; i < mapsize; i++) {
+ CLAMPED_FLOAT_TO_USHORT(values[i] , ctx->Pixel.MapItoR[i] );
+ }
+ break;
+ case GL_PIXEL_MAP_I_TO_G:
+ for (i = 0; i < mapsize; i++) {
+ CLAMPED_FLOAT_TO_USHORT(values[i] , ctx->Pixel.MapItoG[i] );
+ }
+ break;
+ case GL_PIXEL_MAP_I_TO_B:
+ for (i = 0; i < mapsize; i++) {
+ CLAMPED_FLOAT_TO_USHORT(values[i] , ctx->Pixel.MapItoB[i] );
+ }
+ break;
+ case GL_PIXEL_MAP_I_TO_A:
+ for (i = 0; i < mapsize; i++) {
+ CLAMPED_FLOAT_TO_USHORT(values[i] , ctx->Pixel.MapItoA[i] );
+ }
+ break;
+ case GL_PIXEL_MAP_R_TO_R:
+ for (i = 0; i < mapsize; i++) {
+ CLAMPED_FLOAT_TO_USHORT(values[i] , ctx->Pixel.MapRtoR[i] );
+ }
+ break;
+ case GL_PIXEL_MAP_G_TO_G:
+ for (i = 0; i < mapsize; i++) {
+ CLAMPED_FLOAT_TO_USHORT(values[i] , ctx->Pixel.MapGtoG[i] );
+ }
+ break;
+ case GL_PIXEL_MAP_B_TO_B:
+ for (i = 0; i < mapsize; i++) {
+ CLAMPED_FLOAT_TO_USHORT(values[i] , ctx->Pixel.MapBtoB[i] );
+ }
+ break;
+ case GL_PIXEL_MAP_A_TO_A:
+ for (i = 0; i < mapsize; i++) {
+ CLAMPED_FLOAT_TO_USHORT(values[i] , ctx->Pixel.MapAtoA[i] );
+ }
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" );
+ }
+
+ if (ctx->Pack.BufferObj->Name) {
+ ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
+ ctx->Pack.BufferObj);
+ }
+}
+
+
+
+/**********************************************************************/
+/***** glPixelTransfer *****/
+/**********************************************************************/
+
+
+/*
+ * Implements glPixelTransfer[fi] whether called immediately or from a
+ * display list.
+ */
+void GLAPIENTRY
+_mesa_PixelTransferf( GLenum pname, GLfloat param )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ switch (pname) {
+ case GL_MAP_COLOR:
+ if (ctx->Pixel.MapColorFlag == (param ? GL_TRUE : GL_FALSE))
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->Pixel.MapColorFlag = param ? GL_TRUE : GL_FALSE;
+ break;
+ case GL_MAP_STENCIL:
+ if (ctx->Pixel.MapStencilFlag == (param ? GL_TRUE : GL_FALSE))
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->Pixel.MapStencilFlag = param ? GL_TRUE : GL_FALSE;
+ break;
+ case GL_INDEX_SHIFT:
+ if (ctx->Pixel.IndexShift == (GLint) param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->Pixel.IndexShift = (GLint) param;
+ break;
+ case GL_INDEX_OFFSET:
+ if (ctx->Pixel.IndexOffset == (GLint) param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->Pixel.IndexOffset = (GLint) param;
+ break;
+ case GL_RED_SCALE:
+ if (ctx->Pixel.RedScale == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->Pixel.RedScale = param;
+ break;
+ case GL_RED_BIAS:
+ if (ctx->Pixel.RedBias == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->Pixel.RedBias = param;
+ break;
+ case GL_GREEN_SCALE:
+ if (ctx->Pixel.GreenScale == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->Pixel.GreenScale = param;
+ break;
+ case GL_GREEN_BIAS:
+ if (ctx->Pixel.GreenBias == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->Pixel.GreenBias = param;
+ break;
+ case GL_BLUE_SCALE:
+ if (ctx->Pixel.BlueScale == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->Pixel.BlueScale = param;
+ break;
+ case GL_BLUE_BIAS:
+ if (ctx->Pixel.BlueBias == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->Pixel.BlueBias = param;
+ break;
+ case GL_ALPHA_SCALE:
+ if (ctx->Pixel.AlphaScale == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->Pixel.AlphaScale = param;
+ break;
+ case GL_ALPHA_BIAS:
+ if (ctx->Pixel.AlphaBias == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->Pixel.AlphaBias = param;
+ break;
+ case GL_DEPTH_SCALE:
+ if (ctx->Pixel.DepthScale == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->Pixel.DepthScale = param;
+ break;
+ case GL_DEPTH_BIAS:
+ if (ctx->Pixel.DepthBias == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->Pixel.DepthBias = param;
+ break;
+ case GL_POST_COLOR_MATRIX_RED_SCALE:
+ if (ctx->Pixel.PostColorMatrixScale[0] == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->Pixel.PostColorMatrixScale[0] = param;
+ break;
+ case GL_POST_COLOR_MATRIX_RED_BIAS:
+ if (ctx->Pixel.PostColorMatrixBias[0] == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->Pixel.PostColorMatrixBias[0] = param;
+ break;
+ case GL_POST_COLOR_MATRIX_GREEN_SCALE:
+ if (ctx->Pixel.PostColorMatrixScale[1] == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->Pixel.PostColorMatrixScale[1] = param;
+ break;
+ case GL_POST_COLOR_MATRIX_GREEN_BIAS:
+ if (ctx->Pixel.PostColorMatrixBias[1] == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->Pixel.PostColorMatrixBias[1] = param;
+ break;
+ case GL_POST_COLOR_MATRIX_BLUE_SCALE:
+ if (ctx->Pixel.PostColorMatrixScale[2] == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->Pixel.PostColorMatrixScale[2] = param;
+ break;
+ case GL_POST_COLOR_MATRIX_BLUE_BIAS:
+ if (ctx->Pixel.PostColorMatrixBias[2] == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->Pixel.PostColorMatrixBias[2] = param;
+ break;
+ case GL_POST_COLOR_MATRIX_ALPHA_SCALE:
+ if (ctx->Pixel.PostColorMatrixScale[3] == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->Pixel.PostColorMatrixScale[3] = param;
+ break;
+ case GL_POST_COLOR_MATRIX_ALPHA_BIAS:
+ if (ctx->Pixel.PostColorMatrixBias[3] == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->Pixel.PostColorMatrixBias[3] = param;
+ break;
+ case GL_POST_CONVOLUTION_RED_SCALE:
+ if (ctx->Pixel.PostConvolutionScale[0] == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->Pixel.PostConvolutionScale[0] = param;
+ break;
+ case GL_POST_CONVOLUTION_RED_BIAS:
+ if (ctx->Pixel.PostConvolutionBias[0] == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->Pixel.PostConvolutionBias[0] = param;
+ break;
+ case GL_POST_CONVOLUTION_GREEN_SCALE:
+ if (ctx->Pixel.PostConvolutionScale[1] == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->Pixel.PostConvolutionScale[1] = param;
+ break;
+ case GL_POST_CONVOLUTION_GREEN_BIAS:
+ if (ctx->Pixel.PostConvolutionBias[1] == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->Pixel.PostConvolutionBias[1] = param;
+ break;
+ case GL_POST_CONVOLUTION_BLUE_SCALE:
+ if (ctx->Pixel.PostConvolutionScale[2] == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->Pixel.PostConvolutionScale[2] = param;
+ break;
+ case GL_POST_CONVOLUTION_BLUE_BIAS:
+ if (ctx->Pixel.PostConvolutionBias[2] == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->Pixel.PostConvolutionBias[2] = param;
+ break;
+ case GL_POST_CONVOLUTION_ALPHA_SCALE:
+ if (ctx->Pixel.PostConvolutionScale[2] == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->Pixel.PostConvolutionScale[2] = param;
+ break;
+ case GL_POST_CONVOLUTION_ALPHA_BIAS:
+ if (ctx->Pixel.PostConvolutionBias[2] == param)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_PIXEL);
+ ctx->Pixel.PostConvolutionBias[2] = param;
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glPixelTransfer(pname)" );
+ return;
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_PixelTransferi( GLenum pname, GLint param )
+{
+ _mesa_PixelTransferf( pname, (GLfloat) param );
+}
+
+
+
+/**********************************************************************/
+/***** Pixel processing functions ******/
+/**********************************************************************/
+
+/*
+ * Apply scale and bias factors to an array of RGBA pixels.
+ */
+void
+_mesa_scale_and_bias_rgba(GLuint n, GLfloat rgba[][4],
+ GLfloat rScale, GLfloat gScale,
+ GLfloat bScale, GLfloat aScale,
+ GLfloat rBias, GLfloat gBias,
+ GLfloat bBias, GLfloat aBias)
+{
+ if (rScale != 1.0 || rBias != 0.0) {
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ rgba[i][RCOMP] = rgba[i][RCOMP] * rScale + rBias;
+ }
+ }
+ if (gScale != 1.0 || gBias != 0.0) {
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ rgba[i][GCOMP] = rgba[i][GCOMP] * gScale + gBias;
+ }
+ }
+ if (bScale != 1.0 || bBias != 0.0) {
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ rgba[i][BCOMP] = rgba[i][BCOMP] * bScale + bBias;
+ }
+ }
+ if (aScale != 1.0 || aBias != 0.0) {
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ rgba[i][ACOMP] = rgba[i][ACOMP] * aScale + aBias;
+ }
+ }
+}
+
+
+/*
+ * Apply pixel mapping to an array of floating point RGBA pixels.
+ */
+void
+_mesa_map_rgba( const GLcontext *ctx, GLuint n, GLfloat rgba[][4] )
+{
+ const GLfloat rscale = (GLfloat) (ctx->Pixel.MapRtoRsize - 1);
+ const GLfloat gscale = (GLfloat) (ctx->Pixel.MapGtoGsize - 1);
+ const GLfloat bscale = (GLfloat) (ctx->Pixel.MapBtoBsize - 1);
+ const GLfloat ascale = (GLfloat) (ctx->Pixel.MapAtoAsize - 1);
+ const GLfloat *rMap = ctx->Pixel.MapRtoR;
+ const GLfloat *gMap = ctx->Pixel.MapGtoG;
+ const GLfloat *bMap = ctx->Pixel.MapBtoB;
+ const GLfloat *aMap = ctx->Pixel.MapAtoA;
+ GLuint i;
+ for (i=0;i<n;i++) {
+ GLfloat r = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F);
+ GLfloat g = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F);
+ GLfloat b = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F);
+ GLfloat a = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F);
+ rgba[i][RCOMP] = rMap[IROUND(r * rscale)];
+ rgba[i][GCOMP] = gMap[IROUND(g * gscale)];
+ rgba[i][BCOMP] = bMap[IROUND(b * bscale)];
+ rgba[i][ACOMP] = aMap[IROUND(a * ascale)];
+ }
+}
+
+
+/*
+ * Apply the color matrix and post color matrix scaling and biasing.
+ */
+void
+_mesa_transform_rgba(const GLcontext *ctx, GLuint n, GLfloat rgba[][4])
+{
+ const GLfloat rs = ctx->Pixel.PostColorMatrixScale[0];
+ const GLfloat rb = ctx->Pixel.PostColorMatrixBias[0];
+ const GLfloat gs = ctx->Pixel.PostColorMatrixScale[1];
+ const GLfloat gb = ctx->Pixel.PostColorMatrixBias[1];
+ const GLfloat bs = ctx->Pixel.PostColorMatrixScale[2];
+ const GLfloat bb = ctx->Pixel.PostColorMatrixBias[2];
+ const GLfloat as = ctx->Pixel.PostColorMatrixScale[3];
+ const GLfloat ab = ctx->Pixel.PostColorMatrixBias[3];
+ const GLfloat *m = ctx->ColorMatrixStack.Top->m;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ const GLfloat r = rgba[i][RCOMP];
+ const GLfloat g = rgba[i][GCOMP];
+ const GLfloat b = rgba[i][BCOMP];
+ const GLfloat a = rgba[i][ACOMP];
+ rgba[i][RCOMP] = (m[0] * r + m[4] * g + m[ 8] * b + m[12] * a) * rs + rb;
+ rgba[i][GCOMP] = (m[1] * r + m[5] * g + m[ 9] * b + m[13] * a) * gs + gb;
+ rgba[i][BCOMP] = (m[2] * r + m[6] * g + m[10] * b + m[14] * a) * bs + bb;
+ rgba[i][ACOMP] = (m[3] * r + m[7] * g + m[11] * b + m[15] * a) * as + ab;
+ }
+}
+
+
+/**
+ * Apply a color table lookup to an array of floating point RGBA colors.
+ */
+void
+_mesa_lookup_rgba_float(const struct gl_color_table *table,
+ GLuint n, GLfloat rgba[][4])
+{
+ if (!table->Table || table->Size == 0)
+ return;
+
+ switch (table->_BaseFormat) {
+ case GL_INTENSITY:
+ /* replace RGBA with I */
+ if (table->Type == GL_FLOAT) {
+ const GLint max = table->Size - 1;
+ const GLfloat scale = (GLfloat) max;
+ const GLfloat *lut = (const GLfloat *) table->Table;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLint j = IROUND(rgba[i][RCOMP] * scale);
+ GLfloat c = lut[CLAMP(j, 0, max)];
+ rgba[i][RCOMP] = rgba[i][GCOMP] =
+ rgba[i][BCOMP] = rgba[i][ACOMP] = c;
+ }
+ }
+ else {
+ const GLint max = table->Size - 1;
+ const GLfloat scale = (GLfloat) max;
+ const GLchan *lut = (const GLchan *) table->Table;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLint j = IROUND(rgba[i][RCOMP] * scale);
+ GLfloat c = CHAN_TO_FLOAT(lut[CLAMP(j, 0, max)]);
+ rgba[i][RCOMP] = rgba[i][GCOMP] =
+ rgba[i][BCOMP] = rgba[i][ACOMP] = c;
+ }
+ }
+ break;
+ case GL_LUMINANCE:
+ /* replace RGB with L */
+ if (table->Type == GL_FLOAT) {
+ const GLint max = table->Size - 1;
+ const GLfloat scale = (GLfloat) max;
+ const GLfloat *lut = (const GLfloat *) table->Table;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLint j = IROUND(rgba[i][RCOMP] * scale);
+ GLfloat c = lut[CLAMP(j, 0, max)];
+ rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = c;
+ }
+ }
+ else {
+ const GLint max = table->Size - 1;
+ const GLfloat scale = (GLfloat) max;
+ const GLchan *lut = (const GLchan *) table->Table;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLint j = IROUND(rgba[i][RCOMP] * scale);
+ GLfloat c = CHAN_TO_FLOAT(lut[CLAMP(j, 0, max)]);
+ rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = c;
+ }
+ }
+ break;
+ case GL_ALPHA:
+ /* replace A with A */
+ if (table->Type == GL_FLOAT) {
+ const GLint max = table->Size - 1;
+ const GLfloat scale = (GLfloat) max;
+ const GLfloat *lut = (const GLfloat *) table->Table;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLint j = IROUND(rgba[i][ACOMP] * scale);
+ rgba[i][ACOMP] = lut[CLAMP(j, 0, max)];
+ }
+ }
+ else {
+ const GLint max = table->Size - 1;
+ const GLfloat scale = (GLfloat) max;
+ const GLchan *lut = (const GLchan *) table->Table;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLint j = IROUND(rgba[i][ACOMP] * scale);
+ rgba[i][ACOMP] = CHAN_TO_FLOAT(lut[CLAMP(j, 0, max)]);
+ }
+ }
+ break;
+ case GL_LUMINANCE_ALPHA:
+ /* replace RGBA with LLLA */
+ if (table->Type == GL_FLOAT) {
+ const GLint max = table->Size - 1;
+ const GLfloat scale = (GLfloat) max;
+ const GLfloat *lut = (const GLfloat *) table->Table;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLint jL = IROUND(rgba[i][RCOMP] * scale);
+ GLint jA = IROUND(rgba[i][ACOMP] * scale);
+ GLfloat luminance, alpha;
+ jL = CLAMP(jL, 0, max);
+ jA = CLAMP(jA, 0, max);
+ luminance = lut[jL * 2 + 0];
+ alpha = lut[jA * 2 + 1];
+ rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = luminance;
+ rgba[i][ACOMP] = alpha;;
+ }
+ }
+ else {
+ const GLint max = table->Size - 1;
+ const GLfloat scale = (GLfloat) max;
+ const GLchan *lut = (const GLchan *) table->Table;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLint jL = IROUND(rgba[i][RCOMP] * scale);
+ GLint jA = IROUND(rgba[i][ACOMP] * scale);
+ GLfloat luminance, alpha;
+ jL = CLAMP(jL, 0, max);
+ jA = CLAMP(jA, 0, max);
+ luminance = CHAN_TO_FLOAT(lut[jL * 2 + 0]);
+ alpha = CHAN_TO_FLOAT(lut[jA * 2 + 1]);
+ rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = luminance;
+ rgba[i][ACOMP] = alpha;;
+ }
+ }
+ break;
+ case GL_RGB:
+ /* replace RGB with RGB */
+ if (table->Type == GL_FLOAT) {
+ const GLint max = table->Size - 1;
+ const GLfloat scale = (GLfloat) max;
+ const GLfloat *lut = (const GLfloat *) table->Table;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLint jR = IROUND(rgba[i][RCOMP] * scale);
+ GLint jG = IROUND(rgba[i][GCOMP] * scale);
+ GLint jB = IROUND(rgba[i][BCOMP] * scale);
+ jR = CLAMP(jR, 0, max);
+ jG = CLAMP(jG, 0, max);
+ jB = CLAMP(jB, 0, max);
+ rgba[i][RCOMP] = lut[jR * 3 + 0];
+ rgba[i][GCOMP] = lut[jG * 3 + 1];
+ rgba[i][BCOMP] = lut[jB * 3 + 2];
+ }
+ }
+ else {
+ const GLint max = table->Size - 1;
+ const GLfloat scale = (GLfloat) max;
+ const GLchan *lut = (const GLchan *) table->Table;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLint jR = IROUND(rgba[i][RCOMP] * scale);
+ GLint jG = IROUND(rgba[i][GCOMP] * scale);
+ GLint jB = IROUND(rgba[i][BCOMP] * scale);
+ jR = CLAMP(jR, 0, max);
+ jG = CLAMP(jG, 0, max);
+ jB = CLAMP(jB, 0, max);
+ rgba[i][RCOMP] = CHAN_TO_FLOAT(lut[jR * 3 + 0]);
+ rgba[i][GCOMP] = CHAN_TO_FLOAT(lut[jG * 3 + 1]);
+ rgba[i][BCOMP] = CHAN_TO_FLOAT(lut[jB * 3 + 2]);
+ }
+ }
+ break;
+ case GL_RGBA:
+ /* replace RGBA with RGBA */
+ if (table->Type == GL_FLOAT) {
+ const GLint max = table->Size - 1;
+ const GLfloat scale = (GLfloat) max;
+ const GLfloat *lut = (const GLfloat *) table->Table;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLint jR = IROUND(rgba[i][RCOMP] * scale);
+ GLint jG = IROUND(rgba[i][GCOMP] * scale);
+ GLint jB = IROUND(rgba[i][BCOMP] * scale);
+ GLint jA = IROUND(rgba[i][ACOMP] * scale);
+ jR = CLAMP(jR, 0, max);
+ jG = CLAMP(jG, 0, max);
+ jB = CLAMP(jB, 0, max);
+ jA = CLAMP(jA, 0, max);
+ rgba[i][RCOMP] = lut[jR * 4 + 0];
+ rgba[i][GCOMP] = lut[jG * 4 + 1];
+ rgba[i][BCOMP] = lut[jB * 4 + 2];
+ rgba[i][ACOMP] = lut[jA * 4 + 3];
+ }
+ }
+ else {
+ const GLint max = table->Size - 1;
+ const GLfloat scale = (GLfloat) max;
+ const GLchan *lut = (const GLchan *) table->Table;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLint jR = IROUND(rgba[i][RCOMP] * scale);
+ GLint jG = IROUND(rgba[i][GCOMP] * scale);
+ GLint jB = IROUND(rgba[i][BCOMP] * scale);
+ GLint jA = IROUND(rgba[i][ACOMP] * scale);
+ jR = CLAMP(jR, 0, max);
+ jG = CLAMP(jG, 0, max);
+ jB = CLAMP(jB, 0, max);
+ jA = CLAMP(jA, 0, max);
+ rgba[i][RCOMP] = CHAN_TO_FLOAT(lut[jR * 4 + 0]);
+ rgba[i][GCOMP] = CHAN_TO_FLOAT(lut[jG * 4 + 1]);
+ rgba[i][BCOMP] = CHAN_TO_FLOAT(lut[jB * 4 + 2]);
+ rgba[i][ACOMP] = CHAN_TO_FLOAT(lut[jA * 4 + 3]);
+ }
+ }
+ break;
+ default:
+ _mesa_problem(NULL, "Bad format in _mesa_lookup_rgba_float");
+ return;
+ }
+}
+
+
+
+/**
+ * Apply a color table lookup to an array of GLchan RGBA colors.
+ */
+void
+_mesa_lookup_rgba_chan(const struct gl_color_table *table,
+ GLuint n, GLchan rgba[][4])
+{
+ if (!table->Table || table->Size == 0)
+ return;
+
+ switch (table->_BaseFormat) {
+ case GL_INTENSITY:
+ /* replace RGBA with I */
+ if (table->Type == GL_FLOAT) {
+ const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
+ const GLfloat *lut = (const GLfloat *) table->Table;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLint j = IROUND((GLfloat) rgba[i][RCOMP] * scale);
+ GLchan c;
+ CLAMPED_FLOAT_TO_CHAN(c, lut[j]);
+ rgba[i][RCOMP] = rgba[i][GCOMP] =
+ rgba[i][BCOMP] = rgba[i][ACOMP] = c;
+ }
+ }
+ else {
+#if CHAN_TYPE == GL_UNSIGNED_BYTE
+ if (table->Size == 256) {
+ /* common case */
+ const GLchan *lut = (const GLchan *) table->Table;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ const GLchan c = lut[rgba[i][RCOMP]];
+ rgba[i][RCOMP] = rgba[i][GCOMP] =
+ rgba[i][BCOMP] = rgba[i][ACOMP] = c;
+ }
+ }
+ else
+#endif
+ {
+ const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
+ const GLchan *lut = (const GLchan *) table->Table;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLint j = IROUND((GLfloat) rgba[i][RCOMP] * scale);
+ rgba[i][RCOMP] = rgba[i][GCOMP] =
+ rgba[i][BCOMP] = rgba[i][ACOMP] = lut[j];
+ }
+ }
+ }
+ break;
+ case GL_LUMINANCE:
+ /* replace RGB with L */
+ if (table->Type == GL_FLOAT) {
+ const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
+ const GLfloat *lut = (const GLfloat *) table->Table;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLint j = IROUND((GLfloat) rgba[i][RCOMP] * scale);
+ GLchan c;
+ CLAMPED_FLOAT_TO_CHAN(c, lut[j]);
+ rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = c;
+ }
+ }
+ else {
+#if CHAN_TYPE == GL_UNSIGNED_BYTE
+ if (table->Size == 256) {
+ /* common case */
+ const GLchan *lut = (const GLchan *) table->Table;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ const GLchan c = lut[rgba[i][RCOMP]];
+ rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = c;
+ }
+ }
+ else
+#endif
+ {
+ const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
+ const GLchan *lut = (const GLchan *) table->Table;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLint j = IROUND((GLfloat) rgba[i][RCOMP] * scale);
+ rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = lut[j];
+ }
+ }
+ }
+ break;
+ case GL_ALPHA:
+ /* replace A with A */
+ if (table->Type == GL_FLOAT) {
+ const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
+ const GLfloat *lut = (const GLfloat *) table->Table;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLint j = IROUND((GLfloat) rgba[i][ACOMP] * scale);
+ GLchan c;
+ CLAMPED_FLOAT_TO_CHAN(c, lut[j]);
+ rgba[i][ACOMP] = c;
+ }
+ }
+ else {
+#if CHAN_TYPE == GL_UNSIGNED_BYTE
+ if (table->Size == 256) {
+ /* common case */
+ const GLchan *lut = (const GLchan *) table->Table;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ rgba[i][ACOMP] = lut[rgba[i][ACOMP]];
+ }
+ }
+ else
+#endif
+ {
+ const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
+ const GLchan *lut = (const GLchan *) table->Table;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLint j = IROUND((GLfloat) rgba[i][ACOMP] * scale);
+ rgba[i][ACOMP] = lut[j];
+ }
+ }
+ }
+ break;
+ case GL_LUMINANCE_ALPHA:
+ /* replace RGBA with LLLA */
+ if (table->Type == GL_FLOAT) {
+ const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
+ const GLfloat *lut = (const GLfloat *) table->Table;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLint jL = IROUND((GLfloat) rgba[i][RCOMP] * scale);
+ GLint jA = IROUND((GLfloat) rgba[i][ACOMP] * scale);
+ GLchan luminance, alpha;
+ CLAMPED_FLOAT_TO_CHAN(luminance, lut[jL * 2 + 0]);
+ CLAMPED_FLOAT_TO_CHAN(alpha, lut[jA * 2 + 1]);
+ rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = luminance;
+ rgba[i][ACOMP] = alpha;;
+ }
+ }
+ else {
+#if CHAN_TYPE == GL_UNSIGNED_BYTE
+ if (table->Size == 256) {
+ /* common case */
+ const GLchan *lut = (const GLchan *) table->Table;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLchan l = lut[rgba[i][RCOMP] * 2 + 0];
+ GLchan a = lut[rgba[i][ACOMP] * 2 + 1];;
+ rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = l;
+ rgba[i][ACOMP] = a;
+ }
+ }
+ else
+#endif
+ {
+ const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
+ const GLchan *lut = (const GLchan *) table->Table;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLint jL = IROUND((GLfloat) rgba[i][RCOMP] * scale);
+ GLint jA = IROUND((GLfloat) rgba[i][ACOMP] * scale);
+ GLchan luminance = lut[jL * 2 + 0];
+ GLchan alpha = lut[jA * 2 + 1];
+ rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = luminance;
+ rgba[i][ACOMP] = alpha;
+ }
+ }
+ }
+ break;
+ case GL_RGB:
+ /* replace RGB with RGB */
+ if (table->Type == GL_FLOAT) {
+ const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
+ const GLfloat *lut = (const GLfloat *) table->Table;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLint jR = IROUND((GLfloat) rgba[i][RCOMP] * scale);
+ GLint jG = IROUND((GLfloat) rgba[i][GCOMP] * scale);
+ GLint jB = IROUND((GLfloat) rgba[i][BCOMP] * scale);
+ CLAMPED_FLOAT_TO_CHAN(rgba[i][RCOMP], lut[jR * 3 + 0]);
+ CLAMPED_FLOAT_TO_CHAN(rgba[i][GCOMP], lut[jG * 3 + 1]);
+ CLAMPED_FLOAT_TO_CHAN(rgba[i][BCOMP], lut[jB * 3 + 2]);
+ }
+ }
+ else {
+#if CHAN_TYPE == GL_UNSIGNED_BYTE
+ if (table->Size == 256) {
+ /* common case */
+ const GLchan *lut = (const GLchan *) table->Table;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ rgba[i][RCOMP] = lut[rgba[i][RCOMP] * 3 + 0];
+ rgba[i][GCOMP] = lut[rgba[i][GCOMP] * 3 + 1];
+ rgba[i][BCOMP] = lut[rgba[i][BCOMP] * 3 + 2];
+ }
+ }
+ else
+#endif
+ {
+ const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
+ const GLchan *lut = (const GLchan *) table->Table;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLint jR = IROUND((GLfloat) rgba[i][RCOMP] * scale);
+ GLint jG = IROUND((GLfloat) rgba[i][GCOMP] * scale);
+ GLint jB = IROUND((GLfloat) rgba[i][BCOMP] * scale);
+ rgba[i][RCOMP] = lut[jR * 3 + 0];
+ rgba[i][GCOMP] = lut[jG * 3 + 1];
+ rgba[i][BCOMP] = lut[jB * 3 + 2];
+ }
+ }
+ }
+ break;
+ case GL_RGBA:
+ /* replace RGBA with RGBA */
+ if (table->Type == GL_FLOAT) {
+ const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
+ const GLfloat *lut = (const GLfloat *) table->Table;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLint jR = IROUND((GLfloat) rgba[i][RCOMP] * scale);
+ GLint jG = IROUND((GLfloat) rgba[i][GCOMP] * scale);
+ GLint jB = IROUND((GLfloat) rgba[i][BCOMP] * scale);
+ GLint jA = IROUND((GLfloat) rgba[i][ACOMP] * scale);
+ CLAMPED_FLOAT_TO_CHAN(rgba[i][RCOMP], lut[jR * 4 + 0]);
+ CLAMPED_FLOAT_TO_CHAN(rgba[i][GCOMP], lut[jG * 4 + 1]);
+ CLAMPED_FLOAT_TO_CHAN(rgba[i][BCOMP], lut[jB * 4 + 2]);
+ CLAMPED_FLOAT_TO_CHAN(rgba[i][ACOMP], lut[jA * 4 + 3]);
+ }
+ }
+ else {
+#if CHAN_TYPE == GL_UNSIGNED_BYTE
+ if (table->Size == 256) {
+ /* common case */
+ const GLchan *lut = (const GLchan *) table->Table;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ rgba[i][RCOMP] = lut[rgba[i][RCOMP] * 4 + 0];
+ rgba[i][GCOMP] = lut[rgba[i][GCOMP] * 4 + 1];
+ rgba[i][BCOMP] = lut[rgba[i][BCOMP] * 4 + 2];
+ rgba[i][ACOMP] = lut[rgba[i][ACOMP] * 4 + 3];
+ }
+ }
+ else
+#endif
+ {
+ const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
+ const GLfloat *lut = (const GLfloat *) table->Table;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLint jR = IROUND((GLfloat) rgba[i][RCOMP] * scale);
+ GLint jG = IROUND((GLfloat) rgba[i][GCOMP] * scale);
+ GLint jB = IROUND((GLfloat) rgba[i][BCOMP] * scale);
+ GLint jA = IROUND((GLfloat) rgba[i][ACOMP] * scale);
+ CLAMPED_FLOAT_TO_CHAN(rgba[i][RCOMP], lut[jR * 4 + 0]);
+ CLAMPED_FLOAT_TO_CHAN(rgba[i][GCOMP], lut[jG * 4 + 1]);
+ CLAMPED_FLOAT_TO_CHAN(rgba[i][BCOMP], lut[jB * 4 + 2]);
+ CLAMPED_FLOAT_TO_CHAN(rgba[i][ACOMP], lut[jA * 4 + 3]);
+ }
+ }
+ }
+ break;
+ default:
+ _mesa_problem(NULL, "Bad format in _mesa_lookup_rgba_chan");
+ return;
+ }
+}
+
+
+
+/*
+ * Apply color index shift and offset to an array of pixels.
+ */
+void
+_mesa_shift_and_offset_ci( const GLcontext *ctx, GLuint n, GLuint indexes[] )
+{
+ GLint shift = ctx->Pixel.IndexShift;
+ GLint offset = ctx->Pixel.IndexOffset;
+ GLuint i;
+ if (shift > 0) {
+ for (i=0;i<n;i++) {
+ indexes[i] = (indexes[i] << shift) + offset;
+ }
+ }
+ else if (shift < 0) {
+ shift = -shift;
+ for (i=0;i<n;i++) {
+ indexes[i] = (indexes[i] >> shift) + offset;
+ }
+ }
+ else {
+ for (i=0;i<n;i++) {
+ indexes[i] = indexes[i] + offset;
+ }
+ }
+}
+
+
+/*
+ * Apply color index mapping to color indexes.
+ */
+void
+_mesa_map_ci( const GLcontext *ctx, GLuint n, GLuint index[] )
+{
+ const GLuint mask = ctx->Pixel.MapItoIsize - 1;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ const GLuint j = index[i] & mask;
+ index[i] = IROUND(ctx->Pixel.MapItoI[j]);
+ }
+}
+
+
+/*
+ * Map color indexes to rgba values.
+ */
+void
+_mesa_map_ci_to_rgba_chan( const GLcontext *ctx, GLuint n,
+ const GLuint index[], GLchan rgba[][4] )
+{
+#if CHAN_BITS == 8
+ GLuint rmask = ctx->Pixel.MapItoRsize - 1;
+ GLuint gmask = ctx->Pixel.MapItoGsize - 1;
+ GLuint bmask = ctx->Pixel.MapItoBsize - 1;
+ GLuint amask = ctx->Pixel.MapItoAsize - 1;
+ const GLubyte *rMap = ctx->Pixel.MapItoR8;
+ const GLubyte *gMap = ctx->Pixel.MapItoG8;
+ const GLubyte *bMap = ctx->Pixel.MapItoB8;
+ const GLubyte *aMap = ctx->Pixel.MapItoA8;
+ GLuint i;
+ for (i=0;i<n;i++) {
+ rgba[i][RCOMP] = rMap[index[i] & rmask];
+ rgba[i][GCOMP] = gMap[index[i] & gmask];
+ rgba[i][BCOMP] = bMap[index[i] & bmask];
+ rgba[i][ACOMP] = aMap[index[i] & amask];
+ }
+#else
+ GLuint rmask = ctx->Pixel.MapItoRsize - 1;
+ GLuint gmask = ctx->Pixel.MapItoGsize - 1;
+ GLuint bmask = ctx->Pixel.MapItoBsize - 1;
+ GLuint amask = ctx->Pixel.MapItoAsize - 1;
+ const GLfloat *rMap = ctx->Pixel.MapItoR;
+ const GLfloat *gMap = ctx->Pixel.MapItoG;
+ const GLfloat *bMap = ctx->Pixel.MapItoB;
+ const GLfloat *aMap = ctx->Pixel.MapItoA;
+ GLuint i;
+ for (i=0;i<n;i++) {
+ CLAMPED_FLOAT_TO_CHAN(rgba[i][RCOMP], rMap[index[i] & rmask]);
+ CLAMPED_FLOAT_TO_CHAN(rgba[i][GCOMP], gMap[index[i] & gmask]);
+ CLAMPED_FLOAT_TO_CHAN(rgba[i][BCOMP], bMap[index[i] & bmask]);
+ CLAMPED_FLOAT_TO_CHAN(rgba[i][ACOMP], aMap[index[i] & amask]);
+ }
+#endif
+}
+
+
+/*
+ * Map color indexes to float rgba values.
+ */
+void
+_mesa_map_ci_to_rgba( const GLcontext *ctx, GLuint n,
+ const GLuint index[], GLfloat rgba[][4] )
+{
+ GLuint rmask = ctx->Pixel.MapItoRsize - 1;
+ GLuint gmask = ctx->Pixel.MapItoGsize - 1;
+ GLuint bmask = ctx->Pixel.MapItoBsize - 1;
+ GLuint amask = ctx->Pixel.MapItoAsize - 1;
+ const GLfloat *rMap = ctx->Pixel.MapItoR;
+ const GLfloat *gMap = ctx->Pixel.MapItoG;
+ const GLfloat *bMap = ctx->Pixel.MapItoB;
+ const GLfloat *aMap = ctx->Pixel.MapItoA;
+ GLuint i;
+ for (i=0;i<n;i++) {
+ rgba[i][RCOMP] = rMap[index[i] & rmask];
+ rgba[i][GCOMP] = gMap[index[i] & gmask];
+ rgba[i][BCOMP] = bMap[index[i] & bmask];
+ rgba[i][ACOMP] = aMap[index[i] & amask];
+ }
+}
+
+
+/*
+ * Map 8-bit color indexes to rgb values.
+ */
+void
+_mesa_map_ci8_to_rgba( const GLcontext *ctx, GLuint n, const GLubyte index[],
+ GLchan rgba[][4] )
+{
+#if CHAN_BITS == 8
+ GLuint rmask = ctx->Pixel.MapItoRsize - 1;
+ GLuint gmask = ctx->Pixel.MapItoGsize - 1;
+ GLuint bmask = ctx->Pixel.MapItoBsize - 1;
+ GLuint amask = ctx->Pixel.MapItoAsize - 1;
+ const GLubyte *rMap = ctx->Pixel.MapItoR8;
+ const GLubyte *gMap = ctx->Pixel.MapItoG8;
+ const GLubyte *bMap = ctx->Pixel.MapItoB8;
+ const GLubyte *aMap = ctx->Pixel.MapItoA8;
+ GLuint i;
+ for (i=0;i<n;i++) {
+ rgba[i][RCOMP] = rMap[index[i] & rmask];
+ rgba[i][GCOMP] = gMap[index[i] & gmask];
+ rgba[i][BCOMP] = bMap[index[i] & bmask];
+ rgba[i][ACOMP] = aMap[index[i] & amask];
+ }
+#else
+ GLuint rmask = ctx->Pixel.MapItoRsize - 1;
+ GLuint gmask = ctx->Pixel.MapItoGsize - 1;
+ GLuint bmask = ctx->Pixel.MapItoBsize - 1;
+ GLuint amask = ctx->Pixel.MapItoAsize - 1;
+ const GLfloat *rMap = ctx->Pixel.MapItoR;
+ const GLfloat *gMap = ctx->Pixel.MapItoG;
+ const GLfloat *bMap = ctx->Pixel.MapItoB;
+ const GLfloat *aMap = ctx->Pixel.MapItoA;
+ GLuint i;
+ for (i=0;i<n;i++) {
+ CLAMPED_FLOAT_TO_CHAN(rgba[i][RCOMP], rMap[index[i] & rmask]);
+ CLAMPED_FLOAT_TO_CHAN(rgba[i][GCOMP], gMap[index[i] & gmask]);
+ CLAMPED_FLOAT_TO_CHAN(rgba[i][BCOMP], bMap[index[i] & bmask]);
+ CLAMPED_FLOAT_TO_CHAN(rgba[i][ACOMP], aMap[index[i] & amask]);
+ }
+#endif
+}
+
+
+void
+_mesa_shift_and_offset_stencil( const GLcontext *ctx, GLuint n,
+ GLstencil stencil[] )
+{
+ GLuint i;
+ GLint shift = ctx->Pixel.IndexShift;
+ GLint offset = ctx->Pixel.IndexOffset;
+ if (shift > 0) {
+ for (i=0;i<n;i++) {
+ stencil[i] = (stencil[i] << shift) + offset;
+ }
+ }
+ else if (shift < 0) {
+ shift = -shift;
+ for (i=0;i<n;i++) {
+ stencil[i] = (stencil[i] >> shift) + offset;
+ }
+ }
+ else {
+ for (i=0;i<n;i++) {
+ stencil[i] = stencil[i] + offset;
+ }
+ }
+
+}
+
+
+void
+_mesa_map_stencil( const GLcontext *ctx, GLuint n, GLstencil stencil[] )
+{
+ GLuint mask = ctx->Pixel.MapStoSsize - 1;
+ GLuint i;
+ for (i=0;i<n;i++) {
+ stencil[i] = ctx->Pixel.MapStoS[ stencil[i] & mask ];
+ }
+}
+
+
+void
+_mesa_scale_and_bias_depth(const GLcontext *ctx, GLuint n,
+ GLfloat depthValues[])
+{
+ const GLfloat scale = ctx->Pixel.DepthScale;
+ const GLfloat bias = ctx->Pixel.DepthBias;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLfloat d = depthValues[i] * scale + bias;
+ depthValues[i] = CLAMP(d, 0.0F, 1.0F);
+ }
+}
+
+
+/*
+ * This function converts an array of GLchan colors to GLfloat colors.
+ * Most importantly, it undoes the non-uniform quantization of pixel
+ * values introduced when we convert shallow (< 8 bit) pixel values
+ * to GLubytes in the ctx->Driver.ReadRGBASpan() functions.
+ * This fixes a number of OpenGL conformance failures when running on
+ * 16bpp displays, for example.
+ */
+void
+_mesa_chan_to_float_span(const GLcontext *ctx, GLuint n,
+ CONST GLchan rgba[][4], GLfloat rgbaf[][4])
+{
+#if CHAN_TYPE == GL_FLOAT
+ MEMCPY(rgbaf, rgba, n * 4 * sizeof(GLfloat));
+#else
+ const GLuint rShift = CHAN_BITS - ctx->Visual.redBits;
+ const GLuint gShift = CHAN_BITS - ctx->Visual.greenBits;
+ const GLuint bShift = CHAN_BITS - ctx->Visual.blueBits;
+ GLuint aShift;
+ const GLfloat rScale = 1.0F / (GLfloat) ((1 << ctx->Visual.redBits ) - 1);
+ const GLfloat gScale = 1.0F / (GLfloat) ((1 << ctx->Visual.greenBits) - 1);
+ const GLfloat bScale = 1.0F / (GLfloat) ((1 << ctx->Visual.blueBits ) - 1);
+ GLfloat aScale;
+ GLuint i;
+
+ if (ctx->Visual.alphaBits > 0) {
+ aShift = CHAN_BITS - ctx->Visual.alphaBits;
+ aScale = 1.0F / (GLfloat) ((1 << ctx->Visual.alphaBits) - 1);
+ }
+ else {
+ aShift = 0;
+ aScale = 1.0F / CHAN_MAXF;
+ }
+
+ for (i = 0; i < n; i++) {
+ const GLint r = rgba[i][RCOMP] >> rShift;
+ const GLint g = rgba[i][GCOMP] >> gShift;
+ const GLint b = rgba[i][BCOMP] >> bShift;
+ const GLint a = rgba[i][ACOMP] >> aShift;
+ rgbaf[i][RCOMP] = (GLfloat) r * rScale;
+ rgbaf[i][GCOMP] = (GLfloat) g * gScale;
+ rgbaf[i][BCOMP] = (GLfloat) b * bScale;
+ rgbaf[i][ACOMP] = (GLfloat) a * aScale;
+ }
+#endif
+}
+
+/**********************************************************************/
+/***** State Management *****/
+/**********************************************************************/
+
+/*
+ * Return a bitmask of IMAGE_*_BIT flags which to indicate which
+ * pixel transfer operations are enabled.
+ */
+static void
+update_image_transfer_state(GLcontext *ctx)
+{
+ GLuint mask = 0;
+
+ if (ctx->Pixel.RedScale != 1.0F || ctx->Pixel.RedBias != 0.0F ||
+ ctx->Pixel.GreenScale != 1.0F || ctx->Pixel.GreenBias != 0.0F ||
+ ctx->Pixel.BlueScale != 1.0F || ctx->Pixel.BlueBias != 0.0F ||
+ ctx->Pixel.AlphaScale != 1.0F || ctx->Pixel.AlphaBias != 0.0F)
+ mask |= IMAGE_SCALE_BIAS_BIT;
+
+ if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset)
+ mask |= IMAGE_SHIFT_OFFSET_BIT;
+
+ if (ctx->Pixel.MapColorFlag)
+ mask |= IMAGE_MAP_COLOR_BIT;
+
+ if (ctx->Pixel.ColorTableEnabled)
+ mask |= IMAGE_COLOR_TABLE_BIT;
+
+ if (ctx->Pixel.Convolution1DEnabled ||
+ ctx->Pixel.Convolution2DEnabled ||
+ ctx->Pixel.Separable2DEnabled) {
+ mask |= IMAGE_CONVOLUTION_BIT;
+ if (ctx->Pixel.PostConvolutionScale[0] != 1.0F ||
+ ctx->Pixel.PostConvolutionScale[1] != 1.0F ||
+ ctx->Pixel.PostConvolutionScale[2] != 1.0F ||
+ ctx->Pixel.PostConvolutionScale[3] != 1.0F ||
+ ctx->Pixel.PostConvolutionBias[0] != 0.0F ||
+ ctx->Pixel.PostConvolutionBias[1] != 0.0F ||
+ ctx->Pixel.PostConvolutionBias[2] != 0.0F ||
+ ctx->Pixel.PostConvolutionBias[3] != 0.0F) {
+ mask |= IMAGE_POST_CONVOLUTION_SCALE_BIAS;
+ }
+ }
+
+ if (ctx->Pixel.PostConvolutionColorTableEnabled)
+ mask |= IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT;
+
+ if (ctx->ColorMatrixStack.Top->type != MATRIX_IDENTITY ||
+ ctx->Pixel.PostColorMatrixScale[0] != 1.0F ||
+ ctx->Pixel.PostColorMatrixBias[0] != 0.0F ||
+ ctx->Pixel.PostColorMatrixScale[1] != 1.0F ||
+ ctx->Pixel.PostColorMatrixBias[1] != 0.0F ||
+ ctx->Pixel.PostColorMatrixScale[2] != 1.0F ||
+ ctx->Pixel.PostColorMatrixBias[2] != 0.0F ||
+ ctx->Pixel.PostColorMatrixScale[3] != 1.0F ||
+ ctx->Pixel.PostColorMatrixBias[3] != 0.0F)
+ mask |= IMAGE_COLOR_MATRIX_BIT;
+
+ if (ctx->Pixel.PostColorMatrixColorTableEnabled)
+ mask |= IMAGE_POST_COLOR_MATRIX_COLOR_TABLE_BIT;
+
+ if (ctx->Pixel.HistogramEnabled)
+ mask |= IMAGE_HISTOGRAM_BIT;
+
+ if (ctx->Pixel.MinMaxEnabled)
+ mask |= IMAGE_MIN_MAX_BIT;
+
+ ctx->_ImageTransferState = mask;
+}
+
+
+void _mesa_update_pixel( GLcontext *ctx, GLuint new_state )
+{
+ if (new_state & _NEW_COLOR_MATRIX)
+ _math_matrix_analyse( ctx->ColorMatrixStack.Top );
+
+ /* References ColorMatrix.type (derived above).
+ */
+ if (new_state & _IMAGE_NEW_TRANSFER_STATE)
+ update_image_transfer_state(ctx);
+}
+
+
+/**********************************************************************/
+/***** Initialization *****/
+/**********************************************************************/
+
+
+/**
+ * Initialize the context's PIXEL attribute group.
+ */
+void
+_mesa_init_pixel( GLcontext *ctx )
+{
+ int i;
+
+ /* Pixel group */
+ ctx->Pixel.RedBias = 0.0;
+ ctx->Pixel.RedScale = 1.0;
+ ctx->Pixel.GreenBias = 0.0;
+ ctx->Pixel.GreenScale = 1.0;
+ ctx->Pixel.BlueBias = 0.0;
+ ctx->Pixel.BlueScale = 1.0;
+ ctx->Pixel.AlphaBias = 0.0;
+ ctx->Pixel.AlphaScale = 1.0;
+ ctx->Pixel.DepthBias = 0.0;
+ ctx->Pixel.DepthScale = 1.0;
+ ctx->Pixel.IndexOffset = 0;
+ ctx->Pixel.IndexShift = 0;
+ ctx->Pixel.ZoomX = 1.0;
+ ctx->Pixel.ZoomY = 1.0;
+ ctx->Pixel.MapColorFlag = GL_FALSE;
+ ctx->Pixel.MapStencilFlag = GL_FALSE;
+ ctx->Pixel.MapStoSsize = 1;
+ ctx->Pixel.MapItoIsize = 1;
+ ctx->Pixel.MapItoRsize = 1;
+ ctx->Pixel.MapItoGsize = 1;
+ ctx->Pixel.MapItoBsize = 1;
+ ctx->Pixel.MapItoAsize = 1;
+ ctx->Pixel.MapRtoRsize = 1;
+ ctx->Pixel.MapGtoGsize = 1;
+ ctx->Pixel.MapBtoBsize = 1;
+ ctx->Pixel.MapAtoAsize = 1;
+ ctx->Pixel.MapStoS[0] = 0;
+ ctx->Pixel.MapItoI[0] = 0.0;
+ ctx->Pixel.MapItoR[0] = 0.0;
+ ctx->Pixel.MapItoG[0] = 0.0;
+ ctx->Pixel.MapItoB[0] = 0.0;
+ ctx->Pixel.MapItoA[0] = 0.0;
+ ctx->Pixel.MapItoR8[0] = 0;
+ ctx->Pixel.MapItoG8[0] = 0;
+ ctx->Pixel.MapItoB8[0] = 0;
+ ctx->Pixel.MapItoA8[0] = 0;
+ ctx->Pixel.MapRtoR[0] = 0.0;
+ ctx->Pixel.MapGtoG[0] = 0.0;
+ ctx->Pixel.MapBtoB[0] = 0.0;
+ ctx->Pixel.MapAtoA[0] = 0.0;
+ ctx->Pixel.HistogramEnabled = GL_FALSE;
+ ctx->Pixel.MinMaxEnabled = GL_FALSE;
+ ASSIGN_4V(ctx->Pixel.PostColorMatrixScale, 1.0, 1.0, 1.0, 1.0);
+ ASSIGN_4V(ctx->Pixel.PostColorMatrixBias, 0.0, 0.0, 0.0, 0.0);
+ ASSIGN_4V(ctx->Pixel.ColorTableScale, 1.0, 1.0, 1.0, 1.0);
+ ASSIGN_4V(ctx->Pixel.ColorTableBias, 0.0, 0.0, 0.0, 0.0);
+ ASSIGN_4V(ctx->Pixel.PCCTscale, 1.0, 1.0, 1.0, 1.0);
+ ASSIGN_4V(ctx->Pixel.PCCTbias, 0.0, 0.0, 0.0, 0.0);
+ ASSIGN_4V(ctx->Pixel.PCMCTscale, 1.0, 1.0, 1.0, 1.0);
+ ASSIGN_4V(ctx->Pixel.PCMCTbias, 0.0, 0.0, 0.0, 0.0);
+ ctx->Pixel.ColorTableEnabled = GL_FALSE;
+ ctx->Pixel.PostConvolutionColorTableEnabled = GL_FALSE;
+ ctx->Pixel.PostColorMatrixColorTableEnabled = GL_FALSE;
+ ctx->Pixel.Convolution1DEnabled = GL_FALSE;
+ ctx->Pixel.Convolution2DEnabled = GL_FALSE;
+ ctx->Pixel.Separable2DEnabled = GL_FALSE;
+ for (i = 0; i < 3; i++) {
+ ASSIGN_4V(ctx->Pixel.ConvolutionBorderColor[i], 0.0, 0.0, 0.0, 0.0);
+ ctx->Pixel.ConvolutionBorderMode[i] = GL_REDUCE;
+ ASSIGN_4V(ctx->Pixel.ConvolutionFilterScale[i], 1.0, 1.0, 1.0, 1.0);
+ ASSIGN_4V(ctx->Pixel.ConvolutionFilterBias[i], 0.0, 0.0, 0.0, 0.0);
+ }
+ for (i = 0; i < MAX_CONVOLUTION_WIDTH * MAX_CONVOLUTION_WIDTH * 4; i++) {
+ ctx->Convolution1D.Filter[i] = 0.0;
+ ctx->Convolution2D.Filter[i] = 0.0;
+ ctx->Separable2D.Filter[i] = 0.0;
+ }
+ ASSIGN_4V(ctx->Pixel.PostConvolutionScale, 1.0, 1.0, 1.0, 1.0);
+ ASSIGN_4V(ctx->Pixel.PostConvolutionBias, 0.0, 0.0, 0.0, 0.0);
+ /* GL_SGI_texture_color_table */
+ ASSIGN_4V(ctx->Pixel.TextureColorTableScale, 1.0, 1.0, 1.0, 1.0);
+ ASSIGN_4V(ctx->Pixel.TextureColorTableBias, 0.0, 0.0, 0.0, 0.0);
+
+ /* Pixel transfer */
+ ctx->Pack.Alignment = 4;
+ ctx->Pack.RowLength = 0;
+ ctx->Pack.ImageHeight = 0;
+ ctx->Pack.SkipPixels = 0;
+ ctx->Pack.SkipRows = 0;
+ ctx->Pack.SkipImages = 0;
+ ctx->Pack.SwapBytes = GL_FALSE;
+ ctx->Pack.LsbFirst = GL_FALSE;
+ ctx->Pack.ClientStorage = GL_FALSE;
+ ctx->Pack.Invert = GL_FALSE;
+#if FEATURE_EXT_pixel_buffer_object
+ ctx->Pack.BufferObj = ctx->Array.NullBufferObj;
+#endif
+ ctx->Unpack.Alignment = 4;
+ ctx->Unpack.RowLength = 0;
+ ctx->Unpack.ImageHeight = 0;
+ ctx->Unpack.SkipPixels = 0;
+ ctx->Unpack.SkipRows = 0;
+ ctx->Unpack.SkipImages = 0;
+ ctx->Unpack.SwapBytes = GL_FALSE;
+ ctx->Unpack.LsbFirst = GL_FALSE;
+ ctx->Unpack.ClientStorage = GL_FALSE;
+ ctx->Unpack.Invert = GL_FALSE;
+#if FEATURE_EXT_pixel_buffer_object
+ ctx->Unpack.BufferObj = ctx->Array.NullBufferObj;
+#endif
+
+ /*
+ * _mesa_unpack_image() returns image data in this format. When we
+ * execute image commands (glDrawPixels(), glTexImage(), etc) from
+ * within display lists we have to be sure to set the current
+ * unpacking parameters to these values!
+ */
+ ctx->DefaultPacking.Alignment = 1;
+ ctx->DefaultPacking.RowLength = 0;
+ ctx->DefaultPacking.SkipPixels = 0;
+ ctx->DefaultPacking.SkipRows = 0;
+ ctx->DefaultPacking.ImageHeight = 0;
+ ctx->DefaultPacking.SkipImages = 0;
+ ctx->DefaultPacking.SwapBytes = GL_FALSE;
+ ctx->DefaultPacking.LsbFirst = GL_FALSE;
+ ctx->DefaultPacking.ClientStorage = GL_FALSE;
+ ctx->DefaultPacking.Invert = GL_FALSE;
+#if FEATURE_EXT_pixel_buffer_object
+ ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj;
+#endif
+
+ if (ctx->Visual.doubleBufferMode) {
+ ctx->Pixel.ReadBuffer = GL_BACK;
+ }
+ else {
+ ctx->Pixel.ReadBuffer = GL_FRONT;
+ }
+
+ /* Miscellaneous */
+ ctx->_ImageTransferState = 0;
+}
diff --git a/src/mesa/main/pixel.h b/src/mesa/main/pixel.h
new file mode 100644
index 00000000000..161990024b9
--- /dev/null
+++ b/src/mesa/main/pixel.h
@@ -0,0 +1,158 @@
+/**
+ * \file pixel.h
+ * Pixel operations.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef PIXEL_H
+#define PIXEL_H
+
+
+#include "mtypes.h"
+
+
+/** \name API functions */
+/*@{*/
+
+extern void GLAPIENTRY
+_mesa_GetPixelMapfv( GLenum map, GLfloat *values );
+
+extern void GLAPIENTRY
+_mesa_GetPixelMapuiv( GLenum map, GLuint *values );
+
+extern void GLAPIENTRY
+_mesa_GetPixelMapusv( GLenum map, GLushort *values );
+
+extern void GLAPIENTRY
+_mesa_PixelMapfv( GLenum map, GLsizei mapsize, const GLfloat *values );
+
+extern void GLAPIENTRY
+_mesa_PixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values );
+
+extern void GLAPIENTRY
+_mesa_PixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values );
+
+extern void GLAPIENTRY
+_mesa_PixelStoref( GLenum pname, GLfloat param );
+
+
+extern void GLAPIENTRY
+_mesa_PixelStorei( GLenum pname, GLint param );
+
+extern void GLAPIENTRY
+_mesa_PixelTransferf( GLenum pname, GLfloat param );
+
+extern void GLAPIENTRY
+_mesa_PixelTransferi( GLenum pname, GLint param );
+
+extern void GLAPIENTRY
+_mesa_PixelZoom( GLfloat xfactor, GLfloat yfactor );
+
+/*@}*/
+
+
+/** \name Pixel processing functions */
+/*@{*/
+
+extern void
+_mesa_scale_and_bias_rgba(GLuint n, GLfloat rgba[][4],
+ GLfloat rScale, GLfloat gScale,
+ GLfloat bScale, GLfloat aScale,
+ GLfloat rBias, GLfloat gBias,
+ GLfloat bBias, GLfloat aBias);
+
+extern void
+_mesa_map_rgba(const GLcontext *ctx, GLuint n, GLfloat rgba[][4]);
+
+
+extern void
+_mesa_transform_rgba(const GLcontext *ctx, GLuint n, GLfloat rgba[][4]);
+
+
+extern void
+_mesa_lookup_rgba_float(const struct gl_color_table *table,
+ GLuint n, GLfloat rgba[][4]);
+
+extern void
+_mesa_lookup_rgba_chan(const struct gl_color_table *table,
+ GLuint n, GLchan rgba[][4]);
+
+
+extern void
+_mesa_shift_and_offset_ci(const GLcontext *ctx, GLuint n,
+ GLuint indexes[]);
+
+
+extern void
+_mesa_map_ci(const GLcontext *ctx, GLuint n, GLuint index[]);
+
+
+extern void
+_mesa_map_ci_to_rgba_chan(const GLcontext *ctx,
+ GLuint n, const GLuint index[],
+ GLchan rgba[][4]);
+
+
+extern void
+_mesa_map_ci_to_rgba(const GLcontext *ctx,
+ GLuint n, const GLuint index[], GLfloat rgba[][4]);
+
+
+extern void
+_mesa_map_ci8_to_rgba(const GLcontext *ctx,
+ GLuint n, const GLubyte index[],
+ GLchan rgba[][4]);
+
+
+extern void
+_mesa_shift_and_offset_stencil(const GLcontext *ctx, GLuint n,
+ GLstencil indexes[]);
+
+
+extern void
+_mesa_map_stencil(const GLcontext *ctx, GLuint n, GLstencil index[]);
+
+
+extern void
+_mesa_scale_and_bias_depth(const GLcontext *ctx, GLuint n,
+ GLfloat depthValues[]);
+
+
+extern void
+_mesa_chan_to_float_span(const GLcontext *ctx, GLuint n,
+ CONST GLchan rgba[][4], GLfloat rgbaf[][4]);
+
+
+extern void
+_mesa_update_pixel( GLcontext *ctx, GLuint newstate );
+
+extern void
+_mesa_init_pixel( GLcontext * ctx );
+
+/*@}*/
+
+#endif
diff --git a/src/mesa/main/points.c b/src/mesa/main/points.c
new file mode 100644
index 00000000000..aa36fb62877
--- /dev/null
+++ b/src/mesa/main/points.c
@@ -0,0 +1,294 @@
+/**
+ * \file points.c
+ * Point operations.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include "glheader.h"
+#include "context.h"
+#include "macros.h"
+#include "points.h"
+#include "texstate.h"
+#include "mtypes.h"
+
+
+/**
+ * Set current point size.
+ * \param size point diameter in pixels
+ * \sa glPointSize().
+ */
+void GLAPIENTRY
+_mesa_PointSize( GLfloat size )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (size <= 0.0) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glPointSize" );
+ return;
+ }
+
+ if (ctx->Point.Size == size)
+ return;
+
+ FLUSH_VERTICES(ctx, _NEW_POINT);
+ ctx->Point.Size = size;
+
+ if (ctx->Driver.PointSize)
+ ctx->Driver.PointSize(ctx, size);
+}
+
+
+#if _HAVE_FULL_GL
+
+/*
+ * Added by GL_NV_point_sprite
+ */
+void GLAPIENTRY
+_mesa_PointParameteriNV( GLenum pname, GLint param )
+{
+ const GLfloat value = (GLfloat) param;
+ _mesa_PointParameterfvEXT(pname, &value);
+}
+
+
+/*
+ * Added by GL_NV_point_sprite
+ */
+void GLAPIENTRY
+_mesa_PointParameterivNV( GLenum pname, const GLint *params )
+{
+ const GLfloat value = (GLfloat) params[0];
+ _mesa_PointParameterfvEXT(pname, &value);
+}
+
+
+
+/*
+ * Same for both GL_EXT_point_parameters and GL_ARB_point_parameters.
+ */
+void GLAPIENTRY
+_mesa_PointParameterfEXT( GLenum pname, GLfloat param)
+{
+ _mesa_PointParameterfvEXT(pname, &param);
+}
+
+
+
+/*
+ * Same for both GL_EXT_point_parameters and GL_ARB_point_parameters.
+ */
+void GLAPIENTRY
+_mesa_PointParameterfvEXT( GLenum pname, const GLfloat *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ switch (pname) {
+ case GL_DISTANCE_ATTENUATION_EXT:
+ if (ctx->Extensions.EXT_point_parameters) {
+ if (TEST_EQ_3V(ctx->Point.Params, params))
+ return;
+ FLUSH_VERTICES(ctx, _NEW_POINT);
+ COPY_3V(ctx->Point.Params, params);
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glPointParameterf[v]{EXT,ARB}(pname)");
+ return;
+ }
+ break;
+ case GL_POINT_SIZE_MIN_EXT:
+ if (ctx->Extensions.EXT_point_parameters) {
+ if (params[0] < 0.0F) {
+ _mesa_error( ctx, GL_INVALID_VALUE,
+ "glPointParameterf[v]{EXT,ARB}(param)" );
+ return;
+ }
+ if (ctx->Point.MinSize == params[0])
+ return;
+ FLUSH_VERTICES(ctx, _NEW_POINT);
+ ctx->Point.MinSize = params[0];
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glPointParameterf[v]{EXT,ARB}(pname)");
+ return;
+ }
+ break;
+ case GL_POINT_SIZE_MAX_EXT:
+ if (ctx->Extensions.EXT_point_parameters) {
+ if (params[0] < 0.0F) {
+ _mesa_error( ctx, GL_INVALID_VALUE,
+ "glPointParameterf[v]{EXT,ARB}(param)" );
+ return;
+ }
+ if (ctx->Point.MaxSize == params[0])
+ return;
+ FLUSH_VERTICES(ctx, _NEW_POINT);
+ ctx->Point.MaxSize = params[0];
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glPointParameterf[v]{EXT,ARB}(pname)");
+ return;
+ }
+ break;
+ case GL_POINT_FADE_THRESHOLD_SIZE_EXT:
+ if (ctx->Extensions.EXT_point_parameters) {
+ if (params[0] < 0.0F) {
+ _mesa_error( ctx, GL_INVALID_VALUE,
+ "glPointParameterf[v]{EXT,ARB}(param)" );
+ return;
+ }
+ if (ctx->Point.Threshold == params[0])
+ return;
+ FLUSH_VERTICES(ctx, _NEW_POINT);
+ ctx->Point.Threshold = params[0];
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glPointParameterf[v]{EXT,ARB}(pname)");
+ return;
+ }
+ break;
+ case GL_POINT_SPRITE_R_MODE_NV:
+ /* This is one area where ARB_point_sprite and NV_point_sprite
+ * differ. In ARB_point_sprite the POINT_SPRITE_R_MODE is
+ * always ZERO. NV_point_sprite adds the S and R modes.
+ */
+ if (ctx->Extensions.NV_point_sprite) {
+ GLenum value = (GLenum) params[0];
+ if (value != GL_ZERO && value != GL_S && value != GL_R) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glPointParameterf[v]{EXT,ARB}(param)");
+ return;
+ }
+ if (ctx->Point.SpriteRMode == value)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_POINT);
+ ctx->Point.SpriteRMode = value;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glPointParameterf[v]{EXT,ARB}(pname)");
+ return;
+ }
+ break;
+ case GL_POINT_SPRITE_COORD_ORIGIN:
+ if (ctx->Extensions.ARB_point_sprite) {
+ GLenum value = (GLenum) params[0];
+ if (value != GL_LOWER_LEFT && value != GL_UPPER_LEFT) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glPointParameterf[v]{EXT,ARB}(param)");
+ return;
+ }
+ if (ctx->Point.SpriteOrigin == value)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_POINT);
+ ctx->Point.SpriteOrigin = value;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glPointParameterf[v]{EXT,ARB}(pname)");
+ return;
+ }
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM,
+ "glPointParameterf[v]{EXT,ARB}(pname)" );
+ return;
+ }
+
+ if (ctx->Driver.PointParameterfv)
+ (*ctx->Driver.PointParameterfv)(ctx, pname, params);
+}
+#endif
+
+
+
+/**
+ * Update derived point-related state.
+ */
+void
+_mesa_update_point(GLcontext *ctx)
+{
+ /* clamp to user-specified limits now, clamp to ctx->Const.Min/Max
+ * limits during rasterization.
+ */
+ ctx->Point._Size = CLAMP(ctx->Point.Size,
+ ctx->Point.MinSize,
+ ctx->Point.MaxSize);
+
+ if (ctx->Point._Size == 1.0F)
+ ctx->_TriangleCaps &= ~DD_POINT_SIZE;
+ else
+ ctx->_TriangleCaps |= DD_POINT_SIZE;
+
+ ctx->Point._Attenuated = (ctx->Point.Params[0] != 1.0 ||
+ ctx->Point.Params[1] != 0.0 ||
+ ctx->Point.Params[2] != 0.0);
+
+ if (ctx->Point._Attenuated)
+ ctx->_TriangleCaps |= DD_POINT_ATTEN;
+ else
+ ctx->_TriangleCaps &= ~DD_POINT_ATTEN;
+}
+
+
+
+/**
+ * Initialize the context point state.
+ *
+ * \param ctx GL context.
+ *
+ * Initializes __GLcontextRec::Point and point related constants in
+ * __GLcontextRec::Const.
+ */
+void
+_mesa_init_point(GLcontext *ctx)
+{
+ GLuint i;
+
+ ctx->Point.SmoothFlag = GL_FALSE;
+ ctx->Point.Size = 1.0;
+ ctx->Point._Size = 1.0;
+ ctx->Point.Params[0] = 1.0;
+ ctx->Point.Params[1] = 0.0;
+ ctx->Point.Params[2] = 0.0;
+ ctx->Point._Attenuated = GL_FALSE;
+ ctx->Point.MinSize = 0.0;
+ ctx->Point.MaxSize
+ = MAX2(ctx->Const.MaxPointSize, ctx->Const.MaxPointSizeAA);
+ ctx->Point.Threshold = 1.0;
+ ctx->Point.PointSprite = GL_FALSE; /* GL_ARB/NV_point_sprite */
+ ctx->Point.SpriteRMode = GL_ZERO; /* GL_NV_point_sprite (only!) */
+ ctx->Point.SpriteOrigin = GL_UPPER_LEFT; /* GL_ARB_point_sprite */
+ for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
+ ctx->Point.CoordReplace[i] = GL_FALSE; /* GL_ARB/NV_point_sprite */
+ }
+}
diff --git a/src/mesa/main/points.h b/src/mesa/main/points.h
new file mode 100644
index 00000000000..56acd9ee574
--- /dev/null
+++ b/src/mesa/main/points.h
@@ -0,0 +1,60 @@
+/**
+ * \file points.h
+ * Point operations.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef POINTS_H
+#define POINTS_H
+
+
+#include "mtypes.h"
+
+
+extern void GLAPIENTRY
+_mesa_PointSize( GLfloat size );
+
+extern void GLAPIENTRY
+_mesa_PointParameteriNV( GLenum pname, GLint param );
+
+extern void GLAPIENTRY
+_mesa_PointParameterivNV( GLenum pname, const GLint *params );
+
+extern void GLAPIENTRY
+_mesa_PointParameterfEXT( GLenum pname, GLfloat param );
+
+extern void GLAPIENTRY
+_mesa_PointParameterfvEXT( GLenum pname, const GLfloat *params );
+
+extern void
+_mesa_update_point(GLcontext *ctx);
+
+extern void
+_mesa_init_point( GLcontext * ctx );
+
+
+#endif
diff --git a/src/mesa/main/polygon.c b/src/mesa/main/polygon.c
new file mode 100644
index 00000000000..b771408cf36
--- /dev/null
+++ b/src/mesa/main/polygon.c
@@ -0,0 +1,383 @@
+/**
+ * \file polygon.c
+ * Polygon operations.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.3
+ *
+ * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include "glheader.h"
+#include "imports.h"
+#include "bufferobj.h"
+#include "context.h"
+#include "image.h"
+#include "enums.h"
+#include "macros.h"
+#include "polygon.h"
+#include "mtypes.h"
+
+
+/**
+ * Specify whether to cull front- or back-facing facets.
+ *
+ * \param mode culling mode.
+ *
+ * \sa glCullFace().
+ *
+ * Verifies the parameter and updates gl_polygon_attrib::CullFaceMode. On
+ * change, flushes the vertices and notifies the driver via
+ * the dd_function_table::CullFace callback.
+ */
+void GLAPIENTRY
+_mesa_CullFace( GLenum mode )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (MESA_VERBOSE&VERBOSE_API)
+ _mesa_debug(ctx, "glCullFace %s\n", _mesa_lookup_enum_by_nr(mode));
+
+ if (mode!=GL_FRONT && mode!=GL_BACK && mode!=GL_FRONT_AND_BACK) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glCullFace" );
+ return;
+ }
+
+ if (ctx->Polygon.CullFaceMode == mode)
+ return;
+
+ FLUSH_VERTICES(ctx, _NEW_POLYGON);
+ ctx->Polygon.CullFaceMode = mode;
+
+ if (ctx->Driver.CullFace)
+ ctx->Driver.CullFace( ctx, mode );
+}
+
+
+/**
+ * Define front- and back-facing
+ *
+ * \param mode orientation of front-facing polygons.
+ *
+ * \sa glFrontFace().
+ *
+ * Verifies the parameter and updates gl_polygon_attrib::FrontFace. On change
+ * flushes the vertices and notifies the driver via
+ * the dd_function_table::FrontFace callback.
+ */
+void GLAPIENTRY
+_mesa_FrontFace( GLenum mode )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (MESA_VERBOSE&VERBOSE_API)
+ _mesa_debug(ctx, "glFrontFace %s\n", _mesa_lookup_enum_by_nr(mode));
+
+ if (mode!=GL_CW && mode!=GL_CCW) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glFrontFace" );
+ return;
+ }
+
+ if (ctx->Polygon.FrontFace == mode)
+ return;
+
+ FLUSH_VERTICES(ctx, _NEW_POLYGON);
+ ctx->Polygon.FrontFace = mode;
+
+ ctx->Polygon._FrontBit = (GLboolean) (mode == GL_CW);
+
+ if (ctx->Driver.FrontFace)
+ ctx->Driver.FrontFace( ctx, mode );
+}
+
+
+/**
+ * Set the polygon rasterization mode.
+ *
+ * \param face the polygons which \p mode applies to.
+ * \param mode how polygons should be rasterized.
+ *
+ * \sa glPolygonMode().
+ *
+ * Verifies the parameters and updates gl_polygon_attrib::FrontMode and
+ * gl_polygon_attrib::BackMode. On change flushes the vertices and notifies the
+ * driver via the dd_function_table::PolygonMode callback.
+ */
+void GLAPIENTRY
+_mesa_PolygonMode( GLenum face, GLenum mode )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (MESA_VERBOSE&VERBOSE_API)
+ _mesa_debug(ctx, "glPolygonMode %s %s\n",
+ _mesa_lookup_enum_by_nr(face),
+ _mesa_lookup_enum_by_nr(mode));
+
+ if (mode!=GL_POINT && mode!=GL_LINE && mode!=GL_FILL) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glPolygonMode(mode)" );
+ return;
+ }
+
+ switch (face) {
+ case GL_FRONT:
+ if (ctx->Polygon.FrontMode == mode)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_POLYGON);
+ ctx->Polygon.FrontMode = mode;
+ break;
+ case GL_FRONT_AND_BACK:
+ if (ctx->Polygon.FrontMode == mode &&
+ ctx->Polygon.BackMode == mode)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_POLYGON);
+ ctx->Polygon.FrontMode = mode;
+ ctx->Polygon.BackMode = mode;
+ break;
+ case GL_BACK:
+ if (ctx->Polygon.BackMode == mode)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_POLYGON);
+ ctx->Polygon.BackMode = mode;
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glPolygonMode(face)" );
+ return;
+ }
+
+ ctx->_TriangleCaps &= ~DD_TRI_UNFILLED;
+ if (ctx->Polygon.FrontMode!=GL_FILL || ctx->Polygon.BackMode!=GL_FILL)
+ ctx->_TriangleCaps |= DD_TRI_UNFILLED;
+
+ if (ctx->Driver.PolygonMode) {
+ (*ctx->Driver.PolygonMode)( ctx, face, mode );
+ }
+}
+
+#if _HAVE_FULL_GL
+
+
+/**
+ * This routine updates the ctx->Polygon.Stipple state.
+ * If we're getting the stipple data from a PBO, we map the buffer
+ * in order to access the data.
+ * In any case, we obey the current pixel unpacking parameters when fetching
+ * the stipple data.
+ *
+ * In the future, this routine should be used as a fallback, called via
+ * ctx->Driver.PolygonStipple(). We'll have to update all the DRI drivers
+ * too.
+ */
+void
+_mesa_polygon_stipple(GLcontext *ctx, const GLubyte *pattern)
+{
+ if (ctx->Unpack.BufferObj->Name) {
+ /* Get/unpack the stipple pattern from a PBO */
+ GLubyte *buf;
+ if (!_mesa_validate_pbo_access(2, &ctx->Unpack, 32, 32, 1,
+ GL_COLOR_INDEX, GL_BITMAP, pattern)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glPolygonStipple(bad PBO access)");
+ return;
+ }
+ buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+ GL_READ_ONLY_ARB,
+ ctx->Unpack.BufferObj);
+ if (!buf) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glPolygonStipple(PBO mapped)");
+ return;
+ }
+ buf = ADD_POINTERS(buf, pattern);
+ _mesa_unpack_polygon_stipple(buf, ctx->PolygonStipple, &ctx->Unpack);
+ ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+ ctx->Unpack.BufferObj);
+ }
+ else {
+ /* Get/unpack the stipple pattern from user memory */
+ _mesa_unpack_polygon_stipple(pattern, ctx->PolygonStipple, &ctx->Unpack);
+ }
+}
+
+
+/**
+ * Called by glPolygonStipple.
+ */
+void GLAPIENTRY
+_mesa_PolygonStipple( const GLubyte *pattern )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (MESA_VERBOSE&VERBOSE_API)
+ _mesa_debug(ctx, "glPolygonStipple\n");
+
+ FLUSH_VERTICES(ctx, _NEW_POLYGONSTIPPLE);
+
+ _mesa_polygon_stipple(ctx, pattern);
+
+ if (ctx->Driver.PolygonStipple)
+ ctx->Driver.PolygonStipple(ctx, pattern);
+}
+
+
+/**
+ * Called by glPolygonStipple.
+ */
+void GLAPIENTRY
+_mesa_GetPolygonStipple( GLubyte *dest )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (MESA_VERBOSE&VERBOSE_API)
+ _mesa_debug(ctx, "glGetPolygonStipple\n");
+
+ /* XXX someday we may put this code into a separate function and call
+ * it with ctx->Driver.GetPolygonStipple().
+ */
+ if (ctx->Pack.BufferObj->Name) {
+ /* Put/pack the stipple pattern into a PBO */
+ GLubyte *buf;
+ if (!_mesa_validate_pbo_access(2, &ctx->Pack, 32, 32, 1,
+ GL_COLOR_INDEX, GL_BITMAP, dest)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetPolygonStipple(bad PBO access)");
+ return;
+ }
+ buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
+ GL_WRITE_ONLY_ARB,
+ ctx->Pack.BufferObj);
+ if (!buf) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetPolygonStipple(PBO mapped)");
+ return;
+ }
+ buf = ADD_POINTERS(buf, dest);
+ _mesa_pack_polygon_stipple(ctx->PolygonStipple, buf, &ctx->Pack);
+ ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
+ ctx->Pack.BufferObj);
+ }
+ else {
+ /* Put/pack the stipple pattern into user memory */
+ _mesa_pack_polygon_stipple(ctx->PolygonStipple, dest, &ctx->Pack);
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_PolygonOffset( GLfloat factor, GLfloat units )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (MESA_VERBOSE&VERBOSE_API)
+ _mesa_debug(ctx, "glPolygonOffset %f %f\n", factor, units);
+
+ if (ctx->Polygon.OffsetFactor == factor &&
+ ctx->Polygon.OffsetUnits == units)
+ return;
+
+ FLUSH_VERTICES(ctx, _NEW_POLYGON);
+ ctx->Polygon.OffsetFactor = factor;
+ ctx->Polygon.OffsetUnits = units;
+
+ if (ctx->Driver.PolygonOffset)
+ ctx->Driver.PolygonOffset( ctx, factor, units );
+}
+
+
+void GLAPIENTRY
+_mesa_PolygonOffsetEXT( GLfloat factor, GLfloat bias )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ /* XXX mult by DepthMaxF here??? */
+ _mesa_PolygonOffset(factor, bias * ctx->DrawBuffer->_DepthMaxF );
+}
+
+#endif
+
+
+/**********************************************************************/
+/** \name State Management */
+/*@{*/
+
+/*
+ * Check polygon state and set DD_TRI_CULL_FRONT_BACK and/or DD_TRI_OFFSET
+ * in ctx->_TriangleCaps if needed.
+ */
+void _mesa_update_polygon( GLcontext *ctx )
+{
+ ctx->_TriangleCaps &= ~(DD_TRI_CULL_FRONT_BACK | DD_TRI_OFFSET);
+
+ if (ctx->Polygon.CullFlag && ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK)
+ ctx->_TriangleCaps |= DD_TRI_CULL_FRONT_BACK;
+
+ /* Any Polygon offsets enabled? */
+ if (ctx->Polygon.OffsetPoint ||
+ ctx->Polygon.OffsetLine ||
+ ctx->Polygon.OffsetFill) {
+ ctx->_TriangleCaps |= DD_TRI_OFFSET;
+ }
+}
+
+/*@}*/
+
+
+/**********************************************************************/
+/** \name Initialization */
+/*@{*/
+
+/**
+ * Initialize the context polygon state.
+ *
+ * \param ctx GL context.
+ *
+ * Initializes __GLcontextRec::Polygon and __GLcontextRec::PolygonStipple
+ * attribute groups.
+ */
+void _mesa_init_polygon( GLcontext * ctx )
+{
+ /* Polygon group */
+ ctx->Polygon.CullFlag = GL_FALSE;
+ ctx->Polygon.CullFaceMode = GL_BACK;
+ ctx->Polygon.FrontFace = GL_CCW;
+ ctx->Polygon._FrontBit = 0;
+ ctx->Polygon.FrontMode = GL_FILL;
+ ctx->Polygon.BackMode = GL_FILL;
+ ctx->Polygon.SmoothFlag = GL_FALSE;
+ ctx->Polygon.StippleFlag = GL_FALSE;
+ ctx->Polygon.OffsetFactor = 0.0F;
+ ctx->Polygon.OffsetUnits = 0.0F;
+ ctx->Polygon.OffsetPoint = GL_FALSE;
+ ctx->Polygon.OffsetLine = GL_FALSE;
+ ctx->Polygon.OffsetFill = GL_FALSE;
+
+
+ /* Polygon Stipple group */
+ MEMSET( ctx->PolygonStipple, 0xff, 32*sizeof(GLuint) );
+}
+
+/*@}*/
diff --git a/src/mesa/main/polygon.h b/src/mesa/main/polygon.h
new file mode 100644
index 00000000000..2550ed16877
--- /dev/null
+++ b/src/mesa/main/polygon.h
@@ -0,0 +1,69 @@
+/**
+ * \file polygon.h
+ * Polygon operations.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.3
+ *
+ * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef POLYGON_H
+#define POLYGON_H
+
+
+#include "mtypes.h"
+
+
+extern void
+_mesa_polygon_stipple(GLcontext *ctx, const GLubyte *pattern);
+
+
+extern void GLAPIENTRY
+_mesa_CullFace( GLenum mode );
+
+extern void GLAPIENTRY
+_mesa_FrontFace( GLenum mode );
+
+extern void GLAPIENTRY
+_mesa_PolygonMode( GLenum face, GLenum mode );
+
+extern void GLAPIENTRY
+_mesa_PolygonOffset( GLfloat factor, GLfloat units );
+
+extern void GLAPIENTRY
+_mesa_PolygonOffsetEXT( GLfloat factor, GLfloat bias );
+
+extern void GLAPIENTRY
+_mesa_PolygonStipple( const GLubyte *mask );
+
+extern void GLAPIENTRY
+_mesa_GetPolygonStipple( GLubyte *mask );
+
+extern void
+_mesa_update_polygon( GLcontext *ctx );
+
+extern void
+_mesa_init_polygon( GLcontext * ctx );
+
+#endif
diff --git a/src/mesa/main/rastpos.c b/src/mesa/main/rastpos.c
new file mode 100644
index 00000000000..507eb9f9843
--- /dev/null
+++ b/src/mesa/main/rastpos.c
@@ -0,0 +1,1001 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.3
+ *
+ * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/**
+ * \file rastpos.c
+ * Raster position operations.
+ */
+
+#include "glheader.h"
+#include "colormac.h"
+#include "context.h"
+#include "feedback.h"
+#include "light.h"
+#include "macros.h"
+#include "rastpos.h"
+#include "state.h"
+#include "simple_list.h"
+#include "mtypes.h"
+
+#include "math/m_matrix.h"
+
+
+/**
+ * Clip a point against the view volume.
+ *
+ * \param v vertex vector describing the point to clip.
+ *
+ * \return zero if outside view volume, or one if inside.
+ */
+static GLuint
+viewclip_point( const GLfloat v[] )
+{
+ if ( v[0] > v[3] || v[0] < -v[3]
+ || v[1] > v[3] || v[1] < -v[3]
+ || v[2] > v[3] || v[2] < -v[3] ) {
+ return 0;
+ }
+ else {
+ return 1;
+ }
+}
+
+
+/**
+ * Clip a point against the far/near Z clipping planes.
+ *
+ * \param v vertex vector describing the point to clip.
+ *
+ * \return zero if outside view volume, or one if inside.
+ */
+static GLuint
+viewclip_point_z( const GLfloat v[] )
+{
+ if (v[2] > v[3] || v[2] < -v[3] ) {
+ return 0;
+ }
+ else {
+ return 1;
+ }
+}
+
+
+/**
+ * Clip a point against the user clipping planes.
+ *
+ * \param ctx GL context.
+ * \param v vertex vector describing the point to clip.
+ *
+ * \return zero if the point was clipped, or one otherwise.
+ */
+static GLuint
+userclip_point( GLcontext *ctx, const GLfloat v[] )
+{
+ GLuint p;
+
+ for (p = 0; p < ctx->Const.MaxClipPlanes; p++) {
+ if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
+ GLfloat dot = v[0] * ctx->Transform._ClipUserPlane[p][0]
+ + v[1] * ctx->Transform._ClipUserPlane[p][1]
+ + v[2] * ctx->Transform._ClipUserPlane[p][2]
+ + v[3] * ctx->Transform._ClipUserPlane[p][3];
+ if (dot < 0.0F) {
+ return 0;
+ }
+ }
+ }
+
+ return 1;
+}
+
+
+/**
+ * This has been split off to allow the normal shade routines to
+ * get a little closer to the vertex buffer, and to use the
+ * GLvector objects directly.
+ * \param ctx the context
+ * \param vertex vertex location
+ * \param normal normal vector
+ * \param Rcolor returned color
+ * \param Rspec returned specular color (if separate specular enabled)
+ * \param Rindex returned color index
+ */
+static void
+shade_rastpos(GLcontext *ctx,
+ const GLfloat vertex[4],
+ const GLfloat normal[3],
+ GLfloat Rcolor[4],
+ GLfloat Rspec[4],
+ GLfloat *Rindex)
+{
+ GLfloat (*base)[3] = ctx->Light._BaseColor;
+ struct gl_light *light;
+ GLfloat diffuseColor[4], specularColor[4];
+ GLfloat diffuse = 0, specular = 0;
+
+ if (!ctx->_ShineTable[0] || !ctx->_ShineTable[1])
+ _mesa_validate_all_lighting_tables( ctx );
+
+ COPY_3V(diffuseColor, base[0]);
+ diffuseColor[3] = CLAMP(
+ ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3], 0.0F, 1.0F );
+ ASSIGN_4V(specularColor, 0.0, 0.0, 0.0, 0.0);
+
+ foreach (light, &ctx->Light.EnabledList) {
+ GLfloat n_dot_h;
+ GLfloat attenuation = 1.0;
+ GLfloat VP[3];
+ GLfloat n_dot_VP;
+ GLfloat *h;
+ GLfloat diffuseContrib[3], specularContrib[3];
+ GLboolean normalized;
+
+ if (!(light->_Flags & LIGHT_POSITIONAL)) {
+ COPY_3V(VP, light->_VP_inf_norm);
+ attenuation = light->_VP_inf_spot_attenuation;
+ }
+ else {
+ GLfloat d;
+
+ SUB_3V(VP, light->_Position, vertex);
+ d = (GLfloat) LEN_3FV( VP );
+
+ if ( d > 1e-6) {
+ GLfloat invd = 1.0F / d;
+ SELF_SCALE_SCALAR_3V(VP, invd);
+ }
+ attenuation = 1.0F / (light->ConstantAttenuation + d *
+ (light->LinearAttenuation + d *
+ light->QuadraticAttenuation));
+
+ if (light->_Flags & LIGHT_SPOT) {
+ GLfloat PV_dot_dir = - DOT3(VP, light->_NormDirection);
+
+ if (PV_dot_dir<light->_CosCutoff) {
+ continue;
+ }
+ else {
+ double x = PV_dot_dir * (EXP_TABLE_SIZE-1);
+ int k = (int) x;
+ GLfloat spot = (GLfloat) (light->_SpotExpTable[k][0]
+ + (x-k)*light->_SpotExpTable[k][1]);
+ attenuation *= spot;
+ }
+ }
+ }
+
+ if (attenuation < 1e-3)
+ continue;
+
+ n_dot_VP = DOT3( normal, VP );
+
+ if (n_dot_VP < 0.0F) {
+ ACC_SCALE_SCALAR_3V(diffuseColor, attenuation, light->_MatAmbient[0]);
+ continue;
+ }
+
+ COPY_3V(diffuseContrib, light->_MatAmbient[0]);
+ ACC_SCALE_SCALAR_3V(diffuseContrib, n_dot_VP, light->_MatDiffuse[0]);
+ diffuse += n_dot_VP * light->_dli * attenuation;
+ ASSIGN_3V(specularContrib, 0.0, 0.0, 0.0);
+
+ {
+ if (ctx->Light.Model.LocalViewer) {
+ GLfloat v[3];
+ COPY_3V(v, vertex);
+ NORMALIZE_3FV(v);
+ SUB_3V(VP, VP, v);
+ h = VP;
+ normalized = 0;
+ }
+ else if (light->_Flags & LIGHT_POSITIONAL) {
+ h = VP;
+ ACC_3V(h, ctx->_EyeZDir);
+ normalized = 0;
+ }
+ else {
+ h = light->_h_inf_norm;
+ normalized = 1;
+ }
+
+ n_dot_h = DOT3(normal, h);
+
+ if (n_dot_h > 0.0F) {
+ GLfloat (*mat)[4] = ctx->Light.Material.Attrib;
+ GLfloat spec_coef;
+ GLfloat shininess = mat[MAT_ATTRIB_FRONT_SHININESS][0];
+
+ if (!normalized) {
+ n_dot_h *= n_dot_h;
+ n_dot_h /= LEN_SQUARED_3FV( h );
+ shininess *= .5;
+ }
+
+ GET_SHINE_TAB_ENTRY( ctx->_ShineTable[0], n_dot_h, spec_coef );
+
+ if (spec_coef > 1.0e-10) {
+ if (ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR) {
+ ACC_SCALE_SCALAR_3V( specularContrib, spec_coef,
+ light->_MatSpecular[0]);
+ }
+ else {
+ ACC_SCALE_SCALAR_3V( diffuseContrib, spec_coef,
+ light->_MatSpecular[0]);
+ }
+ specular += spec_coef * light->_sli * attenuation;
+ }
+ }
+ }
+
+ ACC_SCALE_SCALAR_3V( diffuseColor, attenuation, diffuseContrib );
+ ACC_SCALE_SCALAR_3V( specularColor, attenuation, specularContrib );
+ }
+
+ if (ctx->Visual.rgbMode) {
+ Rcolor[0] = CLAMP(diffuseColor[0], 0.0F, 1.0F);
+ Rcolor[1] = CLAMP(diffuseColor[1], 0.0F, 1.0F);
+ Rcolor[2] = CLAMP(diffuseColor[2], 0.0F, 1.0F);
+ Rcolor[3] = CLAMP(diffuseColor[3], 0.0F, 1.0F);
+ Rspec[0] = CLAMP(specularColor[0], 0.0F, 1.0F);
+ Rspec[1] = CLAMP(specularColor[1], 0.0F, 1.0F);
+ Rspec[2] = CLAMP(specularColor[2], 0.0F, 1.0F);
+ Rspec[3] = CLAMP(specularColor[3], 0.0F, 1.0F);
+ }
+ else {
+ GLfloat *ind = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_INDEXES];
+ GLfloat d_a = ind[MAT_INDEX_DIFFUSE] - ind[MAT_INDEX_AMBIENT];
+ GLfloat s_a = ind[MAT_INDEX_SPECULAR] - ind[MAT_INDEX_AMBIENT];
+ GLfloat i = (ind[MAT_INDEX_AMBIENT]
+ + diffuse * (1.0F-specular) * d_a
+ + specular * s_a);
+ if (i > ind[MAT_INDEX_SPECULAR]) {
+ i = ind[MAT_INDEX_SPECULAR];
+ }
+ *Rindex = i;
+ }
+}
+
+
+/**
+ * Do texgen needed for glRasterPos.
+ * \param ctx rendering context
+ * \param vObj object-space vertex coordinate
+ * \param vEye eye-space vertex coordinate
+ * \param normal vertex normal
+ * \param unit texture unit number
+ * \param texcoord incoming texcoord and resulting texcoord
+ */
+static void
+compute_texgen(GLcontext *ctx, const GLfloat vObj[4], const GLfloat vEye[4],
+ const GLfloat normal[3], GLuint unit, GLfloat texcoord[4])
+{
+ const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+
+ /* always compute sphere map terms, just in case */
+ GLfloat u[3], two_nu, rx, ry, rz, m, mInv;
+ COPY_3V(u, vEye);
+ NORMALIZE_3FV(u);
+ two_nu = 2.0F * DOT3(normal, u);
+ rx = u[0] - normal[0] * two_nu;
+ ry = u[1] - normal[1] * two_nu;
+ rz = u[2] - normal[2] * two_nu;
+ m = rx * rx + ry * ry + (rz + 1.0F) * (rz + 1.0F);
+ if (m > 0.0F)
+ mInv = 0.5F * _mesa_inv_sqrtf(m);
+ else
+ mInv = 0.0F;
+
+ if (texUnit->TexGenEnabled & S_BIT) {
+ switch (texUnit->GenModeS) {
+ case GL_OBJECT_LINEAR:
+ texcoord[0] = DOT4(vObj, texUnit->ObjectPlaneS);
+ break;
+ case GL_EYE_LINEAR:
+ texcoord[0] = DOT4(vEye, texUnit->EyePlaneS);
+ break;
+ case GL_SPHERE_MAP:
+ texcoord[0] = rx * mInv + 0.5F;
+ break;
+ case GL_REFLECTION_MAP:
+ texcoord[0] = rx;
+ break;
+ case GL_NORMAL_MAP:
+ texcoord[0] = normal[0];
+ break;
+ default:
+ _mesa_problem(ctx, "Bad S texgen in compute_texgen()");
+ return;
+ }
+ }
+
+ if (texUnit->TexGenEnabled & T_BIT) {
+ switch (texUnit->GenModeT) {
+ case GL_OBJECT_LINEAR:
+ texcoord[1] = DOT4(vObj, texUnit->ObjectPlaneT);
+ break;
+ case GL_EYE_LINEAR:
+ texcoord[1] = DOT4(vEye, texUnit->EyePlaneT);
+ break;
+ case GL_SPHERE_MAP:
+ texcoord[1] = ry * mInv + 0.5F;
+ break;
+ case GL_REFLECTION_MAP:
+ texcoord[1] = ry;
+ break;
+ case GL_NORMAL_MAP:
+ texcoord[1] = normal[1];
+ break;
+ default:
+ _mesa_problem(ctx, "Bad T texgen in compute_texgen()");
+ return;
+ }
+ }
+
+ if (texUnit->TexGenEnabled & R_BIT) {
+ switch (texUnit->GenModeR) {
+ case GL_OBJECT_LINEAR:
+ texcoord[2] = DOT4(vObj, texUnit->ObjectPlaneR);
+ break;
+ case GL_EYE_LINEAR:
+ texcoord[2] = DOT4(vEye, texUnit->EyePlaneR);
+ break;
+ case GL_REFLECTION_MAP:
+ texcoord[2] = rz;
+ break;
+ case GL_NORMAL_MAP:
+ texcoord[2] = normal[2];
+ break;
+ default:
+ _mesa_problem(ctx, "Bad R texgen in compute_texgen()");
+ return;
+ }
+ }
+
+ if (texUnit->TexGenEnabled & Q_BIT) {
+ switch (texUnit->GenModeQ) {
+ case GL_OBJECT_LINEAR:
+ texcoord[3] = DOT4(vObj, texUnit->ObjectPlaneQ);
+ break;
+ case GL_EYE_LINEAR:
+ texcoord[3] = DOT4(vEye, texUnit->EyePlaneQ);
+ break;
+ default:
+ _mesa_problem(ctx, "Bad Q texgen in compute_texgen()");
+ return;
+ }
+ }
+}
+
+
+
+/**
+ * Set the raster position for pixel operations.
+ *
+ * All glRasterPos command call this function to update the current
+ * raster position.
+ *
+ * \param ctx GL context.
+ * \param x x coordinate for the raster position.
+ * \param y y coordinate for the raster position.
+ * \param z z coordinate for the raster position.
+ * \param w w coordinate for the raster position.
+ *
+ * \sa Called by _mesa_RasterPos4f().
+ *
+ * Flushes the vertices, transforms and clips the vertex coordinates, and
+ * finally sets the current raster position and associated data in
+ * __GLcontextRec::Current. When in selection mode calls
+ * _mesa_update_hitflag() with the current raster position.
+ */
+static void
+raster_pos4f(GLcontext *ctx, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+ FLUSH_CURRENT(ctx, 0);
+
+ if (ctx->NewState)
+ _mesa_update_state( ctx );
+
+ if (ctx->VertexProgram._Enabled) {
+ /* XXX implement this */
+ _mesa_problem(ctx, "Vertex programs not implemented for glRasterPos");
+ return;
+ }
+ else {
+ GLfloat obj[4], eye[4], clip[4], ndc[3], d;
+ GLfloat *norm, eyenorm[3];
+ GLfloat *objnorm = ctx->Current.Attrib[VERT_ATTRIB_NORMAL];
+
+ ASSIGN_4V( obj, x, y, z, w );
+ /* apply modelview matrix: eye = MV * obj */
+ TRANSFORM_POINT( eye, ctx->ModelviewMatrixStack.Top->m, obj );
+ /* apply projection matrix: clip = Proj * eye */
+ TRANSFORM_POINT( clip, ctx->ProjectionMatrixStack.Top->m, eye );
+
+ /* clip to view volume */
+ if (ctx->Transform.RasterPositionUnclipped) {
+ /* GL_IBM_rasterpos_clip: only clip against Z */
+ if (viewclip_point_z(clip) == 0) {
+ ctx->Current.RasterPosValid = GL_FALSE;
+ return;
+ }
+ }
+ else if (viewclip_point(clip) == 0) {
+ /* Normal OpenGL behaviour */
+ ctx->Current.RasterPosValid = GL_FALSE;
+ return;
+ }
+
+ /* clip to user clipping planes */
+ if (ctx->Transform.ClipPlanesEnabled && !userclip_point(ctx, clip)) {
+ ctx->Current.RasterPosValid = GL_FALSE;
+ return;
+ }
+
+ /* ndc = clip / W */
+ d = (clip[3] == 0.0F) ? 1.0F : 1.0F / clip[3];
+ ndc[0] = clip[0] * d;
+ ndc[1] = clip[1] * d;
+ ndc[2] = clip[2] * d;
+ /* wincoord = viewport_mapping(ndc) */
+ ctx->Current.RasterPos[0] = (ndc[0] * ctx->Viewport._WindowMap.m[MAT_SX]
+ + ctx->Viewport._WindowMap.m[MAT_TX]);
+ ctx->Current.RasterPos[1] = (ndc[1] * ctx->Viewport._WindowMap.m[MAT_SY]
+ + ctx->Viewport._WindowMap.m[MAT_TY]);
+ ctx->Current.RasterPos[2] = (ndc[2] * ctx->Viewport._WindowMap.m[MAT_SZ]
+ + ctx->Viewport._WindowMap.m[MAT_TZ])
+ / ctx->DrawBuffer->_DepthMaxF;
+ ctx->Current.RasterPos[3] = clip[3];
+
+ /* compute raster distance */
+ if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT)
+ ctx->Current.RasterDistance = ctx->Current.Attrib[VERT_ATTRIB_FOG][0];
+ else
+ ctx->Current.RasterDistance =
+ SQRTF( eye[0]*eye[0] + eye[1]*eye[1] + eye[2]*eye[2] );
+
+ /* compute transformed normal vector (for lighting or texgen) */
+ if (ctx->_NeedEyeCoords) {
+ const GLfloat *inv = ctx->ModelviewMatrixStack.Top->inv;
+ TRANSFORM_NORMAL( eyenorm, objnorm, inv );
+ norm = eyenorm;
+ }
+ else {
+ norm = objnorm;
+ }
+
+ /* update raster color */
+ if (ctx->Light.Enabled) {
+ /* lighting */
+ shade_rastpos( ctx, obj, norm,
+ ctx->Current.RasterColor,
+ ctx->Current.RasterSecondaryColor,
+ &ctx->Current.RasterIndex );
+ }
+ else {
+ /* use current color or index */
+ if (ctx->Visual.rgbMode) {
+ COPY_4FV(ctx->Current.RasterColor,
+ ctx->Current.Attrib[VERT_ATTRIB_COLOR0]);
+ COPY_4FV(ctx->Current.RasterSecondaryColor,
+ ctx->Current.Attrib[VERT_ATTRIB_COLOR1]);
+ }
+ else {
+ ctx->Current.RasterIndex = ctx->Current.Index;
+ }
+ }
+
+ /* texture coords */
+ {
+ GLuint u;
+ for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) {
+ GLfloat tc[4];
+ COPY_4V(tc, ctx->Current.Attrib[VERT_ATTRIB_TEX0 + u]);
+ if (ctx->Texture.Unit[u].TexGenEnabled) {
+ compute_texgen(ctx, obj, eye, norm, u, tc);
+ }
+ TRANSFORM_POINT(ctx->Current.RasterTexCoords[u],
+ ctx->TextureMatrixStack[u].Top->m, tc);
+ }
+ }
+
+ ctx->Current.RasterPosValid = GL_TRUE;
+ }
+
+ if (ctx->RenderMode == GL_SELECT) {
+ _mesa_update_hitflag( ctx, ctx->Current.RasterPos[2] );
+ }
+}
+
+
+/** Calls _mesa_RasterPos4f() */
+void GLAPIENTRY
+_mesa_RasterPos2d(GLdouble x, GLdouble y)
+{
+ _mesa_RasterPos4f((GLfloat) x, (GLfloat) y, 0.0F, 1.0F);
+}
+
+/** Calls _mesa_RasterPos4f() */
+void GLAPIENTRY
+_mesa_RasterPos2f(GLfloat x, GLfloat y)
+{
+ _mesa_RasterPos4f(x, y, 0.0F, 1.0F);
+}
+
+/** Calls _mesa_RasterPos4f() */
+void GLAPIENTRY
+_mesa_RasterPos2i(GLint x, GLint y)
+{
+ _mesa_RasterPos4f((GLfloat) x, (GLfloat) y, 0.0F, 1.0F);
+}
+
+/** Calls _mesa_RasterPos4f() */
+void GLAPIENTRY
+_mesa_RasterPos2s(GLshort x, GLshort y)
+{
+ _mesa_RasterPos4f(x, y, 0.0F, 1.0F);
+}
+
+/** Calls _mesa_RasterPos4f() */
+void GLAPIENTRY
+_mesa_RasterPos3d(GLdouble x, GLdouble y, GLdouble z)
+{
+ _mesa_RasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F);
+}
+
+/** Calls _mesa_RasterPos4f() */
+void GLAPIENTRY
+_mesa_RasterPos3f(GLfloat x, GLfloat y, GLfloat z)
+{
+ _mesa_RasterPos4f(x, y, z, 1.0F);
+}
+
+/** Calls _mesa_RasterPos4f() */
+void GLAPIENTRY
+_mesa_RasterPos3i(GLint x, GLint y, GLint z)
+{
+ _mesa_RasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F);
+}
+
+/** Calls _mesa_RasterPos4f() */
+void GLAPIENTRY
+_mesa_RasterPos3s(GLshort x, GLshort y, GLshort z)
+{
+ _mesa_RasterPos4f(x, y, z, 1.0F);
+}
+
+/** Calls _mesa_RasterPos4f() */
+void GLAPIENTRY
+_mesa_RasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
+{
+ _mesa_RasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
+}
+
+/** Calls raster_pos4f() */
+void GLAPIENTRY
+_mesa_RasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ raster_pos4f(ctx, x, y, z, w);
+}
+
+/** Calls _mesa_RasterPos4f() */
+void GLAPIENTRY
+_mesa_RasterPos4i(GLint x, GLint y, GLint z, GLint w)
+{
+ _mesa_RasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
+}
+
+/** Calls _mesa_RasterPos4f() */
+void GLAPIENTRY
+_mesa_RasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w)
+{
+ _mesa_RasterPos4f(x, y, z, w);
+}
+
+/** Calls _mesa_RasterPos4f() */
+void GLAPIENTRY
+_mesa_RasterPos2dv(const GLdouble *v)
+{
+ _mesa_RasterPos4f((GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F);
+}
+
+/** Calls _mesa_RasterPos4f() */
+void GLAPIENTRY
+_mesa_RasterPos2fv(const GLfloat *v)
+{
+ _mesa_RasterPos4f(v[0], v[1], 0.0F, 1.0F);
+}
+
+/** Calls _mesa_RasterPos4f() */
+void GLAPIENTRY
+_mesa_RasterPos2iv(const GLint *v)
+{
+ _mesa_RasterPos4f((GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F);
+}
+
+/** Calls _mesa_RasterPos4f() */
+void GLAPIENTRY
+_mesa_RasterPos2sv(const GLshort *v)
+{
+ _mesa_RasterPos4f(v[0], v[1], 0.0F, 1.0F);
+}
+
+/** Calls _mesa_RasterPos4f() */
+void GLAPIENTRY
+_mesa_RasterPos3dv(const GLdouble *v)
+{
+ _mesa_RasterPos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F);
+}
+
+/** Calls _mesa_RasterPos4f() */
+void GLAPIENTRY
+_mesa_RasterPos3fv(const GLfloat *v)
+{
+ _mesa_RasterPos4f(v[0], v[1], v[2], 1.0F);
+}
+
+/** Calls _mesa_RasterPos4f() */
+void GLAPIENTRY
+_mesa_RasterPos3iv(const GLint *v)
+{
+ _mesa_RasterPos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F);
+}
+
+/** Calls _mesa_RasterPos4f() */
+void GLAPIENTRY
+_mesa_RasterPos3sv(const GLshort *v)
+{
+ _mesa_RasterPos4f(v[0], v[1], v[2], 1.0F);
+}
+
+/** Calls _mesa_RasterPos4f() */
+void GLAPIENTRY
+_mesa_RasterPos4dv(const GLdouble *v)
+{
+ _mesa_RasterPos4f((GLfloat) v[0], (GLfloat) v[1],
+ (GLfloat) v[2], (GLfloat) v[3]);
+}
+
+/** Calls _mesa_RasterPos4f() */
+void GLAPIENTRY
+_mesa_RasterPos4fv(const GLfloat *v)
+{
+ _mesa_RasterPos4f(v[0], v[1], v[2], v[3]);
+}
+
+/** Calls _mesa_RasterPos4f() */
+void GLAPIENTRY
+_mesa_RasterPos4iv(const GLint *v)
+{
+ _mesa_RasterPos4f((GLfloat) v[0], (GLfloat) v[1],
+ (GLfloat) v[2], (GLfloat) v[3]);
+}
+
+/** Calls _mesa_RasterPos4f() */
+void GLAPIENTRY
+_mesa_RasterPos4sv(const GLshort *v)
+{
+ _mesa_RasterPos4f(v[0], v[1], v[2], v[3]);
+}
+
+
+/**********************************************************************/
+/*** GL_ARB_window_pos / GL_MESA_window_pos ***/
+/**********************************************************************/
+
+#if FEATURE_windowpos
+/**
+ * All glWindowPosMESA and glWindowPosARB commands call this function to
+ * update the current raster position.
+ */
+static void
+window_pos3f(GLfloat x, GLfloat y, GLfloat z)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLfloat z2;
+
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+ FLUSH_CURRENT(ctx, 0);
+
+ z2 = CLAMP(z, 0.0F, 1.0F) * (ctx->Viewport.Far - ctx->Viewport.Near)
+ + ctx->Viewport.Near;
+
+ /* set raster position */
+ ctx->Current.RasterPos[0] = x;
+ ctx->Current.RasterPos[1] = y;
+ ctx->Current.RasterPos[2] = z2;
+ ctx->Current.RasterPos[3] = 1.0F;
+
+ ctx->Current.RasterPosValid = GL_TRUE;
+
+ if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT)
+ ctx->Current.RasterDistance = ctx->Current.Attrib[VERT_ATTRIB_FOG][0];
+ else
+ ctx->Current.RasterDistance = 0.0;
+
+ /* raster color = current color or index */
+ if (ctx->Visual.rgbMode) {
+ ctx->Current.RasterColor[0]
+ = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0], 0.0F, 1.0F);
+ ctx->Current.RasterColor[1]
+ = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1], 0.0F, 1.0F);
+ ctx->Current.RasterColor[2]
+ = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2], 0.0F, 1.0F);
+ ctx->Current.RasterColor[3]
+ = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3], 0.0F, 1.0F);
+ ctx->Current.RasterSecondaryColor[0]
+ = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0], 0.0F, 1.0F);
+ ctx->Current.RasterSecondaryColor[1]
+ = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1], 0.0F, 1.0F);
+ ctx->Current.RasterSecondaryColor[2]
+ = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2], 0.0F, 1.0F);
+ ctx->Current.RasterSecondaryColor[3]
+ = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][3], 0.0F, 1.0F);
+ }
+ else {
+ ctx->Current.RasterIndex = ctx->Current.Index;
+ }
+
+ /* raster texcoord = current texcoord */
+ {
+ GLuint texSet;
+ for (texSet = 0; texSet < ctx->Const.MaxTextureCoordUnits; texSet++) {
+ COPY_4FV( ctx->Current.RasterTexCoords[texSet],
+ ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texSet] );
+ }
+ }
+
+ if (ctx->RenderMode==GL_SELECT) {
+ _mesa_update_hitflag( ctx, ctx->Current.RasterPos[2] );
+ }
+}
+
+
+/* This is just to support the GL_MESA_window_pos version */
+static void
+window_pos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ window_pos3f(x, y, z);
+ ctx->Current.RasterPos[3] = w;
+}
+
+
+void GLAPIENTRY
+_mesa_WindowPos2dMESA(GLdouble x, GLdouble y)
+{
+ window_pos4f((GLfloat) x, (GLfloat) y, 0.0F, 1.0F);
+}
+
+void GLAPIENTRY
+_mesa_WindowPos2fMESA(GLfloat x, GLfloat y)
+{
+ window_pos4f(x, y, 0.0F, 1.0F);
+}
+
+void GLAPIENTRY
+_mesa_WindowPos2iMESA(GLint x, GLint y)
+{
+ window_pos4f((GLfloat) x, (GLfloat) y, 0.0F, 1.0F);
+}
+
+void GLAPIENTRY
+_mesa_WindowPos2sMESA(GLshort x, GLshort y)
+{
+ window_pos4f(x, y, 0.0F, 1.0F);
+}
+
+void GLAPIENTRY
+_mesa_WindowPos3dMESA(GLdouble x, GLdouble y, GLdouble z)
+{
+ window_pos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F);
+}
+
+void GLAPIENTRY
+_mesa_WindowPos3fMESA(GLfloat x, GLfloat y, GLfloat z)
+{
+ window_pos4f(x, y, z, 1.0F);
+}
+
+void GLAPIENTRY
+_mesa_WindowPos3iMESA(GLint x, GLint y, GLint z)
+{
+ window_pos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F);
+}
+
+void GLAPIENTRY
+_mesa_WindowPos3sMESA(GLshort x, GLshort y, GLshort z)
+{
+ window_pos4f(x, y, z, 1.0F);
+}
+
+void GLAPIENTRY
+_mesa_WindowPos4dMESA(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
+{
+ window_pos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
+}
+
+void GLAPIENTRY
+_mesa_WindowPos4fMESA(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ window_pos4f(x, y, z, w);
+}
+
+void GLAPIENTRY
+_mesa_WindowPos4iMESA(GLint x, GLint y, GLint z, GLint w)
+{
+ window_pos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
+}
+
+void GLAPIENTRY
+_mesa_WindowPos4sMESA(GLshort x, GLshort y, GLshort z, GLshort w)
+{
+ window_pos4f(x, y, z, w);
+}
+
+void GLAPIENTRY
+_mesa_WindowPos2dvMESA(const GLdouble *v)
+{
+ window_pos4f((GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F);
+}
+
+void GLAPIENTRY
+_mesa_WindowPos2fvMESA(const GLfloat *v)
+{
+ window_pos4f(v[0], v[1], 0.0F, 1.0F);
+}
+
+void GLAPIENTRY
+_mesa_WindowPos2ivMESA(const GLint *v)
+{
+ window_pos4f((GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F);
+}
+
+void GLAPIENTRY
+_mesa_WindowPos2svMESA(const GLshort *v)
+{
+ window_pos4f(v[0], v[1], 0.0F, 1.0F);
+}
+
+void GLAPIENTRY
+_mesa_WindowPos3dvMESA(const GLdouble *v)
+{
+ window_pos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F);
+}
+
+void GLAPIENTRY
+_mesa_WindowPos3fvMESA(const GLfloat *v)
+{
+ window_pos4f(v[0], v[1], v[2], 1.0);
+}
+
+void GLAPIENTRY
+_mesa_WindowPos3ivMESA(const GLint *v)
+{
+ window_pos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F);
+}
+
+void GLAPIENTRY
+_mesa_WindowPos3svMESA(const GLshort *v)
+{
+ window_pos4f(v[0], v[1], v[2], 1.0F);
+}
+
+void GLAPIENTRY
+_mesa_WindowPos4dvMESA(const GLdouble *v)
+{
+ window_pos4f((GLfloat) v[0], (GLfloat) v[1],
+ (GLfloat) v[2], (GLfloat) v[3]);
+}
+
+void GLAPIENTRY
+_mesa_WindowPos4fvMESA(const GLfloat *v)
+{
+ window_pos4f(v[0], v[1], v[2], v[3]);
+}
+
+void GLAPIENTRY
+_mesa_WindowPos4ivMESA(const GLint *v)
+{
+ window_pos4f((GLfloat) v[0], (GLfloat) v[1],
+ (GLfloat) v[2], (GLfloat) v[3]);
+}
+
+void GLAPIENTRY
+_mesa_WindowPos4svMESA(const GLshort *v)
+{
+ window_pos4f(v[0], v[1], v[2], v[3]);
+}
+
+#endif
+
+#if 0
+
+/*
+ * OpenGL implementation of glWindowPos*MESA()
+ */
+void glWindowPos4fMESA( GLfloat x, GLfloat y, GLfloat z, GLfloat w )
+{
+ GLfloat fx, fy;
+
+ /* Push current matrix mode and viewport attributes */
+ glPushAttrib( GL_TRANSFORM_BIT | GL_VIEWPORT_BIT );
+
+ /* Setup projection parameters */
+ glMatrixMode( GL_PROJECTION );
+ glPushMatrix();
+ glLoadIdentity();
+ glMatrixMode( GL_MODELVIEW );
+ glPushMatrix();
+ glLoadIdentity();
+
+ glDepthRange( z, z );
+ glViewport( (int) x - 1, (int) y - 1, 2, 2 );
+
+ /* set the raster (window) position */
+ fx = x - (int) x;
+ fy = y - (int) y;
+ glRasterPos4f( fx, fy, 0.0, w );
+
+ /* restore matrices, viewport and matrix mode */
+ glPopMatrix();
+ glMatrixMode( GL_PROJECTION );
+ glPopMatrix();
+
+ glPopAttrib();
+}
+
+#endif
+
+
+/**********************************************************************/
+/** \name Initialization */
+/**********************************************************************/
+/*@{*/
+
+/**
+ * Initialize the context current raster position information.
+ *
+ * \param ctx GL context.
+ *
+ * Initialize the current raster position information in
+ * __GLcontextRec::Current, and adds the extension entry points to the
+ * dispatcher.
+ */
+void _mesa_init_rastpos( GLcontext * ctx )
+{
+ int i;
+
+ ASSIGN_4V( ctx->Current.RasterPos, 0.0, 0.0, 0.0, 1.0 );
+ ctx->Current.RasterDistance = 0.0;
+ ASSIGN_4V( ctx->Current.RasterColor, 1.0, 1.0, 1.0, 1.0 );
+ ctx->Current.RasterIndex = 1.0;
+ for (i=0; i<MAX_TEXTURE_UNITS; i++)
+ ASSIGN_4V( ctx->Current.RasterTexCoords[i], 0.0, 0.0, 0.0, 1.0 );
+ ctx->Current.RasterPosValid = GL_TRUE;
+}
+
+/*@}*/
diff --git a/src/mesa/main/rastpos.h b/src/mesa/main/rastpos.h
new file mode 100644
index 00000000000..363f86ad87b
--- /dev/null
+++ b/src/mesa/main/rastpos.h
@@ -0,0 +1,193 @@
+/**
+ * \file rastpos.h
+ * Raster position operations.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 4.1
+ *
+ * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef RASTPOS_H
+#define RASTPOS_H
+
+
+#include "glheader.h"
+
+
+extern void GLAPIENTRY
+_mesa_RasterPos2d(GLdouble x, GLdouble y);
+
+extern void GLAPIENTRY
+_mesa_RasterPos2f(GLfloat x, GLfloat y);
+
+extern void GLAPIENTRY
+_mesa_RasterPos2i(GLint x, GLint y);
+
+extern void GLAPIENTRY
+_mesa_RasterPos2s(GLshort x, GLshort y);
+
+extern void GLAPIENTRY
+_mesa_RasterPos3d(GLdouble x, GLdouble y, GLdouble z);
+
+extern void GLAPIENTRY
+_mesa_RasterPos3f(GLfloat x, GLfloat y, GLfloat z);
+
+extern void GLAPIENTRY
+_mesa_RasterPos3i(GLint x, GLint y, GLint z);
+
+extern void GLAPIENTRY
+_mesa_RasterPos3s(GLshort x, GLshort y, GLshort z);
+
+extern void GLAPIENTRY
+_mesa_RasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+
+extern void GLAPIENTRY
+_mesa_RasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+
+extern void GLAPIENTRY
+_mesa_RasterPos4i(GLint x, GLint y, GLint z, GLint w);
+
+extern void GLAPIENTRY
+_mesa_RasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w);
+
+extern void GLAPIENTRY
+_mesa_RasterPos2dv(const GLdouble *v);
+
+extern void GLAPIENTRY
+_mesa_RasterPos2fv(const GLfloat *v);
+
+extern void GLAPIENTRY
+_mesa_RasterPos2iv(const GLint *v);
+
+extern void GLAPIENTRY
+_mesa_RasterPos2sv(const GLshort *v);
+
+extern void GLAPIENTRY
+_mesa_RasterPos3dv(const GLdouble *v);
+
+extern void GLAPIENTRY
+_mesa_RasterPos3fv(const GLfloat *v);
+
+extern void GLAPIENTRY
+_mesa_RasterPos3iv(const GLint *v);
+
+extern void GLAPIENTRY
+_mesa_RasterPos3sv(const GLshort *v);
+
+extern void GLAPIENTRY
+_mesa_RasterPos4dv(const GLdouble *v);
+
+extern void GLAPIENTRY
+_mesa_RasterPos4fv(const GLfloat *v);
+
+extern void GLAPIENTRY
+_mesa_RasterPos4iv(const GLint *v);
+
+extern void GLAPIENTRY
+_mesa_RasterPos4sv(const GLshort *v);
+
+
+/**********************************************************************/
+/** \name GL_MESA_window_pos */
+/**********************************************************************/
+/*@{*/
+
+extern void GLAPIENTRY
+_mesa_WindowPos2dMESA(GLdouble x, GLdouble y);
+
+extern void GLAPIENTRY
+_mesa_WindowPos2fMESA(GLfloat x, GLfloat y);
+
+extern void GLAPIENTRY
+_mesa_WindowPos2iMESA(GLint x, GLint y);
+
+extern void GLAPIENTRY
+_mesa_WindowPos2sMESA(GLshort x, GLshort y);
+
+extern void GLAPIENTRY
+_mesa_WindowPos3dMESA(GLdouble x, GLdouble y, GLdouble z);
+
+extern void GLAPIENTRY
+_mesa_WindowPos3fMESA(GLfloat x, GLfloat y, GLfloat z);
+
+extern void GLAPIENTRY
+_mesa_WindowPos3iMESA(GLint x, GLint y, GLint z);
+
+extern void GLAPIENTRY
+_mesa_WindowPos3sMESA(GLshort x, GLshort y, GLshort z);
+
+extern void GLAPIENTRY
+_mesa_WindowPos4dMESA(GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+
+extern void GLAPIENTRY
+_mesa_WindowPos4fMESA(GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+
+extern void GLAPIENTRY
+_mesa_WindowPos4iMESA(GLint x, GLint y, GLint z, GLint w);
+
+extern void GLAPIENTRY
+_mesa_WindowPos4sMESA(GLshort x, GLshort y, GLshort z, GLshort w);
+
+extern void GLAPIENTRY
+_mesa_WindowPos2dvMESA(const GLdouble *v);
+
+extern void GLAPIENTRY
+_mesa_WindowPos2fvMESA(const GLfloat *v);
+
+extern void GLAPIENTRY
+_mesa_WindowPos2ivMESA(const GLint *v);
+
+extern void GLAPIENTRY
+_mesa_WindowPos2svMESA(const GLshort *v);
+
+extern void GLAPIENTRY
+_mesa_WindowPos3dvMESA(const GLdouble *v);
+
+extern void GLAPIENTRY
+_mesa_WindowPos3fvMESA(const GLfloat *v);
+
+extern void GLAPIENTRY
+_mesa_WindowPos3ivMESA(const GLint *v);
+
+extern void GLAPIENTRY
+_mesa_WindowPos3svMESA(const GLshort *v);
+
+extern void GLAPIENTRY
+_mesa_WindowPos4dvMESA(const GLdouble *v);
+
+extern void GLAPIENTRY
+_mesa_WindowPos4fvMESA(const GLfloat *v);
+
+extern void GLAPIENTRY
+_mesa_WindowPos4ivMESA(const GLint *v);
+
+extern void GLAPIENTRY
+_mesa_WindowPos4svMESA(const GLshort *v);
+
+extern void
+_mesa_init_rastpos( GLcontext * ctx );
+
+/*@}*/
+
+#endif
diff --git a/src/mesa/main/renderbuffer.c b/src/mesa/main/renderbuffer.c
new file mode 100644
index 00000000000..aa14bf8634a
--- /dev/null
+++ b/src/mesa/main/renderbuffer.c
@@ -0,0 +1,2073 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/**
+ * Functions for allocating/managing renderbuffers.
+ * Also, routines for reading/writing software-based renderbuffer data as
+ * ubytes, ushorts, uints, etc.
+ *
+ * The 'alpha8' renderbuffer is interesting. It's used to add a software-based
+ * alpha channel to RGB renderbuffers. This is done by wrapping the RGB
+ * renderbuffer with the alpha renderbuffer. We can do this because of the
+ * OO-nature of renderbuffers.
+ *
+ * Down the road we'll use this for run-time support of 8, 16 and 32-bit
+ * color channels. For example, Mesa may use 32-bit/float color channels
+ * internally (swrast) and use wrapper renderbuffers to convert 32-bit
+ * values down to 16 or 8-bit values for whatever kind of framebuffer we have.
+ */
+
+
+#include "glheader.h"
+#include "imports.h"
+#include "context.h"
+#include "mtypes.h"
+#include "fbobject.h"
+#include "renderbuffer.h"
+
+
+/* 32-bit color index format. Not a public format. */
+#define COLOR_INDEX32 0x424243
+
+
+/*
+ * Routines for get/put values in common buffer formats follow.
+ * Someday add support for arbitrary row stride to make them more
+ * flexible.
+ */
+
+/**********************************************************************
+ * Functions for buffers of 1 X GLubyte values.
+ * Typically stencil.
+ */
+
+static void *
+get_pointer_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb,
+ GLint x, GLint y)
+{
+ if (!rb->Data)
+ return NULL;
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
+ /* Can't assert _ActualFormat since these funcs may be used for serveral
+ * different formats (GL_ALPHA8, GL_STENCIL_INDEX8, etc).
+ */
+ return (GLubyte *) rb->Data + y * rb->Width + x;
+}
+
+
+static void
+get_row_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ GLint x, GLint y, void *values)
+{
+ const GLubyte *src = (const GLubyte *) rb->Data + y * rb->Width + x;
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
+ _mesa_memcpy(values, src, count * sizeof(GLubyte));
+}
+
+
+static void
+get_values_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ const GLint x[], const GLint y[], void *values)
+{
+ GLubyte *dst = (GLubyte *) values;
+ GLuint i;
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
+ for (i = 0; i < count; i++) {
+ const GLubyte *src = (GLubyte *) rb->Data + y[i] * rb->Width + x[i];
+ dst[i] = *src;
+ }
+}
+
+
+static void
+put_row_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ GLint x, GLint y, const void *values, const GLubyte *mask)
+{
+ const GLubyte *src = (const GLubyte *) values;
+ GLubyte *dst = (GLubyte *) rb->Data + y * rb->Width + x;
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
+ if (mask) {
+ GLuint i;
+ for (i = 0; i < count; i++) {
+ if (mask[i]) {
+ dst[i] = src[i];
+ }
+ }
+ }
+ else {
+ _mesa_memcpy(dst, values, count * sizeof(GLubyte));
+ }
+}
+
+
+static void
+put_mono_row_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ GLint x, GLint y, const void *value, const GLubyte *mask)
+{
+ const GLubyte val = *((const GLubyte *) value);
+ GLubyte *dst = (GLubyte *) rb->Data + y * rb->Width + x;
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
+ if (mask) {
+ GLuint i;
+ for (i = 0; i < count; i++) {
+ if (mask[i]) {
+ dst[i] = val;
+ }
+ }
+ }
+ else {
+ GLuint i;
+ for (i = 0; i < count; i++) {
+ dst[i] = val;
+ }
+ }
+}
+
+
+static void
+put_values_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ const GLint x[], const GLint y[],
+ const void *values, const GLubyte *mask)
+{
+ const GLubyte *src = (const GLubyte *) values;
+ GLuint i;
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->Width + x[i];
+ *dst = src[i];
+ }
+ }
+}
+
+
+static void
+put_mono_values_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ const GLint x[], const GLint y[],
+ const void *value, const GLubyte *mask)
+{
+ const GLubyte val = *((const GLubyte *) value);
+ GLuint i;
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->Width + x[i];
+ *dst = val;
+ }
+ }
+}
+
+
+/**********************************************************************
+ * Functions for buffers of 1 X GLushort values.
+ * Typically depth/Z.
+ */
+
+static void *
+get_pointer_ushort(GLcontext *ctx, struct gl_renderbuffer *rb,
+ GLint x, GLint y)
+{
+ if (!rb->Data)
+ return NULL;
+ ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
+ ASSERT(rb->Width > 0);
+ return (GLushort *) rb->Data + y * rb->Width + x;
+}
+
+
+static void
+get_row_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ GLint x, GLint y, void *values)
+{
+ const void *src = rb->GetPointer(ctx, rb, x, y);
+ ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
+ _mesa_memcpy(values, src, count * sizeof(GLushort));
+}
+
+
+static void
+get_values_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ const GLint x[], const GLint y[], void *values)
+{
+ GLushort *dst = (GLushort *) values;
+ GLuint i;
+ ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
+ for (i = 0; i < count; i++) {
+ const GLushort *src = (GLushort *) rb->Data + y[i] * rb->Width + x[i];
+ dst[i] = *src;
+ }
+}
+
+
+static void
+put_row_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ GLint x, GLint y, const void *values, const GLubyte *mask)
+{
+ const GLushort *src = (const GLushort *) values;
+ GLushort *dst = (GLushort *) rb->Data + y * rb->Width + x;
+ ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
+ if (mask) {
+ GLuint i;
+ for (i = 0; i < count; i++) {
+ if (mask[i]) {
+ dst[i] = src[i];
+ }
+ }
+ }
+ else {
+ _mesa_memcpy(dst, src, count * sizeof(GLushort));
+ }
+}
+
+
+static void
+put_mono_row_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ GLint x, GLint y, const void *value, const GLubyte *mask)
+{
+ const GLushort val = *((const GLushort *) value);
+ GLushort *dst = (GLushort *) rb->Data + y * rb->Width + x;
+ ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
+ if (mask) {
+ GLuint i;
+ for (i = 0; i < count; i++) {
+ if (mask[i]) {
+ dst[i] = val;
+ }
+ }
+ }
+ else {
+ GLuint i;
+ for (i = 0; i < count; i++) {
+ dst[i] = val;
+ }
+ }
+}
+
+
+static void
+put_values_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ const GLint x[], const GLint y[], const void *values,
+ const GLubyte *mask)
+{
+ const GLushort *src = (const GLushort *) values;
+ GLuint i;
+ ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ GLushort *dst = (GLushort *) rb->Data + y[i] * rb->Width + x[i];
+ *dst = src[i];
+ }
+ }
+}
+
+
+static void
+put_mono_values_ushort(GLcontext *ctx, struct gl_renderbuffer *rb,
+ GLuint count, const GLint x[], const GLint y[],
+ const void *value, const GLubyte *mask)
+{
+ const GLushort val = *((const GLushort *) value);
+ ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
+ if (mask) {
+ GLuint i;
+ for (i = 0; i < count; i++) {
+ if (mask[i]) {
+ GLushort *dst = (GLushort *) rb->Data + y[i] * rb->Width + x[i];
+ *dst = val;
+ }
+ }
+ }
+ else {
+ GLuint i;
+ for (i = 0; i < count; i++) {
+ GLushort *dst = (GLushort *) rb->Data + y[i] * rb->Width + x[i];
+ *dst = val;
+ }
+ }
+}
+
+
+/**********************************************************************
+ * Functions for buffers of 1 X GLuint values.
+ * Typically depth/Z or color index.
+ */
+
+static void *
+get_pointer_uint(GLcontext *ctx, struct gl_renderbuffer *rb,
+ GLint x, GLint y)
+{
+ if (!rb->Data)
+ return NULL;
+ ASSERT(rb->DataType == GL_UNSIGNED_INT ||
+ rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
+ return (GLuint *) rb->Data + y * rb->Width + x;
+}
+
+
+static void
+get_row_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ GLint x, GLint y, void *values)
+{
+ const void *src = rb->GetPointer(ctx, rb, x, y);
+ ASSERT(rb->DataType == GL_UNSIGNED_INT ||
+ rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
+ _mesa_memcpy(values, src, count * sizeof(GLuint));
+}
+
+
+static void
+get_values_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ const GLint x[], const GLint y[], void *values)
+{
+ GLuint *dst = (GLuint *) values;
+ GLuint i;
+ ASSERT(rb->DataType == GL_UNSIGNED_INT ||
+ rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
+ for (i = 0; i < count; i++) {
+ const GLuint *src = (GLuint *) rb->Data + y[i] * rb->Width + x[i];
+ dst[i] = *src;
+ }
+}
+
+
+static void
+put_row_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ GLint x, GLint y, const void *values, const GLubyte *mask)
+{
+ const GLuint *src = (const GLuint *) values;
+ GLuint *dst = (GLuint *) rb->Data + y * rb->Width + x;
+ ASSERT(rb->DataType == GL_UNSIGNED_INT ||
+ rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
+ if (mask) {
+ GLuint i;
+ for (i = 0; i < count; i++) {
+ if (mask[i]) {
+ dst[i] = src[i];
+ }
+ }
+ }
+ else {
+ _mesa_memcpy(dst, src, count * sizeof(GLuint));
+ }
+}
+
+
+static void
+put_mono_row_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ GLint x, GLint y, const void *value, const GLubyte *mask)
+{
+ const GLuint val = *((const GLuint *) value);
+ GLuint *dst = (GLuint *) rb->Data + y * rb->Width + x;
+ ASSERT(rb->DataType == GL_UNSIGNED_INT ||
+ rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
+ if (mask) {
+ GLuint i;
+ for (i = 0; i < count; i++) {
+ if (mask[i]) {
+ dst[i] = val;
+ }
+ }
+ }
+ else {
+ GLuint i;
+ for (i = 0; i < count; i++) {
+ dst[i] = val;
+ }
+ }
+}
+
+
+static void
+put_values_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ const GLint x[], const GLint y[], const void *values,
+ const GLubyte *mask)
+{
+ const GLuint *src = (const GLuint *) values;
+ GLuint i;
+ ASSERT(rb->DataType == GL_UNSIGNED_INT ||
+ rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ GLuint *dst = (GLuint *) rb->Data + y[i] * rb->Width + x[i];
+ *dst = src[i];
+ }
+ }
+}
+
+
+static void
+put_mono_values_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ const GLint x[], const GLint y[], const void *value,
+ const GLubyte *mask)
+{
+ const GLuint val = *((const GLuint *) value);
+ GLuint i;
+ ASSERT(rb->DataType == GL_UNSIGNED_INT ||
+ rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ GLuint *dst = (GLuint *) rb->Data + y[i] * rb->Width + x[i];
+ *dst = val;
+ }
+ }
+}
+
+
+/**********************************************************************
+ * Functions for buffers of 3 X GLubyte (or GLbyte) values.
+ * Typically color buffers.
+ * NOTE: the incoming and outgoing colors are RGBA! We ignore incoming
+ * alpha values and return 255 for outgoing alpha values.
+ */
+
+static void *
+get_pointer_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb,
+ GLint x, GLint y)
+{
+ ASSERT(rb->_ActualFormat == GL_RGB8);
+ /* No direct access since this buffer is RGB but caller will be
+ * treating it as if it were RGBA.
+ */
+ return NULL;
+}
+
+
+static void
+get_row_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ GLint x, GLint y, void *values)
+{
+ const GLubyte *src = (const GLubyte *) rb->Data + 3 * (y * rb->Width + x);
+ GLubyte *dst = (GLubyte *) values;
+ GLuint i;
+ ASSERT(rb->_ActualFormat == GL_RGB8);
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
+ for (i = 0; i < count; i++) {
+ dst[i * 4 + 0] = src[i * 3 + 0];
+ dst[i * 4 + 1] = src[i * 3 + 1];
+ dst[i * 4 + 2] = src[i * 3 + 2];
+ dst[i * 4 + 3] = 255;
+ }
+}
+
+
+static void
+get_values_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ const GLint x[], const GLint y[], void *values)
+{
+ GLubyte *dst = (GLubyte *) values;
+ GLuint i;
+ ASSERT(rb->_ActualFormat == GL_RGB8);
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
+ for (i = 0; i < count; i++) {
+ const GLubyte *src
+ = (GLubyte *) rb->Data + 3 * (y[i] * rb->Width + x[i]);
+ dst[i * 4 + 0] = src[0];
+ dst[i * 4 + 1] = src[1];
+ dst[i * 4 + 2] = src[2];
+ dst[i * 4 + 3] = 255;
+ }
+}
+
+
+static void
+put_row_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ GLint x, GLint y, const void *values, const GLubyte *mask)
+{
+ /* note: incoming values are RGB+A! */
+ const GLubyte *src = (const GLubyte *) values;
+ GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->Width + x);
+ GLuint i;
+ ASSERT(rb->_ActualFormat == GL_RGB8);
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ dst[i * 3 + 0] = src[i * 4 + 0];
+ dst[i * 3 + 1] = src[i * 4 + 1];
+ dst[i * 3 + 2] = src[i * 4 + 2];
+ }
+ }
+}
+
+
+static void
+put_row_rgb_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ GLint x, GLint y, const void *values, const GLubyte *mask)
+{
+ /* note: incoming values are RGB+A! */
+ const GLubyte *src = (const GLubyte *) values;
+ GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->Width + x);
+ GLuint i;
+ ASSERT(rb->_ActualFormat == GL_RGB8);
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ dst[i * 3 + 0] = src[i * 3 + 0];
+ dst[i * 3 + 1] = src[i * 3 + 1];
+ dst[i * 3 + 2] = src[i * 3 + 2];
+ }
+ }
+}
+
+
+static void
+put_mono_row_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ GLint x, GLint y, const void *value, const GLubyte *mask)
+{
+ /* note: incoming value is RGB+A! */
+ const GLubyte val0 = ((const GLubyte *) value)[0];
+ const GLubyte val1 = ((const GLubyte *) value)[1];
+ const GLubyte val2 = ((const GLubyte *) value)[2];
+ GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->Width + x);
+ ASSERT(rb->_ActualFormat == GL_RGB8);
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
+ if (!mask && val0 == val1 && val1 == val2) {
+ /* optimized case */
+ _mesa_memset(dst, val0, 3 * count);
+ }
+ else {
+ GLuint i;
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ dst[i * 3 + 0] = val0;
+ dst[i * 3 + 1] = val1;
+ dst[i * 3 + 2] = val2;
+ }
+ }
+ }
+}
+
+
+static void
+put_values_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ const GLint x[], const GLint y[], const void *values,
+ const GLubyte *mask)
+{
+ /* note: incoming values are RGB+A! */
+ const GLubyte *src = (const GLubyte *) values;
+ GLuint i;
+ ASSERT(rb->_ActualFormat == GL_RGB8);
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ GLubyte *dst = (GLubyte *) rb->Data + 3 * (y[i] * rb->Width + x[i]);
+ dst[0] = src[i * 4 + 0];
+ dst[1] = src[i * 4 + 1];
+ dst[2] = src[i * 4 + 2];
+ }
+ }
+}
+
+
+static void
+put_mono_values_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb,
+ GLuint count, const GLint x[], const GLint y[],
+ const void *value, const GLubyte *mask)
+{
+ /* note: incoming value is RGB+A! */
+ const GLubyte val0 = ((const GLubyte *) value)[0];
+ const GLubyte val1 = ((const GLubyte *) value)[1];
+ const GLubyte val2 = ((const GLubyte *) value)[2];
+ GLuint i;
+ ASSERT(rb->_ActualFormat == GL_RGB8);
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ GLubyte *dst = (GLubyte *) rb->Data + 3 * (y[i] * rb->Width + x[i]);
+ dst[0] = val0;
+ dst[1] = val1;
+ dst[2] = val2;
+ }
+ }
+}
+
+
+/**********************************************************************
+ * Functions for buffers of 4 X GLubyte (or GLbyte) values.
+ * Typically color buffers.
+ */
+
+static void *
+get_pointer_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb,
+ GLint x, GLint y)
+{
+ if (!rb->Data)
+ return NULL;
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(rb->_ActualFormat == GL_RGBA8);
+ return (GLubyte *) rb->Data + 4 * (y * rb->Width + x);
+}
+
+
+static void
+get_row_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ GLint x, GLint y, void *values)
+{
+ const GLbyte *src = (const GLbyte *) rb->Data + 4 * (y * rb->Width + x);
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(rb->_ActualFormat == GL_RGBA8);
+ _mesa_memcpy(values, src, 4 * count * sizeof(GLbyte));
+}
+
+
+static void
+get_values_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ const GLint x[], const GLint y[], void *values)
+{
+ /* treat 4*GLubyte as 1*GLuint */
+ GLuint *dst = (GLuint *) values;
+ GLuint i;
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(rb->_ActualFormat == GL_RGBA8);
+ for (i = 0; i < count; i++) {
+ const GLuint *src = (GLuint *) rb->Data + (y[i] * rb->Width + x[i]);
+ dst[i] = *src;
+ }
+}
+
+
+static void
+put_row_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ GLint x, GLint y, const void *values, const GLubyte *mask)
+{
+ /* treat 4*GLubyte as 1*GLuint */
+ const GLuint *src = (const GLuint *) values;
+ GLuint *dst = (GLuint *) rb->Data + (y * rb->Width + x);
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(rb->_ActualFormat == GL_RGBA8);
+ if (mask) {
+ GLuint i;
+ for (i = 0; i < count; i++) {
+ if (mask[i]) {
+ dst[i] = src[i];
+ }
+ }
+ }
+ else {
+ _mesa_memcpy(dst, src, 4 * count * sizeof(GLubyte));
+ }
+}
+
+
+static void
+put_row_rgb_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ GLint x, GLint y, const void *values, const GLubyte *mask)
+{
+ /* Store RGB values in RGBA buffer */
+ const GLubyte *src = (const GLubyte *) values;
+ GLubyte *dst = (GLubyte *) rb->Data + 4 * (y * rb->Width + x);
+ GLuint i;
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(rb->_ActualFormat == GL_RGBA8);
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ dst[i * 4 + 0] = src[i * 3 + 0];
+ dst[i * 4 + 1] = src[i * 3 + 1];
+ dst[i * 4 + 2] = src[i * 3 + 2];
+ dst[i * 4 + 3] = 0xff;
+ }
+ }
+}
+
+
+static void
+put_mono_row_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ GLint x, GLint y, const void *value, const GLubyte *mask)
+{
+ /* treat 4*GLubyte as 1*GLuint */
+ const GLuint val = *((const GLuint *) value);
+ GLuint *dst = (GLuint *) rb->Data + (y * rb->Width + x);
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(rb->_ActualFormat == GL_RGBA8);
+ if (!mask && val == 0) {
+ /* common case */
+ _mesa_bzero(dst, count * 4 * sizeof(GLubyte));
+ }
+ else {
+ /* general case */
+ if (mask) {
+ GLuint i;
+ for (i = 0; i < count; i++) {
+ if (mask[i]) {
+ dst[i] = val;
+ }
+ }
+ }
+ else {
+ GLuint i;
+ for (i = 0; i < count; i++) {
+ dst[i] = val;
+ }
+ }
+ }
+}
+
+
+static void
+put_values_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ const GLint x[], const GLint y[], const void *values,
+ const GLubyte *mask)
+{
+ /* treat 4*GLubyte as 1*GLuint */
+ const GLuint *src = (const GLuint *) values;
+ GLuint i;
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(rb->_ActualFormat == GL_RGBA8);
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->Width + x[i]);
+ *dst = src[i];
+ }
+ }
+}
+
+
+static void
+put_mono_values_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb,
+ GLuint count, const GLint x[], const GLint y[],
+ const void *value, const GLubyte *mask)
+{
+ /* treat 4*GLubyte as 1*GLuint */
+ const GLuint val = *((const GLuint *) value);
+ GLuint i;
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(rb->_ActualFormat == GL_RGBA8);
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->Width + x[i]);
+ *dst = val;
+ }
+ }
+}
+
+
+/**********************************************************************
+ * Functions for buffers of 4 X GLushort (or GLshort) values.
+ * Typically accum buffer.
+ */
+
+static void *
+get_pointer_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb,
+ GLint x, GLint y)
+{
+ if (!rb->Data)
+ return NULL;
+ ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
+ return (GLushort *) rb->Data + 4 * (y * rb->Width + x);
+}
+
+
+static void
+get_row_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ GLint x, GLint y, void *values)
+{
+ const GLshort *src = (const GLshort *) rb->Data + 4 * (y * rb->Width + x);
+ ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
+ _mesa_memcpy(values, src, 4 * count * sizeof(GLshort));
+}
+
+
+static void
+get_values_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ const GLint x[], const GLint y[], void *values)
+{
+ GLushort *dst = (GLushort *) values;
+ GLuint i;
+ ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
+ for (i = 0; i < count; i++) {
+ const GLushort *src
+ = (GLushort *) rb->Data + 4 * (y[i] * rb->Width + x[i]);
+ dst[i] = *src;
+ }
+}
+
+
+static void
+put_row_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ GLint x, GLint y, const void *values, const GLubyte *mask)
+{
+ const GLushort *src = (const GLushort *) values;
+ GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->Width + x);
+ ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
+ if (mask) {
+ GLuint i;
+ for (i = 0; i < count; i++) {
+ if (mask[i]) {
+ dst[i * 4 + 0] = src[i * 4 + 0];
+ dst[i * 4 + 1] = src[i * 4 + 1];
+ dst[i * 4 + 2] = src[i * 4 + 2];
+ dst[i * 4 + 3] = src[i * 4 + 3];
+ }
+ }
+ }
+ else {
+ _mesa_memcpy(dst, src, 4 * count * sizeof(GLushort));
+ }
+}
+
+
+static void
+put_row_rgb_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ GLint x, GLint y, const void *values, const GLubyte *mask)
+{
+ /* Put RGB values in RGBA buffer */
+ const GLushort *src = (const GLushort *) values;
+ GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->Width + x);
+ ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
+ if (mask) {
+ GLuint i;
+ for (i = 0; i < count; i++) {
+ if (mask[i]) {
+ dst[i * 4 + 0] = src[i * 3 + 0];
+ dst[i * 4 + 1] = src[i * 3 + 1];
+ dst[i * 4 + 2] = src[i * 3 + 2];
+ dst[i * 4 + 3] = 0xffff;
+ }
+ }
+ }
+ else {
+ _mesa_memcpy(dst, src, 4 * count * sizeof(GLushort));
+ }
+}
+
+
+static void
+put_mono_row_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ GLint x, GLint y, const void *value, const GLubyte *mask)
+{
+ const GLushort val0 = ((const GLushort *) value)[0];
+ const GLushort val1 = ((const GLushort *) value)[1];
+ const GLushort val2 = ((const GLushort *) value)[2];
+ const GLushort val3 = ((const GLushort *) value)[3];
+ GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->Width + x);
+ ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
+ if (!mask && val0 == 0 && val1 == 0 && val2 == 0 && val3 == 0) {
+ /* common case for clearing accum buffer */
+ _mesa_bzero(dst, count * 4 * sizeof(GLushort));
+ }
+ else {
+ GLuint i;
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ dst[i * 4 + 0] = val0;
+ dst[i * 4 + 1] = val1;
+ dst[i * 4 + 2] = val2;
+ dst[i * 4 + 3] = val3;
+ }
+ }
+ }
+}
+
+
+static void
+put_values_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ const GLint x[], const GLint y[], const void *values,
+ const GLubyte *mask)
+{
+ const GLushort *src = (const GLushort *) values;
+ GLuint i;
+ ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ GLushort *dst = (GLushort *) rb->Data + 4 * (y[i] * rb->Width + x[i]);
+ dst[0] = src[i * 4 + 0];
+ dst[1] = src[i * 4 + 1];
+ dst[2] = src[i * 4 + 2];
+ dst[3] = src[i * 4 + 3];
+ }
+ }
+}
+
+
+static void
+put_mono_values_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb,
+ GLuint count, const GLint x[], const GLint y[],
+ const void *value, const GLubyte *mask)
+{
+ const GLushort val0 = ((const GLushort *) value)[0];
+ const GLushort val1 = ((const GLushort *) value)[1];
+ const GLushort val2 = ((const GLushort *) value)[2];
+ const GLushort val3 = ((const GLushort *) value)[3];
+ GLuint i;
+ ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ GLushort *dst = (GLushort *) rb->Data + 4 * (y[i] * rb->Width + x[i]);
+ dst[0] = val0;
+ dst[1] = val1;
+ dst[2] = val2;
+ dst[3] = val3;
+ }
+ }
+}
+
+
+
+/**
+ * This is a software fallback for the gl_renderbuffer->AllocStorage
+ * function.
+ * Device drivers will typically override this function for the buffers
+ * which it manages (typically color buffers, Z and stencil).
+ * Other buffers (like software accumulation and aux buffers) which the driver
+ * doesn't manage can be handled with this function.
+ *
+ * This one multi-purpose function can allocate stencil, depth, accum, color
+ * or color-index buffers!
+ *
+ * This function also plugs in the appropriate GetPointer, Get/PutRow and
+ * Get/PutValues functions.
+ */
+GLboolean
+_mesa_soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
+ GLenum internalFormat,
+ GLuint width, GLuint height)
+{
+ GLuint pixelSize;
+
+ /* first clear these fields */
+ rb->RedBits =
+ rb->GreenBits =
+ rb->BlueBits =
+ rb->AlphaBits =
+ rb->IndexBits =
+ rb->DepthBits =
+ rb->StencilBits = 0;
+
+ switch (internalFormat) {
+ case GL_RGB:
+ case GL_R3_G3_B2:
+ case GL_RGB4:
+ case GL_RGB5:
+ case GL_RGB8:
+ case GL_RGB10:
+ case GL_RGB12:
+ case GL_RGB16:
+ rb->_ActualFormat = GL_RGB8;
+ rb->_BaseFormat = GL_RGB;
+ rb->DataType = GL_UNSIGNED_BYTE;
+ rb->GetPointer = get_pointer_ubyte3;
+ rb->GetRow = get_row_ubyte3;
+ rb->GetValues = get_values_ubyte3;
+ rb->PutRow = put_row_ubyte3;
+ rb->PutRowRGB = put_row_rgb_ubyte3;
+ rb->PutMonoRow = put_mono_row_ubyte3;
+ rb->PutValues = put_values_ubyte3;
+ rb->PutMonoValues = put_mono_values_ubyte3;
+ rb->RedBits = 8 * sizeof(GLubyte);
+ rb->GreenBits = 8 * sizeof(GLubyte);
+ rb->BlueBits = 8 * sizeof(GLubyte);
+ rb->AlphaBits = 0;
+ pixelSize = 3 * sizeof(GLubyte);
+ break;
+ case GL_RGBA:
+ case GL_RGBA2:
+ case GL_RGBA4:
+ case GL_RGB5_A1:
+ case GL_RGBA8:
+ rb->_ActualFormat = GL_RGBA8;
+ rb->_BaseFormat = GL_RGBA;
+ rb->DataType = GL_UNSIGNED_BYTE;
+ rb->GetPointer = get_pointer_ubyte4;
+ rb->GetRow = get_row_ubyte4;
+ rb->GetValues = get_values_ubyte4;
+ rb->PutRow = put_row_ubyte4;
+ rb->PutRowRGB = put_row_rgb_ubyte4;
+ rb->PutMonoRow = put_mono_row_ubyte4;
+ rb->PutValues = put_values_ubyte4;
+ rb->PutMonoValues = put_mono_values_ubyte4;
+ rb->RedBits = 8 * sizeof(GLubyte);
+ rb->GreenBits = 8 * sizeof(GLubyte);
+ rb->BlueBits = 8 * sizeof(GLubyte);
+ rb->AlphaBits = 8 * sizeof(GLubyte);
+ pixelSize = 4 * sizeof(GLubyte);
+ break;
+ case GL_RGB10_A2:
+ case GL_RGBA12:
+ case GL_RGBA16:
+ rb->_ActualFormat = GL_RGBA16;
+ rb->_BaseFormat = GL_RGBA;
+ rb->DataType = GL_UNSIGNED_SHORT;
+ rb->GetPointer = get_pointer_ushort4;
+ rb->GetRow = get_row_ushort4;
+ rb->GetValues = get_values_ushort4;
+ rb->PutRow = put_row_ushort4;
+ rb->PutRowRGB = put_row_rgb_ushort4;
+ rb->PutMonoRow = put_mono_row_ushort4;
+ rb->PutValues = put_values_ushort4;
+ rb->PutMonoValues = put_mono_values_ushort4;
+ rb->RedBits = 8 * sizeof(GLushort);
+ rb->GreenBits = 8 * sizeof(GLushort);
+ rb->BlueBits = 8 * sizeof(GLushort);
+ rb->AlphaBits = 8 * sizeof(GLushort);
+ pixelSize = 4 * sizeof(GLushort);
+ break;
+#if 00
+ case GL_ALPHA8:
+ rb->_ActualFormat = GL_ALPHA8;
+ rb->_BaseFormat = GL_RGBA; /* Yes, not GL_ALPHA! */
+ rb->DataType = GL_UNSIGNED_BYTE;
+ rb->GetPointer = get_pointer_alpha8;
+ rb->GetRow = get_row_alpha8;
+ rb->GetValues = get_values_alpha8;
+ rb->PutRow = put_row_alpha8;
+ rb->PutRowRGB = NULL;
+ rb->PutMonoRow = put_mono_row_alpha8;
+ rb->PutValues = put_values_alpha8;
+ rb->PutMonoValues = put_mono_values_alpha8;
+ rb->RedBits = 0; /*red*/
+ rb->GreenBits = 0; /*green*/
+ rb->BlueBits = 0; /*blue*/
+ rb->AlphaBits = 8 * sizeof(GLubyte);
+ pixelSize = sizeof(GLubyte);
+ break;
+#endif
+ case GL_STENCIL_INDEX:
+ case GL_STENCIL_INDEX1_EXT:
+ case GL_STENCIL_INDEX4_EXT:
+ case GL_STENCIL_INDEX8_EXT:
+ rb->_ActualFormat = GL_STENCIL_INDEX8_EXT;
+ rb->_BaseFormat = GL_STENCIL_INDEX;
+ rb->DataType = GL_UNSIGNED_BYTE;
+ rb->GetPointer = get_pointer_ubyte;
+ rb->GetRow = get_row_ubyte;
+ rb->GetValues = get_values_ubyte;
+ rb->PutRow = put_row_ubyte;
+ rb->PutRowRGB = NULL;
+ rb->PutMonoRow = put_mono_row_ubyte;
+ rb->PutValues = put_values_ubyte;
+ rb->PutMonoValues = put_mono_values_ubyte;
+ rb->StencilBits = 8 * sizeof(GLubyte);
+ pixelSize = sizeof(GLubyte);
+ break;
+ case GL_STENCIL_INDEX16_EXT:
+ rb->_ActualFormat = GL_STENCIL_INDEX16_EXT;
+ rb->_BaseFormat = GL_STENCIL_INDEX;
+ rb->DataType = GL_UNSIGNED_SHORT;
+ rb->GetPointer = get_pointer_ushort;
+ rb->GetRow = get_row_ushort;
+ rb->GetValues = get_values_ushort;
+ rb->PutRow = put_row_ushort;
+ rb->PutRowRGB = NULL;
+ rb->PutMonoRow = put_mono_row_ushort;
+ rb->PutValues = put_values_ushort;
+ rb->PutMonoValues = put_mono_values_ushort;
+ rb->StencilBits = 8 * sizeof(GLushort);
+ pixelSize = sizeof(GLushort);
+ break;
+ case GL_DEPTH_COMPONENT:
+ case GL_DEPTH_COMPONENT16:
+ rb->_ActualFormat = GL_DEPTH_COMPONENT16;
+ rb->_BaseFormat = GL_DEPTH_COMPONENT;
+ rb->DataType = GL_UNSIGNED_SHORT;
+ rb->GetPointer = get_pointer_ushort;
+ rb->GetRow = get_row_ushort;
+ rb->GetValues = get_values_ushort;
+ rb->PutRow = put_row_ushort;
+ rb->PutRowRGB = NULL;
+ rb->PutMonoRow = put_mono_row_ushort;
+ rb->PutValues = put_values_ushort;
+ rb->PutMonoValues = put_mono_values_ushort;
+ rb->DepthBits = 8 * sizeof(GLushort);
+ pixelSize = sizeof(GLushort);
+ break;
+ case GL_DEPTH_COMPONENT24:
+ case GL_DEPTH_COMPONENT32:
+ rb->_BaseFormat = GL_DEPTH_COMPONENT;
+ rb->DataType = GL_UNSIGNED_INT;
+ rb->GetPointer = get_pointer_uint;
+ rb->GetRow = get_row_uint;
+ rb->GetValues = get_values_uint;
+ rb->PutRow = put_row_uint;
+ rb->PutRowRGB = NULL;
+ rb->PutMonoRow = put_mono_row_uint;
+ rb->PutValues = put_values_uint;
+ rb->PutMonoValues = put_mono_values_uint;
+ if (internalFormat == GL_DEPTH_COMPONENT24) {
+ rb->_ActualFormat = GL_DEPTH_COMPONENT24;
+ rb->DepthBits = 24;
+ }
+ else {
+ rb->_ActualFormat = GL_DEPTH_COMPONENT32;
+ rb->DepthBits = 32;
+ }
+ pixelSize = sizeof(GLuint);
+ break;
+ case GL_DEPTH_STENCIL_EXT:
+ case GL_DEPTH24_STENCIL8_EXT:
+ rb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT;
+ rb->_BaseFormat = GL_DEPTH_STENCIL_EXT;
+ rb->DataType = GL_UNSIGNED_INT_24_8_EXT;
+ rb->GetPointer = get_pointer_uint;
+ rb->GetRow = get_row_uint;
+ rb->GetValues = get_values_uint;
+ rb->PutRow = put_row_uint;
+ rb->PutRowRGB = NULL;
+ rb->PutMonoRow = put_mono_row_uint;
+ rb->PutValues = put_values_uint;
+ rb->PutMonoValues = put_mono_values_uint;
+ rb->DepthBits = 24;
+ rb->StencilBits = 8;
+ pixelSize = sizeof(GLuint);
+ break;
+ case GL_COLOR_INDEX8_EXT:
+ rb->_ActualFormat = GL_COLOR_INDEX8_EXT;
+ rb->_BaseFormat = GL_COLOR_INDEX;
+ rb->DataType = GL_UNSIGNED_BYTE;
+ rb->GetPointer = get_pointer_ubyte;
+ rb->GetRow = get_row_ubyte;
+ rb->GetValues = get_values_ubyte;
+ rb->PutRow = put_row_ubyte;
+ rb->PutRowRGB = NULL;
+ rb->PutMonoRow = put_mono_row_ubyte;
+ rb->PutValues = put_values_ubyte;
+ rb->PutMonoValues = put_mono_values_ubyte;
+ rb->IndexBits = 8 * sizeof(GLubyte);
+ pixelSize = sizeof(GLubyte);
+ break;
+ case GL_COLOR_INDEX16_EXT:
+ rb->_ActualFormat = GL_COLOR_INDEX16_EXT;
+ rb->_BaseFormat = GL_COLOR_INDEX;
+ rb->DataType = GL_UNSIGNED_SHORT;
+ rb->GetPointer = get_pointer_ushort;
+ rb->GetRow = get_row_ushort;
+ rb->GetValues = get_values_ushort;
+ rb->PutRow = put_row_ushort;
+ rb->PutRowRGB = NULL;
+ rb->PutMonoRow = put_mono_row_ushort;
+ rb->PutValues = put_values_ushort;
+ rb->PutMonoValues = put_mono_values_ushort;
+ rb->IndexBits = 8 * sizeof(GLushort);
+ pixelSize = sizeof(GLushort);
+ break;
+ case COLOR_INDEX32:
+ rb->_ActualFormat = COLOR_INDEX32;
+ rb->_BaseFormat = GL_COLOR_INDEX;
+ rb->DataType = GL_UNSIGNED_INT;
+ rb->GetPointer = get_pointer_uint;
+ rb->GetRow = get_row_uint;
+ rb->GetValues = get_values_uint;
+ rb->PutRow = put_row_uint;
+ rb->PutRowRGB = NULL;
+ rb->PutMonoRow = put_mono_row_uint;
+ rb->PutValues = put_values_uint;
+ rb->PutMonoValues = put_mono_values_uint;
+ rb->IndexBits = 8 * sizeof(GLuint);
+ pixelSize = sizeof(GLuint);
+ break;
+ default:
+ _mesa_problem(ctx, "Bad internalFormat in _mesa_soft_renderbuffer_storage");
+ return GL_FALSE;
+ }
+
+ ASSERT(rb->DataType);
+ ASSERT(rb->GetPointer);
+ ASSERT(rb->GetRow);
+ ASSERT(rb->GetValues);
+ ASSERT(rb->PutRow);
+ ASSERT(rb->PutMonoRow);
+ ASSERT(rb->PutValues);
+ ASSERT(rb->PutMonoValues);
+
+ /* free old buffer storage */
+ if (rb->Data)
+ _mesa_free(rb->Data);
+
+ /* allocate new buffer storage */
+ rb->Data = _mesa_malloc(width * height * pixelSize);
+ if (rb->Data == NULL) {
+ rb->Width = 0;
+ rb->Height = 0;
+ _mesa_error(ctx, GL_OUT_OF_MEMORY,
+ "software renderbuffer allocation (%d x %d x %d)",
+ width, height, pixelSize);
+ return GL_FALSE;
+ }
+
+ rb->Width = width;
+ rb->Height = height;
+
+ return GL_TRUE;
+}
+
+
+
+/**********************************************************************/
+/**********************************************************************/
+/**********************************************************************/
+
+
+/**
+ * Here we utilize the gl_renderbuffer->Wrapper field to put an alpha
+ * buffer wrapper around an existing RGB renderbuffer (hw or sw).
+ *
+ * When PutRow is called (for example), we store the alpha values in
+ * this buffer, then pass on the PutRow call to the wrapped RGB
+ * buffer.
+ */
+
+
+static GLboolean
+alloc_storage_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb,
+ GLenum internalFormat, GLuint width, GLuint height)
+{
+ ASSERT(arb != arb->Wrapped);
+ ASSERT(arb->_ActualFormat == GL_ALPHA8);
+
+ /* first, pass the call to the wrapped RGB buffer */
+ if (!arb->Wrapped->AllocStorage(ctx, arb->Wrapped, internalFormat,
+ width, height)) {
+ return GL_FALSE;
+ }
+
+ /* next, resize my alpha buffer */
+ if (arb->Data) {
+ _mesa_free(arb->Data);
+ }
+
+ arb->Data = _mesa_malloc(width * height * sizeof(GLubyte));
+ if (arb->Data == NULL) {
+ arb->Width = 0;
+ arb->Height = 0;
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "software alpha buffer allocation");
+ return GL_FALSE;
+ }
+
+ arb->Width = width;
+ arb->Height = height;
+
+ return GL_TRUE;
+}
+
+
+/**
+ * Delete an alpha_renderbuffer object, as well as the wrapped RGB buffer.
+ */
+static void
+delete_renderbuffer_alpha8(struct gl_renderbuffer *arb)
+{
+ if (arb->Data) {
+ _mesa_free(arb->Data);
+ }
+ ASSERT(arb->Wrapped);
+ ASSERT(arb != arb->Wrapped);
+ arb->Wrapped->Delete(arb->Wrapped);
+ arb->Wrapped = NULL;
+ _mesa_free(arb);
+}
+
+
+static void *
+get_pointer_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb,
+ GLint x, GLint y)
+{
+ return NULL; /* don't allow direct access! */
+}
+
+
+static void
+get_row_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb, GLuint count,
+ GLint x, GLint y, void *values)
+{
+ /* NOTE: 'values' is RGBA format! */
+ const GLubyte *src = (const GLubyte *) arb->Data + y * arb->Width + x;
+ GLubyte *dst = (GLubyte *) values;
+ GLuint i;
+ ASSERT(arb != arb->Wrapped);
+ ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
+ /* first, pass the call to the wrapped RGB buffer */
+ arb->Wrapped->GetRow(ctx, arb->Wrapped, count, x, y, values);
+ /* second, fill in alpha values from this buffer! */
+ for (i = 0; i < count; i++) {
+ dst[i * 4 + 3] = src[i];
+ }
+}
+
+
+static void
+get_values_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb, GLuint count,
+ const GLint x[], const GLint y[], void *values)
+{
+ GLubyte *dst = (GLubyte *) values;
+ GLuint i;
+ ASSERT(arb != arb->Wrapped);
+ ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
+ /* first, pass the call to the wrapped RGB buffer */
+ arb->Wrapped->GetValues(ctx, arb->Wrapped, count, x, y, values);
+ /* second, fill in alpha values from this buffer! */
+ for (i = 0; i < count; i++) {
+ const GLubyte *src = (GLubyte *) arb->Data + y[i] * arb->Width + x[i];
+ dst[i * 4 + 3] = *src;
+ }
+}
+
+
+static void
+put_row_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb, GLuint count,
+ GLint x, GLint y, const void *values, const GLubyte *mask)
+{
+ const GLubyte *src = (const GLubyte *) values;
+ GLubyte *dst = (GLubyte *) arb->Data + y * arb->Width + x;
+ GLuint i;
+ ASSERT(arb != arb->Wrapped);
+ ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
+ /* first, pass the call to the wrapped RGB buffer */
+ arb->Wrapped->PutRow(ctx, arb->Wrapped, count, x, y, values, mask);
+ /* second, store alpha in our buffer */
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ dst[i] = src[i * 4 + 3];
+ }
+ }
+}
+
+
+static void
+put_row_rgb_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb, GLuint count,
+ GLint x, GLint y, const void *values, const GLubyte *mask)
+{
+ const GLubyte *src = (const GLubyte *) values;
+ GLubyte *dst = (GLubyte *) arb->Data + y * arb->Width + x;
+ GLuint i;
+ ASSERT(arb != arb->Wrapped);
+ ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
+ /* first, pass the call to the wrapped RGB buffer */
+ arb->Wrapped->PutRowRGB(ctx, arb->Wrapped, count, x, y, values, mask);
+ /* second, store alpha in our buffer */
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ dst[i] = src[i * 4 + 3];
+ }
+ }
+}
+
+
+static void
+put_mono_row_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb, GLuint count,
+ GLint x, GLint y, const void *value, const GLubyte *mask)
+{
+ const GLubyte val = ((const GLubyte *) value)[3];
+ GLubyte *dst = (GLubyte *) arb->Data + y * arb->Width + x;
+ ASSERT(arb != arb->Wrapped);
+ ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
+ /* first, pass the call to the wrapped RGB buffer */
+ arb->Wrapped->PutMonoRow(ctx, arb->Wrapped, count, x, y, value, mask);
+ /* second, store alpha in our buffer */
+ if (mask) {
+ GLuint i;
+ for (i = 0; i < count; i++) {
+ if (mask[i]) {
+ dst[i] = val;
+ }
+ }
+ }
+ else {
+ _mesa_memset(dst, val, count);
+ }
+}
+
+
+static void
+put_values_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb, GLuint count,
+ const GLint x[], const GLint y[],
+ const void *values, const GLubyte *mask)
+{
+ const GLubyte *src = (const GLubyte *) values;
+ GLuint i;
+ ASSERT(arb != arb->Wrapped);
+ ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
+ /* first, pass the call to the wrapped RGB buffer */
+ arb->Wrapped->PutValues(ctx, arb->Wrapped, count, x, y, values, mask);
+ /* second, store alpha in our buffer */
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ GLubyte *dst = (GLubyte *) arb->Data + y[i] * arb->Width + x[i];
+ *dst = src[i * 4 + 3];
+ }
+ }
+}
+
+
+static void
+put_mono_values_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb,
+ GLuint count, const GLint x[], const GLint y[],
+ const void *value, const GLubyte *mask)
+{
+ const GLubyte val = ((const GLubyte *) value)[3];
+ GLuint i;
+ ASSERT(arb != arb->Wrapped);
+ ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
+ /* first, pass the call to the wrapped RGB buffer */
+ arb->Wrapped->PutValues(ctx, arb->Wrapped, count, x, y, value, mask);
+ /* second, store alpha in our buffer */
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ GLubyte *dst = (GLubyte *) arb->Data + y[i] * arb->Width + x[i];
+ *dst = val;
+ }
+ }
+}
+
+
+
+/**********************************************************************/
+/**********************************************************************/
+/**********************************************************************/
+
+
+/**
+ * Default GetPointer routine. Always return NULL to indicate that
+ * direct buffer access is not supported.
+ */
+static void *
+nop_get_pointer(GLcontext *ctx, struct gl_renderbuffer *rb, GLint x, GLint y)
+{
+ return NULL;
+}
+
+
+/**
+ * Initialize the fields of a gl_renderbuffer to default values.
+ */
+void
+_mesa_init_renderbuffer(struct gl_renderbuffer *rb, GLuint name)
+{
+ _glthread_INIT_MUTEX(rb->Mutex);
+
+ rb->ClassID = 0;
+ rb->Name = name;
+ rb->RefCount = 1;
+ rb->Delete = _mesa_delete_renderbuffer;
+
+ /* The rest of these should be set later by the caller of this function or
+ * the AllocStorage method:
+ */
+ rb->AllocStorage = NULL;
+
+ rb->Width = 0;
+ rb->Height = 0;
+ rb->InternalFormat = GL_NONE;
+ rb->_ActualFormat = GL_NONE;
+ rb->_BaseFormat = GL_NONE;
+ rb->DataType = GL_NONE;
+ rb->RedBits = rb->GreenBits = rb->BlueBits = rb->AlphaBits = 0;
+ rb->IndexBits = 0;
+ rb->DepthBits = 0;
+ rb->StencilBits = 0;
+ rb->Data = NULL;
+
+ /* Point back to ourself so that we don't have to check for Wrapped==NULL
+ * all over the drivers.
+ */
+ rb->Wrapped = rb;
+
+ rb->GetPointer = nop_get_pointer;
+ rb->GetRow = NULL;
+ rb->GetValues = NULL;
+ rb->PutRow = NULL;
+ rb->PutRowRGB = NULL;
+ rb->PutMonoRow = NULL;
+ rb->PutValues = NULL;
+ rb->PutMonoValues = NULL;
+}
+
+
+/**
+ * Allocate a new gl_renderbuffer object. This can be used for user-created
+ * renderbuffers or window-system renderbuffers.
+ */
+struct gl_renderbuffer *
+_mesa_new_renderbuffer(GLcontext *ctx, GLuint name)
+{
+ struct gl_renderbuffer *rb = CALLOC_STRUCT(gl_renderbuffer);
+ if (rb) {
+ _mesa_init_renderbuffer(rb, name);
+ }
+ return rb;
+}
+
+
+/**
+ * Delete a gl_framebuffer.
+ * This is the default function for framebuffer->Delete().
+ */
+void
+_mesa_delete_renderbuffer(struct gl_renderbuffer *rb)
+{
+ if (rb->Data) {
+ _mesa_free(rb->Data);
+ }
+ _glthread_INIT_MUTEX(rb->Mutex);
+ _mesa_free(rb);
+}
+
+
+/**
+ * Allocate a software-based renderbuffer. This is called via the
+ * ctx->Driver.NewRenderbuffer() function when the user creates a new
+ * renderbuffer.
+ * This would not be used for hardware-based renderbuffers.
+ */
+struct gl_renderbuffer *
+_mesa_new_soft_renderbuffer(GLcontext *ctx, GLuint name)
+{
+ struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, name);
+ if (rb) {
+ rb->AllocStorage = _mesa_soft_renderbuffer_storage;
+ /* Normally, one would setup the PutRow, GetRow, etc functions here.
+ * But we're doing that in the _mesa_soft_renderbuffer_storage() function
+ * instead.
+ */
+ }
+ return rb;
+}
+
+
+/**
+ * Add software-based color renderbuffers to the given framebuffer.
+ * This is a helper routine for device drivers when creating a
+ * window system framebuffer (not a user-created render/framebuffer).
+ * Once this function is called, you can basically forget about this
+ * renderbuffer; core Mesa will handle all the buffer management and
+ * rendering!
+ */
+GLboolean
+_mesa_add_color_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb,
+ GLuint rgbBits, GLuint alphaBits,
+ GLboolean frontLeft, GLboolean backLeft,
+ GLboolean frontRight, GLboolean backRight)
+{
+ GLuint b;
+
+ if (rgbBits > 16 || alphaBits > 16) {
+ _mesa_problem(ctx,
+ "Unsupported bit depth in _mesa_add_color_renderbuffers");
+ return GL_FALSE;
+ }
+
+ assert(MAX_COLOR_ATTACHMENTS >= 4);
+
+ for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) {
+ struct gl_renderbuffer *rb;
+
+ if (b == BUFFER_FRONT_LEFT && !frontLeft)
+ continue;
+ else if (b == BUFFER_BACK_LEFT && !backLeft)
+ continue;
+ else if (b == BUFFER_FRONT_RIGHT && !frontRight)
+ continue;
+ else if (b == BUFFER_BACK_RIGHT && !backRight)
+ continue;
+
+ assert(fb->Attachment[b].Renderbuffer == NULL);
+
+ rb = _mesa_new_renderbuffer(ctx, 0);
+ if (!rb) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating color buffer");
+ return GL_FALSE;
+ }
+
+ if (rgbBits <= 8) {
+ if (alphaBits)
+ rb->_ActualFormat = GL_RGBA8;
+ else
+ rb->_ActualFormat = GL_RGB8;
+ }
+ else {
+ assert(rgbBits <= 16);
+ if (alphaBits)
+ rb->_ActualFormat = GL_RGBA16;
+ else
+ rb->_ActualFormat = GL_RGBA16; /* don't really have RGB16 yet */
+ }
+ rb->InternalFormat = rb->_ActualFormat;
+
+ rb->AllocStorage = _mesa_soft_renderbuffer_storage;
+ _mesa_add_renderbuffer(fb, b, rb);
+ }
+
+ return GL_TRUE;
+}
+
+
+/**
+ * Add software-based color index renderbuffers to the given framebuffer.
+ * This is a helper routine for device drivers when creating a
+ * window system framebuffer (not a user-created render/framebuffer).
+ * Once this function is called, you can basically forget about this
+ * renderbuffer; core Mesa will handle all the buffer management and
+ * rendering!
+ */
+GLboolean
+_mesa_add_color_index_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb,
+ GLuint indexBits,
+ GLboolean frontLeft, GLboolean backLeft,
+ GLboolean frontRight, GLboolean backRight)
+{
+ GLuint b;
+
+ if (indexBits > 8) {
+ _mesa_problem(ctx,
+ "Unsupported bit depth in _mesa_add_color_index_renderbuffers");
+ return GL_FALSE;
+ }
+
+ assert(MAX_COLOR_ATTACHMENTS >= 4);
+
+ for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) {
+ struct gl_renderbuffer *rb;
+
+ if (b == BUFFER_FRONT_LEFT && !frontLeft)
+ continue;
+ else if (b == BUFFER_BACK_LEFT && !backLeft)
+ continue;
+ else if (b == BUFFER_FRONT_RIGHT && !frontRight)
+ continue;
+ else if (b == BUFFER_BACK_RIGHT && !backRight)
+ continue;
+
+ assert(fb->Attachment[b].Renderbuffer == NULL);
+
+ rb = _mesa_new_renderbuffer(ctx, 0);
+ if (!rb) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating color buffer");
+ return GL_FALSE;
+ }
+
+ if (indexBits <= 8) {
+ /* only support GLuint for now */
+ /*rb->InternalFormat = GL_COLOR_INDEX8_EXT;*/
+ rb->_ActualFormat = COLOR_INDEX32;
+ }
+ else {
+ rb->_ActualFormat = COLOR_INDEX32;
+ }
+ rb->InternalFormat = rb->_ActualFormat;
+
+ rb->AllocStorage = _mesa_soft_renderbuffer_storage;
+ _mesa_add_renderbuffer(fb, b, rb);
+ }
+
+ return GL_TRUE;
+}
+
+
+/**
+ * Add software-based alpha renderbuffers to the given framebuffer.
+ * This is a helper routine for device drivers when creating a
+ * window system framebuffer (not a user-created render/framebuffer).
+ * Once this function is called, you can basically forget about this
+ * renderbuffer; core Mesa will handle all the buffer management and
+ * rendering!
+ */
+GLboolean
+_mesa_add_alpha_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb,
+ GLuint alphaBits,
+ GLboolean frontLeft, GLboolean backLeft,
+ GLboolean frontRight, GLboolean backRight)
+{
+ GLuint b;
+
+ /* for window system framebuffers only! */
+ assert(fb->Name == 0);
+
+ if (alphaBits > 8) {
+ _mesa_problem(ctx,
+ "Unsupported bit depth in _mesa_add_alpha_renderbuffers");
+ return GL_FALSE;
+ }
+
+ assert(MAX_COLOR_ATTACHMENTS >= 4);
+
+ /* Wrap each of the RGB color buffers with an alpha renderbuffer.
+ */
+ for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) {
+ struct gl_renderbuffer *arb;
+
+ if (b == BUFFER_FRONT_LEFT && !frontLeft)
+ continue;
+ else if (b == BUFFER_BACK_LEFT && !backLeft)
+ continue;
+ else if (b == BUFFER_FRONT_RIGHT && !frontRight)
+ continue;
+ else if (b == BUFFER_BACK_RIGHT && !backRight)
+ continue;
+
+ /* the RGB buffer to wrap must already exist!! */
+ assert(fb->Attachment[b].Renderbuffer);
+
+ /* only GLubyte supported for now */
+ assert(fb->Attachment[b].Renderbuffer->DataType == GL_UNSIGNED_BYTE);
+
+ /* allocate alpha renderbuffer */
+ arb = _mesa_new_renderbuffer(ctx, 0);
+ if (!arb) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating alpha buffer");
+ return GL_FALSE;
+ }
+
+ /* wrap the alpha renderbuffer around the RGB renderbuffer */
+ arb->Wrapped = fb->Attachment[b].Renderbuffer;
+
+ /* Set up my alphabuffer fields and plug in my functions.
+ * The functions will put/get the alpha values from/to RGBA arrays
+ * and then call the wrapped buffer's functions to handle the RGB
+ * values.
+ */
+ arb->InternalFormat = arb->Wrapped->InternalFormat;
+ arb->_ActualFormat = GL_ALPHA8;
+ arb->_BaseFormat = arb->Wrapped->_BaseFormat;
+ arb->DataType = arb->Wrapped->DataType;
+ arb->AllocStorage = alloc_storage_alpha8;
+ arb->Delete = delete_renderbuffer_alpha8;
+ arb->GetPointer = get_pointer_alpha8;
+ arb->GetRow = get_row_alpha8;
+ arb->GetValues = get_values_alpha8;
+ arb->PutRow = put_row_alpha8;
+ arb->PutRowRGB = put_row_rgb_alpha8;
+ arb->PutMonoRow = put_mono_row_alpha8;
+ arb->PutValues = put_values_alpha8;
+ arb->PutMonoValues = put_mono_values_alpha8;
+
+ /* clear the pointer to avoid assertion/sanity check failure later */
+ fb->Attachment[b].Renderbuffer = NULL;
+
+ /* plug the alpha renderbuffer into the colorbuffer attachment */
+ _mesa_add_renderbuffer(fb, b, arb);
+ }
+
+ return GL_TRUE;
+}
+
+
+/**
+ * Add a software-based depth renderbuffer to the given framebuffer.
+ * This is a helper routine for device drivers when creating a
+ * window system framebuffer (not a user-created render/framebuffer).
+ * Once this function is called, you can basically forget about this
+ * renderbuffer; core Mesa will handle all the buffer management and
+ * rendering!
+ */
+GLboolean
+_mesa_add_depth_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
+ GLuint depthBits)
+{
+ struct gl_renderbuffer *rb;
+
+ if (depthBits > 32) {
+ _mesa_problem(ctx,
+ "Unsupported depthBits in _mesa_add_depth_renderbuffer");
+ return GL_FALSE;
+ }
+
+ assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer == NULL);
+
+ rb = _mesa_new_renderbuffer(ctx, 0);
+ if (!rb) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating depth buffer");
+ return GL_FALSE;
+ }
+
+ if (depthBits <= 16) {
+ rb->_ActualFormat = GL_DEPTH_COMPONENT16;
+ }
+ else if (depthBits <= 24) {
+ rb->_ActualFormat = GL_DEPTH_COMPONENT24;
+ }
+ else {
+ rb->_ActualFormat = GL_DEPTH_COMPONENT32;
+ }
+ rb->InternalFormat = rb->_ActualFormat;
+
+ rb->AllocStorage = _mesa_soft_renderbuffer_storage;
+ _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb);
+
+ return GL_TRUE;
+}
+
+
+/**
+ * Add a software-based stencil renderbuffer to the given framebuffer.
+ * This is a helper routine for device drivers when creating a
+ * window system framebuffer (not a user-created render/framebuffer).
+ * Once this function is called, you can basically forget about this
+ * renderbuffer; core Mesa will handle all the buffer management and
+ * rendering!
+ */
+GLboolean
+_mesa_add_stencil_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
+ GLuint stencilBits)
+{
+ struct gl_renderbuffer *rb;
+
+ if (stencilBits > 16) {
+ _mesa_problem(ctx,
+ "Unsupported stencilBits in _mesa_add_stencil_renderbuffer");
+ return GL_FALSE;
+ }
+
+ assert(fb->Attachment[BUFFER_STENCIL].Renderbuffer == NULL);
+
+ rb = _mesa_new_renderbuffer(ctx, 0);
+ if (!rb) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating stencil buffer");
+ return GL_FALSE;
+ }
+
+ if (stencilBits <= 8) {
+ rb->_ActualFormat = GL_STENCIL_INDEX8_EXT;
+ }
+ else {
+ /* not really supported (see s_stencil.c code) */
+ rb->_ActualFormat = GL_STENCIL_INDEX16_EXT;
+ }
+ rb->InternalFormat = rb->_ActualFormat;
+
+ rb->AllocStorage = _mesa_soft_renderbuffer_storage;
+ _mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb);
+
+ return GL_TRUE;
+}
+
+
+/**
+ * Add a software-based accumulation renderbuffer to the given framebuffer.
+ * This is a helper routine for device drivers when creating a
+ * window system framebuffer (not a user-created render/framebuffer).
+ * Once this function is called, you can basically forget about this
+ * renderbuffer; core Mesa will handle all the buffer management and
+ * rendering!
+ */
+GLboolean
+_mesa_add_accum_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
+ GLuint redBits, GLuint greenBits,
+ GLuint blueBits, GLuint alphaBits)
+{
+ struct gl_renderbuffer *rb;
+
+ if (redBits > 16 || greenBits > 16 || blueBits > 16 || alphaBits > 16) {
+ _mesa_problem(ctx,
+ "Unsupported accumBits in _mesa_add_accum_renderbuffer");
+ return GL_FALSE;
+ }
+
+ assert(fb->Attachment[BUFFER_ACCUM].Renderbuffer == NULL);
+
+ rb = _mesa_new_renderbuffer(ctx, 0);
+ if (!rb) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating accum buffer");
+ return GL_FALSE;
+ }
+
+ rb->_ActualFormat = GL_RGBA16;
+ rb->InternalFormat = GL_RGBA16;
+ rb->AllocStorage = _mesa_soft_renderbuffer_storage;
+ _mesa_add_renderbuffer(fb, BUFFER_ACCUM, rb);
+
+ return GL_TRUE;
+}
+
+
+
+/**
+ * Add a software-based accumulation renderbuffer to the given framebuffer.
+ * This is a helper routine for device drivers when creating a
+ * window system framebuffer (not a user-created render/framebuffer).
+ * Once this function is called, you can basically forget about this
+ * renderbuffer; core Mesa will handle all the buffer management and
+ * rendering!
+ *
+ * NOTE: color-index aux buffers not supported.
+ */
+GLboolean
+_mesa_add_aux_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb,
+ GLuint colorBits, GLuint numBuffers)
+{
+ GLuint i;
+
+ if (colorBits > 16) {
+ _mesa_problem(ctx,
+ "Unsupported accumBits in _mesa_add_aux_renderbuffers");
+ return GL_FALSE;
+ }
+
+ assert(numBuffers < MAX_AUX_BUFFERS);
+
+ for (i = 0; i < numBuffers; i++) {
+ struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, 0);
+
+ assert(fb->Attachment[BUFFER_AUX0 + i].Renderbuffer == NULL);
+
+ if (!rb) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating accum buffer");
+ return GL_FALSE;
+ }
+
+ if (colorBits <= 8) {
+ rb->_ActualFormat = GL_RGBA8;
+ }
+ else {
+ rb->_ActualFormat = GL_RGBA16;
+ }
+ rb->InternalFormat = rb->_ActualFormat;
+
+ rb->AllocStorage = _mesa_soft_renderbuffer_storage;
+ _mesa_add_renderbuffer(fb, BUFFER_AUX0 + i, rb);
+ }
+ return GL_TRUE;
+}
+
+
+/**
+ * Create/attach software-based renderbuffers to the given framebuffer.
+ * This is a helper routine for device drivers. Drivers can just as well
+ * call the individual _mesa_add_*_renderbuffer() routines directly.
+ */
+void
+_mesa_add_soft_renderbuffers(struct gl_framebuffer *fb,
+ GLboolean color,
+ GLboolean depth,
+ GLboolean stencil,
+ GLboolean accum,
+ GLboolean alpha,
+ GLboolean aux)
+{
+ GLboolean frontLeft = GL_TRUE;
+ GLboolean backLeft = fb->Visual.doubleBufferMode;
+ GLboolean frontRight = fb->Visual.stereoMode;
+ GLboolean backRight = fb->Visual.stereoMode && fb->Visual.doubleBufferMode;
+
+ if (color) {
+ if (fb->Visual.rgbMode) {
+ assert(fb->Visual.redBits == fb->Visual.greenBits);
+ assert(fb->Visual.redBits == fb->Visual.blueBits);
+ _mesa_add_color_renderbuffers(NULL, fb,
+ fb->Visual.redBits,
+ fb->Visual.alphaBits,
+ frontLeft, backLeft,
+ frontRight, backRight);
+ }
+ else {
+ _mesa_add_color_index_renderbuffers(NULL, fb,
+ fb->Visual.indexBits,
+ frontLeft, backLeft,
+ frontRight, backRight);
+ }
+ }
+
+ if (depth) {
+ assert(fb->Visual.depthBits > 0);
+ _mesa_add_depth_renderbuffer(NULL, fb, fb->Visual.depthBits);
+ }
+
+ if (stencil) {
+ assert(fb->Visual.stencilBits > 0);
+ _mesa_add_stencil_renderbuffer(NULL, fb, fb->Visual.stencilBits);
+ }
+
+ if (accum) {
+ assert(fb->Visual.rgbMode);
+ assert(fb->Visual.accumRedBits > 0);
+ assert(fb->Visual.accumGreenBits > 0);
+ assert(fb->Visual.accumBlueBits > 0);
+ _mesa_add_accum_renderbuffer(NULL, fb,
+ fb->Visual.accumRedBits,
+ fb->Visual.accumGreenBits,
+ fb->Visual.accumBlueBits,
+ fb->Visual.accumAlphaBits);
+ }
+
+ if (aux) {
+ assert(fb->Visual.rgbMode);
+ assert(fb->Visual.numAuxBuffers > 0);
+ _mesa_add_aux_renderbuffers(NULL, fb, fb->Visual.redBits,
+ fb->Visual.numAuxBuffers);
+ }
+
+ if (alpha) {
+ assert(fb->Visual.rgbMode);
+ assert(fb->Visual.alphaBits > 0);
+ _mesa_add_alpha_renderbuffers(NULL, fb, fb->Visual.alphaBits,
+ frontLeft, backLeft,
+ frontRight, backRight);
+ }
+
+#if 0
+ if (multisample) {
+ /* maybe someday */
+ }
+#endif
+}
+
+
+/**
+ * Attach a renderbuffer to a framebuffer.
+ */
+void
+_mesa_add_renderbuffer(struct gl_framebuffer *fb,
+ GLuint bufferName, struct gl_renderbuffer *rb)
+{
+ assert(fb);
+ assert(rb);
+#if 00
+ /* there should be no previous renderbuffer on this attachment point! */
+ assert(fb->Attachment[bufferName].Renderbuffer == NULL);
+#endif
+ assert(bufferName < BUFFER_COUNT);
+
+ /* winsys vs. user-created buffer cross check */
+ if (fb->Name) {
+ assert(rb->Name);
+ }
+ else {
+ assert(!rb->Name);
+ }
+
+ fb->Attachment[bufferName].Type = GL_RENDERBUFFER_EXT;
+ fb->Attachment[bufferName].Complete = GL_TRUE;
+ fb->Attachment[bufferName].Renderbuffer = rb;
+}
+
+
+/**
+ * Create a new combined depth/stencil renderbuffer for implementing
+ * the GL_EXT_packed_depth_stencil extension.
+ * \return new depth/stencil renderbuffer
+ */
+struct gl_renderbuffer *
+_mesa_new_depthstencil_renderbuffer(GLcontext *ctx, GLuint name)
+{
+ struct gl_renderbuffer *dsrb;
+
+ dsrb = _mesa_new_renderbuffer(ctx, name);
+ if (!dsrb)
+ return NULL;
+
+ /* init fields not covered by _mesa_new_renderbuffer() */
+ dsrb->InternalFormat = GL_DEPTH24_STENCIL8_EXT;
+ dsrb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT;
+ dsrb->AllocStorage = _mesa_soft_renderbuffer_storage;
+
+ return dsrb;
+}
+
diff --git a/src/mesa/main/renderbuffer.h b/src/mesa/main/renderbuffer.h
new file mode 100644
index 00000000000..d8358e213cb
--- /dev/null
+++ b/src/mesa/main/renderbuffer.h
@@ -0,0 +1,103 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef RENDERBUFFER_H
+#define RENDERBUFFER_H
+
+
+extern void
+_mesa_init_renderbuffer(struct gl_renderbuffer *rb, GLuint name);
+
+extern struct gl_renderbuffer *
+_mesa_new_renderbuffer(GLcontext *ctx, GLuint name);
+
+extern void
+_mesa_delete_renderbuffer(struct gl_renderbuffer *rb);
+
+
+extern struct gl_renderbuffer *
+_mesa_new_soft_renderbuffer(GLcontext *ctx, GLuint name);
+
+
+extern GLboolean
+_mesa_soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
+ GLenum internalFormat,
+ GLuint width, GLuint height);
+
+extern GLboolean
+_mesa_add_color_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb,
+ GLuint rgbBits, GLuint alphaBits,
+ GLboolean frontLeft, GLboolean backLeft,
+ GLboolean frontRight, GLboolean backRight);
+
+extern GLboolean
+_mesa_add_color_index_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb,
+ GLuint indexBits,
+ GLboolean frontLeft, GLboolean backLeft,
+ GLboolean frontRight, GLboolean backRight);
+
+extern GLboolean
+_mesa_add_alpha_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb,
+ GLuint alphaBits,
+ GLboolean frontLeft, GLboolean backLeft,
+ GLboolean frontRight, GLboolean backRight);
+
+extern GLboolean
+_mesa_add_depth_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
+ GLuint depthBits);
+
+extern GLboolean
+_mesa_add_stencil_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
+ GLuint stencilBits);
+
+
+extern GLboolean
+_mesa_add_accum_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
+ GLuint redBits, GLuint greenBits,
+ GLuint blueBits, GLuint alphaBits);
+
+extern GLboolean
+_mesa_add_aux_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb,
+ GLuint bits, GLuint numBuffers);
+
+extern void
+_mesa_add_soft_renderbuffers(struct gl_framebuffer *fb,
+ GLboolean color,
+ GLboolean depth,
+ GLboolean stencil,
+ GLboolean accum,
+ GLboolean alpha,
+ GLboolean aux);
+
+extern void
+_mesa_add_renderbuffer(struct gl_framebuffer *fb,
+ GLuint bufferName, struct gl_renderbuffer *rb);
+
+
+extern struct gl_renderbuffer *
+_mesa_new_depthstencil_renderbuffer(GLcontext *ctx, GLuint name);
+
+
+#endif /* RENDERBUFFER_H */
diff --git a/src/mesa/main/simple_list.h b/src/mesa/main/simple_list.h
new file mode 100644
index 00000000000..63475f6f740
--- /dev/null
+++ b/src/mesa/main/simple_list.h
@@ -0,0 +1,197 @@
+/**
+ * \file simple_list.h
+ * Simple macros for type-safe, intrusive lists.
+ *
+ * Intended to work with a list sentinal which is created as an empty
+ * list. Insert & delete are O(1).
+ *
+ * \author
+ * (C) 1997, Keith Whitwell
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.5
+ *
+ * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef _SIMPLE_LIST_H
+#define _SIMPLE_LIST_H
+
+/**
+ * Remove an element from list.
+ *
+ * \param elem element to remove.
+ */
+#define remove_from_list(elem) \
+do { \
+ (elem)->next->prev = (elem)->prev; \
+ (elem)->prev->next = (elem)->next; \
+} while (0)
+
+/**
+ * Insert an element to the list head.
+ *
+ * \param list list.
+ * \param elem element to insert.
+ */
+#define insert_at_head(list, elem) \
+do { \
+ (elem)->prev = list; \
+ (elem)->next = (list)->next; \
+ (list)->next->prev = elem; \
+ (list)->next = elem; \
+} while(0)
+
+/**
+ * Insert an element to the list tail.
+ *
+ * \param list list.
+ * \param elem element to insert.
+ */
+#define insert_at_tail(list, elem) \
+do { \
+ (elem)->next = list; \
+ (elem)->prev = (list)->prev; \
+ (list)->prev->next = elem; \
+ (list)->prev = elem; \
+} while(0)
+
+/**
+ * Move an element to the list head.
+ *
+ * \param list list.
+ * \param elem element to move.
+ */
+#define move_to_head(list, elem) \
+do { \
+ remove_from_list(elem); \
+ insert_at_head(list, elem); \
+} while (0)
+
+/**
+ * Move an element to the list tail.
+ *
+ * \param list list.
+ * \param elem element to move.
+ */
+#define move_to_tail(list, elem) \
+do { \
+ remove_from_list(elem); \
+ insert_at_tail(list, elem); \
+} while (0)
+
+/**
+ * Make a empty list empty.
+ *
+ * \param sentinal list (sentinal element).
+ */
+#define make_empty_list(sentinal) \
+do { \
+ (sentinal)->next = sentinal; \
+ (sentinal)->prev = sentinal; \
+} while (0)
+
+/**
+ * Get list first element.
+ *
+ * \param list list.
+ *
+ * \return pointer to first element.
+ */
+#define first_elem(list) ((list)->next)
+
+/**
+ * Get list last element.
+ *
+ * \param list list.
+ *
+ * \return pointer to last element.
+ */
+#define last_elem(list) ((list)->prev)
+
+/**
+ * Get next element.
+ *
+ * \param elem element.
+ *
+ * \return pointer to next element.
+ */
+#define next_elem(elem) ((elem)->next)
+
+/**
+ * Get previous element.
+ *
+ * \param elem element.
+ *
+ * \return pointer to previous element.
+ */
+#define prev_elem(elem) ((elem)->prev)
+
+/**
+ * Test whether element is at end of the list.
+ *
+ * \param list list.
+ * \param elem element.
+ *
+ * \return non-zero if element is at end of list, or zero otherwise.
+ */
+#define at_end(list, elem) ((elem) == (list))
+
+/**
+ * Test if a list is empty.
+ *
+ * \param list list.
+ *
+ * \return non-zero if list empty, or zero otherwise.
+ */
+#define is_empty_list(list) ((list)->next == (list))
+
+/**
+ * Walk through the elements of a list.
+ *
+ * \param ptr pointer to the current element.
+ * \param list list.
+ *
+ * \note It should be followed by a { } block or a single statement, as in a \c
+ * for loop.
+ */
+#define foreach(ptr, list) \
+ for( ptr=(list)->next ; ptr!=list ; ptr=(ptr)->next )
+
+/**
+ * Walk through the elements of a list.
+ *
+ * Same as #foreach but lets you unlink the current value during a list
+ * traversal. Useful for freeing a list, element by element.
+ *
+ * \param ptr pointer to the current element.
+ * \param t temporary pointer.
+ * \param list list.
+ *
+ * \note It should be followed by a { } block or a single statement, as in a \c
+ * for loop.
+ */
+#define foreach_s(ptr, t, list) \
+ for(ptr=(list)->next,t=(ptr)->next; list != ptr; ptr=t, t=(t)->next)
+
+#endif
diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c
new file mode 100644
index 00000000000..7e452bdfd7f
--- /dev/null
+++ b/src/mesa/main/state.c
@@ -0,0 +1,1060 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/**
+ * \file state.c
+ * State management.
+ *
+ * This file manages recalculation of derived values in the __GLcontextRec.
+ * Also, this is where we initialize the API dispatch table.
+ */
+
+#include "glheader.h"
+#include "accum.h"
+#include "api_loopback.h"
+#if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program
+#include "arbprogram.h"
+#endif
+#if FEATURE_ATI_fragment_shader
+#include "atifragshader.h"
+#endif
+#include "attrib.h"
+#include "blend.h"
+#if FEATURE_ARB_vertex_buffer_object
+#include "bufferobj.h"
+#endif
+#include "buffers.h"
+#include "clip.h"
+#include "colortab.h"
+#include "context.h"
+#include "convolve.h"
+#include "depth.h"
+#include "dlist.h"
+#include "drawpix.h"
+#include "enable.h"
+#include "eval.h"
+#include "get.h"
+#include "feedback.h"
+#include "fog.h"
+#if FEATURE_EXT_framebuffer_object
+#include "fbobject.h"
+#endif
+#include "framebuffer.h"
+#include "hint.h"
+#include "histogram.h"
+#include "imports.h"
+#include "light.h"
+#include "lines.h"
+#include "macros.h"
+#include "matrix.h"
+#if FEATURE_ARB_occlusion_query
+#include "occlude.h"
+#endif
+#include "pixel.h"
+#include "points.h"
+#include "polygon.h"
+#include "rastpos.h"
+#include "state.h"
+#include "stencil.h"
+#include "teximage.h"
+#include "texobj.h"
+#include "texstate.h"
+#include "mtypes.h"
+#include "varray.h"
+#if FEATURE_NV_vertex_program
+#include "nvprogram.h"
+#endif
+#if FEATURE_NV_fragment_program
+#include "nvprogram.h"
+#include "program.h"
+#include "texenvprogram.h"
+#endif
+#if FEATURE_ARB_shader_objects
+#include "shaderobjects.h"
+#endif
+#include "debug.h"
+#include "dispatch.h"
+
+
+
+/**
+ * Initialize a dispatch table with pointers to Mesa's immediate-mode
+ * commands.
+ *
+ * Pointers to glBegin()/glEnd() object commands and a few others
+ * are provided via the GLvertexformat interface.
+ *
+ * \param ctx GL context to which \c exec belongs.
+ * \param exec dispatch table.
+ */
+void
+_mesa_init_exec_table(struct _glapi_table *exec)
+{
+#if _HAVE_FULL_GL
+ _mesa_loopback_init_api_table( exec );
+#endif
+
+ /* load the dispatch slots we understand */
+ SET_AlphaFunc(exec, _mesa_AlphaFunc);
+ SET_BlendFunc(exec, _mesa_BlendFunc);
+ SET_Clear(exec, _mesa_Clear);
+ SET_ClearColor(exec, _mesa_ClearColor);
+ SET_ClearStencil(exec, _mesa_ClearStencil);
+ SET_ColorMask(exec, _mesa_ColorMask);
+ SET_CullFace(exec, _mesa_CullFace);
+ SET_Disable(exec, _mesa_Disable);
+ SET_DrawBuffer(exec, _mesa_DrawBuffer);
+ SET_Enable(exec, _mesa_Enable);
+ SET_Finish(exec, _mesa_Finish);
+ SET_Flush(exec, _mesa_Flush);
+ SET_FrontFace(exec, _mesa_FrontFace);
+ SET_Frustum(exec, _mesa_Frustum);
+ SET_GetError(exec, _mesa_GetError);
+ SET_GetFloatv(exec, _mesa_GetFloatv);
+ SET_GetString(exec, _mesa_GetString);
+ SET_InitNames(exec, _mesa_InitNames);
+ SET_LineStipple(exec, _mesa_LineStipple);
+ SET_LineWidth(exec, _mesa_LineWidth);
+ SET_LoadIdentity(exec, _mesa_LoadIdentity);
+ SET_LoadMatrixf(exec, _mesa_LoadMatrixf);
+ SET_LoadName(exec, _mesa_LoadName);
+ SET_LogicOp(exec, _mesa_LogicOp);
+ SET_MatrixMode(exec, _mesa_MatrixMode);
+ SET_MultMatrixf(exec, _mesa_MultMatrixf);
+ SET_Ortho(exec, _mesa_Ortho);
+ SET_PixelStorei(exec, _mesa_PixelStorei);
+ SET_PopMatrix(exec, _mesa_PopMatrix);
+ SET_PopName(exec, _mesa_PopName);
+ SET_PushMatrix(exec, _mesa_PushMatrix);
+ SET_PushName(exec, _mesa_PushName);
+ SET_RasterPos2f(exec, _mesa_RasterPos2f);
+ SET_RasterPos2fv(exec, _mesa_RasterPos2fv);
+ SET_RasterPos2i(exec, _mesa_RasterPos2i);
+ SET_RasterPos2iv(exec, _mesa_RasterPos2iv);
+ SET_ReadBuffer(exec, _mesa_ReadBuffer);
+ SET_RenderMode(exec, _mesa_RenderMode);
+ SET_Rotatef(exec, _mesa_Rotatef);
+ SET_Scalef(exec, _mesa_Scalef);
+ SET_Scissor(exec, _mesa_Scissor);
+ SET_SelectBuffer(exec, _mesa_SelectBuffer);
+ SET_ShadeModel(exec, _mesa_ShadeModel);
+ SET_StencilFunc(exec, _mesa_StencilFunc);
+ SET_StencilMask(exec, _mesa_StencilMask);
+ SET_StencilOp(exec, _mesa_StencilOp);
+ SET_TexEnvfv(exec, _mesa_TexEnvfv);
+ SET_TexEnvi(exec, _mesa_TexEnvi);
+ SET_TexImage2D(exec, _mesa_TexImage2D);
+ SET_TexParameteri(exec, _mesa_TexParameteri);
+ SET_Translatef(exec, _mesa_Translatef);
+ SET_Viewport(exec, _mesa_Viewport);
+#if _HAVE_FULL_GL
+ SET_Accum(exec, _mesa_Accum);
+ SET_Bitmap(exec, _mesa_Bitmap);
+ SET_CallList(exec, _mesa_CallList);
+ SET_CallLists(exec, _mesa_CallLists);
+ SET_ClearAccum(exec, _mesa_ClearAccum);
+ SET_ClearDepth(exec, _mesa_ClearDepth);
+ SET_ClearIndex(exec, _mesa_ClearIndex);
+ SET_ClipPlane(exec, _mesa_ClipPlane);
+ SET_ColorMaterial(exec, _mesa_ColorMaterial);
+ SET_CopyPixels(exec, _mesa_CopyPixels);
+ SET_CullParameterfvEXT(exec, _mesa_CullParameterfvEXT);
+ SET_CullParameterdvEXT(exec, _mesa_CullParameterdvEXT);
+ SET_DeleteLists(exec, _mesa_DeleteLists);
+ SET_DepthFunc(exec, _mesa_DepthFunc);
+ SET_DepthMask(exec, _mesa_DepthMask);
+ SET_DepthRange(exec, _mesa_DepthRange);
+ SET_DrawPixels(exec, _mesa_DrawPixels);
+ SET_EndList(exec, _mesa_EndList);
+ SET_FeedbackBuffer(exec, _mesa_FeedbackBuffer);
+ SET_FogCoordPointerEXT(exec, _mesa_FogCoordPointerEXT);
+ SET_Fogf(exec, _mesa_Fogf);
+ SET_Fogfv(exec, _mesa_Fogfv);
+ SET_Fogi(exec, _mesa_Fogi);
+ SET_Fogiv(exec, _mesa_Fogiv);
+ SET_GenLists(exec, _mesa_GenLists);
+ SET_GetClipPlane(exec, _mesa_GetClipPlane);
+ SET_GetBooleanv(exec, _mesa_GetBooleanv);
+ SET_GetDoublev(exec, _mesa_GetDoublev);
+ SET_GetIntegerv(exec, _mesa_GetIntegerv);
+ SET_GetLightfv(exec, _mesa_GetLightfv);
+ SET_GetLightiv(exec, _mesa_GetLightiv);
+ SET_GetMapdv(exec, _mesa_GetMapdv);
+ SET_GetMapfv(exec, _mesa_GetMapfv);
+ SET_GetMapiv(exec, _mesa_GetMapiv);
+ SET_GetMaterialfv(exec, _mesa_GetMaterialfv);
+ SET_GetMaterialiv(exec, _mesa_GetMaterialiv);
+ SET_GetPixelMapfv(exec, _mesa_GetPixelMapfv);
+ SET_GetPixelMapuiv(exec, _mesa_GetPixelMapuiv);
+ SET_GetPixelMapusv(exec, _mesa_GetPixelMapusv);
+ SET_GetPolygonStipple(exec, _mesa_GetPolygonStipple);
+ SET_GetTexEnvfv(exec, _mesa_GetTexEnvfv);
+ SET_GetTexEnviv(exec, _mesa_GetTexEnviv);
+ SET_GetTexLevelParameterfv(exec, _mesa_GetTexLevelParameterfv);
+ SET_GetTexLevelParameteriv(exec, _mesa_GetTexLevelParameteriv);
+ SET_GetTexParameterfv(exec, _mesa_GetTexParameterfv);
+ SET_GetTexParameteriv(exec, _mesa_GetTexParameteriv);
+ SET_GetTexGendv(exec, _mesa_GetTexGendv);
+ SET_GetTexGenfv(exec, _mesa_GetTexGenfv);
+ SET_GetTexGeniv(exec, _mesa_GetTexGeniv);
+ SET_GetTexImage(exec, _mesa_GetTexImage);
+ SET_Hint(exec, _mesa_Hint);
+ SET_IndexMask(exec, _mesa_IndexMask);
+ SET_IsEnabled(exec, _mesa_IsEnabled);
+ SET_IsList(exec, _mesa_IsList);
+ SET_LightModelf(exec, _mesa_LightModelf);
+ SET_LightModelfv(exec, _mesa_LightModelfv);
+ SET_LightModeli(exec, _mesa_LightModeli);
+ SET_LightModeliv(exec, _mesa_LightModeliv);
+ SET_Lightf(exec, _mesa_Lightf);
+ SET_Lightfv(exec, _mesa_Lightfv);
+ SET_Lighti(exec, _mesa_Lighti);
+ SET_Lightiv(exec, _mesa_Lightiv);
+ SET_ListBase(exec, _mesa_ListBase);
+ SET_LoadMatrixd(exec, _mesa_LoadMatrixd);
+ SET_Map1d(exec, _mesa_Map1d);
+ SET_Map1f(exec, _mesa_Map1f);
+ SET_Map2d(exec, _mesa_Map2d);
+ SET_Map2f(exec, _mesa_Map2f);
+ SET_MapGrid1d(exec, _mesa_MapGrid1d);
+ SET_MapGrid1f(exec, _mesa_MapGrid1f);
+ SET_MapGrid2d(exec, _mesa_MapGrid2d);
+ SET_MapGrid2f(exec, _mesa_MapGrid2f);
+ SET_MultMatrixd(exec, _mesa_MultMatrixd);
+ SET_NewList(exec, _mesa_NewList);
+ SET_PassThrough(exec, _mesa_PassThrough);
+ SET_PixelMapfv(exec, _mesa_PixelMapfv);
+ SET_PixelMapuiv(exec, _mesa_PixelMapuiv);
+ SET_PixelMapusv(exec, _mesa_PixelMapusv);
+ SET_PixelStoref(exec, _mesa_PixelStoref);
+ SET_PixelTransferf(exec, _mesa_PixelTransferf);
+ SET_PixelTransferi(exec, _mesa_PixelTransferi);
+ SET_PixelZoom(exec, _mesa_PixelZoom);
+ SET_PointSize(exec, _mesa_PointSize);
+ SET_PolygonMode(exec, _mesa_PolygonMode);
+ SET_PolygonOffset(exec, _mesa_PolygonOffset);
+ SET_PolygonStipple(exec, _mesa_PolygonStipple);
+ SET_PopAttrib(exec, _mesa_PopAttrib);
+ SET_PushAttrib(exec, _mesa_PushAttrib);
+ SET_RasterPos2d(exec, _mesa_RasterPos2d);
+ SET_RasterPos2dv(exec, _mesa_RasterPos2dv);
+ SET_RasterPos2s(exec, _mesa_RasterPos2s);
+ SET_RasterPos2sv(exec, _mesa_RasterPos2sv);
+ SET_RasterPos3d(exec, _mesa_RasterPos3d);
+ SET_RasterPos3dv(exec, _mesa_RasterPos3dv);
+ SET_RasterPos3f(exec, _mesa_RasterPos3f);
+ SET_RasterPos3fv(exec, _mesa_RasterPos3fv);
+ SET_RasterPos3i(exec, _mesa_RasterPos3i);
+ SET_RasterPos3iv(exec, _mesa_RasterPos3iv);
+ SET_RasterPos3s(exec, _mesa_RasterPos3s);
+ SET_RasterPos3sv(exec, _mesa_RasterPos3sv);
+ SET_RasterPos4d(exec, _mesa_RasterPos4d);
+ SET_RasterPos4dv(exec, _mesa_RasterPos4dv);
+ SET_RasterPos4f(exec, _mesa_RasterPos4f);
+ SET_RasterPos4fv(exec, _mesa_RasterPos4fv);
+ SET_RasterPos4i(exec, _mesa_RasterPos4i);
+ SET_RasterPos4iv(exec, _mesa_RasterPos4iv);
+ SET_RasterPos4s(exec, _mesa_RasterPos4s);
+ SET_RasterPos4sv(exec, _mesa_RasterPos4sv);
+ SET_ReadPixels(exec, _mesa_ReadPixels);
+ SET_Rotated(exec, _mesa_Rotated);
+ SET_Scaled(exec, _mesa_Scaled);
+ SET_SecondaryColorPointerEXT(exec, _mesa_SecondaryColorPointerEXT);
+ SET_TexEnvf(exec, _mesa_TexEnvf);
+ SET_TexEnviv(exec, _mesa_TexEnviv);
+ SET_TexGend(exec, _mesa_TexGend);
+ SET_TexGendv(exec, _mesa_TexGendv);
+ SET_TexGenf(exec, _mesa_TexGenf);
+ SET_TexGenfv(exec, _mesa_TexGenfv);
+ SET_TexGeni(exec, _mesa_TexGeni);
+ SET_TexGeniv(exec, _mesa_TexGeniv);
+ SET_TexImage1D(exec, _mesa_TexImage1D);
+ SET_TexParameterf(exec, _mesa_TexParameterf);
+ SET_TexParameterfv(exec, _mesa_TexParameterfv);
+ SET_TexParameteriv(exec, _mesa_TexParameteriv);
+ SET_Translated(exec, _mesa_Translated);
+#endif
+
+ /* 1.1 */
+ SET_BindTexture(exec, _mesa_BindTexture);
+ SET_DeleteTextures(exec, _mesa_DeleteTextures);
+ SET_GenTextures(exec, _mesa_GenTextures);
+#if _HAVE_FULL_GL
+ SET_AreTexturesResident(exec, _mesa_AreTexturesResident);
+ SET_AreTexturesResidentEXT(exec, _mesa_AreTexturesResident);
+ SET_ColorPointer(exec, _mesa_ColorPointer);
+ SET_CopyTexImage1D(exec, _mesa_CopyTexImage1D);
+ SET_CopyTexImage2D(exec, _mesa_CopyTexImage2D);
+ SET_CopyTexSubImage1D(exec, _mesa_CopyTexSubImage1D);
+ SET_CopyTexSubImage2D(exec, _mesa_CopyTexSubImage2D);
+ SET_DisableClientState(exec, _mesa_DisableClientState);
+ SET_EdgeFlagPointer(exec, _mesa_EdgeFlagPointer);
+ SET_EnableClientState(exec, _mesa_EnableClientState);
+ SET_GenTexturesEXT(exec, _mesa_GenTextures);
+ SET_GetPointerv(exec, _mesa_GetPointerv);
+ SET_IndexPointer(exec, _mesa_IndexPointer);
+ SET_InterleavedArrays(exec, _mesa_InterleavedArrays);
+ SET_IsTexture(exec, _mesa_IsTexture);
+ SET_IsTextureEXT(exec, _mesa_IsTexture);
+ SET_NormalPointer(exec, _mesa_NormalPointer);
+ SET_PopClientAttrib(exec, _mesa_PopClientAttrib);
+ SET_PrioritizeTextures(exec, _mesa_PrioritizeTextures);
+ SET_PushClientAttrib(exec, _mesa_PushClientAttrib);
+ SET_TexCoordPointer(exec, _mesa_TexCoordPointer);
+ SET_TexSubImage1D(exec, _mesa_TexSubImage1D);
+ SET_TexSubImage2D(exec, _mesa_TexSubImage2D);
+ SET_VertexPointer(exec, _mesa_VertexPointer);
+#endif
+
+ /* 1.2 */
+#if _HAVE_FULL_GL
+ SET_CopyTexSubImage3D(exec, _mesa_CopyTexSubImage3D);
+ SET_TexImage3D(exec, _mesa_TexImage3D);
+ SET_TexSubImage3D(exec, _mesa_TexSubImage3D);
+#endif
+
+ /* OpenGL 1.2 GL_ARB_imaging */
+#if _HAVE_FULL_GL
+ SET_BlendColor(exec, _mesa_BlendColor);
+ SET_BlendEquation(exec, _mesa_BlendEquation);
+ SET_BlendEquationSeparateEXT(exec, _mesa_BlendEquationSeparateEXT);
+ SET_ColorSubTable(exec, _mesa_ColorSubTable);
+ SET_ColorTable(exec, _mesa_ColorTable);
+ SET_ColorTableParameterfv(exec, _mesa_ColorTableParameterfv);
+ SET_ColorTableParameteriv(exec, _mesa_ColorTableParameteriv);
+ SET_ConvolutionFilter1D(exec, _mesa_ConvolutionFilter1D);
+ SET_ConvolutionFilter2D(exec, _mesa_ConvolutionFilter2D);
+ SET_ConvolutionParameterf(exec, _mesa_ConvolutionParameterf);
+ SET_ConvolutionParameterfv(exec, _mesa_ConvolutionParameterfv);
+ SET_ConvolutionParameteri(exec, _mesa_ConvolutionParameteri);
+ SET_ConvolutionParameteriv(exec, _mesa_ConvolutionParameteriv);
+ SET_CopyColorSubTable(exec, _mesa_CopyColorSubTable);
+ SET_CopyColorTable(exec, _mesa_CopyColorTable);
+ SET_CopyConvolutionFilter1D(exec, _mesa_CopyConvolutionFilter1D);
+ SET_CopyConvolutionFilter2D(exec, _mesa_CopyConvolutionFilter2D);
+ SET_GetColorTable(exec, _mesa_GetColorTable);
+ SET_GetColorTableEXT(exec, _mesa_GetColorTable);
+ SET_GetColorTableParameterfv(exec, _mesa_GetColorTableParameterfv);
+ SET_GetColorTableParameterfvEXT(exec, _mesa_GetColorTableParameterfv);
+ SET_GetColorTableParameteriv(exec, _mesa_GetColorTableParameteriv);
+ SET_GetColorTableParameterivEXT(exec, _mesa_GetColorTableParameteriv);
+ SET_GetConvolutionFilter(exec, _mesa_GetConvolutionFilter);
+ SET_GetConvolutionFilterEXT(exec, _mesa_GetConvolutionFilter);
+ SET_GetConvolutionParameterfv(exec, _mesa_GetConvolutionParameterfv);
+ SET_GetConvolutionParameterfvEXT(exec, _mesa_GetConvolutionParameterfv);
+ SET_GetConvolutionParameteriv(exec, _mesa_GetConvolutionParameteriv);
+ SET_GetConvolutionParameterivEXT(exec, _mesa_GetConvolutionParameteriv);
+ SET_GetHistogram(exec, _mesa_GetHistogram);
+ SET_GetHistogramEXT(exec, _mesa_GetHistogram);
+ SET_GetHistogramParameterfv(exec, _mesa_GetHistogramParameterfv);
+ SET_GetHistogramParameterfvEXT(exec, _mesa_GetHistogramParameterfv);
+ SET_GetHistogramParameteriv(exec, _mesa_GetHistogramParameteriv);
+ SET_GetHistogramParameterivEXT(exec, _mesa_GetHistogramParameteriv);
+ SET_GetMinmax(exec, _mesa_GetMinmax);
+ SET_GetMinmaxEXT(exec, _mesa_GetMinmax);
+ SET_GetMinmaxParameterfv(exec, _mesa_GetMinmaxParameterfv);
+ SET_GetMinmaxParameterfvEXT(exec, _mesa_GetMinmaxParameterfv);
+ SET_GetMinmaxParameteriv(exec, _mesa_GetMinmaxParameteriv);
+ SET_GetMinmaxParameterivEXT(exec, _mesa_GetMinmaxParameteriv);
+ SET_GetSeparableFilter(exec, _mesa_GetSeparableFilter);
+ SET_GetSeparableFilterEXT(exec, _mesa_GetSeparableFilter);
+ SET_Histogram(exec, _mesa_Histogram);
+ SET_Minmax(exec, _mesa_Minmax);
+ SET_ResetHistogram(exec, _mesa_ResetHistogram);
+ SET_ResetMinmax(exec, _mesa_ResetMinmax);
+ SET_SeparableFilter2D(exec, _mesa_SeparableFilter2D);
+#endif
+
+ /* OpenGL 2.0 */
+ SET_StencilFuncSeparate(exec, _mesa_StencilFuncSeparate);
+ SET_StencilMaskSeparate(exec, _mesa_StencilMaskSeparate);
+ SET_StencilOpSeparate(exec, _mesa_StencilOpSeparate);
+
+ /* 2. GL_EXT_blend_color */
+#if 0
+/* SET_BlendColorEXT(exec, _mesa_BlendColorEXT); */
+#endif
+
+ /* 3. GL_EXT_polygon_offset */
+#if _HAVE_FULL_GL
+ SET_PolygonOffsetEXT(exec, _mesa_PolygonOffsetEXT);
+#endif
+
+ /* 6. GL_EXT_texture3d */
+#if 0
+/* SET_CopyTexSubImage3DEXT(exec, _mesa_CopyTexSubImage3D); */
+/* SET_TexImage3DEXT(exec, _mesa_TexImage3DEXT); */
+/* SET_TexSubImage3DEXT(exec, _mesa_TexSubImage3D); */
+#endif
+
+ /* 11. GL_EXT_histogram */
+#if _HAVE_FULL_GL
+ SET_GetHistogramEXT(exec, _mesa_GetHistogram);
+ SET_GetHistogramParameterfvEXT(exec, _mesa_GetHistogramParameterfv);
+ SET_GetHistogramParameterivEXT(exec, _mesa_GetHistogramParameteriv);
+ SET_GetMinmaxEXT(exec, _mesa_GetMinmax);
+ SET_GetMinmaxParameterfvEXT(exec, _mesa_GetMinmaxParameterfv);
+ SET_GetMinmaxParameterivEXT(exec, _mesa_GetMinmaxParameteriv);
+#endif
+
+ /* 30. GL_EXT_vertex_array */
+#if _HAVE_FULL_GL
+ SET_ColorPointerEXT(exec, _mesa_ColorPointerEXT);
+ SET_EdgeFlagPointerEXT(exec, _mesa_EdgeFlagPointerEXT);
+ SET_IndexPointerEXT(exec, _mesa_IndexPointerEXT);
+ SET_NormalPointerEXT(exec, _mesa_NormalPointerEXT);
+ SET_TexCoordPointerEXT(exec, _mesa_TexCoordPointerEXT);
+ SET_VertexPointerEXT(exec, _mesa_VertexPointerEXT);
+#endif
+
+ /* 37. GL_EXT_blend_minmax */
+#if 0
+ SET_BlendEquationEXT(exec, _mesa_BlendEquationEXT);
+#endif
+
+ /* 54. GL_EXT_point_parameters */
+#if _HAVE_FULL_GL
+ SET_PointParameterfEXT(exec, _mesa_PointParameterfEXT);
+ SET_PointParameterfvEXT(exec, _mesa_PointParameterfvEXT);
+#endif
+
+ /* 78. GL_EXT_paletted_texture */
+#if 0
+ SET_ColorTableEXT(exec, _mesa_ColorTableEXT);
+ SET_ColorSubTableEXT(exec, _mesa_ColorSubTableEXT);
+#endif
+#if _HAVE_FULL_GL
+ SET_GetColorTableEXT(exec, _mesa_GetColorTable);
+ SET_GetColorTableParameterfvEXT(exec, _mesa_GetColorTableParameterfv);
+ SET_GetColorTableParameterivEXT(exec, _mesa_GetColorTableParameteriv);
+#endif
+
+ /* 97. GL_EXT_compiled_vertex_array */
+#if _HAVE_FULL_GL
+ SET_LockArraysEXT(exec, _mesa_LockArraysEXT);
+ SET_UnlockArraysEXT(exec, _mesa_UnlockArraysEXT);
+#endif
+
+ /* 148. GL_EXT_multi_draw_arrays */
+#if _HAVE_FULL_GL
+ SET_MultiDrawArraysEXT(exec, _mesa_MultiDrawArraysEXT);
+ SET_MultiDrawElementsEXT(exec, _mesa_MultiDrawElementsEXT);
+#endif
+
+ /* 173. GL_INGR_blend_func_separate */
+#if _HAVE_FULL_GL
+ SET_BlendFuncSeparateEXT(exec, _mesa_BlendFuncSeparateEXT);
+#endif
+
+ /* 196. GL_MESA_resize_buffers */
+#if _HAVE_FULL_GL
+ SET_ResizeBuffersMESA(exec, _mesa_ResizeBuffersMESA);
+#endif
+
+ /* 197. GL_MESA_window_pos */
+#if _HAVE_FULL_GL
+ SET_WindowPos2dMESA(exec, _mesa_WindowPos2dMESA);
+ SET_WindowPos2dvMESA(exec, _mesa_WindowPos2dvMESA);
+ SET_WindowPos2fMESA(exec, _mesa_WindowPos2fMESA);
+ SET_WindowPos2fvMESA(exec, _mesa_WindowPos2fvMESA);
+ SET_WindowPos2iMESA(exec, _mesa_WindowPos2iMESA);
+ SET_WindowPos2ivMESA(exec, _mesa_WindowPos2ivMESA);
+ SET_WindowPos2sMESA(exec, _mesa_WindowPos2sMESA);
+ SET_WindowPos2svMESA(exec, _mesa_WindowPos2svMESA);
+ SET_WindowPos3dMESA(exec, _mesa_WindowPos3dMESA);
+ SET_WindowPos3dvMESA(exec, _mesa_WindowPos3dvMESA);
+ SET_WindowPos3fMESA(exec, _mesa_WindowPos3fMESA);
+ SET_WindowPos3fvMESA(exec, _mesa_WindowPos3fvMESA);
+ SET_WindowPos3iMESA(exec, _mesa_WindowPos3iMESA);
+ SET_WindowPos3ivMESA(exec, _mesa_WindowPos3ivMESA);
+ SET_WindowPos3sMESA(exec, _mesa_WindowPos3sMESA);
+ SET_WindowPos3svMESA(exec, _mesa_WindowPos3svMESA);
+ SET_WindowPos4dMESA(exec, _mesa_WindowPos4dMESA);
+ SET_WindowPos4dvMESA(exec, _mesa_WindowPos4dvMESA);
+ SET_WindowPos4fMESA(exec, _mesa_WindowPos4fMESA);
+ SET_WindowPos4fvMESA(exec, _mesa_WindowPos4fvMESA);
+ SET_WindowPos4iMESA(exec, _mesa_WindowPos4iMESA);
+ SET_WindowPos4ivMESA(exec, _mesa_WindowPos4ivMESA);
+ SET_WindowPos4sMESA(exec, _mesa_WindowPos4sMESA);
+ SET_WindowPos4svMESA(exec, _mesa_WindowPos4svMESA);
+#endif
+
+ /* 200. GL_IBM_multimode_draw_arrays */
+#if _HAVE_FULL_GL
+ SET_MultiModeDrawArraysIBM(exec, _mesa_MultiModeDrawArraysIBM);
+ SET_MultiModeDrawElementsIBM(exec, _mesa_MultiModeDrawElementsIBM);
+#endif
+
+ /* 233. GL_NV_vertex_program */
+#if FEATURE_NV_vertex_program
+ SET_BindProgramNV(exec, _mesa_BindProgram);
+ SET_DeleteProgramsNV(exec, _mesa_DeletePrograms);
+ SET_ExecuteProgramNV(exec, _mesa_ExecuteProgramNV);
+ SET_GenProgramsNV(exec, _mesa_GenPrograms);
+ SET_AreProgramsResidentNV(exec, _mesa_AreProgramsResidentNV);
+ SET_RequestResidentProgramsNV(exec, _mesa_RequestResidentProgramsNV);
+ SET_GetProgramParameterfvNV(exec, _mesa_GetProgramParameterfvNV);
+ SET_GetProgramParameterdvNV(exec, _mesa_GetProgramParameterdvNV);
+ SET_GetProgramivNV(exec, _mesa_GetProgramivNV);
+ SET_GetProgramStringNV(exec, _mesa_GetProgramStringNV);
+ SET_GetTrackMatrixivNV(exec, _mesa_GetTrackMatrixivNV);
+ SET_GetVertexAttribdvNV(exec, _mesa_GetVertexAttribdvNV);
+ SET_GetVertexAttribfvNV(exec, _mesa_GetVertexAttribfvNV);
+ SET_GetVertexAttribivNV(exec, _mesa_GetVertexAttribivNV);
+ SET_GetVertexAttribPointervNV(exec, _mesa_GetVertexAttribPointervNV);
+ SET_IsProgramNV(exec, _mesa_IsProgram);
+ SET_LoadProgramNV(exec, _mesa_LoadProgramNV);
+ SET_ProgramParameter4dNV(exec, _mesa_ProgramParameter4dNV);
+ SET_ProgramParameter4dvNV(exec, _mesa_ProgramParameter4dvNV);
+ SET_ProgramParameter4fNV(exec, _mesa_ProgramParameter4fNV);
+ SET_ProgramParameter4fvNV(exec, _mesa_ProgramParameter4fvNV);
+ SET_ProgramParameters4dvNV(exec, _mesa_ProgramParameters4dvNV);
+ SET_ProgramParameters4fvNV(exec, _mesa_ProgramParameters4fvNV);
+ SET_TrackMatrixNV(exec, _mesa_TrackMatrixNV);
+ SET_VertexAttribPointerNV(exec, _mesa_VertexAttribPointerNV);
+ /* glVertexAttrib*NV functions handled in api_loopback.c */
+#endif
+
+ /* 282. GL_NV_fragment_program */
+#if FEATURE_NV_fragment_program
+ SET_ProgramNamedParameter4fNV(exec, _mesa_ProgramNamedParameter4fNV);
+ SET_ProgramNamedParameter4dNV(exec, _mesa_ProgramNamedParameter4dNV);
+ SET_ProgramNamedParameter4fvNV(exec, _mesa_ProgramNamedParameter4fvNV);
+ SET_ProgramNamedParameter4dvNV(exec, _mesa_ProgramNamedParameter4dvNV);
+ SET_GetProgramNamedParameterfvNV(exec, _mesa_GetProgramNamedParameterfvNV);
+ SET_GetProgramNamedParameterdvNV(exec, _mesa_GetProgramNamedParameterdvNV);
+ SET_ProgramLocalParameter4dARB(exec, _mesa_ProgramLocalParameter4dARB);
+ SET_ProgramLocalParameter4dvARB(exec, _mesa_ProgramLocalParameter4dvARB);
+ SET_ProgramLocalParameter4fARB(exec, _mesa_ProgramLocalParameter4fARB);
+ SET_ProgramLocalParameter4fvARB(exec, _mesa_ProgramLocalParameter4fvARB);
+ SET_GetProgramLocalParameterdvARB(exec, _mesa_GetProgramLocalParameterdvARB);
+ SET_GetProgramLocalParameterfvARB(exec, _mesa_GetProgramLocalParameterfvARB);
+#endif
+
+ /* 262. GL_NV_point_sprite */
+#if _HAVE_FULL_GL
+ SET_PointParameteriNV(exec, _mesa_PointParameteriNV);
+ SET_PointParameterivNV(exec, _mesa_PointParameterivNV);
+#endif
+
+ /* 268. GL_EXT_stencil_two_side */
+#if _HAVE_FULL_GL
+ SET_ActiveStencilFaceEXT(exec, _mesa_ActiveStencilFaceEXT);
+#endif
+
+ /* ???. GL_EXT_depth_bounds_test */
+ SET_DepthBoundsEXT(exec, _mesa_DepthBoundsEXT);
+
+ /* ARB 1. GL_ARB_multitexture */
+#if _HAVE_FULL_GL
+ SET_ActiveTextureARB(exec, _mesa_ActiveTextureARB);
+ SET_ClientActiveTextureARB(exec, _mesa_ClientActiveTextureARB);
+#endif
+
+ /* ARB 3. GL_ARB_transpose_matrix */
+#if _HAVE_FULL_GL
+ SET_LoadTransposeMatrixdARB(exec, _mesa_LoadTransposeMatrixdARB);
+ SET_LoadTransposeMatrixfARB(exec, _mesa_LoadTransposeMatrixfARB);
+ SET_MultTransposeMatrixdARB(exec, _mesa_MultTransposeMatrixdARB);
+ SET_MultTransposeMatrixfARB(exec, _mesa_MultTransposeMatrixfARB);
+#endif
+
+ /* ARB 5. GL_ARB_multisample */
+#if _HAVE_FULL_GL
+ SET_SampleCoverageARB(exec, _mesa_SampleCoverageARB);
+#endif
+
+ /* ARB 12. GL_ARB_texture_compression */
+#if _HAVE_FULL_GL
+ SET_CompressedTexImage3DARB(exec, _mesa_CompressedTexImage3DARB);
+ SET_CompressedTexImage2DARB(exec, _mesa_CompressedTexImage2DARB);
+ SET_CompressedTexImage1DARB(exec, _mesa_CompressedTexImage1DARB);
+ SET_CompressedTexSubImage3DARB(exec, _mesa_CompressedTexSubImage3DARB);
+ SET_CompressedTexSubImage2DARB(exec, _mesa_CompressedTexSubImage2DARB);
+ SET_CompressedTexSubImage1DARB(exec, _mesa_CompressedTexSubImage1DARB);
+ SET_GetCompressedTexImageARB(exec, _mesa_GetCompressedTexImageARB);
+#endif
+
+ /* ARB 14. GL_ARB_point_parameters */
+ /* reuse EXT_point_parameters functions */
+
+ /* ARB 26. GL_ARB_vertex_program */
+ /* ARB 27. GL_ARB_fragment_program */
+#if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program
+ /* glVertexAttrib1sARB aliases glVertexAttrib1sNV */
+ /* glVertexAttrib1fARB aliases glVertexAttrib1fNV */
+ /* glVertexAttrib1dARB aliases glVertexAttrib1dNV */
+ /* glVertexAttrib2sARB aliases glVertexAttrib2sNV */
+ /* glVertexAttrib2fARB aliases glVertexAttrib2fNV */
+ /* glVertexAttrib2dARB aliases glVertexAttrib2dNV */
+ /* glVertexAttrib3sARB aliases glVertexAttrib3sNV */
+ /* glVertexAttrib3fARB aliases glVertexAttrib3fNV */
+ /* glVertexAttrib3dARB aliases glVertexAttrib3dNV */
+ /* glVertexAttrib4sARB aliases glVertexAttrib4sNV */
+ /* glVertexAttrib4fARB aliases glVertexAttrib4fNV */
+ /* glVertexAttrib4dARB aliases glVertexAttrib4dNV */
+ /* glVertexAttrib4NubARB aliases glVertexAttrib4NubNV */
+ /* glVertexAttrib1svARB aliases glVertexAttrib1svNV */
+ /* glVertexAttrib1fvARB aliases glVertexAttrib1fvNV */
+ /* glVertexAttrib1dvARB aliases glVertexAttrib1dvNV */
+ /* glVertexAttrib2svARB aliases glVertexAttrib2svNV */
+ /* glVertexAttrib2fvARB aliases glVertexAttrib2fvNV */
+ /* glVertexAttrib2dvARB aliases glVertexAttrib2dvNV */
+ /* glVertexAttrib3svARB aliases glVertexAttrib3svNV */
+ /* glVertexAttrib3fvARB aliases glVertexAttrib3fvNV */
+ /* glVertexAttrib3dvARB aliases glVertexAttrib3dvNV */
+ /* glVertexAttrib4svARB aliases glVertexAttrib4svNV */
+ /* glVertexAttrib4fvARB aliases glVertexAttrib4fvNV */
+ /* glVertexAttrib4dvARB aliases glVertexAttrib4dvNV */
+ /* glVertexAttrib4NubvARB aliases glVertexAttrib4NubvNV */
+ /* glVertexAttrib4bvARB handled in api_loopback.c */
+ /* glVertexAttrib4ivARB handled in api_loopback.c */
+ /* glVertexAttrib4ubvARB handled in api_loopback.c */
+ /* glVertexAttrib4usvARB handled in api_loopback.c */
+ /* glVertexAttrib4uivARB handled in api_loopback.c */
+ /* glVertexAttrib4NbvARB handled in api_loopback.c */
+ /* glVertexAttrib4NsvARB handled in api_loopback.c */
+ /* glVertexAttrib4NivARB handled in api_loopback.c */
+ /* glVertexAttrib4NusvARB handled in api_loopback.c */
+ /* glVertexAttrib4NuivARB handled in api_loopback.c */
+ SET_VertexAttribPointerARB(exec, _mesa_VertexAttribPointerARB);
+ SET_EnableVertexAttribArrayARB(exec, _mesa_EnableVertexAttribArrayARB);
+ SET_DisableVertexAttribArrayARB(exec, _mesa_DisableVertexAttribArrayARB);
+ SET_ProgramStringARB(exec, _mesa_ProgramStringARB);
+ /* glBindProgramARB aliases glBindProgramNV */
+ /* glDeleteProgramsARB aliases glDeleteProgramsNV */
+ /* glGenProgramsARB aliases glGenProgramsNV */
+ /* glIsProgramARB aliases glIsProgramNV */
+ SET_GetVertexAttribdvARB(exec, _mesa_GetVertexAttribdvARB);
+ SET_GetVertexAttribfvARB(exec, _mesa_GetVertexAttribfvARB);
+ SET_GetVertexAttribivARB(exec, _mesa_GetVertexAttribivARB);
+ /* glGetVertexAttribPointervARB aliases glGetVertexAttribPointervNV */
+ SET_ProgramEnvParameter4dARB(exec, _mesa_ProgramEnvParameter4dARB);
+ SET_ProgramEnvParameter4dvARB(exec, _mesa_ProgramEnvParameter4dvARB);
+ SET_ProgramEnvParameter4fARB(exec, _mesa_ProgramEnvParameter4fARB);
+ SET_ProgramEnvParameter4fvARB(exec, _mesa_ProgramEnvParameter4fvARB);
+ SET_ProgramLocalParameter4dARB(exec, _mesa_ProgramLocalParameter4dARB);
+ SET_ProgramLocalParameter4dvARB(exec, _mesa_ProgramLocalParameter4dvARB);
+ SET_ProgramLocalParameter4fARB(exec, _mesa_ProgramLocalParameter4fARB);
+ SET_ProgramLocalParameter4fvARB(exec, _mesa_ProgramLocalParameter4fvARB);
+ SET_GetProgramEnvParameterdvARB(exec, _mesa_GetProgramEnvParameterdvARB);
+ SET_GetProgramEnvParameterfvARB(exec, _mesa_GetProgramEnvParameterfvARB);
+ SET_GetProgramLocalParameterdvARB(exec, _mesa_GetProgramLocalParameterdvARB);
+ SET_GetProgramLocalParameterfvARB(exec, _mesa_GetProgramLocalParameterfvARB);
+ SET_GetProgramivARB(exec, _mesa_GetProgramivARB);
+ SET_GetProgramStringARB(exec, _mesa_GetProgramStringARB);
+#endif
+
+ /* ARB 28. GL_ARB_vertex_buffer_object */
+#if FEATURE_ARB_vertex_buffer_object
+ SET_BindBufferARB(exec, _mesa_BindBufferARB);
+ SET_BufferDataARB(exec, _mesa_BufferDataARB);
+ SET_BufferSubDataARB(exec, _mesa_BufferSubDataARB);
+ SET_DeleteBuffersARB(exec, _mesa_DeleteBuffersARB);
+ SET_GenBuffersARB(exec, _mesa_GenBuffersARB);
+ SET_GetBufferParameterivARB(exec, _mesa_GetBufferParameterivARB);
+ SET_GetBufferPointervARB(exec, _mesa_GetBufferPointervARB);
+ SET_GetBufferSubDataARB(exec, _mesa_GetBufferSubDataARB);
+ SET_IsBufferARB(exec, _mesa_IsBufferARB);
+ SET_MapBufferARB(exec, _mesa_MapBufferARB);
+ SET_UnmapBufferARB(exec, _mesa_UnmapBufferARB);
+#endif
+
+ /* ARB 29. GL_ARB_occlusion_query */
+#if FEATURE_ARB_occlusion_query
+ SET_GenQueriesARB(exec, _mesa_GenQueriesARB);
+ SET_DeleteQueriesARB(exec, _mesa_DeleteQueriesARB);
+ SET_IsQueryARB(exec, _mesa_IsQueryARB);
+ SET_BeginQueryARB(exec, _mesa_BeginQueryARB);
+ SET_EndQueryARB(exec, _mesa_EndQueryARB);
+ SET_GetQueryivARB(exec, _mesa_GetQueryivARB);
+ SET_GetQueryObjectivARB(exec, _mesa_GetQueryObjectivARB);
+ SET_GetQueryObjectuivARB(exec, _mesa_GetQueryObjectuivARB);
+#endif
+
+ /* ARB 37. GL_ARB_draw_buffers */
+ SET_DrawBuffersARB(exec, _mesa_DrawBuffersARB);
+
+#if FEATURE_ARB_shader_objects
+ SET_DeleteObjectARB(exec, _mesa_DeleteObjectARB);
+ SET_GetHandleARB(exec, _mesa_GetHandleARB);
+ SET_DetachObjectARB(exec, _mesa_DetachObjectARB);
+ SET_CreateShaderObjectARB(exec, _mesa_CreateShaderObjectARB);
+ SET_ShaderSourceARB(exec, _mesa_ShaderSourceARB);
+ SET_CompileShaderARB(exec, _mesa_CompileShaderARB);
+ SET_CreateProgramObjectARB(exec, _mesa_CreateProgramObjectARB);
+ SET_AttachObjectARB(exec, _mesa_AttachObjectARB);
+ SET_LinkProgramARB(exec, _mesa_LinkProgramARB);
+ SET_UseProgramObjectARB(exec, _mesa_UseProgramObjectARB);
+ SET_ValidateProgramARB(exec, _mesa_ValidateProgramARB);
+ SET_Uniform1fARB(exec, _mesa_Uniform1fARB);
+ SET_Uniform2fARB(exec, _mesa_Uniform2fARB);
+ SET_Uniform3fARB(exec, _mesa_Uniform3fARB);
+ SET_Uniform4fARB(exec, _mesa_Uniform4fARB);
+ SET_Uniform1iARB(exec, _mesa_Uniform1iARB);
+ SET_Uniform2iARB(exec, _mesa_Uniform2iARB);
+ SET_Uniform3iARB(exec, _mesa_Uniform3iARB);
+ SET_Uniform4iARB(exec, _mesa_Uniform4iARB);
+ SET_Uniform1fvARB(exec, _mesa_Uniform1fvARB);
+ SET_Uniform2fvARB(exec, _mesa_Uniform2fvARB);
+ SET_Uniform3fvARB(exec, _mesa_Uniform3fvARB);
+ SET_Uniform4fvARB(exec, _mesa_Uniform4fvARB);
+ SET_Uniform1ivARB(exec, _mesa_Uniform1ivARB);
+ SET_Uniform2ivARB(exec, _mesa_Uniform2ivARB);
+ SET_Uniform3ivARB(exec, _mesa_Uniform3ivARB);
+ SET_Uniform4ivARB(exec, _mesa_Uniform4ivARB);
+ SET_UniformMatrix2fvARB(exec, _mesa_UniformMatrix2fvARB);
+ SET_UniformMatrix3fvARB(exec, _mesa_UniformMatrix3fvARB);
+ SET_UniformMatrix4fvARB(exec, _mesa_UniformMatrix4fvARB);
+ SET_GetObjectParameterfvARB(exec, _mesa_GetObjectParameterfvARB);
+ SET_GetObjectParameterivARB(exec, _mesa_GetObjectParameterivARB);
+ SET_GetInfoLogARB(exec, _mesa_GetInfoLogARB);
+ SET_GetAttachedObjectsARB(exec, _mesa_GetAttachedObjectsARB);
+ SET_GetUniformLocationARB(exec, _mesa_GetUniformLocationARB);
+ SET_GetActiveUniformARB(exec, _mesa_GetActiveUniformARB);
+ SET_GetUniformfvARB(exec, _mesa_GetUniformfvARB);
+ SET_GetUniformivARB(exec, _mesa_GetUniformivARB);
+ SET_GetShaderSourceARB(exec, _mesa_GetShaderSourceARB);
+#endif /* FEATURE_ARB_shader_objects */
+
+#if FEATURE_ARB_vertex_shader
+ SET_BindAttribLocationARB(exec, _mesa_BindAttribLocationARB);
+ SET_GetActiveAttribARB(exec, _mesa_GetActiveAttribARB);
+ SET_GetAttribLocationARB(exec, _mesa_GetAttribLocationARB);
+#endif /* FEATURE_ARB_vertex_shader */
+
+ /* GL_ATI_fragment_shader */
+#if FEATURE_ATI_fragment_shader
+ SET_GenFragmentShadersATI(exec, _mesa_GenFragmentShadersATI);
+ SET_BindFragmentShaderATI(exec, _mesa_BindFragmentShaderATI);
+ SET_DeleteFragmentShaderATI(exec, _mesa_DeleteFragmentShaderATI);
+ SET_BeginFragmentShaderATI(exec, _mesa_BeginFragmentShaderATI);
+ SET_EndFragmentShaderATI(exec, _mesa_EndFragmentShaderATI);
+ SET_PassTexCoordATI(exec, _mesa_PassTexCoordATI);
+ SET_SampleMapATI(exec, _mesa_SampleMapATI);
+ SET_ColorFragmentOp1ATI(exec, _mesa_ColorFragmentOp1ATI);
+ SET_ColorFragmentOp2ATI(exec, _mesa_ColorFragmentOp2ATI);
+ SET_ColorFragmentOp3ATI(exec, _mesa_ColorFragmentOp3ATI);
+ SET_AlphaFragmentOp1ATI(exec, _mesa_AlphaFragmentOp1ATI);
+ SET_AlphaFragmentOp2ATI(exec, _mesa_AlphaFragmentOp2ATI);
+ SET_AlphaFragmentOp3ATI(exec, _mesa_AlphaFragmentOp3ATI);
+ SET_SetFragmentShaderConstantATI(exec, _mesa_SetFragmentShaderConstantATI);
+#endif
+
+#if FEATURE_EXT_framebuffer_object
+ SET_IsRenderbufferEXT(exec, _mesa_IsRenderbufferEXT);
+ SET_BindRenderbufferEXT(exec, _mesa_BindRenderbufferEXT);
+ SET_DeleteRenderbuffersEXT(exec, _mesa_DeleteRenderbuffersEXT);
+ SET_GenRenderbuffersEXT(exec, _mesa_GenRenderbuffersEXT);
+ SET_RenderbufferStorageEXT(exec, _mesa_RenderbufferStorageEXT);
+ SET_GetRenderbufferParameterivEXT(exec, _mesa_GetRenderbufferParameterivEXT);
+ SET_IsFramebufferEXT(exec, _mesa_IsFramebufferEXT);
+ SET_BindFramebufferEXT(exec, _mesa_BindFramebufferEXT);
+ SET_DeleteFramebuffersEXT(exec, _mesa_DeleteFramebuffersEXT);
+ SET_GenFramebuffersEXT(exec, _mesa_GenFramebuffersEXT);
+ SET_CheckFramebufferStatusEXT(exec, _mesa_CheckFramebufferStatusEXT);
+ SET_FramebufferTexture1DEXT(exec, _mesa_FramebufferTexture1DEXT);
+ SET_FramebufferTexture2DEXT(exec, _mesa_FramebufferTexture2DEXT);
+ SET_FramebufferTexture3DEXT(exec, _mesa_FramebufferTexture3DEXT);
+ SET_FramebufferRenderbufferEXT(exec, _mesa_FramebufferRenderbufferEXT);
+ SET_GetFramebufferAttachmentParameterivEXT(exec, _mesa_GetFramebufferAttachmentParameterivEXT);
+ SET_GenerateMipmapEXT(exec, _mesa_GenerateMipmapEXT);
+#endif
+
+ /* GL_EXT_timer_query */
+ SET_GetQueryObjecti64vEXT(exec, _mesa_GetQueryObjecti64vEXT);
+ SET_GetQueryObjectui64vEXT(exec, _mesa_GetQueryObjectui64vEXT);
+
+#if FEATURE_EXT_framebuffer_blit
+ SET_BlitFramebufferEXT(exec, _mesa_BlitFramebufferEXT);
+#endif
+}
+
+
+
+/**********************************************************************/
+/** \name State update logic */
+/*@{*/
+
+
+static void
+update_separate_specular( GLcontext *ctx )
+{
+ if (NEED_SECONDARY_COLOR(ctx))
+ ctx->_TriangleCaps |= DD_SEPARATE_SPECULAR;
+ else
+ ctx->_TriangleCaps &= ~DD_SEPARATE_SPECULAR;
+}
+
+
+/**
+ * Update state dependent on vertex arrays.
+ */
+static void
+update_arrays( GLcontext *ctx )
+{
+ GLuint i, min;
+
+ /* find min of _MaxElement values for all enabled arrays */
+
+ /* 0 */
+ if (ctx->VertexProgram._Enabled
+ && ctx->Array.VertexAttrib[VERT_ATTRIB_POS].Enabled) {
+ min = ctx->Array.VertexAttrib[VERT_ATTRIB_POS]._MaxElement;
+ }
+ else if (ctx->Array.Vertex.Enabled) {
+ min = ctx->Array.Vertex._MaxElement;
+ }
+ else {
+ /* can't draw anything without vertex positions! */
+ min = 0;
+ }
+
+ /* 1 */
+ if (ctx->VertexProgram._Enabled
+ && ctx->Array.VertexAttrib[VERT_ATTRIB_WEIGHT].Enabled) {
+ min = MIN2(min, ctx->Array.VertexAttrib[VERT_ATTRIB_WEIGHT]._MaxElement);
+ }
+ /* no conventional vertex weight array */
+
+ /* 2 */
+ if (ctx->VertexProgram._Enabled
+ && ctx->Array.VertexAttrib[VERT_ATTRIB_NORMAL].Enabled) {
+ min = MIN2(min, ctx->Array.VertexAttrib[VERT_ATTRIB_NORMAL]._MaxElement);
+ }
+ else if (ctx->Array.Normal.Enabled) {
+ min = MIN2(min, ctx->Array.Normal._MaxElement);
+ }
+
+ /* 3 */
+ if (ctx->VertexProgram._Enabled
+ && ctx->Array.VertexAttrib[VERT_ATTRIB_COLOR0].Enabled) {
+ min = MIN2(min, ctx->Array.VertexAttrib[VERT_ATTRIB_COLOR0]._MaxElement);
+ }
+ else if (ctx->Array.Color.Enabled) {
+ min = MIN2(min, ctx->Array.Color._MaxElement);
+ }
+
+ /* 4 */
+ if (ctx->VertexProgram._Enabled
+ && ctx->Array.VertexAttrib[VERT_ATTRIB_COLOR1].Enabled) {
+ min = MIN2(min, ctx->Array.VertexAttrib[VERT_ATTRIB_COLOR1]._MaxElement);
+ }
+ else if (ctx->Array.SecondaryColor.Enabled) {
+ min = MIN2(min, ctx->Array.SecondaryColor._MaxElement);
+ }
+
+ /* 5 */
+ if (ctx->VertexProgram._Enabled
+ && ctx->Array.VertexAttrib[VERT_ATTRIB_FOG].Enabled) {
+ min = MIN2(min, ctx->Array.VertexAttrib[VERT_ATTRIB_FOG]._MaxElement);
+ }
+ else if (ctx->Array.FogCoord.Enabled) {
+ min = MIN2(min, ctx->Array.FogCoord._MaxElement);
+ }
+
+ /* 6 */
+ if (ctx->VertexProgram._Enabled
+ && ctx->Array.VertexAttrib[VERT_ATTRIB_SIX].Enabled) {
+ min = MIN2(min, ctx->Array.VertexAttrib[VERT_ATTRIB_SIX]._MaxElement);
+ }
+
+ /* 7 */
+ if (ctx->VertexProgram._Enabled
+ && ctx->Array.VertexAttrib[VERT_ATTRIB_SEVEN].Enabled) {
+ min = MIN2(min, ctx->Array.VertexAttrib[VERT_ATTRIB_SEVEN]._MaxElement);
+ }
+
+ /* 8..15 */
+ for (i = VERT_ATTRIB_TEX0; i < VERT_ATTRIB_MAX; i++) {
+ if (ctx->VertexProgram._Enabled
+ && ctx->Array.VertexAttrib[i].Enabled) {
+ min = MIN2(min, ctx->Array.VertexAttrib[i]._MaxElement);
+ }
+ else if (i - VERT_ATTRIB_TEX0 < ctx->Const.MaxTextureCoordUnits
+ && ctx->Array.TexCoord[i - VERT_ATTRIB_TEX0].Enabled) {
+ min = MIN2(min, ctx->Array.TexCoord[i - VERT_ATTRIB_TEX0]._MaxElement);
+ }
+ }
+
+ if (ctx->Array.Index.Enabled) {
+ min = MIN2(min, ctx->Array.Index._MaxElement);
+ }
+
+ if (ctx->Array.EdgeFlag.Enabled) {
+ min = MIN2(min, ctx->Array.EdgeFlag._MaxElement);
+ }
+
+ /* _MaxElement is one past the last legal array element */
+ ctx->Array._MaxElement = min;
+}
+
+
+/**
+ * Update derived vertex/fragment program state.
+ */
+static void
+update_program(GLcontext *ctx)
+{
+ /* For now, just set the _Enabled (really enabled) flags.
+ * In the future we may have to check other state to be sure we really
+ * have a runable program or shader.
+ */
+ ctx->VertexProgram._Enabled = ctx->VertexProgram.Enabled
+ && ctx->VertexProgram.Current->Base.Instructions;
+ ctx->FragmentProgram._Enabled = ctx->FragmentProgram.Enabled
+ && ctx->FragmentProgram.Current->Base.Instructions;
+ ctx->ATIFragmentShader._Enabled = ctx->ATIFragmentShader.Enabled
+ && ctx->ATIFragmentShader.Current->Instructions;
+
+ ctx->FragmentProgram._Current = ctx->FragmentProgram.Current;
+ ctx->FragmentProgram._Active = ctx->FragmentProgram._Enabled;
+
+ if (ctx->_MaintainTexEnvProgram && !ctx->FragmentProgram._Enabled) {
+ if (!ctx->_TexEnvProgram)
+ ctx->_TexEnvProgram = (struct fragment_program *)
+ ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
+
+ ctx->FragmentProgram._Current = ctx->_TexEnvProgram;
+
+ if (ctx->_UseTexEnvProgram)
+ ctx->FragmentProgram._Active = GL_TRUE;
+ }
+}
+
+
+static void
+update_viewport_matrix(GLcontext *ctx)
+{
+ const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF;
+
+ ASSERT(depthMax > 0);
+
+ /* Compute scale and bias values. This is really driver-specific
+ * and should be maintained elsewhere if at all.
+ * NOTE: RasterPos uses this.
+ */
+ _math_matrix_viewport(&ctx->Viewport._WindowMap,
+ ctx->Viewport.X, ctx->Viewport.Y,
+ ctx->Viewport.Width, ctx->Viewport.Height,
+ ctx->Viewport.Near, ctx->Viewport.Far,
+ depthMax);
+}
+
+
+
+/**
+ * If __GLcontextRec::NewState is non-zero then this function \b must be called
+ * before rendering any primitive. Basically, function pointers and
+ * miscellaneous flags are updated to reflect the current state of the state
+ * machine.
+ *
+ * Calls dd_function_table::UpdateState to perform any internal state
+ * management necessary.
+ *
+ * \sa _mesa_update_modelview_project(), _mesa_update_texture(),
+ * _mesa_update_buffer_bounds(), _mesa_update_polygon(),
+ * _mesa_update_lighting() and _mesa_update_tnl_spaces().
+ */
+void
+_mesa_update_state( GLcontext *ctx )
+{
+ GLbitfield new_state = ctx->NewState;
+
+ if (MESA_VERBOSE & VERBOSE_STATE)
+ _mesa_print_state("_mesa_update_state", new_state);
+
+ if (new_state & _NEW_PROGRAM)
+ update_program( ctx );
+
+ if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION))
+ _mesa_update_modelview_project( ctx, new_state );
+
+ if (new_state & (_NEW_PROGRAM|_NEW_TEXTURE|_NEW_TEXTURE_MATRIX))
+ _mesa_update_texture( ctx, new_state );
+
+ if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL))
+ _mesa_update_framebuffer(ctx);
+
+ if (new_state & (_NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT))
+ _mesa_update_draw_buffer_bounds( ctx );
+
+ if (new_state & _NEW_POINT)
+ _mesa_update_point( ctx );
+
+ if (new_state & _NEW_POLYGON)
+ _mesa_update_polygon( ctx );
+
+ if (new_state & _NEW_LIGHT)
+ _mesa_update_lighting( ctx );
+
+ if (new_state & _NEW_STENCIL)
+ _mesa_update_stencil( ctx );
+
+ if (new_state & _IMAGE_NEW_TRANSFER_STATE)
+ _mesa_update_pixel( ctx, new_state );
+
+ if (new_state & _DD_NEW_SEPARATE_SPECULAR)
+ update_separate_specular( ctx );
+
+ if (new_state & (_NEW_ARRAY | _NEW_PROGRAM))
+ update_arrays( ctx );
+
+ if (new_state & (_NEW_BUFFERS | _NEW_VIEWPORT))
+ update_viewport_matrix(ctx);
+
+ if (ctx->_MaintainTexEnvProgram) {
+ if (new_state & (_NEW_TEXTURE | _DD_NEW_SEPARATE_SPECULAR | _NEW_FOG))
+ _mesa_UpdateTexEnvProgram(ctx);
+ }
+
+ /* ctx->_NeedEyeCoords is now up to date.
+ *
+ * If the truth value of this variable has changed, update for the
+ * new lighting space and recompute the positions of lights and the
+ * normal transform.
+ *
+ * If the lighting space hasn't changed, may still need to recompute
+ * light positions & normal transforms for other reasons.
+ */
+ if (new_state & _MESA_NEW_NEED_EYE_COORDS)
+ _mesa_update_tnl_spaces( ctx, new_state );
+
+ /*
+ * Give the driver a chance to act upon the new_state flags.
+ * The driver might plug in different span functions, for example.
+ * Also, this is where the driver can invalidate the state of any
+ * active modules (such as swrast_setup, swrast, tnl, etc).
+ *
+ * Set ctx->NewState to zero to avoid recursion if
+ * Driver.UpdateState() has to call FLUSH_VERTICES(). (fixed?)
+ */
+ new_state = ctx->NewState;
+ ctx->NewState = 0;
+ ctx->Driver.UpdateState(ctx, new_state);
+ ctx->Array.NewState = 0;
+}
+
+/*@}*/
diff --git a/src/mesa/main/state.h b/src/mesa/main/state.h
new file mode 100644
index 00000000000..58cfcc41462
--- /dev/null
+++ b/src/mesa/main/state.h
@@ -0,0 +1,43 @@
+/**
+ * \file state.h
+ * State management.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.3
+ *
+ * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef STATE_H
+#define STATE_H
+
+#include "mtypes.h"
+
+extern void
+_mesa_init_exec_table(struct _glapi_table *exec);
+
+extern void
+_mesa_update_state( GLcontext *ctx );
+
+
+#endif
diff --git a/src/mesa/main/stencil.c b/src/mesa/main/stencil.c
new file mode 100644
index 00000000000..6b4d7e81eb8
--- /dev/null
+++ b/src/mesa/main/stencil.c
@@ -0,0 +1,552 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/**
+ * \file stencil.c
+ * Stencil operations.
+ *
+ * Note: There's an incompatibility between GL_EXT_stencil_two_side and
+ * OpenGL 2.0's two-sided stencil feature.
+ *
+ * With GL_EXT_stencil_two_side, calling glStencilOp/Func/Mask() only the
+ * front OR back face state (as set by glActiveStencilFaceEXT) is set.
+ *
+ * But with OpenGL 2.0, calling glStencilOp/Func/Mask() sets BOTH the
+ * front AND back state.
+ *
+ * So either we advertise the GL_EXT_stencil_two_side extension, or OpenGL
+ * 2.0, but not both.
+ */
+
+
+#include "glheader.h"
+#include "imports.h"
+#include "context.h"
+#include "macros.h"
+#include "stencil.h"
+#include "mtypes.h"
+
+
+/**
+ * Set the clear value for the stencil buffer.
+ *
+ * \param s clear value.
+ *
+ * \sa glClearStencil().
+ *
+ * Updates gl_stencil_attrib::Clear. On change
+ * flushes the vertices and notifies the driver via
+ * the dd_function_table::ClearStencil callback.
+ */
+void GLAPIENTRY
+_mesa_ClearStencil( GLint s )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (ctx->Stencil.Clear == (GLuint) s)
+ return;
+
+ FLUSH_VERTICES(ctx, _NEW_STENCIL);
+ ctx->Stencil.Clear = (GLuint) s;
+
+ if (ctx->Driver.ClearStencil) {
+ ctx->Driver.ClearStencil( ctx, s );
+ }
+}
+
+
+/**
+ * Set the function and reference value for stencil testing.
+ *
+ * \param func test function.
+ * \param ref reference value.
+ * \param mask bitmask.
+ *
+ * \sa glStencilFunc().
+ *
+ * Verifies the parameters and updates the respective values in
+ * __GLcontextRec::Stencil. On change flushes the vertices and notifies the
+ * driver via the dd_function_table::StencilFunc callback.
+ */
+void GLAPIENTRY
+_mesa_StencilFunc( GLenum func, GLint ref, GLuint mask )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ const GLint stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1;
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ switch (func) {
+ case GL_NEVER:
+ case GL_LESS:
+ case GL_LEQUAL:
+ case GL_GREATER:
+ case GL_GEQUAL:
+ case GL_EQUAL:
+ case GL_NOTEQUAL:
+ case GL_ALWAYS:
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glStencilFunc" );
+ return;
+ }
+
+ ref = CLAMP( ref, 0, stencilMax );
+
+ if (ctx->Extensions.EXT_stencil_two_side) {
+ /* only set active face state */
+ const GLint face = ctx->Stencil.ActiveFace;
+ if (ctx->Stencil.Function[face] == func &&
+ ctx->Stencil.ValueMask[face] == mask &&
+ ctx->Stencil.Ref[face] == ref)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_STENCIL);
+ ctx->Stencil.Function[face] = func;
+ ctx->Stencil.Ref[face] = ref;
+ ctx->Stencil.ValueMask[face] = mask;
+ if (ctx->Driver.StencilFuncSeparate) {
+ ctx->Driver.StencilFuncSeparate(ctx, face ? GL_BACK : GL_FRONT,
+ func, ref, mask);
+ }
+ }
+ else {
+ /* set both front and back state */
+ if (ctx->Stencil.Function[0] == func &&
+ ctx->Stencil.Function[1] == func &&
+ ctx->Stencil.ValueMask[0] == mask &&
+ ctx->Stencil.ValueMask[1] == mask &&
+ ctx->Stencil.Ref[0] == ref &&
+ ctx->Stencil.Ref[1] == ref)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_STENCIL);
+ ctx->Stencil.Function[0] = ctx->Stencil.Function[1] = func;
+ ctx->Stencil.Ref[0] = ctx->Stencil.Ref[1] = ref;
+ ctx->Stencil.ValueMask[0] = ctx->Stencil.ValueMask[1] = mask;
+ if (ctx->Driver.StencilFuncSeparate) {
+ ctx->Driver.StencilFuncSeparate(ctx, GL_FRONT_AND_BACK,
+ func, ref, mask);
+ }
+ }
+}
+
+
+/**
+ * Set the stencil writing mask.
+ *
+ * \param mask bit-mask to enable/disable writing of individual bits in the
+ * stencil planes.
+ *
+ * \sa glStencilMask().
+ *
+ * Updates gl_stencil_attrib::WriteMask. On change flushes the vertices and
+ * notifies the driver via the dd_function_table::StencilMask callback.
+ */
+void GLAPIENTRY
+_mesa_StencilMask( GLuint mask )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (ctx->Extensions.EXT_stencil_two_side) {
+ /* only set active face state */
+ const GLint face = ctx->Stencil.ActiveFace;
+ if (ctx->Stencil.WriteMask[face] == mask)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_STENCIL);
+ ctx->Stencil.WriteMask[face] = mask;
+ if (ctx->Driver.StencilMaskSeparate) {
+ ctx->Driver.StencilMaskSeparate(ctx, face ? GL_BACK : GL_FRONT, mask);
+ }
+ }
+ else {
+ /* set both front and back state */
+ if (ctx->Stencil.WriteMask[0] == mask &&
+ ctx->Stencil.WriteMask[1] == mask)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_STENCIL);
+ ctx->Stencil.WriteMask[0] = ctx->Stencil.WriteMask[1] = mask;
+ if (ctx->Driver.StencilMaskSeparate) {
+ ctx->Driver.StencilMaskSeparate(ctx, GL_FRONT_AND_BACK, mask);
+ }
+ }
+}
+
+
+/**
+ * Set the stencil test actions.
+ *
+ * \param fail action to take when stencil test fails.
+ * \param zfail action to take when stencil test passes, but depth test fails.
+ * \param zpass action to take when stencil test passes and the depth test
+ * passes (or depth testing is not enabled).
+ *
+ * \sa glStencilOp().
+ *
+ * Verifies the parameters and updates the respective fields in
+ * __GLcontextRec::Stencil. On change flushes the vertices and notifies the
+ * driver via the dd_function_table::StencilOp callback.
+ */
+void GLAPIENTRY
+_mesa_StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ switch (fail) {
+ case GL_KEEP:
+ case GL_ZERO:
+ case GL_REPLACE:
+ case GL_INCR:
+ case GL_DECR:
+ case GL_INVERT:
+ break;
+ case GL_INCR_WRAP_EXT:
+ case GL_DECR_WRAP_EXT:
+ if (ctx->Extensions.EXT_stencil_wrap) {
+ break;
+ }
+ /* FALL-THROUGH */
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOp");
+ return;
+ }
+ switch (zfail) {
+ case GL_KEEP:
+ case GL_ZERO:
+ case GL_REPLACE:
+ case GL_INCR:
+ case GL_DECR:
+ case GL_INVERT:
+ break;
+ case GL_INCR_WRAP_EXT:
+ case GL_DECR_WRAP_EXT:
+ if (ctx->Extensions.EXT_stencil_wrap) {
+ break;
+ }
+ /* FALL-THROUGH */
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOp");
+ return;
+ }
+ switch (zpass) {
+ case GL_KEEP:
+ case GL_ZERO:
+ case GL_REPLACE:
+ case GL_INCR:
+ case GL_DECR:
+ case GL_INVERT:
+ break;
+ case GL_INCR_WRAP_EXT:
+ case GL_DECR_WRAP_EXT:
+ if (ctx->Extensions.EXT_stencil_wrap) {
+ break;
+ }
+ /* FALL-THROUGH */
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOp");
+ return;
+ }
+
+ if (ctx->Extensions.EXT_stencil_two_side) {
+ /* only set active face state */
+ const GLint face = ctx->Stencil.ActiveFace;
+ if (ctx->Stencil.ZFailFunc[face] == zfail &&
+ ctx->Stencil.ZPassFunc[face] == zpass &&
+ ctx->Stencil.FailFunc[face] == fail)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_STENCIL);
+ ctx->Stencil.ZFailFunc[face] = zfail;
+ ctx->Stencil.ZPassFunc[face] = zpass;
+ ctx->Stencil.FailFunc[face] = fail;
+ if (ctx->Driver.StencilOpSeparate) {
+ ctx->Driver.StencilOpSeparate(ctx, face ? GL_BACK : GL_FRONT,
+ fail, zfail, zpass);
+ }
+ }
+ else {
+ /* set both front and back state */
+ if (ctx->Stencil.ZFailFunc[0] == zfail &&
+ ctx->Stencil.ZFailFunc[1] == zfail &&
+ ctx->Stencil.ZPassFunc[0] == zpass &&
+ ctx->Stencil.ZPassFunc[1] == zpass &&
+ ctx->Stencil.FailFunc[0] == fail &&
+ ctx->Stencil.FailFunc[1] == fail)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_STENCIL);
+ ctx->Stencil.ZFailFunc[0] = ctx->Stencil.ZFailFunc[1] = zfail;
+ ctx->Stencil.ZPassFunc[0] = ctx->Stencil.ZPassFunc[1] = zpass;
+ ctx->Stencil.FailFunc[0] = ctx->Stencil.FailFunc[1] = fail;
+ if (ctx->Driver.StencilOpSeparate) {
+ ctx->Driver.StencilOpSeparate(ctx, GL_FRONT_AND_BACK,
+ fail, zfail, zpass);
+ }
+ }
+}
+
+
+
+#if _HAVE_FULL_GL
+/* GL_EXT_stencil_two_side */
+void GLAPIENTRY
+_mesa_ActiveStencilFaceEXT(GLenum face)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (!ctx->Extensions.EXT_stencil_two_side) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glActiveStencilFaceEXT");
+ return;
+ }
+
+ if (face == GL_FRONT || face == GL_BACK) {
+ FLUSH_VERTICES(ctx, _NEW_STENCIL);
+ ctx->Stencil.ActiveFace = (face == GL_FRONT) ? 0 : 1;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glActiveStencilFaceEXT(face)");
+ }
+}
+#endif
+
+
+
+/**
+ * OpenGL 2.0 function.
+ * \todo Make StencilOp() call this function. And eventually remove the
+ * ctx->Driver.StencilOp function and use ctx->Driver.StencilOpSeparate
+ * instead.
+ */
+void GLAPIENTRY
+_mesa_StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (face != GL_FRONT && face != GL_BACK && face != GL_FRONT_AND_BACK) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparate(face)");
+ return;
+ }
+
+ switch (fail) {
+ case GL_KEEP:
+ case GL_ZERO:
+ case GL_REPLACE:
+ case GL_INCR:
+ case GL_DECR:
+ case GL_INVERT:
+ break;
+ case GL_INCR_WRAP_EXT:
+ case GL_DECR_WRAP_EXT:
+ if (ctx->Extensions.EXT_stencil_wrap) {
+ break;
+ }
+ /* FALL-THROUGH */
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparate(fail)");
+ return;
+ }
+ switch (zfail) {
+ case GL_KEEP:
+ case GL_ZERO:
+ case GL_REPLACE:
+ case GL_INCR:
+ case GL_DECR:
+ case GL_INVERT:
+ break;
+ case GL_INCR_WRAP_EXT:
+ case GL_DECR_WRAP_EXT:
+ if (ctx->Extensions.EXT_stencil_wrap) {
+ break;
+ }
+ /* FALL-THROUGH */
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparate(zfail)");
+ return;
+ }
+ switch (zpass) {
+ case GL_KEEP:
+ case GL_ZERO:
+ case GL_REPLACE:
+ case GL_INCR:
+ case GL_DECR:
+ case GL_INVERT:
+ break;
+ case GL_INCR_WRAP_EXT:
+ case GL_DECR_WRAP_EXT:
+ if (ctx->Extensions.EXT_stencil_wrap) {
+ break;
+ }
+ /* FALL-THROUGH */
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparate(zpass)");
+ return;
+ }
+
+ FLUSH_VERTICES(ctx, _NEW_STENCIL);
+
+ if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
+ ctx->Stencil.FailFunc[0] = fail;
+ ctx->Stencil.ZFailFunc[0] = zfail;
+ ctx->Stencil.ZPassFunc[0] = zpass;
+ }
+ if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
+ ctx->Stencil.FailFunc[1] = fail;
+ ctx->Stencil.ZFailFunc[1] = zfail;
+ ctx->Stencil.ZPassFunc[1] = zpass;
+ }
+
+ if (ctx->Driver.StencilOpSeparate) {
+ ctx->Driver.StencilOpSeparate(ctx, face, fail, zfail, zpass);
+ }
+}
+
+
+/* OpenGL 2.0 */
+void GLAPIENTRY
+_mesa_StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ const GLint stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1;
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (face != GL_FRONT && face != GL_BACK && face != GL_FRONT_AND_BACK) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glStencilFuncSeparate(face)");
+ return;
+ }
+
+ switch (func) {
+ case GL_NEVER:
+ case GL_LESS:
+ case GL_LEQUAL:
+ case GL_GREATER:
+ case GL_GEQUAL:
+ case GL_EQUAL:
+ case GL_NOTEQUAL:
+ case GL_ALWAYS:
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glStencilFuncSeparate(func)");
+ return;
+ }
+
+ ref = CLAMP(ref, 0, stencilMax);
+
+ FLUSH_VERTICES(ctx, _NEW_STENCIL);
+
+ if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
+ ctx->Stencil.Function[0] = func;
+ ctx->Stencil.Ref[0] = ref;
+ ctx->Stencil.ValueMask[0] = mask;
+ }
+ if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
+ ctx->Stencil.Function[1] = func;
+ ctx->Stencil.Ref[1] = ref;
+ ctx->Stencil.ValueMask[1] = mask;
+ }
+
+ if (ctx->Driver.StencilFuncSeparate) {
+ ctx->Driver.StencilFuncSeparate(ctx, face, func, ref, mask);
+ }
+}
+
+
+/* OpenGL 2.0 */
+void GLAPIENTRY
+_mesa_StencilMaskSeparate(GLenum face, GLuint mask)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (face != GL_FRONT && face != GL_BACK && face != GL_FRONT_AND_BACK) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glStencilaMaskSeparate(face)");
+ return;
+ }
+
+ FLUSH_VERTICES(ctx, _NEW_STENCIL);
+
+ if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
+ ctx->Stencil.WriteMask[0] = mask;
+ }
+ if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
+ ctx->Stencil.WriteMask[1] = mask;
+ }
+
+ if (ctx->Driver.StencilMaskSeparate) {
+ ctx->Driver.StencilMaskSeparate(ctx, face, mask);
+ }
+}
+
+
+/**
+ * Update derived stencil state.
+ */
+void
+_mesa_update_stencil(GLcontext *ctx)
+{
+ if (ctx->Extensions.EXT_stencil_two_side) {
+ ctx->Stencil._TestTwoSide = ctx->Stencil.TestTwoSide;
+ }
+ else {
+ ctx->Stencil._TestTwoSide =
+ (ctx->Stencil.Function[0] != ctx->Stencil.Function[1] ||
+ ctx->Stencil.FailFunc[0] != ctx->Stencil.FailFunc[1] ||
+ ctx->Stencil.ZPassFunc[0] != ctx->Stencil.ZPassFunc[1] ||
+ ctx->Stencil.ZFailFunc[0] != ctx->Stencil.ZFailFunc[1] ||
+ ctx->Stencil.Ref[0] != ctx->Stencil.Ref[1] ||
+ ctx->Stencil.ValueMask[0] != ctx->Stencil.ValueMask[1] ||
+ ctx->Stencil.WriteMask[0] != ctx->Stencil.WriteMask[1]);
+ }
+}
+
+
+/**
+ * Initialize the context stipple state.
+ *
+ * \param ctx GL context.
+ *
+ * Initializes __GLcontextRec::Stencil attribute group.
+ */
+void
+_mesa_init_stencil(GLcontext *ctx)
+{
+ ctx->Stencil.Enabled = GL_FALSE;
+ ctx->Stencil.TestTwoSide = GL_FALSE;
+ ctx->Stencil.ActiveFace = 0; /* 0 = GL_FRONT, 1 = GL_BACK */
+ ctx->Stencil.Function[0] = GL_ALWAYS;
+ ctx->Stencil.Function[1] = GL_ALWAYS;
+ ctx->Stencil.FailFunc[0] = GL_KEEP;
+ ctx->Stencil.FailFunc[1] = GL_KEEP;
+ ctx->Stencil.ZPassFunc[0] = GL_KEEP;
+ ctx->Stencil.ZPassFunc[1] = GL_KEEP;
+ ctx->Stencil.ZFailFunc[0] = GL_KEEP;
+ ctx->Stencil.ZFailFunc[1] = GL_KEEP;
+ ctx->Stencil.Ref[0] = 0;
+ ctx->Stencil.Ref[1] = 0;
+ ctx->Stencil.ValueMask[0] = ~0U;
+ ctx->Stencil.ValueMask[1] = ~0U;
+ ctx->Stencil.WriteMask[0] = ~0U;
+ ctx->Stencil.WriteMask[1] = ~0U;
+ ctx->Stencil.Clear = 0;
+}
diff --git a/src/mesa/main/stencil.h b/src/mesa/main/stencil.h
new file mode 100644
index 00000000000..27c6362023c
--- /dev/null
+++ b/src/mesa/main/stencil.h
@@ -0,0 +1,77 @@
+/**
+ * \file stencil.h
+ * Stencil operations.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef STENCIL_H
+#define STENCIL_H
+
+
+#include "mtypes.h"
+
+
+extern void GLAPIENTRY
+_mesa_ClearStencil( GLint s );
+
+
+extern void GLAPIENTRY
+_mesa_StencilFunc( GLenum func, GLint ref, GLuint mask );
+
+
+extern void GLAPIENTRY
+_mesa_StencilMask( GLuint mask );
+
+
+extern void GLAPIENTRY
+_mesa_StencilOp( GLenum fail, GLenum zfail, GLenum zpass );
+
+
+extern void GLAPIENTRY
+_mesa_ActiveStencilFaceEXT(GLenum face);
+
+
+extern void GLAPIENTRY
+_mesa_StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
+
+
+extern void GLAPIENTRY
+_mesa_StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
+
+
+extern void GLAPIENTRY
+_mesa_StencilMaskSeparate(GLenum face, GLuint mask);
+
+
+extern void
+_mesa_update_stencil(GLcontext *ctx);
+
+
+extern void
+_mesa_init_stencil( GLcontext * ctx );
+
+#endif
diff --git a/src/mesa/main/texcompress.c b/src/mesa/main/texcompress.c
new file mode 100644
index 00000000000..d18b1d0b418
--- /dev/null
+++ b/src/mesa/main/texcompress.c
@@ -0,0 +1,254 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.1
+ *
+ * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/**
+ * \file texcompress.c
+ * Helper functions for texture compression.
+ */
+
+
+#include "glheader.h"
+#include "imports.h"
+#include "colormac.h"
+#include "context.h"
+#include "image.h"
+#include "texcompress.h"
+#include "texformat.h"
+#include "texstore.h"
+
+/**
+ * Get the list of supported internal compression formats.
+ *
+ * \param ctx GL context.
+ * \param formats the resulting format list (may be NULL).
+ *
+ * \return number of formats.
+ */
+GLuint
+_mesa_get_compressed_formats( GLcontext *ctx, GLint *formats )
+{
+ GLuint n = 0;
+ if (ctx->Extensions.ARB_texture_compression) {
+ if (ctx->Extensions.TDFX_texture_compression_FXT1) {
+ if (formats) {
+ formats[n++] = GL_COMPRESSED_RGB_FXT1_3DFX;
+ formats[n++] = GL_COMPRESSED_RGBA_FXT1_3DFX;
+ }
+ else {
+ n += 2;
+ }
+ }
+ if (ctx->Extensions.EXT_texture_compression_s3tc) {
+ if (formats) {
+ formats[n++] = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
+ /* Skip this one because it has a restriction (all transparent
+ * pixels become black). See the texture compressions spec for
+ * a detailed explanation. This is what NVIDIA does.
+ formats[n++] = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
+ */
+ formats[n++] = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
+ formats[n++] = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
+ }
+ else {
+ n += 3;
+ }
+ }
+ if (ctx->Extensions.S3_s3tc) {
+ if (formats) {
+ formats[n++] = GL_RGB_S3TC;
+ formats[n++] = GL_RGB4_S3TC;
+ formats[n++] = GL_RGBA_S3TC;
+ formats[n++] = GL_RGBA4_S3TC;
+ }
+ else {
+ n += 4;
+ }
+ }
+ }
+ return n;
+}
+
+
+
+/**
+ * Return number of bytes needed to store a texture of the given size
+ * using the specified compressed format.
+ * This is called via the ctx->Driver.CompressedTextureSize function,
+ * unless a device driver overrides it.
+ *
+ * \param width texture width in texels.
+ * \param height texture height in texels.
+ * \param depth texture depth in texels.
+ * \param format - one of the specific compressed texture formats
+ *
+ * \return size in bytes, or zero if bad format
+ */
+GLuint
+_mesa_compressed_texture_size( GLcontext *ctx,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format )
+{
+ GLuint size;
+
+ ASSERT(depth == 1);
+ (void) depth;
+
+ switch (format) {
+ case GL_COMPRESSED_RGB_FXT1_3DFX:
+ case GL_COMPRESSED_RGBA_FXT1_3DFX:
+ /* round up width to next multiple of 8, height to next multiple of 4 */
+ width = (width + 7) & ~7;
+ height = (height + 3) & ~3;
+ /* 16 bytes per 8x4 tile of RGB[A] texels */
+ size = width * height / 2;
+ /* Textures smaller than 8x4 will effectively be made into 8x4 and
+ * take 16 bytes.
+ */
+ if (size < 16)
+ size = 16;
+ return size;
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ case GL_RGB_S3TC:
+ case GL_RGB4_S3TC:
+ /* round up width, height to next multiple of 4 */
+ width = (width + 3) & ~3;
+ height = (height + 3) & ~3;
+ /* 8 bytes per 4x4 tile of RGB[A] texels */
+ size = width * height / 2;
+ /* Textures smaller than 4x4 will effectively be made into 4x4 and
+ * take 8 bytes.
+ */
+ if (size < 8)
+ size = 8;
+ return size;
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ case GL_RGBA_S3TC:
+ case GL_RGBA4_S3TC:
+ /* round up width, height to next multiple of 4 */
+ width = (width + 3) & ~3;
+ height = (height + 3) & ~3;
+ /* 16 bytes per 4x4 tile of RGBA texels */
+ size = width * height; /* simple! */
+ /* Textures smaller than 4x4 will effectively be made into 4x4 and
+ * take 16 bytes.
+ */
+ if (size < 16)
+ size = 16;
+ return size;
+ default:
+ _mesa_problem(ctx, "bad texformat in compressed_texture_size");
+ return 0;
+ }
+}
+
+
+/*
+ * Compute the bytes per row in a compressed texture image.
+ * We use this for computing the destination address for sub-texture updates.
+ * \param format one of the specific texture compression formats
+ * \param width image width in pixels
+ * \return stride, in bytes, between rows for compressed image
+ */
+GLint
+_mesa_compressed_row_stride(GLenum format, GLsizei width)
+{
+ GLint stride;
+
+ switch (format) {
+ case GL_COMPRESSED_RGB_FXT1_3DFX:
+ case GL_COMPRESSED_RGBA_FXT1_3DFX:
+ stride = ((width + 7) / 8) * 16; /* 16 bytes per 8x4 tile */
+ break;
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ case GL_RGB_S3TC:
+ case GL_RGB4_S3TC:
+ stride = ((width + 3) / 4) * 8; /* 8 bytes per 4x4 tile */
+ break;
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ case GL_RGBA_S3TC:
+ case GL_RGBA4_S3TC:
+ stride = ((width + 3) / 4) * 16; /* 16 bytes per 4x4 tile */
+ break;
+ default:
+ return 0;
+ }
+
+ return stride;
+}
+
+
+/*
+ * Return the address of the pixel at (col, row, img) in a
+ * compressed texture image.
+ * \param col, row, img - image position (3D)
+ * \param format - compressed image format
+ * \param width - image width
+ * \param image - the image address
+ * \return address of pixel at (row, col)
+ */
+GLubyte *
+_mesa_compressed_image_address(GLint col, GLint row, GLint img,
+ GLenum format,
+ GLsizei width, const GLubyte *image)
+{
+ GLubyte *addr;
+
+ (void) img;
+
+ /* We try to spot a "complete" subtexture "above" ROW, COL;
+ * this texture is given by appropriate rounding of WIDTH x ROW.
+ * Then we just add the amount left (usually on the left).
+ *
+ * Example for X*Y microtiles (Z bytes each)
+ * offset = Z * (((width + X - 1) / X) * (row / Y) + col / X);
+ */
+
+ switch (format) {
+ case GL_COMPRESSED_RGB_FXT1_3DFX:
+ case GL_COMPRESSED_RGBA_FXT1_3DFX:
+ addr = (GLubyte *) image + 16 * (((width + 7) / 8) * (row / 4) + col / 8);
+ break;
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ case GL_RGB_S3TC:
+ case GL_RGB4_S3TC:
+ addr = (GLubyte *) image + 8 * (((width + 3) / 4) * (row / 4) + col / 4);
+ break;
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ case GL_RGBA_S3TC:
+ case GL_RGBA4_S3TC:
+ addr = (GLubyte *) image + 16 * (((width + 3) / 4) * (row / 4) + col / 4);
+ break;
+ default:
+ return NULL;
+ }
+
+ return addr;
+}
diff --git a/src/mesa/main/texcompress.h b/src/mesa/main/texcompress.h
new file mode 100644
index 00000000000..50074145469
--- /dev/null
+++ b/src/mesa/main/texcompress.h
@@ -0,0 +1,65 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.1
+ *
+ * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef TEXCOMPRESS_H
+#define TEXCOMPRESS_H
+
+#include "mtypes.h"
+
+#if _HAVE_FULL_GL
+extern GLuint
+_mesa_get_compressed_formats( GLcontext *ctx, GLint *formats );
+
+extern GLuint
+_mesa_compressed_texture_size( GLcontext *ctx,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format );
+
+extern GLint
+_mesa_compressed_row_stride(GLenum format, GLsizei width);
+
+
+extern GLubyte *
+_mesa_compressed_image_address(GLint col, GLint row, GLint img,
+ GLenum format,
+ GLsizei width, const GLubyte *image);
+
+
+extern void
+_mesa_init_texture_s3tc( GLcontext *ctx );
+
+extern void
+_mesa_init_texture_fxt1( GLcontext *ctx );
+
+
+
+#else
+#define _mesa_get_compressed_formats( c, f ) 0
+#define _mesa_compressed_texture_size( c, w, h, d, f ) 0
+#define _mesa_compressed_row_stride( f, w) 0
+#define _mesa_compressed_image_address(c, r, i, f, w, i2 ) 0
+#define _mesa_compress_teximage( c, w, h, sF, s, sRS, dF, d, drs ) ((void)0)
+#endif
+
+#endif /* TEXCOMPRESS_H */
diff --git a/src/mesa/main/texcompress_fxt1.c b/src/mesa/main/texcompress_fxt1.c
new file mode 100644
index 00000000000..44b450fd56e
--- /dev/null
+++ b/src/mesa/main/texcompress_fxt1.c
@@ -0,0 +1,1708 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/**
+ * \file texcompress_fxt1.c
+ * GL_EXT_texture_compression_fxt1 support.
+ */
+
+
+#include "glheader.h"
+#include "imports.h"
+#include "colormac.h"
+#include "context.h"
+#include "convolve.h"
+#include "image.h"
+#include "texcompress.h"
+#include "texformat.h"
+#include "texstore.h"
+
+
+static void
+fxt1_encode (GLuint width, GLuint height, GLint comps,
+ const void *source, GLint srcRowStride,
+ void *dest, GLint destRowStride);
+
+void
+fxt1_decode_1 (const void *texture, GLint stride,
+ GLint i, GLint j, GLchan *rgba);
+
+
+/**
+ * Called during context initialization.
+ */
+void
+_mesa_init_texture_fxt1( GLcontext *ctx )
+{
+ (void) ctx;
+}
+
+
+/**
+ * Called via TexFormat->StoreImage to store an RGB_FXT1 texture.
+ */
+static GLboolean
+texstore_rgb_fxt1(STORE_PARAMS)
+{
+ const GLchan *pixels;
+ GLint srcRowStride;
+ GLubyte *dst;
+ const GLint texWidth = dstRowStride * 8 / 16; /* a bit of a hack */
+ const GLchan *tempImage = NULL;
+
+ ASSERT(dstFormat == &_mesa_texformat_rgb_fxt1);
+ ASSERT(dstXoffset % 8 == 0);
+ ASSERT(dstYoffset % 4 == 0);
+ ASSERT(dstZoffset == 0);
+ (void) dstZoffset; (void) dstImageStride;
+
+ if (srcFormat != GL_RGB ||
+ srcType != CHAN_TYPE ||
+ ctx->_ImageTransferState ||
+ srcPacking->SwapBytes) {
+ /* convert image to RGB/GLchan */
+ tempImage = _mesa_make_temp_chan_image(ctx, dims,
+ baseInternalFormat,
+ dstFormat->BaseFormat,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr,
+ srcPacking);
+ if (!tempImage)
+ return GL_FALSE; /* out of memory */
+ _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
+ pixels = tempImage;
+ srcRowStride = 3 * srcWidth;
+ srcFormat = GL_RGB;
+ }
+ else {
+ pixels = (const GLchan *) srcAddr;
+ srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat,
+ srcType) / sizeof(GLchan);
+ }
+
+ dst = _mesa_compressed_image_address(dstXoffset, dstYoffset, 0,
+ GL_COMPRESSED_RGB_FXT1_3DFX,
+ texWidth, (GLubyte *) dstAddr);
+
+ fxt1_encode(srcWidth, srcHeight, 3, pixels, srcRowStride,
+ dst, dstRowStride);
+
+ if (tempImage)
+ _mesa_free((void*) tempImage);
+
+ return GL_TRUE;
+}
+
+
+/**
+ * Called via TexFormat->StoreImage to store an RGBA_FXT1 texture.
+ */
+static GLboolean
+texstore_rgba_fxt1(STORE_PARAMS)
+{
+ const GLchan *pixels;
+ GLint srcRowStride;
+ GLubyte *dst;
+ GLint texWidth = dstRowStride * 8 / 16; /* a bit of a hack */
+ const GLchan *tempImage = NULL;
+
+ ASSERT(dstFormat == &_mesa_texformat_rgba_fxt1);
+ ASSERT(dstXoffset % 8 == 0);
+ ASSERT(dstYoffset % 4 == 0);
+ ASSERT(dstZoffset == 0);
+ (void) dstZoffset; (void) dstImageStride;
+
+ if (srcFormat != GL_RGBA ||
+ srcType != CHAN_TYPE ||
+ ctx->_ImageTransferState ||
+ srcPacking->SwapBytes) {
+ /* convert image to RGBA/GLchan */
+ tempImage = _mesa_make_temp_chan_image(ctx, dims,
+ baseInternalFormat,
+ dstFormat->BaseFormat,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr,
+ srcPacking);
+ if (!tempImage)
+ return GL_FALSE; /* out of memory */
+ _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
+ pixels = tempImage;
+ srcRowStride = 4 * srcWidth;
+ srcFormat = GL_RGBA;
+ }
+ else {
+ pixels = (const GLchan *) srcAddr;
+ srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat,
+ srcType) / sizeof(GLchan);
+ }
+
+ dst = _mesa_compressed_image_address(dstXoffset, dstYoffset, 0,
+ GL_COMPRESSED_RGBA_FXT1_3DFX,
+ texWidth, (GLubyte *) dstAddr);
+
+ fxt1_encode(srcWidth, srcHeight, 4, pixels, srcRowStride,
+ dst, dstRowStride);
+
+ if (tempImage)
+ _mesa_free((void*) tempImage);
+
+ return GL_TRUE;
+}
+
+
+static void
+fetch_texel_2d_rgba_fxt1( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLchan *texel )
+{
+ (void) k;
+ fxt1_decode_1(texImage->Data, texImage->RowStride, i, j, texel);
+}
+
+
+static void
+fetch_texel_2d_f_rgba_fxt1( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLfloat *texel )
+{
+ /* just sample as GLchan and convert to float here */
+ GLchan rgba[4];
+ (void) k;
+ fxt1_decode_1(texImage->Data, texImage->RowStride, i, j, rgba);
+ texel[RCOMP] = CHAN_TO_FLOAT(rgba[RCOMP]);
+ texel[GCOMP] = CHAN_TO_FLOAT(rgba[GCOMP]);
+ texel[BCOMP] = CHAN_TO_FLOAT(rgba[BCOMP]);
+ texel[ACOMP] = CHAN_TO_FLOAT(rgba[ACOMP]);
+}
+
+
+static void
+fetch_texel_2d_rgb_fxt1( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLchan *texel )
+{
+ (void) k;
+ fxt1_decode_1(texImage->Data, texImage->RowStride, i, j, texel);
+ texel[ACOMP] = 255;
+}
+
+
+static void
+fetch_texel_2d_f_rgb_fxt1( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLfloat *texel )
+{
+ /* just sample as GLchan and convert to float here */
+ GLchan rgba[4];
+ (void) k;
+ fxt1_decode_1(texImage->Data, texImage->RowStride, i, j, rgba);
+ texel[RCOMP] = CHAN_TO_FLOAT(rgba[RCOMP]);
+ texel[GCOMP] = CHAN_TO_FLOAT(rgba[GCOMP]);
+ texel[BCOMP] = CHAN_TO_FLOAT(rgba[BCOMP]);
+ texel[ACOMP] = 1.0F;
+}
+
+
+
+const struct gl_texture_format _mesa_texformat_rgb_fxt1 = {
+ MESA_FORMAT_RGB_FXT1, /* MesaFormat */
+ GL_RGB, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ 4, /*approx*/ /* RedBits */
+ 4, /*approx*/ /* GreenBits */
+ 4, /*approx*/ /* BlueBits */
+ 0, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 0, /* TexelBytes */
+ texstore_rgb_fxt1, /* StoreTexImageFunc */
+ NULL, /*impossible*/ /* FetchTexel1D */
+ fetch_texel_2d_rgb_fxt1, /* FetchTexel2D */
+ NULL, /*impossible*/ /* FetchTexel3D */
+ NULL, /*impossible*/ /* FetchTexel1Df */
+ fetch_texel_2d_f_rgb_fxt1, /* FetchTexel2Df */
+ NULL, /*impossible*/ /* FetchTexel3Df */
+};
+
+const struct gl_texture_format _mesa_texformat_rgba_fxt1 = {
+ MESA_FORMAT_RGBA_FXT1, /* MesaFormat */
+ GL_RGBA, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ 4, /*approx*/ /* RedBits */
+ 4, /*approx*/ /* GreenBits */
+ 4, /*approx*/ /* BlueBits */
+ 1, /*approx*/ /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 0, /* TexelBytes */
+ texstore_rgba_fxt1, /* StoreTexImageFunc */
+ NULL, /*impossible*/ /* FetchTexel1D */
+ fetch_texel_2d_rgba_fxt1, /* FetchTexel2D */
+ NULL, /*impossible*/ /* FetchTexel3D */
+ NULL, /*impossible*/ /* FetchTexel1Df */
+ fetch_texel_2d_f_rgba_fxt1, /* FetchTexel2Df */
+ NULL, /*impossible*/ /* FetchTexel3Df */
+};
+
+
+/***************************************************************************\
+ * FXT1 encoder
+ *
+ * The encoder was built by reversing the decoder,
+ * and is vaguely based on Texus2 by 3dfx. Note that this code
+ * is merely a proof of concept, since it is highly UNoptimized;
+ * moreover, it is sub-optimal due to initial conditions passed
+ * to Lloyd's algorithm (the interpolation modes are even worse).
+\***************************************************************************/
+
+
+#define MAX_COMP 4 /* ever needed maximum number of components in texel */
+#define MAX_VECT 4 /* ever needed maximum number of base vectors to find */
+#define N_TEXELS 32 /* number of texels in a block (always 32) */
+#define LL_N_REP 50 /* number of iterations in lloyd's vq */
+#define LL_RMS_D 10 /* fault tolerance (maximum delta) */
+#define LL_RMS_E 255 /* fault tolerance (maximum error) */
+#define ALPHA_TS 2 /* alpha threshold: (255 - ALPHA_TS) deemed opaque */
+#define ISTBLACK(v) (*((GLuint *)(v)) == 0)
+
+
+/*
+ * Define a 64-bit unsigned integer type and macros
+ */
+#if defined(__GNUC__) && !defined(__cplusplus)
+
+#define FX64_NATIVE 1
+
+typedef unsigned long long Fx64;
+
+#define FX64_MOV32(a, b) a = b
+#define FX64_OR32(a, b) a |= b
+#define FX64_SHL(a, c) a <<= c
+
+#else /* !__GNUC__ */
+
+#define FX64_NATIVE 0
+
+typedef struct {
+ GLuint lo, hi;
+} Fx64;
+
+#define FX64_MOV32(a, b) a.lo = b
+#define FX64_OR32(a, b) a.lo |= b
+
+#define FX64_SHL(a, c) \
+ do { \
+ if ((c) >= 32) { \
+ a.hi = a.lo << ((c) - 32); \
+ a.lo = 0; \
+ } else { \
+ a.hi = (a.hi << (c)) | (a.lo >> (32 - (c))); \
+ a.lo <<= (c); \
+ } \
+ } while (0)
+
+#endif /* !__GNUC__ */
+
+
+#define F(i) (GLfloat)1 /* can be used to obtain an oblong metric: 0.30 / 0.59 / 0.11 */
+#define SAFECDOT 1 /* for paranoids */
+
+#define MAKEIVEC(NV, NC, IV, B, V0, V1) \
+ do { \
+ /* compute interpolation vector */ \
+ GLfloat d2 = 0.0F; \
+ GLfloat rd2; \
+ \
+ for (i = 0; i < NC; i++) { \
+ IV[i] = (V1[i] - V0[i]) * F(i); \
+ d2 += IV[i] * IV[i]; \
+ } \
+ rd2 = (GLfloat)NV / d2; \
+ B = 0; \
+ for (i = 0; i < NC; i++) { \
+ IV[i] *= F(i); \
+ B -= IV[i] * V0[i]; \
+ IV[i] *= rd2; \
+ } \
+ B = B * rd2 + 0.5f; \
+ } while (0)
+
+#define CALCCDOT(TEXEL, NV, NC, IV, B, V)\
+ do { \
+ GLfloat dot = 0.0F; \
+ for (i = 0; i < NC; i++) { \
+ dot += V[i] * IV[i]; \
+ } \
+ TEXEL = (GLint)(dot + B); \
+ if (SAFECDOT) { \
+ if (TEXEL < 0) { \
+ TEXEL = 0; \
+ } else if (TEXEL > NV) { \
+ TEXEL = NV; \
+ } \
+ } \
+ } while (0)
+
+
+static GLint
+fxt1_bestcol (GLfloat vec[][MAX_COMP], GLint nv,
+ GLubyte input[MAX_COMP], GLint nc)
+{
+ GLint i, j, best = -1;
+ GLfloat err = 1e9; /* big enough */
+
+ for (j = 0; j < nv; j++) {
+ GLfloat e = 0.0F;
+ for (i = 0; i < nc; i++) {
+ e += (vec[j][i] - input[i]) * (vec[j][i] - input[i]);
+ }
+ if (e < err) {
+ err = e;
+ best = j;
+ }
+ }
+
+ return best;
+}
+
+
+static GLint
+fxt1_worst (GLfloat vec[MAX_COMP],
+ GLubyte input[N_TEXELS][MAX_COMP], GLint nc, GLint n)
+{
+ GLint i, k, worst = -1;
+ GLfloat err = -1.0F; /* small enough */
+
+ for (k = 0; k < n; k++) {
+ GLfloat e = 0.0F;
+ for (i = 0; i < nc; i++) {
+ e += (vec[i] - input[k][i]) * (vec[i] - input[k][i]);
+ }
+ if (e > err) {
+ err = e;
+ worst = k;
+ }
+ }
+
+ return worst;
+}
+
+
+static GLint
+fxt1_variance (GLdouble variance[MAX_COMP],
+ GLubyte input[N_TEXELS][MAX_COMP], GLint nc, GLint n)
+{
+ GLint i, k, best = 0;
+ GLint sx, sx2;
+ GLdouble var, maxvar = -1; /* small enough */
+ GLdouble teenth = 1.0 / n;
+
+ for (i = 0; i < nc; i++) {
+ sx = sx2 = 0;
+ for (k = 0; k < n; k++) {
+ GLint t = input[k][i];
+ sx += t;
+ sx2 += t * t;
+ }
+ var = sx2 * teenth - sx * sx * teenth * teenth;
+ if (maxvar < var) {
+ maxvar = var;
+ best = i;
+ }
+ if (variance) {
+ variance[i] = var;
+ }
+ }
+
+ return best;
+}
+
+
+static GLint
+fxt1_choose (GLfloat vec[][MAX_COMP], GLint nv,
+ GLubyte input[N_TEXELS][MAX_COMP], GLint nc, GLint n)
+{
+#if 0
+ /* Choose colors from a grid.
+ */
+ GLint i, j;
+
+ for (j = 0; j < nv; j++) {
+ GLint m = j * (n - 1) / (nv - 1);
+ for (i = 0; i < nc; i++) {
+ vec[j][i] = input[m][i];
+ }
+ }
+#else
+ /* Our solution here is to find the darkest and brightest colors in
+ * the 8x4 tile and use those as the two representative colors.
+ * There are probably better algorithms to use (histogram-based).
+ */
+ GLint i, j, k;
+ GLint minSum = 2000; /* big enough */
+ GLint maxSum = -1; /* small enough */
+ GLint minCol = 0; /* phoudoin: silent compiler! */
+ GLint maxCol = 0; /* phoudoin: silent compiler! */
+
+ struct {
+ GLint flag;
+ GLint key;
+ GLint freq;
+ GLint idx;
+ } hist[N_TEXELS];
+ GLint lenh = 0;
+
+ _mesa_memset(hist, 0, sizeof(hist));
+
+ for (k = 0; k < n; k++) {
+ GLint l;
+ GLint key = 0;
+ GLint sum = 0;
+ for (i = 0; i < nc; i++) {
+ key <<= 8;
+ key |= input[k][i];
+ sum += input[k][i];
+ }
+ for (l = 0; l < n; l++) {
+ if (!hist[l].flag) {
+ /* alloc new slot */
+ hist[l].flag = !0;
+ hist[l].key = key;
+ hist[l].freq = 1;
+ hist[l].idx = k;
+ lenh = l + 1;
+ break;
+ } else if (hist[l].key == key) {
+ hist[l].freq++;
+ break;
+ }
+ }
+ if (minSum > sum) {
+ minSum = sum;
+ minCol = k;
+ }
+ if (maxSum < sum) {
+ maxSum = sum;
+ maxCol = k;
+ }
+ }
+
+ if (lenh <= nv) {
+ for (j = 0; j < lenh; j++) {
+ for (i = 0; i < nc; i++) {
+ vec[j][i] = (GLfloat)input[hist[j].idx][i];
+ }
+ }
+ for (; j < nv; j++) {
+ for (i = 0; i < nc; i++) {
+ vec[j][i] = vec[0][i];
+ }
+ }
+ return 0;
+ }
+
+ for (j = 0; j < nv; j++) {
+ for (i = 0; i < nc; i++) {
+ vec[j][i] = ((nv - 1 - j) * input[minCol][i] + j * input[maxCol][i] + (nv - 1) / 2) / (GLfloat)(nv - 1);
+ }
+ }
+#endif
+
+ return !0;
+}
+
+
+static GLint
+fxt1_lloyd (GLfloat vec[][MAX_COMP], GLint nv,
+ GLubyte input[N_TEXELS][MAX_COMP], GLint nc, GLint n)
+{
+ /* Use the generalized lloyd's algorithm for VQ:
+ * find 4 color vectors.
+ *
+ * for each sample color
+ * sort to nearest vector.
+ *
+ * replace each vector with the centroid of it's matching colors.
+ *
+ * repeat until RMS doesn't improve.
+ *
+ * if a color vector has no samples, or becomes the same as another
+ * vector, replace it with the color which is farthest from a sample.
+ *
+ * vec[][MAX_COMP] initial vectors and resulting colors
+ * nv number of resulting colors required
+ * input[N_TEXELS][MAX_COMP] input texels
+ * nc number of components in input / vec
+ * n number of input samples
+ */
+
+ GLint sum[MAX_VECT][MAX_COMP]; /* used to accumulate closest texels */
+ GLint cnt[MAX_VECT]; /* how many times a certain vector was chosen */
+ GLfloat error, lasterror = 1e9;
+
+ GLint i, j, k, rep;
+
+ /* the quantizer */
+ for (rep = 0; rep < LL_N_REP; rep++) {
+ /* reset sums & counters */
+ for (j = 0; j < nv; j++) {
+ for (i = 0; i < nc; i++) {
+ sum[j][i] = 0;
+ }
+ cnt[j] = 0;
+ }
+ error = 0;
+
+ /* scan whole block */
+ for (k = 0; k < n; k++) {
+#if 1
+ GLint best = -1;
+ GLfloat err = 1e9; /* big enough */
+ /* determine best vector */
+ for (j = 0; j < nv; j++) {
+ GLfloat e = (vec[j][0] - input[k][0]) * (vec[j][0] - input[k][0]) +
+ (vec[j][1] - input[k][1]) * (vec[j][1] - input[k][1]) +
+ (vec[j][2] - input[k][2]) * (vec[j][2] - input[k][2]);
+ if (nc == 4) {
+ e += (vec[j][3] - input[k][3]) * (vec[j][3] - input[k][3]);
+ }
+ if (e < err) {
+ err = e;
+ best = j;
+ }
+ }
+#else
+ GLint best = fxt1_bestcol(vec, nv, input[k], nc, &err);
+#endif
+ /* add in closest color */
+ for (i = 0; i < nc; i++) {
+ sum[best][i] += input[k][i];
+ }
+ /* mark this vector as used */
+ cnt[best]++;
+ /* accumulate error */
+ error += err;
+ }
+
+ /* check RMS */
+ if ((error < LL_RMS_E) ||
+ ((error < lasterror) && ((lasterror - error) < LL_RMS_D))) {
+ return !0; /* good match */
+ }
+ lasterror = error;
+
+ /* move each vector to the barycenter of its closest colors */
+ for (j = 0; j < nv; j++) {
+ if (cnt[j]) {
+ GLfloat div = 1.0F / cnt[j];
+ for (i = 0; i < nc; i++) {
+ vec[j][i] = div * sum[j][i];
+ }
+ } else {
+ /* this vec has no samples or is identical with a previous vec */
+ GLint worst = fxt1_worst(vec[j], input, nc, n);
+ for (i = 0; i < nc; i++) {
+ vec[j][i] = input[worst][i];
+ }
+ }
+ }
+ }
+
+ return 0; /* could not converge fast enough */
+}
+
+
+static void
+fxt1_quantize_CHROMA (GLuint *cc,
+ GLubyte input[N_TEXELS][MAX_COMP])
+{
+ const GLint n_vect = 4; /* 4 base vectors to find */
+ const GLint n_comp = 3; /* 3 components: R, G, B */
+ GLfloat vec[MAX_VECT][MAX_COMP];
+ GLint i, j, k;
+ Fx64 hi; /* high quadword */
+ GLuint lohi, lolo; /* low quadword: hi dword, lo dword */
+
+ if (fxt1_choose(vec, n_vect, input, n_comp, N_TEXELS) != 0) {
+ fxt1_lloyd(vec, n_vect, input, n_comp, N_TEXELS);
+ }
+
+ FX64_MOV32(hi, 4); /* cc-chroma = "010" + unused bit */
+ for (j = n_vect - 1; j >= 0; j--) {
+ for (i = 0; i < n_comp; i++) {
+ /* add in colors */
+ FX64_SHL(hi, 5);
+ FX64_OR32(hi, (GLuint)(vec[j][i] / 8.0F));
+ }
+ }
+ ((Fx64 *)cc)[1] = hi;
+
+ lohi = lolo = 0;
+ /* right microtile */
+ for (k = N_TEXELS - 1; k >= N_TEXELS/2; k--) {
+ lohi <<= 2;
+ lohi |= fxt1_bestcol(vec, n_vect, input[k], n_comp);
+ }
+ /* left microtile */
+ for (; k >= 0; k--) {
+ lolo <<= 2;
+ lolo |= fxt1_bestcol(vec, n_vect, input[k], n_comp);
+ }
+ cc[1] = lohi;
+ cc[0] = lolo;
+}
+
+
+static void
+fxt1_quantize_ALPHA0 (GLuint *cc,
+ GLubyte input[N_TEXELS][MAX_COMP],
+ GLubyte reord[N_TEXELS][MAX_COMP], GLint n)
+{
+ const GLint n_vect = 3; /* 3 base vectors to find */
+ const GLint n_comp = 4; /* 4 components: R, G, B, A */
+ GLfloat vec[MAX_VECT][MAX_COMP];
+ GLint i, j, k;
+ Fx64 hi; /* high quadword */
+ GLuint lohi, lolo; /* low quadword: hi dword, lo dword */
+
+ /* the last vector indicates zero */
+ for (i = 0; i < n_comp; i++) {
+ vec[n_vect][i] = 0;
+ }
+
+ /* the first n texels in reord are guaranteed to be non-zero */
+ if (fxt1_choose(vec, n_vect, reord, n_comp, n) != 0) {
+ fxt1_lloyd(vec, n_vect, reord, n_comp, n);
+ }
+
+ FX64_MOV32(hi, 6); /* alpha = "011" + lerp = 0 */
+ for (j = n_vect - 1; j >= 0; j--) {
+ /* add in alphas */
+ FX64_SHL(hi, 5);
+ FX64_OR32(hi, (GLuint)(vec[j][ACOMP] / 8.0F));
+ }
+ for (j = n_vect - 1; j >= 0; j--) {
+ for (i = 0; i < n_comp - 1; i++) {
+ /* add in colors */
+ FX64_SHL(hi, 5);
+ FX64_OR32(hi, (GLuint)(vec[j][i] / 8.0F));
+ }
+ }
+ ((Fx64 *)cc)[1] = hi;
+
+ lohi = lolo = 0;
+ /* right microtile */
+ for (k = N_TEXELS - 1; k >= N_TEXELS/2; k--) {
+ lohi <<= 2;
+ lohi |= fxt1_bestcol(vec, n_vect + 1, input[k], n_comp);
+ }
+ /* left microtile */
+ for (; k >= 0; k--) {
+ lolo <<= 2;
+ lolo |= fxt1_bestcol(vec, n_vect + 1, input[k], n_comp);
+ }
+ cc[1] = lohi;
+ cc[0] = lolo;
+}
+
+
+static void
+fxt1_quantize_ALPHA1 (GLuint *cc,
+ GLubyte input[N_TEXELS][MAX_COMP])
+{
+ const GLint n_vect = 3; /* highest vector number in each microtile */
+ const GLint n_comp = 4; /* 4 components: R, G, B, A */
+ GLfloat vec[1 + 1 + 1][MAX_COMP]; /* 1.5 extrema for each sub-block */
+ GLfloat b, iv[MAX_COMP]; /* interpolation vector */
+ GLint i, j, k;
+ Fx64 hi; /* high quadword */
+ GLuint lohi, lolo; /* low quadword: hi dword, lo dword */
+
+ GLint minSum;
+ GLint maxSum;
+ GLint minColL = 0, maxColL = 0;
+ GLint minColR = 0, maxColR = 0;
+ GLint sumL = 0, sumR = 0;
+
+ /* Our solution here is to find the darkest and brightest colors in
+ * the 4x4 tile and use those as the two representative colors.
+ * There are probably better algorithms to use (histogram-based).
+ */
+ minSum = 2000; /* big enough */
+ maxSum = -1; /* small enough */
+ for (k = 0; k < N_TEXELS / 2; k++) {
+ GLint sum = 0;
+ for (i = 0; i < n_comp; i++) {
+ sum += input[k][i];
+ }
+ if (minSum > sum) {
+ minSum = sum;
+ minColL = k;
+ }
+ if (maxSum < sum) {
+ maxSum = sum;
+ maxColL = k;
+ }
+ sumL += sum;
+ }
+ minSum = 2000; /* big enough */
+ maxSum = -1; /* small enough */
+ for (; k < N_TEXELS; k++) {
+ GLint sum = 0;
+ for (i = 0; i < n_comp; i++) {
+ sum += input[k][i];
+ }
+ if (minSum > sum) {
+ minSum = sum;
+ minColR = k;
+ }
+ if (maxSum < sum) {
+ maxSum = sum;
+ maxColR = k;
+ }
+ sumR += sum;
+ }
+
+ /* choose the common vector (yuck!) */
+ {
+ GLint j1, j2;
+ GLint v1 = 0, v2 = 0;
+ GLfloat err = 1e9; /* big enough */
+ GLfloat tv[2 * 2][MAX_COMP]; /* 2 extrema for each sub-block */
+ for (i = 0; i < n_comp; i++) {
+ tv[0][i] = input[minColL][i];
+ tv[1][i] = input[maxColL][i];
+ tv[2][i] = input[minColR][i];
+ tv[3][i] = input[maxColR][i];
+ }
+ for (j1 = 0; j1 < 2; j1++) {
+ for (j2 = 2; j2 < 4; j2++) {
+ GLfloat e = 0.0F;
+ for (i = 0; i < n_comp; i++) {
+ e += (tv[j1][i] - tv[j2][i]) * (tv[j1][i] - tv[j2][i]);
+ }
+ if (e < err) {
+ err = e;
+ v1 = j1;
+ v2 = j2;
+ }
+ }
+ }
+ for (i = 0; i < n_comp; i++) {
+ vec[0][i] = tv[1 - v1][i];
+ vec[1][i] = (tv[v1][i] * sumL + tv[v2][i] * sumR) / (sumL + sumR);
+ vec[2][i] = tv[5 - v2][i];
+ }
+ }
+
+ /* left microtile */
+ cc[0] = 0;
+ if (minColL != maxColL) {
+ /* compute interpolation vector */
+ MAKEIVEC(n_vect, n_comp, iv, b, vec[0], vec[1]);
+
+ /* add in texels */
+ lolo = 0;
+ for (k = N_TEXELS / 2 - 1; k >= 0; k--) {
+ GLint texel;
+ /* interpolate color */
+ CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]);
+ /* add in texel */
+ lolo <<= 2;
+ lolo |= texel;
+ }
+
+ cc[0] = lolo;
+ }
+
+ /* right microtile */
+ cc[1] = 0;
+ if (minColR != maxColR) {
+ /* compute interpolation vector */
+ MAKEIVEC(n_vect, n_comp, iv, b, vec[2], vec[1]);
+
+ /* add in texels */
+ lohi = 0;
+ for (k = N_TEXELS - 1; k >= N_TEXELS / 2; k--) {
+ GLint texel;
+ /* interpolate color */
+ CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]);
+ /* add in texel */
+ lohi <<= 2;
+ lohi |= texel;
+ }
+
+ cc[1] = lohi;
+ }
+
+ FX64_MOV32(hi, 7); /* alpha = "011" + lerp = 1 */
+ for (j = n_vect - 1; j >= 0; j--) {
+ /* add in alphas */
+ FX64_SHL(hi, 5);
+ FX64_OR32(hi, (GLuint)(vec[j][ACOMP] / 8.0F));
+ }
+ for (j = n_vect - 1; j >= 0; j--) {
+ for (i = 0; i < n_comp - 1; i++) {
+ /* add in colors */
+ FX64_SHL(hi, 5);
+ FX64_OR32(hi, (GLuint)(vec[j][i] / 8.0F));
+ }
+ }
+ ((Fx64 *)cc)[1] = hi;
+}
+
+
+static void
+fxt1_quantize_HI (GLuint *cc,
+ GLubyte input[N_TEXELS][MAX_COMP],
+ GLubyte reord[N_TEXELS][MAX_COMP], GLint n)
+{
+ const GLint n_vect = 6; /* highest vector number */
+ const GLint n_comp = 3; /* 3 components: R, G, B */
+ GLfloat b = 0.0F; /* phoudoin: silent compiler! */
+ GLfloat iv[MAX_COMP]; /* interpolation vector */
+ GLint i, k;
+ GLuint hihi; /* high quadword: hi dword */
+
+ GLint minSum = 2000; /* big enough */
+ GLint maxSum = -1; /* small enough */
+ GLint minCol = 0; /* phoudoin: silent compiler! */
+ GLint maxCol = 0; /* phoudoin: silent compiler! */
+
+ /* Our solution here is to find the darkest and brightest colors in
+ * the 8x4 tile and use those as the two representative colors.
+ * There are probably better algorithms to use (histogram-based).
+ */
+ for (k = 0; k < n; k++) {
+ GLint sum = 0;
+ for (i = 0; i < n_comp; i++) {
+ sum += reord[k][i];
+ }
+ if (minSum > sum) {
+ minSum = sum;
+ minCol = k;
+ }
+ if (maxSum < sum) {
+ maxSum = sum;
+ maxCol = k;
+ }
+ }
+
+ hihi = 0; /* cc-hi = "00" */
+ for (i = 0; i < n_comp; i++) {
+ /* add in colors */
+ hihi <<= 5;
+ hihi |= reord[maxCol][i] >> 3;
+ }
+ for (i = 0; i < n_comp; i++) {
+ /* add in colors */
+ hihi <<= 5;
+ hihi |= reord[minCol][i] >> 3;
+ }
+ cc[3] = hihi;
+ cc[0] = cc[1] = cc[2] = 0;
+
+ /* compute interpolation vector */
+ if (minCol != maxCol) {
+ MAKEIVEC(n_vect, n_comp, iv, b, reord[minCol], reord[maxCol]);
+ }
+
+ /* add in texels */
+ for (k = N_TEXELS - 1; k >= 0; k--) {
+ GLint t = k * 3;
+ GLuint *kk = (GLuint *)((char *)cc + t / 8);
+ GLint texel = n_vect + 1; /* transparent black */
+
+ if (!ISTBLACK(input[k])) {
+ if (minCol != maxCol) {
+ /* interpolate color */
+ CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]);
+ /* add in texel */
+ kk[0] |= texel << (t & 7);
+ }
+ } else {
+ /* add in texel */
+ kk[0] |= texel << (t & 7);
+ }
+ }
+}
+
+
+static void
+fxt1_quantize_MIXED1 (GLuint *cc,
+ GLubyte input[N_TEXELS][MAX_COMP])
+{
+ const GLint n_vect = 2; /* highest vector number in each microtile */
+ const GLint n_comp = 3; /* 3 components: R, G, B */
+ GLubyte vec[2 * 2][MAX_COMP]; /* 2 extrema for each sub-block */
+ GLfloat b, iv[MAX_COMP]; /* interpolation vector */
+ GLint i, j, k;
+ Fx64 hi; /* high quadword */
+ GLuint lohi, lolo; /* low quadword: hi dword, lo dword */
+
+ GLint minSum;
+ GLint maxSum;
+ GLint minColL = 0, maxColL = -1;
+ GLint minColR = 0, maxColR = -1;
+
+ /* Our solution here is to find the darkest and brightest colors in
+ * the 4x4 tile and use those as the two representative colors.
+ * There are probably better algorithms to use (histogram-based).
+ */
+ minSum = 2000; /* big enough */
+ maxSum = -1; /* small enough */
+ for (k = 0; k < N_TEXELS / 2; k++) {
+ if (!ISTBLACK(input[k])) {
+ GLint sum = 0;
+ for (i = 0; i < n_comp; i++) {
+ sum += input[k][i];
+ }
+ if (minSum > sum) {
+ minSum = sum;
+ minColL = k;
+ }
+ if (maxSum < sum) {
+ maxSum = sum;
+ maxColL = k;
+ }
+ }
+ }
+ minSum = 2000; /* big enough */
+ maxSum = -1; /* small enough */
+ for (; k < N_TEXELS; k++) {
+ if (!ISTBLACK(input[k])) {
+ GLint sum = 0;
+ for (i = 0; i < n_comp; i++) {
+ sum += input[k][i];
+ }
+ if (minSum > sum) {
+ minSum = sum;
+ minColR = k;
+ }
+ if (maxSum < sum) {
+ maxSum = sum;
+ maxColR = k;
+ }
+ }
+ }
+
+ /* left microtile */
+ if (maxColL == -1) {
+ /* all transparent black */
+ cc[0] = ~0u;
+ for (i = 0; i < n_comp; i++) {
+ vec[0][i] = 0;
+ vec[1][i] = 0;
+ }
+ } else {
+ cc[0] = 0;
+ for (i = 0; i < n_comp; i++) {
+ vec[0][i] = input[minColL][i];
+ vec[1][i] = input[maxColL][i];
+ }
+ if (minColL != maxColL) {
+ /* compute interpolation vector */
+ MAKEIVEC(n_vect, n_comp, iv, b, vec[0], vec[1]);
+
+ /* add in texels */
+ lolo = 0;
+ for (k = N_TEXELS / 2 - 1; k >= 0; k--) {
+ GLint texel = n_vect + 1; /* transparent black */
+ if (!ISTBLACK(input[k])) {
+ /* interpolate color */
+ CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]);
+ }
+ /* add in texel */
+ lolo <<= 2;
+ lolo |= texel;
+ }
+ cc[0] = lolo;
+ }
+ }
+
+ /* right microtile */
+ if (maxColR == -1) {
+ /* all transparent black */
+ cc[1] = ~0u;
+ for (i = 0; i < n_comp; i++) {
+ vec[2][i] = 0;
+ vec[3][i] = 0;
+ }
+ } else {
+ cc[1] = 0;
+ for (i = 0; i < n_comp; i++) {
+ vec[2][i] = input[minColR][i];
+ vec[3][i] = input[maxColR][i];
+ }
+ if (minColR != maxColR) {
+ /* compute interpolation vector */
+ MAKEIVEC(n_vect, n_comp, iv, b, vec[2], vec[3]);
+
+ /* add in texels */
+ lohi = 0;
+ for (k = N_TEXELS - 1; k >= N_TEXELS / 2; k--) {
+ GLint texel = n_vect + 1; /* transparent black */
+ if (!ISTBLACK(input[k])) {
+ /* interpolate color */
+ CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]);
+ }
+ /* add in texel */
+ lohi <<= 2;
+ lohi |= texel;
+ }
+ cc[1] = lohi;
+ }
+ }
+
+ FX64_MOV32(hi, 9 | (vec[3][GCOMP] & 4) | ((vec[1][GCOMP] >> 1) & 2)); /* chroma = "1" */
+ for (j = 2 * 2 - 1; j >= 0; j--) {
+ for (i = 0; i < n_comp; i++) {
+ /* add in colors */
+ FX64_SHL(hi, 5);
+ FX64_OR32(hi, vec[j][i] >> 3);
+ }
+ }
+ ((Fx64 *)cc)[1] = hi;
+}
+
+
+static void
+fxt1_quantize_MIXED0 (GLuint *cc,
+ GLubyte input[N_TEXELS][MAX_COMP])
+{
+ const GLint n_vect = 3; /* highest vector number in each microtile */
+ const GLint n_comp = 3; /* 3 components: R, G, B */
+ GLubyte vec[2 * 2][MAX_COMP]; /* 2 extrema for each sub-block */
+ GLfloat b, iv[MAX_COMP]; /* interpolation vector */
+ GLint i, j, k;
+ Fx64 hi; /* high quadword */
+ GLuint lohi, lolo; /* low quadword: hi dword, lo dword */
+
+ GLint minColL = 0, maxColL = 0;
+ GLint minColR = 0, maxColR = 0;
+#if 0
+ GLint minSum;
+ GLint maxSum;
+
+ /* Our solution here is to find the darkest and brightest colors in
+ * the 4x4 tile and use those as the two representative colors.
+ * There are probably better algorithms to use (histogram-based).
+ */
+ minSum = 2000; /* big enough */
+ maxSum = -1; /* small enough */
+ for (k = 0; k < N_TEXELS / 2; k++) {
+ GLint sum = 0;
+ for (i = 0; i < n_comp; i++) {
+ sum += input[k][i];
+ }
+ if (minSum > sum) {
+ minSum = sum;
+ minColL = k;
+ }
+ if (maxSum < sum) {
+ maxSum = sum;
+ maxColL = k;
+ }
+ }
+ minSum = 2000; /* big enough */
+ maxSum = -1; /* small enough */
+ for (; k < N_TEXELS; k++) {
+ GLint sum = 0;
+ for (i = 0; i < n_comp; i++) {
+ sum += input[k][i];
+ }
+ if (minSum > sum) {
+ minSum = sum;
+ minColR = k;
+ }
+ if (maxSum < sum) {
+ maxSum = sum;
+ maxColR = k;
+ }
+ }
+#else
+ GLint minVal;
+ GLint maxVal;
+ GLint maxVarL = fxt1_variance(NULL, input, n_comp, N_TEXELS / 2);
+ GLint maxVarR = fxt1_variance(NULL, &input[N_TEXELS / 2], n_comp, N_TEXELS / 2);
+
+ /* Scan the channel with max variance for lo & hi
+ * and use those as the two representative colors.
+ */
+ minVal = 2000; /* big enough */
+ maxVal = -1; /* small enough */
+ for (k = 0; k < N_TEXELS / 2; k++) {
+ GLint t = input[k][maxVarL];
+ if (minVal > t) {
+ minVal = t;
+ minColL = k;
+ }
+ if (maxVal < t) {
+ maxVal = t;
+ maxColL = k;
+ }
+ }
+ minVal = 2000; /* big enough */
+ maxVal = -1; /* small enough */
+ for (; k < N_TEXELS; k++) {
+ GLint t = input[k][maxVarR];
+ if (minVal > t) {
+ minVal = t;
+ minColR = k;
+ }
+ if (maxVal < t) {
+ maxVal = t;
+ maxColR = k;
+ }
+ }
+#endif
+
+ /* left microtile */
+ cc[0] = 0;
+ for (i = 0; i < n_comp; i++) {
+ vec[0][i] = input[minColL][i];
+ vec[1][i] = input[maxColL][i];
+ }
+ if (minColL != maxColL) {
+ /* compute interpolation vector */
+ MAKEIVEC(n_vect, n_comp, iv, b, vec[0], vec[1]);
+
+ /* add in texels */
+ lolo = 0;
+ for (k = N_TEXELS / 2 - 1; k >= 0; k--) {
+ GLint texel;
+ /* interpolate color */
+ CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]);
+ /* add in texel */
+ lolo <<= 2;
+ lolo |= texel;
+ }
+
+ /* funky encoding for LSB of green */
+ if ((GLint)((lolo >> 1) & 1) != (((vec[1][GCOMP] ^ vec[0][GCOMP]) >> 2) & 1)) {
+ for (i = 0; i < n_comp; i++) {
+ vec[1][i] = input[minColL][i];
+ vec[0][i] = input[maxColL][i];
+ }
+ lolo = ~lolo;
+ }
+
+ cc[0] = lolo;
+ }
+
+ /* right microtile */
+ cc[1] = 0;
+ for (i = 0; i < n_comp; i++) {
+ vec[2][i] = input[minColR][i];
+ vec[3][i] = input[maxColR][i];
+ }
+ if (minColR != maxColR) {
+ /* compute interpolation vector */
+ MAKEIVEC(n_vect, n_comp, iv, b, vec[2], vec[3]);
+
+ /* add in texels */
+ lohi = 0;
+ for (k = N_TEXELS - 1; k >= N_TEXELS / 2; k--) {
+ GLint texel;
+ /* interpolate color */
+ CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]);
+ /* add in texel */
+ lohi <<= 2;
+ lohi |= texel;
+ }
+
+ /* funky encoding for LSB of green */
+ if ((GLint)((lohi >> 1) & 1) != (((vec[3][GCOMP] ^ vec[2][GCOMP]) >> 2) & 1)) {
+ for (i = 0; i < n_comp; i++) {
+ vec[3][i] = input[minColR][i];
+ vec[2][i] = input[maxColR][i];
+ }
+ lohi = ~lohi;
+ }
+
+ cc[1] = lohi;
+ }
+
+ FX64_MOV32(hi, 8 | (vec[3][GCOMP] & 4) | ((vec[1][GCOMP] >> 1) & 2)); /* chroma = "1" */
+ for (j = 2 * 2 - 1; j >= 0; j--) {
+ for (i = 0; i < n_comp; i++) {
+ /* add in colors */
+ FX64_SHL(hi, 5);
+ FX64_OR32(hi, vec[j][i] >> 3);
+ }
+ }
+ ((Fx64 *)cc)[1] = hi;
+}
+
+
+static void
+fxt1_quantize (GLuint *cc, const GLubyte *lines[], GLint comps)
+{
+ GLint trualpha;
+ GLubyte reord[N_TEXELS][MAX_COMP];
+
+ GLubyte input[N_TEXELS][MAX_COMP];
+ GLint i, k, l;
+
+ if (comps == 3) {
+ /* make the whole block opaque */
+ _mesa_memset(input, -1, sizeof(input));
+ }
+
+ /* 8 texels each line */
+ for (l = 0; l < 4; l++) {
+ for (k = 0; k < 4; k++) {
+ for (i = 0; i < comps; i++) {
+ input[k + l * 4][i] = *lines[l]++;
+ }
+ }
+ for (; k < 8; k++) {
+ for (i = 0; i < comps; i++) {
+ input[k + l * 4 + 12][i] = *lines[l]++;
+ }
+ }
+ }
+
+ /* block layout:
+ * 00, 01, 02, 03, 08, 09, 0a, 0b
+ * 10, 11, 12, 13, 18, 19, 1a, 1b
+ * 04, 05, 06, 07, 0c, 0d, 0e, 0f
+ * 14, 15, 16, 17, 1c, 1d, 1e, 1f
+ */
+
+ /* [dBorca]
+ * stupidity flows forth from this
+ */
+ l = N_TEXELS;
+ trualpha = 0;
+ if (comps == 4) {
+ /* skip all transparent black texels */
+ l = 0;
+ for (k = 0; k < N_TEXELS; k++) {
+ /* test all components against 0 */
+ if (!ISTBLACK(input[k])) {
+ /* texel is not transparent black */
+ COPY_4UBV(reord[l], input[k]);
+ if (reord[l][ACOMP] < (255 - ALPHA_TS)) {
+ /* non-opaque texel */
+ trualpha = !0;
+ }
+ l++;
+ }
+ }
+ }
+
+#if 0
+ if (trualpha) {
+ fxt1_quantize_ALPHA0(cc, input, reord, l);
+ } else if (l == 0) {
+ cc[0] = cc[1] = cc[2] = -1;
+ cc[3] = 0;
+ } else if (l < N_TEXELS) {
+ fxt1_quantize_HI(cc, input, reord, l);
+ } else {
+ fxt1_quantize_CHROMA(cc, input);
+ }
+ (void)fxt1_quantize_ALPHA1;
+ (void)fxt1_quantize_MIXED1;
+ (void)fxt1_quantize_MIXED0;
+#else
+ if (trualpha) {
+ fxt1_quantize_ALPHA1(cc, input);
+ } else if (l == 0) {
+ cc[0] = cc[1] = cc[2] = ~0u;
+ cc[3] = 0;
+ } else if (l < N_TEXELS) {
+ fxt1_quantize_MIXED1(cc, input);
+ } else {
+ fxt1_quantize_MIXED0(cc, input);
+ }
+ (void)fxt1_quantize_ALPHA0;
+ (void)fxt1_quantize_HI;
+ (void)fxt1_quantize_CHROMA;
+#endif
+}
+
+
+static void
+fxt1_encode (GLuint width, GLuint height, GLint comps,
+ const void *source, GLint srcRowStride,
+ void *dest, GLint destRowStride)
+{
+ GLuint x, y;
+ const GLubyte *data;
+ GLuint *encoded = (GLuint *)dest;
+ void *newSource = NULL;
+
+ assert(comps == 3 || comps == 4);
+
+ /* Replicate image if width is not M8 or height is not M4 */
+ if ((width & 7) | (height & 3)) {
+ GLint newWidth = (width + 7) & ~7;
+ GLint newHeight = (height + 3) & ~3;
+ newSource = _mesa_malloc(comps * newWidth * newHeight * sizeof(GLchan));
+ if (!newSource) {
+ GET_CURRENT_CONTEXT(ctx);
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture compression");
+ goto cleanUp;
+ }
+ _mesa_upscale_teximage2d(width, height, newWidth, newHeight,
+ comps, (const GLchan *) source,
+ srcRowStride, (GLchan *) newSource);
+ source = newSource;
+ width = newWidth;
+ height = newHeight;
+ srcRowStride = comps * newWidth;
+ }
+
+ /* convert from 16/32-bit channels to GLubyte if needed */
+ if (CHAN_TYPE != GL_UNSIGNED_BYTE) {
+ const GLuint n = width * height * comps;
+ const GLchan *src = (const GLchan *) source;
+ GLubyte *dest = (GLubyte *) _mesa_malloc(n * sizeof(GLubyte));
+ GLuint i;
+ if (!dest) {
+ GET_CURRENT_CONTEXT(ctx);
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture compression");
+ goto cleanUp;
+ }
+ for (i = 0; i < n; i++) {
+ dest[i] = CHAN_TO_UBYTE(src[i]);
+ }
+ if (newSource != NULL) {
+ _mesa_free(newSource);
+ }
+ newSource = dest; /* we'll free this buffer before returning */
+ source = dest; /* the new, GLubyte incoming image */
+ }
+
+ data = (const GLubyte *) source;
+ destRowStride = (destRowStride - width * 2) / 4;
+ for (y = 0; y < height; y += 4) {
+ GLuint offs = 0 + (y + 0) * srcRowStride;
+ for (x = 0; x < width; x += 8) {
+ const GLubyte *lines[4];
+ lines[0] = &data[offs];
+ lines[1] = lines[0] + srcRowStride;
+ lines[2] = lines[1] + srcRowStride;
+ lines[3] = lines[2] + srcRowStride;
+ offs += 8 * comps;
+ fxt1_quantize(encoded, lines, comps);
+ /* 128 bits per 8x4 block */
+ encoded += 4;
+ }
+ encoded += destRowStride;
+ }
+
+ cleanUp:
+ if (newSource != NULL) {
+ _mesa_free(newSource);
+ }
+}
+
+
+/***************************************************************************\
+ * FXT1 decoder
+ *
+ * The decoder is based on GL_3DFX_texture_compression_FXT1
+ * specification and serves as a concept for the encoder.
+\***************************************************************************/
+
+
+/* lookup table for scaling 5 bit colors up to 8 bits */
+static const GLubyte _rgb_scale_5[] = {
+ 0, 8, 16, 25, 33, 41, 49, 58,
+ 66, 74, 82, 90, 99, 107, 115, 123,
+ 132, 140, 148, 156, 165, 173, 181, 189,
+ 197, 206, 214, 222, 230, 239, 247, 255
+};
+
+/* lookup table for scaling 6 bit colors up to 8 bits */
+static const GLubyte _rgb_scale_6[] = {
+ 0, 4, 8, 12, 16, 20, 24, 28,
+ 32, 36, 40, 45, 49, 53, 57, 61,
+ 65, 69, 73, 77, 81, 85, 89, 93,
+ 97, 101, 105, 109, 113, 117, 121, 125,
+ 130, 134, 138, 142, 146, 150, 154, 158,
+ 162, 166, 170, 174, 178, 182, 186, 190,
+ 194, 198, 202, 206, 210, 215, 219, 223,
+ 227, 231, 235, 239, 243, 247, 251, 255
+};
+
+
+#define CC_SEL(cc, which) (((GLuint *)(cc))[(which) / 32] >> ((which) & 31))
+#define UP5(c) _rgb_scale_5[(c) & 31]
+#define UP6(c, b) _rgb_scale_6[(((c) & 31) << 1) | ((b) & 1)]
+#define LERP(n, t, c0, c1) (((n) - (t)) * (c0) + (t) * (c1) + (n) / 2) / (n)
+
+
+static void
+fxt1_decode_1HI (const GLubyte *code, GLint t, GLchan *rgba)
+{
+ const GLuint *cc;
+
+ t *= 3;
+ cc = (const GLuint *)(code + t / 8);
+ t = (cc[0] >> (t & 7)) & 7;
+
+ if (t == 7) {
+ rgba[RCOMP] = rgba[GCOMP] = rgba[BCOMP] = rgba[ACOMP] = 0;
+ } else {
+ GLubyte r, g, b;
+ cc = (const GLuint *)(code + 12);
+ if (t == 0) {
+ b = UP5(CC_SEL(cc, 0));
+ g = UP5(CC_SEL(cc, 5));
+ r = UP5(CC_SEL(cc, 10));
+ } else if (t == 6) {
+ b = UP5(CC_SEL(cc, 15));
+ g = UP5(CC_SEL(cc, 20));
+ r = UP5(CC_SEL(cc, 25));
+ } else {
+ b = LERP(6, t, UP5(CC_SEL(cc, 0)), UP5(CC_SEL(cc, 15)));
+ g = LERP(6, t, UP5(CC_SEL(cc, 5)), UP5(CC_SEL(cc, 20)));
+ r = LERP(6, t, UP5(CC_SEL(cc, 10)), UP5(CC_SEL(cc, 25)));
+ }
+ rgba[RCOMP] = UBYTE_TO_CHAN(r);
+ rgba[GCOMP] = UBYTE_TO_CHAN(g);
+ rgba[BCOMP] = UBYTE_TO_CHAN(b);
+ rgba[ACOMP] = CHAN_MAX;
+ }
+}
+
+
+static void
+fxt1_decode_1CHROMA (const GLubyte *code, GLint t, GLchan *rgba)
+{
+ const GLuint *cc;
+ GLuint kk;
+
+ cc = (const GLuint *)code;
+ if (t & 16) {
+ cc++;
+ t &= 15;
+ }
+ t = (cc[0] >> (t * 2)) & 3;
+
+ t *= 15;
+ cc = (const GLuint *)(code + 8 + t / 8);
+ kk = cc[0] >> (t & 7);
+ rgba[BCOMP] = UBYTE_TO_CHAN( UP5(kk) );
+ rgba[GCOMP] = UBYTE_TO_CHAN( UP5(kk >> 5) );
+ rgba[RCOMP] = UBYTE_TO_CHAN( UP5(kk >> 10) );
+ rgba[ACOMP] = CHAN_MAX;
+}
+
+
+static void
+fxt1_decode_1MIXED (const GLubyte *code, GLint t, GLchan *rgba)
+{
+ const GLuint *cc;
+ GLuint col[2][3];
+ GLint glsb, selb;
+
+ cc = (const GLuint *)code;
+ if (t & 16) {
+ t &= 15;
+ t = (cc[1] >> (t * 2)) & 3;
+ /* col 2 */
+ col[0][BCOMP] = (*(const GLuint *)(code + 11)) >> 6;
+ col[0][GCOMP] = CC_SEL(cc, 99);
+ col[0][RCOMP] = CC_SEL(cc, 104);
+ /* col 3 */
+ col[1][BCOMP] = CC_SEL(cc, 109);
+ col[1][GCOMP] = CC_SEL(cc, 114);
+ col[1][RCOMP] = CC_SEL(cc, 119);
+ glsb = CC_SEL(cc, 126);
+ selb = CC_SEL(cc, 33);
+ } else {
+ t = (cc[0] >> (t * 2)) & 3;
+ /* col 0 */
+ col[0][BCOMP] = CC_SEL(cc, 64);
+ col[0][GCOMP] = CC_SEL(cc, 69);
+ col[0][RCOMP] = CC_SEL(cc, 74);
+ /* col 1 */
+ col[1][BCOMP] = CC_SEL(cc, 79);
+ col[1][GCOMP] = CC_SEL(cc, 84);
+ col[1][RCOMP] = CC_SEL(cc, 89);
+ glsb = CC_SEL(cc, 125);
+ selb = CC_SEL(cc, 1);
+ }
+
+ if (CC_SEL(cc, 124) & 1) {
+ /* alpha[0] == 1 */
+
+ if (t == 3) {
+ /* zero */
+ rgba[RCOMP] = rgba[BCOMP] = rgba[GCOMP] = rgba[ACOMP] = 0;
+ } else {
+ GLubyte r, g, b;
+ if (t == 0) {
+ b = UP5(col[0][BCOMP]);
+ g = UP5(col[0][GCOMP]);
+ r = UP5(col[0][RCOMP]);
+ } else if (t == 2) {
+ b = UP5(col[1][BCOMP]);
+ g = UP6(col[1][GCOMP], glsb);
+ r = UP5(col[1][RCOMP]);
+ } else {
+ b = (UP5(col[0][BCOMP]) + UP5(col[1][BCOMP])) / 2;
+ g = (UP5(col[0][GCOMP]) + UP6(col[1][GCOMP], glsb)) / 2;
+ r = (UP5(col[0][RCOMP]) + UP5(col[1][RCOMP])) / 2;
+ }
+ rgba[RCOMP] = UBYTE_TO_CHAN(r);
+ rgba[GCOMP] = UBYTE_TO_CHAN(g);
+ rgba[BCOMP] = UBYTE_TO_CHAN(b);
+ rgba[ACOMP] = CHAN_MAX;
+ }
+ } else {
+ /* alpha[0] == 0 */
+ GLubyte r, g, b;
+ if (t == 0) {
+ b = UP5(col[0][BCOMP]);
+ g = UP6(col[0][GCOMP], glsb ^ selb);
+ r = UP5(col[0][RCOMP]);
+ } else if (t == 3) {
+ b = UP5(col[1][BCOMP]);
+ g = UP6(col[1][GCOMP], glsb);
+ r = UP5(col[1][RCOMP]);
+ } else {
+ b = LERP(3, t, UP5(col[0][BCOMP]), UP5(col[1][BCOMP]));
+ g = LERP(3, t, UP6(col[0][GCOMP], glsb ^ selb),
+ UP6(col[1][GCOMP], glsb));
+ r = LERP(3, t, UP5(col[0][RCOMP]), UP5(col[1][RCOMP]));
+ }
+ rgba[RCOMP] = UBYTE_TO_CHAN(r);
+ rgba[GCOMP] = UBYTE_TO_CHAN(g);
+ rgba[BCOMP] = UBYTE_TO_CHAN(b);
+ rgba[ACOMP] = CHAN_MAX;
+ }
+}
+
+
+static void
+fxt1_decode_1ALPHA (const GLubyte *code, GLint t, GLchan *rgba)
+{
+ const GLuint *cc;
+ GLubyte r, g, b, a;
+
+ cc = (const GLuint *)code;
+ if (CC_SEL(cc, 124) & 1) {
+ /* lerp == 1 */
+ GLuint col0[4];
+
+ if (t & 16) {
+ t &= 15;
+ t = (cc[1] >> (t * 2)) & 3;
+ /* col 2 */
+ col0[BCOMP] = (*(const GLuint *)(code + 11)) >> 6;
+ col0[GCOMP] = CC_SEL(cc, 99);
+ col0[RCOMP] = CC_SEL(cc, 104);
+ col0[ACOMP] = CC_SEL(cc, 119);
+ } else {
+ t = (cc[0] >> (t * 2)) & 3;
+ /* col 0 */
+ col0[BCOMP] = CC_SEL(cc, 64);
+ col0[GCOMP] = CC_SEL(cc, 69);
+ col0[RCOMP] = CC_SEL(cc, 74);
+ col0[ACOMP] = CC_SEL(cc, 109);
+ }
+
+ if (t == 0) {
+ b = UP5(col0[BCOMP]);
+ g = UP5(col0[GCOMP]);
+ r = UP5(col0[RCOMP]);
+ a = UP5(col0[ACOMP]);
+ } else if (t == 3) {
+ b = UP5(CC_SEL(cc, 79));
+ g = UP5(CC_SEL(cc, 84));
+ r = UP5(CC_SEL(cc, 89));
+ a = UP5(CC_SEL(cc, 114));
+ } else {
+ b = LERP(3, t, UP5(col0[BCOMP]), UP5(CC_SEL(cc, 79)));
+ g = LERP(3, t, UP5(col0[GCOMP]), UP5(CC_SEL(cc, 84)));
+ r = LERP(3, t, UP5(col0[RCOMP]), UP5(CC_SEL(cc, 89)));
+ a = LERP(3, t, UP5(col0[ACOMP]), UP5(CC_SEL(cc, 114)));
+ }
+ } else {
+ /* lerp == 0 */
+
+ if (t & 16) {
+ cc++;
+ t &= 15;
+ }
+ t = (cc[0] >> (t * 2)) & 3;
+
+ if (t == 3) {
+ /* zero */
+ r = g = b = a = 0;
+ } else {
+ GLuint kk;
+ cc = (const GLuint *)code;
+ a = UP5(cc[3] >> (t * 5 + 13));
+ t *= 15;
+ cc = (const GLuint *)(code + 8 + t / 8);
+ kk = cc[0] >> (t & 7);
+ b = UP5(kk);
+ g = UP5(kk >> 5);
+ r = UP5(kk >> 10);
+ }
+ }
+ rgba[RCOMP] = UBYTE_TO_CHAN(r);
+ rgba[GCOMP] = UBYTE_TO_CHAN(g);
+ rgba[BCOMP] = UBYTE_TO_CHAN(b);
+ rgba[ACOMP] = UBYTE_TO_CHAN(a);
+}
+
+
+void
+fxt1_decode_1 (const void *texture, GLint stride, /* in pixels */
+ GLint i, GLint j, GLchan *rgba)
+{
+ static void (*decode_1[]) (const GLubyte *, GLint, GLchan *) = {
+ fxt1_decode_1HI, /* cc-high = "00?" */
+ fxt1_decode_1HI, /* cc-high = "00?" */
+ fxt1_decode_1CHROMA, /* cc-chroma = "010" */
+ fxt1_decode_1ALPHA, /* alpha = "011" */
+ fxt1_decode_1MIXED, /* mixed = "1??" */
+ fxt1_decode_1MIXED, /* mixed = "1??" */
+ fxt1_decode_1MIXED, /* mixed = "1??" */
+ fxt1_decode_1MIXED /* mixed = "1??" */
+ };
+
+ const GLubyte *code = (const GLubyte *)texture +
+ ((j / 4) * (stride / 8) + (i / 8)) * 16;
+ GLint mode = CC_SEL(code, 125);
+ GLint t = i & 7;
+
+ if (t & 4) {
+ t += 12;
+ }
+ t += (j & 3) * 4;
+
+ decode_1[mode](code, t, rgba);
+}
diff --git a/src/mesa/main/texcompress_s3tc.c b/src/mesa/main/texcompress_s3tc.c
new file mode 100644
index 00000000000..881da83b0f5
--- /dev/null
+++ b/src/mesa/main/texcompress_s3tc.c
@@ -0,0 +1,563 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/**
+ * \file texcompress_s3tc.c
+ * GL_EXT_texture_compression_s3tc support.
+ */
+
+#ifndef USE_EXTERNAL_DXTN_LIB
+#define USE_EXTERNAL_DXTN_LIB 0
+#endif
+
+#include "glheader.h"
+#include "imports.h"
+#include "colormac.h"
+#include "context.h"
+#include "convolve.h"
+#include "image.h"
+#include "texcompress.h"
+#include "texformat.h"
+#include "texstore.h"
+
+#if USE_EXTERNAL_DXTN_LIB
+#ifdef __MINGW32__
+/* no dlopen */
+#define DXTN_EXT "dxtn.dll"
+#define DXTN_PREFIX ""
+#define dlopen(name, mode) LoadLibrary(name)
+#define dlsym(hndl, proc) GetProcAddress(hndl, proc)
+#define dlclose(hndl) FreeLibrary(hndl)
+#elif defined(__DJGPP__)
+/* has dlopen, but doesn't like the names */
+#include <dlfcn.h>
+#define DXTN_EXT "dxtn.dxe"
+#define DXTN_PREFIX "_"
+#else
+/* happiness */
+#include <dlfcn.h>
+#define DXTN_EXT "libtxc_dxtn.so"
+#define DXTN_PREFIX ""
+#endif
+#endif /* USE_EXTERNAL_DXTN_LIB */
+
+typedef void (*dxtFetchTexelFuncExt)( GLint srcRowstride, GLubyte *pixdata, GLint col, GLint row, GLvoid *texelOut );
+dxtFetchTexelFuncExt fetch_ext_rgb_dxt1 = NULL;
+dxtFetchTexelFuncExt fetch_ext_rgba_dxt1 = NULL;
+dxtFetchTexelFuncExt fetch_ext_rgba_dxt3 = NULL;
+dxtFetchTexelFuncExt fetch_ext_rgba_dxt5 = NULL;
+
+typedef void (*dxtCompressTexFuncExt)(GLint srccomps, GLint width,
+ GLint height, const GLchan *srcPixData,
+ GLenum destformat, GLubyte *dest,
+ GLint dstRowStride);
+static dxtCompressTexFuncExt ext_tx_compress_dxtn = NULL;
+
+static void *dxtlibhandle = NULL;
+
+
+void
+_mesa_init_texture_s3tc( GLcontext *ctx )
+{
+ /* called during context initialization */
+ ctx->Mesa_DXTn = GL_FALSE;
+#if USE_EXTERNAL_DXTN_LIB
+ if (!dxtlibhandle) {
+ dxtlibhandle = dlopen (DXTN_EXT, RTLD_LAZY | RTLD_GLOBAL);
+ if (!dxtlibhandle) {
+ _mesa_warning(ctx, "couldn't open " DXTN_EXT ", software DXTn "
+ "compression/decompression unavailable\n");
+ }
+ else {
+ /* the fetch functions are not per context! Might be problematic... */
+ fetch_ext_rgb_dxt1 = (dxtFetchTexelFuncExt)dlsym(dxtlibhandle, DXTN_PREFIX "fetch_2d_texel_rgb_dxt1");
+ if (fetch_ext_rgb_dxt1 != NULL) {
+ fetch_ext_rgba_dxt1 = (dxtFetchTexelFuncExt)dlsym(dxtlibhandle, DXTN_PREFIX "fetch_2d_texel_rgba_dxt1");
+ }
+ if (fetch_ext_rgba_dxt1 != NULL) {
+ fetch_ext_rgba_dxt3 = (dxtFetchTexelFuncExt)dlsym(dxtlibhandle, DXTN_PREFIX "fetch_2d_texel_rgba_dxt3");
+ }
+ if (fetch_ext_rgba_dxt3 != NULL) {
+ fetch_ext_rgba_dxt5 = (dxtFetchTexelFuncExt)dlsym(dxtlibhandle, DXTN_PREFIX "fetch_2d_texel_rgba_dxt5");
+ }
+ if (fetch_ext_rgba_dxt5 != NULL) {
+ ext_tx_compress_dxtn = (dxtCompressTexFuncExt)dlsym(dxtlibhandle, DXTN_PREFIX "tx_compress_dxtn");
+ }
+
+ if (ext_tx_compress_dxtn == NULL) {
+ _mesa_warning(ctx, "couldn't reference all symbols in "
+ DXTN_EXT ", software DXTn compression/decompression "
+ "unavailable\n");
+ fetch_ext_rgb_dxt1 = NULL;
+ fetch_ext_rgba_dxt1 = NULL;
+ fetch_ext_rgba_dxt3 = NULL;
+ fetch_ext_rgba_dxt5 = NULL;
+ ext_tx_compress_dxtn = NULL;
+ dlclose(dxtlibhandle);
+ dxtlibhandle = NULL;
+ }
+ }
+ }
+ if (dxtlibhandle) {
+ ctx->Mesa_DXTn = GL_TRUE;
+ _mesa_warning(ctx, "software DXTn compression/decompression available\n");
+ }
+#else
+ (void) ctx;
+#endif
+}
+
+/**
+ * Called via TexFormat->StoreImage to store an RGB_DXT1 texture.
+ */
+static GLboolean
+texstore_rgb_dxt1(STORE_PARAMS)
+{
+ const GLchan *pixels;
+ GLint srcRowStride;
+ GLubyte *dst;
+ const GLint texWidth = dstRowStride * 4 / 8; /* a bit of a hack */
+ const GLchan *tempImage = NULL;
+
+ ASSERT(dstFormat == &_mesa_texformat_rgb_dxt1);
+ ASSERT(dstXoffset % 4 == 0);
+ ASSERT(dstYoffset % 4 == 0);
+ ASSERT(dstZoffset % 4 == 0);
+ (void) dstZoffset; (void) dstImageStride;
+
+ if (srcFormat != GL_RGB ||
+ srcType != CHAN_TYPE ||
+ ctx->_ImageTransferState ||
+ srcPacking->SwapBytes) {
+ /* convert image to RGB/GLchan */
+ tempImage = _mesa_make_temp_chan_image(ctx, dims,
+ baseInternalFormat,
+ dstFormat->BaseFormat,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr,
+ srcPacking);
+ if (!tempImage)
+ return GL_FALSE; /* out of memory */
+ _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
+ pixels = tempImage;
+ srcRowStride = 3 * srcWidth;
+ srcFormat = GL_RGB;
+ }
+ else {
+ pixels = (const GLchan *) srcAddr;
+ srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat,
+ srcType) / sizeof(GLchan);
+ }
+
+ dst = _mesa_compressed_image_address(dstXoffset, dstYoffset, 0,
+ GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
+ texWidth, (GLubyte *) dstAddr);
+
+ if (ext_tx_compress_dxtn) {
+ (*ext_tx_compress_dxtn)(3, srcWidth, srcHeight, pixels, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, dst, dstRowStride);
+ }
+ else {
+ _mesa_problem(ctx, "external dxt library not available");
+ }
+
+ if (tempImage)
+ _mesa_free((void *) tempImage);
+
+ return GL_TRUE;
+}
+
+
+/**
+ * Called via TexFormat->StoreImage to store an RGBA_DXT1 texture.
+ */
+static GLboolean
+texstore_rgba_dxt1(STORE_PARAMS)
+{
+ const GLchan *pixels;
+ GLint srcRowStride;
+ GLubyte *dst;
+ const GLint texWidth = dstRowStride * 4 / 8; /* a bit of a hack */
+ const GLchan *tempImage = NULL;
+
+ ASSERT(dstFormat == &_mesa_texformat_rgba_dxt1);
+ ASSERT(dstXoffset % 4 == 0);
+ ASSERT(dstYoffset % 4 == 0);
+ ASSERT(dstZoffset % 4 == 0);
+ (void) dstZoffset; (void) dstImageStride;
+
+ if (srcFormat != GL_RGBA ||
+ srcType != CHAN_TYPE ||
+ ctx->_ImageTransferState ||
+ srcPacking->SwapBytes) {
+ /* convert image to RGBA/GLchan */
+ tempImage = _mesa_make_temp_chan_image(ctx, dims,
+ baseInternalFormat,
+ dstFormat->BaseFormat,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr,
+ srcPacking);
+ if (!tempImage)
+ return GL_FALSE; /* out of memory */
+ _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
+ pixels = tempImage;
+ srcRowStride = 4 * srcWidth;
+ srcFormat = GL_RGBA;
+ }
+ else {
+ pixels = (const GLchan *) srcAddr;
+ srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat,
+ srcType) / sizeof(GLchan);
+ }
+
+ dst = _mesa_compressed_image_address(dstXoffset, dstYoffset, 0,
+ GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
+ texWidth, (GLubyte *) dstAddr);
+ if (ext_tx_compress_dxtn) {
+ (*ext_tx_compress_dxtn)(4, srcWidth, srcHeight, pixels, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, dst, dstRowStride);
+ }
+ else {
+ _mesa_problem(ctx, "external dxt library not available");
+ }
+
+ if (tempImage)
+ _mesa_free((void*) tempImage);
+
+ return GL_TRUE;
+}
+
+
+/**
+ * Called via TexFormat->StoreImage to store an RGBA_DXT3 texture.
+ */
+static GLboolean
+texstore_rgba_dxt3(STORE_PARAMS)
+{
+ const GLchan *pixels;
+ GLint srcRowStride;
+ GLubyte *dst;
+ const GLint texWidth = dstRowStride * 4 / 16; /* a bit of a hack */
+ const GLchan *tempImage = NULL;
+
+ ASSERT(dstFormat == &_mesa_texformat_rgba_dxt3);
+ ASSERT(dstXoffset % 4 == 0);
+ ASSERT(dstYoffset % 4 == 0);
+ ASSERT(dstZoffset % 4 == 0);
+ (void) dstZoffset; (void) dstImageStride;
+
+ if (srcFormat != GL_RGBA ||
+ srcType != CHAN_TYPE ||
+ ctx->_ImageTransferState ||
+ srcPacking->SwapBytes) {
+ /* convert image to RGBA/GLchan */
+ tempImage = _mesa_make_temp_chan_image(ctx, dims,
+ baseInternalFormat,
+ dstFormat->BaseFormat,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr,
+ srcPacking);
+ if (!tempImage)
+ return GL_FALSE; /* out of memory */
+ _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
+ pixels = tempImage;
+ srcRowStride = 4 * srcWidth;
+ }
+ else {
+ pixels = (const GLchan *) srcAddr;
+ srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat,
+ srcType) / sizeof(GLchan);
+ }
+
+ dst = _mesa_compressed_image_address(dstXoffset, dstYoffset, 0,
+ GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
+ texWidth, (GLubyte *) dstAddr);
+ if (ext_tx_compress_dxtn) {
+ (*ext_tx_compress_dxtn)(4, srcWidth, srcHeight, pixels, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, dst, dstRowStride);
+ }
+ else {
+ _mesa_problem(ctx, "external dxt library not available");
+ }
+
+ if (tempImage)
+ _mesa_free((void *) tempImage);
+
+ return GL_TRUE;
+}
+
+
+/**
+ * Called via TexFormat->StoreImage to store an RGBA_DXT5 texture.
+ */
+static GLboolean
+texstore_rgba_dxt5(STORE_PARAMS)
+{
+ const GLchan *pixels;
+ GLint srcRowStride;
+ GLubyte *dst;
+ const GLint texWidth = dstRowStride * 4 / 16; /* a bit of a hack */
+ const GLchan *tempImage = NULL;
+
+ ASSERT(dstFormat == &_mesa_texformat_rgba_dxt5);
+ ASSERT(dstXoffset % 4 == 0);
+ ASSERT(dstYoffset % 4 == 0);
+ ASSERT(dstZoffset % 4 == 0);
+ (void) dstZoffset; (void) dstImageStride;
+
+ if (srcFormat != GL_RGBA ||
+ srcType != CHAN_TYPE ||
+ ctx->_ImageTransferState ||
+ srcPacking->SwapBytes) {
+ /* convert image to RGBA/GLchan */
+ tempImage = _mesa_make_temp_chan_image(ctx, dims,
+ baseInternalFormat,
+ dstFormat->BaseFormat,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr,
+ srcPacking);
+ if (!tempImage)
+ return GL_FALSE; /* out of memory */
+ _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
+ pixels = tempImage;
+ srcRowStride = 4 * srcWidth;
+ }
+ else {
+ pixels = (const GLchan *) srcAddr;
+ srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat,
+ srcType) / sizeof(GLchan);
+ }
+
+ dst = _mesa_compressed_image_address(dstXoffset, dstYoffset, 0,
+ GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,
+ texWidth, (GLubyte *) dstAddr);
+ if (ext_tx_compress_dxtn) {
+ (*ext_tx_compress_dxtn)(4, srcWidth, srcHeight, pixels, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, dst, dstRowStride);
+ }
+ else {
+ _mesa_problem(ctx, "external dxt library not available");
+ }
+
+ if (tempImage)
+ _mesa_free((void *) tempImage);
+
+ return GL_TRUE;
+}
+
+
+static void
+fetch_texel_2d_rgb_dxt1( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLchan *texel )
+{
+ (void) k;
+ if (fetch_ext_rgb_dxt1) {
+ ASSERT (sizeof(GLchan) == sizeof(GLubyte));
+ (*fetch_ext_rgb_dxt1)((texImage)->RowStride, (GLubyte *)(texImage)->Data, i, j, texel);
+ }
+ else _mesa_debug(NULL, "attempted to decode s3tc texture without library available\n");
+}
+
+
+static void
+fetch_texel_2d_f_rgb_dxt1( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLfloat *texel )
+{
+ /* just sample as GLchan and convert to float here */
+ GLchan rgba[4];
+ fetch_texel_2d_rgb_dxt1(texImage, i, j, k, rgba);
+ texel[RCOMP] = CHAN_TO_FLOAT(rgba[RCOMP]);
+ texel[GCOMP] = CHAN_TO_FLOAT(rgba[GCOMP]);
+ texel[BCOMP] = CHAN_TO_FLOAT(rgba[BCOMP]);
+ texel[ACOMP] = CHAN_TO_FLOAT(rgba[ACOMP]);
+}
+
+
+static void
+fetch_texel_2d_rgba_dxt1( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLchan *texel )
+{
+ (void) k;
+ if (fetch_ext_rgba_dxt1) {
+ (*fetch_ext_rgba_dxt1)((texImage)->RowStride, (GLubyte *)(texImage)->Data, i, j, texel);
+ }
+ else _mesa_debug(NULL, "attempted to decode s3tc texture without library available\n");
+}
+
+
+static void
+fetch_texel_2d_f_rgba_dxt1( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLfloat *texel )
+{
+ /* just sample as GLchan and convert to float here */
+ GLchan rgba[4];
+ fetch_texel_2d_rgba_dxt1(texImage, i, j, k, rgba);
+ texel[RCOMP] = CHAN_TO_FLOAT(rgba[RCOMP]);
+ texel[GCOMP] = CHAN_TO_FLOAT(rgba[GCOMP]);
+ texel[BCOMP] = CHAN_TO_FLOAT(rgba[BCOMP]);
+ texel[ACOMP] = CHAN_TO_FLOAT(rgba[ACOMP]);
+}
+
+
+static void
+fetch_texel_2d_rgba_dxt3( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLchan *texel )
+{
+ (void) k;
+ if (fetch_ext_rgba_dxt3) {
+ ASSERT (sizeof(GLchan) == sizeof(GLubyte));
+ (*fetch_ext_rgba_dxt3)((texImage)->RowStride, (GLubyte *)(texImage)->Data, i, j, texel);
+ }
+ else _mesa_debug(NULL, "attempted to decode s3tc texture without library available\n");
+}
+
+
+static void
+fetch_texel_2d_f_rgba_dxt3( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLfloat *texel )
+{
+ /* just sample as GLchan and convert to float here */
+ GLchan rgba[4];
+ fetch_texel_2d_rgba_dxt3(texImage, i, j, k, rgba);
+ texel[RCOMP] = CHAN_TO_FLOAT(rgba[RCOMP]);
+ texel[GCOMP] = CHAN_TO_FLOAT(rgba[GCOMP]);
+ texel[BCOMP] = CHAN_TO_FLOAT(rgba[BCOMP]);
+ texel[ACOMP] = CHAN_TO_FLOAT(rgba[ACOMP]);
+}
+
+
+static void
+fetch_texel_2d_rgba_dxt5( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLchan *texel )
+{
+ (void) k;
+ if (fetch_ext_rgba_dxt5) {
+ (*fetch_ext_rgba_dxt5)((texImage)->RowStride, (GLubyte *)(texImage)->Data, i, j, texel);
+ }
+ else _mesa_debug(NULL, "attempted to decode s3tc texture without library available\n");
+}
+
+
+static void
+fetch_texel_2d_f_rgba_dxt5( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLfloat *texel )
+{
+ /* just sample as GLchan and convert to float here */
+ GLchan rgba[4];
+ fetch_texel_2d_rgba_dxt5(texImage, i, j, k, rgba);
+ texel[RCOMP] = CHAN_TO_FLOAT(rgba[RCOMP]);
+ texel[GCOMP] = CHAN_TO_FLOAT(rgba[GCOMP]);
+ texel[BCOMP] = CHAN_TO_FLOAT(rgba[BCOMP]);
+ texel[ACOMP] = CHAN_TO_FLOAT(rgba[ACOMP]);
+}
+
+
+const struct gl_texture_format _mesa_texformat_rgb_dxt1 = {
+ MESA_FORMAT_RGB_DXT1, /* MesaFormat */
+ GL_RGB, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ 4, /*approx*/ /* RedBits */
+ 4, /*approx*/ /* GreenBits */
+ 4, /*approx*/ /* BlueBits */
+ 0, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 0, /* TexelBytes */
+ texstore_rgb_dxt1, /* StoreTexImageFunc */
+ NULL, /*impossible*/ /* FetchTexel1D */
+ fetch_texel_2d_rgb_dxt1, /* FetchTexel2D */
+ NULL, /*impossible*/ /* FetchTexel3D */
+ NULL, /*impossible*/ /* FetchTexel1Df */
+ fetch_texel_2d_f_rgb_dxt1, /* FetchTexel2Df */
+ NULL, /*impossible*/ /* FetchTexel3Df */
+};
+
+const struct gl_texture_format _mesa_texformat_rgba_dxt1 = {
+ MESA_FORMAT_RGBA_DXT1, /* MesaFormat */
+ GL_RGBA, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ 4, /*approx*/ /* RedBits */
+ 4, /*approx*/ /* GreenBits */
+ 4, /*approx*/ /* BlueBits */
+ 1, /*approx*/ /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 0, /* TexelBytes */
+ texstore_rgba_dxt1, /* StoreTexImageFunc */
+ NULL, /*impossible*/ /* FetchTexel1D */
+ fetch_texel_2d_rgba_dxt1, /* FetchTexel2D */
+ NULL, /*impossible*/ /* FetchTexel3D */
+ NULL, /*impossible*/ /* FetchTexel1Df */
+ fetch_texel_2d_f_rgba_dxt1, /* FetchTexel2Df */
+ NULL, /*impossible*/ /* FetchTexel3Df */
+};
+
+const struct gl_texture_format _mesa_texformat_rgba_dxt3 = {
+ MESA_FORMAT_RGBA_DXT3, /* MesaFormat */
+ GL_RGBA, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ 4, /*approx*/ /* RedBits */
+ 4, /*approx*/ /* GreenBits */
+ 4, /*approx*/ /* BlueBits */
+ 4, /*approx*/ /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 0, /* TexelBytes */
+ texstore_rgba_dxt3, /* StoreTexImageFunc */
+ NULL, /*impossible*/ /* FetchTexel1D */
+ fetch_texel_2d_rgba_dxt3, /* FetchTexel2D */
+ NULL, /*impossible*/ /* FetchTexel3D */
+ NULL, /*impossible*/ /* FetchTexel1Df */
+ fetch_texel_2d_f_rgba_dxt3, /* FetchTexel2Df */
+ NULL, /*impossible*/ /* FetchTexel3Df */
+};
+
+const struct gl_texture_format _mesa_texformat_rgba_dxt5 = {
+ MESA_FORMAT_RGBA_DXT5, /* MesaFormat */
+ GL_RGBA, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ 4,/*approx*/ /* RedBits */
+ 4,/*approx*/ /* GreenBits */
+ 4,/*approx*/ /* BlueBits */
+ 4,/*approx*/ /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 0, /* TexelBytes */
+ texstore_rgba_dxt5, /* StoreTexImageFunc */
+ NULL, /*impossible*/ /* FetchTexel1D */
+ fetch_texel_2d_rgba_dxt5, /* FetchTexel2D */
+ NULL, /*impossible*/ /* FetchTexel3D */
+ NULL, /*impossible*/ /* FetchTexel1Df */
+ fetch_texel_2d_f_rgba_dxt5, /* FetchTexel2Df */
+ NULL, /*impossible*/ /* FetchTexel3Df */
+};
diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c
new file mode 100644
index 00000000000..02ff833dab4
--- /dev/null
+++ b/src/mesa/main/texenvprogram.c
@@ -0,0 +1,1197 @@
+/**************************************************************************
+ *
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include "glheader.h"
+#include "macros.h"
+#include "enums.h"
+#include "texenvprogram.h"
+
+#include "shader/program.h"
+#include "shader/program_instruction.h"
+
+#define MAX_INSTRUCTIONS 100
+
+#define DISASSEM (MESA_VERBOSE & VERBOSE_DISASSEM)
+
+struct mode_opt {
+ GLuint Source:4;
+ GLuint Operand:3;
+};
+
+struct state_key {
+ GLbitfield enabled_units;
+ GLuint separate_specular:1;
+ GLuint fog_enabled:1;
+ GLuint fog_mode:2;
+
+ struct {
+ GLuint enabled:1;
+ GLuint source_index:3; /* one of TEXTURE_1D/2D/3D/CUBE/RECT_INDEX */
+ GLuint ScaleShiftRGB:2;
+ GLuint ScaleShiftA:2;
+
+ GLuint NumArgsRGB:2;
+ GLuint ModeRGB:4;
+ struct mode_opt OptRGB[3];
+
+ GLuint NumArgsA:2;
+ GLuint ModeA:4;
+ struct mode_opt OptA[3];
+ } unit[8];
+};
+
+#define FOG_LINEAR 0
+#define FOG_EXP 1
+#define FOG_EXP2 2
+#define FOG_UNKNOWN 3
+
+static GLuint translate_fog_mode( GLenum mode )
+{
+ switch (mode) {
+ case GL_LINEAR: return FOG_LINEAR;
+ case GL_EXP: return FOG_EXP;
+ case GL_EXP2: return FOG_EXP2;
+ default: return FOG_UNKNOWN;
+ }
+}
+
+#define OPR_SRC_COLOR 0
+#define OPR_ONE_MINUS_SRC_COLOR 1
+#define OPR_SRC_ALPHA 2
+#define OPR_ONE_MINUS_SRC_ALPHA 3
+#define OPR_ZERO 4
+#define OPR_ONE 5
+#define OPR_UNKNOWN 7
+
+static GLuint translate_operand( GLenum operand )
+{
+ switch (operand) {
+ case GL_SRC_COLOR: return OPR_SRC_COLOR;
+ case GL_ONE_MINUS_SRC_COLOR: return OPR_ONE_MINUS_SRC_COLOR;
+ case GL_SRC_ALPHA: return OPR_SRC_ALPHA;
+ case GL_ONE_MINUS_SRC_ALPHA: return OPR_ONE_MINUS_SRC_ALPHA;
+ case GL_ZERO: return OPR_ZERO;
+ case GL_ONE: return OPR_ONE;
+ default: return OPR_UNKNOWN;
+ }
+}
+
+#define SRC_TEXTURE 0
+#define SRC_TEXTURE0 1
+#define SRC_TEXTURE1 2
+#define SRC_TEXTURE2 3
+#define SRC_TEXTURE3 4
+#define SRC_TEXTURE4 5
+#define SRC_TEXTURE5 6
+#define SRC_TEXTURE6 7
+#define SRC_TEXTURE7 8
+#define SRC_CONSTANT 9
+#define SRC_PRIMARY_COLOR 10
+#define SRC_PREVIOUS 11
+#define SRC_UNKNOWN 15
+
+static GLuint translate_source( GLenum src )
+{
+ switch (src) {
+ case GL_TEXTURE: return SRC_TEXTURE;
+ case GL_TEXTURE0:
+ case GL_TEXTURE1:
+ case GL_TEXTURE2:
+ case GL_TEXTURE3:
+ case GL_TEXTURE4:
+ case GL_TEXTURE5:
+ case GL_TEXTURE6:
+ case GL_TEXTURE7: return SRC_TEXTURE0 + (src - GL_TEXTURE0);
+ case GL_CONSTANT: return SRC_CONSTANT;
+ case GL_PRIMARY_COLOR: return SRC_PRIMARY_COLOR;
+ case GL_PREVIOUS: return SRC_PREVIOUS;
+ default: return SRC_UNKNOWN;
+ }
+}
+
+#define MODE_REPLACE 0
+#define MODE_MODULATE 1
+#define MODE_ADD 2
+#define MODE_ADD_SIGNED 3
+#define MODE_INTERPOLATE 4
+#define MODE_SUBTRACT 5
+#define MODE_DOT3_RGB 6
+#define MODE_DOT3_RGB_EXT 7
+#define MODE_DOT3_RGBA 8
+#define MODE_DOT3_RGBA_EXT 9
+#define MODE_MODULATE_ADD_ATI 10
+#define MODE_MODULATE_SIGNED_ADD_ATI 11
+#define MODE_MODULATE_SUBTRACT_ATI 12
+#define MODE_UNKNOWN 15
+
+static GLuint translate_mode( GLenum mode )
+{
+ switch (mode) {
+ case GL_REPLACE: return MODE_REPLACE;
+ case GL_MODULATE: return MODE_MODULATE;
+ case GL_ADD: return MODE_ADD;
+ case GL_ADD_SIGNED: return MODE_ADD_SIGNED;
+ case GL_INTERPOLATE: return MODE_INTERPOLATE;
+ case GL_SUBTRACT: return MODE_SUBTRACT;
+ case GL_DOT3_RGB: return MODE_DOT3_RGB;
+ case GL_DOT3_RGB_EXT: return MODE_DOT3_RGB_EXT;
+ case GL_DOT3_RGBA: return MODE_DOT3_RGBA;
+ case GL_DOT3_RGBA_EXT: return MODE_DOT3_RGBA_EXT;
+ case GL_MODULATE_ADD_ATI: return MODE_MODULATE_ADD_ATI;
+ case GL_MODULATE_SIGNED_ADD_ATI: return MODE_MODULATE_SIGNED_ADD_ATI;
+ case GL_MODULATE_SUBTRACT_ATI: return MODE_MODULATE_SUBTRACT_ATI;
+ default: return MODE_UNKNOWN;
+ }
+}
+
+#define TEXTURE_UNKNOWN_INDEX 7
+static GLuint translate_tex_src_bit( GLbitfield bit )
+{
+ switch (bit) {
+ case TEXTURE_1D_BIT: return TEXTURE_1D_INDEX;
+ case TEXTURE_2D_BIT: return TEXTURE_2D_INDEX;
+ case TEXTURE_RECT_BIT: return TEXTURE_RECT_INDEX;
+ case TEXTURE_3D_BIT: return TEXTURE_3D_INDEX;
+ case TEXTURE_CUBE_BIT: return TEXTURE_CUBE_INDEX;
+ default: return TEXTURE_UNKNOWN_INDEX;
+ }
+}
+
+/**
+ * Examine current texture environment state and generate a unique
+ * key to identify it.
+ */
+static struct state_key *
+make_state_key(GLcontext *ctx)
+{
+ struct state_key *key = CALLOC_STRUCT(state_key);
+ GLuint i, j;
+
+ for (i=0;i<MAX_TEXTURE_UNITS;i++) {
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i];
+
+ if (!texUnit->_ReallyEnabled)
+ continue;
+
+ key->unit[i].enabled = 1;
+ key->enabled_units |= (1<<i);
+
+ key->unit[i].source_index =
+ translate_tex_src_bit(texUnit->_ReallyEnabled);
+
+ key->unit[i].NumArgsRGB = texUnit->_CurrentCombine->_NumArgsRGB;
+ key->unit[i].NumArgsA = texUnit->_CurrentCombine->_NumArgsA;
+
+ key->unit[i].ModeRGB =
+ translate_mode(texUnit->_CurrentCombine->ModeRGB);
+ key->unit[i].ModeA =
+ translate_mode(texUnit->_CurrentCombine->ModeA);
+
+ key->unit[i].ScaleShiftRGB = texUnit->_CurrentCombine->ScaleShiftRGB;
+ key->unit[i].ScaleShiftA = texUnit->_CurrentCombine->ScaleShiftRGB;
+
+ for (j=0;j<3;j++) {
+ key->unit[i].OptRGB[j].Operand =
+ translate_operand(texUnit->_CurrentCombine->OperandRGB[j]);
+ key->unit[i].OptA[j].Operand =
+ translate_operand(texUnit->_CurrentCombine->OperandA[j]);
+ key->unit[i].OptRGB[j].Source =
+ translate_source(texUnit->_CurrentCombine->SourceRGB[j]);
+ key->unit[i].OptA[j].Source =
+ translate_source(texUnit->_CurrentCombine->SourceA[j]);
+ }
+ }
+
+ if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
+ key->separate_specular = 1;
+
+ if (ctx->Fog.Enabled) {
+ key->fog_enabled = 1;
+ key->fog_mode = translate_fog_mode(ctx->Fog.Mode);
+ }
+
+ return key;
+}
+
+/* Use uregs to represent registers internally, translate to Mesa's
+ * expected formats on emit.
+ *
+ * NOTE: These are passed by value extensively in this file rather
+ * than as usual by pointer reference. If this disturbs you, try
+ * remembering they are just 32bits in size.
+ *
+ * GCC is smart enough to deal with these dword-sized structures in
+ * much the same way as if I had defined them as dwords and was using
+ * macros to access and set the fields. This is much nicer and easier
+ * to evolve.
+ */
+struct ureg {
+ GLuint file:4;
+ GLuint idx:8;
+ GLuint negatebase:1;
+ GLuint abs:1;
+ GLuint negateabs:1;
+ GLuint swz:12;
+ GLuint pad:5;
+};
+
+const static struct ureg undef = {
+ ~0,
+ ~0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+
+/* State used to build the fragment program:
+ */
+struct texenv_fragment_program {
+ struct fragment_program *program;
+ GLcontext *ctx;
+ struct state_key *state;
+
+ GLbitfield alu_temps; /* Track texture indirections, see spec. */
+ GLbitfield temps_output; /* Track texture indirections, see spec. */
+ GLbitfield temp_in_use; /* Tracks temporary regs which are in use. */
+ GLboolean error;
+
+ struct ureg src_texture[MAX_TEXTURE_UNITS];
+ /* Reg containing each texture unit's sampled texture color,
+ * else undef.
+ */
+
+ struct ureg src_previous; /* Reg containing color from previous
+ * stage. May need to be decl'd.
+ */
+
+ GLuint last_tex_stage; /* Number of last enabled texture unit */
+
+ struct ureg half;
+ struct ureg one;
+ struct ureg zero;
+};
+
+
+
+static struct ureg make_ureg(GLuint file, GLuint idx)
+{
+ struct ureg reg;
+ reg.file = file;
+ reg.idx = idx;
+ reg.negatebase = 0;
+ reg.abs = 0;
+ reg.negateabs = 0;
+ reg.swz = SWIZZLE_NOOP;
+ reg.pad = 0;
+ return reg;
+}
+
+static struct ureg swizzle( struct ureg reg, int x, int y, int z, int w )
+{
+ reg.swz = MAKE_SWIZZLE4(GET_SWZ(reg.swz, x),
+ GET_SWZ(reg.swz, y),
+ GET_SWZ(reg.swz, z),
+ GET_SWZ(reg.swz, w));
+
+ return reg;
+}
+
+static struct ureg swizzle1( struct ureg reg, int x )
+{
+ return swizzle(reg, x, x, x, x);
+}
+
+static struct ureg negate( struct ureg reg )
+{
+ reg.negatebase ^= 1;
+ return reg;
+}
+
+static GLboolean is_undef( struct ureg reg )
+{
+ return reg.file == 0xf;
+}
+
+
+static struct ureg get_temp( struct texenv_fragment_program *p )
+{
+ int bit;
+
+ /* First try and reuse temps which have been used already:
+ */
+ bit = _mesa_ffs( ~p->temp_in_use & p->alu_temps );
+
+ /* Then any unused temporary:
+ */
+ if (!bit)
+ bit = _mesa_ffs( ~p->temp_in_use );
+
+ if (!bit) {
+ _mesa_problem(NULL, "%s: out of temporaries\n", __FILE__);
+ _mesa_exit(1);
+ }
+
+ if (bit > p->program->Base.NumTemporaries)
+ p->program->Base.NumTemporaries = bit;
+
+ p->temp_in_use |= 1<<(bit-1);
+ return make_ureg(PROGRAM_TEMPORARY, (bit-1));
+}
+
+static struct ureg get_tex_temp( struct texenv_fragment_program *p )
+{
+ int bit;
+
+ /* First try to find availble temp not previously used (to avoid
+ * starting a new texture indirection). According to the spec, the
+ * ~p->temps_output isn't necessary, but will keep it there for
+ * now:
+ */
+ bit = _mesa_ffs( ~p->temp_in_use & ~p->alu_temps & ~p->temps_output );
+
+ /* Then any unused temporary:
+ */
+ if (!bit)
+ bit = _mesa_ffs( ~p->temp_in_use );
+
+ if (!bit) {
+ _mesa_problem(NULL, "%s: out of temporaries\n", __FILE__);
+ _mesa_exit(1);
+ }
+
+ if (bit > p->program->Base.NumTemporaries)
+ p->program->Base.NumTemporaries = bit;
+
+ p->temp_in_use |= 1<<(bit-1);
+ return make_ureg(PROGRAM_TEMPORARY, (bit-1));
+}
+
+
+static void release_temps( struct texenv_fragment_program *p )
+{
+ GLuint max_temp = p->ctx->Const.FragmentProgram.MaxTemps;
+
+ /* KW: To support tex_env_crossbar, don't release the registers in
+ * temps_output.
+ */
+ if (max_temp >= sizeof(int) * 8)
+ p->temp_in_use = p->temps_output;
+ else
+ p->temp_in_use = ~((1<<max_temp)-1) | p->temps_output;
+}
+
+
+static struct ureg register_param6( struct texenv_fragment_program *p,
+ GLint s0,
+ GLint s1,
+ GLint s2,
+ GLint s3,
+ GLint s4,
+ GLint s5)
+{
+ GLint tokens[6];
+ GLuint idx;
+ tokens[0] = s0;
+ tokens[1] = s1;
+ tokens[2] = s2;
+ tokens[3] = s3;
+ tokens[4] = s4;
+ tokens[5] = s5;
+ idx = _mesa_add_state_reference( p->program->Base.Parameters, tokens );
+ return make_ureg(PROGRAM_STATE_VAR, idx);
+}
+
+
+#define register_param1(p,s0) register_param6(p,s0,0,0,0,0,0)
+#define register_param2(p,s0,s1) register_param6(p,s0,s1,0,0,0,0)
+#define register_param3(p,s0,s1,s2) register_param6(p,s0,s1,s2,0,0,0)
+#define register_param4(p,s0,s1,s2,s3) register_param6(p,s0,s1,s2,s3,0,0)
+
+
+static struct ureg register_input( struct texenv_fragment_program *p, GLuint input )
+{
+ p->program->Base.InputsRead |= (1 << input);
+ return make_ureg(PROGRAM_INPUT, input);
+}
+
+
+static void emit_arg( struct prog_src_register *reg,
+ struct ureg ureg )
+{
+ reg->File = ureg.file;
+ reg->Index = ureg.idx;
+ reg->Swizzle = ureg.swz;
+ reg->NegateBase = ureg.negatebase ? 0xf : 0x0;
+ reg->Abs = ureg.abs;
+ reg->NegateAbs = ureg.negateabs;
+}
+
+static void emit_dst( struct prog_dst_register *dst,
+ struct ureg ureg, GLuint mask )
+{
+ dst->File = ureg.file;
+ dst->Index = ureg.idx;
+ dst->WriteMask = mask;
+ dst->CondMask = 0;
+ dst->CondSwizzle = 0;
+}
+
+static struct prog_instruction *
+emit_op(struct texenv_fragment_program *p,
+ enum prog_opcode op,
+ struct ureg dest,
+ GLuint mask,
+ GLboolean saturate,
+ struct ureg src0,
+ struct ureg src1,
+ struct ureg src2 )
+{
+ GLuint nr = p->program->Base.NumInstructions++;
+ struct prog_instruction *inst = &p->program->Base.Instructions[nr];
+
+ _mesa_init_instruction(inst);
+ inst->Opcode = op;
+
+ emit_arg( &inst->SrcReg[0], src0 );
+ emit_arg( &inst->SrcReg[1], src1 );
+ emit_arg( &inst->SrcReg[2], src2 );
+
+ inst->SaturateMode = saturate ? SATURATE_ZERO_ONE : SATURATE_OFF;
+
+ emit_dst( &inst->DstReg, dest, mask );
+
+ /* Accounting for indirection tracking:
+ */
+ if (dest.file == PROGRAM_TEMPORARY)
+ p->temps_output |= 1 << dest.idx;
+
+ return inst;
+}
+
+
+static struct ureg emit_arith( struct texenv_fragment_program *p,
+ enum prog_opcode op,
+ struct ureg dest,
+ GLuint mask,
+ GLboolean saturate,
+ struct ureg src0,
+ struct ureg src1,
+ struct ureg src2 )
+{
+ emit_op(p, op, dest, mask, saturate, src0, src1, src2);
+
+ /* Accounting for indirection tracking:
+ */
+ if (src0.file == PROGRAM_TEMPORARY)
+ p->alu_temps |= 1 << src0.idx;
+
+ if (!is_undef(src1) && src1.file == PROGRAM_TEMPORARY)
+ p->alu_temps |= 1 << src1.idx;
+
+ if (!is_undef(src2) && src2.file == PROGRAM_TEMPORARY)
+ p->alu_temps |= 1 << src2.idx;
+
+ if (dest.file == PROGRAM_TEMPORARY)
+ p->alu_temps |= 1 << dest.idx;
+
+ p->program->NumAluInstructions++;
+ return dest;
+}
+
+static struct ureg emit_texld( struct texenv_fragment_program *p,
+ enum prog_opcode op,
+ struct ureg dest,
+ GLuint destmask,
+ GLuint tex_unit,
+ GLuint tex_idx,
+ struct ureg coord )
+{
+ struct prog_instruction *inst = emit_op( p, op,
+ dest, destmask,
+ GL_FALSE, /* don't saturate? */
+ coord, /* arg 0? */
+ undef,
+ undef);
+
+ inst->TexSrcTarget = tex_idx;
+ inst->TexSrcUnit = tex_unit;
+
+ p->program->NumTexInstructions++;
+
+ /* Is this a texture indirection?
+ */
+ if ((coord.file == PROGRAM_TEMPORARY &&
+ (p->temps_output & (1<<coord.idx))) ||
+ (dest.file == PROGRAM_TEMPORARY &&
+ (p->alu_temps & (1<<dest.idx)))) {
+ p->program->NumTexIndirections++;
+ p->temps_output = 1<<coord.idx;
+ p->alu_temps = 0;
+ assert(0); /* KW: texture env crossbar */
+ }
+
+ return dest;
+}
+
+
+static struct ureg register_const4f( struct texenv_fragment_program *p,
+ GLfloat s0,
+ GLfloat s1,
+ GLfloat s2,
+ GLfloat s3)
+{
+ GLfloat values[4];
+ GLuint idx;
+ values[0] = s0;
+ values[1] = s1;
+ values[2] = s2;
+ values[3] = s3;
+ idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values );
+ return make_ureg(PROGRAM_STATE_VAR, idx);
+}
+
+#define register_scalar_const(p, s0) register_const4f(p, s0, s0, s0, s0)
+#define register_const1f(p, s0) register_const4f(p, s0, 0, 0, 1)
+#define register_const2f(p, s0, s1) register_const4f(p, s0, s1, 0, 1)
+#define register_const3f(p, s0, s1, s2) register_const4f(p, s0, s1, s2, 1)
+
+
+static struct ureg get_one( struct texenv_fragment_program *p )
+{
+ if (is_undef(p->one))
+ p->one = register_scalar_const(p, 1.0);
+ return p->one;
+}
+
+static struct ureg get_half( struct texenv_fragment_program *p )
+{
+ if (is_undef(p->half))
+ p->half = register_scalar_const(p, 0.5);
+ return p->half;
+}
+
+static struct ureg get_zero( struct texenv_fragment_program *p )
+{
+ if (is_undef(p->zero))
+ p->zero = register_scalar_const(p, 0.0);
+ return p->zero;
+}
+
+
+static void program_error( struct texenv_fragment_program *p, const char *msg )
+{
+ _mesa_problem(NULL, msg);
+ p->error = 1;
+}
+
+static struct ureg get_source( struct texenv_fragment_program *p,
+ GLuint src, GLuint unit )
+{
+ switch (src) {
+ case SRC_TEXTURE:
+ assert(!is_undef(p->src_texture[unit]));
+ return p->src_texture[unit];
+
+ case SRC_TEXTURE0:
+ case SRC_TEXTURE1:
+ case SRC_TEXTURE2:
+ case SRC_TEXTURE3:
+ case SRC_TEXTURE4:
+ case SRC_TEXTURE5:
+ case SRC_TEXTURE6:
+ case SRC_TEXTURE7:
+ assert(!is_undef(p->src_texture[src - SRC_TEXTURE0]));
+ return p->src_texture[src - SRC_TEXTURE0];
+
+ case SRC_CONSTANT:
+ return register_param2(p, STATE_TEXENV_COLOR, unit);
+
+ case SRC_PRIMARY_COLOR:
+ return register_input(p, FRAG_ATTRIB_COL0);
+
+ case SRC_PREVIOUS:
+ default:
+ if (is_undef(p->src_previous))
+ return register_input(p, FRAG_ATTRIB_COL0);
+ else
+ return p->src_previous;
+ }
+}
+
+static struct ureg emit_combine_source( struct texenv_fragment_program *p,
+ GLuint mask,
+ GLuint unit,
+ GLuint source,
+ GLuint operand )
+{
+ struct ureg arg, src, one;
+
+ src = get_source(p, source, unit);
+
+ switch (operand) {
+ case OPR_ONE_MINUS_SRC_COLOR:
+ /* Get unused tmp,
+ * Emit tmp = 1.0 - arg.xyzw
+ */
+ arg = get_temp( p );
+ one = get_one( p );
+ return emit_arith( p, OPCODE_SUB, arg, mask, 0, one, src, undef);
+
+ case OPR_SRC_ALPHA:
+ if (mask == WRITEMASK_W)
+ return src;
+ else
+ return swizzle1( src, SWIZZLE_W );
+ case OPR_ONE_MINUS_SRC_ALPHA:
+ /* Get unused tmp,
+ * Emit tmp = 1.0 - arg.wwww
+ */
+ arg = get_temp(p);
+ one = get_one(p);
+ return emit_arith(p, OPCODE_SUB, arg, mask, 0,
+ one, swizzle1(src, SWIZZLE_W), undef);
+ case OPR_ZERO:
+ return get_zero(p);
+ case OPR_ONE:
+ return get_one(p);
+ case OPR_SRC_COLOR:
+ default:
+ return src;
+ }
+}
+
+static GLboolean args_match( struct state_key *key, GLuint unit )
+{
+ GLuint i, nr = key->unit[unit].NumArgsRGB;
+
+ for (i = 0 ; i < nr ; i++) {
+ if (key->unit[unit].OptA[i].Source != key->unit[unit].OptRGB[i].Source)
+ return GL_FALSE;
+
+ switch(key->unit[unit].OptA[i].Operand) {
+ case OPR_SRC_ALPHA:
+ switch(key->unit[unit].OptRGB[i].Operand) {
+ case OPR_SRC_COLOR:
+ case OPR_SRC_ALPHA:
+ break;
+ default:
+ return GL_FALSE;
+ }
+ break;
+ case OPR_ONE_MINUS_SRC_ALPHA:
+ switch(key->unit[unit].OptRGB[i].Operand) {
+ case OPR_ONE_MINUS_SRC_COLOR:
+ case OPR_ONE_MINUS_SRC_ALPHA:
+ break;
+ default:
+ return GL_FALSE;
+ }
+ break;
+ default:
+ return GL_FALSE; /* impossible */
+ }
+ }
+
+ return GL_TRUE;
+}
+
+static struct ureg emit_combine( struct texenv_fragment_program *p,
+ struct ureg dest,
+ GLuint mask,
+ GLboolean saturate,
+ GLuint unit,
+ GLuint nr,
+ GLuint mode,
+ struct mode_opt *opt)
+{
+ struct ureg src[3];
+ struct ureg tmp, half;
+ GLuint i;
+
+ tmp = undef; /* silence warning (bug 5318) */
+
+ for (i = 0; i < nr; i++)
+ src[i] = emit_combine_source( p, mask, unit, opt[i].Source, opt[i].Operand );
+
+ switch (mode) {
+ case MODE_REPLACE:
+ if (mask == WRITEMASK_XYZW && !saturate)
+ return src[0];
+ else
+ return emit_arith( p, OPCODE_MOV, dest, mask, saturate, src[0], undef, undef );
+ case MODE_MODULATE:
+ return emit_arith( p, OPCODE_MUL, dest, mask, saturate,
+ src[0], src[1], undef );
+ case MODE_ADD:
+ return emit_arith( p, OPCODE_ADD, dest, mask, saturate,
+ src[0], src[1], undef );
+ case MODE_ADD_SIGNED:
+ /* tmp = arg0 + arg1
+ * result = tmp - .5
+ */
+ half = get_half(p);
+ tmp = get_temp( p );
+ emit_arith( p, OPCODE_ADD, tmp, mask, 0, src[0], src[1], undef );
+ emit_arith( p, OPCODE_SUB, dest, mask, saturate, tmp, half, undef );
+ return dest;
+ case MODE_INTERPOLATE:
+ /* Arg0 * (Arg2) + Arg1 * (1-Arg2) -- note arguments are reordered:
+ */
+ return emit_arith( p, OPCODE_LRP, dest, mask, saturate, src[2], src[0], src[1] );
+
+ case MODE_SUBTRACT:
+ return emit_arith( p, OPCODE_SUB, dest, mask, saturate, src[0], src[1], undef );
+
+ case MODE_DOT3_RGBA:
+ case MODE_DOT3_RGBA_EXT:
+ case MODE_DOT3_RGB_EXT:
+ case MODE_DOT3_RGB: {
+ struct ureg tmp0 = get_temp( p );
+ struct ureg tmp1 = get_temp( p );
+ struct ureg neg1 = register_scalar_const(p, -1);
+ struct ureg two = register_scalar_const(p, 2);
+
+ /* tmp0 = 2*src0 - 1
+ * tmp1 = 2*src1 - 1
+ *
+ * dst = tmp0 dot3 tmp1
+ */
+ emit_arith( p, OPCODE_MAD, tmp0, WRITEMASK_XYZW, 0,
+ two, src[0], neg1);
+
+ if (_mesa_memcmp(&src[0], &src[1], sizeof(struct ureg)) == 0)
+ tmp1 = tmp0;
+ else
+ emit_arith( p, OPCODE_MAD, tmp1, WRITEMASK_XYZW, 0,
+ two, src[1], neg1);
+ emit_arith( p, OPCODE_DP3, dest, mask, saturate, tmp0, tmp1, undef);
+ return dest;
+ }
+ case MODE_MODULATE_ADD_ATI:
+ /* Arg0 * Arg2 + Arg1 */
+ return emit_arith( p, OPCODE_MAD, dest, mask, saturate,
+ src[0], src[2], src[1] );
+ case MODE_MODULATE_SIGNED_ADD_ATI: {
+ /* Arg0 * Arg2 + Arg1 - 0.5 */
+ struct ureg tmp0 = get_temp(p);
+ half = get_half(p);
+ emit_arith( p, OPCODE_MAD, tmp0, mask, 0, src[0], src[2], src[1] );
+ emit_arith( p, OPCODE_SUB, dest, mask, saturate, tmp0, half, undef );
+ return dest;
+ }
+ case MODE_MODULATE_SUBTRACT_ATI:
+ /* Arg0 * Arg2 - Arg1 */
+ emit_arith( p, OPCODE_MAD, dest, mask, 0, src[0], src[2], negate(src[1]) );
+ return dest;
+ default:
+ return src[0];
+ }
+}
+
+
+/**
+ * Generate instructions for one texture unit's env/combiner mode.
+ */
+static struct ureg
+emit_texenv(struct texenv_fragment_program *p, GLuint unit)
+{
+ struct state_key *key = p->state;
+ GLboolean saturate = (unit < p->last_tex_stage);
+ GLuint rgb_shift, alpha_shift;
+ struct ureg out, shift;
+ struct ureg dest;
+
+ if (!key->unit[unit].enabled) {
+ return get_source(p, SRC_PREVIOUS, 0);
+ }
+
+ switch (key->unit[unit].ModeRGB) {
+ case MODE_DOT3_RGB_EXT:
+ alpha_shift = key->unit[unit].ScaleShiftA;
+ rgb_shift = 0;
+ break;
+ case MODE_DOT3_RGBA_EXT:
+ alpha_shift = 0;
+ rgb_shift = 0;
+ break;
+ default:
+ rgb_shift = key->unit[unit].ScaleShiftRGB;
+ alpha_shift = key->unit[unit].ScaleShiftA;
+ break;
+ }
+
+ /* If this is the very last calculation, emit direct to output reg:
+ */
+ if (key->separate_specular ||
+ unit != p->last_tex_stage ||
+ alpha_shift ||
+ rgb_shift)
+ dest = get_temp( p );
+ else
+ dest = make_ureg(PROGRAM_OUTPUT, FRAG_RESULT_COLR);
+
+ /* Emit the RGB and A combine ops
+ */
+ if (key->unit[unit].ModeRGB == key->unit[unit].ModeA &&
+ args_match(key, unit)) {
+ out = emit_combine( p, dest, WRITEMASK_XYZW, saturate,
+ unit,
+ key->unit[unit].NumArgsRGB,
+ key->unit[unit].ModeRGB,
+ key->unit[unit].OptRGB);
+ }
+ else if (key->unit[unit].ModeRGB == MODE_DOT3_RGBA_EXT ||
+ key->unit[unit].ModeA == MODE_DOT3_RGBA) {
+
+ out = emit_combine( p, dest, WRITEMASK_XYZW, saturate,
+ unit,
+ key->unit[unit].NumArgsRGB,
+ key->unit[unit].ModeRGB,
+ key->unit[unit].OptRGB);
+ }
+ else {
+ /* Need to do something to stop from re-emitting identical
+ * argument calculations here:
+ */
+ out = emit_combine( p, dest, WRITEMASK_XYZ, saturate,
+ unit,
+ key->unit[unit].NumArgsRGB,
+ key->unit[unit].ModeRGB,
+ key->unit[unit].OptRGB);
+ out = emit_combine( p, dest, WRITEMASK_W, saturate,
+ unit,
+ key->unit[unit].NumArgsA,
+ key->unit[unit].ModeA,
+ key->unit[unit].OptA);
+ }
+
+ /* Deal with the final shift:
+ */
+ if (alpha_shift || rgb_shift) {
+ if (rgb_shift == alpha_shift) {
+ shift = register_scalar_const(p, 1<<rgb_shift);
+ }
+ else {
+ shift = register_const4f(p,
+ 1<<rgb_shift,
+ 1<<rgb_shift,
+ 1<<rgb_shift,
+ 1<<alpha_shift);
+ }
+ return emit_arith( p, OPCODE_MUL, dest, WRITEMASK_XYZW,
+ saturate, out, shift, undef );
+ }
+ else
+ return out;
+}
+
+
+/**
+ * Generate instruction for getting a texture source term.
+ */
+static void load_texture( struct texenv_fragment_program *p, GLuint unit )
+{
+ if (is_undef(p->src_texture[unit])) {
+ GLuint dim = p->state->unit[unit].source_index;
+ struct ureg texcoord = register_input(p, FRAG_ATTRIB_TEX0+unit);
+ struct ureg tmp = get_tex_temp( p );
+
+ if (dim == TEXTURE_UNKNOWN_INDEX)
+ program_error(p, "TexSrcBit");
+
+ /* TODO: Use D0_MASK_XY where possible.
+ */
+ if (p->state->unit[unit].enabled)
+ p->src_texture[unit] = emit_texld( p, OPCODE_TXP,
+ tmp, WRITEMASK_XYZW,
+ unit, dim, texcoord );
+ else
+ p->src_texture[unit] = get_zero(p);
+ }
+}
+
+static GLboolean load_texenv_source( struct texenv_fragment_program *p,
+ GLuint src, GLuint unit )
+{
+ switch (src) {
+ case SRC_TEXTURE:
+ load_texture(p, unit);
+ break;
+
+ case SRC_TEXTURE0:
+ case SRC_TEXTURE1:
+ case SRC_TEXTURE2:
+ case SRC_TEXTURE3:
+ case SRC_TEXTURE4:
+ case SRC_TEXTURE5:
+ case SRC_TEXTURE6:
+ case SRC_TEXTURE7:
+ load_texture(p, src - SRC_TEXTURE0);
+ break;
+
+ default:
+ break;
+ }
+
+ return GL_TRUE;
+}
+
+
+/**
+ * Generate instructions for loading all texture source terms.
+ */
+static GLboolean
+load_texunit_sources( struct texenv_fragment_program *p, int unit )
+{
+ struct state_key *key = p->state;
+ GLuint i;
+
+ for (i = 0; i < key->unit[unit].NumArgsRGB; i++) {
+ load_texenv_source( p, key->unit[unit].OptRGB[i].Source, unit);
+ }
+
+ for (i = 0; i < key->unit[unit].NumArgsA; i++) {
+ load_texenv_source( p, key->unit[unit].OptA[i].Source, unit );
+ }
+
+ return GL_TRUE;
+}
+
+
+/**
+ * Generate a new fragment program which implements the context's
+ * current texture env/combine mode.
+ */
+static void
+create_new_program(struct state_key *key, GLcontext *ctx,
+ struct fragment_program *program)
+{
+ struct texenv_fragment_program p;
+ GLuint unit;
+ struct ureg cf, out;
+
+ _mesa_memset(&p, 0, sizeof(p));
+ p.ctx = ctx;
+ p.state = key;
+ p.program = program;
+
+ p.program->Base.Instructions =
+ (struct prog_instruction*) _mesa_malloc(sizeof(struct prog_instruction) * MAX_INSTRUCTIONS);
+ p.program->Base.NumInstructions = 0;
+ p.program->Base.Target = GL_FRAGMENT_PROGRAM_ARB;
+ p.program->NumTexIndirections = 1; /* correct? */
+ p.program->NumTexInstructions = 0;
+ p.program->NumAluInstructions = 0;
+ p.program->Base.String = 0;
+ p.program->Base.NumInstructions =
+ p.program->Base.NumTemporaries =
+ p.program->Base.NumParameters =
+ p.program->Base.NumAttributes = p.program->Base.NumAddressRegs = 0;
+ p.program->Base.Parameters = _mesa_new_parameter_list();
+
+ p.program->Base.InputsRead = 0;
+ p.program->Base.OutputsWritten = 1 << FRAG_RESULT_COLR;
+
+ for (unit = 0; unit < MAX_TEXTURE_UNITS; unit++)
+ p.src_texture[unit] = undef;
+
+ p.src_previous = undef;
+ p.last_tex_stage = 0;
+ release_temps(&p);
+
+ if (key->enabled_units) {
+ /* First pass - to support texture_env_crossbar, first identify
+ * all referenced texture sources and emit texld instructions
+ * for each:
+ */
+ for (unit = 0 ; unit < ctx->Const.MaxTextureUnits ; unit++)
+ if (key->unit[unit].enabled) {
+ load_texunit_sources( &p, unit );
+ p.last_tex_stage = unit;
+ }
+
+ /* Second pass - emit combine instructions to build final color:
+ */
+ for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++)
+ if (key->enabled_units & (1<<unit)) {
+ p.src_previous = emit_texenv( &p, unit );
+ release_temps(&p); /* release all temps */
+ }
+ }
+
+ cf = get_source( &p, SRC_PREVIOUS, 0 );
+ out = make_ureg( PROGRAM_OUTPUT, FRAG_RESULT_COLR );
+
+ if (key->separate_specular) {
+ /* Emit specular add.
+ */
+ struct ureg s = register_input(&p, FRAG_ATTRIB_COL1);
+ emit_arith( &p, OPCODE_ADD, out, WRITEMASK_XYZ, 0, cf, s, undef );
+ emit_arith( &p, OPCODE_MOV, out, WRITEMASK_W, 0, cf, undef, undef );
+ }
+ else if (_mesa_memcmp(&cf, &out, sizeof(cf)) != 0) {
+ /* Will wind up in here if no texture enabled or a couple of
+ * other scenarios (GL_REPLACE for instance).
+ */
+ emit_arith( &p, OPCODE_MOV, out, WRITEMASK_XYZW, 0, cf, undef, undef );
+ }
+
+ /* Finish up:
+ */
+ emit_arith( &p, OPCODE_END, undef, WRITEMASK_XYZW, 0, undef, undef, undef);
+
+ if (key->fog_enabled) {
+ /* Pull fog mode from GLcontext, the value in the state key is
+ * a reduced value and not what is expected in FogOption
+ */
+ p.program->FogOption = ctx->Fog.Mode;
+ } else
+ p.program->FogOption = GL_NONE;
+
+ if (p.program->NumTexIndirections > ctx->Const.FragmentProgram.MaxTexIndirections)
+ program_error(&p, "Exceeded max nr indirect texture lookups");
+
+ if (p.program->NumTexInstructions > ctx->Const.FragmentProgram.MaxTexInstructions)
+ program_error(&p, "Exceeded max TEX instructions");
+
+ if (p.program->NumAluInstructions > ctx->Const.FragmentProgram.MaxAluInstructions)
+ program_error(&p, "Exceeded max ALU instructions");
+
+ ASSERT(p.program->Base.NumInstructions <= MAX_INSTRUCTIONS);
+
+ /* Notify driver the fragment program has (actually) changed.
+ */
+ if (ctx->Driver.ProgramStringNotify || DISASSEM) {
+ if (ctx->Driver.ProgramStringNotify)
+ ctx->Driver.ProgramStringNotify( ctx, GL_FRAGMENT_PROGRAM_ARB,
+ &p.program->Base );
+
+ if (DISASSEM) {
+ _mesa_print_program(&p.program->Base);
+ _mesa_printf("\n");
+ }
+ }
+}
+
+
+static void *search_cache( struct texenvprog_cache *cache,
+ GLuint hash,
+ const void *key,
+ GLuint keysize)
+{
+ struct texenvprog_cache *c;
+
+ for (c = cache; c; c = c->next) {
+ if (c->hash == hash && _mesa_memcmp(c->key, key, keysize) == 0)
+ return c->data;
+ }
+
+ return NULL;
+}
+
+static void cache_item( struct texenvprog_cache **cache,
+ GLuint hash,
+ void *key,
+ void *data )
+{
+ struct texenvprog_cache *c = CALLOC_STRUCT(texenvprog_cache);
+ c->hash = hash;
+ c->key = key;
+ c->data = data;
+ c->next = *cache;
+ *cache = c;
+}
+
+static GLuint hash_key( struct state_key *key )
+{
+ GLuint *ikey = (GLuint *)key;
+ GLuint hash = 0, i;
+
+ /* I'm sure this can be improved on, but speed is important:
+ */
+ for (i = 0; i < sizeof(*key)/sizeof(GLuint); i++)
+ hash ^= ikey[i];
+
+ return hash;
+}
+
+void _mesa_UpdateTexEnvProgram( GLcontext *ctx )
+{
+ struct state_key *key;
+ GLuint hash;
+ struct fragment_program *prev = ctx->FragmentProgram._Current;
+
+ if (!ctx->FragmentProgram._Enabled) {
+ key = make_state_key(ctx);
+ hash = hash_key(key);
+
+ ctx->FragmentProgram._Current = ctx->_TexEnvProgram =
+ (struct fragment_program *)
+ search_cache(ctx->Texture.env_fp_cache, hash, key, sizeof(*key));
+
+ if (!ctx->_TexEnvProgram) {
+ if (0) _mesa_printf("Building new texenv proggy for key %x\n", hash);
+
+ ctx->FragmentProgram._Current = ctx->_TexEnvProgram =
+ (struct fragment_program *)
+ ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
+
+ create_new_program(key, ctx, ctx->_TexEnvProgram);
+
+ cache_item(&ctx->Texture.env_fp_cache, hash, key, ctx->_TexEnvProgram);
+ } else {
+ _mesa_free(key);
+ if (0) _mesa_printf("Found existing texenv program for key %x\n", hash);
+ }
+ }
+ else {
+ ctx->FragmentProgram._Current = ctx->FragmentProgram.Current;
+ }
+
+ /* Tell the driver about the change. Could define a new target for
+ * this?
+ */
+ if (ctx->FragmentProgram._Current != prev && ctx->Driver.BindProgram) {
+ ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB,
+ (struct program *) ctx->FragmentProgram._Current);
+ }
+}
+
+void _mesa_TexEnvProgramCacheDestroy( GLcontext *ctx )
+{
+ struct texenvprog_cache *a, *tmp;
+
+ for (a = ctx->Texture.env_fp_cache; a; a = tmp) {
+ tmp = a->next;
+ _mesa_free(a->key);
+ ctx->Driver.DeleteProgram(ctx, (struct program *) a->data);
+ _mesa_free(a);
+ }
+}
diff --git a/src/mesa/main/texenvprogram.h b/src/mesa/main/texenvprogram.h
new file mode 100644
index 00000000000..30c8cca3889
--- /dev/null
+++ b/src/mesa/main/texenvprogram.h
@@ -0,0 +1,40 @@
+/**
+ * \file texenvprogram.h
+ * Texture state management.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 5.1
+ *
+ * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef TEXENVPROGRAM_H
+#define TEXENVPROGRAM_H
+
+
+#include "mtypes.h"
+
+extern void _mesa_UpdateTexEnvProgram( GLcontext *ctx );
+extern void _mesa_TexEnvProgramCacheDestroy( GLcontext *ctx );
+
+#endif
diff --git a/src/mesa/main/texformat.c b/src/mesa/main/texformat.c
new file mode 100644
index 00000000000..5ef9e46df22
--- /dev/null
+++ b/src/mesa/main/texformat.c
@@ -0,0 +1,1397 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/**
+ * \file texformat.c
+ * Texture formats.
+ *
+ * \author Gareth Hughes
+ */
+
+
+#include "colormac.h"
+#include "context.h"
+#include "texformat.h"
+#include "texstore.h"
+
+
+
+/* Texel fetch routines for all supported formats
+ */
+#define DIM 1
+#include "texformat_tmp.h"
+
+#define DIM 2
+#include "texformat_tmp.h"
+
+#define DIM 3
+#include "texformat_tmp.h"
+
+/**
+ * Null texel fetch function.
+ *
+ * Have to have this so the FetchTexel function pointer is never NULL.
+ */
+static void fetch_null_texel( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLchan *texel )
+{
+ (void) texImage; (void) i; (void) j; (void) k;
+ texel[RCOMP] = 0;
+ texel[GCOMP] = 0;
+ texel[BCOMP] = 0;
+ texel[ACOMP] = 0;
+ _mesa_warning(NULL, "fetch_null_texel() called!");
+}
+
+static void fetch_null_texelf( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLfloat *texel )
+{
+ (void) texImage; (void) i; (void) j; (void) k;
+ texel[RCOMP] = 0.0;
+ texel[GCOMP] = 0.0;
+ texel[BCOMP] = 0.0;
+ texel[ACOMP] = 0.0;
+ _mesa_warning(NULL, "fetch_null_texelf() called!");
+}
+
+static void store_null_texel(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ /* no-op */
+}
+
+
+/**
+ * Notes about the predefined gl_texture_formats:
+ *
+ * 1. There are 1D, 2D and 3D functions for fetching texels from texture
+ * images, returning both GLchan values and GLfloat values. (six
+ * functions in total)
+ * You don't have to provide both the GLchan and GLfloat functions;
+ * just one or the other is OK. Mesa will use an "adaptor" to convert
+ * between GLchan/GLfloat when needed.
+ * Since the adaptors have small performance penalty, we provide both
+ * GLchan and GLfloat functions for some common formats like RGB, RGBA.
+ */
+
+
+/***************************************************************/
+/** \name Default GLchan-based formats */
+/*@{*/
+
+const struct gl_texture_format _mesa_texformat_rgba = {
+ MESA_FORMAT_RGBA, /* MesaFormat */
+ GL_RGBA, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ CHAN_BITS, /* RedBits */
+ CHAN_BITS, /* GreenBits */
+ CHAN_BITS, /* BlueBits */
+ CHAN_BITS, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 4 * sizeof(GLchan), /* TexelBytes */
+ _mesa_texstore_rgba, /* StoreTexImageFunc */
+ fetch_texel_1d_rgba, /* FetchTexel1D */
+ fetch_texel_2d_rgba, /* FetchTexel2D */
+ fetch_texel_3d_rgba, /* FetchTexel3D */
+ fetch_texel_1d_f_rgba, /* FetchTexel1Df */
+ fetch_texel_2d_f_rgba, /* FetchTexel2Df */
+ fetch_texel_3d_f_rgba, /* FetchTexel3Df */
+ store_texel_rgba /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_rgb = {
+ MESA_FORMAT_RGB, /* MesaFormat */
+ GL_RGB, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ CHAN_BITS, /* RedBits */
+ CHAN_BITS, /* GreenBits */
+ CHAN_BITS, /* BlueBits */
+ 0, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 3 * sizeof(GLchan), /* TexelBytes */
+ _mesa_texstore_rgba,/*yes*/ /* StoreTexImageFunc */
+ fetch_texel_1d_rgb, /* FetchTexel1D */
+ fetch_texel_2d_rgb, /* FetchTexel2D */
+ fetch_texel_3d_rgb, /* FetchTexel3D */
+ fetch_texel_1d_f_rgb, /* FetchTexel1Df */
+ fetch_texel_2d_f_rgb, /* FetchTexel2Df */
+ fetch_texel_3d_f_rgb, /* FetchTexel3Df */
+ store_texel_rgb /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_alpha = {
+ MESA_FORMAT_ALPHA, /* MesaFormat */
+ GL_ALPHA, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ 0, /* RedBits */
+ 0, /* GreenBits */
+ 0, /* BlueBits */
+ CHAN_BITS, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ sizeof(GLchan), /* TexelBytes */
+ _mesa_texstore_rgba,/*yes*/ /* StoreTexImageFunc */
+ fetch_texel_1d_alpha, /* FetchTexel1D */
+ fetch_texel_2d_alpha, /* FetchTexel2D */
+ fetch_texel_3d_alpha, /* FetchTexel3D */
+ NULL, /* FetchTexel1Df */
+ NULL, /* FetchTexel2Df */
+ NULL, /* FetchTexel3Df */
+ store_texel_alpha /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_luminance = {
+ MESA_FORMAT_LUMINANCE, /* MesaFormat */
+ GL_LUMINANCE, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ 0, /* RedBits */
+ 0, /* GreenBits */
+ 0, /* BlueBits */
+ 0, /* AlphaBits */
+ CHAN_BITS, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ sizeof(GLchan), /* TexelBytes */
+ _mesa_texstore_rgba,/*yes*/ /* StoreTexImageFunc */
+ fetch_texel_1d_luminance, /* FetchTexel1D */
+ fetch_texel_2d_luminance, /* FetchTexel2D */
+ fetch_texel_3d_luminance, /* FetchTexel3D */
+ NULL, /* FetchTexel1Df */
+ NULL, /* FetchTexel2Df */
+ NULL, /* FetchTexel3Df */
+ store_texel_luminance /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_luminance_alpha = {
+ MESA_FORMAT_LUMINANCE_ALPHA, /* MesaFormat */
+ GL_LUMINANCE_ALPHA, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ 0, /* RedBits */
+ 0, /* GreenBits */
+ 0, /* BlueBits */
+ CHAN_BITS, /* AlphaBits */
+ CHAN_BITS, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 2 * sizeof(GLchan), /* TexelBytes */
+ _mesa_texstore_rgba,/*yes*/ /* StoreTexImageFunc */
+ fetch_texel_1d_luminance_alpha, /* FetchTexel1D */
+ fetch_texel_2d_luminance_alpha, /* FetchTexel2D */
+ fetch_texel_3d_luminance_alpha, /* FetchTexel3D */
+ NULL, /* FetchTexel1Df */
+ NULL, /* FetchTexel2Df */
+ NULL, /* FetchTexel3Df */
+ store_texel_luminance_alpha /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_intensity = {
+ MESA_FORMAT_INTENSITY, /* MesaFormat */
+ GL_INTENSITY, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ 0, /* RedBits */
+ 0, /* GreenBits */
+ 0, /* BlueBits */
+ 0, /* AlphaBits */
+ 0, /* LuminanceBits */
+ CHAN_BITS, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ sizeof(GLchan), /* TexelBytes */
+ _mesa_texstore_rgba,/*yes*/ /* StoreTexImageFunc */
+ fetch_texel_1d_intensity, /* FetchTexel1D */
+ fetch_texel_2d_intensity, /* FetchTexel2D */
+ fetch_texel_3d_intensity, /* FetchTexel3D */
+ NULL, /* FetchTexel1Df */
+ NULL, /* FetchTexel2Df */
+ NULL, /* FetchTexel3Df */
+ store_texel_intensity /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_depth_component_float32 = {
+ MESA_FORMAT_DEPTH_COMPONENT_FLOAT32, /* MesaFormat */
+ GL_DEPTH_COMPONENT, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ 0, /* RedBits */
+ 0, /* GreenBits */
+ 0, /* BlueBits */
+ 0, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ sizeof(GLfloat) * 8, /* DepthBits */
+ sizeof(GLfloat) * 8, /* StencilBits */
+ sizeof(GLfloat), /* TexelBytes */
+ _mesa_texstore_depth_component_float32,/* StoreTexImageFunc */
+ NULL, /* FetchTexel1D */
+ NULL, /* FetchTexel1D */
+ NULL, /* FetchTexel1D */
+ fetch_texel_1d_f_depth_component_f32,/* FetchTexel1Df */
+ fetch_texel_2d_f_depth_component_f32,/* FetchTexel2Df */
+ fetch_texel_3d_f_depth_component_f32,/* FetchTexel3Df */
+ store_texel_depth_component_f32 /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_depth_component16 = {
+ MESA_FORMAT_DEPTH_COMPONENT16, /* MesaFormat */
+ GL_DEPTH_COMPONENT, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ 0, /* RedBits */
+ 0, /* GreenBits */
+ 0, /* BlueBits */
+ 0, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ sizeof(GLushort) * 8, /* DepthBits */
+ sizeof(GLushort) * 8, /* StencilBits */
+ sizeof(GLushort), /* TexelBytes */
+ _mesa_texstore_depth_component16, /* StoreTexImageFunc */
+ NULL, /* FetchTexel1D */
+ NULL, /* FetchTexel1D */
+ NULL, /* FetchTexel1D */
+ fetch_texel_1d_f_depth_component16, /* FetchTexel1Df */
+ fetch_texel_2d_f_depth_component16, /* FetchTexel2Df */
+ fetch_texel_3d_f_depth_component16, /* FetchTexel3Df */
+ store_texel_depth_component16 /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_rgba_float32 = {
+ MESA_FORMAT_RGBA_FLOAT32, /* MesaFormat */
+ GL_RGBA, /* BaseFormat */
+ GL_FLOAT, /* DataType */
+ 8 * sizeof(GLfloat), /* RedBits */
+ 8 * sizeof(GLfloat), /* GreenBits */
+ 8 * sizeof(GLfloat), /* BlueBits */
+ 8 * sizeof(GLfloat), /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 4 * sizeof(GLfloat), /* TexelBytes */
+ _mesa_texstore_rgba_float32, /* StoreTexImageFunc */
+ NULL, /* FetchTexel1D */
+ NULL, /* FetchTexel1D */
+ NULL, /* FetchTexel1D */
+ fetch_texel_1d_f_rgba_f32, /* FetchTexel1Df */
+ fetch_texel_2d_f_rgba_f32, /* FetchTexel2Df */
+ fetch_texel_3d_f_rgba_f32, /* FetchTexel3Df */
+ store_texel_rgba_f32 /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_rgba_float16 = {
+ MESA_FORMAT_RGBA_FLOAT16, /* MesaFormat */
+ GL_RGBA, /* BaseFormat */
+ GL_FLOAT, /* DataType */
+ 8 * sizeof(GLhalfARB), /* RedBits */
+ 8 * sizeof(GLhalfARB), /* GreenBits */
+ 8 * sizeof(GLhalfARB), /* BlueBits */
+ 8 * sizeof(GLhalfARB), /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 4 * sizeof(GLhalfARB), /* TexelBytes */
+ _mesa_texstore_rgba_float16, /* StoreTexImageFunc */
+ NULL, /* FetchTexel1D */
+ NULL, /* FetchTexel1D */
+ NULL, /* FetchTexel1D */
+ fetch_texel_1d_f_rgba_f16, /* FetchTexel1Df */
+ fetch_texel_2d_f_rgba_f16, /* FetchTexel2Df */
+ fetch_texel_3d_f_rgba_f16, /* FetchTexel3Df */
+ store_texel_rgba_f16 /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_rgb_float32 = {
+ MESA_FORMAT_RGB_FLOAT32, /* MesaFormat */
+ GL_RGB, /* BaseFormat */
+ GL_FLOAT, /* DataType */
+ 8 * sizeof(GLfloat), /* RedBits */
+ 8 * sizeof(GLfloat), /* GreenBits */
+ 8 * sizeof(GLfloat), /* BlueBits */
+ 0, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 3 * sizeof(GLfloat), /* TexelBytes */
+ _mesa_texstore_rgba_float32,/*yes*/ /* StoreTexImageFunc */
+ NULL, /* FetchTexel1D */
+ NULL, /* FetchTexel1D */
+ NULL, /* FetchTexel1D */
+ fetch_texel_1d_f_rgb_f32, /* FetchTexel1Df */
+ fetch_texel_2d_f_rgb_f32, /* FetchTexel2Df */
+ fetch_texel_3d_f_rgb_f32, /* FetchTexel3Df */
+ store_texel_rgb_f32 /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_rgb_float16 = {
+ MESA_FORMAT_RGB_FLOAT16, /* MesaFormat */
+ GL_RGB, /* BaseFormat */
+ GL_FLOAT, /* DataType */
+ 8 * sizeof(GLhalfARB), /* RedBits */
+ 8 * sizeof(GLhalfARB), /* GreenBits */
+ 8 * sizeof(GLhalfARB), /* BlueBits */
+ 0, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 3 * sizeof(GLhalfARB), /* TexelBytes */
+ _mesa_texstore_rgba_float16,/*yes*/ /* StoreTexImageFunc */
+ NULL, /* FetchTexel1D */
+ NULL, /* FetchTexel1D */
+ NULL, /* FetchTexel1D */
+ fetch_texel_1d_f_rgb_f16, /* FetchTexel1Df */
+ fetch_texel_2d_f_rgb_f16, /* FetchTexel2Df */
+ fetch_texel_3d_f_rgb_f16, /* FetchTexel3Df */
+ store_texel_rgb_f16 /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_alpha_float32 = {
+ MESA_FORMAT_ALPHA_FLOAT32, /* MesaFormat */
+ GL_ALPHA, /* BaseFormat */
+ GL_FLOAT, /* DataType */
+ 0, /* RedBits */
+ 0, /* GreenBits */
+ 0, /* BlueBits */
+ 8 * sizeof(GLfloat), /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 1 * sizeof(GLfloat), /* TexelBytes */
+ _mesa_texstore_rgba_float32,/*yes*/ /* StoreTexImageFunc */
+ NULL, /* FetchTexel1D */
+ NULL, /* FetchTexel1D */
+ NULL, /* FetchTexel1D */
+ fetch_texel_1d_f_alpha_f32, /* FetchTexel1Df */
+ fetch_texel_2d_f_alpha_f32, /* FetchTexel2Df */
+ fetch_texel_3d_f_alpha_f32, /* FetchTexel3Df */
+ store_texel_alpha_f32 /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_alpha_float16 = {
+ MESA_FORMAT_ALPHA_FLOAT16, /* MesaFormat */
+ GL_ALPHA, /* BaseFormat */
+ GL_FLOAT, /* DataType */
+ 0, /* RedBits */
+ 0, /* GreenBits */
+ 0, /* BlueBits */
+ 8 * sizeof(GLhalfARB), /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 1 * sizeof(GLhalfARB), /* TexelBytes */
+ _mesa_texstore_rgba_float16,/*yes*/ /* StoreTexImageFunc */
+ NULL, /* FetchTexel1D */
+ NULL, /* FetchTexel1D */
+ NULL, /* FetchTexel1D */
+ fetch_texel_1d_f_alpha_f16, /* FetchTexel1Df */
+ fetch_texel_2d_f_alpha_f16, /* FetchTexel2Df */
+ fetch_texel_3d_f_alpha_f16, /* FetchTexel3Df */
+ store_texel_alpha_f16 /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_luminance_float32 = {
+ MESA_FORMAT_LUMINANCE_FLOAT32, /* MesaFormat */
+ GL_LUMINANCE, /* BaseFormat */
+ GL_FLOAT, /* DataType */
+ 0, /* RedBits */
+ 0, /* GreenBits */
+ 0, /* BlueBits */
+ 0, /* AlphaBits */
+ 8 * sizeof(GLfloat), /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 1 * sizeof(GLfloat), /* TexelBytes */
+ _mesa_texstore_rgba_float32,/*yes*/ /* StoreTexImageFunc */
+ NULL, /* FetchTexel1D */
+ NULL, /* FetchTexel2D */
+ NULL, /* FetchTexel3D */
+ fetch_texel_1d_f_luminance_f32, /* FetchTexel1Df */
+ fetch_texel_2d_f_luminance_f32, /* FetchTexel2Df */
+ fetch_texel_3d_f_luminance_f32, /* FetchTexel3Df */
+ store_texel_luminance_f32 /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_luminance_float16 = {
+ MESA_FORMAT_LUMINANCE_FLOAT16, /* MesaFormat */
+ GL_LUMINANCE, /* BaseFormat */
+ GL_FLOAT, /* DataType */
+ 0, /* RedBits */
+ 0, /* GreenBits */
+ 0, /* BlueBits */
+ 0, /* AlphaBits */
+ 8 * sizeof(GLhalfARB), /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 1 * sizeof(GLhalfARB), /* TexelBytes */
+ _mesa_texstore_rgba_float16,/*yes*/ /* StoreTexImageFunc */
+ NULL, /* FetchTexel1D */
+ NULL, /* FetchTexel2D */
+ NULL, /* FetchTexel3D */
+ fetch_texel_1d_f_luminance_f16, /* FetchTexel1Df */
+ fetch_texel_2d_f_luminance_f16, /* FetchTexel2Df */
+ fetch_texel_3d_f_luminance_f16, /* FetchTexel3Df */
+ store_texel_luminance_f16 /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_luminance_alpha_float32 = {
+ MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32, /* MesaFormat */
+ GL_LUMINANCE_ALPHA, /* BaseFormat */
+ GL_FLOAT, /* DataType */
+ 0, /* RedBits */
+ 0, /* GreenBits */
+ 0, /* BlueBits */
+ 8 * sizeof(GLfloat), /* AlphaBits */
+ 8 * sizeof(GLfloat), /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 2 * sizeof(GLfloat), /* TexelBytes */
+ _mesa_texstore_rgba_float32, /* StoreTexImageFunc */
+ NULL, /* FetchTexel1D */
+ NULL, /* FetchTexel2D */
+ NULL, /* FetchTexel3D */
+ fetch_texel_1d_f_luminance_alpha_f32,/* FetchTexel1Df */
+ fetch_texel_2d_f_luminance_alpha_f32,/* FetchTexel2Df */
+ fetch_texel_3d_f_luminance_alpha_f32,/* FetchTexel3Df */
+ store_texel_luminance_alpha_f32 /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_luminance_alpha_float16 = {
+ MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16, /* MesaFormat */
+ GL_LUMINANCE_ALPHA, /* BaseFormat */
+ GL_FLOAT, /* DataType */
+ 0, /* RedBits */
+ 0, /* GreenBits */
+ 0, /* BlueBits */
+ 8 * sizeof(GLhalfARB), /* AlphaBits */
+ 8 * sizeof(GLhalfARB), /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 2 * sizeof(GLhalfARB), /* TexelBytes */
+ _mesa_texstore_rgba_float16, /* StoreTexImageFunc */
+ NULL, /* FetchTexel1D */
+ NULL, /* FetchTexel2D */
+ NULL, /* FetchTexel3D */
+ fetch_texel_1d_f_luminance_alpha_f16,/* FetchTexel1Df */
+ fetch_texel_2d_f_luminance_alpha_f16,/* FetchTexel2Df */
+ fetch_texel_3d_f_luminance_alpha_f16,/* FetchTexel3Df */
+ store_texel_luminance_alpha_f16 /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_intensity_float32 = {
+ MESA_FORMAT_INTENSITY_FLOAT32, /* MesaFormat */
+ GL_INTENSITY, /* BaseFormat */
+ GL_FLOAT, /* DataType */
+ 0, /* RedBits */
+ 0, /* GreenBits */
+ 0, /* BlueBits */
+ 0, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 8 * sizeof(GLfloat), /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 1 * sizeof(GLfloat), /* TexelBytes */
+ _mesa_texstore_rgba_float32,/*yes*/ /* StoreTexImageFunc */
+ NULL, /* FetchTexel1D */
+ NULL, /* FetchTexel2D */
+ NULL, /* FetchTexel3D */
+ fetch_texel_1d_f_intensity_f32, /* FetchTexel1Df */
+ fetch_texel_2d_f_intensity_f32, /* FetchTexel2Df */
+ fetch_texel_3d_f_intensity_f32, /* FetchTexel3Df */
+ store_texel_intensity_f32 /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_intensity_float16 = {
+ MESA_FORMAT_INTENSITY_FLOAT16, /* MesaFormat */
+ GL_INTENSITY, /* BaseFormat */
+ GL_FLOAT, /* DataType */
+ 0, /* RedBits */
+ 0, /* GreenBits */
+ 0, /* BlueBits */
+ 0, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 8 * sizeof(GLhalfARB), /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 1 * sizeof(GLhalfARB), /* TexelBytes */
+ _mesa_texstore_rgba_float16,/*yes*/ /* StoreTexImageFunc */
+ NULL, /* FetchTexel1D */
+ NULL, /* FetchTexel2D */
+ NULL, /* FetchTexel3D */
+ fetch_texel_1d_f_intensity_f16, /* FetchTexel1Df */
+ fetch_texel_2d_f_intensity_f16, /* FetchTexel2Df */
+ fetch_texel_3d_f_intensity_f16, /* FetchTexel3Df */
+ store_texel_intensity_f16 /* StoreTexel */
+};
+
+
+/*@}*/
+
+
+/***************************************************************/
+/** \name Hardware formats */
+/*@{*/
+
+const struct gl_texture_format _mesa_texformat_rgba8888 = {
+ MESA_FORMAT_RGBA8888, /* MesaFormat */
+ GL_RGBA, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ 8, /* RedBits */
+ 8, /* GreenBits */
+ 8, /* BlueBits */
+ 8, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 4, /* TexelBytes */
+ _mesa_texstore_rgba8888, /* StoreTexImageFunc */
+ fetch_texel_1d_rgba8888, /* FetchTexel1D */
+ fetch_texel_2d_rgba8888, /* FetchTexel2D */
+ fetch_texel_3d_rgba8888, /* FetchTexel3D */
+ NULL, /* FetchTexel1Df */
+ NULL, /* FetchTexel2Df */
+ NULL, /* FetchTexel3Df */
+ store_texel_rgba8888 /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_rgba8888_rev = {
+ MESA_FORMAT_RGBA8888_REV, /* MesaFormat */
+ GL_RGBA, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ 8, /* RedBits */
+ 8, /* GreenBits */
+ 8, /* BlueBits */
+ 8, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 4, /* TexelBytes */
+ _mesa_texstore_rgba8888, /* StoreTexImageFunc */
+ fetch_texel_1d_rgba8888_rev, /* FetchTexel1D */
+ fetch_texel_2d_rgba8888_rev, /* FetchTexel2D */
+ fetch_texel_3d_rgba8888_rev, /* FetchTexel3D */
+ NULL, /* FetchTexel1Df */
+ NULL, /* FetchTexel2Df */
+ NULL, /* FetchTexel3Df */
+ store_texel_rgba8888_rev /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_argb8888 = {
+ MESA_FORMAT_ARGB8888, /* MesaFormat */
+ GL_RGBA, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ 8, /* RedBits */
+ 8, /* GreenBits */
+ 8, /* BlueBits */
+ 8, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 4, /* TexelBytes */
+ _mesa_texstore_argb8888, /* StoreTexImageFunc */
+ fetch_texel_1d_argb8888, /* FetchTexel1D */
+ fetch_texel_2d_argb8888, /* FetchTexel2D */
+ fetch_texel_3d_argb8888, /* FetchTexel3D */
+ NULL, /* FetchTexel1Df */
+ NULL, /* FetchTexel2Df */
+ NULL, /* FetchTexel3Df */
+ store_texel_argb8888 /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_argb8888_rev = {
+ MESA_FORMAT_ARGB8888_REV, /* MesaFormat */
+ GL_RGBA, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ 8, /* RedBits */
+ 8, /* GreenBits */
+ 8, /* BlueBits */
+ 8, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 4, /* TexelBytes */
+ _mesa_texstore_argb8888, /* StoreTexImageFunc */
+ fetch_texel_1d_argb8888_rev, /* FetchTexel1D */
+ fetch_texel_2d_argb8888_rev, /* FetchTexel2D */
+ fetch_texel_3d_argb8888_rev, /* FetchTexel3D */
+ NULL, /* FetchTexel1Df */
+ NULL, /* FetchTexel2Df */
+ NULL, /* FetchTexel3Df */
+ store_texel_argb8888_rev /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_rgb888 = {
+ MESA_FORMAT_RGB888, /* MesaFormat */
+ GL_RGB, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ 8, /* RedBits */
+ 8, /* GreenBits */
+ 8, /* BlueBits */
+ 0, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 3, /* TexelBytes */
+ _mesa_texstore_rgb888, /* StoreTexImageFunc */
+ fetch_texel_1d_rgb888, /* FetchTexel1D */
+ fetch_texel_2d_rgb888, /* FetchTexel2D */
+ fetch_texel_3d_rgb888, /* FetchTexel3D */
+ NULL, /* FetchTexel1Df */
+ NULL, /* FetchTexel2Df */
+ NULL, /* FetchTexel3Df */
+ store_texel_rgb888 /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_bgr888 = {
+ MESA_FORMAT_BGR888, /* MesaFormat */
+ GL_RGB, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ 8, /* RedBits */
+ 8, /* GreenBits */
+ 8, /* BlueBits */
+ 0, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 3, /* TexelBytes */
+ _mesa_texstore_bgr888, /* StoreTexImageFunc */
+ fetch_texel_1d_bgr888, /* FetchTexel1D */
+ fetch_texel_2d_bgr888, /* FetchTexel2D */
+ fetch_texel_3d_bgr888, /* FetchTexel3D */
+ NULL, /* FetchTexel1Df */
+ NULL, /* FetchTexel2Df */
+ NULL, /* FetchTexel3Df */
+ store_texel_bgr888 /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_rgb565 = {
+ MESA_FORMAT_RGB565, /* MesaFormat */
+ GL_RGB, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ 5, /* RedBits */
+ 6, /* GreenBits */
+ 5, /* BlueBits */
+ 0, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 2, /* TexelBytes */
+ _mesa_texstore_rgb565, /* StoreTexImageFunc */
+ fetch_texel_1d_rgb565, /* FetchTexel1D */
+ fetch_texel_2d_rgb565, /* FetchTexel2D */
+ fetch_texel_3d_rgb565, /* FetchTexel3D */
+ NULL, /* FetchTexel1Df */
+ NULL, /* FetchTexel2Df */
+ NULL, /* FetchTexel3Df */
+ store_texel_rgb565 /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_rgb565_rev = {
+ MESA_FORMAT_RGB565_REV, /* MesaFormat */
+ GL_RGB, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ 5, /* RedBits */
+ 6, /* GreenBits */
+ 5, /* BlueBits */
+ 0, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 2, /* TexelBytes */
+ _mesa_texstore_rgb565, /* StoreTexImageFunc */
+ fetch_texel_1d_rgb565_rev, /* FetchTexel1D */
+ fetch_texel_2d_rgb565_rev, /* FetchTexel2D */
+ fetch_texel_3d_rgb565_rev, /* FetchTexel3D */
+ NULL, /* FetchTexel1Df */
+ NULL, /* FetchTexel2Df */
+ NULL, /* FetchTexel3Df */
+ store_texel_rgb565_rev /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_argb4444 = {
+ MESA_FORMAT_ARGB4444, /* MesaFormat */
+ GL_RGBA, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ 4, /* RedBits */
+ 4, /* GreenBits */
+ 4, /* BlueBits */
+ 4, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 2, /* TexelBytes */
+ _mesa_texstore_argb4444, /* StoreTexImageFunc */
+ fetch_texel_1d_argb4444, /* FetchTexel1D */
+ fetch_texel_2d_argb4444, /* FetchTexel2D */
+ fetch_texel_3d_argb4444, /* FetchTexel3D */
+ NULL, /* FetchTexel1Df */
+ NULL, /* FetchTexel2Df */
+ NULL, /* FetchTexel3Df */
+ store_texel_argb4444 /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_argb4444_rev = {
+ MESA_FORMAT_ARGB4444_REV, /* MesaFormat */
+ GL_RGBA, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ 4, /* RedBits */
+ 4, /* GreenBits */
+ 4, /* BlueBits */
+ 4, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 2, /* TexelBytes */
+ _mesa_texstore_argb4444, /* StoreTexImageFunc */
+ fetch_texel_1d_argb4444_rev, /* FetchTexel1D */
+ fetch_texel_2d_argb4444_rev, /* FetchTexel2D */
+ fetch_texel_3d_argb4444_rev, /* FetchTexel3D */
+ NULL, /* FetchTexel1Df */
+ NULL, /* FetchTexel2Df */
+ NULL, /* FetchTexel3Df */
+ store_texel_argb4444_rev /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_argb1555 = {
+ MESA_FORMAT_ARGB1555, /* MesaFormat */
+ GL_RGBA, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ 5, /* RedBits */
+ 5, /* GreenBits */
+ 5, /* BlueBits */
+ 1, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 2, /* TexelBytes */
+ _mesa_texstore_argb1555, /* StoreTexImageFunc */
+ fetch_texel_1d_argb1555, /* FetchTexel1D */
+ fetch_texel_2d_argb1555, /* FetchTexel2D */
+ fetch_texel_3d_argb1555, /* FetchTexel3D */
+ NULL, /* FetchTexel1Df */
+ NULL, /* FetchTexel2Df */
+ NULL, /* FetchTexel3Df */
+ store_texel_argb1555 /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_argb1555_rev = {
+ MESA_FORMAT_ARGB1555_REV, /* MesaFormat */
+ GL_RGBA, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ 5, /* RedBits */
+ 5, /* GreenBits */
+ 5, /* BlueBits */
+ 1, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 2, /* TexelBytes */
+ _mesa_texstore_argb1555, /* StoreTexImageFunc */
+ fetch_texel_1d_argb1555_rev, /* FetchTexel1D */
+ fetch_texel_2d_argb1555_rev, /* FetchTexel2D */
+ fetch_texel_3d_argb1555_rev, /* FetchTexel3D */
+ NULL, /* FetchTexel1Df */
+ NULL, /* FetchTexel2Df */
+ NULL, /* FetchTexel3Df */
+ store_texel_argb1555_rev /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_al88 = {
+ MESA_FORMAT_AL88, /* MesaFormat */
+ GL_LUMINANCE_ALPHA, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ 0, /* RedBits */
+ 0, /* GreenBits */
+ 0, /* BlueBits */
+ 8, /* AlphaBits */
+ 8, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 2, /* TexelBytes */
+ _mesa_texstore_al88, /* StoreTexImageFunc */
+ fetch_texel_1d_al88, /* FetchTexel1D */
+ fetch_texel_2d_al88, /* FetchTexel2D */
+ fetch_texel_3d_al88, /* FetchTexel3D */
+ NULL, /* FetchTexel1Df */
+ NULL, /* FetchTexel2Df */
+ NULL, /* FetchTexel3Df */
+ store_texel_al88 /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_al88_rev = {
+ MESA_FORMAT_AL88_REV, /* MesaFormat */
+ GL_LUMINANCE_ALPHA, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ 0, /* RedBits */
+ 0, /* GreenBits */
+ 0, /* BlueBits */
+ 8, /* AlphaBits */
+ 8, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 2, /* TexelBytes */
+ _mesa_texstore_al88, /* StoreTexImageFunc */
+ fetch_texel_1d_al88_rev, /* FetchTexel1D */
+ fetch_texel_2d_al88_rev, /* FetchTexel2D */
+ fetch_texel_3d_al88_rev, /* FetchTexel3D */
+ NULL, /* FetchTexel1Df */
+ NULL, /* FetchTexel2Df */
+ NULL, /* FetchTexel3Df */
+ store_texel_al88_rev /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_rgb332 = {
+ MESA_FORMAT_RGB332, /* MesaFormat */
+ GL_RGB, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ 3, /* RedBits */
+ 3, /* GreenBits */
+ 2, /* BlueBits */
+ 0, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 1, /* TexelBytes */
+ _mesa_texstore_rgb332, /* StoreTexImageFunc */
+ fetch_texel_1d_rgb332, /* FetchTexel1D */
+ fetch_texel_2d_rgb332, /* FetchTexel2D */
+ fetch_texel_3d_rgb332, /* FetchTexel3D */
+ NULL, /* FetchTexel1Df */
+ NULL, /* FetchTexel2Df */
+ NULL, /* FetchTexel3Df */
+ store_texel_rgb332 /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_a8 = {
+ MESA_FORMAT_A8, /* MesaFormat */
+ GL_ALPHA, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ 0, /* RedBits */
+ 0, /* GreenBits */
+ 0, /* BlueBits */
+ 8, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 1, /* TexelBytes */
+ _mesa_texstore_a8, /* StoreTexImageFunc */
+ fetch_texel_1d_a8, /* FetchTexel1D */
+ fetch_texel_2d_a8, /* FetchTexel2D */
+ fetch_texel_3d_a8, /* FetchTexel3D */
+ NULL, /* FetchTexel1Df */
+ NULL, /* FetchTexel2Df */
+ NULL, /* FetchTexel3Df */
+ store_texel_a8 /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_l8 = {
+ MESA_FORMAT_L8, /* MesaFormat */
+ GL_LUMINANCE, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ 0, /* RedBits */
+ 0, /* GreenBits */
+ 0, /* BlueBits */
+ 0, /* AlphaBits */
+ 8, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 1, /* TexelBytes */
+ _mesa_texstore_a8,/*yes*/ /* StoreTexImageFunc */
+ fetch_texel_1d_l8, /* FetchTexel1D */
+ fetch_texel_2d_l8, /* FetchTexel2D */
+ fetch_texel_3d_l8, /* FetchTexel3D */
+ NULL, /* FetchTexel1Df */
+ NULL, /* FetchTexel2Df */
+ NULL, /* FetchTexel3Df */
+ store_texel_l8 /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_i8 = {
+ MESA_FORMAT_I8, /* MesaFormat */
+ GL_INTENSITY, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ 0, /* RedBits */
+ 0, /* GreenBits */
+ 0, /* BlueBits */
+ 0, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 8, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 1, /* TexelBytes */
+ _mesa_texstore_a8,/*yes*/ /* StoreTexImageFunc */
+ fetch_texel_1d_i8, /* FetchTexel1D */
+ fetch_texel_2d_i8, /* FetchTexel2D */
+ fetch_texel_3d_i8, /* FetchTexel3D */
+ NULL, /* FetchTexel1Df */
+ NULL, /* FetchTexel2Df */
+ NULL, /* FetchTexel3Df */
+ store_texel_i8 /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_ci8 = {
+ MESA_FORMAT_CI8, /* MesaFormat */
+ GL_COLOR_INDEX, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ 0, /* RedBits */
+ 0, /* GreenBits */
+ 0, /* BlueBits */
+ 0, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 8, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 1, /* TexelBytes */
+ _mesa_texstore_ci8, /* StoreTexImageFunc */
+ fetch_texel_1d_ci8, /* FetchTexel1D */
+ fetch_texel_2d_ci8, /* FetchTexel2D */
+ fetch_texel_3d_ci8, /* FetchTexel3D */
+ NULL, /* FetchTexel1Df */
+ NULL, /* FetchTexel2Df */
+ NULL, /* FetchTexel3Df */
+ store_texel_ci8 /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_ycbcr = {
+ MESA_FORMAT_YCBCR, /* MesaFormat */
+ GL_YCBCR_MESA, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ 0, /* RedBits */
+ 0, /* GreenBits */
+ 0, /* BlueBits */
+ 0, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 2, /* TexelBytes */
+ _mesa_texstore_ycbcr, /* StoreTexImageFunc */
+ fetch_texel_1d_ycbcr, /* FetchTexel1D */
+ fetch_texel_2d_ycbcr, /* FetchTexel2D */
+ fetch_texel_3d_ycbcr, /* FetchTexel3D */
+ NULL, /* FetchTexel1Df */
+ NULL, /* FetchTexel2Df */
+ NULL, /* FetchTexel3Df */
+ store_texel_ycbcr /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_ycbcr_rev = {
+ MESA_FORMAT_YCBCR_REV, /* MesaFormat */
+ GL_YCBCR_MESA, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ 0, /* RedBits */
+ 0, /* GreenBits */
+ 0, /* BlueBits */
+ 0, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 2, /* TexelBytes */
+ _mesa_texstore_ycbcr, /* StoreTexImageFunc */
+ fetch_texel_1d_ycbcr_rev, /* FetchTexel1D */
+ fetch_texel_2d_ycbcr_rev, /* FetchTexel2D */
+ fetch_texel_3d_ycbcr_rev, /* FetchTexel3D */
+ NULL, /* FetchTexel1Df */
+ NULL, /* FetchTexel2Df */
+ NULL, /* FetchTexel3Df */
+ store_texel_ycbcr_rev /* StoreTexel */
+};
+
+const struct gl_texture_format _mesa_texformat_z24_s8 = {
+ MESA_FORMAT_Z24_S8, /* MesaFormat */
+ GL_DEPTH_STENCIL_EXT, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
+ 0, /* RedBits */
+ 0, /* GreenBits */
+ 0, /* BlueBits */
+ 0, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 24, /* DepthBits */
+ 8, /* StencilBits */
+ 4, /* TexelBytes */
+ _mesa_texstore_z24_s8, /* StoreTexImageFunc */
+ NULL, /* FetchTexel1D */
+ NULL, /* FetchTexel2D */
+ NULL, /* FetchTexel3D */
+ fetch_texel_1d_f_z24_s8, /* FetchTexel1Df */
+ fetch_texel_2d_f_z24_s8, /* FetchTexel2Df */
+ fetch_texel_3d_f_z24_s8, /* FetchTexel3Df */
+ store_texel_z24_s8 /* StoreTexel */
+};
+
+/*@}*/
+
+
+/***************************************************************/
+/** \name Null format (useful for proxy textures) */
+/*@{*/
+
+const struct gl_texture_format _mesa_null_texformat = {
+ -1, /* MesaFormat */
+ 0, /* BaseFormat */
+ GL_NONE, /* DataType */
+ 0, /* RedBits */
+ 0, /* GreenBits */
+ 0, /* BlueBits */
+ 0, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+ 0, /* DepthBits */
+ 0, /* StencilBits */
+ 0, /* TexelBytes */
+ NULL, /* StoreTexImageFunc */
+ fetch_null_texel, /* FetchTexel1D */
+ fetch_null_texel, /* FetchTexel2D */
+ fetch_null_texel, /* FetchTexel3D */
+ fetch_null_texelf, /* FetchTexel1Df */
+ fetch_null_texelf, /* FetchTexel2Df */
+ fetch_null_texelf, /* FetchTexel3Df */
+ store_null_texel /* StoreTexel */
+};
+
+/*@}*/
+
+
+/**
+ * Choose an appropriate texture format given the format, type and
+ * internalFormat parameters passed to glTexImage().
+ *
+ * \param ctx the GL context.
+ * \param internalFormat user's prefered internal texture format.
+ * \param format incoming image pixel format.
+ * \param type incoming image data type.
+ *
+ * \return a pointer to a gl_texture_format object which describes the
+ * choosen texture format, or NULL on failure.
+ *
+ * This is called via dd_function_table::ChooseTextureFormat. Hardware drivers
+ * will typically override this function with a specialized version.
+ */
+const struct gl_texture_format *
+_mesa_choose_tex_format( GLcontext *ctx, GLint internalFormat,
+ GLenum format, GLenum type )
+{
+ (void) format;
+ (void) type;
+
+ switch (internalFormat) {
+ /* RGBA formats */
+ case 4:
+ case GL_RGBA:
+ case GL_RGB10_A2:
+ case GL_RGBA12:
+ case GL_RGBA16:
+ return &_mesa_texformat_rgba;
+ case GL_RGBA8:
+ return &_mesa_texformat_rgba8888;
+ case GL_RGB5_A1:
+ return &_mesa_texformat_argb1555;
+ case GL_RGBA2:
+ return &_mesa_texformat_argb4444_rev; /* just to test another format*/
+ case GL_RGBA4:
+ return &_mesa_texformat_argb4444;
+
+ /* RGB formats */
+ case 3:
+ case GL_RGB:
+ case GL_RGB10:
+ case GL_RGB12:
+ case GL_RGB16:
+ return &_mesa_texformat_rgb;
+ case GL_RGB8:
+ return &_mesa_texformat_rgb888;
+ case GL_R3_G3_B2:
+ return &_mesa_texformat_rgb332;
+ case GL_RGB4:
+ return &_mesa_texformat_rgb565_rev; /* just to test another format */
+ case GL_RGB5:
+ return &_mesa_texformat_rgb565;
+
+ /* Alpha formats */
+ case GL_ALPHA:
+ case GL_ALPHA4:
+ case GL_ALPHA12:
+ case GL_ALPHA16:
+ return &_mesa_texformat_alpha;
+ case GL_ALPHA8:
+ return &_mesa_texformat_a8;
+
+ /* Luminance formats */
+ case 1:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE4:
+ case GL_LUMINANCE12:
+ case GL_LUMINANCE16:
+ return &_mesa_texformat_luminance;
+ case GL_LUMINANCE8:
+ return &_mesa_texformat_l8;
+
+ /* Luminance/Alpha formats */
+ case 2:
+ case GL_LUMINANCE_ALPHA:
+ case GL_LUMINANCE4_ALPHA4:
+ case GL_LUMINANCE6_ALPHA2:
+ case GL_LUMINANCE12_ALPHA4:
+ case GL_LUMINANCE12_ALPHA12:
+ case GL_LUMINANCE16_ALPHA16:
+ return &_mesa_texformat_luminance_alpha;
+ case GL_LUMINANCE8_ALPHA8:
+ return &_mesa_texformat_al88;
+
+ case GL_INTENSITY:
+ case GL_INTENSITY4:
+ case GL_INTENSITY12:
+ case GL_INTENSITY16:
+ return &_mesa_texformat_intensity;
+ case GL_INTENSITY8:
+ return &_mesa_texformat_i8;
+
+ case GL_COLOR_INDEX:
+ case GL_COLOR_INDEX1_EXT:
+ case GL_COLOR_INDEX2_EXT:
+ case GL_COLOR_INDEX4_EXT:
+ case GL_COLOR_INDEX12_EXT:
+ case GL_COLOR_INDEX16_EXT:
+ case GL_COLOR_INDEX8_EXT:
+ return &_mesa_texformat_ci8;
+
+ default:
+ ; /* fallthrough */
+ }
+
+ if (ctx->Extensions.SGIX_depth_texture ||
+ ctx->Extensions.ARB_depth_texture) {
+ switch (internalFormat) {
+ case GL_DEPTH_COMPONENT:
+ case GL_DEPTH_COMPONENT24_SGIX:
+ case GL_DEPTH_COMPONENT32_SGIX:
+ return &_mesa_texformat_depth_component_float32;
+ case GL_DEPTH_COMPONENT16_SGIX:
+ return &_mesa_texformat_depth_component16;
+ default:
+ ; /* fallthrough */
+ }
+ }
+
+ if (ctx->Extensions.ARB_texture_compression) {
+ switch (internalFormat) {
+ case GL_COMPRESSED_ALPHA_ARB:
+ return &_mesa_texformat_alpha;
+ case GL_COMPRESSED_LUMINANCE_ARB:
+ return &_mesa_texformat_luminance;
+ case GL_COMPRESSED_LUMINANCE_ALPHA_ARB:
+ return &_mesa_texformat_luminance_alpha;
+ case GL_COMPRESSED_INTENSITY_ARB:
+ return &_mesa_texformat_intensity;
+ case GL_COMPRESSED_RGB_ARB:
+ if (ctx->Extensions.TDFX_texture_compression_FXT1)
+ return &_mesa_texformat_rgb_fxt1;
+ else if (ctx->Extensions.EXT_texture_compression_s3tc ||
+ ctx->Extensions.S3_s3tc)
+ return &_mesa_texformat_rgb_dxt1;
+ else
+ return &_mesa_texformat_rgb;
+ case GL_COMPRESSED_RGBA_ARB:
+ if (ctx->Extensions.TDFX_texture_compression_FXT1)
+ return &_mesa_texformat_rgba_fxt1;
+ else if (ctx->Extensions.EXT_texture_compression_s3tc ||
+ ctx->Extensions.S3_s3tc)
+ return &_mesa_texformat_rgba_dxt3; /* Not rgba_dxt1, see spec */
+ else
+ return &_mesa_texformat_rgba;
+ default:
+ ; /* fallthrough */
+ }
+ }
+
+ if (ctx->Extensions.MESA_ycbcr_texture) {
+ if (internalFormat == GL_YCBCR_MESA) {
+ if (type == GL_UNSIGNED_SHORT_8_8_MESA)
+ return &_mesa_texformat_ycbcr;
+ else
+ return &_mesa_texformat_ycbcr_rev;
+ }
+ }
+
+ if (ctx->Extensions.TDFX_texture_compression_FXT1) {
+ switch (internalFormat) {
+ case GL_COMPRESSED_RGB_FXT1_3DFX:
+ return &_mesa_texformat_rgb_fxt1;
+ case GL_COMPRESSED_RGBA_FXT1_3DFX:
+ return &_mesa_texformat_rgba_fxt1;
+ default:
+ ; /* fallthrough */
+ }
+ }
+
+ if (ctx->Extensions.EXT_texture_compression_s3tc) {
+ switch (internalFormat) {
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ return &_mesa_texformat_rgb_dxt1;
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ return &_mesa_texformat_rgba_dxt1;
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ return &_mesa_texformat_rgba_dxt3;
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ return &_mesa_texformat_rgba_dxt5;
+ default:
+ ; /* fallthrough */
+ }
+ }
+
+ if (ctx->Extensions.S3_s3tc) {
+ switch (internalFormat) {
+ case GL_RGB_S3TC:
+ case GL_RGB4_S3TC:
+ return &_mesa_texformat_rgb_dxt1;
+ case GL_RGBA_S3TC:
+ case GL_RGBA4_S3TC:
+ return &_mesa_texformat_rgba_dxt3;
+ default:
+ ; /* fallthrough */
+ }
+ }
+
+ if (ctx->Extensions.ARB_texture_float) {
+ switch (internalFormat) {
+ case GL_ALPHA16F_ARB:
+ return &_mesa_texformat_alpha_float16;
+ case GL_ALPHA32F_ARB:
+ return &_mesa_texformat_alpha_float32;
+ case GL_LUMINANCE16F_ARB:
+ return &_mesa_texformat_luminance_float16;
+ case GL_LUMINANCE32F_ARB:
+ return &_mesa_texformat_luminance_float32;
+ case GL_LUMINANCE_ALPHA16F_ARB:
+ return &_mesa_texformat_luminance_alpha_float16;
+ case GL_LUMINANCE_ALPHA32F_ARB:
+ return &_mesa_texformat_luminance_alpha_float32;
+ case GL_INTENSITY16F_ARB:
+ return &_mesa_texformat_intensity_float16;
+ case GL_INTENSITY32F_ARB:
+ return &_mesa_texformat_intensity_float32;
+ case GL_RGB16F_ARB:
+ return &_mesa_texformat_rgb_float16;
+ case GL_RGB32F_ARB:
+ return &_mesa_texformat_rgb_float32;
+ case GL_RGBA16F_ARB:
+ return &_mesa_texformat_rgba_float16;
+ case GL_RGBA32F_ARB:
+ return &_mesa_texformat_rgba_float32;
+ default:
+ ; /* fallthrough */
+ }
+ }
+
+ if (ctx->Extensions.EXT_packed_depth_stencil) {
+ switch (internalFormat) {
+ case GL_DEPTH_STENCIL_EXT:
+ case GL_DEPTH24_STENCIL8_EXT:
+ return &_mesa_texformat_z24_s8;
+ default:
+ ; /* fallthrough */
+ }
+ }
+
+ _mesa_problem(ctx, "unexpected format in _mesa_choose_tex_format()");
+ return NULL;
+}
diff --git a/src/mesa/main/texformat.h b/src/mesa/main/texformat.h
new file mode 100644
index 00000000000..63f524bbe13
--- /dev/null
+++ b/src/mesa/main/texformat.h
@@ -0,0 +1,230 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.1
+ *
+ * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/**
+ * \file texformat.h
+ * Texture formats definitions.
+ *
+ * \author Gareth Hughes
+ */
+
+
+#ifndef TEXFORMAT_H
+#define TEXFORMAT_H
+
+
+#include "mtypes.h"
+
+
+/**
+ * Mesa internal texture image formats.
+ * All texture images are stored in one of these formats.
+ *
+ * NOTE: when you add a new format, be sure to update the do_row()
+ * function in texstore.c used for auto mipmap generation.
+ */
+enum _format {
+ /**
+ * \name Hardware-friendly formats.
+ *
+ * Drivers can override the default formats and convert texture images to
+ * one of these as required. The driver's
+ * dd_function_table::ChooseTextureFormat function will choose one of these
+ * formats.
+ *
+ * \note In the default case, some of these formats will be duplicates of
+ * the generic formats listed below. However, these formats guarantee their
+ * internal component sizes, while GLchan may vary between GLubyte, GLushort
+ * and GLfloat.
+ */
+ /*@{*/
+ /* msb <------ TEXEL BITS -----------> lsb */
+ /* ---- ---- ---- ---- ---- ---- ---- ---- */
+ MESA_FORMAT_RGBA8888, /* RRRR RRRR GGGG GGGG BBBB BBBB AAAA AAAA */
+ MESA_FORMAT_RGBA8888_REV, /* AAAA AAAA BBBB BBBB GGGG GGGG RRRR RRRR */
+ MESA_FORMAT_ARGB8888, /* AAAA AAAA RRRR RRRR GGGG GGGG BBBB BBBB */
+ MESA_FORMAT_ARGB8888_REV, /* BBBB BBBB GGGG GGGG RRRR RRRR AAAA AAAA */
+ MESA_FORMAT_RGB888, /* RRRR RRRR GGGG GGGG BBBB BBBB */
+ MESA_FORMAT_BGR888, /* BBBB BBBB GGGG GGGG RRRR RRRR */
+ MESA_FORMAT_RGB565, /* RRRR RGGG GGGB BBBB */
+ MESA_FORMAT_RGB565_REV, /* GGGB BBBB RRRR RGGG */
+ MESA_FORMAT_ARGB4444, /* AAAA RRRR GGGG BBBB */
+ MESA_FORMAT_ARGB4444_REV, /* GGGG BBBB AAAA RRRR */
+ MESA_FORMAT_ARGB1555, /* ARRR RRGG GGGB BBBB */
+ MESA_FORMAT_ARGB1555_REV, /* GGGB BBBB ARRR RRGG */
+ MESA_FORMAT_AL88, /* AAAA AAAA LLLL LLLL */
+ MESA_FORMAT_AL88_REV, /* LLLL LLLL AAAA AAAA */
+ MESA_FORMAT_RGB332, /* RRRG GGBB */
+ MESA_FORMAT_A8, /* AAAA AAAA */
+ MESA_FORMAT_L8, /* LLLL LLLL */
+ MESA_FORMAT_I8, /* IIII IIII */
+ MESA_FORMAT_CI8, /* CCCC CCCC */
+ MESA_FORMAT_YCBCR, /* YYYY YYYY UorV UorV */
+ MESA_FORMAT_YCBCR_REV, /* UorV UorV YYYY YYYY */
+ MESA_FORMAT_Z24_S8, /* ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ SSSS SSSS */
+ /*@}*/
+
+ /**
+ * \name Compressed texture formats.
+ */
+ /*@{*/
+ MESA_FORMAT_RGB_FXT1,
+ MESA_FORMAT_RGBA_FXT1,
+ MESA_FORMAT_RGB_DXT1,
+ MESA_FORMAT_RGBA_DXT1,
+ MESA_FORMAT_RGBA_DXT3,
+ MESA_FORMAT_RGBA_DXT5,
+ /*@}*/
+
+ /**
+ * \name Generic GLchan-based formats.
+ *
+ * Software-oriented texture formats. Texels are arrays of GLchan
+ * values so there are no byte order issues.
+ *
+ * \note Because these are based on the GLchan data type, one cannot assume
+ * 8 bits per channel with these formats. If you require GLubyte channels,
+ * use one of the hardware formats above.
+ */
+ /*@{*/
+ MESA_FORMAT_RGBA,
+ MESA_FORMAT_RGB,
+ MESA_FORMAT_ALPHA,
+ MESA_FORMAT_LUMINANCE,
+ MESA_FORMAT_LUMINANCE_ALPHA,
+ MESA_FORMAT_INTENSITY,
+ /*@}*/
+
+ /**
+ * Depth textures
+ */
+ /*@{*/
+ MESA_FORMAT_DEPTH_COMPONENT_FLOAT32,
+ MESA_FORMAT_DEPTH_COMPONENT16,
+ /*@}*/
+
+ /**
+ * \name Floating point texture formats.
+ */
+ /*@{*/
+ MESA_FORMAT_RGBA_FLOAT32,
+ MESA_FORMAT_RGBA_FLOAT16,
+ MESA_FORMAT_RGB_FLOAT32,
+ MESA_FORMAT_RGB_FLOAT16,
+ MESA_FORMAT_ALPHA_FLOAT32,
+ MESA_FORMAT_ALPHA_FLOAT16,
+ MESA_FORMAT_LUMINANCE_FLOAT32,
+ MESA_FORMAT_LUMINANCE_FLOAT16,
+ MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32,
+ MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16,
+ MESA_FORMAT_INTENSITY_FLOAT32,
+ MESA_FORMAT_INTENSITY_FLOAT16
+ /*@}*/
+};
+
+
+/** GLchan-valued formats */
+/*@{*/
+extern const struct gl_texture_format _mesa_texformat_rgba;
+extern const struct gl_texture_format _mesa_texformat_rgb;
+extern const struct gl_texture_format _mesa_texformat_alpha;
+extern const struct gl_texture_format _mesa_texformat_luminance;
+extern const struct gl_texture_format _mesa_texformat_luminance_alpha;
+extern const struct gl_texture_format _mesa_texformat_intensity;
+/*@}*/
+
+/** Depth textures */
+/*@{*/
+extern const struct gl_texture_format _mesa_texformat_depth_component_float32;
+extern const struct gl_texture_format _mesa_texformat_depth_component16;
+/*@}*/
+
+/** Floating point texture formats */
+/*@{*/
+extern const struct gl_texture_format _mesa_texformat_rgba_float32;
+extern const struct gl_texture_format _mesa_texformat_rgba_float16;
+extern const struct gl_texture_format _mesa_texformat_rgb_float32;
+extern const struct gl_texture_format _mesa_texformat_rgb_float16;
+extern const struct gl_texture_format _mesa_texformat_alpha_float32;
+extern const struct gl_texture_format _mesa_texformat_alpha_float16;
+extern const struct gl_texture_format _mesa_texformat_luminance_float32;
+extern const struct gl_texture_format _mesa_texformat_luminance_float16;
+extern const struct gl_texture_format _mesa_texformat_luminance_alpha_float32;
+extern const struct gl_texture_format _mesa_texformat_luminance_alpha_float16;
+extern const struct gl_texture_format _mesa_texformat_intensity_float32;
+extern const struct gl_texture_format _mesa_texformat_intensity_float16;
+/*@}*/
+
+/** \name Assorted hardware-friendly formats */
+/*@{*/
+extern const struct gl_texture_format _mesa_texformat_rgba8888;
+extern const struct gl_texture_format _mesa_texformat_rgba8888_rev;
+extern const struct gl_texture_format _mesa_texformat_argb8888;
+extern const struct gl_texture_format _mesa_texformat_argb8888_rev;
+extern const struct gl_texture_format _mesa_texformat_rgb888;
+extern const struct gl_texture_format _mesa_texformat_bgr888;
+extern const struct gl_texture_format _mesa_texformat_rgb565;
+extern const struct gl_texture_format _mesa_texformat_rgb565_rev;
+extern const struct gl_texture_format _mesa_texformat_argb4444;
+extern const struct gl_texture_format _mesa_texformat_argb4444_rev;
+extern const struct gl_texture_format _mesa_texformat_argb1555;
+extern const struct gl_texture_format _mesa_texformat_argb1555_rev;
+extern const struct gl_texture_format _mesa_texformat_al88;
+extern const struct gl_texture_format _mesa_texformat_al88_rev;
+extern const struct gl_texture_format _mesa_texformat_rgb332;
+extern const struct gl_texture_format _mesa_texformat_a8;
+extern const struct gl_texture_format _mesa_texformat_l8;
+extern const struct gl_texture_format _mesa_texformat_i8;
+extern const struct gl_texture_format _mesa_texformat_ci8;
+extern const struct gl_texture_format _mesa_texformat_z24_s8;
+/*@}*/
+
+/** \name YCbCr formats */
+/*@{*/
+extern const struct gl_texture_format _mesa_texformat_ycbcr;
+extern const struct gl_texture_format _mesa_texformat_ycbcr_rev;
+/*@}*/
+
+/** \name Compressed formats */
+/*@{*/
+extern const struct gl_texture_format _mesa_texformat_rgb_fxt1;
+extern const struct gl_texture_format _mesa_texformat_rgba_fxt1;
+extern const struct gl_texture_format _mesa_texformat_rgb_dxt1;
+extern const struct gl_texture_format _mesa_texformat_rgba_dxt1;
+extern const struct gl_texture_format _mesa_texformat_rgba_dxt3;
+extern const struct gl_texture_format _mesa_texformat_rgba_dxt5;
+/*@}*/
+
+/** \name The null format */
+/*@{*/
+extern const struct gl_texture_format _mesa_null_texformat;
+/*@}*/
+
+
+extern const struct gl_texture_format *
+_mesa_choose_tex_format( GLcontext *ctx, GLint internalFormat,
+ GLenum format, GLenum type );
+
+#endif
diff --git a/src/mesa/main/texformat_tmp.h b/src/mesa/main/texformat_tmp.h
new file mode 100644
index 00000000000..cc6ed1cc936
--- /dev/null
+++ b/src/mesa/main/texformat_tmp.h
@@ -0,0 +1,1291 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/**
+ * \file texformat_tmp.h
+ * Texel fetch functions template.
+ *
+ * This template file is used by texformat.c to generate texel fetch functions
+ * for 1-D, 2-D and 3-D texture images.
+ *
+ * It should be expanded by defining \p DIM as the number texture dimensions
+ * (1, 2 or 3). According to the value of \p DIM a series of macros is defined
+ * for the texel lookup in the gl_texture_image::Data.
+ *
+ * \sa texformat.c and FetchTexel.
+ *
+ * \author Gareth Hughes
+ * \author Brian Paul
+ */
+
+
+#if DIM == 1
+
+#define TEXEL_ADDR( type, image, i, j, k, size ) \
+ ((void) (j), (void) (k), ((type *)(image)->Data + (i) * (size)))
+
+#define FETCH(x) fetch_texel_1d_##x
+
+#elif DIM == 2
+
+#define TEXEL_ADDR( type, image, i, j, k, size ) \
+ ((void) (k), \
+ ((type *)(image)->Data + ((image)->RowStride * (j) + (i)) * (size)))
+
+#define FETCH(x) fetch_texel_2d_##x
+
+#elif DIM == 3
+
+#define TEXEL_ADDR( type, image, i, j, k, size ) \
+ ((type *)(image)->Data + (((image)->Height * (k) + (j)) * \
+ (image)->RowStride + (i)) * (size))
+
+#define FETCH(x) fetch_texel_3d_##x
+
+#else
+#error illegal number of texture dimensions
+#endif
+
+
+/* MESA_FORMAT_RGBA **********************************************************/
+
+/* Fetch texel from 1D, 2D or 3D RGBA texture, returning 4 GLchans */
+static void FETCH(rgba)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLchan *texel )
+{
+ const GLchan *src = TEXEL_ADDR(GLchan, texImage, i, j, k, 4);
+ COPY_CHAN4( texel, src );
+}
+
+/* Fetch texel from 1D, 2D or 3D RGBA texture, returning 4 GLfloats */
+static void FETCH(f_rgba)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLfloat *texel )
+{
+ const GLchan *src = TEXEL_ADDR(GLchan, texImage, i, j, k, 4);
+ texel[RCOMP] = CHAN_TO_FLOAT(src[0]);
+ texel[GCOMP] = CHAN_TO_FLOAT(src[1]);
+ texel[BCOMP] = CHAN_TO_FLOAT(src[2]);
+ texel[ACOMP] = CHAN_TO_FLOAT(src[3]);
+}
+
+#if DIM == 3
+/* Store a GLchan RGBA texel */
+static void store_texel_rgba(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLchan *rgba = (const GLchan *) texel;
+ GLchan *dst = TEXEL_ADDR(GLchan, texImage, i, j, k, 4);
+ dst[0] = rgba[RCOMP];
+ dst[1] = rgba[GCOMP];
+ dst[2] = rgba[BCOMP];
+ dst[3] = rgba[ACOMP];
+}
+#endif
+
+/* MESA_FORMAT_RGB ***********************************************************/
+
+/* Fetch texel from 1D, 2D or 3D RGB texture, returning 4 GLchans */
+static void FETCH(rgb)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLchan *texel )
+{
+ const GLchan *src = TEXEL_ADDR(GLchan, texImage, i, j, k, 3);
+ texel[RCOMP] = src[0];
+ texel[GCOMP] = src[1];
+ texel[BCOMP] = src[2];
+ texel[ACOMP] = CHAN_MAX;
+}
+
+/* Fetch texel from 1D, 2D or 3D RGB texture, returning 4 GLfloats */
+static void FETCH(f_rgb)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLfloat *texel )
+{
+ const GLchan *src = TEXEL_ADDR(GLchan, texImage, i, j, k, 3);
+ texel[RCOMP] = CHAN_TO_FLOAT(src[0]);
+ texel[GCOMP] = CHAN_TO_FLOAT(src[1]);
+ texel[BCOMP] = CHAN_TO_FLOAT(src[2]);
+ texel[ACOMP] = 1.0F;
+}
+
+#if DIM == 3
+static void store_texel_rgb(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLchan *rgba = (const GLchan *) texel;
+ GLchan *dst = TEXEL_ADDR(GLchan, texImage, i, j, k, 3);
+ dst[0] = rgba[RCOMP];
+ dst[1] = rgba[GCOMP];
+ dst[2] = rgba[BCOMP];
+}
+#endif
+
+/* MESA_FORMAT_ALPHA *********************************************************/
+
+/* Fetch texel from 1D, 2D or 3D ALPHA texture, returning 4 GLchans */
+static void FETCH(alpha)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLchan *texel )
+{
+ const GLchan *src = TEXEL_ADDR(GLchan, texImage, i, j, k, 1);
+ texel[RCOMP] =
+ texel[GCOMP] =
+ texel[BCOMP] = 0;
+ texel[ACOMP] = src[0];
+}
+
+#if DIM == 3
+static void store_texel_alpha(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLchan *rgba = (const GLchan *) texel;
+ GLchan *dst = TEXEL_ADDR(GLchan, texImage, i, j, k, 1);
+ dst[0] = rgba[ACOMP];
+}
+#endif
+
+/* MESA_FORMAT_LUMINANCE *****************************************************/
+
+/* Fetch texel from 1D, 2D or 3D LUMIN texture, returning 4 GLchans */
+static void FETCH(luminance)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLchan *texel )
+{
+ const GLchan *src = TEXEL_ADDR(GLchan, texImage, i, j, k, 1);
+ texel[RCOMP] =
+ texel[GCOMP] =
+ texel[BCOMP] = src[0];
+ texel[ACOMP] = CHAN_MAX;
+}
+
+#if DIM == 3
+static void store_texel_luminance(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLchan *rgba = (const GLchan *) texel;
+ GLchan *dst = TEXEL_ADDR(GLchan, texImage, i, j, k, 1);
+ dst[0] = rgba[RCOMP];
+}
+#endif
+
+/* MESA_FORMAT_LUMINANCE_ALPHA ***********************************************/
+
+/* Fetch texel from 1D, 2D or 3D L_A texture, returning 4 GLchans */
+static void FETCH(luminance_alpha)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLchan *texel )
+{
+ const GLchan *src = TEXEL_ADDR(GLchan, texImage, i, j, k, 2);
+ texel[RCOMP] = src[0];
+ texel[GCOMP] = src[0];
+ texel[BCOMP] = src[0];
+ texel[ACOMP] = src[1];
+}
+
+#if DIM == 3
+static void store_texel_luminance_alpha(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLchan *rgba = (const GLchan *) texel;
+ GLchan *dst = TEXEL_ADDR(GLchan, texImage, i, j, k, 2);
+ dst[0] = rgba[RCOMP];
+ dst[1] = rgba[ACOMP];
+}
+#endif
+
+/* MESA_FORMAT_INTENSITY *****************************************************/
+
+/* Fetch texel from 1D, 2D or 3D INT. texture, returning 4 GLchans */
+static void FETCH(intensity)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLchan *texel )
+{
+ const GLchan *src = TEXEL_ADDR(GLchan, texImage, i, j, k, 1);
+ texel[RCOMP] = src[0];
+ texel[GCOMP] = src[0];
+ texel[BCOMP] = src[0];
+ texel[ACOMP] = src[0];
+}
+
+#if DIM == 3
+static void store_texel_intensity(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLchan *rgba = (const GLchan *) texel;
+ GLchan *dst = TEXEL_ADDR(GLchan, texImage, i, j, k, 1);
+ dst[0] = rgba[RCOMP];
+}
+#endif
+
+
+/* MESA_FORMAT_DEPTH_COMPONENT_F32 *******************************************/
+
+/* Fetch depth texel from 1D, 2D or 3D float32 DEPTH texture,
+ * returning 1 GLfloat.
+ * Note: no GLchan version of this function.
+ */
+static void FETCH(f_depth_component_f32)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLfloat *texel )
+{
+ const GLfloat *src = TEXEL_ADDR(GLfloat, texImage, i, j, k, 1);
+ texel[0] = src[0];
+}
+
+#if DIM == 3
+static void store_texel_depth_component_f32(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLfloat *depth = (const GLfloat *) texel;
+ GLfloat *dst = TEXEL_ADDR(GLfloat, texImage, i, j, k, 1);
+ dst[0] = *depth;
+}
+#endif
+
+
+/* MESA_FORMAT_DEPTH_COMPONENT16 *********************************************/
+
+/* Fetch depth texel from 1D, 2D or 3D float32 DEPTH texture,
+ * returning 1 GLfloat.
+ * Note: no GLchan version of this function.
+ */
+static void FETCH(f_depth_component16)(const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLfloat *texel )
+{
+ const GLushort *src = TEXEL_ADDR(GLushort, texImage, i, j, k, 1);
+ texel[0] = src[0] * (1.0F / 65535.0F);
+}
+
+#if DIM == 3
+static void store_texel_depth_component16(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLushort *depth = (const GLushort *) texel;
+ GLushort *dst = TEXEL_ADDR(GLushort, texImage, i, j, k, 1);
+ dst[0] = *depth;
+}
+#endif
+
+
+/* MESA_FORMAT_RGBA_F32 ******************************************************/
+
+/* Fetch texel from 1D, 2D or 3D RGBA_FLOAT32 texture, returning 4 GLfloats.
+ */
+static void FETCH(f_rgba_f32)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLfloat *texel )
+{
+ const GLfloat *src = TEXEL_ADDR(GLfloat, texImage, i, j, k, 4);
+ texel[RCOMP] = src[0];
+ texel[GCOMP] = src[1];
+ texel[BCOMP] = src[2];
+ texel[ACOMP] = src[3];
+}
+
+#if DIM == 3
+static void store_texel_rgba_f32(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLfloat *depth = (const GLfloat *) texel;
+ GLfloat *dst = TEXEL_ADDR(GLfloat, texImage, i, j, k, 1);
+ dst[0] = depth[RCOMP];
+ dst[1] = depth[GCOMP];
+ dst[2] = depth[BCOMP];
+ dst[3] = depth[ACOMP];
+}
+#endif
+
+
+/* MESA_FORMAT_RGBA_F16 ******************************************************/
+
+/* Fetch texel from 1D, 2D or 3D RGBA_FLOAT16 texture,
+ * returning 4 GLfloats.
+ */
+static void FETCH(f_rgba_f16)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLfloat *texel )
+{
+ const GLhalfARB *src = TEXEL_ADDR(GLhalfARB, texImage, i, j, k, 4);
+ texel[RCOMP] = _mesa_half_to_float(src[0]);
+ texel[GCOMP] = _mesa_half_to_float(src[1]);
+ texel[BCOMP] = _mesa_half_to_float(src[2]);
+ texel[ACOMP] = _mesa_half_to_float(src[3]);
+}
+
+#if DIM == 3
+static void store_texel_rgba_f16(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLfloat *depth = (const GLfloat *) texel;
+ GLhalfARB *dst = TEXEL_ADDR(GLhalfARB, texImage, i, j, k, 1);
+ dst[0] = _mesa_float_to_half(*depth);
+}
+#endif
+
+/* MESA_FORMAT_RGB_F32 *******************************************************/
+
+/* Fetch texel from 1D, 2D or 3D RGB_FLOAT32 texture,
+ * returning 4 GLfloats.
+ */
+static void FETCH(f_rgb_f32)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLfloat *texel )
+{
+ const GLfloat *src = TEXEL_ADDR(GLfloat, texImage, i, j, k, 3);
+ texel[RCOMP] = src[0];
+ texel[GCOMP] = src[1];
+ texel[BCOMP] = src[2];
+ texel[ACOMP] = 1.0F;
+}
+
+#if DIM == 3
+static void store_texel_rgb_f32(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLfloat *depth = (const GLfloat *) texel;
+ GLfloat *dst = TEXEL_ADDR(GLfloat, texImage, i, j, k, 1);
+ dst[0] = *depth;
+}
+#endif
+
+
+/* MESA_FORMAT_RGB_F16 *******************************************************/
+
+/* Fetch texel from 1D, 2D or 3D RGB_FLOAT16 texture,
+ * returning 4 GLfloats.
+ */
+static void FETCH(f_rgb_f16)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLfloat *texel )
+{
+ const GLhalfARB *src = TEXEL_ADDR(GLhalfARB, texImage, i, j, k, 3);
+ texel[RCOMP] = _mesa_half_to_float(src[0]);
+ texel[GCOMP] = _mesa_half_to_float(src[1]);
+ texel[BCOMP] = _mesa_half_to_float(src[2]);
+ texel[ACOMP] = 1.0F;
+}
+
+#if DIM == 3
+static void store_texel_rgb_f16(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLfloat *depth = (const GLfloat *) texel;
+ GLhalfARB *dst = TEXEL_ADDR(GLhalfARB, texImage, i, j, k, 1);
+ dst[0] = _mesa_float_to_half(*depth);
+}
+#endif
+
+
+/* MESA_FORMAT_ALPHA_F32 *****************************************************/
+
+/* Fetch texel from 1D, 2D or 3D ALPHA_FLOAT32 texture,
+ * returning 4 GLfloats.
+ */
+static void FETCH(f_alpha_f32)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLfloat *texel )
+{
+ const GLfloat *src = TEXEL_ADDR(GLfloat, texImage, i, j, k, 1);
+ texel[RCOMP] =
+ texel[GCOMP] =
+ texel[BCOMP] = 0.0F;
+ texel[ACOMP] = src[0];
+}
+
+#if DIM == 3
+static void store_texel_alpha_f32(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLfloat *rgba = (const GLfloat *) texel;
+ GLfloat *dst = TEXEL_ADDR(GLfloat, texImage, i, j, k, 1);
+ dst[0] = rgba[ACOMP];
+}
+#endif
+
+
+/* MESA_FORMAT_ALPHA_F32 *****************************************************/
+
+/* Fetch texel from 1D, 2D or 3D ALPHA_FLOAT16 texture,
+ * returning 4 GLfloats.
+ */
+static void FETCH(f_alpha_f16)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLfloat *texel )
+{
+ const GLhalfARB *src = TEXEL_ADDR(GLhalfARB, texImage, i, j, k, 1);
+ texel[RCOMP] =
+ texel[GCOMP] =
+ texel[BCOMP] = 0.0F;
+ texel[ACOMP] = _mesa_half_to_float(src[0]);
+}
+
+#if DIM == 3
+static void store_texel_alpha_f16(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLfloat *rgba = (const GLfloat *) texel;
+ GLhalfARB *dst = TEXEL_ADDR(GLhalfARB, texImage, i, j, k, 1);
+ dst[0] = _mesa_float_to_half(rgba[ACOMP]);
+}
+#endif
+
+
+/* MESA_FORMAT_LUMINANCE_F32 *************************************************/
+
+/* Fetch texel from 1D, 2D or 3D LUMINANCE_FLOAT32 texture,
+ * returning 4 GLfloats.
+ */
+static void FETCH(f_luminance_f32)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLfloat *texel )
+{
+ const GLfloat *src = TEXEL_ADDR(GLfloat, texImage, i, j, k, 1);
+ texel[RCOMP] =
+ texel[GCOMP] =
+ texel[BCOMP] = src[0];
+ texel[ACOMP] = 1.0F;
+}
+
+#if DIM == 3
+static void store_texel_luminance_f32(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLfloat *rgba = (const GLfloat *) texel;
+ GLfloat *dst = TEXEL_ADDR(GLfloat, texImage, i, j, k, 1);
+ dst[0] = rgba[RCOMP];
+}
+#endif
+
+
+/* MESA_FORMAT_LUMINANCE_F16 *************************************************/
+
+/* Fetch texel from 1D, 2D or 3D LUMINANCE_FLOAT16 texture,
+ * returning 4 GLfloats.
+ */
+static void FETCH(f_luminance_f16)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLfloat *texel )
+{
+ const GLhalfARB *src = TEXEL_ADDR(GLhalfARB, texImage, i, j, k, 1);
+ texel[RCOMP] =
+ texel[GCOMP] =
+ texel[BCOMP] = _mesa_half_to_float(src[0]);
+ texel[ACOMP] = 1.0F;
+}
+
+#if DIM == 3
+static void store_texel_luminance_f16(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLfloat *rgba = (const GLfloat *) texel;
+ GLhalfARB *dst = TEXEL_ADDR(GLhalfARB, texImage, i, j, k, 1);
+ dst[0] = _mesa_float_to_half(rgba[RCOMP]);
+}
+#endif
+
+
+/* MESA_FORMAT_LUMINANCE_ALPHA_F32 *******************************************/
+
+/* Fetch texel from 1D, 2D or 3D LUMINANCE_ALPHA_FLOAT32 texture,
+ * returning 4 GLfloats.
+ */
+static void FETCH(f_luminance_alpha_f32)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLfloat *texel )
+{
+ const GLfloat *src = TEXEL_ADDR(GLfloat, texImage, i, j, k, 2);
+ texel[RCOMP] =
+ texel[GCOMP] =
+ texel[BCOMP] = src[0];
+ texel[ACOMP] = src[1];
+}
+
+#if DIM == 3
+static void store_texel_luminance_alpha_f32(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLfloat *rgba = (const GLfloat *) texel;
+ GLfloat *dst = TEXEL_ADDR(GLfloat, texImage, i, j, k, 2);
+ dst[0] = rgba[RCOMP];
+ dst[1] = rgba[ACOMP];
+}
+#endif
+
+
+/* MESA_FORMAT_LUMINANCE_ALPHA_F16 *******************************************/
+
+/* Fetch texel from 1D, 2D or 3D LUMINANCE_ALPHA_FLOAT16 texture,
+ * returning 4 GLfloats.
+ */
+static void FETCH(f_luminance_alpha_f16)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLfloat *texel )
+{
+ const GLhalfARB *src = TEXEL_ADDR(GLhalfARB, texImage, i, j, k, 2);
+ texel[RCOMP] =
+ texel[GCOMP] =
+ texel[BCOMP] = _mesa_half_to_float(src[0]);
+ texel[ACOMP] = _mesa_half_to_float(src[1]);
+}
+
+#if DIM == 3
+static void store_texel_luminance_alpha_f16(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLfloat *rgba = (const GLfloat *) texel;
+ GLhalfARB *dst = TEXEL_ADDR(GLhalfARB, texImage, i, j, k, 2);
+ dst[0] = _mesa_float_to_half(rgba[RCOMP]);
+ dst[1] = _mesa_float_to_half(rgba[ACOMP]);
+}
+#endif
+
+
+/* MESA_FORMAT_INTENSITY_F32 *************************************************/
+
+/* Fetch texel from 1D, 2D or 3D INTENSITY_FLOAT32 texture,
+ * returning 4 GLfloats.
+ */
+static void FETCH(f_intensity_f32)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLfloat *texel )
+{
+ const GLfloat *src = TEXEL_ADDR(GLfloat, texImage, i, j, k, 1);
+ texel[RCOMP] =
+ texel[GCOMP] =
+ texel[BCOMP] =
+ texel[ACOMP] = src[0];
+}
+
+#if DIM == 3
+static void store_texel_intensity_f32(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLfloat *rgba = (const GLfloat *) texel;
+ GLfloat *dst = TEXEL_ADDR(GLfloat, texImage, i, j, k, 1);
+ dst[0] = rgba[RCOMP];
+}
+#endif
+
+
+/* MESA_FORMAT_INTENSITY_F16 *************************************************/
+
+/* Fetch texel from 1D, 2D or 3D INTENSITY_FLOAT16 texture,
+ * returning 4 GLfloats.
+ */
+static void FETCH(f_intensity_f16)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLfloat *texel )
+{
+ const GLhalfARB *src = TEXEL_ADDR(GLhalfARB, texImage, i, j, k, 1);
+ texel[RCOMP] =
+ texel[GCOMP] =
+ texel[BCOMP] =
+ texel[ACOMP] = _mesa_half_to_float(src[0]);
+}
+
+#if DIM == 3
+static void store_texel_intensity_f16(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLfloat *rgba = (const GLfloat *) texel;
+ GLhalfARB *dst = TEXEL_ADDR(GLhalfARB, texImage, i, j, k, 1);
+ dst[0] = _mesa_float_to_half(rgba[RCOMP]);
+}
+#endif
+
+
+
+
+/*
+ * Begin Hardware formats
+ */
+
+/* MESA_FORMAT_RGBA8888 ******************************************************/
+
+/* Fetch texel from 1D, 2D or 3D rgba8888 texture, return 4 GLchans */
+static void FETCH(rgba8888)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLchan *texel )
+{
+ const GLuint s = *TEXEL_ADDR(GLuint, texImage, i, j, k, 1);
+ texel[RCOMP] = UBYTE_TO_CHAN( (s >> 24) );
+ texel[GCOMP] = UBYTE_TO_CHAN( (s >> 16) & 0xff );
+ texel[BCOMP] = UBYTE_TO_CHAN( (s >> 8) & 0xff );
+ texel[ACOMP] = UBYTE_TO_CHAN( (s ) & 0xff );
+}
+
+#if DIM == 3
+static void store_texel_rgba8888(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLubyte *rgba = (const GLubyte *) texel;
+ GLuint *dst = TEXEL_ADDR(GLuint, texImage, i, j, k, 1);
+ *dst = PACK_COLOR_8888(rgba[RCOMP], rgba[GCOMP], rgba[BCOMP], rgba[ACOMP]);
+}
+#endif
+
+
+/* MESA_FORMAT_RGBA888_REV ***************************************************/
+
+/* Fetch texel from 1D, 2D or 3D abgr8888 texture, return 4 GLchans */
+static void FETCH(rgba8888_rev)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLchan *texel )
+{
+ const GLuint s = *TEXEL_ADDR(GLuint, texImage, i, j, k, 1);
+ texel[RCOMP] = UBYTE_TO_CHAN( (s ) & 0xff );
+ texel[GCOMP] = UBYTE_TO_CHAN( (s >> 8) & 0xff );
+ texel[BCOMP] = UBYTE_TO_CHAN( (s >> 16) & 0xff );
+ texel[ACOMP] = UBYTE_TO_CHAN( (s >> 24) );
+}
+
+#if DIM == 3
+static void store_texel_rgba8888_rev(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLubyte *rgba = (const GLubyte *) texel;
+ GLuint *dst = TEXEL_ADDR(GLuint, texImage, i, j, k, 1);
+ *dst = PACK_COLOR_8888_REV(rgba[RCOMP], rgba[GCOMP], rgba[BCOMP], rgba[ACOMP]);
+}
+#endif
+
+
+/* MESA_FORMAT_ARGB8888 ******************************************************/
+
+/* Fetch texel from 1D, 2D or 3D argb8888 texture, return 4 GLchans */
+static void FETCH(argb8888)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLchan *texel )
+{
+ const GLuint s = *TEXEL_ADDR(GLuint, texImage, i, j, k, 1);
+ texel[RCOMP] = UBYTE_TO_CHAN( (s >> 16) & 0xff );
+ texel[GCOMP] = UBYTE_TO_CHAN( (s >> 8) & 0xff );
+ texel[BCOMP] = UBYTE_TO_CHAN( (s ) & 0xff );
+ texel[ACOMP] = UBYTE_TO_CHAN( (s >> 24) );
+}
+
+#if DIM == 3
+static void store_texel_argb8888(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLubyte *rgba = (const GLubyte *) texel;
+ GLuint *dst = TEXEL_ADDR(GLuint, texImage, i, j, k, 1);
+ *dst = PACK_COLOR_8888(rgba[ACOMP], rgba[RCOMP], rgba[GCOMP], rgba[BCOMP]);
+}
+#endif
+
+
+/* MESA_FORMAT_ARGB8888_REV **************************************************/
+
+/* Fetch texel from 1D, 2D or 3D argb8888_rev texture, return 4 GLchans */
+static void FETCH(argb8888_rev)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLchan *texel )
+{
+ const GLuint s = *TEXEL_ADDR(GLuint, texImage, i, j, k, 1);
+ texel[RCOMP] = UBYTE_TO_CHAN( (s >> 8) & 0xff );
+ texel[GCOMP] = UBYTE_TO_CHAN( (s >> 16) & 0xff );
+ texel[BCOMP] = UBYTE_TO_CHAN( (s >> 24) );
+ texel[ACOMP] = UBYTE_TO_CHAN( (s ) & 0xff );
+}
+
+#if DIM == 3
+static void store_texel_argb8888_rev(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLubyte *rgba = (const GLubyte *) texel;
+ GLuint *dst = TEXEL_ADDR(GLuint, texImage, i, j, k, 1);
+ *dst = PACK_COLOR_8888(rgba[ACOMP], rgba[RCOMP], rgba[GCOMP], rgba[BCOMP]);
+}
+#endif
+
+
+/* MESA_FORMAT_RGB888 ********************************************************/
+
+/* Fetch texel from 1D, 2D or 3D rgb888 texture, return 4 GLchans */
+static void FETCH(rgb888)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLchan *texel )
+{
+ const GLubyte *src = TEXEL_ADDR(GLubyte, texImage, i, j, k, 3);
+ texel[RCOMP] = UBYTE_TO_CHAN( src[2] );
+ texel[GCOMP] = UBYTE_TO_CHAN( src[1] );
+ texel[BCOMP] = UBYTE_TO_CHAN( src[0] );
+ texel[ACOMP] = CHAN_MAX;
+}
+
+#if DIM == 3
+static void store_texel_rgb888(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLubyte *rgba = (const GLubyte *) texel;
+ GLubyte *dst = TEXEL_ADDR(GLubyte, texImage, i, j, k, 3);
+ dst[0] = rgba[RCOMP];
+ dst[1] = rgba[GCOMP];
+ dst[2] = rgba[BCOMP];
+}
+#endif
+
+
+/* MESA_FORMAT_BGR888 ********************************************************/
+
+/* Fetch texel from 1D, 2D or 3D bgr888 texture, return 4 GLchans */
+static void FETCH(bgr888)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLchan *texel )
+{
+ const GLubyte *src = TEXEL_ADDR(GLubyte, texImage, i, j, k, 3);
+ texel[RCOMP] = UBYTE_TO_CHAN( src[0] );
+ texel[GCOMP] = UBYTE_TO_CHAN( src[1] );
+ texel[BCOMP] = UBYTE_TO_CHAN( src[2] );
+ texel[ACOMP] = CHAN_MAX;
+}
+
+#if DIM == 3
+static void store_texel_bgr888(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLubyte *rgba = (const GLubyte *) texel;
+ GLubyte *dst = TEXEL_ADDR(GLubyte, texImage, i, j, k, 3);
+ dst[0] = rgba[BCOMP];
+ dst[1] = rgba[GCOMP];
+ dst[2] = rgba[RCOMP];
+}
+#endif
+
+
+/* use color expansion like (g << 2) | (g >> 4) (does somewhat random rounding)
+ instead of slow (g << 2) * 255 / 252 (always rounds down) */
+
+/* MESA_FORMAT_RGB565 ********************************************************/
+
+/* Fetch texel from 1D, 2D or 3D rgb565 texture, return 4 GLchans */
+static void FETCH(rgb565)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLchan *texel )
+{
+ const GLushort *src = TEXEL_ADDR(GLushort, texImage, i, j, k, 1);
+ const GLushort s = *src;
+ texel[RCOMP] = UBYTE_TO_CHAN( ((s >> 8) & 0xf8) | ((s >> 13) & 0x7) );
+ texel[GCOMP] = UBYTE_TO_CHAN( ((s >> 3) & 0xfc) | ((s >> 9) & 0x3) );
+ texel[BCOMP] = UBYTE_TO_CHAN( ((s << 3) & 0xf8) | ((s >> 2) & 0x7) );
+ texel[ACOMP] = CHAN_MAX;
+}
+
+#if DIM == 3
+static void store_texel_rgb565(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLubyte *rgba = (const GLubyte *) texel;
+ GLushort *dst = TEXEL_ADDR(GLushort, texImage, i, j, k, 1);
+ *dst = PACK_COLOR_565(rgba[RCOMP], rgba[GCOMP], rgba[BCOMP]);
+}
+#endif
+
+
+/* MESA_FORMAT_RGB565_REV ****************************************************/
+
+/* Fetch texel from 1D, 2D or 3D rgb565_rev texture, return 4 GLchans */
+static void FETCH(rgb565_rev)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLchan *texel )
+{
+ const GLushort *src = TEXEL_ADDR(GLushort, texImage, i, j, k, 1);
+ const GLushort s = (*src >> 8) | (*src << 8); /* byte swap */
+ texel[RCOMP] = UBYTE_TO_CHAN( ((s >> 8) & 0xf8) | ((s >> 13) & 0x7) );
+ texel[GCOMP] = UBYTE_TO_CHAN( ((s >> 3) & 0xfc) | ((s >> 9) & 0x3) );
+ texel[BCOMP] = UBYTE_TO_CHAN( ((s << 3) & 0xf8) | ((s >> 2) & 0x7) );
+ texel[ACOMP] = CHAN_MAX;
+}
+
+#if DIM == 3
+static void store_texel_rgb565_rev(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLubyte *rgba = (const GLubyte *) texel;
+ GLushort *dst = TEXEL_ADDR(GLushort, texImage, i, j, k, 1);
+ *dst = PACK_COLOR_565(rgba[BCOMP], rgba[GCOMP], rgba[RCOMP]);
+}
+#endif
+
+
+/* MESA_FORMAT_ARGB4444 ******************************************************/
+
+/* Fetch texel from 1D, 2D or 3D argb444 texture, return 4 GLchans */
+static void FETCH(argb4444)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLchan *texel )
+{
+ const GLushort *src = TEXEL_ADDR(GLushort, texImage, i, j, k, 1);
+ const GLushort s = *src;
+ texel[RCOMP] = UBYTE_TO_CHAN( ((s >> 8) & 0xf) | ((s >> 4) & 0xf0) );
+ texel[GCOMP] = UBYTE_TO_CHAN( ((s >> 4) & 0xf) | ((s ) & 0xf0) );
+ texel[BCOMP] = UBYTE_TO_CHAN( ((s ) & 0xf) | ((s << 4) & 0xf0) );
+ texel[ACOMP] = UBYTE_TO_CHAN( ((s >> 12) & 0xf) | ((s >> 8) & 0xf0) );
+}
+
+#if DIM == 3
+static void store_texel_argb4444(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLubyte *rgba = (const GLubyte *) texel;
+ GLushort *dst = TEXEL_ADDR(GLushort, texImage, i, j, k, 1);
+ *dst = PACK_COLOR_4444(rgba[RCOMP], rgba[GCOMP], rgba[BCOMP], rgba[ACOMP]);
+}
+#endif
+
+
+/* MESA_FORMAT_ARGB4444_REV **************************************************/
+
+/* Fetch texel from 1D, 2D or 3D argb4444_rev texture, return 4 GLchans */
+static void FETCH(argb4444_rev)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLchan *texel )
+{
+ const GLushort s = *TEXEL_ADDR(GLushort, texImage, i, j, k, 1);
+ texel[RCOMP] = UBYTE_TO_CHAN( ((s ) & 0xf) | ((s << 4) & 0xf0) );
+ texel[GCOMP] = UBYTE_TO_CHAN( ((s >> 12) & 0xf) | ((s >> 8) & 0xf0) );
+ texel[BCOMP] = UBYTE_TO_CHAN( ((s >> 8) & 0xf) | ((s >> 4) & 0xf0) );
+ texel[ACOMP] = UBYTE_TO_CHAN( ((s >> 4) & 0xf) | ((s ) & 0xf0) );
+}
+
+#if DIM == 3
+static void store_texel_argb4444_rev(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLubyte *rgba = (const GLubyte *) texel;
+ GLushort *dst = TEXEL_ADDR(GLushort, texImage, i, j, k, 1);
+ *dst = PACK_COLOR_4444(rgba[ACOMP], rgba[BCOMP], rgba[GCOMP], rgba[RCOMP]);
+}
+#endif
+
+
+/* MESA_FORMAT_ARGB1555 ******************************************************/
+
+/* Fetch texel from 1D, 2D or 3D argb1555 texture, return 4 GLchans */
+static void FETCH(argb1555)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLchan *texel )
+{
+ const GLushort *src = TEXEL_ADDR(GLushort, texImage, i, j, k, 1);
+ const GLushort s = *src;
+ texel[RCOMP] = UBYTE_TO_CHAN( ((s >> 7) & 0xf8) | ((s >> 12) & 0x7) );
+ texel[GCOMP] = UBYTE_TO_CHAN( ((s >> 2) & 0xf8) | ((s >> 7) & 0x7) );
+ texel[BCOMP] = UBYTE_TO_CHAN( ((s << 3) & 0xf8) | ((s >> 2) & 0x7) );
+ texel[ACOMP] = UBYTE_TO_CHAN( ((s >> 15) & 0x01) * 255 );
+}
+
+#if DIM == 3
+static void store_texel_argb1555(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLubyte *rgba = (const GLubyte *) texel;
+ GLushort *dst = TEXEL_ADDR(GLushort, texImage, i, j, k, 1);
+ *dst = PACK_COLOR_1555(rgba[ACOMP], rgba[RCOMP], rgba[GCOMP], rgba[BCOMP]);
+}
+#endif
+
+
+/* MESA_FORMAT_ARGB1555_REV **************************************************/
+
+/* Fetch texel from 1D, 2D or 3D argb1555_rev texture, return 4 GLchans */
+static void FETCH(argb1555_rev)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLchan *texel )
+{
+ const GLushort *src = TEXEL_ADDR(GLushort, texImage, i, j, k, 1);
+ const GLushort s = (*src << 8) | (*src >> 8); /* byteswap */
+ texel[RCOMP] = UBYTE_TO_CHAN( ((s >> 7) & 0xf8) | ((s >> 12) & 0x7) );
+ texel[GCOMP] = UBYTE_TO_CHAN( ((s >> 2) & 0xf8) | ((s >> 7) & 0x7) );
+ texel[BCOMP] = UBYTE_TO_CHAN( ((s << 3) & 0xf8) | ((s >> 2) & 0x7) );
+ texel[ACOMP] = UBYTE_TO_CHAN( ((s >> 15) & 0x01) * 255 );
+}
+
+#if DIM == 3
+static void store_texel_argb1555_rev(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLubyte *rgba = (const GLubyte *) texel;
+ GLushort *dst = TEXEL_ADDR(GLushort, texImage, i, j, k, 1);
+ *dst = PACK_COLOR_1555_REV(rgba[ACOMP], rgba[RCOMP], rgba[GCOMP], rgba[BCOMP]);
+}
+#endif
+
+
+/* MESA_FORMAT_AL88 **********************************************************/
+
+/* Fetch texel from 1D, 2D or 3D al88 texture, return 4 GLchans */
+static void FETCH(al88)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLchan *texel )
+{
+ const GLushort s = *TEXEL_ADDR(GLushort, texImage, i, j, k, 1);
+ texel[RCOMP] =
+ texel[GCOMP] =
+ texel[BCOMP] = UBYTE_TO_CHAN( s & 0xff );
+ texel[ACOMP] = UBYTE_TO_CHAN( s >> 8 );
+}
+
+#if DIM == 3
+static void store_texel_al88(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLubyte *rgba = (const GLubyte *) texel;
+ GLushort *dst = TEXEL_ADDR(GLushort, texImage, i, j, k, 1);
+ *dst = PACK_COLOR_88(rgba[ACOMP], rgba[RCOMP]);
+}
+#endif
+
+
+/* MESA_FORMAT_AL88_REV ******************************************************/
+
+/* Fetch texel from 1D, 2D or 3D al88_rev texture, return 4 GLchans */
+static void FETCH(al88_rev)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLchan *texel )
+{
+ const GLushort s = *TEXEL_ADDR(GLushort, texImage, i, j, k, 1);
+ texel[RCOMP] =
+ texel[GCOMP] =
+ texel[BCOMP] = UBYTE_TO_CHAN( s >> 8 );
+ texel[ACOMP] = UBYTE_TO_CHAN( s & 0xff );
+}
+
+#if DIM == 3
+static void store_texel_al88_rev(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLubyte *rgba = (const GLubyte *) texel;
+ GLushort *dst = TEXEL_ADDR(GLushort, texImage, i, j, k, 1);
+ *dst = PACK_COLOR_88(rgba[RCOMP], rgba[ACOMP]);
+}
+#endif
+
+
+/* MESA_FORMAT_RGB332 ********************************************************/
+
+/* Fetch texel from 1D, 2D or 3D rgb332 texture, return 4 GLchans */
+static void FETCH(rgb332)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLchan *texel )
+{
+ static const GLubyte lut2to8[4] = {0, 85, 170, 255};
+ static const GLubyte lut3to8[8] = {0, 36, 73, 109, 146, 182, 219, 255};
+ const GLubyte *src = TEXEL_ADDR(GLubyte, texImage, i, j, k, 1);
+ const GLubyte s = *src;
+ texel[RCOMP] = UBYTE_TO_CHAN( lut3to8[(s >> 5) & 0x7] );
+ texel[GCOMP] = UBYTE_TO_CHAN( lut3to8[(s >> 2) & 0x7] );
+ texel[BCOMP] = UBYTE_TO_CHAN( lut2to8[(s ) & 0x3] );
+ texel[ACOMP] = CHAN_MAX;
+}
+
+#if DIM == 3
+static void store_texel_rgb332(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLubyte *rgba = (const GLubyte *) texel;
+ GLubyte *dst = TEXEL_ADDR(GLubyte, texImage, i, j, k, 1);
+ *dst = PACK_COLOR_332(rgba[RCOMP], rgba[GCOMP], rgba[BCOMP]);
+}
+#endif
+
+
+/* MESA_FORMAT_A8 ************************************************************/
+
+/* Fetch texel from 1D, 2D or 3D a8 texture, return 4 GLchans */
+static void FETCH(a8)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLchan *texel )
+{
+ const GLubyte *src = TEXEL_ADDR(GLubyte, texImage, i, j, k, 1);
+ texel[RCOMP] =
+ texel[GCOMP] =
+ texel[BCOMP] = 0;
+ texel[ACOMP] = UBYTE_TO_CHAN( src[0] );
+}
+
+#if DIM == 3
+static void store_texel_a8(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLubyte *rgba = (const GLubyte *) texel;
+ GLubyte *dst = TEXEL_ADDR(GLubyte, texImage, i, j, k, 1);
+ *dst = rgba[ACOMP];
+}
+#endif
+
+
+/* MESA_FORMAT_L8 ************************************************************/
+
+/* Fetch texel from 1D, 2D or 3D l8 texture, return 4 GLchans */
+static void FETCH(l8)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLchan *texel )
+{
+ const GLubyte *src = TEXEL_ADDR(GLubyte, texImage, i, j, k, 1);
+ texel[RCOMP] =
+ texel[GCOMP] =
+ texel[BCOMP] = UBYTE_TO_CHAN( src[0] );
+ texel[ACOMP] = CHAN_MAX;
+}
+
+#if DIM == 3
+static void store_texel_l8(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLubyte *rgba = (const GLubyte *) texel;
+ GLubyte *dst = TEXEL_ADDR(GLubyte, texImage, i, j, k, 1);
+ *dst = rgba[RCOMP];
+}
+#endif
+
+
+/* MESA_FORMAT_I8 ************************************************************/
+
+/* Fetch texel from 1D, 2D or 3D i8 texture, return 4 GLchans */
+static void FETCH(i8)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLchan *texel )
+{
+ const GLubyte *src = TEXEL_ADDR(GLubyte, texImage, i, j, k, 1);
+ texel[RCOMP] =
+ texel[GCOMP] =
+ texel[BCOMP] =
+ texel[ACOMP] = UBYTE_TO_CHAN( src[0] );
+}
+
+#if DIM == 3
+static void store_texel_i8(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLubyte *rgba = (const GLubyte *) texel;
+ GLubyte *dst = TEXEL_ADDR(GLubyte, texImage, i, j, k, 1);
+ *dst = rgba[RCOMP];
+}
+#endif
+
+
+/* MESA_FORMAT_CI8 ***********************************************************/
+
+/* Fetch CI texel from 1D, 2D or 3D ci8 texture, lookup the index in a
+ * color table, and return 4 GLchans.
+ */
+static void FETCH(ci8)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLchan *texel )
+{
+ const GLubyte *src = TEXEL_ADDR(GLubyte, texImage, i, j, k, 1);
+ const struct gl_color_table *palette;
+ GLuint index;
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (ctx->Texture.SharedPalette) {
+ palette = &ctx->Texture.Palette;
+ }
+ else {
+ palette = &texImage->TexObject->Palette;
+ }
+ if (palette->Size == 0)
+ return; /* undefined results */
+
+ /* Mask the index against size of palette to avoid going out of bounds */
+ index = (*src) & (palette->Size - 1);
+
+ if (palette->Type == GL_FLOAT) {
+ const GLfloat *ftable = (const GLfloat *) palette->Table;
+ switch (palette->_BaseFormat) {
+ case GL_ALPHA:
+ texel[RCOMP] =
+ texel[GCOMP] =
+ texel[BCOMP] = 0;
+ texel[ACOMP] = (GLchan) (ftable[index] * CHAN_MAX);
+ return;
+ case GL_LUMINANCE:
+ texel[RCOMP] =
+ texel[GCOMP] =
+ texel[BCOMP] = (GLchan) (ftable[index] * CHAN_MAX);
+ texel[ACOMP] = CHAN_MAX;
+ break;
+ case GL_INTENSITY:
+ texel[RCOMP] =
+ texel[GCOMP] =
+ texel[BCOMP] =
+ texel[ACOMP] = ftable[index] * CHAN_MAX;
+ return;
+ case GL_LUMINANCE_ALPHA:
+ texel[RCOMP] =
+ texel[GCOMP] =
+ texel[BCOMP] = (GLchan) (ftable[index * 2 + 0] * CHAN_MAX);
+ texel[ACOMP] = (GLchan) (ftable[index * 2 + 1] * CHAN_MAX);
+ return;
+ case GL_RGB:
+ texel[RCOMP] = (GLchan) (ftable[index * 3 + 0] * CHAN_MAX);
+ texel[GCOMP] = (GLchan) (ftable[index * 3 + 1] * CHAN_MAX);
+ texel[BCOMP] = (GLchan) (ftable[index * 3 + 2] * CHAN_MAX);
+ texel[ACOMP] = CHAN_MAX;
+ return;
+ case GL_RGBA:
+ texel[RCOMP] = (GLchan) (ftable[index * 4 + 0] * CHAN_MAX);
+ texel[GCOMP] = (GLchan) (ftable[index * 4 + 1] * CHAN_MAX);
+ texel[BCOMP] = (GLchan) (ftable[index * 4 + 2] * CHAN_MAX);
+ texel[ACOMP] = (GLchan) (ftable[index * 4 + 3] * CHAN_MAX);
+ return;
+ default:
+ _mesa_problem(ctx, "Bad palette format in fetch_texel_ci8");
+ }
+ }
+ else {
+ const GLchan *table = (const GLchan *) palette->Table;
+ switch (palette->_BaseFormat) {
+ case GL_ALPHA:
+ texel[RCOMP] =
+ texel[GCOMP] =
+ texel[BCOMP] = 0;
+ texel[ACOMP] = table[index];
+ return;
+ case GL_LUMINANCE:
+ texel[RCOMP] =
+ texel[GCOMP] =
+ texel[BCOMP] = table[index];
+ texel[ACOMP] = CHAN_MAX;
+ break;
+ case GL_INTENSITY:
+ texel[RCOMP] =
+ texel[GCOMP] =
+ texel[BCOMP] =
+ texel[ACOMP] = table[index];
+ return;
+ case GL_LUMINANCE_ALPHA:
+ texel[RCOMP] =
+ texel[GCOMP] =
+ texel[BCOMP] = table[index * 2 + 0];
+ texel[ACOMP] = table[index * 2 + 1];
+ return;
+ case GL_RGB:
+ texel[RCOMP] = table[index * 3 + 0];
+ texel[GCOMP] = table[index * 3 + 1];
+ texel[BCOMP] = table[index * 3 + 2];
+ texel[ACOMP] = CHAN_MAX;
+ return;
+ case GL_RGBA:
+ texel[RCOMP] = table[index * 4 + 0];
+ texel[GCOMP] = table[index * 4 + 1];
+ texel[BCOMP] = table[index * 4 + 2];
+ texel[ACOMP] = table[index * 4 + 3];
+ return;
+ default:
+ _mesa_problem(ctx, "Bad palette format in fetch_texel_ci8");
+ }
+ }
+}
+
+#if DIM == 3
+static void store_texel_ci8(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ const GLubyte *index = (const GLubyte *) texel;
+ GLubyte *dst = TEXEL_ADDR(GLubyte, texImage, i, j, k, 1);
+ *dst = *index;
+}
+#endif
+
+
+/* MESA_FORMAT_YCBCR *********************************************************/
+
+/* Fetch texel from 1D, 2D or 3D ycbcr texture, return 4 GLchans */
+/* We convert YCbCr to RGB here */
+/* XXX this may break if GLchan != GLubyte */
+static void FETCH(ycbcr)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLchan *texel )
+{
+ const GLushort *src0 = TEXEL_ADDR(GLushort, texImage, (i & ~1), j, k, 1); /* even */
+ const GLushort *src1 = src0 + 1; /* odd */
+ const GLubyte y0 = (*src0 >> 8) & 0xff; /* luminance */
+ const GLubyte cb = *src0 & 0xff; /* chroma U */
+ const GLubyte y1 = (*src1 >> 8) & 0xff; /* luminance */
+ const GLubyte cr = *src1 & 0xff; /* chroma V */
+ GLint r, g, b;
+ if (i & 1) {
+ /* odd pixel: use y1,cr,cb */
+ r = (GLint) (1.164 * (y1-16) + 1.596 * (cr-128));
+ g = (GLint) (1.164 * (y1-16) - 0.813 * (cr-128) - 0.391 * (cb-128));
+ b = (GLint) (1.164 * (y1-16) + 2.018 * (cb-128));
+ }
+ else {
+ /* even pixel: use y0,cr,cb */
+ r = (GLint) (1.164 * (y0-16) + 1.596 * (cr-128));
+ g = (GLint) (1.164 * (y0-16) - 0.813 * (cr-128) - 0.391 * (cb-128));
+ b = (GLint) (1.164 * (y0-16) + 2.018 * (cb-128));
+ }
+ texel[RCOMP] = CLAMP(r, 0, CHAN_MAX);
+ texel[GCOMP] = CLAMP(g, 0, CHAN_MAX);
+ texel[BCOMP] = CLAMP(b, 0, CHAN_MAX);
+ texel[ACOMP] = CHAN_MAX;
+}
+
+#if DIM == 3
+static void store_texel_ycbcr(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ /* XXX to do */
+}
+#endif
+
+
+/* MESA_FORMAT_YCBCR_REV *****************************************************/
+
+/* Fetch texel from 1D, 2D or 3D ycbcr_rev texture, return 4 GLchans */
+/* We convert YCbCr to RGB here */
+/* XXX this may break if GLchan != GLubyte */
+static void FETCH(ycbcr_rev)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLchan *texel )
+{
+ const GLushort *src0 = TEXEL_ADDR(GLushort, texImage, (i & ~1), j, k, 1); /* even */
+ const GLushort *src1 = src0 + 1; /* odd */
+ const GLubyte y0 = *src0 & 0xff; /* luminance */
+ const GLubyte cr = (*src0 >> 8) & 0xff; /* chroma V */
+ const GLubyte y1 = *src1 & 0xff; /* luminance */
+ const GLubyte cb = (*src1 >> 8) & 0xff; /* chroma U */
+ GLint r, g, b;
+ if (i & 1) {
+ /* odd pixel: use y1,cr,cb */
+ r = (GLint) (1.164 * (y1-16) + 1.596 * (cr-128));
+ g = (GLint) (1.164 * (y1-16) - 0.813 * (cr-128) - 0.391 * (cb-128));
+ b = (GLint) (1.164 * (y1-16) + 2.018 * (cb-128));
+ }
+ else {
+ /* even pixel: use y0,cr,cb */
+ r = (GLint) (1.164 * (y0-16) + 1.596 * (cr-128));
+ g = (GLint) (1.164 * (y0-16) - 0.813 * (cr-128) - 0.391 * (cb-128));
+ b = (GLint) (1.164 * (y0-16) + 2.018 * (cb-128));
+ }
+ texel[RCOMP] = CLAMP(r, 0, CHAN_MAX);
+ texel[GCOMP] = CLAMP(g, 0, CHAN_MAX);
+ texel[BCOMP] = CLAMP(b, 0, CHAN_MAX);
+ texel[ACOMP] = CHAN_MAX;
+}
+
+#if DIM == 3
+static void store_texel_ycbcr_rev(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ /* XXX to do */
+}
+#endif
+
+
+/* MESA_TEXFORMAT_Z24_S8 ***************************************************/
+
+static void FETCH(f_z24_s8)( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLfloat *texel )
+{
+ /* only return Z, not stencil data */
+ const GLuint *src = TEXEL_ADDR(GLuint, texImage, i, j, k, 1);
+ const GLfloat scale = 1.0F / (GLfloat) 0xffffff;
+ texel[0] = ((*src) >> 8) * scale;
+ ASSERT(texImage->TexFormat->MesaFormat == MESA_FORMAT_Z24_S8);
+ ASSERT(texel[0] >= 0.0F);
+ ASSERT(texel[0] <= 1.0F);
+}
+
+#if DIM == 3
+static void store_texel_z24_s8(struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, const void *texel)
+{
+ /* only store Z, not stencil */
+ GLuint *dst = TEXEL_ADDR(GLuint, texImage, i, j, k, 1);
+ GLfloat depth = *((GLfloat *) texel);
+ GLuint zi = ((GLuint) (depth * 0xffffff)) << 8;
+ *dst = zi | (*dst & 0xff);
+}
+#endif
+
+
+
+#undef TEXEL_ADDR
+#undef DIM
+#undef FETCH
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
new file mode 100644
index 00000000000..ff1d51d7d09
--- /dev/null
+++ b/src/mesa/main/teximage.c
@@ -0,0 +1,3451 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/**
+ * \file teximage.c
+ * Texture image-related functions.
+ */
+
+
+#include "glheader.h"
+#include "bufferobj.h"
+#include "context.h"
+#include "convolve.h"
+#include "fbobject.h"
+#include "framebuffer.h"
+#include "image.h"
+#include "imports.h"
+#include "macros.h"
+#include "state.h"
+#include "texcompress.h"
+#include "texformat.h"
+#include "teximage.h"
+#include "texstate.h"
+#include "texstore.h"
+#include "mtypes.h"
+
+
+/**
+ * We allocate texture memory on 512-byte boundaries so we can use MMX/SSE
+ * elsewhere.
+ */
+void *
+_mesa_alloc_texmemory(GLsizei bytes)
+{
+ return _mesa_align_malloc(bytes, 512);
+}
+
+
+/**
+ * Free texture memory allocated with _mesa_alloc_texmemory()
+ */
+void
+_mesa_free_texmemory(void *m)
+{
+ _mesa_align_free(m);
+}
+
+
+
+
+#if 0
+static void PrintTexture(GLcontext *ctx, const struct gl_texture_image *img)
+{
+#if CHAN_TYPE == GL_FLOAT
+ _mesa_problem(NULL, "PrintTexture doesn't support float channels");
+#else
+ GLuint i, j, c;
+ const GLchan *data = (const GLchan *) img->Data;
+
+ if (!data) {
+ _mesa_printf("No texture data\n");
+ return;
+ }
+
+ switch (img->Format) {
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_INTENSITY:
+ case GL_COLOR_INDEX:
+ c = 1;
+ break;
+ case GL_LUMINANCE_ALPHA:
+ c = 2;
+ break;
+ case GL_RGB:
+ c = 3;
+ break;
+ case GL_RGBA:
+ c = 4;
+ break;
+ default:
+ _mesa_problem(NULL, "error in PrintTexture\n");
+ return;
+ }
+
+ for (i = 0; i < img->Height; i++) {
+ for (j = 0; j < img->Width; j++) {
+ if (c==1)
+ _mesa_printf("%02x ", data[0]);
+ else if (c==2)
+ _mesa_printf("%02x%02x ", data[0], data[1]);
+ else if (c==3)
+ _mesa_printf("%02x%02x%02x ", data[0], data[1], data[2]);
+ else if (c==4)
+ _mesa_printf("%02x%02x%02x%02x ", data[0], data[1], data[2], data[3]);
+ data += (img->RowStride - img->Width) * c;
+ }
+ /* XXX use img->ImageStride here */
+ _mesa_printf("\n");
+ }
+#endif
+}
+#endif
+
+
+/*
+ * Compute floor(log_base_2(n)).
+ * If n < 0 return -1.
+ */
+static int
+logbase2( int n )
+{
+ GLint i = 1;
+ GLint log2 = 0;
+
+ if (n < 0)
+ return -1;
+
+ if (n == 0)
+ return 0;
+
+ while ( n > i ) {
+ i *= 2;
+ log2++;
+ }
+ if (i != n) {
+ return log2 - 1;
+ }
+ else {
+ return log2;
+ }
+}
+
+
+
+/**
+ * Return the simple base format for a given internal texture format.
+ * For example, given GL_LUMINANCE12_ALPHA4, return GL_LUMINANCE_ALPHA.
+ *
+ * \param ctx GL context.
+ * \param internalFormat the internal texture format token or 1, 2, 3, or 4.
+ *
+ * \return the corresponding \u base internal format (GL_ALPHA, GL_LUMINANCE,
+ * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA), or -1 if invalid enum.
+ *
+ * This is the format which is used during texture application (i.e. the
+ * texture format and env mode determine the arithmetic used.
+ */
+GLint
+_mesa_base_tex_format( GLcontext *ctx, GLint internalFormat )
+{
+ switch (internalFormat) {
+ case GL_ALPHA:
+ case GL_ALPHA4:
+ case GL_ALPHA8:
+ case GL_ALPHA12:
+ case GL_ALPHA16:
+ return GL_ALPHA;
+ case 1:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE4:
+ case GL_LUMINANCE8:
+ case GL_LUMINANCE12:
+ case GL_LUMINANCE16:
+ return GL_LUMINANCE;
+ case 2:
+ case GL_LUMINANCE_ALPHA:
+ case GL_LUMINANCE4_ALPHA4:
+ case GL_LUMINANCE6_ALPHA2:
+ case GL_LUMINANCE8_ALPHA8:
+ case GL_LUMINANCE12_ALPHA4:
+ case GL_LUMINANCE12_ALPHA12:
+ case GL_LUMINANCE16_ALPHA16:
+ return GL_LUMINANCE_ALPHA;
+ case GL_INTENSITY:
+ case GL_INTENSITY4:
+ case GL_INTENSITY8:
+ case GL_INTENSITY12:
+ case GL_INTENSITY16:
+ return GL_INTENSITY;
+ case 3:
+ case GL_RGB:
+ case GL_R3_G3_B2:
+ case GL_RGB4:
+ case GL_RGB5:
+ case GL_RGB8:
+ case GL_RGB10:
+ case GL_RGB12:
+ case GL_RGB16:
+ return GL_RGB;
+ case 4:
+ case GL_RGBA:
+ case GL_RGBA2:
+ case GL_RGBA4:
+ case GL_RGB5_A1:
+ case GL_RGBA8:
+ case GL_RGB10_A2:
+ case GL_RGBA12:
+ case GL_RGBA16:
+ return GL_RGBA;
+ default:
+ ; /* fallthrough */
+ }
+
+ if (ctx->Extensions.EXT_paletted_texture) {
+ switch (internalFormat) {
+ case GL_COLOR_INDEX:
+ case GL_COLOR_INDEX1_EXT:
+ case GL_COLOR_INDEX2_EXT:
+ case GL_COLOR_INDEX4_EXT:
+ case GL_COLOR_INDEX8_EXT:
+ case GL_COLOR_INDEX12_EXT:
+ case GL_COLOR_INDEX16_EXT:
+ return GL_COLOR_INDEX;
+ default:
+ ; /* fallthrough */
+ }
+ }
+
+ if (ctx->Extensions.SGIX_depth_texture ||
+ ctx->Extensions.ARB_depth_texture) {
+ switch (internalFormat) {
+ case GL_DEPTH_COMPONENT:
+ case GL_DEPTH_COMPONENT16_SGIX:
+ case GL_DEPTH_COMPONENT24_SGIX:
+ case GL_DEPTH_COMPONENT32_SGIX:
+ return GL_DEPTH_COMPONENT;
+ default:
+ ; /* fallthrough */
+ }
+ }
+
+ if (ctx->Extensions.ARB_texture_compression) {
+ switch (internalFormat) {
+ case GL_COMPRESSED_ALPHA:
+ return GL_ALPHA;
+ case GL_COMPRESSED_LUMINANCE:
+ return GL_LUMINANCE;
+ case GL_COMPRESSED_LUMINANCE_ALPHA:
+ return GL_LUMINANCE_ALPHA;
+ case GL_COMPRESSED_INTENSITY:
+ return GL_INTENSITY;
+ case GL_COMPRESSED_RGB:
+ return GL_RGB;
+ case GL_COMPRESSED_RGBA:
+ return GL_RGBA;
+ default:
+ ; /* fallthrough */
+ }
+ }
+
+ if (ctx->Extensions.TDFX_texture_compression_FXT1) {
+ switch (internalFormat) {
+ case GL_COMPRESSED_RGB_FXT1_3DFX:
+ return GL_RGB;
+ case GL_COMPRESSED_RGBA_FXT1_3DFX:
+ return GL_RGBA;
+ default:
+ ; /* fallthrough */
+ }
+ }
+
+ if (ctx->Extensions.EXT_texture_compression_s3tc) {
+ switch (internalFormat) {
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ return GL_RGB;
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ return GL_RGBA;
+ default:
+ ; /* fallthrough */
+ }
+ }
+
+ if (ctx->Extensions.S3_s3tc) {
+ switch (internalFormat) {
+ case GL_RGB_S3TC:
+ case GL_RGB4_S3TC:
+ return GL_RGB;
+ case GL_RGBA_S3TC:
+ case GL_RGBA4_S3TC:
+ return GL_RGBA;
+ default:
+ ; /* fallthrough */
+ }
+ }
+
+ if (ctx->Extensions.MESA_ycbcr_texture) {
+ if (internalFormat == GL_YCBCR_MESA)
+ return GL_YCBCR_MESA;
+ }
+
+ if (ctx->Extensions.ARB_texture_float) {
+ switch (internalFormat) {
+ case GL_ALPHA16F_ARB:
+ case GL_ALPHA32F_ARB:
+ return GL_ALPHA;
+ case GL_RGBA16F_ARB:
+ case GL_RGBA32F_ARB:
+ return GL_RGBA;
+ case GL_RGB16F_ARB:
+ case GL_RGB32F_ARB:
+ return GL_RGB;
+ case GL_INTENSITY16F_ARB:
+ case GL_INTENSITY32F_ARB:
+ return GL_INTENSITY;
+ case GL_LUMINANCE16F_ARB:
+ case GL_LUMINANCE32F_ARB:
+ return GL_LUMINANCE;
+ case GL_LUMINANCE_ALPHA16F_ARB:
+ case GL_LUMINANCE_ALPHA32F_ARB:
+ return GL_LUMINANCE_ALPHA;
+ default:
+ ; /* fallthrough */
+ }
+ }
+
+ if (ctx->Extensions.EXT_packed_depth_stencil) {
+ switch (internalFormat) {
+ case GL_DEPTH_STENCIL_EXT:
+ case GL_DEPTH24_STENCIL8_EXT:
+ return GL_DEPTH_STENCIL_EXT;
+ default:
+ ; /* fallthrough */
+ }
+ }
+
+ return -1; /* error */
+}
+
+
+/**
+ * Test if the given image format is a color/RGBA format (i.e., not color
+ * index, depth, stencil, etc).
+ * \param format the image format value (may by an internal texture format)
+ * \return GL_TRUE if its a color/RGBA format, GL_FALSE otherwise.
+ */
+static GLboolean
+is_color_format(GLenum format)
+{
+ switch (format) {
+ case GL_RED:
+ case GL_GREEN:
+ case GL_BLUE:
+ case GL_ALPHA:
+ case GL_ALPHA4:
+ case GL_ALPHA8:
+ case GL_ALPHA12:
+ case GL_ALPHA16:
+ case 1:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE4:
+ case GL_LUMINANCE8:
+ case GL_LUMINANCE12:
+ case GL_LUMINANCE16:
+ case 2:
+ case GL_LUMINANCE_ALPHA:
+ case GL_LUMINANCE4_ALPHA4:
+ case GL_LUMINANCE6_ALPHA2:
+ case GL_LUMINANCE8_ALPHA8:
+ case GL_LUMINANCE12_ALPHA4:
+ case GL_LUMINANCE12_ALPHA12:
+ case GL_LUMINANCE16_ALPHA16:
+ case GL_INTENSITY:
+ case GL_INTENSITY4:
+ case GL_INTENSITY8:
+ case GL_INTENSITY12:
+ case GL_INTENSITY16:
+ case 3:
+ case GL_RGB:
+ case GL_BGR:
+ case GL_R3_G3_B2:
+ case GL_RGB4:
+ case GL_RGB5:
+ case GL_RGB8:
+ case GL_RGB10:
+ case GL_RGB12:
+ case GL_RGB16:
+ case 4:
+ case GL_ABGR_EXT:
+ case GL_RGBA:
+ case GL_BGRA:
+ case GL_RGBA2:
+ case GL_RGBA4:
+ case GL_RGB5_A1:
+ case GL_RGBA8:
+ case GL_RGB10_A2:
+ case GL_RGBA12:
+ case GL_RGBA16:
+ /* float texture formats */
+ case GL_ALPHA16F_ARB:
+ case GL_ALPHA32F_ARB:
+ case GL_LUMINANCE16F_ARB:
+ case GL_LUMINANCE32F_ARB:
+ case GL_LUMINANCE_ALPHA16F_ARB:
+ case GL_LUMINANCE_ALPHA32F_ARB:
+ case GL_INTENSITY16F_ARB:
+ case GL_INTENSITY32F_ARB:
+ case GL_RGB16F_ARB:
+ case GL_RGB32F_ARB:
+ case GL_RGBA16F_ARB:
+ case GL_RGBA32F_ARB:
+ /* compressed formats */
+ case GL_COMPRESSED_ALPHA:
+ case GL_COMPRESSED_LUMINANCE:
+ case GL_COMPRESSED_LUMINANCE_ALPHA:
+ case GL_COMPRESSED_INTENSITY:
+ case GL_COMPRESSED_RGB:
+ case GL_COMPRESSED_RGBA:
+ case GL_RGB_S3TC:
+ case GL_RGB4_S3TC:
+ case GL_RGBA_S3TC:
+ case GL_RGBA4_S3TC:
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ case GL_COMPRESSED_RGB_FXT1_3DFX:
+ case GL_COMPRESSED_RGBA_FXT1_3DFX:
+ return GL_TRUE;
+ case GL_YCBCR_MESA: /* not considered to be RGB */
+ default:
+ return GL_FALSE;
+ }
+}
+
+
+/**
+ * Test if the given image format is a color index format.
+ */
+static GLboolean
+is_index_format(GLenum format)
+{
+ switch (format) {
+ case GL_COLOR_INDEX:
+ case GL_COLOR_INDEX1_EXT:
+ case GL_COLOR_INDEX2_EXT:
+ case GL_COLOR_INDEX4_EXT:
+ case GL_COLOR_INDEX8_EXT:
+ case GL_COLOR_INDEX12_EXT:
+ case GL_COLOR_INDEX16_EXT:
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
+}
+
+
+/**
+ * Test if the given image format is a depth component format.
+ */
+static GLboolean
+is_depth_format(GLenum format)
+{
+ switch (format) {
+ case GL_DEPTH_COMPONENT16_ARB:
+ case GL_DEPTH_COMPONENT24_ARB:
+ case GL_DEPTH_COMPONENT32_ARB:
+ case GL_DEPTH_COMPONENT:
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
+}
+
+
+/**
+ * Test if the given image format is a YCbCr format.
+ */
+static GLboolean
+is_ycbcr_format(GLenum format)
+{
+ switch (format) {
+ case GL_YCBCR_MESA:
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
+}
+
+
+/**
+ * Test if the given image format is a Depth/Stencil format.
+ */
+static GLboolean
+is_depthstencil_format(GLenum format)
+{
+ switch (format) {
+ case GL_DEPTH24_STENCIL8_EXT:
+ case GL_DEPTH_STENCIL_EXT:
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
+}
+
+
+
+/**
+ * Test if it is a supported compressed format.
+ *
+ * \param internalFormat the internal format token provided by the user.
+ *
+ * \ret GL_TRUE if \p internalFormat is a supported compressed format, or
+ * GL_FALSE otherwise.
+ *
+ * Currently only GL_COMPRESSED_RGB_FXT1_3DFX and GL_COMPRESSED_RGBA_FXT1_3DFX
+ * are supported.
+ */
+static GLboolean
+is_compressed_format(GLcontext *ctx, GLenum internalFormat)
+{
+ (void) ctx;
+ switch (internalFormat) {
+ case GL_COMPRESSED_RGB_FXT1_3DFX:
+ case GL_COMPRESSED_RGBA_FXT1_3DFX:
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ case GL_RGB_S3TC:
+ case GL_RGB4_S3TC:
+ case GL_RGBA_S3TC:
+ case GL_RGBA4_S3TC:
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
+}
+
+
+static GLuint
+texture_face(GLenum target)
+{
+ if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
+ target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)
+ return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
+ else
+ return 0;
+}
+
+
+
+/**
+ * Store a gl_texture_image pointer in a gl_texture_object structure
+ * according to the target and level parameters.
+ *
+ * \param tObj texture object.
+ * \param target texture target.
+ * \param level image level.
+ * \param texImage texture image.
+ *
+ * This was basically prompted by the introduction of cube maps.
+ */
+void
+_mesa_set_tex_image(struct gl_texture_object *tObj,
+ GLenum target, GLint level,
+ struct gl_texture_image *texImage)
+{
+ ASSERT(tObj);
+ ASSERT(texImage);
+ switch (target) {
+ case GL_TEXTURE_1D:
+ case GL_TEXTURE_2D:
+ case GL_TEXTURE_3D:
+ tObj->Image[0][level] = texImage;
+ break;
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
+ {
+ GLuint face = ((GLuint) target -
+ (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X);
+ tObj->Image[face][level] = texImage;
+ }
+ break;
+ case GL_TEXTURE_RECTANGLE_NV:
+ ASSERT(level == 0);
+ tObj->Image[0][level] = texImage;
+ break;
+ default:
+ _mesa_problem(NULL, "bad target in _mesa_set_tex_image()");
+ return;
+ }
+ /* Set the 'back' pointer */
+ texImage->TexObject = tObj;
+}
+
+
+/**
+ * Allocate a texture image structure.
+ *
+ * Called via ctx->Driver.NewTextureImage() unless overriden by a device
+ * driver.
+ *
+ * \return a pointer to gl_texture_image struct with all fields initialized to
+ * zero.
+ */
+struct gl_texture_image *
+_mesa_new_texture_image( GLcontext *ctx )
+{
+ (void) ctx;
+ return CALLOC_STRUCT(gl_texture_image);
+}
+
+
+/**
+ * Free texture image data.
+ * This function is a fallback called via ctx->Driver.FreeTexImageData().
+ *
+ * \param teximage texture image.
+ *
+ * Free the texture image data if it's not marked as client data.
+ */
+void
+_mesa_free_texture_image_data(GLcontext *ctx,
+ struct gl_texture_image *texImage)
+{
+ if (texImage->Data && !texImage->IsClientData) {
+ /* free the old texture data */
+ _mesa_free_texmemory(texImage->Data);
+ }
+
+ texImage->Data = NULL;
+}
+
+
+/**
+ * Free texture image.
+ *
+ * \param teximage texture image.
+ *
+ * Free the texture image structure and the associated image data.
+ */
+void
+_mesa_delete_texture_image( GLcontext *ctx, struct gl_texture_image *texImage )
+{
+ if (texImage->Data) {
+ ctx->Driver.FreeTexImageData( ctx, texImage );
+ }
+ ASSERT(texImage->Data == NULL);
+ FREE( texImage );
+}
+
+
+/**
+ * Test if a target is a proxy target.
+ *
+ * \param target texture target.
+ *
+ * \return GL_TRUE if the target is a proxy target, GL_FALSE otherwise.
+ */
+GLboolean
+_mesa_is_proxy_texture(GLenum target)
+{
+ return (target == GL_PROXY_TEXTURE_1D ||
+ target == GL_PROXY_TEXTURE_2D ||
+ target == GL_PROXY_TEXTURE_3D ||
+ target == GL_PROXY_TEXTURE_CUBE_MAP_ARB ||
+ target == GL_PROXY_TEXTURE_RECTANGLE_NV);
+}
+
+
+/**
+ * Get the texture object that corresponds to the target of the given texture unit.
+ *
+ * \param ctx GL context.
+ * \param texUnit texture unit.
+ * \param target texture target.
+ *
+ * \return pointer to the texture object on success, or NULL on failure.
+ *
+ * \sa gl_texture_unit.
+ */
+struct gl_texture_object *
+_mesa_select_tex_object(GLcontext *ctx, const struct gl_texture_unit *texUnit,
+ GLenum target)
+{
+ switch (target) {
+ case GL_TEXTURE_1D:
+ return texUnit->Current1D;
+ case GL_PROXY_TEXTURE_1D:
+ return ctx->Texture.Proxy1D;
+ case GL_TEXTURE_2D:
+ return texUnit->Current2D;
+ case GL_PROXY_TEXTURE_2D:
+ return ctx->Texture.Proxy2D;
+ case GL_TEXTURE_3D:
+ return texUnit->Current3D;
+ case GL_PROXY_TEXTURE_3D:
+ return ctx->Texture.Proxy3D;
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
+ case GL_TEXTURE_CUBE_MAP_ARB:
+ return ctx->Extensions.ARB_texture_cube_map
+ ? texUnit->CurrentCubeMap : NULL;
+ case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
+ return ctx->Extensions.ARB_texture_cube_map
+ ? ctx->Texture.ProxyCubeMap : NULL;
+ case GL_TEXTURE_RECTANGLE_NV:
+ return ctx->Extensions.NV_texture_rectangle
+ ? texUnit->CurrentRect : NULL;
+ case GL_PROXY_TEXTURE_RECTANGLE_NV:
+ return ctx->Extensions.NV_texture_rectangle
+ ? ctx->Texture.ProxyRect : NULL;
+ default:
+ _mesa_problem(NULL, "bad target in _mesa_select_tex_object()");
+ return NULL;
+ }
+}
+
+
+/**
+ * Get the texture image struct which corresponds to target and level
+ * of the given texture unit.
+ *
+ * \param ctx GL context.
+ * \param texUnit texture unit.
+ * \param target texture target.
+ * \param level image level.
+ *
+ * \return pointer to the texture image structure on success, or NULL on failure.
+ *
+ * \sa gl_texture_unit.
+ */
+struct gl_texture_image *
+_mesa_select_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit,
+ GLenum target, GLint level)
+{
+ ASSERT(texUnit);
+ ASSERT(level < MAX_TEXTURE_LEVELS);
+ switch (target) {
+ case GL_TEXTURE_1D:
+ return texUnit->Current1D->Image[0][level];
+ case GL_PROXY_TEXTURE_1D:
+ return ctx->Texture.Proxy1D->Image[0][level];
+ case GL_TEXTURE_2D:
+ return texUnit->Current2D->Image[0][level];
+ case GL_PROXY_TEXTURE_2D:
+ return ctx->Texture.Proxy2D->Image[0][level];
+ case GL_TEXTURE_3D:
+ return texUnit->Current3D->Image[0][level];
+ case GL_PROXY_TEXTURE_3D:
+ return ctx->Texture.Proxy3D->Image[0][level];
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
+ if (ctx->Extensions.ARB_texture_cube_map) {
+ GLuint face = ((GLuint) target -
+ (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X);
+ return texUnit->CurrentCubeMap->Image[face][level];
+ }
+ else
+ return NULL;
+ case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
+ if (ctx->Extensions.ARB_texture_cube_map)
+ return ctx->Texture.ProxyCubeMap->Image[0][level];
+ else
+ return NULL;
+ case GL_TEXTURE_RECTANGLE_NV:
+ if (ctx->Extensions.NV_texture_rectangle) {
+ ASSERT(level == 0);
+ return texUnit->CurrentRect->Image[0][level];
+ }
+ else {
+ return NULL;
+ }
+ case GL_PROXY_TEXTURE_RECTANGLE_NV:
+ if (ctx->Extensions.NV_texture_rectangle) {
+ ASSERT(level == 0);
+ return ctx->Texture.ProxyRect->Image[0][level];
+ }
+ else {
+ return NULL;
+ }
+ default:
+ _mesa_problem(ctx, "bad target in _mesa_select_tex_image()");
+ return NULL;
+ }
+}
+
+
+/**
+ * Like _mesa_select_tex_image() but if the image doesn't exist, allocate
+ * it and install it. Only return NULL if passed a bad parameter or run
+ * out of memory.
+ */
+struct gl_texture_image *
+_mesa_get_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit,
+ GLenum target, GLint level)
+{
+ struct gl_texture_image *texImage;
+ texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
+ if (!texImage) {
+ struct gl_texture_object *texObj;
+ texImage = ctx->Driver.NewTextureImage(ctx);
+ if (!texImage) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture image allocation");
+ return NULL;
+ }
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ ASSERT(texObj);
+ _mesa_set_tex_image(texObj, target, level, texImage);
+ }
+ return texImage;
+}
+
+
+/**
+ * Return pointer to the specified proxy texture image.
+ * Note that proxy textures are per-context, not per-texture unit.
+ * \return pointer to texture image or NULL if invalid target, invalid
+ * level, or out of memory.
+ */
+struct gl_texture_image *
+_mesa_get_proxy_tex_image(GLcontext *ctx, GLenum target, GLint level)
+{
+ struct gl_texture_image *texImage;
+
+ if (level < 0 )
+ return NULL;
+
+ switch (target) {
+ case GL_PROXY_TEXTURE_1D:
+ if (level >= ctx->Const.MaxTextureLevels)
+ return NULL;
+ texImage = ctx->Texture.Proxy1D->Image[0][level];
+ if (!texImage) {
+ texImage = ctx->Driver.NewTextureImage(ctx);
+ if (!texImage) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
+ return NULL;
+ }
+ ctx->Texture.Proxy1D->Image[0][level] = texImage;
+ /* Set the 'back' pointer */
+ texImage->TexObject = ctx->Texture.Proxy1D;
+ }
+ return texImage;
+ case GL_PROXY_TEXTURE_2D:
+ if (level >= ctx->Const.MaxTextureLevels)
+ return NULL;
+ texImage = ctx->Texture.Proxy2D->Image[0][level];
+ if (!texImage) {
+ texImage = ctx->Driver.NewTextureImage(ctx);
+ if (!texImage) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
+ return NULL;
+ }
+ ctx->Texture.Proxy2D->Image[0][level] = texImage;
+ /* Set the 'back' pointer */
+ texImage->TexObject = ctx->Texture.Proxy2D;
+ }
+ return texImage;
+ case GL_PROXY_TEXTURE_3D:
+ if (level >= ctx->Const.Max3DTextureLevels)
+ return NULL;
+ texImage = ctx->Texture.Proxy3D->Image[0][level];
+ if (!texImage) {
+ texImage = ctx->Driver.NewTextureImage(ctx);
+ if (!texImage) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
+ return NULL;
+ }
+ ctx->Texture.Proxy3D->Image[0][level] = texImage;
+ /* Set the 'back' pointer */
+ texImage->TexObject = ctx->Texture.Proxy3D;
+ }
+ return texImage;
+ case GL_PROXY_TEXTURE_CUBE_MAP:
+ if (level >= ctx->Const.MaxCubeTextureLevels)
+ return NULL;
+ texImage = ctx->Texture.ProxyCubeMap->Image[0][level];
+ if (!texImage) {
+ texImage = ctx->Driver.NewTextureImage(ctx);
+ if (!texImage) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
+ return NULL;
+ }
+ ctx->Texture.ProxyCubeMap->Image[0][level] = texImage;
+ /* Set the 'back' pointer */
+ texImage->TexObject = ctx->Texture.ProxyCubeMap;
+ }
+ return texImage;
+ case GL_PROXY_TEXTURE_RECTANGLE_NV:
+ if (level > 0)
+ return NULL;
+ texImage = ctx->Texture.ProxyRect->Image[0][level];
+ if (!texImage) {
+ texImage = ctx->Driver.NewTextureImage(ctx);
+ if (!texImage) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
+ return NULL;
+ }
+ ctx->Texture.ProxyRect->Image[0][level] = texImage;
+ /* Set the 'back' pointer */
+ texImage->TexObject = ctx->Texture.ProxyRect;
+ }
+ return texImage;
+ default:
+ return NULL;
+ }
+}
+
+
+/**
+ * Get the maximum number of allowed mipmap levels.
+ *
+ * \param ctx GL context.
+ * \param target texture target.
+ *
+ * \return the maximum number of allowed mipmap levels for the given
+ * texture target, or zero if passed a bad target.
+ *
+ * \sa gl_constants.
+ */
+GLint
+_mesa_max_texture_levels(GLcontext *ctx, GLenum target)
+{
+ switch (target) {
+ case GL_TEXTURE_1D:
+ case GL_PROXY_TEXTURE_1D:
+ case GL_TEXTURE_2D:
+ case GL_PROXY_TEXTURE_2D:
+ return ctx->Const.MaxTextureLevels;
+ case GL_TEXTURE_3D:
+ case GL_PROXY_TEXTURE_3D:
+ return ctx->Const.Max3DTextureLevels;
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
+ case GL_TEXTURE_CUBE_MAP_ARB:
+ case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
+ return ctx->Const.MaxCubeTextureLevels;
+ case GL_TEXTURE_RECTANGLE_NV:
+ case GL_PROXY_TEXTURE_RECTANGLE_NV:
+ return 1;
+ default:
+ return 0; /* bad target */
+ }
+}
+
+
+
+#if 000 /* not used anymore */
+/*
+ * glTexImage[123]D can accept a NULL image pointer. In this case we
+ * create a texture image with unspecified image contents per the OpenGL
+ * spec.
+ */
+static GLubyte *
+make_null_texture(GLint width, GLint height, GLint depth, GLenum format)
+{
+ const GLint components = _mesa_components_in_format(format);
+ const GLint numPixels = width * height * depth;
+ GLubyte *data = (GLubyte *) MALLOC(numPixels * components * sizeof(GLubyte));
+
+#ifdef DEBUG
+ /*
+ * Let's see if anyone finds this. If glTexImage2D() is called with
+ * a NULL image pointer then load the texture image with something
+ * interesting instead of leaving it indeterminate.
+ */
+ if (data) {
+ static const char message[8][32] = {
+ " X X XXXXX XXX X ",
+ " XX XX X X X X X ",
+ " X X X X X X X ",
+ " X X XXXX XXX XXXXX ",
+ " X X X X X X ",
+ " X X X X X X X ",
+ " X X XXXXX XXX X X ",
+ " "
+ };
+
+ GLubyte *imgPtr = data;
+ GLint h, i, j, k;
+ for (h = 0; h < depth; h++) {
+ for (i = 0; i < height; i++) {
+ GLint srcRow = 7 - (i % 8);
+ for (j = 0; j < width; j++) {
+ GLint srcCol = j % 32;
+ GLubyte texel = (message[srcRow][srcCol]=='X') ? 255 : 70;
+ for (k = 0; k < components; k++) {
+ *imgPtr++ = texel;
+ }
+ }
+ }
+ }
+ }
+#endif
+
+ return data;
+}
+#endif
+
+
+
+/**
+ * Reset the fields of a gl_texture_image struct to zero.
+ *
+ * \param img texture image structure.
+ *
+ * This is called when a proxy texture test fails, we set all the
+ * image members (except DriverData) to zero.
+ * It's also used in glTexImage[123]D as a safeguard to be sure all
+ * required fields get initialized properly by the Driver.TexImage[123]D
+ * functions.
+ */
+static void
+clear_teximage_fields(struct gl_texture_image *img)
+{
+ ASSERT(img);
+ img->_BaseFormat = 0;
+ img->InternalFormat = 0;
+ img->Border = 0;
+ img->Width = 0;
+ img->Height = 0;
+ img->Depth = 0;
+ img->RowStride = 0;
+ img->ImageStride = 0;
+ img->Width2 = 0;
+ img->Height2 = 0;
+ img->Depth2 = 0;
+ img->WidthLog2 = 0;
+ img->HeightLog2 = 0;
+ img->DepthLog2 = 0;
+ img->Data = NULL;
+ img->TexFormat = &_mesa_null_texformat;
+ img->FetchTexelc = NULL;
+ img->FetchTexelf = NULL;
+ img->IsCompressed = 0;
+ img->CompressedSize = 0;
+}
+
+
+/**
+ * Initialize basic fields of the gl_texture_image struct.
+ *
+ * \param ctx GL context.
+ * \param target texture target.
+ * \param img texture image structure to be initialized.
+ * \param width image width.
+ * \param height image height.
+ * \param depth image depth.
+ * \param border image border.
+ * \param internalFormat internal format.
+ *
+ * Fills in the fields of \p img with the given information.
+ * Note: width, height and depth include the border.
+ */
+void
+_mesa_init_teximage_fields(GLcontext *ctx, GLenum target,
+ struct gl_texture_image *img,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLint border, GLenum internalFormat)
+{
+ ASSERT(img);
+ img->_BaseFormat = _mesa_base_tex_format( ctx, internalFormat );
+ ASSERT(img->_BaseFormat > 0);
+ img->InternalFormat = internalFormat;
+ img->Border = border;
+ img->Width = width;
+ img->Height = height;
+ img->Depth = depth;
+ img->RowStride = width;
+ img->ImageStride = width * height;
+ img->Width2 = width - 2 * border; /* == 1 << img->WidthLog2; */
+ img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */
+ img->Depth2 = depth - 2 * border; /* == 1 << img->DepthLog2; */
+ img->WidthLog2 = logbase2(img->Width2);
+ if (height == 1) /* 1-D texture */
+ img->HeightLog2 = 0;
+ else
+ img->HeightLog2 = logbase2(img->Height2);
+ if (depth == 1) /* 2-D texture */
+ img->DepthLog2 = 0;
+ else
+ img->DepthLog2 = logbase2(img->Depth2);
+ img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2);
+ img->IsCompressed = is_compressed_format(ctx, internalFormat);
+ if (img->IsCompressed)
+ img->CompressedSize = ctx->Driver.CompressedTextureSize(ctx, width,
+ height, depth, internalFormat);
+ else
+ img->CompressedSize = 0;
+
+ if ((width == 1 || _mesa_bitcount(img->Width2) == 1) &&
+ (height == 1 || _mesa_bitcount(img->Height2) == 1) &&
+ (depth == 1 || _mesa_bitcount(img->Depth2) == 1))
+ img->_IsPowerOfTwo = GL_TRUE;
+ else
+ img->_IsPowerOfTwo = GL_FALSE;
+
+ /* Compute Width/Height/DepthScale for mipmap lod computation */
+ if (target == GL_TEXTURE_RECTANGLE_NV) {
+ /* scale = 1.0 since texture coords directly map to texels */
+ img->WidthScale = 1.0;
+ img->HeightScale = 1.0;
+ img->DepthScale = 1.0;
+ }
+ else {
+ img->WidthScale = (GLfloat) img->Width;
+ img->HeightScale = (GLfloat) img->Height;
+ img->DepthScale = (GLfloat) img->Depth;
+ }
+}
+
+
+/**
+ * This is the fallback for Driver.TestProxyTexImage(). Test the texture
+ * level, width, height and depth against the ctx->Const limits for textures.
+ *
+ * A hardware driver might override this function if, for example, the
+ * max 3D texture size is 512x512x64 (i.e. not a cube).
+ *
+ * \param target one of GL_PROXY_TEXTURE_1D, GL_PROXY_TEXTURE_2D,
+ * GL_PROXY_TEXTURE_3D, GL_PROXY_TEXTURE_RECTANGLE_NV,
+ * GL_PROXY_TEXTURE_CUBE_MAP_ARB.
+ * \param level as passed to glTexImage
+ * \param internalFormat as passed to glTexImage
+ * \param format as passed to glTexImage
+ * \param type as passed to glTexImage
+ * \param width as passed to glTexImage
+ * \param height as passed to glTexImage
+ * \param depth as passed to glTexImage
+ * \param border as passed to glTexImage
+ * \return GL_TRUE if the image is acceptable, GL_FALSE if not acceptable.
+ */
+GLboolean
+_mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level,
+ GLint internalFormat, GLenum format, GLenum type,
+ GLint width, GLint height, GLint depth, GLint border)
+{
+ GLint maxSize;
+
+ (void) internalFormat;
+ (void) format;
+ (void) type;
+
+ switch (target) {
+ case GL_PROXY_TEXTURE_1D:
+ maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
+ if (width < 2 * border || width > 2 + maxSize ||
+ (!ctx->Extensions.ARB_texture_non_power_of_two &&
+ _mesa_bitcount(width - 2 * border) != 1) ||
+ level >= ctx->Const.MaxTextureLevels) {
+ /* bad width or level */
+ return GL_FALSE;
+ }
+ return GL_TRUE;
+ case GL_PROXY_TEXTURE_2D:
+ maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
+ if (width < 2 * border || width > 2 + maxSize ||
+ (!ctx->Extensions.ARB_texture_non_power_of_two &&
+ _mesa_bitcount(width - 2 * border) != 1) ||
+ height < 2 * border || height > 2 + maxSize ||
+ (!ctx->Extensions.ARB_texture_non_power_of_two &&
+ _mesa_bitcount(height - 2 * border) != 1) ||
+ level >= ctx->Const.MaxTextureLevels) {
+ /* bad width or height or level */
+ return GL_FALSE;
+ }
+ return GL_TRUE;
+ case GL_PROXY_TEXTURE_3D:
+ maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1);
+ if (width < 2 * border || width > 2 + maxSize ||
+ (!ctx->Extensions.ARB_texture_non_power_of_two &&
+ _mesa_bitcount(width - 2 * border) != 1) ||
+ height < 2 * border || height > 2 + maxSize ||
+ (!ctx->Extensions.ARB_texture_non_power_of_two &&
+ _mesa_bitcount(height - 2 * border) != 1) ||
+ depth < 2 * border || depth > 2 + maxSize ||
+ (!ctx->Extensions.ARB_texture_non_power_of_two &&
+ _mesa_bitcount(depth - 2 * border) != 1) ||
+ level >= ctx->Const.Max3DTextureLevels) {
+ /* bad width or height or depth or level */
+ return GL_FALSE;
+ }
+ return GL_TRUE;
+ case GL_PROXY_TEXTURE_RECTANGLE_NV:
+ if (width < 1 || width > ctx->Const.MaxTextureRectSize ||
+ height < 1 || height > ctx->Const.MaxTextureRectSize ||
+ level != 0) {
+ /* bad width or height or level */
+ return GL_FALSE;
+ }
+ return GL_TRUE;
+ case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
+ maxSize = 1 << (ctx->Const.MaxCubeTextureLevels - 1);
+ if (width < 2 * border || width > 2 + maxSize ||
+ (!ctx->Extensions.ARB_texture_non_power_of_two &&
+ _mesa_bitcount(width - 2 * border) != 1) ||
+ height < 2 * border || height > 2 + maxSize ||
+ (!ctx->Extensions.ARB_texture_non_power_of_two &&
+ _mesa_bitcount(height - 2 * border) != 1) ||
+ level >= ctx->Const.MaxCubeTextureLevels) {
+ /* bad width or height */
+ return GL_FALSE;
+ }
+ return GL_TRUE;
+ default:
+ _mesa_problem(ctx, "Invalid target in _mesa_test_proxy_teximage");
+ return GL_FALSE;
+ }
+}
+
+
+/**
+ * Test the glTexImage[123]D() parameters for errors.
+ *
+ * \param ctx GL context.
+ * \param target texture target given by the user.
+ * \param level image level given by the user.
+ * \param internalFormat internal format given by the user.
+ * \param format pixel data format given by the user.
+ * \param type pixel data type given by the user.
+ * \param dimensions texture image dimensions (must be 1, 2 or 3).
+ * \param width image width given by the user.
+ * \param height image height given by the user.
+ * \param depth image depth given by the user.
+ * \param border image border given by the user.
+ *
+ * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
+ *
+ * Verifies each of the parameters against the constants specified in
+ * __GLcontextRec::Const and the supported extensions, and according to the
+ * OpenGL specification.
+ */
+static GLboolean
+texture_error_check( GLcontext *ctx, GLenum target,
+ GLint level, GLint internalFormat,
+ GLenum format, GLenum type,
+ GLuint dimensions,
+ GLint width, GLint height,
+ GLint depth, GLint border )
+{
+ const GLboolean isProxy = _mesa_is_proxy_texture(target);
+ GLboolean sizeOK;
+ GLboolean colorFormat, indexFormat;
+
+ /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */
+ if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
+ if (!isProxy) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glTexImage%dD(level=%d)", dimensions, level);
+ }
+ return GL_TRUE;
+ }
+
+ /* Check border */
+ if (border < 0 || border > 1 ||
+ ((target == GL_TEXTURE_RECTANGLE_NV ||
+ target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0)) {
+ if (!isProxy) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glTexImage%dD(border=%d)", dimensions, border);
+ }
+ return GL_TRUE;
+ }
+
+ if (width < 0 || height < 0 || depth < 0) {
+ if (!isProxy) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glTexImage%dD(width, height or depth < 0)", dimensions);
+ }
+ return GL_TRUE;
+ }
+
+ /* Check target and call ctx->Driver.TestProxyTexImage() to check the
+ * level, width, height and depth.
+ */
+ if (dimensions == 1) {
+ if (target == GL_PROXY_TEXTURE_1D || target == GL_TEXTURE_1D) {
+ sizeOK = ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_1D,
+ level, internalFormat,
+ format, type,
+ width, 1, 1, border);
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" );
+ return GL_TRUE;
+ }
+ }
+ else if (dimensions == 2) {
+ if (target == GL_PROXY_TEXTURE_2D || target == GL_TEXTURE_2D) {
+ sizeOK = ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_2D,
+ level, internalFormat,
+ format, type,
+ width, height, 1, border);
+ }
+ else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB ||
+ (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
+ target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) {
+ if (!ctx->Extensions.ARB_texture_cube_map) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)");
+ return GL_TRUE;
+ }
+ sizeOK = (width == height) &&
+ ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_CUBE_MAP_ARB,
+ level, internalFormat, format, type,
+ width, height, 1, border);
+ }
+ else if (target == GL_PROXY_TEXTURE_RECTANGLE_NV ||
+ target == GL_TEXTURE_RECTANGLE_NV) {
+ if (!ctx->Extensions.NV_texture_rectangle) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)");
+ return GL_TRUE;
+ }
+ sizeOK = ctx->Driver.TestProxyTexImage(ctx,
+ GL_PROXY_TEXTURE_RECTANGLE_NV,
+ level, internalFormat,
+ format, type,
+ width, height, 1, border);
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)");
+ return GL_TRUE;
+ }
+ }
+ else if (dimensions == 3) {
+ if (target == GL_PROXY_TEXTURE_3D || target == GL_TEXTURE_3D) {
+ sizeOK = ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_3D,
+ level, internalFormat,
+ format, type,
+ width, height, depth, border);
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage3D(target)" );
+ return GL_TRUE;
+ }
+ }
+ else {
+ _mesa_problem( ctx, "bad dims in texture_error_check" );
+ return GL_TRUE;
+ }
+
+ if (!sizeOK) {
+ if (!isProxy) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glTexImage%dD(level=%d, width=%d, height=%d, depth=%d)",
+ dimensions, level, width, height, depth);
+ }
+ return GL_TRUE;
+ }
+
+ /* Check internalFormat */
+ if (_mesa_base_tex_format(ctx, internalFormat) < 0) {
+ if (!isProxy) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glTexImage%dD(internalFormat=0x%x)",
+ dimensions, internalFormat);
+ }
+ return GL_TRUE;
+ }
+
+ /* Check incoming image format and type */
+ if (!_mesa_is_legal_format_and_type(ctx, format, type)) {
+ /* Yes, generate GL_INVALID_OPERATION, not GL_INVALID_ENUM, if there
+ * is a type/format mismatch. See 1.2 spec page 94, sec 3.6.4.
+ */
+ if (!isProxy) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTexImage%dD(format or type)", dimensions);
+ }
+ return GL_TRUE;
+ }
+
+ /* make sure internal format and format basically agree */
+ colorFormat = is_color_format(format);
+ indexFormat = is_index_format(format);
+ if ((is_color_format(internalFormat) && !colorFormat && !indexFormat) ||
+ (is_index_format(internalFormat) && !indexFormat) ||
+ (is_depth_format(internalFormat) != is_depth_format(format)) ||
+ (is_ycbcr_format(internalFormat) != is_ycbcr_format(format)) ||
+ (is_depthstencil_format(internalFormat) != is_depthstencil_format(format))) {
+ if (!isProxy)
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTexImage(internalFormat/format)");
+ return GL_TRUE;
+ }
+
+ /* additional checks for ycbcr textures */
+ if (internalFormat == GL_YCBCR_MESA) {
+ ASSERT(ctx->Extensions.MESA_ycbcr_texture);
+ if (type != GL_UNSIGNED_SHORT_8_8_MESA &&
+ type != GL_UNSIGNED_SHORT_8_8_REV_MESA) {
+ char message[100];
+ _mesa_sprintf(message,
+ "glTexImage%d(format/type YCBCR mismatch", dimensions);
+ _mesa_error(ctx, GL_INVALID_ENUM, message);
+ return GL_TRUE; /* error */
+ }
+ if (target != GL_TEXTURE_2D &&
+ target != GL_PROXY_TEXTURE_2D &&
+ target != GL_TEXTURE_RECTANGLE_NV &&
+ target != GL_PROXY_TEXTURE_RECTANGLE_NV) {
+ if (!isProxy)
+ _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage(target)");
+ return GL_TRUE;
+ }
+ if (border != 0) {
+ if (!isProxy) {
+ char message[100];
+ _mesa_sprintf(message,
+ "glTexImage%d(format=GL_YCBCR_MESA and border=%d)",
+ dimensions, border);
+ _mesa_error(ctx, GL_INVALID_VALUE, message);
+ }
+ return GL_TRUE;
+ }
+ }
+
+ /* additional checks for depth textures */
+ if (_mesa_base_tex_format(ctx, internalFormat) == GL_DEPTH_COMPONENT) {
+ /* Only 1D and 2D textures supported */
+ if (target != GL_TEXTURE_1D &&
+ target != GL_PROXY_TEXTURE_1D &&
+ target != GL_TEXTURE_2D &&
+ target != GL_PROXY_TEXTURE_2D) {
+ if (!isProxy)
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glTexImage(target/internalFormat)");
+ return GL_TRUE;
+ }
+ }
+
+ /* additional checks for compressed textures */
+ if (is_compressed_format(ctx, internalFormat)) {
+ if (target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D) {
+ /* OK */
+ }
+ else if (ctx->Extensions.ARB_texture_cube_map &&
+ (target == GL_PROXY_TEXTURE_CUBE_MAP ||
+ (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
+ target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z))) {
+ /* OK */
+ }
+ else {
+ if (!isProxy) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glTexImage%d(target)", dimensions);
+ return GL_TRUE;
+ }
+ }
+ if (border != 0) {
+ if (!isProxy) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTexImage%D(border!=0)", dimensions);
+ }
+ return GL_TRUE;
+ }
+ }
+
+ /* if we get here, the parameters are OK */
+ return GL_FALSE;
+}
+
+
+/**
+ * Test glTexSubImage[123]D() parameters for errors.
+ *
+ * \param ctx GL context.
+ * \param dimensions texture image dimensions (must be 1, 2 or 3).
+ * \param target texture target given by the user.
+ * \param level image level given by the user.
+ * \param xoffset sub-image x offset given by the user.
+ * \param yoffset sub-image y offset given by the user.
+ * \param zoffset sub-image z offset given by the user.
+ * \param format pixel data format given by the user.
+ * \param type pixel data type given by the user.
+ * \param width image width given by the user.
+ * \param height image height given by the user.
+ * \param depth image depth given by the user.
+ *
+ * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
+ *
+ * Verifies each of the parameters against the constants specified in
+ * __GLcontextRec::Const and the supported extensions, and according to the
+ * OpenGL specification.
+ */
+static GLboolean
+subtexture_error_check( GLcontext *ctx, GLuint dimensions,
+ GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLint width, GLint height, GLint depth,
+ GLenum format, GLenum type )
+{
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ struct gl_texture_image *destTex;
+
+ /* Check target */
+ if (dimensions == 1) {
+ if (target != GL_TEXTURE_1D) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(target)" );
+ return GL_TRUE;
+ }
+ }
+ else if (dimensions == 2) {
+ if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
+ target <=GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
+ if (!ctx->Extensions.ARB_texture_cube_map) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" );
+ return GL_TRUE;
+ }
+ }
+ else if (ctx->Extensions.NV_texture_rectangle &&
+ target == GL_TEXTURE_RECTANGLE_NV) {
+ if (!ctx->Extensions.NV_texture_rectangle) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" );
+ return GL_TRUE;
+ }
+ }
+ else if (target != GL_TEXTURE_2D) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" );
+ return GL_TRUE;
+ }
+ }
+ else if (dimensions == 3) {
+ if (target != GL_TEXTURE_3D) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage3D(target)" );
+ return GL_TRUE;
+ }
+ }
+ else {
+ _mesa_problem( ctx, "invalid dims in texture_error_check" );
+ return GL_TRUE;
+ }
+
+ /* Basic level check */
+ if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage2D(level=%d)", level);
+ return GL_TRUE;
+ }
+
+ if (width < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glTexSubImage%dD(width=%d)", dimensions, width);
+ return GL_TRUE;
+ }
+ if (height < 0 && dimensions > 1) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glTexSubImage%dD(height=%d)", dimensions, height);
+ return GL_TRUE;
+ }
+ if (depth < 0 && dimensions > 2) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glTexSubImage%dD(depth=%d)", dimensions, depth);
+ return GL_TRUE;
+ }
+
+ destTex = _mesa_select_tex_image(ctx, texUnit, target, level);
+
+ if (!destTex) {
+ /* undefined image level */
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glTexSubImage%dD", dimensions);
+ return GL_TRUE;
+ }
+
+ if (xoffset < -((GLint)destTex->Border)) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(xoffset)",
+ dimensions);
+ return GL_TRUE;
+ }
+ if (xoffset + width > (GLint) (destTex->Width + destTex->Border)) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(xoffset+width)",
+ dimensions);
+ return GL_TRUE;
+ }
+ if (dimensions > 1) {
+ if (yoffset < -((GLint)destTex->Border)) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(yoffset)",
+ dimensions);
+ return GL_TRUE;
+ }
+ if (yoffset + height > (GLint) (destTex->Height + destTex->Border)) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(yoffset+height)",
+ dimensions);
+ return GL_TRUE;
+ }
+ }
+ if (dimensions > 2) {
+ if (zoffset < -((GLint)destTex->Border)) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset)");
+ return GL_TRUE;
+ }
+ if (zoffset + depth > (GLint) (destTex->Depth + destTex->Border)) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset+depth)");
+ return GL_TRUE;
+ }
+ }
+
+ if (!_mesa_is_legal_format_and_type(ctx, format, type)) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glTexSubImage%dD(format or type)", dimensions);
+ return GL_TRUE;
+ }
+
+ if (destTex->IsCompressed) {
+ const struct gl_texture_unit *texUnit;
+ const struct gl_texture_image *texImage;
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
+
+ if (target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D) {
+ /* OK */
+ }
+ else if (ctx->Extensions.ARB_texture_cube_map &&
+ (target == GL_PROXY_TEXTURE_CUBE_MAP ||
+ (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
+ target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z))) {
+ /* OK */
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glTexSubImage%D(target)", dimensions);
+ return GL_TRUE;
+ }
+ /* offset must be multiple of 4 */
+ if ((xoffset & 3) || (yoffset & 3)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTexSubImage%D(xoffset or yoffset)", dimensions);
+ return GL_TRUE;
+ }
+ /* size must be multiple of 4 or equal to whole texture size */
+ if ((width & 3) && (GLuint) width != texImage->Width) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTexSubImage%D(width)", dimensions);
+ return GL_TRUE;
+ }
+ if ((height & 3) && (GLuint) height != texImage->Height) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTexSubImage%D(width)", dimensions);
+ return GL_TRUE;
+ }
+ }
+
+ return GL_FALSE;
+}
+
+
+/**
+ * Test glCopyTexImage[12]D() parameters for errors.
+ *
+ * \param ctx GL context.
+ * \param dimensions texture image dimensions (must be 1, 2 or 3).
+ * \param target texture target given by the user.
+ * \param level image level given by the user.
+ * \param internalFormat internal format given by the user.
+ * \param width image width given by the user.
+ * \param height image height given by the user.
+ * \param depth image depth given by the user.
+ * \param border texture border.
+ *
+ * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
+ *
+ * Verifies each of the parameters against the constants specified in
+ * __GLcontextRec::Const and the supported extensions, and according to the
+ * OpenGL specification.
+ */
+static GLboolean
+copytexture_error_check( GLcontext *ctx, GLuint dimensions,
+ GLenum target, GLint level, GLint internalFormat,
+ GLint width, GLint height, GLint border )
+{
+ GLenum type;
+ GLboolean sizeOK;
+ GLint format;
+
+ /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */
+ if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
+ /* Check that the source buffer is complete */
+ if (ctx->ReadBuffer->Name) {
+ _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer);
+ if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
+ "glCopyTexImage%dD(invalid readbuffer)", dimensions);
+ return GL_TRUE;
+ }
+ }
+
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexImage%dD(level=%d)", dimensions, level);
+ return GL_TRUE;
+ }
+
+ /* Check border */
+ if (border < 0 || border > 1 ||
+ ((target == GL_TEXTURE_RECTANGLE_NV ||
+ target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0)) {
+ return GL_TRUE;
+ }
+
+ format = _mesa_base_tex_format(ctx, internalFormat);
+ if (format < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexImage%dD(internalFormat)", dimensions);
+ return GL_TRUE;
+ }
+
+ /* NOTE: the format and type aren't really significant for
+ * TestProxyTexImage(). Only the internalformat really matters.
+ if (!_mesa_source_buffer_exists(ctx, format)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glCopyTexImage%dD(missing readbuffer)", dimensions);
+ return GL_TRUE;
+ }
+
+ */
+ type = GL_FLOAT;
+
+ /* Check target and call ctx->Driver.TestProxyTexImage() to check the
+ * level, width, height and depth.
+ */
+ if (dimensions == 1) {
+ if (target == GL_TEXTURE_1D) {
+ sizeOK = ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_1D,
+ level, internalFormat,
+ format, type,
+ width, 1, 1, border);
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage1D(target)" );
+ return GL_TRUE;
+ }
+ }
+ else if (dimensions == 2) {
+ if (target == GL_TEXTURE_2D) {
+ sizeOK = ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_2D,
+ level, internalFormat,
+ format, type,
+ width, height, 1, border);
+ }
+ else if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
+ target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
+ if (!ctx->Extensions.ARB_texture_cube_map) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" );
+ return GL_TRUE;
+ }
+ sizeOK = (width == height) &&
+ ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_CUBE_MAP_ARB,
+ level, internalFormat, format, type,
+ width, height, 1, border);
+ }
+ else if (target == GL_TEXTURE_RECTANGLE_NV) {
+ if (!ctx->Extensions.NV_texture_rectangle) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" );
+ return GL_TRUE;
+ }
+ sizeOK = ctx->Driver.TestProxyTexImage(ctx,
+ GL_PROXY_TEXTURE_RECTANGLE_NV,
+ level, internalFormat,
+ format, type,
+ width, height, 1, border);
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" );
+ return GL_TRUE;
+ }
+ }
+ else {
+ _mesa_problem(ctx, "invalid dimensions in copytexture_error_check");
+ return GL_TRUE;
+ }
+
+ if (!sizeOK) {
+ if (dimensions == 1) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexImage1D(width=%d)", width);
+ }
+ else {
+ ASSERT(dimensions == 2);
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexImage2D(width=%d, height=%d)", width, height);
+ }
+ return GL_TRUE;
+ }
+
+ if (is_compressed_format(ctx, internalFormat)) {
+ if (target != GL_TEXTURE_2D) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glCopyTexImage%d(target)", dimensions);
+ return GL_TRUE;
+ }
+ if (border != 0) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glCopyTexImage%D(border!=0)", dimensions);
+ return GL_TRUE;
+ }
+ }
+ else if (is_depth_format(internalFormat)) {
+ /* make sure we have depth/stencil buffers */
+ if (!ctx->ReadBuffer->_DepthBuffer) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glCopyTexImage%D(no depth)", dimensions);
+ return GL_TRUE;
+ }
+ }
+ else if (is_depthstencil_format(internalFormat)) {
+ /* make sure we have depth/stencil buffers */
+ if (!ctx->ReadBuffer->_DepthBuffer || !ctx->ReadBuffer->_StencilBuffer) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glCopyTexImage%D(no depth/stencil buffer)", dimensions);
+ return GL_TRUE;
+ }
+ }
+
+ /* if we get here, the parameters are OK */
+ return GL_FALSE;
+}
+
+
+/**
+ * Test glCopyTexSubImage[12]D() parameters for errors.
+ *
+ * \param ctx GL context.
+ * \param dimensions texture image dimensions (must be 1, 2 or 3).
+ * \param target texture target given by the user.
+ * \param level image level given by the user.
+ * \param xoffset sub-image x offset given by the user.
+ * \param yoffset sub-image y offset given by the user.
+ * \param zoffset sub-image z offset given by the user.
+ * \param width image width given by the user.
+ * \param height image height given by the user.
+ *
+ * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
+ *
+ * Verifies each of the parameters against the constants specified in
+ * __GLcontextRec::Const and the supported extensions, and according to the
+ * OpenGL specification.
+ */
+static GLboolean
+copytexsubimage_error_check( GLcontext *ctx, GLuint dimensions,
+ GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height )
+{
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ struct gl_texture_image *teximage;
+
+ /* Check target */
+ /* Check that the source buffer is complete */
+ if (ctx->ReadBuffer->Name) {
+ _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer);
+ if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
+ "glCopyTexImage%dD(invalid readbuffer)", dimensions);
+ return GL_TRUE;
+ }
+ }
+
+ if (dimensions == 1) {
+ if (target != GL_TEXTURE_1D) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage1D(target)" );
+ return GL_TRUE;
+ }
+ }
+ else if (dimensions == 2) {
+ if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
+ target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
+ if (!ctx->Extensions.ARB_texture_cube_map) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" );
+ return GL_TRUE;
+ }
+ }
+ else if (target == GL_TEXTURE_RECTANGLE_NV) {
+ if (!ctx->Extensions.NV_texture_rectangle) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" );
+ return GL_TRUE;
+ }
+ }
+ else if (target != GL_TEXTURE_2D) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" );
+ return GL_TRUE;
+ }
+ }
+ else if (dimensions == 3) {
+ if (target != GL_TEXTURE_3D) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage3D(target)" );
+ return GL_TRUE;
+ }
+ }
+
+ /* Check level */
+ if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexSubImage%dD(level=%d)", dimensions, level);
+ return GL_TRUE;
+ }
+
+ /* Check size */
+ if (width < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexSubImage%dD(width=%d)", dimensions, width);
+ return GL_TRUE;
+ }
+ if (dimensions > 1 && height < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexSubImage%dD(height=%d)", dimensions, height);
+ return GL_TRUE;
+ }
+
+ teximage = _mesa_select_tex_image(ctx, texUnit, target, level);
+ if (!teximage) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glCopyTexSubImage%dD(undefined texture level: %d)",
+ dimensions, level);
+ return GL_TRUE;
+ }
+
+ if (xoffset < -((GLint)teximage->Border)) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexSubImage%dD(xoffset=%d)", dimensions, xoffset);
+ return GL_TRUE;
+ }
+ if (xoffset + width > (GLint) (teximage->Width + teximage->Border)) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexSubImage%dD(xoffset+width)", dimensions);
+ return GL_TRUE;
+ }
+ if (dimensions > 1) {
+ if (yoffset < -((GLint)teximage->Border)) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexSubImage%dD(yoffset=%d)", dimensions, yoffset);
+ return GL_TRUE;
+ }
+ /* NOTE: we're adding the border here, not subtracting! */
+ if (yoffset + height > (GLint) (teximage->Height + teximage->Border)) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexSubImage%dD(yoffset+height)", dimensions);
+ return GL_TRUE;
+ }
+ }
+
+ if (dimensions > 2) {
+ if (zoffset < -((GLint)teximage->Border)) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexSubImage%dD(zoffset)", dimensions);
+ return GL_TRUE;
+ }
+ if (zoffset > (GLint) (teximage->Depth + teximage->Border)) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexSubImage%dD(zoffset+depth)", dimensions);
+ return GL_TRUE;
+ }
+ }
+
+ if (teximage->IsCompressed) {
+ if (!_mesa_source_buffer_exists(ctx, teximage->_BaseFormat)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glCopyTexSubImage%dD(missing readbuffer)", dimensions);
+ return GL_TRUE;
+ }
+
+ if (target != GL_TEXTURE_2D) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glCopyTexSubImage%d(target)", dimensions);
+ return GL_TRUE;
+ }
+ /* offset must be multiple of 4 */
+ if ((xoffset & 3) || (yoffset & 3)) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexSubImage%D(xoffset or yoffset)", dimensions);
+ return GL_TRUE;
+ }
+ /* size must be multiple of 4 */
+ if ((width & 3) != 0 && (GLuint) width != teximage->Width) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexSubImage%D(width)", dimensions);
+ return GL_TRUE;
+ }
+ if ((height & 3) != 0 && (GLuint) height != teximage->Height) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexSubImage%D(height)", dimensions);
+ return GL_TRUE;
+ }
+ }
+
+ if (teximage->InternalFormat == GL_YCBCR_MESA) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyTexSubImage2D");
+ return GL_TRUE;
+ }
+
+ if (teximage->_BaseFormat == GL_DEPTH_COMPONENT) {
+ if (!ctx->ReadBuffer->_DepthBuffer) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glCopyTexSubImage%D(no depth buffer)",
+ dimensions);
+ return GL_TRUE;
+ }
+ }
+ else if (teximage->_BaseFormat == GL_DEPTH_STENCIL_EXT) {
+ if (!ctx->ReadBuffer->_DepthBuffer || !ctx->ReadBuffer->_StencilBuffer) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glCopyTexSubImage%D(no depth/stencil buffer)",
+ dimensions);
+ return GL_TRUE;
+ }
+ }
+
+ /* if we get here, the parameters are OK */
+ return GL_FALSE;
+}
+
+
+/**
+ * Get texture image. Called by glGetTexImage.
+ *
+ * \param target texture target.
+ * \param level image level.
+ * \param format pixel data format for returned image.
+ * \param type pixel data type for returned image.
+ * \param pixels returned pixel data.
+ */
+void GLAPIENTRY
+_mesa_GetTexImage( GLenum target, GLint level, GLenum format,
+ GLenum type, GLvoid *pixels )
+{
+ const struct gl_texture_unit *texUnit;
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+ GLint maxLevels = 0;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ texUnit = &(ctx->Texture.Unit[ctx->Texture.CurrentUnit]);
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ if (!texObj || _mesa_is_proxy_texture(target)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(target)");
+ return;
+ }
+
+ maxLevels = _mesa_max_texture_levels(ctx, target);
+ ASSERT(maxLevels > 0); /* 0 indicates bad target, caught above */
+
+ if (level < 0 || level >= maxLevels) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexImage(level)" );
+ return;
+ }
+
+ if (_mesa_sizeof_packed_type(type) <= 0) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexImage(type)" );
+ return;
+ }
+
+ if (_mesa_components_in_format(format) <= 0 ||
+ format == GL_STENCIL_INDEX) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexImage(format)" );
+ return;
+ }
+
+ if (!ctx->Extensions.EXT_paletted_texture && is_index_format(format)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
+ }
+
+ if (!ctx->Extensions.SGIX_depth_texture &&
+ !ctx->Extensions.ARB_depth_texture && is_depth_format(format)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
+ }
+
+ if (!ctx->Extensions.MESA_ycbcr_texture && is_ycbcr_format(format)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
+ }
+
+ if (!ctx->Extensions.EXT_packed_depth_stencil
+ && is_depthstencil_format(format)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
+ }
+
+ if (!pixels)
+ return;
+
+ texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
+ if (!texImage) {
+ /* invalid mipmap level, not an error */
+ return;
+ }
+
+ /* Make sure the requested image format is compatible with the
+ * texture's format. Note that a color index texture can be converted
+ * to RGBA so that combo is allowed.
+ */
+ if (is_color_format(format)
+ && !is_color_format(texImage->TexFormat->BaseFormat)
+ && !is_index_format(texImage->TexFormat->BaseFormat)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
+ return;
+ }
+ else if (is_index_format(format)
+ && !is_index_format(texImage->TexFormat->BaseFormat)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
+ return;
+ }
+ else if (is_depth_format(format)
+ && !is_depth_format(texImage->TexFormat->BaseFormat)
+ && !is_depthstencil_format(texImage->TexFormat->BaseFormat)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
+ return;
+ }
+ else if (is_ycbcr_format(format)
+ && !is_ycbcr_format(texImage->TexFormat->BaseFormat)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
+ return;
+ }
+ else if (is_depthstencil_format(format)
+ && !is_depthstencil_format(texImage->TexFormat->BaseFormat)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
+ return;
+ }
+
+ /* typically, this will call _mesa_get_teximage() */
+ ctx->Driver.GetTexImage(ctx, target, level, format, type, pixels,
+ texObj, texImage);
+}
+
+
+
+/**
+ * Check if the given texture image is bound to any framebuffer objects
+ * and update/invalidate them.
+ * XXX We're only checking the currently bound framebuffer object for now.
+ * In the future, perhaps struct gl_texture_image should have a pointer (or
+ * list of pointers (yikes)) to the gl_framebuffer(s) which it's bound to.
+ */
+static void
+update_fbo_texture(GLcontext *ctx, struct gl_texture_object *texObj,
+ GLuint face, GLuint level)
+{
+ if (ctx->DrawBuffer->Name) {
+ GLuint i;
+ for (i = 0; i < BUFFER_COUNT; i++) {
+ struct gl_renderbuffer_attachment *att =
+ ctx->DrawBuffer->Attachment + i;
+ if (att->Type == GL_TEXTURE &&
+ att->Texture == texObj &&
+ att->TextureLevel == level &&
+ att->CubeMapFace == face) {
+ ASSERT(att->Texture->Image[att->CubeMapFace][att->TextureLevel]);
+ /* Tell driver about the new renderbuffer texture */
+ ctx->Driver.RenderTexture(ctx, ctx->DrawBuffer, att);
+ }
+ }
+ }
+}
+
+
+
+/*
+ * Called from the API. Note that width includes the border.
+ */
+void GLAPIENTRY
+_mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
+ GLsizei width, GLint border, GLenum format,
+ GLenum type, const GLvoid *pixels )
+{
+ GLsizei postConvWidth = width;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (is_color_format(internalFormat)) {
+ _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
+ }
+
+ if (target == GL_TEXTURE_1D) {
+ /* non-proxy target */
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+ const GLuint face = texture_face(target);
+
+ if (texture_error_check(ctx, target, level, internalFormat,
+ format, type, 1, postConvWidth, 1, 1, border)) {
+ return; /* error was recorded */
+ }
+
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ texImage = _mesa_get_tex_image(ctx, texUnit, target, level);
+
+ if (!texImage) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
+ return;
+ }
+ else if (texImage->Data) {
+ ctx->Driver.FreeTexImageData( ctx, texImage );
+ }
+ ASSERT(texImage->Data == NULL);
+ clear_teximage_fields(texImage); /* not really needed, but helpful */
+ _mesa_init_teximage_fields(ctx, target, texImage,
+ postConvWidth, 1, 1,
+ border, internalFormat);
+
+ if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
+ _mesa_update_state(ctx);
+
+ ASSERT(ctx->Driver.TexImage1D);
+
+ /* Give the texture to the driver! <pixels> may be null! */
+ (*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat,
+ width, border, format, type, pixels,
+ &ctx->Unpack, texObj, texImage);
+
+ ASSERT(texImage->TexFormat);
+
+ update_fbo_texture(ctx, texObj, face, level);
+
+ /* state update */
+ texObj->Complete = GL_FALSE;
+ ctx->NewState |= _NEW_TEXTURE;
+ }
+ else if (target == GL_PROXY_TEXTURE_1D) {
+ /* Proxy texture: check for errors and update proxy state */
+ struct gl_texture_image *texImage;
+ texImage = _mesa_get_proxy_tex_image(ctx, target, level);
+ if (texture_error_check(ctx, target, level, internalFormat,
+ format, type, 1, postConvWidth, 1, 1, border)) {
+ /* when error, clear all proxy texture image parameters */
+ if (texImage)
+ clear_teximage_fields(texImage);
+ }
+ else {
+ /* no error, set the tex image parameters */
+ ASSERT(texImage);
+ _mesa_init_teximage_fields(ctx, target, texImage,
+ postConvWidth, 1, 1,
+ border, internalFormat);
+ texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
+ internalFormat, format, type);
+ }
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" );
+ return;
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
+ GLsizei width, GLsizei height, GLint border,
+ GLenum format, GLenum type,
+ const GLvoid *pixels )
+{
+ GLsizei postConvWidth = width, postConvHeight = height;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (is_color_format(internalFormat)) {
+ _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,
+ &postConvHeight);
+ }
+
+ if (target == GL_TEXTURE_2D ||
+ (ctx->Extensions.ARB_texture_cube_map &&
+ target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
+ target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) ||
+ (ctx->Extensions.NV_texture_rectangle &&
+ target == GL_TEXTURE_RECTANGLE_NV)) {
+ /* non-proxy target */
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+ const GLuint face = texture_face(target);
+
+ if (texture_error_check(ctx, target, level, internalFormat,
+ format, type, 2, postConvWidth, postConvHeight,
+ 1, border)) {
+ return; /* error was recorded */
+ }
+
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ texImage = _mesa_get_tex_image(ctx, texUnit, target, level);
+ if (!texImage) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
+ return;
+ }
+ else if (texImage->Data) {
+ ctx->Driver.FreeTexImageData( ctx, texImage );
+ }
+ ASSERT(texImage->Data == NULL);
+ clear_teximage_fields(texImage); /* not really needed, but helpful */
+ _mesa_init_teximage_fields(ctx, target, texImage,
+ postConvWidth, postConvHeight, 1,
+ border, internalFormat);
+
+ if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
+ _mesa_update_state(ctx);
+
+ ASSERT(ctx->Driver.TexImage2D);
+
+ /* Give the texture to the driver! <pixels> may be null! */
+ (*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat,
+ width, height, border, format, type, pixels,
+ &ctx->Unpack, texObj, texImage);
+
+ ASSERT(texImage->TexFormat);
+
+ update_fbo_texture(ctx, texObj, face, level);
+
+ /* state update */
+ texObj->Complete = GL_FALSE;
+ ctx->NewState |= _NEW_TEXTURE;
+ }
+ else if (target == GL_PROXY_TEXTURE_2D ||
+ (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB &&
+ ctx->Extensions.ARB_texture_cube_map) ||
+ (target == GL_PROXY_TEXTURE_RECTANGLE_NV &&
+ ctx->Extensions.NV_texture_rectangle)) {
+ /* Proxy texture: check for errors and update proxy state */
+ struct gl_texture_image *texImage;
+ texImage = _mesa_get_proxy_tex_image(ctx, target, level);
+ if (texture_error_check(ctx, target, level, internalFormat,
+ format, type, 2, postConvWidth, postConvHeight,
+ 1, border)) {
+ /* when error, clear all proxy texture image parameters */
+ if (texImage)
+ clear_teximage_fields(ctx->Texture.Proxy2D->Image[0][level]);
+ }
+ else {
+ /* no error, set the tex image parameters */
+ _mesa_init_teximage_fields(ctx, target, texImage,
+ postConvWidth, postConvHeight, 1,
+ border, internalFormat);
+ texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
+ internalFormat, format, type);
+ }
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage2D(target)" );
+ return;
+ }
+}
+
+
+/*
+ * Called by the API or display list executor.
+ * Note that width and height include the border.
+ */
+void GLAPIENTRY
+_mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLint border, GLenum format, GLenum type,
+ const GLvoid *pixels )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (target == GL_TEXTURE_3D) {
+ /* non-proxy target */
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+ const GLuint face = texture_face(target);
+
+ if (texture_error_check(ctx, target, level, (GLint) internalFormat,
+ format, type, 3, width, height, depth, border)) {
+ return; /* error was recorded */
+ }
+
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ texImage = _mesa_get_tex_image(ctx, texUnit, target, level);
+ if (!texImage) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
+ return;
+ }
+ else if (texImage->Data) {
+ ctx->Driver.FreeTexImageData( ctx, texImage );
+ }
+ ASSERT(texImage->Data == NULL);
+ clear_teximage_fields(texImage); /* not really needed, but helpful */
+ _mesa_init_teximage_fields(ctx, target, texImage,
+ width, height, depth,
+ border, internalFormat);
+
+ if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
+ _mesa_update_state(ctx);
+
+ ASSERT(ctx->Driver.TexImage3D);
+
+ /* Give the texture to the driver! <pixels> may be null! */
+ (*ctx->Driver.TexImage3D)(ctx, target, level, internalFormat,
+ width, height, depth, border, format, type,
+ pixels, &ctx->Unpack, texObj, texImage);
+
+ ASSERT(texImage->TexFormat);
+
+ update_fbo_texture(ctx, texObj, face, level);
+
+ /* state update */
+ texObj->Complete = GL_FALSE;
+ ctx->NewState |= _NEW_TEXTURE;
+ }
+ else if (target == GL_PROXY_TEXTURE_3D) {
+ /* Proxy texture: check for errors and update proxy state */
+ struct gl_texture_image *texImage;
+ texImage = _mesa_get_proxy_tex_image(ctx, target, level);
+ if (texture_error_check(ctx, target, level, internalFormat,
+ format, type, 3, width, height, depth, border)) {
+ /* when error, clear all proxy texture image parameters */
+ if (texImage)
+ clear_teximage_fields(texImage);
+ }
+ else {
+ /* no error, set the tex image parameters */
+ _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
+ border, internalFormat);
+ texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
+ internalFormat, format, type);
+ }
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage3D(target)" );
+ return;
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalFormat,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLint border, GLenum format, GLenum type,
+ const GLvoid *pixels )
+{
+ _mesa_TexImage3D(target, level, (GLint) internalFormat, width, height,
+ depth, border, format, type, pixels);
+}
+
+
+
+void GLAPIENTRY
+_mesa_TexSubImage1D( GLenum target, GLint level,
+ GLint xoffset, GLsizei width,
+ GLenum format, GLenum type,
+ const GLvoid *pixels )
+{
+ GLsizei postConvWidth = width;
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
+ _mesa_update_state(ctx);
+
+ /* XXX should test internal format */
+ if (is_color_format(format)) {
+ _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
+ }
+
+ if (subtexture_error_check(ctx, 1, target, level, xoffset, 0, 0,
+ postConvWidth, 1, 1, format, type)) {
+ return; /* error was detected */
+ }
+
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
+ assert(texImage);
+
+ if (width == 0)
+ return; /* no-op, not an error */
+
+ /* If we have a border, xoffset=-1 is legal. Bias by border width */
+ xoffset += texImage->Border;
+
+ ASSERT(ctx->Driver.TexSubImage1D);
+ (*ctx->Driver.TexSubImage1D)(ctx, target, level, xoffset, width,
+ format, type, pixels, &ctx->Unpack,
+ texObj, texImage);
+ ctx->NewState |= _NEW_TEXTURE;
+}
+
+
+void GLAPIENTRY
+_mesa_TexSubImage2D( GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const GLvoid *pixels )
+{
+ GLsizei postConvWidth = width, postConvHeight = height;
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
+ _mesa_update_state(ctx);
+
+ /* XXX should test internal format */
+ if (is_color_format(format)) {
+ _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,
+ &postConvHeight);
+ }
+
+ if (subtexture_error_check(ctx, 2, target, level, xoffset, yoffset, 0,
+ postConvWidth, postConvHeight, 1, format, type)) {
+ return; /* error was detected */
+ }
+
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
+ assert(texImage);
+
+ if (width == 0 || height == 0)
+ return; /* no-op, not an error */
+
+ /* If we have a border, xoffset=-1 is legal. Bias by border width */
+ xoffset += texImage->Border;
+ yoffset += texImage->Border;
+
+ ASSERT(ctx->Driver.TexSubImage2D);
+ (*ctx->Driver.TexSubImage2D)(ctx, target, level, xoffset, yoffset,
+ width, height, format, type, pixels,
+ &ctx->Unpack, texObj, texImage);
+ ctx->NewState |= _NEW_TEXTURE;
+}
+
+
+
+void GLAPIENTRY
+_mesa_TexSubImage3D( GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type,
+ const GLvoid *pixels )
+{
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
+ _mesa_update_state(ctx);
+
+ if (subtexture_error_check(ctx, 3, target, level, xoffset, yoffset, zoffset,
+ width, height, depth, format, type)) {
+ return; /* error was detected */
+ }
+
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
+ assert(texImage);
+
+ if (width == 0 || height == 0 || height == 0)
+ return; /* no-op, not an error */
+
+ /* If we have a border, xoffset=-1 is legal. Bias by border width */
+ xoffset += texImage->Border;
+ yoffset += texImage->Border;
+ zoffset += texImage->Border;
+
+ ASSERT(ctx->Driver.TexSubImage3D);
+ (*ctx->Driver.TexSubImage3D)(ctx, target, level,
+ xoffset, yoffset, zoffset,
+ width, height, depth,
+ format, type, pixels,
+ &ctx->Unpack, texObj, texImage );
+ ctx->NewState |= _NEW_TEXTURE;
+}
+
+
+
+void GLAPIENTRY
+_mesa_CopyTexImage1D( GLenum target, GLint level,
+ GLenum internalFormat,
+ GLint x, GLint y,
+ GLsizei width, GLint border )
+{
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+ GLsizei postConvWidth = width;
+ const GLuint face = texture_face(target);
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
+ _mesa_update_state(ctx);
+
+ if (is_color_format(internalFormat)) {
+ _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
+ }
+
+ if (copytexture_error_check(ctx, 1, target, level, internalFormat,
+ postConvWidth, 1, border))
+ return;
+
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ texImage = _mesa_get_tex_image(ctx, texUnit, target, level);
+ if (!texImage) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D");
+ return;
+ }
+ else if (texImage->Data) {
+ ctx->Driver.FreeTexImageData( ctx, texImage );
+ }
+ ASSERT(texImage->Data == NULL);
+
+ clear_teximage_fields(texImage); /* not really needed, but helpful */
+ _mesa_init_teximage_fields(ctx, target, texImage, postConvWidth, 1, 1,
+ border, internalFormat);
+
+
+ ASSERT(ctx->Driver.CopyTexImage1D);
+ (*ctx->Driver.CopyTexImage1D)(ctx, target, level, internalFormat,
+ x, y, width, border);
+
+ ASSERT(texImage->TexFormat);
+
+ update_fbo_texture(ctx, texObj, face, level);
+
+ /* state update */
+ texObj->Complete = GL_FALSE;
+ ctx->NewState |= _NEW_TEXTURE;
+}
+
+
+
+void GLAPIENTRY
+_mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
+ GLint x, GLint y, GLsizei width, GLsizei height,
+ GLint border )
+{
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+ GLsizei postConvWidth = width, postConvHeight = height;
+ const GLuint face = texture_face(target);
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
+ _mesa_update_state(ctx);
+
+ if (is_color_format(internalFormat)) {
+ _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,
+ &postConvHeight);
+ }
+
+ if (copytexture_error_check(ctx, 2, target, level, internalFormat,
+ postConvWidth, postConvHeight, border))
+ return;
+
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ texImage = _mesa_get_tex_image(ctx, texUnit, target, level);
+ if (!texImage) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D");
+ return;
+ }
+ else if (texImage->Data) {
+ ctx->Driver.FreeTexImageData( ctx, texImage );
+ }
+ ASSERT(texImage->Data == NULL);
+
+ clear_teximage_fields(texImage); /* not really needed, but helpful */
+ _mesa_init_teximage_fields(ctx, target, texImage,
+ postConvWidth, postConvHeight, 1,
+ border, internalFormat);
+
+ ASSERT(ctx->Driver.CopyTexImage2D);
+ (*ctx->Driver.CopyTexImage2D)(ctx, target, level, internalFormat,
+ x, y, width, height, border);
+
+ ASSERT(texImage->TexFormat);
+
+ update_fbo_texture(ctx, texObj, face, level);
+
+ /* state update */
+ texObj->Complete = GL_FALSE;
+ ctx->NewState |= _NEW_TEXTURE;
+}
+
+
+
+void GLAPIENTRY
+_mesa_CopyTexSubImage1D( GLenum target, GLint level,
+ GLint xoffset, GLint x, GLint y, GLsizei width )
+{
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_image *texImage;
+ GLsizei postConvWidth = width;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
+ _mesa_update_state(ctx);
+
+ /* XXX should test internal format */
+ _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
+
+ if (copytexsubimage_error_check(ctx, 1, target, level,
+ xoffset, 0, 0, postConvWidth, 1))
+ return;
+
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
+ ASSERT(texImage);
+
+ /* If we have a border, xoffset=-1 is legal. Bias by border width */
+ xoffset += texImage->Border;
+
+ ASSERT(ctx->Driver.CopyTexSubImage1D);
+ (*ctx->Driver.CopyTexSubImage1D)(ctx, target, level, xoffset, x, y, width);
+ ctx->NewState |= _NEW_TEXTURE;
+}
+
+
+
+void GLAPIENTRY
+_mesa_CopyTexSubImage2D( GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLint x, GLint y, GLsizei width, GLsizei height )
+{
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_image *texImage;
+ GLsizei postConvWidth = width, postConvHeight = height;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
+ _mesa_update_state(ctx);
+
+ /* XXX should test internal format */
+ _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, &postConvHeight);
+
+ if (copytexsubimage_error_check(ctx, 2, target, level, xoffset, yoffset, 0,
+ postConvWidth, postConvHeight))
+ return;
+
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
+ ASSERT(texImage);
+
+ /* If we have a border, xoffset=-1 is legal. Bias by border width */
+ xoffset += texImage->Border;
+ yoffset += texImage->Border;
+
+ ASSERT(ctx->Driver.CopyTexSubImage2D);
+ (*ctx->Driver.CopyTexSubImage2D)(ctx, target, level,
+ xoffset, yoffset, x, y, width, height);
+ ctx->NewState |= _NEW_TEXTURE;
+}
+
+
+
+void GLAPIENTRY
+_mesa_CopyTexSubImage3D( GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLint x, GLint y, GLsizei width, GLsizei height )
+{
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_image *texImage;
+ GLsizei postConvWidth = width, postConvHeight = height;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE)
+ _mesa_update_state(ctx);
+
+ /* XXX should test internal format */
+ _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, &postConvHeight);
+
+ if (copytexsubimage_error_check(ctx, 3, target, level, xoffset, yoffset,
+ zoffset, postConvWidth, postConvHeight))
+ return;
+
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
+ ASSERT(texImage);
+
+ /* If we have a border, xoffset=-1 is legal. Bias by border width */
+ xoffset += texImage->Border;
+ yoffset += texImage->Border;
+ zoffset += texImage->Border;
+
+ ASSERT(ctx->Driver.CopyTexSubImage3D);
+ (*ctx->Driver.CopyTexSubImage3D)(ctx, target, level,
+ xoffset, yoffset, zoffset,
+ x, y, width, height);
+ ctx->NewState |= _NEW_TEXTURE;
+}
+
+
+
+
+/**********************************************************************/
+/****** Compressed Textures ******/
+/**********************************************************************/
+
+
+/**
+ * Error checking for glCompressedTexImage[123]D().
+ * \return error code or GL_NO_ERROR.
+ */
+static GLenum
+compressed_texture_error_check(GLcontext *ctx, GLint dimensions,
+ GLenum target, GLint level,
+ GLenum internalFormat, GLsizei width,
+ GLsizei height, GLsizei depth, GLint border,
+ GLsizei imageSize)
+{
+ GLint expectedSize, maxLevels = 0, maxTextureSize;
+
+ if (dimensions == 1) {
+ /* 1D compressed textures not allowed */
+ return GL_INVALID_ENUM;
+ }
+ else if (dimensions == 2) {
+ if (target == GL_PROXY_TEXTURE_2D) {
+ maxLevels = ctx->Const.MaxTextureLevels;
+ }
+ else if (target == GL_TEXTURE_2D) {
+ maxLevels = ctx->Const.MaxTextureLevels;
+ }
+ else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB) {
+ if (!ctx->Extensions.ARB_texture_cube_map)
+ return GL_INVALID_ENUM; /*target*/
+ maxLevels = ctx->Const.MaxCubeTextureLevels;
+ }
+ else if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
+ target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
+ if (!ctx->Extensions.ARB_texture_cube_map)
+ return GL_INVALID_ENUM; /*target*/
+ maxLevels = ctx->Const.MaxCubeTextureLevels;
+ }
+ else {
+ return GL_INVALID_ENUM; /*target*/
+ }
+ }
+ else if (dimensions == 3) {
+ /* 3D compressed textures not allowed */
+ return GL_INVALID_ENUM;
+ }
+
+ maxTextureSize = 1 << (maxLevels - 1);
+
+ if (!is_compressed_format(ctx, internalFormat))
+ return GL_INVALID_ENUM;
+
+ if (_mesa_base_tex_format(ctx, internalFormat) < 0)
+ return GL_INVALID_ENUM;
+
+ if (border != 0)
+ return GL_INVALID_VALUE;
+
+ /*
+ * XXX We should probably use the proxy texture error check function here.
+ */
+ if (width < 1 || width > maxTextureSize ||
+ (!ctx->Extensions.ARB_texture_non_power_of_two && _mesa_bitcount(width) != 1))
+ return GL_INVALID_VALUE;
+
+ if ((height < 1 || height > maxTextureSize ||
+ (!ctx->Extensions.ARB_texture_non_power_of_two && _mesa_bitcount(height) != 1))
+ && dimensions > 1)
+ return GL_INVALID_VALUE;
+
+ if ((depth < 1 || depth > maxTextureSize ||
+ (!ctx->Extensions.ARB_texture_non_power_of_two && _mesa_bitcount(depth) != 1))
+ && dimensions > 2)
+ return GL_INVALID_VALUE;
+
+ /* For cube map, width must equal height */
+ if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
+ target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB && width != height)
+ return GL_INVALID_VALUE;
+
+ if (level < 0 || level >= maxLevels)
+ return GL_INVALID_VALUE;
+
+ expectedSize = ctx->Driver.CompressedTextureSize(ctx, width, height, depth,
+ internalFormat);
+ if (expectedSize != imageSize)
+ return GL_INVALID_VALUE;
+
+ return GL_NO_ERROR;
+}
+
+
+/**
+ * Error checking for glCompressedTexSubImage[123]D().
+ * \warning There are some bad assumptions here about the size of compressed
+ * texture tiles (multiple of 4) used to test the validity of the
+ * offset and size parameters.
+ * \return error code or GL_NO_ERROR.
+ */
+static GLenum
+compressed_subtexture_error_check(GLcontext *ctx, GLint dimensions,
+ GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLsizei imageSize)
+{
+ GLint expectedSize, maxLevels = 0, maxTextureSize;
+ (void) zoffset;
+
+ if (dimensions == 1) {
+ /* 1D compressed textures not allowed */
+ return GL_INVALID_ENUM;
+ }
+ else if (dimensions == 2) {
+ if (target == GL_PROXY_TEXTURE_2D) {
+ maxLevels = ctx->Const.MaxTextureLevels;
+ }
+ else if (target == GL_TEXTURE_2D) {
+ maxLevels = ctx->Const.MaxTextureLevels;
+ }
+ else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB) {
+ if (!ctx->Extensions.ARB_texture_cube_map)
+ return GL_INVALID_ENUM; /*target*/
+ maxLevels = ctx->Const.MaxCubeTextureLevels;
+ }
+ else if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
+ target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
+ if (!ctx->Extensions.ARB_texture_cube_map)
+ return GL_INVALID_ENUM; /*target*/
+ maxLevels = ctx->Const.MaxCubeTextureLevels;
+ }
+ else {
+ return GL_INVALID_ENUM; /*target*/
+ }
+ }
+ else if (dimensions == 3) {
+ /* 3D compressed textures not allowed */
+ return GL_INVALID_ENUM;
+ }
+
+ maxTextureSize = 1 << (maxLevels - 1);
+
+ if (!is_compressed_format(ctx, format))
+ return GL_INVALID_ENUM;
+
+ if (width < 1 || width > maxTextureSize)
+ return GL_INVALID_VALUE;
+
+ if ((height < 1 || height > maxTextureSize)
+ && dimensions > 1)
+ return GL_INVALID_VALUE;
+
+ if (level < 0 || level >= maxLevels)
+ return GL_INVALID_VALUE;
+
+ /* XXX these tests are specific to the compressed format.
+ * this code should be generalized in some way.
+ */
+ if ((xoffset & 3) != 0 || (yoffset & 3) != 0)
+ return GL_INVALID_VALUE;
+
+ if ((width & 3) != 0 && width != 2 && width != 1)
+ return GL_INVALID_VALUE;
+
+ if ((height & 3) != 0 && height != 2 && height != 1)
+ return GL_INVALID_VALUE;
+
+ expectedSize = ctx->Driver.CompressedTextureSize(ctx, width, height, depth,
+ format);
+ if (expectedSize != imageSize)
+ return GL_INVALID_VALUE;
+
+ return GL_NO_ERROR;
+}
+
+
+
+void GLAPIENTRY
+_mesa_CompressedTexImage1DARB(GLenum target, GLint level,
+ GLenum internalFormat, GLsizei width,
+ GLint border, GLsizei imageSize,
+ const GLvoid *data)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (target == GL_TEXTURE_1D) {
+ /* non-proxy target */
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+ GLenum error = compressed_texture_error_check(ctx, 1, target, level,
+ internalFormat, width, 1, 1, border, imageSize);
+ if (error) {
+ _mesa_error(ctx, error, "glCompressedTexImage1D");
+ return;
+ }
+
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ texImage = _mesa_get_tex_image(ctx, texUnit, target, level);
+ if (!texImage) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage1D");
+ return;
+ }
+ else if (texImage->Data) {
+ ctx->Driver.FreeTexImageData( ctx, texImage );
+ }
+ ASSERT(texImage->Data == NULL);
+
+ _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1,
+ border, internalFormat);
+
+ ASSERT(ctx->Driver.CompressedTexImage1D);
+ (*ctx->Driver.CompressedTexImage1D)(ctx, target, level,
+ internalFormat, width, border,
+ imageSize, data,
+ texObj, texImage);
+
+ /* state update */
+ texObj->Complete = GL_FALSE;
+ ctx->NewState |= _NEW_TEXTURE;
+ }
+ else if (target == GL_PROXY_TEXTURE_1D) {
+ /* Proxy texture: check for errors and update proxy state */
+ GLenum error = compressed_texture_error_check(ctx, 1, target, level,
+ internalFormat, width, 1, 1, border, imageSize);
+ if (!error) {
+ ASSERT(ctx->Driver.TestProxyTexImage);
+ error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
+ internalFormat, GL_NONE, GL_NONE,
+ width, 1, 1, border);
+ }
+ if (error) {
+ /* if error, clear all proxy texture image parameters */
+ struct gl_texture_image *texImage;
+ texImage = _mesa_get_proxy_tex_image(ctx, target, level);
+ if (texImage)
+ clear_teximage_fields(texImage);
+ }
+ else {
+ /* store the teximage parameters */
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_image *texImage;
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
+ _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1,
+ border, internalFormat);
+ }
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage1D(target)");
+ return;
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_CompressedTexImage2DARB(GLenum target, GLint level,
+ GLenum internalFormat, GLsizei width,
+ GLsizei height, GLint border, GLsizei imageSize,
+ const GLvoid *data)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (target == GL_TEXTURE_2D ||
+ (ctx->Extensions.ARB_texture_cube_map &&
+ target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
+ target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) {
+ /* non-proxy target */
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+ GLenum error = compressed_texture_error_check(ctx, 2, target, level,
+ internalFormat, width, height, 1, border, imageSize);
+ if (error) {
+ _mesa_error(ctx, error, "glCompressedTexImage2D");
+ return;
+ }
+
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ texImage = _mesa_get_tex_image(ctx, texUnit, target, level);
+ if (!texImage) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
+ return;
+ }
+ else if (texImage->Data) {
+ ctx->Driver.FreeTexImageData( ctx, texImage );
+ }
+ ASSERT(texImage->Data == NULL);
+
+ _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
+ border, internalFormat);
+
+ ASSERT(ctx->Driver.CompressedTexImage2D);
+ (*ctx->Driver.CompressedTexImage2D)(ctx, target, level,
+ internalFormat, width, height,
+ border, imageSize, data,
+ texObj, texImage);
+
+ /* state update */
+ texObj->Complete = GL_FALSE;
+ ctx->NewState |= _NEW_TEXTURE;
+ }
+ else if (target == GL_PROXY_TEXTURE_2D ||
+ (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB &&
+ ctx->Extensions.ARB_texture_cube_map)) {
+ /* Proxy texture: check for errors and update proxy state */
+ GLenum error = compressed_texture_error_check(ctx, 2, target, level,
+ internalFormat, width, height, 1, border, imageSize);
+ if (!error) {
+ ASSERT(ctx->Driver.TestProxyTexImage);
+ error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
+ internalFormat, GL_NONE, GL_NONE,
+ width, height, 1, border);
+ }
+ if (error) {
+ /* if error, clear all proxy texture image parameters */
+ struct gl_texture_image *texImage;
+ texImage = _mesa_get_proxy_tex_image(ctx, target, level);
+ if (texImage)
+ clear_teximage_fields(texImage);
+ }
+ else {
+ /* store the teximage parameters */
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_image *texImage;
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
+ _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
+ border, internalFormat);
+ }
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage2D(target)");
+ return;
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_CompressedTexImage3DARB(GLenum target, GLint level,
+ GLenum internalFormat, GLsizei width,
+ GLsizei height, GLsizei depth, GLint border,
+ GLsizei imageSize, const GLvoid *data)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (target == GL_TEXTURE_3D) {
+ /* non-proxy target */
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+ GLenum error = compressed_texture_error_check(ctx, 3, target, level,
+ internalFormat, width, height, depth, border, imageSize);
+ if (error) {
+ _mesa_error(ctx, error, "glCompressedTexImage3D");
+ return;
+ }
+
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ texImage = _mesa_get_tex_image(ctx, texUnit, target, level);
+ if (!texImage) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage3D");
+ return;
+ }
+ else if (texImage->Data) {
+ ctx->Driver.FreeTexImageData( ctx, texImage );
+ }
+ ASSERT(texImage->Data == NULL);
+
+ _mesa_init_teximage_fields(ctx, target, texImage, width, height, depth,
+ border, internalFormat);
+
+ ASSERT(ctx->Driver.CompressedTexImage3D);
+ (*ctx->Driver.CompressedTexImage3D)(ctx, target, level,
+ internalFormat,
+ width, height, depth,
+ border, imageSize, data,
+ texObj, texImage);
+
+ /* state update */
+ texObj->Complete = GL_FALSE;
+ ctx->NewState |= _NEW_TEXTURE;
+ }
+ else if (target == GL_PROXY_TEXTURE_3D) {
+ /* Proxy texture: check for errors and update proxy state */
+ GLenum error = compressed_texture_error_check(ctx, 3, target, level,
+ internalFormat, width, height, depth, border, imageSize);
+ if (!error) {
+ ASSERT(ctx->Driver.TestProxyTexImage);
+ error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
+ internalFormat, GL_NONE, GL_NONE,
+ width, height, depth, border);
+ }
+ if (error) {
+ /* if error, clear all proxy texture image parameters */
+ struct gl_texture_image *texImage;
+ texImage = _mesa_get_proxy_tex_image(ctx, target, level);
+ if (texImage)
+ clear_teximage_fields(texImage);
+ }
+ else {
+ /* store the teximage parameters */
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_image *texImage;
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
+ _mesa_init_teximage_fields(ctx, target, texImage, width, height,
+ depth, border, internalFormat);
+ }
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage3D(target)");
+ return;
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
+ GLsizei width, GLenum format,
+ GLsizei imageSize, const GLvoid *data)
+{
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+ GLenum error;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ error = compressed_subtexture_error_check(ctx, 1, target, level,
+ xoffset, 0, 0, width, 1, 1, format, imageSize);
+ if (error) {
+ _mesa_error(ctx, error, "glCompressedTexSubImage1D");
+ return;
+ }
+
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
+ assert(texImage);
+
+ if ((GLint) format != texImage->InternalFormat) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glCompressedTexSubImage1D(format)");
+ return;
+ }
+
+ if ((width == 1 || width == 2) && (GLuint) width != texImage->Width) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage1D(width)");
+ return;
+ }
+
+ if (width == 0)
+ return; /* no-op, not an error */
+
+ if (ctx->Driver.CompressedTexSubImage1D) {
+ (*ctx->Driver.CompressedTexSubImage1D)(ctx, target, level,
+ xoffset, width,
+ format, imageSize, data,
+ texObj, texImage);
+ }
+ ctx->NewState |= _NEW_TEXTURE;
+}
+
+
+void GLAPIENTRY
+_mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
+ GLint yoffset, GLsizei width, GLsizei height,
+ GLenum format, GLsizei imageSize,
+ const GLvoid *data)
+{
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+ GLenum error;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ error = compressed_subtexture_error_check(ctx, 2, target, level,
+ xoffset, yoffset, 0, width, height, 1, format, imageSize);
+ if (error) {
+ /* XXX proxy target? */
+ _mesa_error(ctx, error, "glCompressedTexSubImage2D");
+ return;
+ }
+
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
+ assert(texImage);
+
+ if ((GLint) format != texImage->InternalFormat) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glCompressedTexSubImage2D(format)");
+ return;
+ }
+
+ if (((width == 1 || width == 2) && (GLuint) width != texImage->Width) ||
+ ((height == 1 || height == 2) && (GLuint) height != texImage->Height)) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage2D(size)");
+ return;
+ }
+
+ if (width == 0 || height == 0)
+ return; /* no-op, not an error */
+
+ if (ctx->Driver.CompressedTexSubImage2D) {
+ (*ctx->Driver.CompressedTexSubImage2D)(ctx, target, level,
+ xoffset, yoffset, width, height,
+ format, imageSize, data,
+ texObj, texImage);
+ }
+ ctx->NewState |= _NEW_TEXTURE;
+}
+
+
+void GLAPIENTRY
+_mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
+ GLint yoffset, GLint zoffset, GLsizei width,
+ GLsizei height, GLsizei depth, GLenum format,
+ GLsizei imageSize, const GLvoid *data)
+{
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+ GLenum error;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ error = compressed_subtexture_error_check(ctx, 3, target, level,
+ xoffset, yoffset, zoffset, width, height, depth, format, imageSize);
+ if (error) {
+ _mesa_error(ctx, error, "glCompressedTexSubImage2D");
+ return;
+ }
+
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
+ assert(texImage);
+
+ if ((GLint) format != texImage->InternalFormat) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glCompressedTexSubImage3D(format)");
+ return;
+ }
+
+ if (((width == 1 || width == 2) && (GLuint) width != texImage->Width) ||
+ ((height == 1 || height == 2) && (GLuint) height != texImage->Height) ||
+ ((depth == 1 || depth == 2) && (GLuint) depth != texImage->Depth)) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage3D(size)");
+ return;
+ }
+
+ if (width == 0 || height == 0 || depth == 0)
+ return; /* no-op, not an error */
+
+ if (ctx->Driver.CompressedTexSubImage3D) {
+ (*ctx->Driver.CompressedTexSubImage3D)(ctx, target, level,
+ xoffset, yoffset, zoffset,
+ width, height, depth,
+ format, imageSize, data,
+ texObj, texImage);
+ }
+ ctx->NewState |= _NEW_TEXTURE;
+}
+
+
+void GLAPIENTRY
+_mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img)
+{
+ const struct gl_texture_unit *texUnit;
+ const struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+ GLint maxLevels;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ if (!texObj) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB");
+ return;
+ }
+
+ maxLevels = _mesa_max_texture_levels(ctx, target);
+ ASSERT(maxLevels > 0); /* 0 indicates bad target, caught above */
+
+ if (level < 0 || level >= maxLevels) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glGetCompressedTexImageARB(level)");
+ return;
+ }
+
+ if (_mesa_is_proxy_texture(target)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB(target)");
+ return;
+ }
+
+ texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
+ if (!texImage) {
+ /* probably invalid mipmap level */
+ _mesa_error(ctx, GL_INVALID_VALUE, "glGetCompressedTexImageARB(level)");
+ return;
+ }
+
+ if (!texImage->IsCompressed) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetCompressedTexImageARB");
+ return;
+ }
+
+ /* this typically calls _mesa_get_compressed_teximage() */
+ ctx->Driver.GetCompressedTexImage(ctx, target, level, img, texObj,texImage);
+}
diff --git a/src/mesa/main/teximage.h b/src/mesa/main/teximage.h
new file mode 100644
index 00000000000..410789fe046
--- /dev/null
+++ b/src/mesa/main/teximage.h
@@ -0,0 +1,242 @@
+/**
+ * \file teximage.h
+ * Texture images manipulation functions.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef TEXIMAGE_H
+#define TEXIMAGE_H
+
+
+#include "mtypes.h"
+
+
+extern void *
+_mesa_alloc_texmemory(GLsizei bytes);
+
+extern void
+_mesa_free_texmemory(void *m);
+
+
+/** \name Internal functions */
+/*@{*/
+
+extern GLint
+_mesa_base_tex_format( GLcontext *ctx, GLint internalFormat );
+
+
+extern GLboolean
+_mesa_is_proxy_texture(GLenum target);
+
+
+extern struct gl_texture_image *
+_mesa_new_texture_image( GLcontext *ctx );
+
+
+extern void
+_mesa_delete_texture_image( GLcontext *ctx, struct gl_texture_image *teximage );
+
+extern void
+_mesa_free_texture_image_data( GLcontext *ctx,
+ struct gl_texture_image *texImage );
+
+
+extern void
+_mesa_init_teximage_fields(GLcontext *ctx, GLenum target,
+ struct gl_texture_image *img,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLint border, GLenum internalFormat);
+
+
+extern void
+_mesa_set_tex_image(struct gl_texture_object *tObj,
+ GLenum target, GLint level,
+ struct gl_texture_image *texImage);
+
+
+extern struct gl_texture_object *
+_mesa_select_tex_object(GLcontext *ctx, const struct gl_texture_unit *texUnit,
+ GLenum target);
+
+
+extern struct gl_texture_image *
+_mesa_select_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit,
+ GLenum target, GLint level);
+
+
+extern struct gl_texture_image *
+_mesa_get_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit,
+ GLenum target, GLint level);
+
+
+extern struct gl_texture_image *
+_mesa_get_proxy_tex_image(GLcontext *ctx, GLenum target, GLint level);
+
+
+extern GLint
+_mesa_max_texture_levels(GLcontext *ctx, GLenum target);
+
+
+extern GLboolean
+_mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level,
+ GLint internalFormat, GLenum format, GLenum type,
+ GLint width, GLint height, GLint depth, GLint border);
+
+/*@}*/
+
+
+/** \name API entry point functions */
+/*@{*/
+
+extern void GLAPIENTRY
+_mesa_TexImage1D( GLenum target, GLint level, GLint internalformat,
+ GLsizei width, GLint border,
+ GLenum format, GLenum type, const GLvoid *pixels );
+
+
+extern void GLAPIENTRY
+_mesa_TexImage2D( GLenum target, GLint level, GLint internalformat,
+ GLsizei width, GLsizei height, GLint border,
+ GLenum format, GLenum type, const GLvoid *pixels );
+
+
+extern void GLAPIENTRY
+_mesa_TexImage3D( GLenum target, GLint level, GLint internalformat,
+ GLsizei width, GLsizei height, GLsizei depth, GLint border,
+ GLenum format, GLenum type, const GLvoid *pixels );
+
+
+extern void GLAPIENTRY
+_mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalformat,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLint border, GLenum format, GLenum type,
+ const GLvoid *pixels );
+
+
+extern void GLAPIENTRY
+_mesa_GetTexImage( GLenum target, GLint level,
+ GLenum format, GLenum type, GLvoid *pixels );
+
+
+extern void GLAPIENTRY
+_mesa_TexSubImage1D( GLenum target, GLint level, GLint xoffset,
+ GLsizei width,
+ GLenum format, GLenum type,
+ const GLvoid *pixels );
+
+
+extern void GLAPIENTRY
+_mesa_TexSubImage2D( GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const GLvoid *pixels );
+
+
+extern void GLAPIENTRY
+_mesa_TexSubImage3D( GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type,
+ const GLvoid *pixels );
+
+
+extern void GLAPIENTRY
+_mesa_CopyTexImage1D( GLenum target, GLint level, GLenum internalformat,
+ GLint x, GLint y, GLsizei width, GLint border );
+
+
+extern void GLAPIENTRY
+_mesa_CopyTexImage2D( GLenum target, GLint level,
+ GLenum internalformat, GLint x, GLint y,
+ GLsizei width, GLsizei height, GLint border );
+
+
+extern void GLAPIENTRY
+_mesa_CopyTexSubImage1D( GLenum target, GLint level, GLint xoffset,
+ GLint x, GLint y, GLsizei width );
+
+
+extern void GLAPIENTRY
+_mesa_CopyTexSubImage2D( GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLint x, GLint y, GLsizei width, GLsizei height );
+
+
+extern void GLAPIENTRY
+_mesa_CopyTexSubImage3D( GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLint x, GLint y, GLsizei width, GLsizei height );
+
+
+
+extern void GLAPIENTRY
+_mesa_CompressedTexImage1DARB(GLenum target, GLint level,
+ GLenum internalformat, GLsizei width,
+ GLint border, GLsizei imageSize,
+ const GLvoid *data);
+
+extern void GLAPIENTRY
+_mesa_CompressedTexImage2DARB(GLenum target, GLint level,
+ GLenum internalformat, GLsizei width,
+ GLsizei height, GLint border, GLsizei imageSize,
+ const GLvoid *data);
+
+extern void GLAPIENTRY
+_mesa_CompressedTexImage3DARB(GLenum target, GLint level,
+ GLenum internalformat, GLsizei width,
+ GLsizei height, GLsizei depth, GLint border,
+ GLsizei imageSize, const GLvoid *data);
+
+#ifdef VMS
+#define _mesa_CompressedTexSubImage1DARB _mesa_CompressedTexSubImage1DAR
+#define _mesa_CompressedTexSubImage2DARB _mesa_CompressedTexSubImage2DAR
+#define _mesa_CompressedTexSubImage3DARB _mesa_CompressedTexSubImage3DAR
+#endif
+extern void GLAPIENTRY
+_mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
+ GLsizei width, GLenum format,
+ GLsizei imageSize, const GLvoid *data);
+
+extern void GLAPIENTRY
+_mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
+ GLint yoffset, GLsizei width, GLsizei height,
+ GLenum format, GLsizei imageSize,
+ const GLvoid *data);
+
+extern void GLAPIENTRY
+_mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
+ GLint yoffset, GLint zoffset, GLsizei width,
+ GLsizei height, GLsizei depth, GLenum format,
+ GLsizei imageSize, const GLvoid *data);
+
+extern void GLAPIENTRY
+_mesa_GetCompressedTexImageARB(GLenum target, GLint lod, GLvoid *img);
+
+/*@}*/
+
+#endif
diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c
new file mode 100644
index 00000000000..cfe9229cdb1
--- /dev/null
+++ b/src/mesa/main/texobj.c
@@ -0,0 +1,1052 @@
+/**
+ * \file texobj.c
+ * Texture object management.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include "glheader.h"
+#include "colortab.h"
+#include "context.h"
+#include "enums.h"
+#include "fbobject.h"
+#include "hash.h"
+#include "imports.h"
+#include "macros.h"
+#include "teximage.h"
+#include "texstate.h"
+#include "texobj.h"
+#include "mtypes.h"
+
+
+#ifdef __VMS
+#define _mesa_sprintf sprintf
+#endif
+
+/**********************************************************************/
+/** \name Internal functions */
+/*@{*/
+
+
+/**
+ * Return the gl_texture_object for a given ID.
+ */
+struct gl_texture_object *
+_mesa_lookup_texture(GLcontext *ctx, GLuint id)
+{
+ return (struct gl_texture_object *)
+ _mesa_HashLookup(ctx->Shared->TexObjects, id);
+}
+
+
+
+/**
+ * Allocate and initialize a new texture object. But don't put it into the
+ * texture object hash table.
+ *
+ * Called via ctx->Driver.NewTextureObject, unless overridden by a device
+ * driver.
+ *
+ * \param shared the shared GL state structure to contain the texture object
+ * \param name integer name for the texture object
+ * \param target either GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D,
+ * GL_TEXTURE_CUBE_MAP_ARB or GL_TEXTURE_RECTANGLE_NV. zero is ok for the sake
+ * of GenTextures()
+ *
+ * \return pointer to new texture object.
+ */
+struct gl_texture_object *
+_mesa_new_texture_object( GLcontext *ctx, GLuint name, GLenum target )
+{
+ struct gl_texture_object *obj;
+ (void) ctx;
+ obj = MALLOC_STRUCT(gl_texture_object);
+ _mesa_initialize_texture_object(obj, name, target);
+ return obj;
+}
+
+
+/**
+ * Initialize a new texture object to default values.
+ * \param obj the texture object
+ * \param name the texture name
+ * \param target the texture target
+ */
+void
+_mesa_initialize_texture_object( struct gl_texture_object *obj,
+ GLuint name, GLenum target )
+{
+ ASSERT(target == 0 ||
+ target == GL_TEXTURE_1D ||
+ target == GL_TEXTURE_2D ||
+ target == GL_TEXTURE_3D ||
+ target == GL_TEXTURE_CUBE_MAP_ARB ||
+ target == GL_TEXTURE_RECTANGLE_NV);
+
+ _mesa_bzero(obj, sizeof(*obj));
+ /* init the non-zero fields */
+ _glthread_INIT_MUTEX(obj->Mutex);
+ obj->RefCount = 1;
+ obj->Name = name;
+ obj->Target = target;
+ obj->Priority = 1.0F;
+ if (target == GL_TEXTURE_RECTANGLE_NV) {
+ obj->WrapS = GL_CLAMP_TO_EDGE;
+ obj->WrapT = GL_CLAMP_TO_EDGE;
+ obj->WrapR = GL_CLAMP_TO_EDGE;
+ obj->MinFilter = GL_LINEAR;
+ }
+ else {
+ obj->WrapS = GL_REPEAT;
+ obj->WrapT = GL_REPEAT;
+ obj->WrapR = GL_REPEAT;
+ obj->MinFilter = GL_NEAREST_MIPMAP_LINEAR;
+ }
+ obj->MagFilter = GL_LINEAR;
+ obj->MinLod = -1000.0;
+ obj->MaxLod = 1000.0;
+ obj->LodBias = 0.0;
+ obj->BaseLevel = 0;
+ obj->MaxLevel = 1000;
+ obj->MaxAnisotropy = 1.0;
+ obj->CompareFlag = GL_FALSE; /* SGIX_shadow */
+ obj->CompareOperator = GL_TEXTURE_LEQUAL_R_SGIX; /* SGIX_shadow */
+ obj->CompareMode = GL_NONE; /* ARB_shadow */
+ obj->CompareFunc = GL_LEQUAL; /* ARB_shadow */
+ obj->DepthMode = GL_LUMINANCE; /* ARB_depth_texture */
+ obj->ShadowAmbient = 0.0F; /* ARB/SGIX_shadow_ambient */
+ _mesa_init_colortable(&obj->Palette);
+}
+
+
+/**
+ * Deallocate a texture object struct. It should have already been
+ * removed from the texture object pool.
+ *
+ * \param shared the shared GL state to which the object belongs.
+ * \param texOjb the texture object to delete.
+ */
+void
+_mesa_delete_texture_object( GLcontext *ctx, struct gl_texture_object *texObj )
+{
+ GLuint i, face;
+
+ (void) ctx;
+
+ _mesa_free_colortable_data(&texObj->Palette);
+
+ /* free the texture images */
+ for (face = 0; face < 6; face++) {
+ for (i = 0; i < MAX_TEXTURE_LEVELS; i++) {
+ if (texObj->Image[face][i]) {
+ _mesa_delete_texture_image( ctx, texObj->Image[face][i] );
+ }
+ }
+ }
+
+ /* destroy the mutex -- it may have allocated memory (eg on bsd) */
+ _glthread_DESTROY_MUTEX(texObj->Mutex);
+
+ /* free this object */
+ _mesa_free(texObj);
+}
+
+
+
+
+/**
+ * Copy texture object state from one texture object to another.
+ * Use for glPush/PopAttrib.
+ *
+ * \param dest destination texture object.
+ * \param src source texture object.
+ */
+void
+_mesa_copy_texture_object( struct gl_texture_object *dest,
+ const struct gl_texture_object *src )
+{
+ dest->Name = src->Name;
+ dest->Priority = src->Priority;
+ dest->BorderColor[0] = src->BorderColor[0];
+ dest->BorderColor[1] = src->BorderColor[1];
+ dest->BorderColor[2] = src->BorderColor[2];
+ dest->BorderColor[3] = src->BorderColor[3];
+ dest->WrapS = src->WrapS;
+ dest->WrapT = src->WrapT;
+ dest->WrapR = src->WrapR;
+ dest->MinFilter = src->MinFilter;
+ dest->MagFilter = src->MagFilter;
+ dest->MinLod = src->MinLod;
+ dest->MaxLod = src->MaxLod;
+ dest->LodBias = src->LodBias;
+ dest->BaseLevel = src->BaseLevel;
+ dest->MaxLevel = src->MaxLevel;
+ dest->MaxAnisotropy = src->MaxAnisotropy;
+ dest->CompareFlag = src->CompareFlag;
+ dest->CompareOperator = src->CompareOperator;
+ dest->ShadowAmbient = src->ShadowAmbient;
+ dest->CompareMode = src->CompareMode;
+ dest->CompareFunc = src->CompareFunc;
+ dest->DepthMode = src->DepthMode;
+ dest->_MaxLevel = src->_MaxLevel;
+ dest->_MaxLambda = src->_MaxLambda;
+ dest->GenerateMipmap = src->GenerateMipmap;
+ dest->Palette = src->Palette;
+ dest->Complete = src->Complete;
+}
+
+
+/**
+ * Report why a texture object is incomplete.
+ *
+ * \param t texture object.
+ * \param why string describing why it's incomplete.
+ *
+ * \note For debug purposes only.
+ */
+#if 0
+static void
+incomplete(const struct gl_texture_object *t, const char *why)
+{
+ _mesa_printf("Texture Obj %d incomplete because: %s\n", t->Name, why);
+}
+#else
+#define incomplete(t, why)
+#endif
+
+
+/**
+ * Examine a texture object to determine if it is complete.
+ *
+ * The gl_texture_object::Complete flag will be set to GL_TRUE or GL_FALSE
+ * accordingly.
+ *
+ * \param ctx GL context.
+ * \param t texture object.
+ *
+ * According to the texture target, verifies that each of the mipmaps is
+ * present and has the expected size.
+ */
+void
+_mesa_test_texobj_completeness( const GLcontext *ctx,
+ struct gl_texture_object *t )
+{
+ const GLint baseLevel = t->BaseLevel;
+ GLint maxLog2 = 0, maxLevels = 0;
+
+ t->Complete = GL_TRUE; /* be optimistic */
+
+ /* Always need the base level image */
+ if (!t->Image[0][baseLevel]) {
+ char s[100];
+ _mesa_sprintf(s, "obj %p (%d) Image[baseLevel=%d] == NULL",
+ (void *) t, t->Name, baseLevel);
+ incomplete(t, s);
+ t->Complete = GL_FALSE;
+ return;
+ }
+
+ /* Check width/height/depth for zero */
+ if (t->Image[0][baseLevel]->Width == 0 ||
+ t->Image[0][baseLevel]->Height == 0 ||
+ t->Image[0][baseLevel]->Depth == 0) {
+ incomplete(t, "texture width = 0");
+ t->Complete = GL_FALSE;
+ return;
+ }
+
+ /* Compute _MaxLevel */
+ if (t->Target == GL_TEXTURE_1D) {
+ maxLog2 = t->Image[0][baseLevel]->WidthLog2;
+ maxLevels = ctx->Const.MaxTextureLevels;
+ }
+ else if (t->Target == GL_TEXTURE_2D) {
+ maxLog2 = MAX2(t->Image[0][baseLevel]->WidthLog2,
+ t->Image[0][baseLevel]->HeightLog2);
+ maxLevels = ctx->Const.MaxTextureLevels;
+ }
+ else if (t->Target == GL_TEXTURE_3D) {
+ GLint max = MAX2(t->Image[0][baseLevel]->WidthLog2,
+ t->Image[0][baseLevel]->HeightLog2);
+ maxLog2 = MAX2(max, (GLint)(t->Image[0][baseLevel]->DepthLog2));
+ maxLevels = ctx->Const.Max3DTextureLevels;
+ }
+ else if (t->Target == GL_TEXTURE_CUBE_MAP_ARB) {
+ maxLog2 = MAX2(t->Image[0][baseLevel]->WidthLog2,
+ t->Image[0][baseLevel]->HeightLog2);
+ maxLevels = ctx->Const.MaxCubeTextureLevels;
+ }
+ else if (t->Target == GL_TEXTURE_RECTANGLE_NV) {
+ maxLog2 = 0; /* not applicable */
+ maxLevels = 1; /* no mipmapping */
+ }
+ else {
+ _mesa_problem(ctx, "Bad t->Target in _mesa_test_texobj_completeness");
+ return;
+ }
+
+ ASSERT(maxLevels > 0);
+
+ t->_MaxLevel = baseLevel + maxLog2;
+ t->_MaxLevel = MIN2(t->_MaxLevel, t->MaxLevel);
+ t->_MaxLevel = MIN2(t->_MaxLevel, maxLevels - 1);
+
+ /* Compute _MaxLambda = q - b (see the 1.2 spec) used during mipmapping */
+ t->_MaxLambda = (GLfloat) (t->_MaxLevel - t->BaseLevel);
+
+ if (t->Target == GL_TEXTURE_CUBE_MAP_ARB) {
+ /* make sure that all six cube map level 0 images are the same size */
+ const GLuint w = t->Image[0][baseLevel]->Width2;
+ const GLuint h = t->Image[0][baseLevel]->Height2;
+ GLuint face;
+ for (face = 1; face < 6; face++) {
+ if (t->Image[face][baseLevel] == NULL ||
+ t->Image[face][baseLevel]->Width2 != w ||
+ t->Image[face][baseLevel]->Height2 != h) {
+ t->Complete = GL_FALSE;
+ incomplete(t, "Non-quare cubemap image");
+ return;
+ }
+ }
+ }
+
+ /* extra checking for mipmaps */
+ if (t->MinFilter != GL_NEAREST && t->MinFilter != GL_LINEAR) {
+ /*
+ * Mipmapping: determine if we have a complete set of mipmaps
+ */
+ GLint i;
+ GLint minLevel = baseLevel;
+ GLint maxLevel = t->_MaxLevel;
+
+ if (minLevel > maxLevel) {
+ t->Complete = GL_FALSE;
+ incomplete(t, "minLevel > maxLevel");
+ return;
+ }
+
+ /* Test dimension-independent attributes */
+ for (i = minLevel; i <= maxLevel; i++) {
+ if (t->Image[0][i]) {
+ if (t->Image[0][i]->TexFormat != t->Image[0][baseLevel]->TexFormat) {
+ t->Complete = GL_FALSE;
+ incomplete(t, "Format[i] != Format[baseLevel]");
+ return;
+ }
+ if (t->Image[0][i]->Border != t->Image[0][baseLevel]->Border) {
+ t->Complete = GL_FALSE;
+ incomplete(t, "Border[i] != Border[baseLevel]");
+ return;
+ }
+ }
+ }
+
+ /* Test things which depend on number of texture image dimensions */
+ if (t->Target == GL_TEXTURE_1D) {
+ /* Test 1-D mipmaps */
+ GLuint width = t->Image[0][baseLevel]->Width2;
+ for (i = baseLevel + 1; i < maxLevels; i++) {
+ if (width > 1) {
+ width /= 2;
+ }
+ if (i >= minLevel && i <= maxLevel) {
+ if (!t->Image[0][i]) {
+ t->Complete = GL_FALSE;
+ incomplete(t, "1D Image[0][i] == NULL");
+ return;
+ }
+ if (t->Image[0][i]->Width2 != width ) {
+ t->Complete = GL_FALSE;
+ incomplete(t, "1D Image[0][i] bad width");
+ return;
+ }
+ }
+ if (width == 1) {
+ return; /* found smallest needed mipmap, all done! */
+ }
+ }
+ }
+ else if (t->Target == GL_TEXTURE_2D) {
+ /* Test 2-D mipmaps */
+ GLuint width = t->Image[0][baseLevel]->Width2;
+ GLuint height = t->Image[0][baseLevel]->Height2;
+ for (i = baseLevel + 1; i < maxLevels; i++) {
+ if (width > 1) {
+ width /= 2;
+ }
+ if (height > 1) {
+ height /= 2;
+ }
+ if (i >= minLevel && i <= maxLevel) {
+ if (!t->Image[0][i]) {
+ t->Complete = GL_FALSE;
+ incomplete(t, "2D Image[0][i] == NULL");
+ return;
+ }
+ if (t->Image[0][i]->Width2 != width) {
+ t->Complete = GL_FALSE;
+ incomplete(t, "2D Image[0][i] bad width");
+ return;
+ }
+ if (t->Image[0][i]->Height2 != height) {
+ t->Complete = GL_FALSE;
+ incomplete(t, "2D Image[0][i] bad height");
+ return;
+ }
+ if (width==1 && height==1) {
+ return; /* found smallest needed mipmap, all done! */
+ }
+ }
+ }
+ }
+ else if (t->Target == GL_TEXTURE_3D) {
+ /* Test 3-D mipmaps */
+ GLuint width = t->Image[0][baseLevel]->Width2;
+ GLuint height = t->Image[0][baseLevel]->Height2;
+ GLuint depth = t->Image[0][baseLevel]->Depth2;
+ for (i = baseLevel + 1; i < maxLevels; i++) {
+ if (width > 1) {
+ width /= 2;
+ }
+ if (height > 1) {
+ height /= 2;
+ }
+ if (depth > 1) {
+ depth /= 2;
+ }
+ if (i >= minLevel && i <= maxLevel) {
+ if (!t->Image[0][i]) {
+ incomplete(t, "3D Image[0][i] == NULL");
+ t->Complete = GL_FALSE;
+ return;
+ }
+ if (t->Image[0][i]->_BaseFormat == GL_DEPTH_COMPONENT) {
+ t->Complete = GL_FALSE;
+ incomplete(t, "GL_DEPTH_COMPONENT only works with 1/2D tex");
+ return;
+ }
+ if (t->Image[0][i]->Width2 != width) {
+ t->Complete = GL_FALSE;
+ incomplete(t, "3D Image[0][i] bad width");
+ return;
+ }
+ if (t->Image[0][i]->Height2 != height) {
+ t->Complete = GL_FALSE;
+ incomplete(t, "3D Image[0][i] bad height");
+ return;
+ }
+ if (t->Image[0][i]->Depth2 != depth) {
+ t->Complete = GL_FALSE;
+ incomplete(t, "3D Image[0][i] bad depth");
+ return;
+ }
+ }
+ if (width == 1 && height == 1 && depth == 1) {
+ return; /* found smallest needed mipmap, all done! */
+ }
+ }
+ }
+ else if (t->Target == GL_TEXTURE_CUBE_MAP_ARB) {
+ /* make sure 6 cube faces are consistant */
+ GLuint width = t->Image[0][baseLevel]->Width2;
+ GLuint height = t->Image[0][baseLevel]->Height2;
+ for (i = baseLevel + 1; i < maxLevels; i++) {
+ if (width > 1) {
+ width /= 2;
+ }
+ if (height > 1) {
+ height /= 2;
+ }
+ if (i >= minLevel && i <= maxLevel) {
+ GLuint face;
+ for (face = 0; face < 6; face++) {
+ /* check that we have images defined */
+ if (!t->Image[face][i]) {
+ t->Complete = GL_FALSE;
+ incomplete(t, "CubeMap Image[n][i] == NULL");
+ return;
+ }
+ /* Don't support GL_DEPTH_COMPONENT for cube maps */
+ if (t->Image[face][i]->_BaseFormat == GL_DEPTH_COMPONENT) {
+ t->Complete = GL_FALSE;
+ incomplete(t, "GL_DEPTH_COMPONENT only works with 1/2D tex");
+ return;
+ }
+ /* check that all six images have same size */
+ if (t->Image[face][i]->Width2!=width ||
+ t->Image[face][i]->Height2!=height) {
+ t->Complete = GL_FALSE;
+ incomplete(t, "CubeMap Image[n][i] bad size");
+ return;
+ }
+ }
+ }
+ if (width == 1 && height == 1) {
+ return; /* found smallest needed mipmap, all done! */
+ }
+ }
+ }
+ else if (t->Target == GL_TEXTURE_RECTANGLE_NV) {
+ /* XXX special checking? */
+ }
+ else {
+ /* Target = ??? */
+ _mesa_problem(ctx, "Bug in gl_test_texture_object_completeness\n");
+ }
+ }
+}
+
+/*@}*/
+
+
+/***********************************************************************/
+/** \name API functions */
+/*@{*/
+
+/**
+ * Texture name generation lock.
+ *
+ * Used by _mesa_GenTextures() to guarantee that the generation and allocation
+ * of texture IDs is atomic.
+ */
+_glthread_DECLARE_STATIC_MUTEX(GenTexturesLock);
+
+/**
+ * Generate texture names.
+ *
+ * \param n number of texture names to be generated.
+ * \param textures an array in which will hold the generated texture names.
+ *
+ * \sa glGenTextures().
+ *
+ * While holding the GenTexturesLock lock, calls _mesa_HashFindFreeKeyBlock()
+ * to find a block of free texture IDs which are stored in \p textures.
+ * Corresponding empty texture objects are also generated.
+ */
+void GLAPIENTRY
+_mesa_GenTextures( GLsizei n, GLuint *textures )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLuint first;
+ GLint i;
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (n < 0) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glGenTextures" );
+ return;
+ }
+
+ if (!textures)
+ return;
+
+ /*
+ * This must be atomic (generation and allocation of texture IDs)
+ */
+ _glthread_LOCK_MUTEX(GenTexturesLock);
+
+ first = _mesa_HashFindFreeKeyBlock(ctx->Shared->TexObjects, n);
+
+ /* Allocate new, empty texture objects */
+ for (i = 0; i < n; i++) {
+ struct gl_texture_object *texObj;
+ GLuint name = first + i;
+ GLenum target = 0;
+ texObj = (*ctx->Driver.NewTextureObject)( ctx, name, target);
+ if (!texObj) {
+ _glthread_UNLOCK_MUTEX(GenTexturesLock);
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenTextures");
+ return;
+ }
+
+ /* insert into hash table */
+ _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
+ _mesa_HashInsert(ctx->Shared->TexObjects, texObj->Name, texObj);
+ _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+
+ textures[i] = name;
+ }
+
+ _glthread_UNLOCK_MUTEX(GenTexturesLock);
+}
+
+
+/**
+ * Check if the given texture object is bound to the current draw or
+ * read framebuffer. If so, Unbind it.
+ */
+static void
+unbind_texobj_from_fbo(GLcontext *ctx, struct gl_texture_object *texObj)
+{
+ const GLuint n = (ctx->DrawBuffer == ctx->ReadBuffer) ? 1 : 2;
+ GLuint i;
+
+ for (i = 0; i < n; i++) {
+ struct gl_framebuffer *fb = (i == 0) ? ctx->DrawBuffer : ctx->ReadBuffer;
+ if (fb->Name) {
+ GLuint j;
+ for (j = 0; j < BUFFER_COUNT; j++) {
+ if (fb->Attachment[j].Type == GL_TEXTURE &&
+ fb->Attachment[j].Texture == texObj) {
+ _mesa_remove_attachment(ctx, fb->Attachment + j);
+ }
+ }
+ }
+ }
+}
+
+
+/**
+ * Check if the given texture object is bound to any texture image units and
+ * unbind it if so.
+ * XXX all RefCount accesses should be protected by a mutex.
+ */
+static void
+unbind_texobj_from_texunits(GLcontext *ctx, struct gl_texture_object *texObj)
+{
+ GLuint u;
+
+ for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++) {
+ struct gl_texture_unit *unit = &ctx->Texture.Unit[u];
+ if (texObj == unit->Current1D) {
+ unit->Current1D = ctx->Shared->Default1D;
+ ctx->Shared->Default1D->RefCount++;
+ texObj->RefCount--;
+ if (texObj == unit->_Current)
+ unit->_Current = unit->Current1D;
+ }
+ else if (texObj == unit->Current2D) {
+ unit->Current2D = ctx->Shared->Default2D;
+ ctx->Shared->Default2D->RefCount++;
+ texObj->RefCount--;
+ if (texObj == unit->_Current)
+ unit->_Current = unit->Current2D;
+ }
+ else if (texObj == unit->Current3D) {
+ unit->Current3D = ctx->Shared->Default3D;
+ ctx->Shared->Default3D->RefCount++;
+ texObj->RefCount--;
+ if (texObj == unit->_Current)
+ unit->_Current = unit->Current3D;
+ }
+ else if (texObj == unit->CurrentCubeMap) {
+ unit->CurrentCubeMap = ctx->Shared->DefaultCubeMap;
+ ctx->Shared->DefaultCubeMap->RefCount++;
+ texObj->RefCount--;
+ if (texObj == unit->_Current)
+ unit->_Current = unit->CurrentCubeMap;
+ }
+ else if (texObj == unit->CurrentRect) {
+ unit->CurrentRect = ctx->Shared->DefaultRect;
+ ctx->Shared->DefaultRect->RefCount++;
+ texObj->RefCount--;
+ if (texObj == unit->_Current)
+ unit->_Current = unit->CurrentRect;
+ }
+ }
+}
+
+
+/**
+ * Delete named textures.
+ *
+ * \param n number of textures to be deleted.
+ * \param textures array of texture IDs to be deleted.
+ *
+ * \sa glDeleteTextures().
+ *
+ * If we're about to delete a texture that's currently bound to any
+ * texture unit, unbind the texture first. Decrement the reference
+ * count on the texture object and delete it if it's zero.
+ * Recall that texture objects can be shared among several rendering
+ * contexts.
+ */
+void GLAPIENTRY
+_mesa_DeleteTextures( GLsizei n, const GLuint *textures)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint i;
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* too complex */
+
+ if (!textures)
+ return;
+
+ for (i = 0; i < n; i++) {
+ if (textures[i] > 0) {
+ struct gl_texture_object *delObj
+ = _mesa_lookup_texture(ctx, textures[i]);
+ if (delObj) {
+
+ /* Check if texture is bound to any framebuffer objects.
+ * If so, unbind.
+ * See section 4.4.2.3 of GL_EXT_framebuffer_object.
+ */
+ unbind_texobj_from_fbo(ctx, delObj);
+
+ /* Check if this texture is currently bound to any texture units.
+ * If so, unbind it and decrement the reference count.
+ */
+ unbind_texobj_from_texunits(ctx, delObj);
+
+ ctx->NewState |= _NEW_TEXTURE;
+
+ /* The texture _name_ is now free for re-use.
+ * Remove it from the hash table now.
+ */
+ _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
+ _mesa_HashRemove(ctx->Shared->TexObjects, delObj->Name);
+ _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+
+ /* The actual texture object will not be freed until it's no
+ * longer bound in any context.
+ * XXX all RefCount accesses should be protected by a mutex.
+ */
+ delObj->RefCount--;
+ if (delObj->RefCount == 0) {
+ ASSERT(delObj->Name != 0); /* Never delete default tex objs */
+ ASSERT(ctx->Driver.DeleteTexture);
+ (*ctx->Driver.DeleteTexture)(ctx, delObj);
+ }
+ }
+ }
+ }
+}
+
+
+/**
+ * Bind a named texture to a texturing target.
+ *
+ * \param target texture target.
+ * \param texName texture name.
+ *
+ * \sa glBindTexture().
+ *
+ * Determines the old texture object bound and returns immediately if rebinding
+ * the same texture. Get the current texture which is either a default texture
+ * if name is null, a named texture from the hash, or a new texture if the
+ * given texture name is new. Increments its reference count, binds it, and
+ * calls dd_function_table::BindTexture. Decrements the old texture reference
+ * count and deletes it if it reaches zero.
+ */
+void GLAPIENTRY
+_mesa_BindTexture( GLenum target, GLuint texName )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLuint unit = ctx->Texture.CurrentUnit;
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+ struct gl_texture_object *oldTexObj;
+ struct gl_texture_object *newTexObj = NULL;
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glBindTexture %s %d\n",
+ _mesa_lookup_enum_by_nr(target), (GLint) texName);
+
+ /*
+ * Get pointer to currently bound texture object (oldTexObj)
+ */
+ switch (target) {
+ case GL_TEXTURE_1D:
+ oldTexObj = texUnit->Current1D;
+ break;
+ case GL_TEXTURE_2D:
+ oldTexObj = texUnit->Current2D;
+ break;
+ case GL_TEXTURE_3D:
+ oldTexObj = texUnit->Current3D;
+ break;
+ case GL_TEXTURE_CUBE_MAP_ARB:
+ if (!ctx->Extensions.ARB_texture_cube_map) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" );
+ return;
+ }
+ oldTexObj = texUnit->CurrentCubeMap;
+ break;
+ case GL_TEXTURE_RECTANGLE_NV:
+ if (!ctx->Extensions.NV_texture_rectangle) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" );
+ return;
+ }
+ oldTexObj = texUnit->CurrentRect;
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" );
+ return;
+ }
+
+ if (oldTexObj->Name == texName)
+ /* XXX this might be wrong. If the texobj is in use by another
+ * context and a texobj parameter was changed, this might be our
+ * only chance to update this context's hardware state.
+ */
+ return; /* rebinding the same texture- no change */
+
+ /*
+ * Get pointer to new texture object (newTexObj)
+ */
+ if (texName == 0) {
+ /* newTexObj = a default texture object */
+ switch (target) {
+ case GL_TEXTURE_1D:
+ newTexObj = ctx->Shared->Default1D;
+ break;
+ case GL_TEXTURE_2D:
+ newTexObj = ctx->Shared->Default2D;
+ break;
+ case GL_TEXTURE_3D:
+ newTexObj = ctx->Shared->Default3D;
+ break;
+ case GL_TEXTURE_CUBE_MAP_ARB:
+ newTexObj = ctx->Shared->DefaultCubeMap;
+ break;
+ case GL_TEXTURE_RECTANGLE_NV:
+ newTexObj = ctx->Shared->DefaultRect;
+ break;
+ default:
+ ; /* Bad targets are caught above */
+ }
+ }
+ else {
+ /* non-default texture object */
+ newTexObj = _mesa_lookup_texture(ctx, texName);
+ if (newTexObj) {
+ /* error checking */
+ if (newTexObj->Target != 0 && newTexObj->Target != target) {
+ /* the named texture object's dimensions don't match the target */
+ _mesa_error( ctx, GL_INVALID_OPERATION,
+ "glBindTexture(wrong dimensionality)" );
+ return;
+ }
+ if (newTexObj->Target == 0 && target == GL_TEXTURE_RECTANGLE_NV) {
+ /* have to init wrap and filter state here - kind of klunky */
+ newTexObj->WrapS = GL_CLAMP_TO_EDGE;
+ newTexObj->WrapT = GL_CLAMP_TO_EDGE;
+ newTexObj->WrapR = GL_CLAMP_TO_EDGE;
+ newTexObj->MinFilter = GL_LINEAR;
+ if (ctx->Driver.TexParameter) {
+ static const GLfloat fparam_wrap[1] = {(GLfloat) GL_CLAMP_TO_EDGE};
+ static const GLfloat fparam_filter[1] = {(GLfloat) GL_LINEAR};
+ (*ctx->Driver.TexParameter)( ctx, target, newTexObj, GL_TEXTURE_WRAP_S, fparam_wrap );
+ (*ctx->Driver.TexParameter)( ctx, target, newTexObj, GL_TEXTURE_WRAP_T, fparam_wrap );
+ (*ctx->Driver.TexParameter)( ctx, target, newTexObj, GL_TEXTURE_WRAP_R, fparam_wrap );
+ (*ctx->Driver.TexParameter)( ctx, target, newTexObj, GL_TEXTURE_MIN_FILTER, fparam_filter );
+ }
+ }
+ }
+ else {
+ /* if this is a new texture id, allocate a texture object now */
+ newTexObj = (*ctx->Driver.NewTextureObject)(ctx, texName, target);
+ if (!newTexObj) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindTexture");
+ return;
+ }
+
+ /* and insert it into hash table */
+ _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
+ _mesa_HashInsert(ctx->Shared->TexObjects, texName, newTexObj);
+ _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+ }
+ newTexObj->Target = target;
+ }
+
+ /* XXX all RefCount accesses should be protected by a mutex. */
+ newTexObj->RefCount++;
+
+ /* do the actual binding, but first flush outstanding vertices:
+ */
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+
+ switch (target) {
+ case GL_TEXTURE_1D:
+ texUnit->Current1D = newTexObj;
+ break;
+ case GL_TEXTURE_2D:
+ texUnit->Current2D = newTexObj;
+ break;
+ case GL_TEXTURE_3D:
+ texUnit->Current3D = newTexObj;
+ break;
+ case GL_TEXTURE_CUBE_MAP_ARB:
+ texUnit->CurrentCubeMap = newTexObj;
+ break;
+ case GL_TEXTURE_RECTANGLE_NV:
+ texUnit->CurrentRect = newTexObj;
+ break;
+ default:
+ _mesa_problem(ctx, "bad target in BindTexture");
+ return;
+ }
+
+ /* Pass BindTexture call to device driver */
+ if (ctx->Driver.BindTexture)
+ (*ctx->Driver.BindTexture)( ctx, target, newTexObj );
+
+ /* Decrement the reference count on the old texture and check if it's
+ * time to delete it.
+ */
+ /* XXX all RefCount accesses should be protected by a mutex. */
+ oldTexObj->RefCount--;
+ ASSERT(oldTexObj->RefCount >= 0);
+ if (oldTexObj->RefCount == 0) {
+ ASSERT(oldTexObj->Name != 0);
+ ASSERT(ctx->Driver.DeleteTexture);
+ (*ctx->Driver.DeleteTexture)( ctx, oldTexObj );
+ }
+}
+
+
+/**
+ * Set texture priorities.
+ *
+ * \param n number of textures.
+ * \param texName texture names.
+ * \param priorities corresponding texture priorities.
+ *
+ * \sa glPrioritizeTextures().
+ *
+ * Looks up each texture in the hash, clamps the corresponding priority between
+ * 0.0 and 1.0, and calls dd_function_table::PrioritizeTexture.
+ */
+void GLAPIENTRY
+_mesa_PrioritizeTextures( GLsizei n, const GLuint *texName,
+ const GLclampf *priorities )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint i;
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (n < 0) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glPrioritizeTextures" );
+ return;
+ }
+
+ if (!priorities)
+ return;
+
+ for (i = 0; i < n; i++) {
+ if (texName[i] > 0) {
+ struct gl_texture_object *t = _mesa_lookup_texture(ctx, texName[i]);
+ if (t) {
+ t->Priority = CLAMP( priorities[i], 0.0F, 1.0F );
+ if (ctx->Driver.PrioritizeTexture)
+ ctx->Driver.PrioritizeTexture( ctx, t, t->Priority );
+ }
+ }
+ }
+
+ ctx->NewState |= _NEW_TEXTURE;
+}
+
+/**
+ * See if textures are loaded in texture memory.
+ *
+ * \param n number of textures to query.
+ * \param texName array with the texture names.
+ * \param residences array which will hold the residence status.
+ *
+ * \return GL_TRUE if all textures are resident and \p residences is left unchanged,
+ *
+ * \sa glAreTexturesResident().
+ *
+ * Looks up each texture in the hash and calls
+ * dd_function_table::IsTextureResident.
+ */
+GLboolean GLAPIENTRY
+_mesa_AreTexturesResident(GLsizei n, const GLuint *texName,
+ GLboolean *residences)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLboolean allResident = GL_TRUE;
+ GLint i, j;
+ ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
+
+ if (n < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glAreTexturesResident(n)");
+ return GL_FALSE;
+ }
+
+ if (!texName || !residences)
+ return GL_FALSE;
+
+ for (i = 0; i < n; i++) {
+ struct gl_texture_object *t;
+ if (texName[i] == 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glAreTexturesResident");
+ return GL_FALSE;
+ }
+ t = _mesa_lookup_texture(ctx, texName[i]);
+ if (!t) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glAreTexturesResident");
+ return GL_FALSE;
+ }
+ if (!ctx->Driver.IsTextureResident ||
+ ctx->Driver.IsTextureResident(ctx, t)) {
+ /* The texture is resident */
+ if (!allResident)
+ residences[i] = GL_TRUE;
+ }
+ else {
+ /* The texture is not resident */
+ if (allResident) {
+ allResident = GL_FALSE;
+ for (j = 0; j < i; j++)
+ residences[j] = GL_TRUE;
+ }
+ residences[i] = GL_FALSE;
+ }
+ }
+
+ return allResident;
+}
+
+/**
+ * See if a name corresponds to a texture.
+ *
+ * \param texture texture name.
+ *
+ * \return GL_TRUE if texture name corresponds to a texture, or GL_FALSE
+ * otherwise.
+ *
+ * \sa glIsTexture().
+ *
+ * Calls _mesa_HashLookup().
+ */
+GLboolean GLAPIENTRY
+_mesa_IsTexture( GLuint texture )
+{
+ struct gl_texture_object *t;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
+
+ if (!texture)
+ return GL_FALSE;
+
+ t = _mesa_lookup_texture(ctx, texture);
+
+ /* IsTexture is true only after object has been bound once. */
+ return t && t->Target;
+}
+
+/*@}*/
diff --git a/src/mesa/main/texobj.h b/src/mesa/main/texobj.h
new file mode 100644
index 00000000000..ac66ac69d3c
--- /dev/null
+++ b/src/mesa/main/texobj.h
@@ -0,0 +1,98 @@
+/**
+ * \file texobj.h
+ * Texture object management.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef TEXTOBJ_H
+#define TEXTOBJ_H
+
+
+#include "mtypes.h"
+
+
+/**
+ * \name Internal functions
+ */
+/*@{*/
+
+extern struct gl_texture_object *
+_mesa_lookup_texture(GLcontext *ctx, GLuint id);
+
+extern struct gl_texture_object *
+_mesa_new_texture_object( GLcontext *ctx, GLuint name, GLenum target );
+
+extern void
+_mesa_initialize_texture_object( struct gl_texture_object *obj,
+ GLuint name, GLenum target );
+
+extern void
+_mesa_delete_texture_object( GLcontext *ctx, struct gl_texture_object *obj );
+
+extern void
+_mesa_copy_texture_object( struct gl_texture_object *dest,
+ const struct gl_texture_object *src );
+
+extern void
+_mesa_test_texobj_completeness( const GLcontext *ctx,
+ struct gl_texture_object *obj );
+
+/*@}*/
+
+
+/**
+ * \name API functions
+ */
+/*@{*/
+
+extern void GLAPIENTRY
+_mesa_GenTextures( GLsizei n, GLuint *textures );
+
+
+extern void GLAPIENTRY
+_mesa_DeleteTextures( GLsizei n, const GLuint *textures );
+
+
+extern void GLAPIENTRY
+_mesa_BindTexture( GLenum target, GLuint texture );
+
+
+extern void GLAPIENTRY
+_mesa_PrioritizeTextures( GLsizei n, const GLuint *textures,
+ const GLclampf *priorities );
+
+
+extern GLboolean GLAPIENTRY
+_mesa_AreTexturesResident( GLsizei n, const GLuint *textures,
+ GLboolean *residences );
+
+extern GLboolean GLAPIENTRY
+_mesa_IsTexture( GLuint texture );
+
+/*@}*/
+
+#endif
diff --git a/src/mesa/main/texrender.c b/src/mesa/main/texrender.c
new file mode 100644
index 00000000000..db720cef6e0
--- /dev/null
+++ b/src/mesa/main/texrender.c
@@ -0,0 +1,363 @@
+
+#include "context.h"
+#include "fbobject.h"
+#include "texrender.h"
+#include "renderbuffer.h"
+
+
+/*
+ * Render-to-texture code for GL_EXT_framebuffer_object
+ */
+
+
+/**
+ * Derived from gl_renderbuffer class
+ */
+struct texture_renderbuffer
+{
+ struct gl_renderbuffer Base; /* Base class object */
+ struct gl_texture_image *TexImage;
+ StoreTexelFunc Store;
+ GLint Zoffset;
+};
+
+
+/**
+ * Get row of values from the renderbuffer that wraps a texture image.
+ */
+static void
+texture_get_row(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ GLint x, GLint y, void *values)
+{
+ const struct texture_renderbuffer *trb
+ = (const struct texture_renderbuffer *) rb;
+ const GLint z = trb->Zoffset;
+ GLuint i;
+
+ ASSERT(trb->TexImage->Width == rb->Width);
+ ASSERT(trb->TexImage->Height == rb->Height);
+
+ if (rb->DataType == CHAN_TYPE) {
+ GLchan *rgbaOut = (GLchan *) values;
+ for (i = 0; i < count; i++) {
+ trb->TexImage->FetchTexelc(trb->TexImage, x + i, y, z, rgbaOut + 4 * i);
+ }
+ }
+ else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) {
+ GLuint *zValues = (GLuint *) values;
+ for (i = 0; i < count; i++) {
+ GLfloat flt;
+ trb->TexImage->FetchTexelf(trb->TexImage, x + i, y, z, &flt);
+ zValues[i] = ((GLuint) (flt * 0xffffff)) << 8;
+ }
+ }
+ else {
+ _mesa_problem(ctx, "invalid rb->DataType in texture_get_row");
+ }
+}
+
+
+static void
+texture_get_values(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ const GLint x[], const GLint y[], void *values)
+{
+ const struct texture_renderbuffer *trb
+ = (const struct texture_renderbuffer *) rb;
+ const GLint z = trb->Zoffset;
+ GLuint i;
+
+ if (rb->DataType == CHAN_TYPE) {
+ GLchan *rgbaOut = (GLchan *) values;
+ for (i = 0; i < count; i++) {
+ trb->TexImage->FetchTexelc(trb->TexImage, x[i], y[i], z,
+ rgbaOut + 4 * i);
+ }
+ }
+ else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) {
+ GLuint *zValues = (GLuint *) values;
+ for (i = 0; i < count; i++) {
+ GLfloat flt;
+ trb->TexImage->FetchTexelf(trb->TexImage, x[i], y[i], z, &flt);
+ zValues[i] = ((GLuint) (flt * 0xffffff)) << 8;
+ }
+ }
+ else {
+ _mesa_problem(ctx, "invalid rb->DataType in texture_get_values");
+ }
+}
+
+
+/**
+ * Put row of values into a renderbuffer that wraps a texture image.
+ */
+static void
+texture_put_row(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ GLint x, GLint y, const void *values, const GLubyte *mask)
+{
+ const struct texture_renderbuffer *trb
+ = (const struct texture_renderbuffer *) rb;
+ const GLint z = trb->Zoffset;
+ GLuint i;
+
+ if (rb->DataType == CHAN_TYPE) {
+ const GLchan *rgba = (const GLchan *) values;
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ trb->Store(trb->TexImage, x + i, y, z, rgba);
+ }
+ rgba += 4;
+ }
+ }
+ else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) {
+ const GLuint *zValues = (const GLuint *) values;
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ GLfloat flt = (zValues[i] >> 8) * (1.0 / 0xffffff);
+ trb->Store(trb->TexImage, x + i, y, z, &flt);
+ }
+ }
+ }
+ else {
+ _mesa_problem(ctx, "invalid rb->DataType in texture_put_row");
+ }
+}
+
+
+static void
+texture_put_mono_row(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ GLint x, GLint y, const void *value, const GLubyte *mask)
+{
+ const struct texture_renderbuffer *trb
+ = (const struct texture_renderbuffer *) rb;
+ const GLint z = trb->Zoffset;
+ GLuint i;
+
+ if (rb->DataType == CHAN_TYPE) {
+ const GLchan *rgba = (const GLchan *) value;
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ trb->Store(trb->TexImage, x + i, y, z, rgba);
+ }
+ }
+ }
+ else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) {
+ const GLuint zValue = *((const GLuint *) value);
+ const GLfloat flt = (zValue >> 8) * (1.0 / 0xffffff);
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ trb->Store(trb->TexImage, x + i, y, z, &flt);
+ }
+ }
+ }
+ else {
+ _mesa_problem(ctx, "invalid rb->DataType in texture_put_mono_row");
+ }
+}
+
+
+static void
+texture_put_values(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ const GLint x[], const GLint y[], const void *values,
+ const GLubyte *mask)
+{
+ const struct texture_renderbuffer *trb
+ = (const struct texture_renderbuffer *) rb;
+ const GLint z = trb->Zoffset;
+ GLuint i;
+
+ if (rb->DataType == CHAN_TYPE) {
+ const GLchan *rgba = (const GLchan *) values;
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ trb->Store(trb->TexImage, x[i], y[i], z, rgba);
+ }
+ rgba += 4;
+ }
+ }
+ else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) {
+ const GLuint *zValues = (const GLuint *) values;
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ GLfloat flt = (zValues[i] >> 8) * (1.0 / 0xffffff);
+ trb->Store(trb->TexImage, x[i], y[i], z, &flt);
+ }
+ }
+ }
+ else {
+ _mesa_problem(ctx, "invalid rb->DataType in texture_put_values");
+ }
+}
+
+
+static void
+texture_put_mono_values(GLcontext *ctx, struct gl_renderbuffer *rb,
+ GLuint count, const GLint x[], const GLint y[],
+ const void *value, const GLubyte *mask)
+{
+ const struct texture_renderbuffer *trb
+ = (const struct texture_renderbuffer *) rb;
+ const GLint z = trb->Zoffset;
+ GLuint i;
+
+ if (rb->DataType == CHAN_TYPE) {
+ const GLchan *rgba = (const GLchan *) value;
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ trb->Store(trb->TexImage, x[i], y[i], z, rgba);
+ }
+ }
+ }
+ else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) {
+ const GLuint zValue = *((const GLuint *) value);
+ const GLfloat flt = (zValue >> 8) * (1.0 / 0xffffff);
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ trb->Store(trb->TexImage, x[i], y[i], z, &flt);
+ }
+ }
+ }
+ else {
+ _mesa_problem(ctx, "invalid rb->DataType in texture_put_mono_values");
+ }
+}
+
+
+static void
+delete_texture_wrapper(struct gl_renderbuffer *rb)
+{
+ ASSERT(rb->RefCount == 0);
+ _mesa_free(rb);
+}
+
+
+/**
+ * This function creates a renderbuffer object which wraps a texture image.
+ * The new renderbuffer is plugged into the given attachment point.
+ * This allows rendering into the texture as if it were a renderbuffer.
+ */
+static void
+wrap_texture(GLcontext *ctx, struct gl_renderbuffer_attachment *att)
+{
+ struct texture_renderbuffer *trb;
+ const GLuint name = 0;
+
+ ASSERT(att->Type == GL_TEXTURE);
+ ASSERT(att->Renderbuffer == NULL);
+
+ trb = CALLOC_STRUCT(texture_renderbuffer);
+ if (!trb) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "wrap_texture");
+ return;
+ }
+
+ /* init base gl_renderbuffer fields */
+ _mesa_init_renderbuffer(&trb->Base, name);
+ /* plug in our texture_renderbuffer-specific functions */
+ trb->Base.Delete = delete_texture_wrapper;
+ trb->Base.AllocStorage = NULL; /* illegal! */
+ trb->Base.GetRow = texture_get_row;
+ trb->Base.GetValues = texture_get_values;
+ trb->Base.PutRow = texture_put_row;
+ trb->Base.PutMonoRow = texture_put_mono_row;
+ trb->Base.PutValues = texture_put_values;
+ trb->Base.PutMonoValues = texture_put_mono_values;
+
+ /* update attachment point */
+ att->Renderbuffer = &(trb->Base);
+}
+
+
+
+/**
+ * Update the renderbuffer wrapper for rendering to a texture.
+ * For example, update the width, height of the RB based on the texture size,
+ * update the internal format info, etc.
+ */
+static void
+update_wrapper(GLcontext *ctx, const struct gl_renderbuffer_attachment *att)
+{
+ struct texture_renderbuffer *trb
+ = (struct texture_renderbuffer *) att->Renderbuffer;
+
+ ASSERT(trb);
+
+ trb->TexImage = att->Texture->Image[att->CubeMapFace][att->TextureLevel];
+ ASSERT(trb->TexImage);
+
+ trb->Store = trb->TexImage->TexFormat->StoreTexel;
+ ASSERT(trb->Store);
+
+ trb->Zoffset = att->Zoffset;
+
+ trb->Base.Width = trb->TexImage->Width;
+ trb->Base.Height = trb->TexImage->Height;
+ trb->Base.InternalFormat = trb->TexImage->InternalFormat;
+ /* XXX may need more special cases here */
+ if (trb->TexImage->TexFormat->BaseFormat == GL_DEPTH_STENCIL_EXT) {
+ trb->Base._ActualFormat = GL_DEPTH24_STENCIL8_EXT;
+ trb->Base.DataType = GL_UNSIGNED_INT_24_8_EXT;
+ }
+ else if (trb->TexImage->TexFormat->BaseFormat == GL_DEPTH_COMPONENT) {
+ trb->Base._ActualFormat = GL_DEPTH_COMPONENT;
+ trb->Base.DataType = GL_FLOAT;
+ }
+ else {
+ trb->Base._ActualFormat = trb->TexImage->InternalFormat;
+ trb->Base.DataType = CHAN_TYPE;
+ }
+ trb->Base._BaseFormat = trb->TexImage->TexFormat->BaseFormat;
+#if 0
+ /* fix/avoid this assertion someday */
+ ASSERT(trb->Base._BaseFormat == GL_RGB ||
+ trb->Base._BaseFormat == GL_RGBA ||
+ trb->Base._BaseFormat == GL_DEPTH_COMPONENT);
+#endif
+ trb->Base.Data = trb->TexImage->Data;
+
+ trb->Base.RedBits = trb->TexImage->TexFormat->RedBits;
+ trb->Base.GreenBits = trb->TexImage->TexFormat->GreenBits;
+ trb->Base.BlueBits = trb->TexImage->TexFormat->BlueBits;
+ trb->Base.AlphaBits = trb->TexImage->TexFormat->AlphaBits;
+ trb->Base.DepthBits = trb->TexImage->TexFormat->DepthBits;
+}
+
+
+
+/**
+ * Called when rendering to a texture image begins, or when changing
+ * the dest mipmap level, cube face, etc.
+ * This is a fallback routine for software render-to-texture.
+ *
+ * Called via the glRenderbufferTexture1D/2D/3D() functions
+ * and elsewhere (such as glTexImage2D).
+ *
+ * The image we're rendering into is
+ * att->Texture->Image[att->CubeMapFace][att->TextureLevel];
+ * It'll never be NULL.
+ *
+ * \param fb the framebuffer object the texture is being bound to
+ * \param att the fb attachment point of the texture
+ *
+ * \sa _mesa_framebuffer_renderbuffer
+ */
+void
+_mesa_render_texture(GLcontext *ctx,
+ struct gl_framebuffer *fb,
+ struct gl_renderbuffer_attachment *att)
+{
+ if (!att->Renderbuffer) {
+ wrap_texture(ctx, att);
+ }
+ update_wrapper(ctx, att);
+}
+
+
+void
+_mesa_finish_render_texture(GLcontext *ctx,
+ struct gl_renderbuffer_attachment *att)
+{
+ /* do nothing */
+ /* The renderbuffer texture wrapper will get deleted by the
+ * normal mechanism for deleting renderbuffers.
+ */
+}
diff --git a/src/mesa/main/texrender.h b/src/mesa/main/texrender.h
new file mode 100644
index 00000000000..7c3fb0871bd
--- /dev/null
+++ b/src/mesa/main/texrender.h
@@ -0,0 +1,15 @@
+#ifndef TEXRENDER_H
+#define TEXRENDER_H
+
+
+extern void
+_mesa_render_texture(GLcontext *ctx,
+ struct gl_framebuffer *fb,
+ struct gl_renderbuffer_attachment *att);
+
+extern void
+_mesa_finish_render_texture(GLcontext *ctx,
+ struct gl_renderbuffer_attachment *att);
+
+
+#endif /* TEXRENDER_H */
diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c
new file mode 100644
index 00000000000..daf579a7bfc
--- /dev/null
+++ b/src/mesa/main/texstate.c
@@ -0,0 +1,3135 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file texstate.c
+ *
+ * Texture state handling.
+ */
+
+#include "glheader.h"
+#include "colormac.h"
+#include "colortab.h"
+#include "context.h"
+#include "enums.h"
+#include "macros.h"
+#include "texobj.h"
+#include "teximage.h"
+#include "texstate.h"
+#include "texenvprogram.h"
+#include "mtypes.h"
+#include "math/m_xform.h"
+#include "shaderobjects.h"
+
+
+
+#define ENUM_TO_FLOAT(X) ((GLfloat)(GLint)(X))
+#define ENUM_TO_DOUBLE(X) ((GLdouble)(GLint)(X))
+
+
+/**
+ * Default texture combine environment state. This is used to initialize
+ * a context's texture units and as the basis for converting "classic"
+ * texture environmnets to ARB_texture_env_combine style values.
+ */
+static const struct gl_tex_env_combine_state default_combine_state = {
+ GL_MODULATE, GL_MODULATE,
+ { GL_TEXTURE, GL_PREVIOUS, GL_CONSTANT },
+ { GL_TEXTURE, GL_PREVIOUS, GL_CONSTANT },
+ { GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_ALPHA },
+ { GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA },
+ 0, 0,
+ 2, 2
+};
+
+
+/**
+ * Copy a texture binding. Helper used by _mesa_copy_texture_state().
+ */
+static void
+copy_texture_binding(const GLcontext *ctx,
+ struct gl_texture_object **dst,
+ struct gl_texture_object *src)
+{
+ /* only copy if names differ (per OpenGL SI) */
+ if ((*dst)->Name != src->Name) {
+ /* unbind/delete dest binding which we're changing */
+ (*dst)->RefCount--;
+ if ((*dst)->RefCount == 0) {
+ /* time to delete this texture object */
+ ASSERT((*dst)->Name != 0);
+ ASSERT(ctx->Driver.DeleteTexture);
+ /* XXX cast-away const, unfortunately */
+ (*ctx->Driver.DeleteTexture)((GLcontext *) ctx, *dst);
+ }
+ /* make new binding, incrementing ref count */
+ *dst = src;
+ src->RefCount++;
+ }
+}
+
+
+/**
+ * Used by glXCopyContext to copy texture state from one context to another.
+ */
+void
+_mesa_copy_texture_state( const GLcontext *src, GLcontext *dst )
+{
+ GLuint i;
+
+ ASSERT(src);
+ ASSERT(dst);
+
+ dst->Texture.CurrentUnit = src->Texture.CurrentUnit;
+ dst->Texture._GenFlags = src->Texture._GenFlags;
+ dst->Texture._TexGenEnabled = src->Texture._TexGenEnabled;
+ dst->Texture._TexMatEnabled = src->Texture._TexMatEnabled;
+ dst->Texture.SharedPalette = src->Texture.SharedPalette;
+
+ /* per-unit state */
+ for (i = 0; i < src->Const.MaxTextureUnits; i++) {
+ dst->Texture.Unit[i].Enabled = src->Texture.Unit[i].Enabled;
+ dst->Texture.Unit[i].EnvMode = src->Texture.Unit[i].EnvMode;
+ COPY_4V(dst->Texture.Unit[i].EnvColor, src->Texture.Unit[i].EnvColor);
+ dst->Texture.Unit[i].TexGenEnabled = src->Texture.Unit[i].TexGenEnabled;
+ dst->Texture.Unit[i].GenModeS = src->Texture.Unit[i].GenModeS;
+ dst->Texture.Unit[i].GenModeT = src->Texture.Unit[i].GenModeT;
+ dst->Texture.Unit[i].GenModeR = src->Texture.Unit[i].GenModeR;
+ dst->Texture.Unit[i].GenModeQ = src->Texture.Unit[i].GenModeQ;
+ dst->Texture.Unit[i]._GenBitS = src->Texture.Unit[i]._GenBitS;
+ dst->Texture.Unit[i]._GenBitT = src->Texture.Unit[i]._GenBitT;
+ dst->Texture.Unit[i]._GenBitR = src->Texture.Unit[i]._GenBitR;
+ dst->Texture.Unit[i]._GenBitQ = src->Texture.Unit[i]._GenBitQ;
+ dst->Texture.Unit[i]._GenFlags = src->Texture.Unit[i]._GenFlags;
+ COPY_4V(dst->Texture.Unit[i].ObjectPlaneS, src->Texture.Unit[i].ObjectPlaneS);
+ COPY_4V(dst->Texture.Unit[i].ObjectPlaneT, src->Texture.Unit[i].ObjectPlaneT);
+ COPY_4V(dst->Texture.Unit[i].ObjectPlaneR, src->Texture.Unit[i].ObjectPlaneR);
+ COPY_4V(dst->Texture.Unit[i].ObjectPlaneQ, src->Texture.Unit[i].ObjectPlaneQ);
+ COPY_4V(dst->Texture.Unit[i].EyePlaneS, src->Texture.Unit[i].EyePlaneS);
+ COPY_4V(dst->Texture.Unit[i].EyePlaneT, src->Texture.Unit[i].EyePlaneT);
+ COPY_4V(dst->Texture.Unit[i].EyePlaneR, src->Texture.Unit[i].EyePlaneR);
+ COPY_4V(dst->Texture.Unit[i].EyePlaneQ, src->Texture.Unit[i].EyePlaneQ);
+ dst->Texture.Unit[i].LodBias = src->Texture.Unit[i].LodBias;
+
+ /* GL_EXT_texture_env_combine */
+ dst->Texture.Unit[i].Combine.ModeRGB = src->Texture.Unit[i].Combine.ModeRGB;
+ dst->Texture.Unit[i].Combine.ModeA = src->Texture.Unit[i].Combine.ModeA;
+ COPY_3V(dst->Texture.Unit[i].Combine.SourceRGB, src->Texture.Unit[i].Combine.SourceRGB);
+ COPY_3V(dst->Texture.Unit[i].Combine.SourceA, src->Texture.Unit[i].Combine.SourceA);
+ COPY_3V(dst->Texture.Unit[i].Combine.OperandRGB, src->Texture.Unit[i].Combine.OperandRGB);
+ COPY_3V(dst->Texture.Unit[i].Combine.OperandA, src->Texture.Unit[i].Combine.OperandA);
+ dst->Texture.Unit[i].Combine.ScaleShiftRGB = src->Texture.Unit[i].Combine.ScaleShiftRGB;
+ dst->Texture.Unit[i].Combine.ScaleShiftA = src->Texture.Unit[i].Combine.ScaleShiftA;
+
+ /* copy texture object bindings, not contents of texture objects */
+ copy_texture_binding(src, &dst->Texture.Unit[i].Current1D,
+ src->Texture.Unit[i].Current1D);
+ copy_texture_binding(src, &dst->Texture.Unit[i].Current2D,
+ src->Texture.Unit[i].Current2D);
+ copy_texture_binding(src, &dst->Texture.Unit[i].Current3D,
+ src->Texture.Unit[i].Current3D);
+ copy_texture_binding(src, &dst->Texture.Unit[i].CurrentCubeMap,
+ src->Texture.Unit[i].CurrentCubeMap);
+ copy_texture_binding(src, &dst->Texture.Unit[i].CurrentRect,
+ src->Texture.Unit[i].CurrentRect);
+ }
+}
+
+
+/*
+ * For debugging
+ */
+void
+_mesa_print_texunit_state( GLcontext *ctx, GLuint unit )
+{
+ const struct gl_texture_unit *texUnit = ctx->Texture.Unit + unit;
+ _mesa_printf("Texture Unit %d\n", unit);
+ _mesa_printf(" GL_TEXTURE_ENV_MODE = %s\n", _mesa_lookup_enum_by_nr(texUnit->EnvMode));
+ _mesa_printf(" GL_COMBINE_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.ModeRGB));
+ _mesa_printf(" GL_COMBINE_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.ModeA));
+ _mesa_printf(" GL_SOURCE0_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[0]));
+ _mesa_printf(" GL_SOURCE1_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[1]));
+ _mesa_printf(" GL_SOURCE2_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[2]));
+ _mesa_printf(" GL_SOURCE0_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[0]));
+ _mesa_printf(" GL_SOURCE1_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[1]));
+ _mesa_printf(" GL_SOURCE2_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[2]));
+ _mesa_printf(" GL_OPERAND0_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[0]));
+ _mesa_printf(" GL_OPERAND1_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[1]));
+ _mesa_printf(" GL_OPERAND2_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[2]));
+ _mesa_printf(" GL_OPERAND0_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[0]));
+ _mesa_printf(" GL_OPERAND1_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[1]));
+ _mesa_printf(" GL_OPERAND2_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[2]));
+ _mesa_printf(" GL_RGB_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftRGB);
+ _mesa_printf(" GL_ALPHA_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftA);
+ _mesa_printf(" GL_TEXTURE_ENV_COLOR = (%f, %f, %f, %f)\n", texUnit->EnvColor[0], texUnit->EnvColor[1], texUnit->EnvColor[2], texUnit->EnvColor[3]);
+}
+
+
+
+/**********************************************************************/
+/* Texture Environment */
+/**********************************************************************/
+
+/**
+ * Convert "classic" texture environment to ARB_texture_env_combine style
+ * environments.
+ *
+ * \param state texture_env_combine state vector to be filled-in.
+ * \param mode Classic texture environment mode (i.e., \c GL_REPLACE,
+ * \c GL_BLEND, \c GL_DECAL, etc.).
+ * \param texBaseFormat Base format of the texture associated with the
+ * texture unit.
+ */
+static void
+calculate_derived_texenv( struct gl_tex_env_combine_state *state,
+ GLenum mode, GLenum texBaseFormat )
+{
+ GLenum mode_rgb;
+ GLenum mode_a;
+
+ *state = default_combine_state;
+
+ switch (texBaseFormat) {
+ case GL_ALPHA:
+ state->SourceRGB[0] = GL_PREVIOUS;
+ break;
+
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ case GL_RGBA:
+ break;
+
+ case GL_LUMINANCE:
+ case GL_RGB:
+ case GL_YCBCR_MESA:
+ state->SourceA[0] = GL_PREVIOUS;
+ break;
+
+ default:
+ _mesa_problem(NULL, "Invalid texBaseFormat in calculate_derived_texenv");
+ return;
+ }
+
+ switch (mode) {
+ case GL_REPLACE:
+ case GL_MODULATE:
+ mode_rgb = (texBaseFormat == GL_ALPHA) ? GL_REPLACE : mode;
+ mode_a = mode;
+ break;
+
+ case GL_DECAL:
+ mode_rgb = GL_INTERPOLATE;
+ mode_a = GL_REPLACE;
+
+ state->SourceA[0] = GL_PREVIOUS;
+
+ /* Having alpha / luminance / intensity textures replace using the
+ * incoming fragment color matches the definition in NV_texture_shader.
+ * The 1.5 spec simply marks these as "undefined".
+ */
+ switch (texBaseFormat) {
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ state->SourceRGB[0] = GL_PREVIOUS;
+ break;
+ case GL_RGB:
+ case GL_YCBCR_MESA:
+ mode_rgb = GL_REPLACE;
+ break;
+ case GL_RGBA:
+ state->SourceRGB[2] = GL_TEXTURE;
+ break;
+ }
+ break;
+
+ case GL_BLEND:
+ mode_rgb = GL_INTERPOLATE;
+ mode_a = GL_MODULATE;
+
+ switch (texBaseFormat) {
+ case GL_ALPHA:
+ mode_rgb = GL_REPLACE;
+ break;
+ case GL_INTENSITY:
+ mode_a = GL_INTERPOLATE;
+ state->SourceA[0] = GL_CONSTANT;
+ state->OperandA[2] = GL_SRC_ALPHA;
+ /* FALLTHROUGH */
+ case GL_LUMINANCE:
+ case GL_RGB:
+ case GL_LUMINANCE_ALPHA:
+ case GL_RGBA:
+ case GL_YCBCR_MESA:
+ state->SourceRGB[2] = GL_TEXTURE;
+ state->SourceA[2] = GL_TEXTURE;
+ state->SourceRGB[0] = GL_CONSTANT;
+ state->OperandRGB[2] = GL_SRC_COLOR;
+ break;
+ }
+ break;
+
+ case GL_ADD:
+ mode_rgb = (texBaseFormat == GL_ALPHA) ? GL_REPLACE : GL_ADD;
+ mode_a = (texBaseFormat == GL_INTENSITY) ? GL_ADD : GL_MODULATE;
+ break;
+
+ default:
+ _mesa_problem(NULL,
+ "Invalid texture env mode in calculate_derived_texenv");
+ return;
+ }
+
+ state->ModeRGB = (state->SourceRGB[0] != GL_PREVIOUS)
+ ? mode_rgb : GL_REPLACE;
+ state->ModeA = (state->SourceA[0] != GL_PREVIOUS)
+ ? mode_a : GL_REPLACE;
+}
+
+
+void GLAPIENTRY
+_mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+#define TE_ERROR(errCode, msg, value) \
+ _mesa_error(ctx, errCode, msg, _mesa_lookup_enum_by_nr(value));
+
+ if (target == GL_TEXTURE_ENV) {
+ switch (pname) {
+ case GL_TEXTURE_ENV_MODE:
+ {
+ const GLenum mode = (GLenum) (GLint) *param;
+ if (texUnit->EnvMode == mode)
+ return;
+ if (mode == GL_MODULATE ||
+ mode == GL_BLEND ||
+ mode == GL_DECAL ||
+ mode == GL_REPLACE ||
+ (mode == GL_ADD && ctx->Extensions.EXT_texture_env_add) ||
+ (mode == GL_COMBINE &&
+ (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine))) {
+ /* legal */
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texUnit->EnvMode = mode;
+ }
+ else {
+ TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
+ return;
+ }
+ }
+ break;
+ case GL_TEXTURE_ENV_COLOR:
+ {
+ GLfloat tmp[4];
+ tmp[0] = CLAMP( param[0], 0.0F, 1.0F );
+ tmp[1] = CLAMP( param[1], 0.0F, 1.0F );
+ tmp[2] = CLAMP( param[2], 0.0F, 1.0F );
+ tmp[3] = CLAMP( param[3], 0.0F, 1.0F );
+ if (TEST_EQ_4V(tmp, texUnit->EnvColor))
+ return;
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ COPY_4FV(texUnit->EnvColor, tmp);
+ }
+ break;
+ case GL_COMBINE_RGB:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ const GLenum mode = (GLenum) (GLint) *param;
+ if (texUnit->Combine.ModeRGB == mode)
+ return;
+ switch (mode) {
+ case GL_REPLACE:
+ case GL_MODULATE:
+ case GL_ADD:
+ case GL_ADD_SIGNED:
+ case GL_INTERPOLATE:
+ /* OK */
+ break;
+ case GL_SUBTRACT:
+ if (!ctx->Extensions.ARB_texture_env_combine) {
+ TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
+ return;
+ }
+ break;
+ case GL_DOT3_RGB_EXT:
+ case GL_DOT3_RGBA_EXT:
+ if (!ctx->Extensions.EXT_texture_env_dot3) {
+ TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
+ return;
+ }
+ break;
+ case GL_DOT3_RGB:
+ case GL_DOT3_RGBA:
+ if (!ctx->Extensions.ARB_texture_env_dot3) {
+ TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
+ return;
+ }
+ break;
+ case GL_MODULATE_ADD_ATI:
+ case GL_MODULATE_SIGNED_ADD_ATI:
+ case GL_MODULATE_SUBTRACT_ATI:
+ if (!ctx->Extensions.ATI_texture_env_combine3) {
+ TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
+ return;
+ }
+ break;
+ default:
+ TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
+ return;
+ }
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texUnit->Combine.ModeRGB = mode;
+ }
+ else {
+ TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
+ return;
+ }
+ break;
+ case GL_COMBINE_ALPHA:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ const GLenum mode = (GLenum) (GLint) *param;
+ if (texUnit->Combine.ModeA == mode)
+ return;
+ switch (mode) {
+ case GL_REPLACE:
+ case GL_MODULATE:
+ case GL_ADD:
+ case GL_ADD_SIGNED:
+ case GL_INTERPOLATE:
+ /* OK */
+ break;
+ case GL_SUBTRACT:
+ if (!ctx->Extensions.ARB_texture_env_combine) {
+ TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
+ return;
+ }
+ break;
+ case GL_MODULATE_ADD_ATI:
+ case GL_MODULATE_SIGNED_ADD_ATI:
+ case GL_MODULATE_SUBTRACT_ATI:
+ if (!ctx->Extensions.ATI_texture_env_combine3) {
+ TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
+ return;
+ }
+ break;
+ default:
+ TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
+ return;
+ }
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texUnit->Combine.ModeA = mode;
+ }
+ else {
+ TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
+ return;
+ }
+ break;
+ case GL_SOURCE0_RGB:
+ case GL_SOURCE1_RGB:
+ case GL_SOURCE2_RGB:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ const GLenum source = (GLenum) (GLint) *param;
+ const GLuint s = pname - GL_SOURCE0_RGB;
+ if (texUnit->Combine.SourceRGB[s] == source)
+ return;
+ if (source == GL_TEXTURE ||
+ source == GL_CONSTANT ||
+ source == GL_PRIMARY_COLOR ||
+ source == GL_PREVIOUS ||
+ (ctx->Extensions.ARB_texture_env_crossbar &&
+ source >= GL_TEXTURE0 &&
+ source < GL_TEXTURE0 + ctx->Const.MaxTextureUnits) ||
+ (ctx->Extensions.ATI_texture_env_combine3 &&
+ (source == GL_ZERO || source == GL_ONE))) {
+ /* legal */
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texUnit->Combine.SourceRGB[s] = source;
+ }
+ else {
+ TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", source);
+ return;
+ }
+ }
+ else {
+ TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
+ return;
+ }
+ break;
+ case GL_SOURCE0_ALPHA:
+ case GL_SOURCE1_ALPHA:
+ case GL_SOURCE2_ALPHA:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ const GLenum source = (GLenum) (GLint) *param;
+ const GLuint s = pname - GL_SOURCE0_ALPHA;
+ if (texUnit->Combine.SourceA[s] == source)
+ return;
+ if (source == GL_TEXTURE ||
+ source == GL_CONSTANT ||
+ source == GL_PRIMARY_COLOR ||
+ source == GL_PREVIOUS ||
+ (ctx->Extensions.ARB_texture_env_crossbar &&
+ source >= GL_TEXTURE0 &&
+ source < GL_TEXTURE0 + ctx->Const.MaxTextureUnits) ||
+ (ctx->Extensions.ATI_texture_env_combine3 &&
+ (source == GL_ZERO || source == GL_ONE))) {
+ /* legal */
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texUnit->Combine.SourceA[s] = source;
+ }
+ else {
+ TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", source);
+ return;
+ }
+ }
+ else {
+ TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
+ return;
+ }
+ break;
+ case GL_OPERAND0_RGB:
+ case GL_OPERAND1_RGB:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ const GLenum operand = (GLenum) (GLint) *param;
+ const GLuint s = pname - GL_OPERAND0_RGB;
+ if (texUnit->Combine.OperandRGB[s] == operand)
+ return;
+ switch (operand) {
+ case GL_SRC_COLOR:
+ case GL_ONE_MINUS_SRC_COLOR:
+ case GL_SRC_ALPHA:
+ case GL_ONE_MINUS_SRC_ALPHA:
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texUnit->Combine.OperandRGB[s] = operand;
+ break;
+ default:
+ TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
+ return;
+ }
+ }
+ else {
+ TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
+ return;
+ }
+ break;
+ case GL_OPERAND0_ALPHA:
+ case GL_OPERAND1_ALPHA:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ const GLenum operand = (GLenum) (GLint) *param;
+ if (texUnit->Combine.OperandA[pname-GL_OPERAND0_ALPHA] == operand)
+ return;
+ switch (operand) {
+ case GL_SRC_ALPHA:
+ case GL_ONE_MINUS_SRC_ALPHA:
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texUnit->Combine.OperandA[pname-GL_OPERAND0_ALPHA] = operand;
+ break;
+ default:
+ TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
+ return;
+ }
+ }
+ else {
+ TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
+ return;
+ }
+ break;
+ case GL_OPERAND2_RGB:
+ if (ctx->Extensions.ARB_texture_env_combine) {
+ const GLenum operand = (GLenum) (GLint) *param;
+ if (texUnit->Combine.OperandRGB[2] == operand)
+ return;
+ switch (operand) {
+ case GL_SRC_COLOR: /* ARB combine only */
+ case GL_ONE_MINUS_SRC_COLOR: /* ARB combine only */
+ case GL_SRC_ALPHA:
+ case GL_ONE_MINUS_SRC_ALPHA: /* ARB combine only */
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texUnit->Combine.OperandRGB[2] = operand;
+ break;
+ default:
+ TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
+ return;
+ }
+ }
+ else if (ctx->Extensions.EXT_texture_env_combine) {
+ const GLenum operand = (GLenum) (GLint) *param;
+ if (texUnit->Combine.OperandRGB[2] == operand)
+ return;
+ /* operand must be GL_SRC_ALPHA which is the initial value - thus
+ don't need to actually compare the operand to the possible value */
+ else {
+ TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
+ return;
+ }
+ }
+ else {
+ TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
+ return;
+ }
+ break;
+ case GL_OPERAND2_ALPHA:
+ if (ctx->Extensions.ARB_texture_env_combine) {
+ const GLenum operand = (GLenum) (GLint) *param;
+ if (texUnit->Combine.OperandA[2] == operand)
+ return;
+ switch (operand) {
+ case GL_SRC_ALPHA:
+ case GL_ONE_MINUS_SRC_ALPHA: /* ARB combine only */
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texUnit->Combine.OperandA[2] = operand;
+ break;
+ default:
+ TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
+ return;
+ }
+ }
+ else if (ctx->Extensions.EXT_texture_env_combine) {
+ const GLenum operand = (GLenum) (GLint) *param;
+ if (texUnit->Combine.OperandA[2] == operand)
+ return;
+ /* operand must be GL_SRC_ALPHA which is the initial value - thus
+ don't need to actually compare the operand to the possible value */
+ else {
+ TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
+ return;
+ }
+ }
+ else {
+ TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
+ return;
+ }
+ break;
+ case GL_RGB_SCALE:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ GLuint newshift;
+ if (*param == 1.0) {
+ newshift = 0;
+ }
+ else if (*param == 2.0) {
+ newshift = 1;
+ }
+ else if (*param == 4.0) {
+ newshift = 2;
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_VALUE,
+ "glTexEnv(GL_RGB_SCALE not 1, 2 or 4)" );
+ return;
+ }
+ if (texUnit->Combine.ScaleShiftRGB == newshift)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texUnit->Combine.ScaleShiftRGB = newshift;
+ }
+ else {
+ TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
+ return;
+ }
+ break;
+ case GL_ALPHA_SCALE:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ GLuint newshift;
+ if (*param == 1.0) {
+ newshift = 0;
+ }
+ else if (*param == 2.0) {
+ newshift = 1;
+ }
+ else if (*param == 4.0) {
+ newshift = 2;
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_VALUE,
+ "glTexEnv(GL_ALPHA_SCALE not 1, 2 or 4)" );
+ return;
+ }
+ if (texUnit->Combine.ScaleShiftA == newshift)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texUnit->Combine.ScaleShiftA = newshift;
+ }
+ else {
+ TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
+ return;
+ }
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname)" );
+ return;
+ }
+ }
+ else if (target == GL_TEXTURE_FILTER_CONTROL_EXT) {
+ /* GL_EXT_texture_lod_bias */
+ if (!ctx->Extensions.EXT_texture_lod_bias) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)", target );
+ return;
+ }
+ if (pname == GL_TEXTURE_LOD_BIAS_EXT) {
+ if (texUnit->LodBias == param[0])
+ return;
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texUnit->LodBias = param[0];
+ }
+ else {
+ TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
+ return;
+ }
+ }
+ else if (target == GL_POINT_SPRITE_NV) {
+ /* GL_ARB_point_sprite / GL_NV_point_sprite */
+ if (!ctx->Extensions.NV_point_sprite
+ && !ctx->Extensions.ARB_point_sprite) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)", target );
+ return;
+ }
+ if (pname == GL_COORD_REPLACE_NV) {
+ const GLenum value = (GLenum) param[0];
+ if (value == GL_TRUE || value == GL_FALSE) {
+ /* It's kind of weird to set point state via glTexEnv,
+ * but that's what the spec calls for.
+ */
+ const GLboolean state = (GLboolean) value;
+ if (ctx->Point.CoordReplace[ctx->Texture.CurrentUnit] == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_POINT);
+ ctx->Point.CoordReplace[ctx->Texture.CurrentUnit] = state;
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glTexEnv(param=0x%x)", value);
+ return;
+ }
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname=0x%x)", pname );
+ return;
+ }
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)",target );
+ return;
+ }
+
+ if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glTexEnv %s %s %.1f(%s) ...\n",
+ _mesa_lookup_enum_by_nr(target),
+ _mesa_lookup_enum_by_nr(pname),
+ *param,
+ _mesa_lookup_enum_by_nr((GLenum) (GLint) *param));
+
+ /* Tell device driver about the new texture environment */
+ if (ctx->Driver.TexEnv) {
+ (*ctx->Driver.TexEnv)( ctx, target, pname, param );
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_TexEnvf( GLenum target, GLenum pname, GLfloat param )
+{
+ _mesa_TexEnvfv( target, pname, &param );
+}
+
+
+
+void GLAPIENTRY
+_mesa_TexEnvi( GLenum target, GLenum pname, GLint param )
+{
+ GLfloat p[4];
+ p[0] = (GLfloat) param;
+ p[1] = p[2] = p[3] = 0.0;
+ _mesa_TexEnvfv( target, pname, p );
+}
+
+
+void GLAPIENTRY
+_mesa_TexEnviv( GLenum target, GLenum pname, const GLint *param )
+{
+ GLfloat p[4];
+ if (pname == GL_TEXTURE_ENV_COLOR) {
+ p[0] = INT_TO_FLOAT( param[0] );
+ p[1] = INT_TO_FLOAT( param[1] );
+ p[2] = INT_TO_FLOAT( param[2] );
+ p[3] = INT_TO_FLOAT( param[3] );
+ }
+ else {
+ p[0] = (GLfloat) param[0];
+ p[1] = p[2] = p[3] = 0; /* init to zero, just to be safe */
+ }
+ _mesa_TexEnvfv( target, pname, p );
+}
+
+
+void GLAPIENTRY
+_mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (target == GL_TEXTURE_ENV) {
+ switch (pname) {
+ case GL_TEXTURE_ENV_MODE:
+ *params = ENUM_TO_FLOAT(texUnit->EnvMode);
+ break;
+ case GL_TEXTURE_ENV_COLOR:
+ COPY_4FV( params, texUnit->EnvColor );
+ break;
+ case GL_COMBINE_RGB:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ *params = (GLfloat) texUnit->Combine.ModeRGB;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
+ }
+ break;
+ case GL_COMBINE_ALPHA:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ *params = (GLfloat) texUnit->Combine.ModeA;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
+ }
+ break;
+ case GL_SOURCE0_RGB:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ *params = (GLfloat) texUnit->Combine.SourceRGB[0];
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
+ }
+ break;
+ case GL_SOURCE1_RGB:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ *params = (GLfloat) texUnit->Combine.SourceRGB[1];
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
+ }
+ break;
+ case GL_SOURCE2_RGB:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ *params = (GLfloat) texUnit->Combine.SourceRGB[2];
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
+ }
+ break;
+ case GL_SOURCE0_ALPHA:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ *params = (GLfloat) texUnit->Combine.SourceA[0];
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
+ }
+ break;
+ case GL_SOURCE1_ALPHA:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ *params = (GLfloat) texUnit->Combine.SourceA[1];
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
+ }
+ break;
+ case GL_SOURCE2_ALPHA:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ *params = (GLfloat) texUnit->Combine.SourceA[2];
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
+ }
+ break;
+ case GL_OPERAND0_RGB:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ *params = (GLfloat) texUnit->Combine.OperandRGB[0];
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
+ }
+ break;
+ case GL_OPERAND1_RGB:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ *params = (GLfloat) texUnit->Combine.OperandRGB[1];
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
+ }
+ break;
+ case GL_OPERAND2_RGB:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ *params = (GLfloat) texUnit->Combine.OperandRGB[2];
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
+ }
+ break;
+ case GL_OPERAND0_ALPHA:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ *params = (GLfloat) texUnit->Combine.OperandA[0];
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
+ }
+ break;
+ case GL_OPERAND1_ALPHA:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ *params = (GLfloat) texUnit->Combine.OperandA[1];
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
+ }
+ break;
+ case GL_OPERAND2_ALPHA:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ *params = (GLfloat) texUnit->Combine.OperandA[2];
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
+ }
+ break;
+ case GL_RGB_SCALE:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ if (texUnit->Combine.ScaleShiftRGB == 0)
+ *params = 1.0;
+ else if (texUnit->Combine.ScaleShiftRGB == 1)
+ *params = 2.0;
+ else
+ *params = 4.0;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
+ return;
+ }
+ break;
+ case GL_ALPHA_SCALE:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ if (texUnit->Combine.ScaleShiftA == 0)
+ *params = 1.0;
+ else if (texUnit->Combine.ScaleShiftA == 1)
+ *params = 2.0;
+ else
+ *params = 4.0;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
+ return;
+ }
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname=0x%x)", pname);
+ }
+ }
+ else if (target == GL_TEXTURE_FILTER_CONTROL_EXT) {
+ /* GL_EXT_texture_lod_bias */
+ if (!ctx->Extensions.EXT_texture_lod_bias) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" );
+ return;
+ }
+ if (pname == GL_TEXTURE_LOD_BIAS_EXT) {
+ *params = texUnit->LodBias;
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)" );
+ return;
+ }
+ }
+ else if (target == GL_POINT_SPRITE_NV) {
+ /* GL_ARB_point_sprite / GL_NV_point_sprite */
+ if (!ctx->Extensions.NV_point_sprite
+ && !ctx->Extensions.ARB_point_sprite) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" );
+ return;
+ }
+ if (pname == GL_COORD_REPLACE_NV) {
+ *params = (GLfloat) ctx->Point.CoordReplace[ctx->Texture.CurrentUnit];
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)" );
+ return;
+ }
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" );
+ return;
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (target == GL_TEXTURE_ENV) {
+ switch (pname) {
+ case GL_TEXTURE_ENV_MODE:
+ *params = (GLint) texUnit->EnvMode;
+ break;
+ case GL_TEXTURE_ENV_COLOR:
+ params[0] = FLOAT_TO_INT( texUnit->EnvColor[0] );
+ params[1] = FLOAT_TO_INT( texUnit->EnvColor[1] );
+ params[2] = FLOAT_TO_INT( texUnit->EnvColor[2] );
+ params[3] = FLOAT_TO_INT( texUnit->EnvColor[3] );
+ break;
+ case GL_COMBINE_RGB:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ *params = (GLint) texUnit->Combine.ModeRGB;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
+ }
+ break;
+ case GL_COMBINE_ALPHA:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ *params = (GLint) texUnit->Combine.ModeA;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
+ }
+ break;
+ case GL_SOURCE0_RGB:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ *params = (GLint) texUnit->Combine.SourceRGB[0];
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
+ }
+ break;
+ case GL_SOURCE1_RGB:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ *params = (GLint) texUnit->Combine.SourceRGB[1];
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
+ }
+ break;
+ case GL_SOURCE2_RGB:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ *params = (GLint) texUnit->Combine.SourceRGB[2];
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
+ }
+ break;
+ case GL_SOURCE0_ALPHA:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ *params = (GLint) texUnit->Combine.SourceA[0];
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
+ }
+ break;
+ case GL_SOURCE1_ALPHA:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ *params = (GLint) texUnit->Combine.SourceA[1];
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
+ }
+ break;
+ case GL_SOURCE2_ALPHA:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ *params = (GLint) texUnit->Combine.SourceA[2];
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
+ }
+ break;
+ case GL_OPERAND0_RGB:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ *params = (GLint) texUnit->Combine.OperandRGB[0];
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
+ }
+ break;
+ case GL_OPERAND1_RGB:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ *params = (GLint) texUnit->Combine.OperandRGB[1];
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
+ }
+ break;
+ case GL_OPERAND2_RGB:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ *params = (GLint) texUnit->Combine.OperandRGB[2];
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
+ }
+ break;
+ case GL_OPERAND0_ALPHA:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ *params = (GLint) texUnit->Combine.OperandA[0];
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
+ }
+ break;
+ case GL_OPERAND1_ALPHA:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ *params = (GLint) texUnit->Combine.OperandA[1];
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
+ }
+ break;
+ case GL_OPERAND2_ALPHA:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ *params = (GLint) texUnit->Combine.OperandA[2];
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
+ }
+ break;
+ case GL_RGB_SCALE:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ if (texUnit->Combine.ScaleShiftRGB == 0)
+ *params = 1;
+ else if (texUnit->Combine.ScaleShiftRGB == 1)
+ *params = 2;
+ else
+ *params = 4;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
+ return;
+ }
+ break;
+ case GL_ALPHA_SCALE:
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ if (texUnit->Combine.ScaleShiftA == 0)
+ *params = 1;
+ else if (texUnit->Combine.ScaleShiftA == 1)
+ *params = 2;
+ else
+ *params = 4;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
+ return;
+ }
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname=0x%x)",
+ pname);
+ }
+ }
+ else if (target == GL_TEXTURE_FILTER_CONTROL_EXT) {
+ /* GL_EXT_texture_lod_bias */
+ if (!ctx->Extensions.EXT_texture_lod_bias) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(target)" );
+ return;
+ }
+ if (pname == GL_TEXTURE_LOD_BIAS_EXT) {
+ *params = (GLint) texUnit->LodBias;
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)" );
+ return;
+ }
+ }
+ else if (target == GL_POINT_SPRITE_NV) {
+ /* GL_ARB_point_sprite / GL_NV_point_sprite */
+ if (!ctx->Extensions.NV_point_sprite
+ && !ctx->Extensions.ARB_point_sprite) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(target)" );
+ return;
+ }
+ if (pname == GL_COORD_REPLACE_NV) {
+ *params = (GLint) ctx->Point.CoordReplace[ctx->Texture.CurrentUnit];
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)" );
+ return;
+ }
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(target)" );
+ return;
+ }
+}
+
+
+
+
+/**********************************************************************/
+/* Texture Parameters */
+/**********************************************************************/
+
+static GLboolean
+_mesa_validate_texture_wrap_mode(GLcontext * ctx,
+ GLenum target, GLenum eparam)
+{
+ const struct gl_extensions * const e = & ctx->Extensions;
+
+ if (eparam == GL_CLAMP || eparam == GL_CLAMP_TO_EDGE ||
+ (eparam == GL_CLAMP_TO_BORDER && e->ARB_texture_border_clamp)) {
+ /* any texture target */
+ return GL_TRUE;
+ }
+ else if (target != GL_TEXTURE_RECTANGLE_NV &&
+ (eparam == GL_REPEAT ||
+ (eparam == GL_MIRRORED_REPEAT &&
+ e->ARB_texture_mirrored_repeat) ||
+ (eparam == GL_MIRROR_CLAMP_EXT &&
+ (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)) ||
+ (eparam == GL_MIRROR_CLAMP_TO_EDGE_EXT &&
+ (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)) ||
+ (eparam == GL_MIRROR_CLAMP_TO_BORDER_EXT &&
+ (e->EXT_texture_mirror_clamp)))) {
+ /* non-rectangle texture */
+ return GL_TRUE;
+ }
+
+ _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
+ return GL_FALSE;
+}
+
+
+void GLAPIENTRY
+_mesa_TexParameterf( GLenum target, GLenum pname, GLfloat param )
+{
+ _mesa_TexParameterfv(target, pname, &param);
+}
+
+
+void GLAPIENTRY
+_mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ GLenum eparam = (GLenum) (GLint) params[0];
+ struct gl_texture_object *texObj;
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glTexParameter %s %s %.1f(%s)...\n",
+ _mesa_lookup_enum_by_nr(target),
+ _mesa_lookup_enum_by_nr(pname),
+ *params,
+ _mesa_lookup_enum_by_nr(eparam));
+
+
+ switch (target) {
+ case GL_TEXTURE_1D:
+ texObj = texUnit->Current1D;
+ break;
+ case GL_TEXTURE_2D:
+ texObj = texUnit->Current2D;
+ break;
+ case GL_TEXTURE_3D:
+ texObj = texUnit->Current3D;
+ break;
+ case GL_TEXTURE_CUBE_MAP:
+ if (!ctx->Extensions.ARB_texture_cube_map) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" );
+ return;
+ }
+ texObj = texUnit->CurrentCubeMap;
+ break;
+ case GL_TEXTURE_RECTANGLE_NV:
+ if (!ctx->Extensions.NV_texture_rectangle) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" );
+ return;
+ }
+ texObj = texUnit->CurrentRect;
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" );
+ return;
+ }
+
+ switch (pname) {
+ case GL_TEXTURE_MIN_FILTER:
+ /* A small optimization */
+ if (texObj->MinFilter == eparam)
+ return;
+ if (eparam==GL_NEAREST || eparam==GL_LINEAR) {
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texObj->MinFilter = eparam;
+ }
+ else if ((eparam==GL_NEAREST_MIPMAP_NEAREST ||
+ eparam==GL_LINEAR_MIPMAP_NEAREST ||
+ eparam==GL_NEAREST_MIPMAP_LINEAR ||
+ eparam==GL_LINEAR_MIPMAP_LINEAR) &&
+ texObj->Target != GL_TEXTURE_RECTANGLE_NV) {
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texObj->MinFilter = eparam;
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
+ return;
+ }
+ break;
+ case GL_TEXTURE_MAG_FILTER:
+ /* A small optimization */
+ if (texObj->MagFilter == eparam)
+ return;
+
+ if (eparam==GL_NEAREST || eparam==GL_LINEAR) {
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texObj->MagFilter = eparam;
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
+ return;
+ }
+ break;
+ case GL_TEXTURE_WRAP_S:
+ if (texObj->WrapS == eparam)
+ return;
+ if (_mesa_validate_texture_wrap_mode(ctx, texObj->Target, eparam)) {
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texObj->WrapS = eparam;
+ }
+ else {
+ return;
+ }
+ break;
+ case GL_TEXTURE_WRAP_T:
+ if (texObj->WrapT == eparam)
+ return;
+ if (_mesa_validate_texture_wrap_mode(ctx, texObj->Target, eparam)) {
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texObj->WrapT = eparam;
+ }
+ else {
+ return;
+ }
+ break;
+ case GL_TEXTURE_WRAP_R:
+ if (texObj->WrapR == eparam)
+ return;
+ if (_mesa_validate_texture_wrap_mode(ctx, texObj->Target, eparam)) {
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texObj->WrapR = eparam;
+ }
+ else {
+ return;
+ }
+ break;
+ case GL_TEXTURE_BORDER_COLOR:
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texObj->BorderColor[RCOMP] = params[0];
+ texObj->BorderColor[GCOMP] = params[1];
+ texObj->BorderColor[BCOMP] = params[2];
+ texObj->BorderColor[ACOMP] = params[3];
+ UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[RCOMP], params[0]);
+ UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[GCOMP], params[1]);
+ UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[BCOMP], params[2]);
+ UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[ACOMP], params[3]);
+ break;
+ case GL_TEXTURE_MIN_LOD:
+ if (texObj->MinLod == params[0])
+ return;
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texObj->MinLod = params[0];
+ break;
+ case GL_TEXTURE_MAX_LOD:
+ if (texObj->MaxLod == params[0])
+ return;
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texObj->MaxLod = params[0];
+ break;
+ case GL_TEXTURE_BASE_LEVEL:
+ if (params[0] < 0.0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
+ return;
+ }
+ if (target == GL_TEXTURE_RECTANGLE_NV && params[0] != 0.0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
+ return;
+ }
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texObj->BaseLevel = (GLint) params[0];
+ break;
+ case GL_TEXTURE_MAX_LEVEL:
+ if (params[0] < 0.0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
+ return;
+ }
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texObj->MaxLevel = (GLint) params[0];
+ break;
+ case GL_TEXTURE_PRIORITY:
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texObj->Priority = CLAMP( params[0], 0.0F, 1.0F );
+ break;
+ case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+ if (ctx->Extensions.EXT_texture_filter_anisotropic) {
+ if (params[0] < 1.0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
+ return;
+ }
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ /* clamp to max, that's what NVIDIA does */
+ texObj->MaxAnisotropy = MIN2(params[0],
+ ctx->Const.MaxTextureMaxAnisotropy);
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glTexParameter(pname=GL_TEXTURE_MAX_ANISOTROPY_EXT)");
+ return;
+ }
+ break;
+ case GL_TEXTURE_COMPARE_SGIX:
+ if (ctx->Extensions.SGIX_shadow) {
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texObj->CompareFlag = params[0] ? GL_TRUE : GL_FALSE;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glTexParameter(pname=GL_TEXTURE_COMPARE_SGIX)");
+ return;
+ }
+ break;
+ case GL_TEXTURE_COMPARE_OPERATOR_SGIX:
+ if (ctx->Extensions.SGIX_shadow) {
+ GLenum op = (GLenum) params[0];
+ if (op == GL_TEXTURE_LEQUAL_R_SGIX ||
+ op == GL_TEXTURE_GEQUAL_R_SGIX) {
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texObj->CompareOperator = op;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(param)");
+ }
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glTexParameter(pname=GL_TEXTURE_COMPARE_OPERATOR_SGIX)");
+ return;
+ }
+ break;
+ case GL_SHADOW_AMBIENT_SGIX: /* aka GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
+ if (ctx->Extensions.SGIX_shadow_ambient) {
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texObj->ShadowAmbient = CLAMP(params[0], 0.0F, 1.0F);
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glTexParameter(pname=GL_SHADOW_AMBIENT_SGIX)");
+ return;
+ }
+ break;
+ case GL_GENERATE_MIPMAP_SGIS:
+ if (ctx->Extensions.SGIS_generate_mipmap) {
+ texObj->GenerateMipmap = params[0] ? GL_TRUE : GL_FALSE;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glTexParameter(pname=GL_GENERATE_MIPMAP_SGIS)");
+ return;
+ }
+ break;
+ case GL_TEXTURE_COMPARE_MODE_ARB:
+ if (ctx->Extensions.ARB_shadow) {
+ const GLenum mode = (GLenum) params[0];
+ if (mode == GL_NONE || mode == GL_COMPARE_R_TO_TEXTURE_ARB) {
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texObj->CompareMode = mode;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glTexParameter(bad GL_TEXTURE_COMPARE_MODE_ARB: 0x%x)", mode);
+ return;
+ }
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glTexParameter(pname=GL_TEXTURE_COMPARE_MODE_ARB)");
+ return;
+ }
+ break;
+ case GL_TEXTURE_COMPARE_FUNC_ARB:
+ if (ctx->Extensions.ARB_shadow) {
+ const GLenum func = (GLenum) params[0];
+ if (func == GL_LEQUAL || func == GL_GEQUAL) {
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texObj->CompareFunc = func;
+ }
+ else if (ctx->Extensions.EXT_shadow_funcs &&
+ (func == GL_EQUAL ||
+ func == GL_NOTEQUAL ||
+ func == GL_LESS ||
+ func == GL_GREATER ||
+ func == GL_ALWAYS ||
+ func == GL_NEVER)) {
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texObj->CompareFunc = func;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glTexParameter(bad GL_TEXTURE_COMPARE_FUNC_ARB)");
+ return;
+ }
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glTexParameter(pname=GL_TEXTURE_COMPARE_FUNC_ARB)");
+ return;
+ }
+ break;
+ case GL_DEPTH_TEXTURE_MODE_ARB:
+ if (ctx->Extensions.ARB_depth_texture) {
+ const GLenum result = (GLenum) params[0];
+ if (result == GL_LUMINANCE || result == GL_INTENSITY
+ || result == GL_ALPHA) {
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texObj->DepthMode = result;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glTexParameter(bad GL_DEPTH_TEXTURE_MODE_ARB)");
+ return;
+ }
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glTexParameter(pname=GL_DEPTH_TEXTURE_MODE_ARB)");
+ return;
+ }
+ break;
+ case GL_TEXTURE_LOD_BIAS:
+ /* NOTE: this is really part of OpenGL 1.4, not EXT_texture_lod_bias*/
+ if (ctx->Extensions.EXT_texture_lod_bias) {
+ if (texObj->LodBias != params[0]) {
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texObj->LodBias = params[0];
+ }
+ }
+ break;
+
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glTexParameter(pname=0x%x)", pname);
+ return;
+ }
+
+ texObj->Complete = GL_FALSE;
+
+ if (ctx->Driver.TexParameter) {
+ (*ctx->Driver.TexParameter)( ctx, target, texObj, pname, params );
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_TexParameteri( GLenum target, GLenum pname, GLint param )
+{
+ GLfloat fparam[4];
+ if (pname == GL_TEXTURE_PRIORITY)
+ fparam[0] = INT_TO_FLOAT(param);
+ else
+ fparam[0] = (GLfloat) param;
+ fparam[1] = fparam[2] = fparam[3] = 0.0;
+ _mesa_TexParameterfv(target, pname, fparam);
+}
+
+
+void GLAPIENTRY
+_mesa_TexParameteriv( GLenum target, GLenum pname, const GLint *params )
+{
+ GLfloat fparam[4];
+ if (pname == GL_TEXTURE_BORDER_COLOR) {
+ fparam[0] = INT_TO_FLOAT(params[0]);
+ fparam[1] = INT_TO_FLOAT(params[1]);
+ fparam[2] = INT_TO_FLOAT(params[2]);
+ fparam[3] = INT_TO_FLOAT(params[3]);
+ }
+ else {
+ if (pname == GL_TEXTURE_PRIORITY)
+ fparam[0] = INT_TO_FLOAT(params[0]);
+ else
+ fparam[0] = (GLfloat) params[0];
+ fparam[1] = fparam[2] = fparam[3] = 0.0F;
+ }
+ _mesa_TexParameterfv(target, pname, fparam);
+}
+
+
+void GLAPIENTRY
+_mesa_GetTexLevelParameterfv( GLenum target, GLint level,
+ GLenum pname, GLfloat *params )
+{
+ GLint iparam;
+ _mesa_GetTexLevelParameteriv( target, level, pname, &iparam );
+ *params = (GLfloat) iparam;
+}
+
+
+static GLuint
+tex_image_dimensions(GLcontext *ctx, GLenum target)
+{
+ switch (target) {
+ case GL_TEXTURE_1D:
+ case GL_PROXY_TEXTURE_1D:
+ return 1;
+ case GL_TEXTURE_2D:
+ case GL_PROXY_TEXTURE_2D:
+ return 2;
+ case GL_TEXTURE_3D:
+ case GL_PROXY_TEXTURE_3D:
+ return 3;
+ case GL_TEXTURE_CUBE_MAP:
+ case GL_PROXY_TEXTURE_CUBE_MAP:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ return ctx->Extensions.ARB_texture_cube_map ? 2 : 0;
+ case GL_TEXTURE_RECTANGLE_NV:
+ case GL_PROXY_TEXTURE_RECTANGLE_NV:
+ return ctx->Extensions.NV_texture_rectangle ? 2 : 0;
+ default:
+ _mesa_problem(ctx, "bad target in _mesa_tex_target_dimensions()");
+ return 0;
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_GetTexLevelParameteriv( GLenum target, GLint level,
+ GLenum pname, GLint *params )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ const struct gl_texture_image *img = NULL;
+ GLuint dimensions;
+ GLboolean isProxy;
+ GLint maxLevels;
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ /* this will catch bad target values */
+ dimensions = tex_image_dimensions(ctx, target); /* 1, 2 or 3 */
+ if (dimensions == 0) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(target)");
+ return;
+ }
+
+ maxLevels = _mesa_max_texture_levels(ctx, target);
+ if (maxLevels == 0) {
+ /* should not happen since <target> was just checked above */
+ _mesa_problem(ctx, "maxLevels=0 in _mesa_GetTexLevelParameter");
+ return;
+ }
+
+ if (level < 0 || level >= maxLevels) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexLevelParameter[if]v" );
+ return;
+ }
+
+ img = _mesa_select_tex_image(ctx, texUnit, target, level);
+ if (!img || !img->TexFormat) {
+ /* undefined texture image */
+ if (pname == GL_TEXTURE_COMPONENTS)
+ *params = 1;
+ else
+ *params = 0;
+ return;
+ }
+
+ isProxy = _mesa_is_proxy_texture(target);
+
+ switch (pname) {
+ case GL_TEXTURE_WIDTH:
+ *params = img->Width;
+ return;
+ case GL_TEXTURE_HEIGHT:
+ *params = img->Height;
+ return;
+ case GL_TEXTURE_DEPTH:
+ *params = img->Depth;
+ return;
+ case GL_TEXTURE_INTERNAL_FORMAT:
+ *params = img->InternalFormat;
+ return;
+ case GL_TEXTURE_BORDER:
+ *params = img->Border;
+ return;
+ case GL_TEXTURE_RED_SIZE:
+ if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA)
+ *params = img->TexFormat->RedBits;
+ else
+ *params = 0;
+ return;
+ case GL_TEXTURE_GREEN_SIZE:
+ if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA)
+ *params = img->TexFormat->GreenBits;
+ else
+ *params = 0;
+ return;
+ case GL_TEXTURE_BLUE_SIZE:
+ if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA)
+ *params = img->TexFormat->BlueBits;
+ else
+ *params = 0;
+ return;
+ case GL_TEXTURE_ALPHA_SIZE:
+ if (img->_BaseFormat == GL_ALPHA ||
+ img->_BaseFormat == GL_LUMINANCE_ALPHA ||
+ img->_BaseFormat == GL_RGBA)
+ *params = img->TexFormat->AlphaBits;
+ else
+ *params = 0;
+ return;
+ case GL_TEXTURE_INTENSITY_SIZE:
+ if (img->_BaseFormat != GL_INTENSITY)
+ *params = 0;
+ else if (img->TexFormat->IntensityBits > 0)
+ *params = img->TexFormat->IntensityBits;
+ else /* intensity probably stored as rgb texture */
+ *params = MIN2(img->TexFormat->RedBits, img->TexFormat->GreenBits);
+ return;
+ case GL_TEXTURE_LUMINANCE_SIZE:
+ if (img->_BaseFormat != GL_LUMINANCE &&
+ img->_BaseFormat != GL_LUMINANCE_ALPHA)
+ *params = 0;
+ else if (img->TexFormat->LuminanceBits > 0)
+ *params = img->TexFormat->LuminanceBits;
+ else /* luminance probably stored as rgb texture */
+ *params = MIN2(img->TexFormat->RedBits, img->TexFormat->GreenBits);
+ return;
+ case GL_TEXTURE_INDEX_SIZE_EXT:
+ if (img->_BaseFormat == GL_COLOR_INDEX)
+ *params = img->TexFormat->IndexBits;
+ else
+ *params = 0;
+ return;
+ case GL_TEXTURE_DEPTH_SIZE_ARB:
+ if (ctx->Extensions.SGIX_depth_texture ||
+ ctx->Extensions.ARB_depth_texture)
+ *params = img->TexFormat->DepthBits;
+ else
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetTexLevelParameter[if]v(pname)");
+ return;
+ case GL_TEXTURE_STENCIL_SIZE_EXT:
+ if (ctx->Extensions.EXT_packed_depth_stencil) {
+ *params = img->TexFormat->StencilBits;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetTexLevelParameter[if]v(pname)");
+ }
+ return;
+
+ /* GL_ARB_texture_compression */
+ case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
+ if (ctx->Extensions.ARB_texture_compression) {
+ if (img->IsCompressed && !isProxy)
+ *params = img->CompressedSize;
+ else
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetTexLevelParameter[if]v(pname)");
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetTexLevelParameter[if]v(pname)");
+ }
+ return;
+ case GL_TEXTURE_COMPRESSED:
+ if (ctx->Extensions.ARB_texture_compression) {
+ *params = (GLint) img->IsCompressed;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetTexLevelParameter[if]v(pname)");
+ }
+ return;
+
+ /* GL_ARB_texture_float */
+ case GL_TEXTURE_RED_TYPE_ARB:
+ if (ctx->Extensions.ARB_texture_float) {
+ *params = img->TexFormat->RedBits ? img->TexFormat->DataType : GL_NONE;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetTexLevelParameter[if]v(pname)");
+ }
+ return;
+ case GL_TEXTURE_GREEN_TYPE_ARB:
+ if (ctx->Extensions.ARB_texture_float) {
+ *params = img->TexFormat->GreenBits ? img->TexFormat->DataType : GL_NONE;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetTexLevelParameter[if]v(pname)");
+ }
+ return;
+ case GL_TEXTURE_BLUE_TYPE_ARB:
+ if (ctx->Extensions.ARB_texture_float) {
+ *params = img->TexFormat->BlueBits ? img->TexFormat->DataType : GL_NONE;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetTexLevelParameter[if]v(pname)");
+ }
+ return;
+ case GL_TEXTURE_ALPHA_TYPE_ARB:
+ if (ctx->Extensions.ARB_texture_float) {
+ *params = img->TexFormat->AlphaBits ? img->TexFormat->DataType : GL_NONE;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetTexLevelParameter[if]v(pname)");
+ }
+ return;
+ case GL_TEXTURE_LUMINANCE_TYPE_ARB:
+ if (ctx->Extensions.ARB_texture_float) {
+ *params = img->TexFormat->LuminanceBits ? img->TexFormat->DataType : GL_NONE;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetTexLevelParameter[if]v(pname)");
+ }
+ return;
+ case GL_TEXTURE_INTENSITY_TYPE_ARB:
+ if (ctx->Extensions.ARB_texture_float) {
+ *params = img->TexFormat->IntensityBits ? img->TexFormat->DataType : GL_NONE;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetTexLevelParameter[if]v(pname)");
+ }
+ return;
+ case GL_TEXTURE_DEPTH_TYPE_ARB:
+ if (ctx->Extensions.ARB_texture_float) {
+ *params = img->TexFormat->DepthBits ? img->TexFormat->DataType : GL_NONE;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetTexLevelParameter[if]v(pname)");
+ }
+ return;
+
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetTexLevelParameter[if]v(pname)");
+ }
+}
+
+
+
+void GLAPIENTRY
+_mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ struct gl_texture_object *obj;
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ obj = _mesa_select_tex_object(ctx, texUnit, target);
+ if (!obj) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(target)");
+ return;
+ }
+
+ switch (pname) {
+ case GL_TEXTURE_MAG_FILTER:
+ *params = ENUM_TO_FLOAT(obj->MagFilter);
+ return;
+ case GL_TEXTURE_MIN_FILTER:
+ *params = ENUM_TO_FLOAT(obj->MinFilter);
+ return;
+ case GL_TEXTURE_WRAP_S:
+ *params = ENUM_TO_FLOAT(obj->WrapS);
+ return;
+ case GL_TEXTURE_WRAP_T:
+ *params = ENUM_TO_FLOAT(obj->WrapT);
+ return;
+ case GL_TEXTURE_WRAP_R:
+ *params = ENUM_TO_FLOAT(obj->WrapR);
+ return;
+ case GL_TEXTURE_BORDER_COLOR:
+ params[0] = CLAMP(obj->BorderColor[0], 0.0F, 1.0F);
+ params[1] = CLAMP(obj->BorderColor[1], 0.0F, 1.0F);
+ params[2] = CLAMP(obj->BorderColor[2], 0.0F, 1.0F);
+ params[3] = CLAMP(obj->BorderColor[3], 0.0F, 1.0F);
+ return;
+ case GL_TEXTURE_RESIDENT:
+ {
+ GLboolean resident;
+ if (ctx->Driver.IsTextureResident)
+ resident = ctx->Driver.IsTextureResident(ctx, obj);
+ else
+ resident = GL_TRUE;
+ *params = ENUM_TO_FLOAT(resident);
+ }
+ return;
+ case GL_TEXTURE_PRIORITY:
+ *params = obj->Priority;
+ return;
+ case GL_TEXTURE_MIN_LOD:
+ *params = obj->MinLod;
+ return;
+ case GL_TEXTURE_MAX_LOD:
+ *params = obj->MaxLod;
+ return;
+ case GL_TEXTURE_BASE_LEVEL:
+ *params = (GLfloat) obj->BaseLevel;
+ return;
+ case GL_TEXTURE_MAX_LEVEL:
+ *params = (GLfloat) obj->MaxLevel;
+ return;
+ case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+ if (ctx->Extensions.EXT_texture_filter_anisotropic) {
+ *params = obj->MaxAnisotropy;
+ return;
+ }
+ break;
+ case GL_TEXTURE_COMPARE_SGIX:
+ if (ctx->Extensions.SGIX_shadow) {
+ *params = (GLfloat) obj->CompareFlag;
+ return;
+ }
+ break;
+ case GL_TEXTURE_COMPARE_OPERATOR_SGIX:
+ if (ctx->Extensions.SGIX_shadow) {
+ *params = (GLfloat) obj->CompareOperator;
+ return;
+ }
+ break;
+ case GL_SHADOW_AMBIENT_SGIX: /* aka GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
+ if (ctx->Extensions.SGIX_shadow_ambient) {
+ *params = obj->ShadowAmbient;
+ return;
+ }
+ break;
+ case GL_GENERATE_MIPMAP_SGIS:
+ if (ctx->Extensions.SGIS_generate_mipmap) {
+ *params = (GLfloat) obj->GenerateMipmap;
+ return;
+ }
+ break;
+ case GL_TEXTURE_COMPARE_MODE_ARB:
+ if (ctx->Extensions.ARB_shadow) {
+ *params = (GLfloat) obj->CompareMode;
+ return;
+ }
+ break;
+ case GL_TEXTURE_COMPARE_FUNC_ARB:
+ if (ctx->Extensions.ARB_shadow) {
+ *params = (GLfloat) obj->CompareFunc;
+ return;
+ }
+ break;
+ case GL_DEPTH_TEXTURE_MODE_ARB:
+ if (ctx->Extensions.ARB_depth_texture) {
+ *params = (GLfloat) obj->DepthMode;
+ return;
+ }
+ break;
+ case GL_TEXTURE_LOD_BIAS:
+ if (ctx->Extensions.EXT_texture_lod_bias) {
+ *params = obj->LodBias;
+ return;
+ }
+ break;
+ default:
+ ; /* silence warnings */
+ }
+ /* If we get here, pname was an unrecognized enum */
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname=0x%x)",
+ pname);
+}
+
+
+void GLAPIENTRY
+_mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ struct gl_texture_object *obj;
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ obj = _mesa_select_tex_object(ctx, texUnit, target);
+ if (!obj) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(target)");
+ return;
+ }
+
+ switch (pname) {
+ case GL_TEXTURE_MAG_FILTER:
+ *params = (GLint) obj->MagFilter;
+ return;
+ case GL_TEXTURE_MIN_FILTER:
+ *params = (GLint) obj->MinFilter;
+ return;
+ case GL_TEXTURE_WRAP_S:
+ *params = (GLint) obj->WrapS;
+ return;
+ case GL_TEXTURE_WRAP_T:
+ *params = (GLint) obj->WrapT;
+ return;
+ case GL_TEXTURE_WRAP_R:
+ *params = (GLint) obj->WrapR;
+ return;
+ case GL_TEXTURE_BORDER_COLOR:
+ {
+ GLfloat b[4];
+ b[0] = CLAMP(obj->BorderColor[0], 0.0F, 1.0F);
+ b[1] = CLAMP(obj->BorderColor[1], 0.0F, 1.0F);
+ b[2] = CLAMP(obj->BorderColor[2], 0.0F, 1.0F);
+ b[3] = CLAMP(obj->BorderColor[3], 0.0F, 1.0F);
+ params[0] = FLOAT_TO_INT(b[0]);
+ params[1] = FLOAT_TO_INT(b[1]);
+ params[2] = FLOAT_TO_INT(b[2]);
+ params[3] = FLOAT_TO_INT(b[3]);
+ }
+ return;
+ case GL_TEXTURE_RESIDENT:
+ {
+ GLboolean resident;
+ if (ctx->Driver.IsTextureResident)
+ resident = ctx->Driver.IsTextureResident(ctx, obj);
+ else
+ resident = GL_TRUE;
+ *params = (GLint) resident;
+ }
+ return;
+ case GL_TEXTURE_PRIORITY:
+ *params = FLOAT_TO_INT(obj->Priority);
+ return;
+ case GL_TEXTURE_MIN_LOD:
+ *params = (GLint) obj->MinLod;
+ return;
+ case GL_TEXTURE_MAX_LOD:
+ *params = (GLint) obj->MaxLod;
+ return;
+ case GL_TEXTURE_BASE_LEVEL:
+ *params = obj->BaseLevel;
+ return;
+ case GL_TEXTURE_MAX_LEVEL:
+ *params = obj->MaxLevel;
+ return;
+ case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+ if (ctx->Extensions.EXT_texture_filter_anisotropic) {
+ *params = (GLint) obj->MaxAnisotropy;
+ return;
+ }
+ break;
+ case GL_TEXTURE_COMPARE_SGIX:
+ if (ctx->Extensions.SGIX_shadow) {
+ *params = (GLint) obj->CompareFlag;
+ return;
+ }
+ break;
+ case GL_TEXTURE_COMPARE_OPERATOR_SGIX:
+ if (ctx->Extensions.SGIX_shadow) {
+ *params = (GLint) obj->CompareOperator;
+ return;
+ }
+ break;
+ case GL_SHADOW_AMBIENT_SGIX: /* aka GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
+ if (ctx->Extensions.SGIX_shadow_ambient) {
+ *params = (GLint) FLOAT_TO_INT(obj->ShadowAmbient);
+ return;
+ }
+ break;
+ case GL_GENERATE_MIPMAP_SGIS:
+ if (ctx->Extensions.SGIS_generate_mipmap) {
+ *params = (GLint) obj->GenerateMipmap;
+ return;
+ }
+ break;
+ case GL_TEXTURE_COMPARE_MODE_ARB:
+ if (ctx->Extensions.ARB_shadow) {
+ *params = (GLint) obj->CompareMode;
+ return;
+ }
+ break;
+ case GL_TEXTURE_COMPARE_FUNC_ARB:
+ if (ctx->Extensions.ARB_shadow) {
+ *params = (GLint) obj->CompareFunc;
+ return;
+ }
+ break;
+ case GL_DEPTH_TEXTURE_MODE_ARB:
+ if (ctx->Extensions.ARB_depth_texture) {
+ *params = (GLint) obj->DepthMode;
+ return;
+ }
+ break;
+ case GL_TEXTURE_LOD_BIAS:
+ if (ctx->Extensions.EXT_texture_lod_bias) {
+ *params = (GLint) obj->LodBias;
+ return;
+ }
+ break;
+ default:
+ ; /* silence warnings */
+ }
+ /* If we get here, pname was an unrecognized enum */
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname=0x%x)", pname);
+}
+
+
+
+
+/**********************************************************************/
+/* Texture Coord Generation */
+/**********************************************************************/
+
+#if FEATURE_texgen
+void GLAPIENTRY
+_mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLuint tUnit = ctx->Texture.CurrentUnit;
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit];
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glTexGen %s %s %.1f(%s)...\n",
+ _mesa_lookup_enum_by_nr(coord),
+ _mesa_lookup_enum_by_nr(pname),
+ *params,
+ _mesa_lookup_enum_by_nr((GLenum) (GLint) *params));
+
+ switch (coord) {
+ case GL_S:
+ if (pname==GL_TEXTURE_GEN_MODE) {
+ GLenum mode = (GLenum) (GLint) *params;
+ GLbitfield bits;
+ switch (mode) {
+ case GL_OBJECT_LINEAR:
+ bits = TEXGEN_OBJ_LINEAR;
+ break;
+ case GL_EYE_LINEAR:
+ bits = TEXGEN_EYE_LINEAR;
+ break;
+ case GL_REFLECTION_MAP_NV:
+ bits = TEXGEN_REFLECTION_MAP_NV;
+ break;
+ case GL_NORMAL_MAP_NV:
+ bits = TEXGEN_NORMAL_MAP_NV;
+ break;
+ case GL_SPHERE_MAP:
+ bits = TEXGEN_SPHERE_MAP;
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
+ return;
+ }
+ if (texUnit->GenModeS == mode)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texUnit->GenModeS = mode;
+ texUnit->_GenBitS = bits;
+ }
+ else if (pname==GL_OBJECT_PLANE) {
+ if (TEST_EQ_4V(texUnit->ObjectPlaneS, params))
+ return;
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ COPY_4FV(texUnit->ObjectPlaneS, params);
+ }
+ else if (pname==GL_EYE_PLANE) {
+ GLfloat tmp[4];
+ /* Transform plane equation by the inverse modelview matrix */
+ if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) {
+ _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
+ }
+ _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv );
+ if (TEST_EQ_4V(texUnit->EyePlaneS, tmp))
+ return;
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ COPY_4FV(texUnit->EyePlaneS, tmp);
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
+ return;
+ }
+ break;
+ case GL_T:
+ if (pname==GL_TEXTURE_GEN_MODE) {
+ GLenum mode = (GLenum) (GLint) *params;
+ GLbitfield bitt;
+ switch (mode) {
+ case GL_OBJECT_LINEAR:
+ bitt = TEXGEN_OBJ_LINEAR;
+ break;
+ case GL_EYE_LINEAR:
+ bitt = TEXGEN_EYE_LINEAR;
+ break;
+ case GL_REFLECTION_MAP_NV:
+ bitt = TEXGEN_REFLECTION_MAP_NV;
+ break;
+ case GL_NORMAL_MAP_NV:
+ bitt = TEXGEN_NORMAL_MAP_NV;
+ break;
+ case GL_SPHERE_MAP:
+ bitt = TEXGEN_SPHERE_MAP;
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
+ return;
+ }
+ if (texUnit->GenModeT == mode)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texUnit->GenModeT = mode;
+ texUnit->_GenBitT = bitt;
+ }
+ else if (pname==GL_OBJECT_PLANE) {
+ if (TEST_EQ_4V(texUnit->ObjectPlaneT, params))
+ return;
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ COPY_4FV(texUnit->ObjectPlaneT, params);
+ }
+ else if (pname==GL_EYE_PLANE) {
+ GLfloat tmp[4];
+ /* Transform plane equation by the inverse modelview matrix */
+ if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) {
+ _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
+ }
+ _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv );
+ if (TEST_EQ_4V(texUnit->EyePlaneT, tmp))
+ return;
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ COPY_4FV(texUnit->EyePlaneT, tmp);
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
+ return;
+ }
+ break;
+ case GL_R:
+ if (pname==GL_TEXTURE_GEN_MODE) {
+ GLenum mode = (GLenum) (GLint) *params;
+ GLbitfield bitr;
+ switch (mode) {
+ case GL_OBJECT_LINEAR:
+ bitr = TEXGEN_OBJ_LINEAR;
+ break;
+ case GL_REFLECTION_MAP_NV:
+ bitr = TEXGEN_REFLECTION_MAP_NV;
+ break;
+ case GL_NORMAL_MAP_NV:
+ bitr = TEXGEN_NORMAL_MAP_NV;
+ break;
+ case GL_EYE_LINEAR:
+ bitr = TEXGEN_EYE_LINEAR;
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
+ return;
+ }
+ if (texUnit->GenModeR == mode)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texUnit->GenModeR = mode;
+ texUnit->_GenBitR = bitr;
+ }
+ else if (pname==GL_OBJECT_PLANE) {
+ if (TEST_EQ_4V(texUnit->ObjectPlaneR, params))
+ return;
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ COPY_4FV(texUnit->ObjectPlaneR, params);
+ }
+ else if (pname==GL_EYE_PLANE) {
+ GLfloat tmp[4];
+ /* Transform plane equation by the inverse modelview matrix */
+ if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) {
+ _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
+ }
+ _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv );
+ if (TEST_EQ_4V(texUnit->EyePlaneR, tmp))
+ return;
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ COPY_4FV(texUnit->EyePlaneR, tmp);
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
+ return;
+ }
+ break;
+ case GL_Q:
+ if (pname==GL_TEXTURE_GEN_MODE) {
+ GLenum mode = (GLenum) (GLint) *params;
+ GLbitfield bitq;
+ switch (mode) {
+ case GL_OBJECT_LINEAR:
+ bitq = TEXGEN_OBJ_LINEAR;
+ break;
+ case GL_EYE_LINEAR:
+ bitq = TEXGEN_EYE_LINEAR;
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
+ return;
+ }
+ if (texUnit->GenModeQ == mode)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texUnit->GenModeQ = mode;
+ texUnit->_GenBitQ = bitq;
+ }
+ else if (pname==GL_OBJECT_PLANE) {
+ if (TEST_EQ_4V(texUnit->ObjectPlaneQ, params))
+ return;
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ COPY_4FV(texUnit->ObjectPlaneQ, params);
+ }
+ else if (pname==GL_EYE_PLANE) {
+ GLfloat tmp[4];
+ /* Transform plane equation by the inverse modelview matrix */
+ if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) {
+ _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
+ }
+ _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv );
+ if (TEST_EQ_4V(texUnit->EyePlaneQ, tmp))
+ return;
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ COPY_4FV(texUnit->EyePlaneQ, tmp);
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
+ return;
+ }
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(coord)" );
+ return;
+ }
+
+ if (ctx->Driver.TexGen)
+ ctx->Driver.TexGen( ctx, coord, pname, params );
+}
+
+
+void GLAPIENTRY
+_mesa_TexGeniv(GLenum coord, GLenum pname, const GLint *params )
+{
+ GLfloat p[4];
+ p[0] = (GLfloat) params[0];
+ if (pname == GL_TEXTURE_GEN_MODE) {
+ p[1] = p[2] = p[3] = 0.0F;
+ }
+ else {
+ p[1] = (GLfloat) params[1];
+ p[2] = (GLfloat) params[2];
+ p[3] = (GLfloat) params[3];
+ }
+ _mesa_TexGenfv(coord, pname, p);
+}
+
+
+void GLAPIENTRY
+_mesa_TexGend(GLenum coord, GLenum pname, GLdouble param )
+{
+ GLfloat p = (GLfloat) param;
+ _mesa_TexGenfv( coord, pname, &p );
+}
+
+
+void GLAPIENTRY
+_mesa_TexGendv(GLenum coord, GLenum pname, const GLdouble *params )
+{
+ GLfloat p[4];
+ p[0] = (GLfloat) params[0];
+ if (pname == GL_TEXTURE_GEN_MODE) {
+ p[1] = p[2] = p[3] = 0.0F;
+ }
+ else {
+ p[1] = (GLfloat) params[1];
+ p[2] = (GLfloat) params[2];
+ p[3] = (GLfloat) params[3];
+ }
+ _mesa_TexGenfv( coord, pname, p );
+}
+
+
+void GLAPIENTRY
+_mesa_TexGenf( GLenum coord, GLenum pname, GLfloat param )
+{
+ _mesa_TexGenfv(coord, pname, &param);
+}
+
+
+void GLAPIENTRY
+_mesa_TexGeni( GLenum coord, GLenum pname, GLint param )
+{
+ _mesa_TexGeniv( coord, pname, &param );
+}
+
+
+
+void GLAPIENTRY
+_mesa_GetTexGendv( GLenum coord, GLenum pname, GLdouble *params )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLuint tUnit = ctx->Texture.CurrentUnit;
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit];
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ switch (coord) {
+ case GL_S:
+ if (pname==GL_TEXTURE_GEN_MODE) {
+ params[0] = ENUM_TO_DOUBLE(texUnit->GenModeS);
+ }
+ else if (pname==GL_OBJECT_PLANE) {
+ COPY_4V( params, texUnit->ObjectPlaneS );
+ }
+ else if (pname==GL_EYE_PLANE) {
+ COPY_4V( params, texUnit->EyePlaneS );
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
+ return;
+ }
+ break;
+ case GL_T:
+ if (pname==GL_TEXTURE_GEN_MODE) {
+ params[0] = ENUM_TO_DOUBLE(texUnit->GenModeT);
+ }
+ else if (pname==GL_OBJECT_PLANE) {
+ COPY_4V( params, texUnit->ObjectPlaneT );
+ }
+ else if (pname==GL_EYE_PLANE) {
+ COPY_4V( params, texUnit->EyePlaneT );
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
+ return;
+ }
+ break;
+ case GL_R:
+ if (pname==GL_TEXTURE_GEN_MODE) {
+ params[0] = ENUM_TO_DOUBLE(texUnit->GenModeR);
+ }
+ else if (pname==GL_OBJECT_PLANE) {
+ COPY_4V( params, texUnit->ObjectPlaneR );
+ }
+ else if (pname==GL_EYE_PLANE) {
+ COPY_4V( params, texUnit->EyePlaneR );
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
+ return;
+ }
+ break;
+ case GL_Q:
+ if (pname==GL_TEXTURE_GEN_MODE) {
+ params[0] = ENUM_TO_DOUBLE(texUnit->GenModeQ);
+ }
+ else if (pname==GL_OBJECT_PLANE) {
+ COPY_4V( params, texUnit->ObjectPlaneQ );
+ }
+ else if (pname==GL_EYE_PLANE) {
+ COPY_4V( params, texUnit->EyePlaneQ );
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
+ return;
+ }
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(coord)" );
+ return;
+ }
+}
+
+
+
+void GLAPIENTRY
+_mesa_GetTexGenfv( GLenum coord, GLenum pname, GLfloat *params )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLuint tUnit = ctx->Texture.CurrentUnit;
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit];
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ switch (coord) {
+ case GL_S:
+ if (pname==GL_TEXTURE_GEN_MODE) {
+ params[0] = ENUM_TO_FLOAT(texUnit->GenModeS);
+ }
+ else if (pname==GL_OBJECT_PLANE) {
+ COPY_4V( params, texUnit->ObjectPlaneS );
+ }
+ else if (pname==GL_EYE_PLANE) {
+ COPY_4V( params, texUnit->EyePlaneS );
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
+ return;
+ }
+ break;
+ case GL_T:
+ if (pname==GL_TEXTURE_GEN_MODE) {
+ params[0] = ENUM_TO_FLOAT(texUnit->GenModeT);
+ }
+ else if (pname==GL_OBJECT_PLANE) {
+ COPY_4V( params, texUnit->ObjectPlaneT );
+ }
+ else if (pname==GL_EYE_PLANE) {
+ COPY_4V( params, texUnit->EyePlaneT );
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
+ return;
+ }
+ break;
+ case GL_R:
+ if (pname==GL_TEXTURE_GEN_MODE) {
+ params[0] = ENUM_TO_FLOAT(texUnit->GenModeR);
+ }
+ else if (pname==GL_OBJECT_PLANE) {
+ COPY_4V( params, texUnit->ObjectPlaneR );
+ }
+ else if (pname==GL_EYE_PLANE) {
+ COPY_4V( params, texUnit->EyePlaneR );
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
+ return;
+ }
+ break;
+ case GL_Q:
+ if (pname==GL_TEXTURE_GEN_MODE) {
+ params[0] = ENUM_TO_FLOAT(texUnit->GenModeQ);
+ }
+ else if (pname==GL_OBJECT_PLANE) {
+ COPY_4V( params, texUnit->ObjectPlaneQ );
+ }
+ else if (pname==GL_EYE_PLANE) {
+ COPY_4V( params, texUnit->EyePlaneQ );
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
+ return;
+ }
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(coord)" );
+ return;
+ }
+}
+
+
+
+void GLAPIENTRY
+_mesa_GetTexGeniv( GLenum coord, GLenum pname, GLint *params )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLuint tUnit = ctx->Texture.CurrentUnit;
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit];
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ switch (coord) {
+ case GL_S:
+ if (pname==GL_TEXTURE_GEN_MODE) {
+ params[0] = texUnit->GenModeS;
+ }
+ else if (pname==GL_OBJECT_PLANE) {
+ params[0] = (GLint) texUnit->ObjectPlaneS[0];
+ params[1] = (GLint) texUnit->ObjectPlaneS[1];
+ params[2] = (GLint) texUnit->ObjectPlaneS[2];
+ params[3] = (GLint) texUnit->ObjectPlaneS[3];
+ }
+ else if (pname==GL_EYE_PLANE) {
+ params[0] = (GLint) texUnit->EyePlaneS[0];
+ params[1] = (GLint) texUnit->EyePlaneS[1];
+ params[2] = (GLint) texUnit->EyePlaneS[2];
+ params[3] = (GLint) texUnit->EyePlaneS[3];
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
+ return;
+ }
+ break;
+ case GL_T:
+ if (pname==GL_TEXTURE_GEN_MODE) {
+ params[0] = texUnit->GenModeT;
+ }
+ else if (pname==GL_OBJECT_PLANE) {
+ params[0] = (GLint) texUnit->ObjectPlaneT[0];
+ params[1] = (GLint) texUnit->ObjectPlaneT[1];
+ params[2] = (GLint) texUnit->ObjectPlaneT[2];
+ params[3] = (GLint) texUnit->ObjectPlaneT[3];
+ }
+ else if (pname==GL_EYE_PLANE) {
+ params[0] = (GLint) texUnit->EyePlaneT[0];
+ params[1] = (GLint) texUnit->EyePlaneT[1];
+ params[2] = (GLint) texUnit->EyePlaneT[2];
+ params[3] = (GLint) texUnit->EyePlaneT[3];
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
+ return;
+ }
+ break;
+ case GL_R:
+ if (pname==GL_TEXTURE_GEN_MODE) {
+ params[0] = texUnit->GenModeR;
+ }
+ else if (pname==GL_OBJECT_PLANE) {
+ params[0] = (GLint) texUnit->ObjectPlaneR[0];
+ params[1] = (GLint) texUnit->ObjectPlaneR[1];
+ params[2] = (GLint) texUnit->ObjectPlaneR[2];
+ params[3] = (GLint) texUnit->ObjectPlaneR[3];
+ }
+ else if (pname==GL_EYE_PLANE) {
+ params[0] = (GLint) texUnit->EyePlaneR[0];
+ params[1] = (GLint) texUnit->EyePlaneR[1];
+ params[2] = (GLint) texUnit->EyePlaneR[2];
+ params[3] = (GLint) texUnit->EyePlaneR[3];
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
+ return;
+ }
+ break;
+ case GL_Q:
+ if (pname==GL_TEXTURE_GEN_MODE) {
+ params[0] = texUnit->GenModeQ;
+ }
+ else if (pname==GL_OBJECT_PLANE) {
+ params[0] = (GLint) texUnit->ObjectPlaneQ[0];
+ params[1] = (GLint) texUnit->ObjectPlaneQ[1];
+ params[2] = (GLint) texUnit->ObjectPlaneQ[2];
+ params[3] = (GLint) texUnit->ObjectPlaneQ[3];
+ }
+ else if (pname==GL_EYE_PLANE) {
+ params[0] = (GLint) texUnit->EyePlaneQ[0];
+ params[1] = (GLint) texUnit->EyePlaneQ[1];
+ params[2] = (GLint) texUnit->EyePlaneQ[2];
+ params[3] = (GLint) texUnit->EyePlaneQ[3];
+ }
+ else {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
+ return;
+ }
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(coord)" );
+ return;
+ }
+}
+#endif
+
+/* GL_ARB_multitexture */
+void GLAPIENTRY
+_mesa_ActiveTextureARB( GLenum target )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ const GLuint texUnit = target - GL_TEXTURE0;
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glActiveTexture %s\n",
+ _mesa_lookup_enum_by_nr(target));
+
+ /* Cater for texture unit 0 is first, therefore use >= */
+ if (texUnit >= ctx->Const.MaxTextureUnits) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glActiveTexture(target)");
+ return;
+ }
+
+ if (ctx->Texture.CurrentUnit == texUnit)
+ return;
+
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+
+ ctx->Texture.CurrentUnit = texUnit;
+ if (ctx->Transform.MatrixMode == GL_TEXTURE) {
+ /* update current stack pointer */
+ ctx->CurrentStack = &ctx->TextureMatrixStack[texUnit];
+ }
+
+ if (ctx->Driver.ActiveTexture) {
+ (*ctx->Driver.ActiveTexture)( ctx, (GLuint) texUnit );
+ }
+}
+
+
+/* GL_ARB_multitexture */
+void GLAPIENTRY
+_mesa_ClientActiveTextureARB( GLenum target )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLuint texUnit = target - GL_TEXTURE0;
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (texUnit >= ctx->Const.MaxTextureUnits) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glClientActiveTexture(target)");
+ return;
+ }
+
+ FLUSH_VERTICES(ctx, _NEW_ARRAY);
+ ctx->Array.ActiveTexture = texUnit;
+}
+
+
+
+/**********************************************************************/
+/***** State management *****/
+/**********************************************************************/
+
+
+/**
+ * \note This routine refers to derived texture attribute values to
+ * compute the ENABLE_TEXMAT flags, but is only called on
+ * _NEW_TEXTURE_MATRIX. On changes to _NEW_TEXTURE, the ENABLE_TEXMAT
+ * flags are updated by _mesa_update_textures(), below.
+ *
+ * \param ctx GL context.
+ */
+static void
+update_texture_matrices( GLcontext *ctx )
+{
+ GLuint i;
+
+ ctx->Texture._TexMatEnabled = 0;
+
+ for (i=0; i < ctx->Const.MaxTextureUnits; i++) {
+ if (_math_matrix_is_dirty(ctx->TextureMatrixStack[i].Top)) {
+ _math_matrix_analyse( ctx->TextureMatrixStack[i].Top );
+
+ if (ctx->Texture.Unit[i]._ReallyEnabled &&
+ ctx->TextureMatrixStack[i].Top->type != MATRIX_IDENTITY)
+ ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(i);
+
+ if (ctx->Driver.TextureMatrix)
+ ctx->Driver.TextureMatrix( ctx, i, ctx->TextureMatrixStack[i].Top);
+ }
+ }
+}
+
+
+/**
+ * Helper function for determining which texture object (1D, 2D, cube, etc)
+ * should actually be used.
+ */
+static void
+texture_override(GLcontext *ctx,
+ struct gl_texture_unit *texUnit, GLbitfield enableBits,
+ struct gl_texture_object *texObj, GLuint textureBit)
+{
+ if (!texUnit->_ReallyEnabled && (enableBits & textureBit)) {
+ if (!texObj->Complete) {
+ _mesa_test_texobj_completeness(ctx, texObj);
+ }
+ if (texObj->Complete) {
+ texUnit->_ReallyEnabled = textureBit;
+ texUnit->_Current = texObj;
+ }
+ }
+}
+
+
+/**
+ * \note This routine refers to derived texture matrix values to
+ * compute the ENABLE_TEXMAT flags, but is only called on
+ * _NEW_TEXTURE. On changes to _NEW_TEXTURE_MATRIX, the ENABLE_TEXMAT
+ * flags are updated by _mesa_update_texture_matrices, above.
+ *
+ * \param ctx GL context.
+ */
+static void
+update_texture_state( GLcontext *ctx )
+{
+ GLuint unit;
+ struct gl2_program_intf **prog = ctx->ShaderObjects.CurrentProgram;
+ GLbitfield progteximageusage[MAX_TEXTURE_IMAGE_UNITS];
+
+ ctx->NewState |= _NEW_TEXTURE; /* TODO: only set this if there are
+ * actual changes.
+ */
+
+ ctx->Texture._EnabledUnits = 0;
+ ctx->Texture._GenFlags = 0;
+ ctx->Texture._TexMatEnabled = 0;
+ ctx->Texture._TexGenEnabled = 0;
+
+ /*
+ * Grab texture image usage state from shader program. It must be
+ * grabbed every time uniform sampler changes, so maybe there is a
+ * better place to perform these rather expensive computations.
+ */
+ if (ctx->ShaderObjects._FragmentShaderPresent) {
+ (**prog).GetTextureImageUsage (prog, progteximageusage);
+ }
+
+ /*
+ * Update texture unit state.
+ */
+ for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+ GLbitfield enableBits;
+
+ texUnit->_Current = NULL;
+ texUnit->_ReallyEnabled = 0;
+ texUnit->_GenFlags = 0;
+
+ /* Get the bitmask of texture enables */
+ if (ctx->ShaderObjects._FragmentShaderPresent) {
+ enableBits = progteximageusage[unit];
+ }
+ else if (ctx->FragmentProgram._Enabled) {
+ enableBits = ctx->FragmentProgram.Current->TexturesUsed[unit];
+ }
+ else {
+ if (!texUnit->Enabled)
+ continue;
+ enableBits = texUnit->Enabled;
+ }
+
+ /* Look for the highest-priority texture target that's enabled and
+ * complete. That's the one we'll use for texturing. If we're using
+ * a fragment program we're guaranteed that bitcount(enabledBits) <= 1.
+ */
+ texture_override(ctx, texUnit, enableBits,
+ texUnit->CurrentCubeMap, TEXTURE_CUBE_BIT);
+ texture_override(ctx, texUnit, enableBits,
+ texUnit->Current3D, TEXTURE_3D_BIT);
+ texture_override(ctx, texUnit, enableBits,
+ texUnit->CurrentRect, TEXTURE_RECT_BIT);
+ texture_override(ctx, texUnit, enableBits,
+ texUnit->Current2D, TEXTURE_2D_BIT);
+ texture_override(ctx, texUnit, enableBits,
+ texUnit->Current1D, TEXTURE_1D_BIT);
+
+ if (!texUnit->_ReallyEnabled) {
+ continue;
+ }
+
+ if (texUnit->_ReallyEnabled)
+ ctx->Texture._EnabledUnits |= (1 << unit);
+
+ if (texUnit->EnvMode == GL_COMBINE) {
+ texUnit->_CurrentCombine = & texUnit->Combine;
+ }
+ else {
+ const struct gl_texture_object *texObj = texUnit->_Current;
+ GLenum format = texObj->Image[0][texObj->BaseLevel]->_BaseFormat;
+ if (format == GL_COLOR_INDEX) {
+ format = GL_RGBA; /* a bit of a hack */
+ }
+ else if (format == GL_DEPTH_COMPONENT
+ || format == GL_DEPTH_STENCIL_EXT) {
+ format = texObj->DepthMode;
+ }
+ calculate_derived_texenv(&texUnit->_EnvMode, texUnit->EnvMode, format);
+ texUnit->_CurrentCombine = & texUnit->_EnvMode;
+ }
+
+ switch (texUnit->_CurrentCombine->ModeRGB) {
+ case GL_REPLACE:
+ texUnit->_CurrentCombine->_NumArgsRGB = 1;
+ break;
+ case GL_MODULATE:
+ case GL_ADD:
+ case GL_ADD_SIGNED:
+ case GL_SUBTRACT:
+ case GL_DOT3_RGB:
+ case GL_DOT3_RGBA:
+ case GL_DOT3_RGB_EXT:
+ case GL_DOT3_RGBA_EXT:
+ texUnit->_CurrentCombine->_NumArgsRGB = 2;
+ break;
+ case GL_INTERPOLATE:
+ case GL_MODULATE_ADD_ATI:
+ case GL_MODULATE_SIGNED_ADD_ATI:
+ case GL_MODULATE_SUBTRACT_ATI:
+ texUnit->_CurrentCombine->_NumArgsRGB = 3;
+ break;
+ default:
+ texUnit->_CurrentCombine->_NumArgsRGB = 0;
+ _mesa_problem(ctx, "invalid RGB combine mode in update_texture_state");
+ return;
+ }
+
+ switch (texUnit->_CurrentCombine->ModeA) {
+ case GL_REPLACE:
+ texUnit->_CurrentCombine->_NumArgsA = 1;
+ break;
+ case GL_MODULATE:
+ case GL_ADD:
+ case GL_ADD_SIGNED:
+ case GL_SUBTRACT:
+ texUnit->_CurrentCombine->_NumArgsA = 2;
+ break;
+ case GL_INTERPOLATE:
+ case GL_MODULATE_ADD_ATI:
+ case GL_MODULATE_SIGNED_ADD_ATI:
+ case GL_MODULATE_SUBTRACT_ATI:
+ texUnit->_CurrentCombine->_NumArgsA = 3;
+ break;
+ default:
+ texUnit->_CurrentCombine->_NumArgsA = 0;
+ _mesa_problem(ctx, "invalid Alpha combine mode in update_texture_state");
+ break;
+ }
+
+ if (texUnit->TexGenEnabled) {
+ if (texUnit->TexGenEnabled & S_BIT) {
+ texUnit->_GenFlags |= texUnit->_GenBitS;
+ }
+ if (texUnit->TexGenEnabled & T_BIT) {
+ texUnit->_GenFlags |= texUnit->_GenBitT;
+ }
+ if (texUnit->TexGenEnabled & Q_BIT) {
+ texUnit->_GenFlags |= texUnit->_GenBitQ;
+ }
+ if (texUnit->TexGenEnabled & R_BIT) {
+ texUnit->_GenFlags |= texUnit->_GenBitR;
+ }
+
+ ctx->Texture._TexGenEnabled |= ENABLE_TEXGEN(unit);
+ ctx->Texture._GenFlags |= texUnit->_GenFlags;
+ }
+
+ if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY)
+ ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(unit);
+ }
+
+ ctx->Texture._EnabledCoordUnits = ctx->Texture._EnabledUnits;
+ /* Fragment programs may need texture coordinates but not the
+ * corresponding texture images.
+ */
+ if (ctx->ShaderObjects.CurrentProgram != NULL) {
+ ctx->Texture._EnabledCoordUnits |= (1 << ctx->Const.MaxTextureCoordUnits) - 1;
+ }
+ else if (ctx->FragmentProgram._Enabled) {
+ ctx->Texture._EnabledCoordUnits |=
+ (ctx->FragmentProgram.Current->Base.InputsRead >> FRAG_ATTRIB_TEX0);
+ }
+}
+
+
+void _mesa_update_texture( GLcontext *ctx, GLuint new_state )
+{
+ if (new_state & _NEW_TEXTURE_MATRIX)
+ update_texture_matrices( ctx );
+
+ if (new_state & (_NEW_TEXTURE | _NEW_PROGRAM))
+ update_texture_state( ctx );
+}
+
+
+/**********************************************************************/
+/***** Initialization *****/
+/**********************************************************************/
+
+/**
+ * Allocate the proxy textures for the given context.
+ *
+ * \param ctx the context to allocate proxies for.
+ *
+ * \return GL_TRUE on success, or GL_FALSE on failure
+ *
+ * If run out of memory part way through the allocations, clean up and return
+ * GL_FALSE.
+ */
+static GLboolean
+alloc_proxy_textures( GLcontext *ctx )
+{
+ ctx->Texture.Proxy1D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D);
+ if (!ctx->Texture.Proxy1D)
+ goto cleanup;
+
+ ctx->Texture.Proxy2D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_2D);
+ if (!ctx->Texture.Proxy2D)
+ goto cleanup;
+
+ ctx->Texture.Proxy3D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_3D);
+ if (!ctx->Texture.Proxy3D)
+ goto cleanup;
+
+ ctx->Texture.ProxyCubeMap = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_CUBE_MAP_ARB);
+ if (!ctx->Texture.ProxyCubeMap)
+ goto cleanup;
+
+ ctx->Texture.ProxyRect = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_RECTANGLE_NV);
+ if (!ctx->Texture.ProxyRect)
+ goto cleanup;
+
+ return GL_TRUE;
+
+ cleanup:
+ if (ctx->Texture.Proxy1D)
+ (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1D);
+ if (ctx->Texture.Proxy2D)
+ (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy2D);
+ if (ctx->Texture.Proxy3D)
+ (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy3D);
+ if (ctx->Texture.ProxyCubeMap)
+ (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyCubeMap);
+ if (ctx->Texture.ProxyRect)
+ (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyRect);
+ return GL_FALSE;
+}
+
+
+/**
+ * Initialize a texture unit.
+ *
+ * \param ctx GL context.
+ * \param unit texture unit number to be initialized.
+ */
+static void
+init_texture_unit( GLcontext *ctx, GLuint unit )
+{
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+
+ texUnit->EnvMode = GL_MODULATE;
+ ASSIGN_4V( texUnit->EnvColor, 0.0, 0.0, 0.0, 0.0 );
+
+ texUnit->Combine = default_combine_state;
+ texUnit->_EnvMode = default_combine_state;
+ texUnit->_CurrentCombine = & texUnit->_EnvMode;
+
+ texUnit->TexGenEnabled = 0;
+ texUnit->GenModeS = GL_EYE_LINEAR;
+ texUnit->GenModeT = GL_EYE_LINEAR;
+ texUnit->GenModeR = GL_EYE_LINEAR;
+ texUnit->GenModeQ = GL_EYE_LINEAR;
+ texUnit->_GenBitS = TEXGEN_EYE_LINEAR;
+ texUnit->_GenBitT = TEXGEN_EYE_LINEAR;
+ texUnit->_GenBitR = TEXGEN_EYE_LINEAR;
+ texUnit->_GenBitQ = TEXGEN_EYE_LINEAR;
+
+ /* Yes, these plane coefficients are correct! */
+ ASSIGN_4V( texUnit->ObjectPlaneS, 1.0, 0.0, 0.0, 0.0 );
+ ASSIGN_4V( texUnit->ObjectPlaneT, 0.0, 1.0, 0.0, 0.0 );
+ ASSIGN_4V( texUnit->ObjectPlaneR, 0.0, 0.0, 0.0, 0.0 );
+ ASSIGN_4V( texUnit->ObjectPlaneQ, 0.0, 0.0, 0.0, 0.0 );
+ ASSIGN_4V( texUnit->EyePlaneS, 1.0, 0.0, 0.0, 0.0 );
+ ASSIGN_4V( texUnit->EyePlaneT, 0.0, 1.0, 0.0, 0.0 );
+ ASSIGN_4V( texUnit->EyePlaneR, 0.0, 0.0, 0.0, 0.0 );
+ ASSIGN_4V( texUnit->EyePlaneQ, 0.0, 0.0, 0.0, 0.0 );
+
+ texUnit->Current1D = ctx->Shared->Default1D;
+ texUnit->Current2D = ctx->Shared->Default2D;
+ texUnit->Current3D = ctx->Shared->Default3D;
+ texUnit->CurrentCubeMap = ctx->Shared->DefaultCubeMap;
+ texUnit->CurrentRect = ctx->Shared->DefaultRect;
+}
+
+
+/**
+ * Initialize texture state for the given context.
+ */
+GLboolean
+_mesa_init_texture(GLcontext *ctx)
+{
+ GLuint i;
+
+ assert(MAX_TEXTURE_LEVELS >= MAX_3D_TEXTURE_LEVELS);
+ assert(MAX_TEXTURE_LEVELS >= MAX_CUBE_TEXTURE_LEVELS);
+
+ /* Effectively bind the default textures to all texture units */
+ ctx->Shared->Default1D->RefCount += MAX_TEXTURE_UNITS;
+ ctx->Shared->Default2D->RefCount += MAX_TEXTURE_UNITS;
+ ctx->Shared->Default3D->RefCount += MAX_TEXTURE_UNITS;
+ ctx->Shared->DefaultCubeMap->RefCount += MAX_TEXTURE_UNITS;
+ ctx->Shared->DefaultRect->RefCount += MAX_TEXTURE_UNITS;
+
+ /* Texture group */
+ ctx->Texture.CurrentUnit = 0; /* multitexture */
+ ctx->Texture._EnabledUnits = 0;
+ for (i=0; i<MAX_TEXTURE_UNITS; i++)
+ init_texture_unit( ctx, i );
+ ctx->Texture.SharedPalette = GL_FALSE;
+ _mesa_init_colortable(&ctx->Texture.Palette);
+
+ /* Allocate proxy textures */
+ if (!alloc_proxy_textures( ctx ))
+ return GL_FALSE;
+
+ return GL_TRUE;
+}
+
+
+/**
+ * Free dynamically-allocted texture data attached to the given context.
+ */
+void
+_mesa_free_texture_data(GLcontext *ctx)
+{
+ GLuint i;
+
+ /* Free proxy texture objects */
+ (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1D );
+ (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy2D );
+ (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy3D );
+ (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyCubeMap );
+ (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyRect );
+
+ for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++)
+ _mesa_free_colortable_data( &ctx->Texture.Unit[i].ColorTable );
+
+ _mesa_TexEnvProgramCacheDestroy( ctx );
+}
diff --git a/src/mesa/main/texstate.h b/src/mesa/main/texstate.h
new file mode 100644
index 00000000000..ca29c6a23ff
--- /dev/null
+++ b/src/mesa/main/texstate.h
@@ -0,0 +1,152 @@
+/**
+ * \file texstate.h
+ * Texture state management.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef TEXSTATE_H
+#define TEXSTATE_H
+
+
+#include "mtypes.h"
+
+
+extern void
+_mesa_copy_texture_state( const GLcontext *src, GLcontext *dst );
+
+extern void
+_mesa_print_texunit_state( GLcontext *ctx, GLuint unit );
+
+
+/**
+ * \name Called from API
+ */
+/*@{*/
+
+extern void GLAPIENTRY
+_mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params );
+
+extern void GLAPIENTRY
+_mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params );
+
+extern void GLAPIENTRY
+_mesa_GetTexGendv( GLenum coord, GLenum pname, GLdouble *params );
+
+extern void GLAPIENTRY
+_mesa_GetTexGenfv( GLenum coord, GLenum pname, GLfloat *params );
+
+extern void GLAPIENTRY
+_mesa_GetTexGeniv( GLenum coord, GLenum pname, GLint *params );
+
+extern void GLAPIENTRY
+_mesa_GetTexLevelParameterfv( GLenum target, GLint level,
+ GLenum pname, GLfloat *params );
+
+extern void GLAPIENTRY
+_mesa_GetTexLevelParameteriv( GLenum target, GLint level,
+ GLenum pname, GLint *params );
+
+extern void GLAPIENTRY
+_mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params );
+
+extern void GLAPIENTRY
+_mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params );
+
+
+extern void GLAPIENTRY
+_mesa_TexEnvf( GLenum target, GLenum pname, GLfloat param );
+
+extern void GLAPIENTRY
+_mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param );
+
+extern void GLAPIENTRY
+_mesa_TexEnvi( GLenum target, GLenum pname, GLint param );
+
+extern void GLAPIENTRY
+_mesa_TexEnviv( GLenum target, GLenum pname, const GLint *param );
+
+
+extern void GLAPIENTRY
+_mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params );
+
+extern void GLAPIENTRY
+_mesa_TexParameterf( GLenum target, GLenum pname, GLfloat param );
+
+
+extern void GLAPIENTRY
+_mesa_TexParameteri( GLenum target, GLenum pname, GLint param );
+
+extern void GLAPIENTRY
+_mesa_TexParameteriv( GLenum target, GLenum pname, const GLint *params );
+
+
+extern void GLAPIENTRY
+_mesa_TexGend( GLenum coord, GLenum pname, GLdouble param );
+
+extern void GLAPIENTRY
+_mesa_TexGendv( GLenum coord, GLenum pname, const GLdouble *params );
+
+extern void GLAPIENTRY
+_mesa_TexGenf( GLenum coord, GLenum pname, GLfloat param );
+
+extern void GLAPIENTRY
+_mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params );
+
+extern void GLAPIENTRY
+_mesa_TexGeni( GLenum coord, GLenum pname, GLint param );
+
+extern void GLAPIENTRY
+_mesa_TexGeniv( GLenum coord, GLenum pname, const GLint *params );
+
+
+/*
+ * GL_ARB_multitexture
+ */
+extern void GLAPIENTRY
+_mesa_ActiveTextureARB( GLenum target );
+
+extern void GLAPIENTRY
+_mesa_ClientActiveTextureARB( GLenum target );
+
+
+/**
+ * \name Initialization, state maintenance
+ */
+/*@{*/
+
+extern void
+_mesa_update_texture( GLcontext *ctx, GLuint new_state );
+
+extern GLboolean
+_mesa_init_texture( GLcontext *ctx );
+
+extern void
+_mesa_free_texture_data( GLcontext *ctx );
+
+/*@}*/
+
+#endif
diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c
new file mode 100644
index 00000000000..717551d716c
--- /dev/null
+++ b/src/mesa/main/texstore.c
@@ -0,0 +1,4253 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Authors:
+ * Brian Paul
+ */
+
+/*
+ * The GL texture image functions in teximage.c basically just do
+ * error checking and data structure allocation. They in turn call
+ * device driver functions which actually copy/convert/store the user's
+ * texture image data.
+ *
+ * However, most device drivers will be able to use the fallback functions
+ * in this file. That is, most drivers will have the following bit of
+ * code:
+ * ctx->Driver.TexImage1D = _mesa_store_teximage1d;
+ * ctx->Driver.TexImage2D = _mesa_store_teximage2d;
+ * ctx->Driver.TexImage3D = _mesa_store_teximage3d;
+ * etc...
+ *
+ * Texture image processing is actually kind of complicated. We have to do:
+ * Format/type conversions
+ * pixel unpacking
+ * pixel transfer (scale, bais, lookup, convolution!, etc)
+ *
+ * These functions can handle most everything, including processing full
+ * images and sub-images.
+ */
+
+
+#include "glheader.h"
+#include "bufferobj.h"
+#include "colormac.h"
+#include "context.h"
+#include "convolve.h"
+#include "image.h"
+#include "macros.h"
+#include "imports.h"
+#include "texcompress.h"
+#include "texformat.h"
+#include "teximage.h"
+#include "texstore.h"
+
+
+static const GLint ZERO = 4, ONE = 5;
+
+static GLboolean can_swizzle(GLenum logicalBaseFormat)
+{
+ switch (logicalBaseFormat) {
+ case GL_RGBA:
+ case GL_RGB:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
+}
+
+
+/**
+ * When promoting texture formats (see below) we need to compute the
+ * mapping of dest components back to source components.
+ * This function does that.
+ * \param logicalBaseFormat the logical format of the texture
+ * \param textureBaseFormat the final texture format
+ * \return map[4] the four mapping values
+ */
+static void
+compute_component_mapping(GLenum logicalBaseFormat, GLenum textureBaseFormat,
+ GLubyte map[6])
+{
+ map[ZERO] = ZERO;
+ map[ONE] = ONE;
+
+ /* compute mapping from dest components back to src components */
+ switch (textureBaseFormat) {
+ case GL_RGB:
+ case GL_RGBA:
+ switch (logicalBaseFormat) {
+ case GL_LUMINANCE:
+ map[0] = map[1] = map[2] = 0;
+ if (textureBaseFormat == GL_RGBA)
+ map[3] = ONE;
+ break;
+ case GL_ALPHA:
+ ASSERT(textureBaseFormat == GL_RGBA);
+ map[0] = map[1] = map[2] = ZERO;
+ map[3] = 0;
+ break;
+ case GL_INTENSITY:
+ map[0] = map[1] = map[2] = 0;
+ if (textureBaseFormat == GL_RGBA)
+ map[3] = 0;
+ break;
+ case GL_LUMINANCE_ALPHA:
+ ASSERT(textureBaseFormat == GL_RGBA);
+ map[0] = map[1] = map[2] = 0;
+ map[3] = 1;
+ break;
+ case GL_RGB:
+ ASSERT(textureBaseFormat == GL_RGBA);
+ map[0] = 0;
+ map[1] = 1;
+ map[2] = 2;
+ map[3] = ONE;
+ break;
+ case GL_RGBA:
+ ASSERT(textureBaseFormat == GL_RGBA);
+ map[0] = 0;
+ map[1] = 1;
+ map[2] = 2;
+ map[3] = 3;
+ break;
+ default:
+ _mesa_problem(NULL, "Unexpected logicalBaseFormat");
+ map[0] = map[1] = map[2] = map[3] = 0;
+ }
+ break;
+ case GL_LUMINANCE_ALPHA:
+ switch (logicalBaseFormat) {
+ case GL_LUMINANCE:
+ map[0] = 0;
+ map[1] = ONE;
+ break;
+ case GL_ALPHA:
+ map[0] = ZERO;
+ map[1] = 0;
+ break;
+ case GL_INTENSITY:
+ map[0] = 0;
+ map[1] = 0;
+ break;
+ default:
+ _mesa_problem(NULL, "Unexpected logicalBaseFormat");
+ map[0] = map[1] = 0;
+ }
+ break;
+ default:
+ _mesa_problem(NULL, "Unexpected logicalBaseFormat");
+ map[0] = map[1] = 0;
+ break;
+ }
+}
+
+
+/**
+ * Make a temporary (color) texture image with GLfloat components.
+ * Apply all needed pixel unpacking and pixel transfer operations.
+ * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
+ * Suppose the user specifies GL_LUMINANCE as the internal texture format
+ * but the graphics hardware doesn't support luminance textures. So, might
+ * use an RGB hardware format instead.
+ * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
+ *
+ * \param ctx the rendering context
+ * \param dims image dimensions: 1, 2 or 3
+ * \param logicalBaseFormat basic texture derived from the user's
+ * internal texture format value
+ * \param textureBaseFormat the actual basic format of the texture
+ * \param srcWidth source image width
+ * \param srcHeight source image height
+ * \param srcDepth source image depth
+ * \param srcFormat source image format
+ * \param srcType source image type
+ * \param srcAddr source image address
+ * \param srcPacking source image pixel packing
+ * \return resulting image with format = textureBaseFormat and type = GLfloat.
+ */
+static GLfloat *
+make_temp_float_image(GLcontext *ctx, GLuint dims,
+ GLenum logicalBaseFormat,
+ GLenum textureBaseFormat,
+ GLint srcWidth, GLint srcHeight, GLint srcDepth,
+ GLenum srcFormat, GLenum srcType,
+ const GLvoid *srcAddr,
+ const struct gl_pixelstore_attrib *srcPacking)
+{
+ GLuint transferOps = ctx->_ImageTransferState;
+ GLfloat *tempImage;
+
+ ASSERT(dims >= 1 && dims <= 3);
+
+ ASSERT(logicalBaseFormat == GL_RGBA ||
+ logicalBaseFormat == GL_RGB ||
+ logicalBaseFormat == GL_LUMINANCE_ALPHA ||
+ logicalBaseFormat == GL_LUMINANCE ||
+ logicalBaseFormat == GL_ALPHA ||
+ logicalBaseFormat == GL_INTENSITY ||
+ logicalBaseFormat == GL_COLOR_INDEX ||
+ logicalBaseFormat == GL_DEPTH_COMPONENT);
+
+ ASSERT(textureBaseFormat == GL_RGBA ||
+ textureBaseFormat == GL_RGB ||
+ textureBaseFormat == GL_LUMINANCE_ALPHA ||
+ textureBaseFormat == GL_LUMINANCE ||
+ textureBaseFormat == GL_ALPHA ||
+ textureBaseFormat == GL_INTENSITY ||
+ textureBaseFormat == GL_COLOR_INDEX ||
+ textureBaseFormat == GL_DEPTH_COMPONENT);
+
+ /* conventional color image */
+
+ if ((dims == 1 && ctx->Pixel.Convolution1DEnabled) ||
+ (dims >= 2 && ctx->Pixel.Convolution2DEnabled) ||
+ (dims >= 2 && ctx->Pixel.Separable2DEnabled)) {
+ /* need image convolution */
+ const GLuint preConvTransferOps
+ = (transferOps & IMAGE_PRE_CONVOLUTION_BITS) | IMAGE_CLAMP_BIT;
+ const GLuint postConvTransferOps
+ = (transferOps & IMAGE_POST_CONVOLUTION_BITS) | IMAGE_CLAMP_BIT;
+ GLint img, row;
+ GLint convWidth, convHeight;
+ GLfloat *convImage;
+
+ /* pre-convolution image buffer (3D) */
+ tempImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth
+ * 4 * sizeof(GLfloat));
+ if (!tempImage)
+ return NULL;
+
+ /* post-convolution image buffer (2D) */
+ convImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight
+ * 4 * sizeof(GLfloat));
+ if (!convImage) {
+ _mesa_free(tempImage);
+ return NULL;
+ }
+
+ /* loop over 3D image slices */
+ for (img = 0; img < srcDepth; img++) {
+ GLfloat *dst = tempImage + img * (srcWidth * srcHeight * 4);
+
+ /* unpack and do transfer ops up to convolution */
+ for (row = 0; row < srcHeight; row++) {
+ const GLvoid *src = _mesa_image_address(dims, srcPacking,
+ srcAddr, srcWidth, srcHeight,
+ srcFormat, srcType, img, row, 0);
+ _mesa_unpack_color_span_float(ctx, srcWidth, GL_RGBA, dst,
+ srcFormat, srcType, src,
+ srcPacking,
+ preConvTransferOps);
+ dst += srcWidth * 4;
+ }
+
+ /* do convolution */
+ {
+ GLfloat *src = tempImage + img * (srcWidth * srcHeight * 4);
+ convWidth = srcWidth;
+ convHeight = srcHeight;
+ if (dims == 1) {
+ ASSERT(ctx->Pixel.Convolution1DEnabled);
+ _mesa_convolve_1d_image(ctx, &convWidth, src, convImage);
+ }
+ else {
+ if (ctx->Pixel.Convolution2DEnabled) {
+ _mesa_convolve_2d_image(ctx, &convWidth, &convHeight,
+ src, convImage);
+ }
+ else {
+ ASSERT(ctx->Pixel.Separable2DEnabled);
+ _mesa_convolve_sep_image(ctx, &convWidth, &convHeight,
+ src, convImage);
+ }
+ }
+ }
+
+ /* do post-convolution transfer and pack into tempImage */
+ {
+ const GLint logComponents
+ = _mesa_components_in_format(logicalBaseFormat);
+ const GLfloat *src = convImage;
+ GLfloat *dst = tempImage + img * (convWidth * convHeight * 4);
+ for (row = 0; row < convHeight; row++) {
+ _mesa_pack_rgba_span_float(ctx, convWidth,
+ (const GLfloat (*)[4]) src,
+ logicalBaseFormat, GL_FLOAT,
+ dst, &ctx->DefaultPacking,
+ postConvTransferOps);
+ src += convWidth * 4;
+ dst += convWidth * logComponents;
+ }
+ }
+ } /* loop over 3D image slices */
+
+ _mesa_free(convImage);
+
+ /* might need these below */
+ srcWidth = convWidth;
+ srcHeight = convHeight;
+ }
+ else {
+ /* no convolution */
+ const GLint components = _mesa_components_in_format(logicalBaseFormat);
+ const GLint srcStride = _mesa_image_row_stride(srcPacking,
+ srcWidth, srcFormat, srcType);
+ GLfloat *dst;
+ GLint img, row;
+
+ tempImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth
+ * components * sizeof(GLfloat));
+ if (!tempImage)
+ return NULL;
+
+ dst = tempImage;
+ for (img = 0; img < srcDepth; img++) {
+ const GLubyte *src
+ = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
+ srcWidth, srcHeight,
+ srcFormat, srcType,
+ img, 0, 0);
+ for (row = 0; row < srcHeight; row++) {
+ _mesa_unpack_color_span_float(ctx, srcWidth, logicalBaseFormat,
+ dst, srcFormat, srcType, src,
+ srcPacking, transferOps);
+ dst += srcWidth * components;
+ src += srcStride;
+ }
+ }
+ }
+
+ if (logicalBaseFormat != textureBaseFormat) {
+ /* more work */
+ GLint texComponents = _mesa_components_in_format(textureBaseFormat);
+ GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
+ GLfloat *newImage;
+ GLint i, n;
+ GLubyte map[6];
+
+ /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
+ ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
+ textureBaseFormat == GL_LUMINANCE_ALPHA);
+
+ /* The actual texture format should have at least as many components
+ * as the logical texture format.
+ */
+ ASSERT(texComponents >= logComponents);
+
+ newImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth
+ * texComponents * sizeof(GLfloat));
+ if (!newImage) {
+ _mesa_free(tempImage);
+ return NULL;
+ }
+
+ compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
+
+ n = srcWidth * srcHeight * srcDepth;
+ for (i = 0; i < n; i++) {
+ GLint k;
+ for (k = 0; k < texComponents; k++) {
+ GLint j = map[k];
+ if (j == ZERO)
+ newImage[i * texComponents + k] = 0.0F;
+ else if (j == ONE)
+ newImage[i * texComponents + k] = 1.0F;
+ else
+ newImage[i * texComponents + k] = tempImage[i * logComponents + j];
+ }
+ }
+
+ _mesa_free(tempImage);
+ tempImage = newImage;
+ }
+
+ return tempImage;
+}
+
+
+/**
+ * Make a temporary (color) texture image with GLchan components.
+ * Apply all needed pixel unpacking and pixel transfer operations.
+ * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
+ * Suppose the user specifies GL_LUMINANCE as the internal texture format
+ * but the graphics hardware doesn't support luminance textures. So, might
+ * use an RGB hardware format instead.
+ * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
+ *
+ * \param ctx the rendering context
+ * \param dims image dimensions: 1, 2 or 3
+ * \param logicalBaseFormat basic texture derived from the user's
+ * internal texture format value
+ * \param textureBaseFormat the actual basic format of the texture
+ * \param srcWidth source image width
+ * \param srcHeight source image height
+ * \param srcDepth source image depth
+ * \param srcFormat source image format
+ * \param srcType source image type
+ * \param srcAddr source image address
+ * \param srcPacking source image pixel packing
+ * \return resulting image with format = textureBaseFormat and type = GLchan.
+ */
+GLchan *
+_mesa_make_temp_chan_image(GLcontext *ctx, GLuint dims,
+ GLenum logicalBaseFormat,
+ GLenum textureBaseFormat,
+ GLint srcWidth, GLint srcHeight, GLint srcDepth,
+ GLenum srcFormat, GLenum srcType,
+ const GLvoid *srcAddr,
+ const struct gl_pixelstore_attrib *srcPacking)
+{
+ GLuint transferOps = ctx->_ImageTransferState;
+ const GLint components = _mesa_components_in_format(logicalBaseFormat);
+ GLboolean freeSrcImage = GL_FALSE;
+ GLint img, row;
+ GLchan *tempImage, *dst;
+
+ ASSERT(dims >= 1 && dims <= 3);
+
+ ASSERT(logicalBaseFormat == GL_RGBA ||
+ logicalBaseFormat == GL_RGB ||
+ logicalBaseFormat == GL_LUMINANCE_ALPHA ||
+ logicalBaseFormat == GL_LUMINANCE ||
+ logicalBaseFormat == GL_ALPHA ||
+ logicalBaseFormat == GL_INTENSITY);
+
+ ASSERT(textureBaseFormat == GL_RGBA ||
+ textureBaseFormat == GL_RGB ||
+ textureBaseFormat == GL_LUMINANCE_ALPHA ||
+ textureBaseFormat == GL_LUMINANCE ||
+ textureBaseFormat == GL_ALPHA ||
+ textureBaseFormat == GL_INTENSITY);
+
+ if ((dims == 1 && ctx->Pixel.Convolution1DEnabled) ||
+ (dims >= 2 && ctx->Pixel.Convolution2DEnabled) ||
+ (dims >= 2 && ctx->Pixel.Separable2DEnabled)) {
+ /* get convolved image */
+ GLfloat *convImage = make_temp_float_image(ctx, dims,
+ logicalBaseFormat,
+ logicalBaseFormat,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType,
+ srcAddr, srcPacking);
+ if (!convImage)
+ return NULL;
+ /* the convolved image is our new source image */
+ srcAddr = convImage;
+ srcFormat = logicalBaseFormat;
+ srcType = GL_FLOAT;
+ srcPacking = &ctx->DefaultPacking;
+ _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
+ transferOps = 0;
+ freeSrcImage = GL_TRUE;
+ }
+
+ /* unpack and transfer the source image */
+ tempImage = (GLchan *) _mesa_malloc(srcWidth * srcHeight * srcDepth
+ * components * sizeof(GLchan));
+ if (!tempImage)
+ return NULL;
+
+ dst = tempImage;
+ for (img = 0; img < srcDepth; img++) {
+ const GLint srcStride = _mesa_image_row_stride(srcPacking,
+ srcWidth, srcFormat,
+ srcType);
+ const GLubyte *src
+ = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
+ srcWidth, srcHeight,
+ srcFormat, srcType,
+ img, 0, 0);
+ for (row = 0; row < srcHeight; row++) {
+ _mesa_unpack_color_span_chan(ctx, srcWidth, logicalBaseFormat, dst,
+ srcFormat, srcType, src, srcPacking,
+ transferOps);
+ dst += srcWidth * components;
+ src += srcStride;
+ }
+ }
+
+ /* If we made a temporary image for convolution, free it here */
+ if (freeSrcImage) {
+ _mesa_free((void *) srcAddr);
+ }
+
+ if (logicalBaseFormat != textureBaseFormat) {
+ /* one more conversion step */
+ GLint texComponents = _mesa_components_in_format(textureBaseFormat);
+ GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
+ GLchan *newImage;
+ GLint i, n;
+ GLubyte map[6];
+
+ /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
+ ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
+ textureBaseFormat == GL_LUMINANCE_ALPHA);
+
+ /* The actual texture format should have at least as many components
+ * as the logical texture format.
+ */
+ ASSERT(texComponents >= logComponents);
+
+ newImage = (GLchan *) _mesa_malloc(srcWidth * srcHeight * srcDepth
+ * texComponents * sizeof(GLchan));
+ if (!newImage) {
+ _mesa_free(tempImage);
+ return NULL;
+ }
+
+ compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
+
+ n = srcWidth * srcHeight * srcDepth;
+ for (i = 0; i < n; i++) {
+ GLint k;
+ for (k = 0; k < texComponents; k++) {
+ GLint j = map[k];
+ if (j == ZERO)
+ newImage[i * texComponents + k] = 0;
+ else if (j == ONE)
+ newImage[i * texComponents + k] = CHAN_MAX;
+ else
+ newImage[i * texComponents + k] = tempImage[i * logComponents + j];
+ }
+ }
+
+ _mesa_free(tempImage);
+ tempImage = newImage;
+ }
+
+ return tempImage;
+}
+
+
+/**
+ * Copy GLubyte pixels from <src> to <dst> with swizzling.
+ * \param dst destination pixels
+ * \param dstComponents number of color components in destination pixels
+ * \param src source pixels
+ * \param srcComponents number of color components in source pixels
+ * \param map the swizzle mapping
+ * \param count number of pixels to copy/swizzle.
+ */
+static void
+swizzle_copy(GLubyte *dst, GLuint dstComponents, const GLubyte *src,
+ GLuint srcComponents, const GLubyte *map, GLuint count)
+{
+ GLubyte tmp[8];
+ GLint i;
+
+ tmp[ZERO] = 0x0;
+ tmp[ONE] = 0xff;
+
+ switch (dstComponents) {
+ case 4:
+ for (i = 0; i < count; i++) {
+ COPY_4UBV(tmp, src);
+ src += srcComponents;
+ dst[0] = tmp[map[0]];
+ dst[1] = tmp[map[1]];
+ dst[2] = tmp[map[2]];
+ dst[3] = tmp[map[3]];
+ dst += 4;
+ }
+ break;
+ case 3:
+ for (i = 0; i < count; i++) {
+ COPY_4UBV(tmp, src);
+ src += srcComponents;
+ dst[0] = tmp[map[0]];
+ dst[1] = tmp[map[1]];
+ dst[2] = tmp[map[2]];
+ dst += 3;
+ }
+ break;
+ case 2:
+ for (i = 0; i < count; i++) {
+ COPY_4UBV(tmp, src);
+ src += srcComponents;
+ dst[0] = tmp[map[0]];
+ dst[1] = tmp[map[1]];
+ dst += 2;
+ }
+ break;
+ }
+}
+
+
+/**
+ * Transfer a GLubyte texture image with component swizzling.
+ */
+static void
+_mesa_swizzle_ubyte_image(GLcontext *ctx,
+ GLuint dimensions,
+ GLenum srcFormat,
+ const GLubyte *dstmap, GLint dstComponents,
+
+ GLvoid *dstAddr,
+ GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
+ GLint dstRowStride, GLint dstImageStride,
+
+ GLint srcWidth, GLint srcHeight, GLint srcDepth,
+ const GLvoid *srcAddr,
+ const struct gl_pixelstore_attrib *srcPacking )
+{
+ GLint srcComponents = _mesa_components_in_format(srcFormat);
+ GLubyte srcmap[6], map[4];
+ GLint i;
+
+ const GLint srcRowStride =
+ _mesa_image_row_stride(srcPacking, srcWidth,
+ srcFormat, GL_UNSIGNED_BYTE);
+ const GLint srcImageStride
+ = _mesa_image_image_stride(srcPacking, srcWidth, srcHeight, srcFormat,
+ GL_UNSIGNED_BYTE);
+ const GLubyte *srcImage
+ = (const GLubyte *) _mesa_image_address(dimensions, srcPacking, srcAddr,
+ srcWidth, srcHeight, srcFormat,
+ GL_UNSIGNED_BYTE, 0, 0, 0);
+
+ GLubyte *dstImage = (GLubyte *) dstAddr
+ + dstZoffset * dstImageStride
+ + dstYoffset * dstRowStride
+ + dstXoffset * dstComponents;
+
+ compute_component_mapping(srcFormat, GL_RGBA, srcmap);
+
+ for (i = 0; i < 4; i++)
+ map[i] = srcmap[dstmap[i]];
+
+ if (srcRowStride == srcWidth * srcComponents &&
+ (srcImageStride == srcWidth * srcHeight * srcComponents ||
+ srcDepth == 1)) {
+ swizzle_copy(dstImage, dstComponents, srcImage, srcComponents, map,
+ srcWidth * srcHeight * srcDepth);
+ }
+ else {
+ GLint img, row;
+ for (img = 0; img < srcDepth; img++) {
+ const GLubyte *srcRow = srcImage;
+ GLubyte *dstRow = dstImage;
+ for (row = 0; row < srcHeight; row++) {
+ swizzle_copy(dstRow, dstComponents, srcRow, srcComponents, map, srcWidth);
+ dstRow += dstRowStride;
+ srcRow += srcRowStride;
+ }
+ srcImage += srcImageStride;
+ dstImage += dstImageStride;
+ }
+ }
+}
+
+
+/**
+ * Teximage storage routine for when a simple memcpy will do.
+ * No pixel transfer operations or special texel encodings allowed.
+ * 1D, 2D and 3D images supported.
+ */
+static void
+memcpy_texture(GLcontext *ctx,
+ GLuint dimensions,
+ const struct gl_texture_format *dstFormat,
+ GLvoid *dstAddr,
+ GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
+ GLint dstRowStride, GLint dstImageStride,
+ GLint srcWidth, GLint srcHeight, GLint srcDepth,
+ GLenum srcFormat, GLenum srcType,
+ const GLvoid *srcAddr,
+ const struct gl_pixelstore_attrib *srcPacking)
+{
+ const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
+ srcFormat, srcType);
+ const GLint srcImageStride = _mesa_image_image_stride(srcPacking,
+ srcWidth, srcHeight, srcFormat, srcType);
+ const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(dimensions,
+ srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
+ const GLint bytesPerRow = srcWidth * dstFormat->TexelBytes;
+ const GLint bytesPerImage = srcHeight * bytesPerRow;
+ const GLint bytesPerTexture = srcDepth * bytesPerImage;
+ GLubyte *dstImage = (GLubyte *) dstAddr
+ + dstZoffset * dstImageStride
+ + dstYoffset * dstRowStride
+ + dstXoffset * dstFormat->TexelBytes;
+
+ if (dstRowStride == srcRowStride &&
+ dstRowStride == bytesPerRow &&
+ ((dstImageStride == srcImageStride &&
+ dstImageStride == bytesPerImage) ||
+ (srcDepth == 1))) {
+ /* one big memcpy */
+ ctx->Driver.TextureMemCpy(dstImage, srcImage, bytesPerTexture);
+ }
+ else {
+ GLint img, row;
+ for (img = 0; img < srcDepth; img++) {
+ const GLubyte *srcRow = srcImage;
+ GLubyte *dstRow = dstImage;
+ for (row = 0; row < srcHeight; row++) {
+ ctx->Driver.TextureMemCpy(dstRow, srcRow, bytesPerRow);
+ dstRow += dstRowStride;
+ srcRow += srcRowStride;
+ }
+ srcImage += srcImageStride;
+ dstImage += dstImageStride;
+ }
+ }
+}
+
+
+
+/**
+ * Store an image in any of the formats:
+ * _mesa_texformat_rgba
+ * _mesa_texformat_rgb
+ * _mesa_texformat_alpha
+ * _mesa_texformat_luminance
+ * _mesa_texformat_luminance_alpha
+ * _mesa_texformat_intensity
+ *
+ * \param dims either 1 or 2 or 3
+ * \param baseInternalFormat user-specified base internal format
+ * \param dstFormat destination Mesa texture format
+ * \param dstAddr destination image address
+ * \param dstX/Y/Zoffset destination x/y/z offset (ala TexSubImage), in texels
+ * \param dstRowStride destination image row stride, in bytes
+ * \param dstImageStride destination image layer stride, in bytes
+ * \param srcWidth/Height/Depth source image size, in pixels
+ * \param srcFormat incoming image format
+ * \param srcType incoming image data type
+ * \param srcAddr source image address
+ * \param srcPacking source image packing parameters
+ */
+GLboolean
+_mesa_texstore_rgba(GLcontext *ctx, GLuint dims,
+ GLenum baseInternalFormat,
+ const struct gl_texture_format *dstFormat,
+ GLvoid *dstAddr,
+ GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
+ GLint dstRowStride, GLint dstImageStride,
+ GLint srcWidth, GLint srcHeight, GLint srcDepth,
+ GLenum srcFormat, GLenum srcType,
+ const GLvoid *srcAddr,
+ const struct gl_pixelstore_attrib *srcPacking)
+{
+ const GLint components = _mesa_components_in_format(baseInternalFormat);
+
+ ASSERT(dstFormat == &_mesa_texformat_rgba ||
+ dstFormat == &_mesa_texformat_rgb ||
+ dstFormat == &_mesa_texformat_alpha ||
+ dstFormat == &_mesa_texformat_luminance ||
+ dstFormat == &_mesa_texformat_luminance_alpha ||
+ dstFormat == &_mesa_texformat_intensity);
+ ASSERT(baseInternalFormat == GL_RGBA ||
+ baseInternalFormat == GL_RGB ||
+ baseInternalFormat == GL_ALPHA ||
+ baseInternalFormat == GL_LUMINANCE ||
+ baseInternalFormat == GL_LUMINANCE_ALPHA ||
+ baseInternalFormat == GL_INTENSITY);
+ ASSERT(dstFormat->TexelBytes == components * sizeof(GLchan));
+
+ if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes &&
+ baseInternalFormat == srcFormat &&
+ srcType == CHAN_TYPE) {
+ /* simple memcpy path */
+ memcpy_texture(ctx, dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ dstRowStride, dstImageStride,
+ srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+ srcAddr, srcPacking);
+ }
+ else if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes &&
+ dstFormat == &_mesa_texformat_rgb &&
+ srcFormat == GL_RGBA &&
+ srcType == CHAN_TYPE) {
+ /* extract RGB from RGBA */
+ int img, row, col;
+ GLchan *dstImage = (GLchan *) (GLubyte *) dstAddr
+ + dstZoffset * dstImageStride
+ + dstYoffset * dstRowStride
+ + dstXoffset * dstFormat->TexelBytes;
+ for (img = 0; img < srcDepth; img++) {
+ const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
+ srcWidth, srcFormat, srcType);
+ GLchan *srcRow = (GLchan *) _mesa_image_address(dims, srcPacking,
+ srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
+ GLchan *dstRow = dstImage;
+ for (row = 0; row < srcHeight; row++) {
+ for (col = 0; col < srcWidth; col++) {
+ dstRow[col * 3 + RCOMP] = srcRow[col * 4 + RCOMP];
+ dstRow[col * 3 + GCOMP] = srcRow[col * 4 + GCOMP];
+ dstRow[col * 3 + BCOMP] = srcRow[col * 4 + BCOMP];
+ }
+ dstRow += dstRowStride;
+ srcRow = (GLchan *) ((GLubyte *) srcRow + srcRowStride);
+ }
+ dstImage += dstImageStride;
+ }
+ }
+ else {
+ /* general path */
+ const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
+ baseInternalFormat,
+ dstFormat->BaseFormat,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr,
+ srcPacking);
+ const GLchan *src = tempImage;
+ GLint bytesPerRow;
+ GLubyte *dstImage = (GLubyte *) dstAddr
+ + dstZoffset * dstImageStride
+ + dstYoffset * dstRowStride
+ + dstXoffset * dstFormat->TexelBytes;
+ GLint img, row;
+ if (!tempImage)
+ return GL_FALSE;
+ _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
+ bytesPerRow = srcWidth * components * sizeof(GLchan);
+ for (img = 0; img < srcDepth; img++) {
+ GLubyte *dstRow = dstImage;
+ for (row = 0; row < srcHeight; row++) {
+ _mesa_memcpy(dstRow, src, bytesPerRow);
+ dstRow += dstRowStride;
+ src += srcWidth * components;
+ }
+ dstImage += dstImageStride;
+ }
+
+ _mesa_free((void *) tempImage);
+ }
+ return GL_TRUE;
+}
+
+
+/**
+ * Store a floating point depth component texture image.
+ */
+GLboolean
+_mesa_texstore_depth_component_float32(STORE_PARAMS)
+{
+ (void) dims;
+ ASSERT(dstFormat == &_mesa_texformat_depth_component_float32);
+ ASSERT(dstFormat->TexelBytes == sizeof(GLfloat));
+
+ if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes &&
+ baseInternalFormat == GL_DEPTH_COMPONENT &&
+ srcFormat == GL_DEPTH_COMPONENT &&
+ srcType == GL_FLOAT) {
+ /* simple memcpy path */
+ memcpy_texture(ctx, dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ dstRowStride, dstImageStride,
+ srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+ srcAddr, srcPacking);
+ }
+ else {
+ /* general path */
+ GLubyte *dstImage = (GLubyte *) dstAddr
+ + dstZoffset * dstImageStride
+ + dstYoffset * dstRowStride
+ + dstXoffset * dstFormat->TexelBytes;
+ GLint img, row;
+ for (img = 0; img < srcDepth; img++) {
+ GLubyte *dstRow = dstImage;
+ for (row = 0; row < srcHeight; row++) {
+ const GLvoid *src = _mesa_image_address(dims, srcPacking,
+ srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
+ _mesa_unpack_depth_span(ctx, srcWidth,
+ GL_FLOAT, (GLfloat *) dstRow, 1.0F,
+ srcType, src, srcPacking);
+ dstRow += dstRowStride;
+ }
+ dstImage += dstImageStride;
+ }
+ }
+ return GL_TRUE;
+}
+
+
+/**
+ * Store a 16-bit integer depth component texture image.
+ */
+GLboolean
+_mesa_texstore_depth_component16(STORE_PARAMS)
+{
+ (void) dims;
+ ASSERT(dstFormat == &_mesa_texformat_depth_component16);
+ ASSERT(dstFormat->TexelBytes == sizeof(GLushort));
+
+ if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes &&
+ baseInternalFormat == GL_DEPTH_COMPONENT &&
+ srcFormat == GL_DEPTH_COMPONENT &&
+ srcType == GL_UNSIGNED_SHORT) {
+ /* simple memcpy path */
+ memcpy_texture(ctx, dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ dstRowStride, dstImageStride,
+ srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+ srcAddr, srcPacking);
+ }
+ else {
+ /* general path */
+ GLubyte *dstImage = (GLubyte *) dstAddr
+ + dstZoffset * dstImageStride
+ + dstYoffset * dstRowStride
+ + dstXoffset * dstFormat->TexelBytes;
+ GLint img, row;
+ for (img = 0; img < srcDepth; img++) {
+ GLubyte *dstRow = dstImage;
+ for (row = 0; row < srcHeight; row++) {
+ const GLvoid *src = _mesa_image_address(dims, srcPacking,
+ srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
+ GLushort *dst16 = (GLushort *) dstRow;
+ _mesa_unpack_depth_span(ctx, srcWidth,
+ GL_UNSIGNED_SHORT, dst16, 65535.0F,
+ srcType, src, srcPacking);
+ dstRow += dstRowStride;
+ }
+ dstImage += dstImageStride;
+ }
+ }
+ return GL_TRUE;
+}
+
+
+/**
+ * Store an rgb565 or rgb565_rev texture image.
+ */
+GLboolean
+_mesa_texstore_rgb565(STORE_PARAMS)
+{
+ ASSERT(dstFormat == &_mesa_texformat_rgb565 ||
+ dstFormat == &_mesa_texformat_rgb565_rev);
+ ASSERT(dstFormat->TexelBytes == 2);
+
+ if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes &&
+ dstFormat == &_mesa_texformat_rgb565 &&
+ baseInternalFormat == GL_RGB &&
+ srcFormat == GL_RGB &&
+ srcType == GL_UNSIGNED_SHORT_5_6_5) {
+ /* simple memcpy path */
+ memcpy_texture(ctx, dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ dstRowStride, dstImageStride,
+ srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+ srcAddr, srcPacking);
+ }
+ else if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes &&
+ baseInternalFormat == GL_RGB &&
+ srcFormat == GL_RGB &&
+ srcType == GL_UNSIGNED_BYTE &&
+ dims == 2) {
+ /* do optimized tex store */
+ const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
+ srcFormat, srcType);
+ const GLubyte *src = (const GLubyte *)
+ _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight,
+ srcFormat, srcType, 0, 0, 0);
+ GLubyte *dst = (GLubyte *) dstAddr
+ + dstZoffset * dstImageStride
+ + dstYoffset * dstRowStride
+ + dstXoffset * dstFormat->TexelBytes;
+ GLint row, col;
+ for (row = 0; row < srcHeight; row++) {
+ const GLubyte *srcUB = (const GLubyte *) src;
+ GLushort *dstUS = (GLushort *) dst;
+ /* check for byteswapped format */
+ if (dstFormat == &_mesa_texformat_rgb565) {
+ for (col = 0; col < srcWidth; col++) {
+ dstUS[col] = PACK_COLOR_565( srcUB[0], srcUB[1], srcUB[2] );
+ srcUB += 3;
+ }
+ }
+ else {
+ for (col = 0; col < srcWidth; col++) {
+ dstUS[col] = PACK_COLOR_565_REV( srcUB[0], srcUB[1], srcUB[2] );
+ srcUB += 3;
+ }
+ }
+ dst += dstRowStride;
+ src += srcRowStride;
+ }
+ }
+ else {
+ /* general path */
+ const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
+ baseInternalFormat,
+ dstFormat->BaseFormat,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr,
+ srcPacking);
+ const GLchan *src = tempImage;
+ GLubyte *dstImage = (GLubyte *) dstAddr
+ + dstZoffset * dstImageStride
+ + dstYoffset * dstRowStride
+ + dstXoffset * dstFormat->TexelBytes;
+ GLint img, row, col;
+ if (!tempImage)
+ return GL_FALSE;
+ _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
+ for (img = 0; img < srcDepth; img++) {
+ GLubyte *dstRow = dstImage;
+ for (row = 0; row < srcHeight; row++) {
+ GLushort *dstUS = (GLushort *) dstRow;
+ /* check for byteswapped format */
+ if (dstFormat == &_mesa_texformat_rgb565) {
+ for (col = 0; col < srcWidth; col++) {
+ dstUS[col] = PACK_COLOR_565( CHAN_TO_UBYTE(src[RCOMP]),
+ CHAN_TO_UBYTE(src[GCOMP]),
+ CHAN_TO_UBYTE(src[BCOMP]) );
+ src += 3;
+ }
+ }
+ else {
+ for (col = 0; col < srcWidth; col++) {
+ dstUS[col] = PACK_COLOR_565_REV( CHAN_TO_UBYTE(src[RCOMP]),
+ CHAN_TO_UBYTE(src[GCOMP]),
+ CHAN_TO_UBYTE(src[BCOMP]) );
+ src += 3;
+ }
+ }
+ dstRow += dstRowStride;
+ }
+ dstImage += dstImageStride;
+ }
+ _mesa_free((void *) tempImage);
+ }
+ return GL_TRUE;
+}
+
+
+GLboolean
+_mesa_texstore_rgba8888(STORE_PARAMS)
+{
+ const GLuint ui = 1;
+ const GLubyte littleEndian = *((const GLubyte *) &ui);
+
+ (void)littleEndian;
+ ASSERT(dstFormat == &_mesa_texformat_rgba8888 ||
+ dstFormat == &_mesa_texformat_rgba8888_rev);
+ ASSERT(dstFormat->TexelBytes == 4);
+
+ if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes &&
+ dstFormat == &_mesa_texformat_rgba8888 &&
+ baseInternalFormat == GL_RGBA &&
+ ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
+ (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV))) {
+ /* simple memcpy path */
+ memcpy_texture(ctx, dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ dstRowStride, dstImageStride,
+ srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+ srcAddr, srcPacking);
+ }
+#if 0
+ else if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes &&
+ srcType == GL_UNSIGNED_BYTE &&
+ dstFormat == &_mesa_texformat_rgba8888 &&
+ littleEndian &&
+ /* Three texture formats involved: srcFormat,
+ * baseInternalFormat and destFormat (GL_RGBA). Only two
+ * may differ. _mesa_swizzle_ubyte_image can't handle two
+ * propagations at once correctly. */
+ (srcFormat == baseInternalFormat ||
+ baseInternalFormat == GL_RGBA) &&
+ can_swizzle(srcFormat)) {
+ GLubyte dstmap[4];
+
+ /* dstmap - how to swizzle from GL_RGBA to dst format:
+ *
+ * FIXME - add !litteEndian and _rev varients:
+ */
+ dstmap[3] = 0;
+ dstmap[2] = 1;
+ dstmap[1] = 2;
+ dstmap[0] = 3;
+
+ _mesa_swizzle_ubyte_image(ctx, dims,
+ srcFormat,
+ dstmap, 4,
+ dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ dstRowStride, dstImageStride,
+ srcWidth, srcHeight, srcDepth, srcAddr,
+ srcPacking);
+ }
+#endif
+ else {
+ /* general path */
+ const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
+ baseInternalFormat,
+ dstFormat->BaseFormat,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr,
+ srcPacking);
+ const GLchan *src = tempImage;
+ GLubyte *dstImage = (GLubyte *) dstAddr
+ + dstZoffset * dstImageStride
+ + dstYoffset * dstRowStride
+ + dstXoffset * dstFormat->TexelBytes;
+ GLint img, row, col;
+ if (!tempImage)
+ return GL_FALSE;
+ _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
+ for (img = 0; img < srcDepth; img++) {
+ GLubyte *dstRow = dstImage;
+ for (row = 0; row < srcHeight; row++) {
+ GLuint *dstUI = (GLuint *) dstRow;
+ if (dstFormat == &_mesa_texformat_rgba8888) {
+ for (col = 0; col < srcWidth; col++) {
+ dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[RCOMP]),
+ CHAN_TO_UBYTE(src[GCOMP]),
+ CHAN_TO_UBYTE(src[BCOMP]),
+ CHAN_TO_UBYTE(src[ACOMP]) );
+ src += 4;
+ }
+ }
+ else {
+ for (col = 0; col < srcWidth; col++) {
+ dstUI[col] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src[RCOMP]),
+ CHAN_TO_UBYTE(src[GCOMP]),
+ CHAN_TO_UBYTE(src[BCOMP]),
+ CHAN_TO_UBYTE(src[ACOMP]) );
+ src += 4;
+ }
+ }
+ dstRow += dstRowStride;
+ }
+ dstImage += dstImageStride;
+ }
+ _mesa_free((void *) tempImage);
+ }
+ return GL_TRUE;
+}
+
+
+GLboolean
+_mesa_texstore_argb8888(STORE_PARAMS)
+{
+ const GLuint ui = 1;
+ const GLubyte littleEndian = *((const GLubyte *) &ui);
+
+ ASSERT(dstFormat == &_mesa_texformat_argb8888 ||
+ dstFormat == &_mesa_texformat_argb8888_rev);
+ ASSERT(dstFormat->TexelBytes == 4);
+
+ if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes &&
+ dstFormat == &_mesa_texformat_argb8888 &&
+ baseInternalFormat == GL_RGBA &&
+ srcFormat == GL_BGRA &&
+ ((srcType == GL_UNSIGNED_BYTE && littleEndian) ||
+ srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) {
+ /* simple memcpy path (little endian) */
+ memcpy_texture(ctx, dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ dstRowStride, dstImageStride,
+ srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+ srcAddr, srcPacking);
+ }
+ else if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes &&
+ dstFormat == &_mesa_texformat_argb8888_rev &&
+ baseInternalFormat == GL_RGBA &&
+ srcFormat == GL_BGRA &&
+ ((srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
+ srcType == GL_UNSIGNED_INT_8_8_8_8)) {
+ /* simple memcpy path (big endian) */
+ memcpy_texture(ctx, dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ dstRowStride, dstImageStride,
+ srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+ srcAddr, srcPacking);
+ }
+ else if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes &&
+ dstFormat == &_mesa_texformat_argb8888 &&
+ srcFormat == GL_RGB &&
+ srcType == GL_UNSIGNED_BYTE) {
+
+ int img, row, col;
+ GLubyte *dstImage = (GLubyte *) dstAddr
+ + dstZoffset * dstImageStride
+ + dstYoffset * dstRowStride
+ + dstXoffset * dstFormat->TexelBytes;
+ for (img = 0; img < srcDepth; img++) {
+ const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
+ srcWidth, srcFormat, srcType);
+ GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
+ srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
+ GLubyte *dstRow = dstImage;
+ for (row = 0; row < srcHeight; row++) {
+ for (col = 0; col < srcWidth; col++) {
+ dstRow[col * 4 + 0] = srcRow[col * 3 + BCOMP];
+ dstRow[col * 4 + 1] = srcRow[col * 3 + GCOMP];
+ dstRow[col * 4 + 2] = srcRow[col * 3 + RCOMP];
+ dstRow[col * 4 + 3] = 0xff;
+ }
+ dstRow += dstRowStride;
+ srcRow += srcRowStride;
+ }
+ dstImage += dstImageStride;
+ }
+ }
+ else if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes &&
+ dstFormat == &_mesa_texformat_argb8888 &&
+ srcFormat == GL_RGBA &&
+ (srcType == GL_UNSIGNED_BYTE && littleEndian)) {
+
+ int img, row, col;
+ GLubyte *dstImage = (GLubyte *) dstAddr
+ + dstZoffset * dstImageStride
+ + dstYoffset * dstRowStride
+ + dstXoffset * dstFormat->TexelBytes;
+
+ /* For some reason, streaming copies to write-combined regions
+ * are extremely sensitive to the characteristics of how the
+ * source data is retrieved. By reordering the source reads to
+ * be in-order, the speed of this operation increases by half.
+ * Strangely the same isn't required for the RGB path, above.
+ */
+ for (img = 0; img < srcDepth; img++) {
+ const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
+ srcWidth, srcFormat, srcType);
+ GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
+ srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
+ GLubyte *dstRow = dstImage;
+ for (row = 0; row < srcHeight; row++) {
+ for (col = 0; col < srcWidth; col++) {
+ *(GLuint *)(dstRow + col * 4) = (srcRow[col * 4 + RCOMP] << 16 |
+ srcRow[col * 4 + GCOMP] << 8 |
+ srcRow[col * 4 + BCOMP] << 0 |
+ srcRow[col * 4 + ACOMP] << 24);
+ }
+ dstRow += dstRowStride;
+ srcRow += srcRowStride;
+ }
+ dstImage += dstImageStride;
+ }
+ }
+ else if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes &&
+ dstFormat == &_mesa_texformat_argb8888 &&
+ srcFormat == GL_RGBA &&
+ srcType == GL_UNSIGNED_BYTE) {
+
+ int img, row, col;
+ GLubyte *dstImage = (GLubyte *) dstAddr
+ + dstZoffset * dstImageStride
+ + dstYoffset * dstRowStride
+ + dstXoffset * dstFormat->TexelBytes;
+ for (img = 0; img < srcDepth; img++) {
+ const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
+ srcWidth, srcFormat, srcType);
+ GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
+ srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
+ GLubyte *dstRow = dstImage;
+ for (row = 0; row < srcHeight; row++) {
+ for (col = 0; col < srcWidth; col++) {
+ dstRow[col * 4 + 0] = srcRow[col * 4 + BCOMP];
+ dstRow[col * 4 + 1] = srcRow[col * 4 + GCOMP];
+ dstRow[col * 4 + 2] = srcRow[col * 4 + RCOMP];
+ dstRow[col * 4 + 3] = srcRow[col * 4 + ACOMP];
+ }
+ dstRow += dstRowStride;
+ srcRow += srcRowStride;
+ }
+ dstImage += dstImageStride;
+ }
+ }
+ else if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes &&
+ dstFormat == &_mesa_texformat_argb8888 &&
+ srcType == GL_UNSIGNED_BYTE &&
+ littleEndian &&
+ /* Three texture formats involved: srcFormat,
+ * baseInternalFormat and destFormat (GL_RGBA). Only two
+ * may differ. _mesa_swizzle_ubyte_image can't handle two
+ * propagations at once correctly. */
+ (srcFormat == baseInternalFormat ||
+ baseInternalFormat == GL_RGBA) &&
+ can_swizzle(srcFormat)) {
+
+ GLubyte dstmap[4];
+
+ /* dstmap - how to swizzle from GL_RGBA to dst format:
+ */
+ dstmap[3] = 3; /* alpha */
+ dstmap[2] = 0; /* red */
+ dstmap[1] = 1; /* green */
+ dstmap[0] = 2; /* blue */
+
+ _mesa_swizzle_ubyte_image(ctx, dims,
+ srcFormat,
+ dstmap, 4,
+ dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ dstRowStride, dstImageStride,
+ srcWidth, srcHeight, srcDepth, srcAddr,
+ srcPacking);
+ }
+ else {
+ /* general path */
+ const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
+ baseInternalFormat,
+ dstFormat->BaseFormat,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr,
+ srcPacking);
+ const GLchan *src = tempImage;
+ GLubyte *dstImage = (GLubyte *) dstAddr
+ + dstZoffset * dstImageStride
+ + dstYoffset * dstRowStride
+ + dstXoffset * dstFormat->TexelBytes;
+ GLint img, row, col;
+ if (!tempImage)
+ return GL_FALSE;
+ _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
+ for (img = 0; img < srcDepth; img++) {
+ GLubyte *dstRow = dstImage;
+ for (row = 0; row < srcHeight; row++) {
+ GLuint *dstUI = (GLuint *) dstRow;
+ if (dstFormat == &_mesa_texformat_argb8888) {
+ for (col = 0; col < srcWidth; col++) {
+ dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[ACOMP]),
+ CHAN_TO_UBYTE(src[RCOMP]),
+ CHAN_TO_UBYTE(src[GCOMP]),
+ CHAN_TO_UBYTE(src[BCOMP]) );
+ src += 4;
+ }
+ }
+ else {
+ for (col = 0; col < srcWidth; col++) {
+ dstUI[col] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src[ACOMP]),
+ CHAN_TO_UBYTE(src[RCOMP]),
+ CHAN_TO_UBYTE(src[GCOMP]),
+ CHAN_TO_UBYTE(src[BCOMP]) );
+ src += 4;
+ }
+ }
+ dstRow += dstRowStride;
+ }
+ dstImage += dstImageStride;
+ }
+ _mesa_free((void *) tempImage);
+ }
+ return GL_TRUE;
+}
+
+
+GLboolean
+_mesa_texstore_rgb888(STORE_PARAMS)
+{
+ const GLuint ui = 1;
+ const GLubyte littleEndian = *((const GLubyte *) &ui);
+
+ ASSERT(dstFormat == &_mesa_texformat_rgb888);
+ ASSERT(dstFormat->TexelBytes == 3);
+
+ if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes &&
+ baseInternalFormat == GL_RGB &&
+ srcFormat == GL_BGR &&
+ srcType == GL_UNSIGNED_BYTE &&
+ littleEndian) {
+ /* simple memcpy path */
+ memcpy_texture(ctx, dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ dstRowStride, dstImageStride,
+ srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+ srcAddr, srcPacking);
+ }
+ else if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes &&
+ srcFormat == GL_RGBA &&
+ srcType == GL_UNSIGNED_BYTE) {
+ /* extract RGB from RGBA */
+ int img, row, col;
+ GLubyte *dstImage = (GLubyte *) dstAddr
+ + dstZoffset * dstImageStride
+ + dstYoffset * dstRowStride
+ + dstXoffset * dstFormat->TexelBytes;
+ for (img = 0; img < srcDepth; img++) {
+ const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
+ srcWidth, srcFormat, srcType);
+ GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
+ srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
+ GLubyte *dstRow = dstImage;
+ for (row = 0; row < srcHeight; row++) {
+ for (col = 0; col < srcWidth; col++) {
+ dstRow[col * 3 + 0] = srcRow[col * 4 + BCOMP];
+ dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP];
+ dstRow[col * 3 + 2] = srcRow[col * 4 + RCOMP];
+ }
+ dstRow += dstRowStride;
+ srcRow += srcRowStride;
+ }
+ dstImage += dstImageStride;
+ }
+ }
+ else {
+ /* general path */
+ const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
+ baseInternalFormat,
+ dstFormat->BaseFormat,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr,
+ srcPacking);
+ const GLchan *src = (const GLchan *) tempImage;
+ GLubyte *dstImage = (GLubyte *) dstAddr
+ + dstZoffset * dstImageStride
+ + dstYoffset * dstRowStride
+ + dstXoffset * dstFormat->TexelBytes;
+ GLint img, row, col;
+ if (!tempImage)
+ return GL_FALSE;
+ _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
+ for (img = 0; img < srcDepth; img++) {
+ GLubyte *dstRow = dstImage;
+ for (row = 0; row < srcHeight; row++) {
+#if 0
+ if (littleEndian) {
+ for (col = 0; col < srcWidth; col++) {
+ dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[RCOMP]);
+ dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
+ dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[BCOMP]);
+ srcUB += 3;
+ }
+ }
+ else {
+ for (col = 0; col < srcWidth; col++) {
+ dstRow[col * 3 + 0] = srcUB[BCOMP];
+ dstRow[col * 3 + 1] = srcUB[GCOMP];
+ dstRow[col * 3 + 2] = srcUB[RCOMP];
+ srcUB += 3;
+ }
+ }
+#else
+ for (col = 0; col < srcWidth; col++) {
+ dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[BCOMP]);
+ dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
+ dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[RCOMP]);
+ src += 3;
+ }
+#endif
+ dstRow += dstRowStride;
+ }
+ dstImage += dstImageStride;
+ }
+ _mesa_free((void *) tempImage);
+ }
+ return GL_TRUE;
+}
+
+
+GLboolean
+_mesa_texstore_bgr888(STORE_PARAMS)
+{
+ const GLuint ui = 1;
+ const GLubyte littleEndian = *((const GLubyte *) &ui);
+
+ ASSERT(dstFormat == &_mesa_texformat_bgr888);
+ ASSERT(dstFormat->TexelBytes == 3);
+
+ if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes &&
+ baseInternalFormat == GL_RGB &&
+ srcFormat == GL_RGB &&
+ srcType == GL_UNSIGNED_BYTE &&
+ littleEndian) {
+ /* simple memcpy path */
+ memcpy_texture(ctx, dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ dstRowStride, dstImageStride,
+ srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+ srcAddr, srcPacking);
+ }
+ else if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes &&
+ srcFormat == GL_RGBA &&
+ srcType == GL_UNSIGNED_BYTE) {
+ /* extract BGR from RGBA */
+ int img, row, col;
+ GLubyte *dstImage = (GLubyte *) dstAddr
+ + dstZoffset * dstImageStride
+ + dstYoffset * dstRowStride
+ + dstXoffset * dstFormat->TexelBytes;
+ for (img = 0; img < srcDepth; img++) {
+ const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
+ srcWidth, srcFormat, srcType);
+ GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
+ srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
+ GLubyte *dstRow = dstImage;
+ for (row = 0; row < srcHeight; row++) {
+ for (col = 0; col < srcWidth; col++) {
+ dstRow[col * 3 + 0] = srcRow[col * 4 + RCOMP];
+ dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP];
+ dstRow[col * 3 + 2] = srcRow[col * 4 + BCOMP];
+ }
+ dstRow += dstRowStride;
+ srcRow += srcRowStride;
+ }
+ dstImage += dstImageStride;
+ }
+ }
+ else {
+ /* general path */
+ const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
+ baseInternalFormat,
+ dstFormat->BaseFormat,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr,
+ srcPacking);
+ const GLchan *src = (const GLchan *) tempImage;
+ GLubyte *dstImage = (GLubyte *) dstAddr
+ + dstZoffset * dstImageStride
+ + dstYoffset * dstRowStride
+ + dstXoffset * dstFormat->TexelBytes;
+ GLint img, row, col;
+ if (!tempImage)
+ return GL_FALSE;
+ _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
+ for (img = 0; img < srcDepth; img++) {
+ GLubyte *dstRow = dstImage;
+ for (row = 0; row < srcHeight; row++) {
+ for (col = 0; col < srcWidth; col++) {
+ dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[RCOMP]);
+ dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
+ dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[BCOMP]);
+ src += 3;
+ }
+ dstRow += dstRowStride;
+ }
+ dstImage += dstImageStride;
+ }
+ _mesa_free((void *) tempImage);
+ }
+ return GL_TRUE;
+}
+
+
+GLboolean
+_mesa_texstore_argb4444(STORE_PARAMS)
+{
+ ASSERT(dstFormat == &_mesa_texformat_argb4444 ||
+ dstFormat == &_mesa_texformat_argb4444_rev);
+ ASSERT(dstFormat->TexelBytes == 2);
+
+ if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes &&
+ dstFormat == &_mesa_texformat_argb4444 &&
+ baseInternalFormat == GL_RGBA &&
+ srcFormat == GL_BGRA &&
+ srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV) {
+ /* simple memcpy path */
+ memcpy_texture(ctx, dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ dstRowStride, dstImageStride,
+ srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+ srcAddr, srcPacking);
+ }
+ else {
+ /* general path */
+ const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
+ baseInternalFormat,
+ dstFormat->BaseFormat,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr,
+ srcPacking);
+ const GLchan *src = tempImage;
+ GLubyte *dstImage = (GLubyte *) dstAddr
+ + dstZoffset * dstImageStride
+ + dstYoffset * dstRowStride
+ + dstXoffset * dstFormat->TexelBytes;
+ GLint img, row, col;
+ if (!tempImage)
+ return GL_FALSE;
+ _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
+ for (img = 0; img < srcDepth; img++) {
+ GLubyte *dstRow = dstImage;
+ for (row = 0; row < srcHeight; row++) {
+ GLushort *dstUS = (GLushort *) dstRow;
+ if (dstFormat == &_mesa_texformat_argb4444) {
+ for (col = 0; col < srcWidth; col++) {
+ dstUS[col] = PACK_COLOR_4444( CHAN_TO_UBYTE(src[ACOMP]),
+ CHAN_TO_UBYTE(src[RCOMP]),
+ CHAN_TO_UBYTE(src[GCOMP]),
+ CHAN_TO_UBYTE(src[BCOMP]) );
+ src += 4;
+ }
+ }
+ else {
+ for (col = 0; col < srcWidth; col++) {
+ dstUS[col] = PACK_COLOR_4444_REV( CHAN_TO_UBYTE(src[ACOMP]),
+ CHAN_TO_UBYTE(src[RCOMP]),
+ CHAN_TO_UBYTE(src[GCOMP]),
+ CHAN_TO_UBYTE(src[BCOMP]) );
+ src += 4;
+ }
+ }
+ dstRow += dstRowStride;
+ }
+ dstImage += dstImageStride;
+ }
+ _mesa_free((void *) tempImage);
+ }
+ return GL_TRUE;
+}
+
+
+
+GLboolean
+_mesa_texstore_argb1555(STORE_PARAMS)
+{
+ ASSERT(dstFormat == &_mesa_texformat_argb1555 ||
+ dstFormat == &_mesa_texformat_argb1555_rev);
+ ASSERT(dstFormat->TexelBytes == 2);
+
+ if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes &&
+ dstFormat == &_mesa_texformat_argb1555 &&
+ baseInternalFormat == GL_RGBA &&
+ srcFormat == GL_BGRA &&
+ srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV) {
+ /* simple memcpy path */
+ memcpy_texture(ctx, dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ dstRowStride, dstImageStride,
+ srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+ srcAddr, srcPacking);
+ }
+ else {
+ /* general path */
+ const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
+ baseInternalFormat,
+ dstFormat->BaseFormat,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr,
+ srcPacking);
+ const GLchan *src =tempImage;
+ GLubyte *dstImage = (GLubyte *) dstAddr
+ + dstZoffset * dstImageStride
+ + dstYoffset * dstRowStride
+ + dstXoffset * dstFormat->TexelBytes;
+ GLint img, row, col;
+ if (!tempImage)
+ return GL_FALSE;
+ _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
+ for (img = 0; img < srcDepth; img++) {
+ GLubyte *dstRow = dstImage;
+ for (row = 0; row < srcHeight; row++) {
+ GLushort *dstUS = (GLushort *) dstRow;
+ if (dstFormat == &_mesa_texformat_argb1555) {
+ for (col = 0; col < srcWidth; col++) {
+ dstUS[col] = PACK_COLOR_1555( CHAN_TO_UBYTE(src[ACOMP]),
+ CHAN_TO_UBYTE(src[RCOMP]),
+ CHAN_TO_UBYTE(src[GCOMP]),
+ CHAN_TO_UBYTE(src[BCOMP]) );
+ src += 4;
+ }
+ }
+ else {
+ for (col = 0; col < srcWidth; col++) {
+ dstUS[col] = PACK_COLOR_1555_REV( CHAN_TO_UBYTE(src[ACOMP]),
+ CHAN_TO_UBYTE(src[RCOMP]),
+ CHAN_TO_UBYTE(src[GCOMP]),
+ CHAN_TO_UBYTE(src[BCOMP]) );
+ src += 4;
+ }
+ }
+ dstRow += dstRowStride;
+ }
+ dstImage += dstImageStride;
+ }
+ _mesa_free((void *) tempImage);
+ }
+ return GL_TRUE;
+}
+
+
+GLboolean
+_mesa_texstore_al88(STORE_PARAMS)
+{
+ const GLuint ui = 1;
+ const GLubyte littleEndian = *((const GLubyte *) &ui);
+
+ ASSERT(dstFormat == &_mesa_texformat_al88 ||
+ dstFormat == &_mesa_texformat_al88_rev);
+ ASSERT(dstFormat->TexelBytes == 2);
+
+ if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes &&
+ dstFormat == &_mesa_texformat_al88 &&
+ baseInternalFormat == GL_LUMINANCE_ALPHA &&
+ srcFormat == GL_LUMINANCE_ALPHA &&
+ srcType == GL_UNSIGNED_BYTE &&
+ littleEndian) {
+ /* simple memcpy path */
+ memcpy_texture(ctx, dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ dstRowStride, dstImageStride,
+ srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+ srcAddr, srcPacking);
+ }
+ else {
+ /* general path */
+ const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
+ baseInternalFormat,
+ dstFormat->BaseFormat,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr,
+ srcPacking);
+ const GLchan *src = tempImage;
+ GLubyte *dstImage = (GLubyte *) dstAddr
+ + dstZoffset * dstImageStride
+ + dstYoffset * dstRowStride
+ + dstXoffset * dstFormat->TexelBytes;
+ GLint img, row, col;
+ if (!tempImage)
+ return GL_FALSE;
+ _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
+ for (img = 0; img < srcDepth; img++) {
+ GLubyte *dstRow = dstImage;
+ for (row = 0; row < srcHeight; row++) {
+ GLushort *dstUS = (GLushort *) dstRow;
+ if (dstFormat == &_mesa_texformat_al88) {
+ for (col = 0; col < srcWidth; col++) {
+ /* src[0] is luminance, src[1] is alpha */
+ dstUS[col] = PACK_COLOR_88( CHAN_TO_UBYTE(src[1]),
+ CHAN_TO_UBYTE(src[0]) );
+ src += 2;
+ }
+ }
+ else {
+ for (col = 0; col < srcWidth; col++) {
+ /* src[0] is luminance, src[1] is alpha */
+ dstUS[col] = PACK_COLOR_88_REV( CHAN_TO_UBYTE(src[1]),
+ CHAN_TO_UBYTE(src[0]) );
+ src += 2;
+ }
+ }
+ dstRow += dstRowStride;
+ }
+ dstImage += dstImageStride;
+ }
+ _mesa_free((void *) tempImage);
+ }
+ return GL_TRUE;
+}
+
+
+GLboolean
+_mesa_texstore_rgb332(STORE_PARAMS)
+{
+ ASSERT(dstFormat == &_mesa_texformat_rgb332);
+ ASSERT(dstFormat->TexelBytes == 1);
+
+ if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes &&
+ baseInternalFormat == GL_RGB &&
+ srcFormat == GL_RGB && srcType == GL_UNSIGNED_BYTE_3_3_2) {
+ /* simple memcpy path */
+ memcpy_texture(ctx, dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ dstRowStride, dstImageStride,
+ srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+ srcAddr, srcPacking);
+ }
+ else {
+ /* general path */
+ const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
+ baseInternalFormat,
+ dstFormat->BaseFormat,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr,
+ srcPacking);
+ const GLchan *src = tempImage;
+ GLubyte *dstImage = (GLubyte *) dstAddr
+ + dstZoffset * dstImageStride
+ + dstYoffset * dstRowStride
+ + dstXoffset * dstFormat->TexelBytes;
+ GLint img, row, col;
+ if (!tempImage)
+ return GL_FALSE;
+ _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
+ for (img = 0; img < srcDepth; img++) {
+ GLubyte *dstRow = dstImage;
+ for (row = 0; row < srcHeight; row++) {
+ for (col = 0; col < srcWidth; col++) {
+ dstRow[col] = PACK_COLOR_332( CHAN_TO_UBYTE(src[RCOMP]),
+ CHAN_TO_UBYTE(src[GCOMP]),
+ CHAN_TO_UBYTE(src[BCOMP]) );
+ src += 3;
+ }
+ dstRow += dstRowStride;
+ }
+ dstImage += dstImageStride;
+ }
+ _mesa_free((void *) tempImage);
+ }
+ return GL_TRUE;
+}
+
+
+/**
+ * Texstore for _mesa_texformat_a8, _mesa_texformat_l8, _mesa_texformat_i8.
+ */
+GLboolean
+_mesa_texstore_a8(STORE_PARAMS)
+{
+ ASSERT(dstFormat == &_mesa_texformat_a8 ||
+ dstFormat == &_mesa_texformat_l8 ||
+ dstFormat == &_mesa_texformat_i8);
+ ASSERT(dstFormat->TexelBytes == 1);
+
+ if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes &&
+ baseInternalFormat == srcFormat &&
+ srcType == GL_UNSIGNED_BYTE) {
+ /* simple memcpy path */
+ memcpy_texture(ctx, dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ dstRowStride, dstImageStride,
+ srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+ srcAddr, srcPacking);
+ }
+ else {
+ /* general path */
+ const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
+ baseInternalFormat,
+ dstFormat->BaseFormat,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr,
+ srcPacking);
+ const GLchan *src = tempImage;
+ GLubyte *dstImage = (GLubyte *) dstAddr
+ + dstZoffset * dstImageStride
+ + dstYoffset * dstRowStride
+ + dstXoffset * dstFormat->TexelBytes;
+ GLint img, row, col;
+ if (!tempImage)
+ return GL_FALSE;
+ _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
+ for (img = 0; img < srcDepth; img++) {
+ GLubyte *dstRow = dstImage;
+ for (row = 0; row < srcHeight; row++) {
+ for (col = 0; col < srcWidth; col++) {
+ dstRow[col] = CHAN_TO_UBYTE(src[col]);
+ }
+ dstRow += dstRowStride;
+ src += srcWidth;
+ }
+ dstImage += dstImageStride;
+ }
+ _mesa_free((void *) tempImage);
+ }
+ return GL_TRUE;
+}
+
+
+
+GLboolean
+_mesa_texstore_ci8(STORE_PARAMS)
+{
+ (void) dims; (void) baseInternalFormat;
+ ASSERT(dstFormat == &_mesa_texformat_ci8);
+ ASSERT(dstFormat->TexelBytes == 1);
+ ASSERT(baseInternalFormat == GL_COLOR_INDEX);
+
+ if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes &&
+ srcFormat == GL_COLOR_INDEX &&
+ srcType == GL_UNSIGNED_BYTE) {
+ /* simple memcpy path */
+ memcpy_texture(ctx, dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ dstRowStride, dstImageStride,
+ srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+ srcAddr, srcPacking);
+ }
+ else {
+ /* general path */
+ GLubyte *dstImage = (GLubyte *) dstAddr
+ + dstZoffset * dstImageStride
+ + dstYoffset * dstRowStride
+ + dstXoffset * dstFormat->TexelBytes;
+ GLint img, row;
+ for (img = 0; img < srcDepth; img++) {
+ GLubyte *dstRow = dstImage;
+ for (row = 0; row < srcHeight; row++) {
+ const GLvoid *src = _mesa_image_address(dims, srcPacking,
+ srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
+ _mesa_unpack_index_span(ctx, srcWidth, GL_UNSIGNED_BYTE, dstRow,
+ srcType, src, srcPacking,
+ ctx->_ImageTransferState);
+ dstRow += dstRowStride;
+ }
+ dstImage += dstImageStride;
+ }
+ }
+ return GL_TRUE;
+}
+
+
+/**
+ * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_rev.
+ */
+GLboolean
+_mesa_texstore_ycbcr(STORE_PARAMS)
+{
+ const GLuint ui = 1;
+ const GLubyte littleEndian = *((const GLubyte *) &ui);
+ (void) ctx; (void) dims; (void) baseInternalFormat;
+
+ ASSERT((dstFormat == &_mesa_texformat_ycbcr) ||
+ (dstFormat == &_mesa_texformat_ycbcr_rev));
+ ASSERT(dstFormat->TexelBytes == 2);
+ ASSERT(ctx->Extensions.MESA_ycbcr_texture);
+ ASSERT(srcFormat == GL_YCBCR_MESA);
+ ASSERT((srcType == GL_UNSIGNED_SHORT_8_8_MESA) ||
+ (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA));
+ ASSERT(baseInternalFormat == GL_YCBCR_MESA);
+
+ /* always just memcpy since no pixel transfer ops apply */
+ memcpy_texture(ctx, dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ dstRowStride, dstImageStride,
+ srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+ srcAddr, srcPacking);
+
+ /* Check if we need byte swapping */
+ /* XXX the logic here _might_ be wrong */
+ if (srcPacking->SwapBytes ^
+ (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA) ^
+ (dstFormat == &_mesa_texformat_ycbcr_rev) ^
+ !littleEndian) {
+ GLubyte *pImage = (GLubyte *) dstAddr
+ + dstZoffset * dstImageStride
+ + dstYoffset * dstRowStride
+ + dstXoffset * dstFormat->TexelBytes;
+ GLint img, row;
+ for (img = 0; img < srcDepth; img++) {
+ GLubyte *pRow = pImage;
+ for (row = 0; row < srcHeight; row++) {
+ _mesa_swap2((GLushort *) pRow, srcWidth);
+ pRow += dstRowStride;
+ }
+ pImage += dstImageStride;
+ }
+ }
+ return GL_TRUE;
+}
+
+
+
+/**
+ * Store a combined depth/stencil texture image.
+ */
+GLboolean
+_mesa_texstore_z24_s8(STORE_PARAMS)
+{
+ ASSERT(dstFormat == &_mesa_texformat_z24_s8);
+ ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT);
+ ASSERT(srcType == GL_UNSIGNED_INT_24_8_EXT);
+
+ if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes) {
+ /* simple path */
+ memcpy_texture(ctx, dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ dstRowStride, dstImageStride,
+ srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+ srcAddr, srcPacking);
+ }
+ else {
+ /* general path */
+ const GLint srcRowStride
+ = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
+ / sizeof(GLuint);
+ GLuint *dstImage = (GLuint *) dstAddr;
+ GLint img, row;
+
+ for (img = 0; img < srcDepth; img++) {
+ GLuint *dst = dstImage;
+ const GLuint *src
+ = (const GLuint *) _mesa_image_address(dims, srcPacking, srcAddr,
+ srcWidth, srcHeight,
+ srcFormat, srcType,
+ img, 0, 0);
+ for (row = 0; row < srcHeight; row++) {
+ GLubyte stencil[MAX_WIDTH];
+ GLint i;
+ /* the 24 depth bits will be in the high position: */
+ _mesa_unpack_depth_span(ctx, srcWidth,
+ GL_UNSIGNED_INT, /* dst type */
+ dst, /* dst addr */
+ (GLfloat) 0xffffff, /* depthScale */
+ srcType, src, srcPacking);
+ /* get the 8-bit stencil values */
+ _mesa_unpack_stencil_span(ctx, srcWidth,
+ GL_UNSIGNED_BYTE, /* dst type */
+ stencil, /* dst addr */
+ srcType, src, srcPacking,
+ ctx->_ImageTransferState);
+ /* merge stencil values into depth values */
+ for (i = 0; i < srcWidth; i++)
+ dst[i] |= stencil[i];
+
+ src += srcRowStride;
+ dst += dstRowStride / sizeof(GLuint);
+ }
+ dstImage += dstImageStride / sizeof(GLuint);
+ }
+ }
+
+
+ return GL_TRUE;
+}
+
+
+
+/**
+ * Store an image in any of the formats:
+ * _mesa_texformat_rgba_float32
+ * _mesa_texformat_rgb_float32
+ * _mesa_texformat_alpha_float32
+ * _mesa_texformat_luminance_float32
+ * _mesa_texformat_luminance_alpha_float32
+ * _mesa_texformat_intensity_float32
+ */
+GLboolean
+_mesa_texstore_rgba_float32(STORE_PARAMS)
+{
+ const GLint components = _mesa_components_in_format(dstFormat->BaseFormat);
+
+ ASSERT(dstFormat == &_mesa_texformat_rgba_float32 ||
+ dstFormat == &_mesa_texformat_rgb_float32 ||
+ dstFormat == &_mesa_texformat_alpha_float32 ||
+ dstFormat == &_mesa_texformat_luminance_float32 ||
+ dstFormat == &_mesa_texformat_luminance_alpha_float32 ||
+ dstFormat == &_mesa_texformat_intensity_float32);
+ ASSERT(baseInternalFormat == GL_RGBA ||
+ baseInternalFormat == GL_RGB ||
+ baseInternalFormat == GL_ALPHA ||
+ baseInternalFormat == GL_LUMINANCE ||
+ baseInternalFormat == GL_LUMINANCE_ALPHA ||
+ baseInternalFormat == GL_INTENSITY);
+ ASSERT(dstFormat->TexelBytes == components * sizeof(GLfloat));
+
+ if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes &&
+ baseInternalFormat == srcFormat &&
+ srcType == GL_FLOAT) {
+ /* simple memcpy path */
+ memcpy_texture(ctx, dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ dstRowStride, dstImageStride,
+ srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+ srcAddr, srcPacking);
+ }
+ else {
+ /* general path */
+ const GLfloat *tempImage = make_temp_float_image(ctx, dims,
+ baseInternalFormat,
+ dstFormat->BaseFormat,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr,
+ srcPacking);
+ const GLfloat *src = tempImage;
+ GLint bytesPerRow;
+ GLubyte *dstImage = (GLubyte *) dstAddr
+ + dstZoffset * dstImageStride
+ + dstYoffset * dstRowStride
+ + dstXoffset * dstFormat->TexelBytes;
+ GLint img, row;
+ if (!tempImage)
+ return GL_FALSE;
+ _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
+ bytesPerRow = srcWidth * components * sizeof(GLfloat);
+ for (img = 0; img < srcDepth; img++) {
+ GLubyte *dst = dstImage;
+ for (row = 0; row < srcHeight; row++) {
+ _mesa_memcpy(dst, src, bytesPerRow);
+ dst += dstRowStride;
+ src += srcWidth * components;
+ }
+ dstImage += dstImageStride;
+ }
+
+ _mesa_free((void *) tempImage);
+ }
+ return GL_TRUE;
+}
+
+
+/**
+ * As above, but store 16-bit floats.
+ */
+GLboolean
+_mesa_texstore_rgba_float16(STORE_PARAMS)
+{
+ const GLint components = _mesa_components_in_format(dstFormat->BaseFormat);
+
+ ASSERT(dstFormat == &_mesa_texformat_rgba_float16 ||
+ dstFormat == &_mesa_texformat_rgb_float16 ||
+ dstFormat == &_mesa_texformat_alpha_float16 ||
+ dstFormat == &_mesa_texformat_luminance_float16 ||
+ dstFormat == &_mesa_texformat_luminance_alpha_float16 ||
+ dstFormat == &_mesa_texformat_intensity_float16);
+ ASSERT(baseInternalFormat == GL_RGBA ||
+ baseInternalFormat == GL_RGB ||
+ baseInternalFormat == GL_ALPHA ||
+ baseInternalFormat == GL_LUMINANCE ||
+ baseInternalFormat == GL_LUMINANCE_ALPHA ||
+ baseInternalFormat == GL_INTENSITY);
+ ASSERT(dstFormat->TexelBytes == components * sizeof(GLhalfARB));
+
+ if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes &&
+ baseInternalFormat == srcFormat &&
+ srcType == GL_HALF_FLOAT_ARB) {
+ /* simple memcpy path */
+ memcpy_texture(ctx, dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ dstRowStride, dstImageStride,
+ srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+ srcAddr, srcPacking);
+ }
+ else {
+ /* general path */
+ const GLfloat *tempImage = make_temp_float_image(ctx, dims,
+ baseInternalFormat,
+ dstFormat->BaseFormat,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr,
+ srcPacking);
+ const GLfloat *src = tempImage;
+ GLubyte *dstImage = (GLubyte *) dstAddr
+ + dstZoffset * dstImageStride
+ + dstYoffset * dstRowStride
+ + dstXoffset * dstFormat->TexelBytes;
+ GLint img, row;
+ if (!tempImage)
+ return GL_FALSE;
+ _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
+ for (img = 0; img < srcDepth; img++) {
+ GLubyte *dstRow = dstImage;
+ for (row = 0; row < srcHeight; row++) {
+ GLhalfARB *dstTexel = (GLhalfARB *) dstRow;
+ GLint i;
+ for (i = 0; i < srcWidth * components; i++) {
+ dstTexel[i] = _mesa_float_to_half(src[i]);
+ }
+ dstRow += dstRowStride;
+ src += srcWidth * components;
+ }
+ dstImage += dstImageStride;
+ }
+
+ _mesa_free((void *) tempImage);
+ }
+ return GL_TRUE;
+}
+
+
+
+/**
+ * Check if an unpack PBO is active prior to fetching a texture image.
+ * If so, do bounds checking and map the buffer into main memory.
+ * Any errors detected will be recorded.
+ * The caller _must_ call _mesa_unmap_teximage_pbo() too!
+ */
+const GLvoid *
+_mesa_validate_pbo_teximage(GLcontext *ctx, GLuint dimensions,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type, const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *unpack,
+ const char *funcName)
+{
+ GLubyte *buf;
+
+ if (unpack->BufferObj->Name == 0) {
+ /* no PBO */
+ return pixels;
+ }
+ if (!_mesa_validate_pbo_access(dimensions, unpack, width, height, depth,
+ format, type, pixels)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access");
+ return NULL;
+ }
+
+ buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+ GL_READ_ONLY_ARB, unpack->BufferObj);
+ if (!buf) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(PBO is mapped");
+ return NULL;
+ }
+
+ return ADD_POINTERS(buf, pixels);
+}
+
+
+/**
+ * Check if an unpack PBO is active prior to fetching a compressed texture
+ * image.
+ * If so, do bounds checking and map the buffer into main memory.
+ * Any errors detected will be recorded.
+ * The caller _must_ call _mesa_unmap_teximage_pbo() too!
+ */
+const GLvoid *
+_mesa_validate_pbo_compressed_teximage(GLcontext *ctx,
+ GLsizei imageSize, const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ const char *funcName)
+{
+ GLubyte *buf;
+
+ if (packing->BufferObj->Name == 0) {
+ /* not using a PBO - return pointer unchanged */
+ return pixels;
+ }
+ if ((const GLubyte *) pixels + imageSize >
+ ((const GLubyte *) 0) + packing->BufferObj->Size) {
+ /* out of bounds read! */
+ _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access");
+ return NULL;
+ }
+
+ buf = (GLubyte*) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+ GL_READ_ONLY_ARB, packing->BufferObj);
+ if (!buf) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(PBO is mapped");
+ return NULL;
+ }
+
+ return ADD_POINTERS(buf, pixels);
+}
+
+
+/**
+ * This function must be called after either of the validate_pbo_*_teximage()
+ * functions. It unmaps the PBO buffer if it was mapped earlier.
+ */
+void
+_mesa_unmap_teximage_pbo(GLcontext *ctx,
+ const struct gl_pixelstore_attrib *unpack)
+{
+ if (unpack->BufferObj->Name) {
+ ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+ unpack->BufferObj);
+ }
+}
+
+
+
+/**
+ * Adaptor for fetching a GLchan texel from a float-valued texture.
+ */
+static void
+FetchTexelFloatToChan( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLchan *texelOut )
+{
+ GLfloat temp[4];
+ ASSERT(texImage->FetchTexelf);
+ texImage->FetchTexelf(texImage, i, j, k, temp);
+ if (texImage->TexFormat->BaseFormat == GL_DEPTH_COMPONENT ||
+ texImage->TexFormat->BaseFormat == GL_DEPTH_STENCIL_EXT) {
+ /* just one channel */
+ UNCLAMPED_FLOAT_TO_CHAN(texelOut[0], temp[0]);
+ }
+ else {
+ /* four channels */
+ UNCLAMPED_FLOAT_TO_CHAN(texelOut[0], temp[0]);
+ UNCLAMPED_FLOAT_TO_CHAN(texelOut[1], temp[1]);
+ UNCLAMPED_FLOAT_TO_CHAN(texelOut[2], temp[2]);
+ UNCLAMPED_FLOAT_TO_CHAN(texelOut[3], temp[3]);
+ }
+}
+
+
+/**
+ * Adaptor for fetching a float texel from a GLchan-valued texture.
+ */
+static void
+FetchTexelChanToFloat( const struct gl_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLfloat *texelOut )
+{
+ GLchan temp[4];
+ ASSERT(texImage->FetchTexelc);
+ texImage->FetchTexelc(texImage, i, j, k, temp);
+ if (texImage->TexFormat->BaseFormat == GL_DEPTH_COMPONENT ||
+ texImage->TexFormat->BaseFormat == GL_DEPTH_STENCIL_EXT) {
+ /* just one channel */
+ texelOut[0] = CHAN_TO_FLOAT(temp[0]);
+ }
+ else {
+ /* four channels */
+ texelOut[0] = CHAN_TO_FLOAT(temp[0]);
+ texelOut[1] = CHAN_TO_FLOAT(temp[1]);
+ texelOut[2] = CHAN_TO_FLOAT(temp[2]);
+ texelOut[3] = CHAN_TO_FLOAT(temp[3]);
+ }
+}
+
+
+/**
+ * Initialize the texture image's FetchTexelc and FetchTexelf methods.
+ */
+static void
+set_fetch_functions(struct gl_texture_image *texImage, GLuint dims)
+{
+ ASSERT(dims == 1 || dims == 2 || dims == 3);
+ ASSERT(texImage->TexFormat);
+
+ switch (dims) {
+ case 1:
+ texImage->FetchTexelc = texImage->TexFormat->FetchTexel1D;
+ texImage->FetchTexelf = texImage->TexFormat->FetchTexel1Df;
+ break;
+ case 2:
+ texImage->FetchTexelc = texImage->TexFormat->FetchTexel2D;
+ texImage->FetchTexelf = texImage->TexFormat->FetchTexel2Df;
+ break;
+ case 3:
+ texImage->FetchTexelc = texImage->TexFormat->FetchTexel3D;
+ texImage->FetchTexelf = texImage->TexFormat->FetchTexel3Df;
+ break;
+ default:
+ ;
+ }
+
+ /* now check if we need to use a float/chan adaptor */
+ if (!texImage->FetchTexelc) {
+ texImage->FetchTexelc = FetchTexelFloatToChan;
+ }
+ else if (!texImage->FetchTexelf) {
+ texImage->FetchTexelf = FetchTexelChanToFloat;
+ }
+
+
+ ASSERT(texImage->FetchTexelc);
+ ASSERT(texImage->FetchTexelf);
+}
+
+
+/*
+ * This is the software fallback for Driver.TexImage1D()
+ * and Driver.CopyTexImage1D().
+ * \sa _mesa_store_teximage2d()
+ */
+void
+_mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint border,
+ GLenum format, GLenum type, const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ GLint postConvWidth = width;
+ GLint sizeInBytes;
+ (void) border;
+
+ if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
+ _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
+ }
+
+ /* choose the texture format */
+ assert(ctx->Driver.ChooseTextureFormat);
+ texImage->TexFormat = ctx->Driver.ChooseTextureFormat(ctx, internalFormat,
+ format, type);
+ assert(texImage->TexFormat);
+ set_fetch_functions(texImage, 1);
+
+ /* allocate memory */
+ if (texImage->IsCompressed)
+ sizeInBytes = texImage->CompressedSize;
+ else
+ sizeInBytes = postConvWidth * texImage->TexFormat->TexelBytes;
+ texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
+ if (!texImage->Data) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
+ return;
+ }
+
+ pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type,
+ pixels, packing, "glTexImage1D");
+ if (!pixels) {
+ /* Note: we check for a NULL image pointer here, _after_ we allocated
+ * memory for the texture. That's what the GL spec calls for.
+ */
+ return;
+ }
+ else {
+ const GLint dstRowStride = 0, dstImageStride = 0;
+ GLboolean success;
+ ASSERT(texImage->TexFormat->StoreImage);
+ success = texImage->TexFormat->StoreImage(ctx, 1, texImage->_BaseFormat,
+ texImage->TexFormat,
+ texImage->Data,
+ 0, 0, 0, /* dstX/Y/Zoffset */
+ dstRowStride, dstImageStride,
+ width, 1, 1,
+ format, type, pixels, packing);
+ if (!success) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
+ }
+ }
+
+ /* GL_SGIS_generate_mipmap */
+ if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+ _mesa_generate_mipmap(ctx, target,
+ &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
+ texObj);
+ }
+
+ _mesa_unmap_teximage_pbo(ctx, packing);
+}
+
+
+/**
+ * This is the software fallback for Driver.TexImage2D()
+ * and Driver.CopyTexImage2D().
+ * We store the image in heap memory. We know nothing about on-board
+ * VRAM here. But since most DRI drivers rely on keeping a copy of all
+ * textures in main memory, this routine will typically be used by
+ * hardware drivers too.
+ *
+ * Reasons why a driver might override this function:
+ * - Special memory allocation needs (VRAM, AGP, etc)
+ * - Unusual row/image strides or padding
+ * - Special housekeeping
+ * - Using VRAM-based Pixel Buffer Objects
+ */
+void
+_mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint height, GLint border,
+ GLenum format, GLenum type, const void *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ GLint postConvWidth = width, postConvHeight = height;
+ GLint texelBytes, sizeInBytes;
+ (void) border;
+
+ if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
+ _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,
+ &postConvHeight);
+ }
+
+ /* choose the texture format */
+ assert(ctx->Driver.ChooseTextureFormat);
+ texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
+ internalFormat, format, type);
+ assert(texImage->TexFormat);
+ set_fetch_functions(texImage, 2);
+
+ texelBytes = texImage->TexFormat->TexelBytes;
+
+ /* allocate memory */
+ if (texImage->IsCompressed)
+ sizeInBytes = texImage->CompressedSize;
+ else
+ sizeInBytes = postConvWidth * postConvHeight * texelBytes;
+ texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
+ if (!texImage->Data) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
+ return;
+ }
+
+ pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type,
+ pixels, packing, "glTexImage2D");
+ if (!pixels) {
+ /* Note: we check for a NULL image pointer here, _after_ we allocated
+ * memory for the texture. That's what the GL spec calls for.
+ */
+ return;
+ }
+ else {
+ GLint dstRowStride, dstImageStride = 0;
+ GLboolean success;
+ if (texImage->IsCompressed) {
+ dstRowStride
+ = _mesa_compressed_row_stride(texImage->InternalFormat,width);
+ }
+ else {
+ dstRowStride = postConvWidth * texImage->TexFormat->TexelBytes;
+ }
+ ASSERT(texImage->TexFormat->StoreImage);
+ success = texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat,
+ texImage->TexFormat,
+ texImage->Data,
+ 0, 0, 0, /* dstX/Y/Zoffset */
+ dstRowStride, dstImageStride,
+ width, height, 1,
+ format, type, pixels, packing);
+ if (!success) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
+ }
+ }
+
+ /* GL_SGIS_generate_mipmap */
+ if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+ _mesa_generate_mipmap(ctx, target,
+ &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
+ texObj);
+ }
+
+ _mesa_unmap_teximage_pbo(ctx, packing);
+}
+
+
+
+/**
+ * This is the software fallback for Driver.TexImage3D()
+ * and Driver.CopyTexImage3D().
+ * \sa _mesa_store_teximage2d()
+ */
+void
+_mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint height, GLint depth, GLint border,
+ GLenum format, GLenum type, const void *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ GLint texelBytes, sizeInBytes;
+ (void) border;
+
+ /* choose the texture format */
+ assert(ctx->Driver.ChooseTextureFormat);
+ texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
+ internalFormat, format, type);
+ assert(texImage->TexFormat);
+ set_fetch_functions(texImage, 3);
+
+ texelBytes = texImage->TexFormat->TexelBytes;
+
+ /* allocate memory */
+ if (texImage->IsCompressed)
+ sizeInBytes = texImage->CompressedSize;
+ else
+ sizeInBytes = width * height * depth * texelBytes;
+ texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
+ if (!texImage->Data) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
+ return;
+ }
+
+ pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format,
+ type, pixels, packing, "glTexImage3D");
+ if (!pixels) {
+ /* Note: we check for a NULL image pointer here, _after_ we allocated
+ * memory for the texture. That's what the GL spec calls for.
+ */
+ return;
+ }
+ else {
+ GLint dstRowStride, dstImageStride;
+ GLboolean success;
+ if (texImage->IsCompressed) {
+ dstRowStride
+ = _mesa_compressed_row_stride(texImage->InternalFormat,width);
+ dstImageStride = 0;
+ }
+ else {
+ dstRowStride = width * texImage->TexFormat->TexelBytes;
+ dstImageStride = dstRowStride * height;
+ }
+ ASSERT(texImage->TexFormat->StoreImage);
+ success = texImage->TexFormat->StoreImage(ctx, 3, texImage->_BaseFormat,
+ texImage->TexFormat,
+ texImage->Data,
+ 0, 0, 0, /* dstX/Y/Zoffset */
+ dstRowStride, dstImageStride,
+ width, height, depth,
+ format, type, pixels, packing);
+ if (!success) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
+ }
+ }
+
+ /* GL_SGIS_generate_mipmap */
+ if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+ _mesa_generate_mipmap(ctx, target,
+ &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
+ texObj);
+ }
+
+ _mesa_unmap_teximage_pbo(ctx, packing);
+}
+
+
+
+
+/*
+ * This is the software fallback for Driver.TexSubImage1D()
+ * and Driver.CopyTexSubImage1D().
+ */
+void
+_mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
+ GLint xoffset, GLint width,
+ GLenum format, GLenum type, const void *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type,
+ pixels, packing, "glTexSubImage1D");
+ if (!pixels)
+ return;
+
+ {
+ const GLint dstRowStride = 0, dstImageStride = 0;
+ GLboolean success;
+ ASSERT(texImage->TexFormat->StoreImage);
+ success = texImage->TexFormat->StoreImage(ctx, 1, texImage->_BaseFormat,
+ texImage->TexFormat,
+ texImage->Data,
+ xoffset, 0, 0, /* offsets */
+ dstRowStride, dstImageStride,
+ width, 1, 1,
+ format, type, pixels, packing);
+ if (!success) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
+ }
+ }
+
+ /* GL_SGIS_generate_mipmap */
+ if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+ _mesa_generate_mipmap(ctx, target,
+ &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
+ texObj);
+ }
+
+ _mesa_unmap_teximage_pbo(ctx, packing);
+}
+
+
+
+/**
+ * This is the software fallback for Driver.TexSubImage2D()
+ * and Driver.CopyTexSubImage2D().
+ */
+void
+_mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLint width, GLint height,
+ GLenum format, GLenum type, const void *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type,
+ pixels, packing, "glTexSubImage2D");
+ if (!pixels)
+ return;
+
+ {
+ GLint dstRowStride = 0, dstImageStride = 0;
+ GLboolean success;
+ if (texImage->IsCompressed) {
+ dstRowStride = _mesa_compressed_row_stride(texImage->InternalFormat,
+ texImage->Width);
+ }
+ else {
+ dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes;
+ }
+ ASSERT(texImage->TexFormat->StoreImage);
+ success = texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat,
+ texImage->TexFormat,
+ texImage->Data,
+ xoffset, yoffset, 0,
+ dstRowStride, dstImageStride,
+ width, height, 1,
+ format, type, pixels, packing);
+ if (!success) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
+ }
+ }
+
+ /* GL_SGIS_generate_mipmap */
+ if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+ _mesa_generate_mipmap(ctx, target,
+ &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
+ texObj);
+ }
+
+ _mesa_unmap_teximage_pbo(ctx, packing);
+}
+
+
+/*
+ * This is the software fallback for Driver.TexSubImage3D().
+ * and Driver.CopyTexSubImage3D().
+ */
+void
+_mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLint width, GLint height, GLint depth,
+ GLenum format, GLenum type, const void *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format,
+ type, pixels, packing,
+ "glTexSubImage3D");
+ if (!pixels)
+ return;
+
+ {
+ GLint dstRowStride, dstImageStride;
+ GLboolean success;
+ if (texImage->IsCompressed) {
+ dstRowStride = _mesa_compressed_row_stride(texImage->InternalFormat,
+ texImage->Width);
+ dstImageStride = 0; /* XXX fix */
+ }
+ else {
+ dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes;
+ dstImageStride = dstRowStride * texImage->Height;
+ }
+ ASSERT(texImage->TexFormat->StoreImage);
+ success = texImage->TexFormat->StoreImage(ctx, 3, texImage->_BaseFormat,
+ texImage->TexFormat,
+ texImage->Data,
+ xoffset, yoffset, zoffset,
+ dstRowStride, dstImageStride,
+ width, height, depth,
+ format, type, pixels, packing);
+ if (!success) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D");
+ }
+ }
+
+ /* GL_SGIS_generate_mipmap */
+ if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+ _mesa_generate_mipmap(ctx, target,
+ &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
+ texObj);
+ }
+
+ _mesa_unmap_teximage_pbo(ctx, packing);
+}
+
+
+/*
+ * Fallback for Driver.CompressedTexImage1D()
+ */
+void
+_mesa_store_compressed_teximage1d(GLcontext *ctx, GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint border,
+ GLsizei imageSize, const GLvoid *data,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ /* this space intentionally left blank */
+ (void) ctx;
+ (void) target; (void) level;
+ (void) internalFormat;
+ (void) width; (void) border;
+ (void) imageSize; (void) data;
+ (void) texObj;
+ (void) texImage;
+}
+
+
+
+/*
+ * Fallback for Driver.CompressedTexImage2D()
+ */
+void
+_mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint height, GLint border,
+ GLsizei imageSize, const GLvoid *data,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ (void) width; (void) height; (void) border;
+
+ /* This is pretty simple, basically just do a memcpy without worrying
+ * about the usual image unpacking or image transfer operations.
+ */
+ ASSERT(texObj);
+ ASSERT(texImage);
+ ASSERT(texImage->Width > 0);
+ ASSERT(texImage->Height > 0);
+ ASSERT(texImage->Depth == 1);
+ ASSERT(texImage->Data == NULL); /* was freed in glCompressedTexImage2DARB */
+
+ /* choose the texture format */
+ assert(ctx->Driver.ChooseTextureFormat);
+ texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
+ internalFormat, 0, 0);
+ assert(texImage->TexFormat);
+ set_fetch_functions(texImage, 2);
+
+ /* allocate storage */
+ texImage->Data = _mesa_alloc_texmemory(imageSize);
+ if (!texImage->Data) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2DARB");
+ return;
+ }
+
+ data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data,
+ &ctx->Unpack,
+ "glCompressedTexImage2D");
+ if (!data)
+ return;
+
+ /* copy the data */
+ ASSERT(texImage->CompressedSize == (GLuint) imageSize);
+ MEMCPY(texImage->Data, data, imageSize);
+
+ /* GL_SGIS_generate_mipmap */
+ if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+ _mesa_generate_mipmap(ctx, target,
+ &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
+ texObj);
+ }
+
+ _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
+}
+
+
+
+/*
+ * Fallback for Driver.CompressedTexImage3D()
+ */
+void
+_mesa_store_compressed_teximage3d(GLcontext *ctx, GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint height, GLint depth,
+ GLint border,
+ GLsizei imageSize, const GLvoid *data,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ /* this space intentionally left blank */
+ (void) ctx;
+ (void) target; (void) level;
+ (void) internalFormat;
+ (void) width; (void) height; (void) depth;
+ (void) border;
+ (void) imageSize; (void) data;
+ (void) texObj;
+ (void) texImage;
+}
+
+
+
+/**
+ * Fallback for Driver.CompressedTexSubImage1D()
+ */
+void
+_mesa_store_compressed_texsubimage1d(GLcontext *ctx, GLenum target,
+ GLint level,
+ GLint xoffset, GLsizei width,
+ GLenum format,
+ GLsizei imageSize, const GLvoid *data,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ /* this space intentionally left blank */
+ (void) ctx;
+ (void) target; (void) level;
+ (void) xoffset; (void) width;
+ (void) format;
+ (void) imageSize; (void) data;
+ (void) texObj;
+ (void) texImage;
+}
+
+
+/**
+ * Fallback for Driver.CompressedTexSubImage2D()
+ */
+void
+_mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target,
+ GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLenum format,
+ GLsizei imageSize, const GLvoid *data,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ GLint bytesPerRow, destRowStride, srcRowStride;
+ GLint i, rows;
+ GLubyte *dest;
+ const GLubyte *src;
+ (void) format;
+
+ /* these should have been caught sooner */
+ ASSERT((width & 3) == 0 || width == 2 || width == 1);
+ ASSERT((height & 3) == 0 || height == 2 || height == 1);
+ ASSERT((xoffset & 3) == 0);
+ ASSERT((yoffset & 3) == 0);
+
+ data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data,
+ &ctx->Unpack,
+ "glCompressedTexSubImage2D");
+ if (!data)
+ return;
+
+ srcRowStride = _mesa_compressed_row_stride(texImage->InternalFormat, width);
+ src = (const GLubyte *) data;
+
+ destRowStride = _mesa_compressed_row_stride(texImage->InternalFormat,
+ texImage->Width);
+ dest = _mesa_compressed_image_address(xoffset, yoffset, 0,
+ texImage->InternalFormat,
+ texImage->Width,
+ (GLubyte*) texImage->Data);
+
+ bytesPerRow = srcRowStride;
+ rows = height / 4;
+
+ for (i = 0; i < rows; i++) {
+ MEMCPY(dest, src, bytesPerRow);
+ dest += destRowStride;
+ src += srcRowStride;
+ }
+
+ /* GL_SGIS_generate_mipmap */
+ if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+ _mesa_generate_mipmap(ctx, target,
+ &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
+ texObj);
+ }
+
+ _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
+}
+
+
+/**
+ * Fallback for Driver.CompressedTexSubImage3D()
+ */
+void
+_mesa_store_compressed_texsubimage3d(GLcontext *ctx, GLenum target,
+ GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format,
+ GLsizei imageSize, const GLvoid *data,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ /* this space intentionally left blank */
+ (void) ctx;
+ (void) target; (void) level;
+ (void) xoffset; (void) yoffset; (void) zoffset;
+ (void) width; (void) height; (void) depth;
+ (void) format;
+ (void) imageSize; (void) data;
+ (void) texObj;
+ (void) texImage;
+}
+
+
+/*
+ * Average together two rows of a source image to produce a single new
+ * row in the dest image. It's legal for the two source rows to point
+ * to the same data. The source width must be equal to either the
+ * dest width or two times the dest width.
+ */
+static void
+do_row(const struct gl_texture_format *format, GLint srcWidth,
+ const GLvoid *srcRowA, const GLvoid *srcRowB,
+ GLint dstWidth, GLvoid *dstRow)
+{
+ const GLuint k0 = (srcWidth == dstWidth) ? 0 : 1;
+ const GLuint colStride = (srcWidth == dstWidth) ? 1 : 2;
+
+ /* This assertion is no longer valid with non-power-of-2 textures
+ assert(srcWidth == dstWidth || srcWidth == 2 * dstWidth);
+ */
+
+ switch (format->MesaFormat) {
+ case MESA_FORMAT_RGBA:
+ {
+ GLuint i, j, k;
+ const GLchan (*rowA)[4] = (const GLchan (*)[4]) srcRowA;
+ const GLchan (*rowB)[4] = (const GLchan (*)[4]) srcRowB;
+ GLchan (*dst)[4] = (GLchan (*)[4]) dstRow;
+ for (i = j = 0, k = k0; i < (GLuint) dstWidth;
+ i++, j += colStride, k += colStride) {
+ dst[i][0] = (rowA[j][0] + rowA[k][0] +
+ rowB[j][0] + rowB[k][0]) / 4;
+ dst[i][1] = (rowA[j][1] + rowA[k][1] +
+ rowB[j][1] + rowB[k][1]) / 4;
+ dst[i][2] = (rowA[j][2] + rowA[k][2] +
+ rowB[j][2] + rowB[k][2]) / 4;
+ dst[i][3] = (rowA[j][3] + rowA[k][3] +
+ rowB[j][3] + rowB[k][3]) / 4;
+ }
+ }
+ return;
+ case MESA_FORMAT_RGB:
+ {
+ GLuint i, j, k;
+ const GLchan (*rowA)[3] = (const GLchan (*)[3]) srcRowA;
+ const GLchan (*rowB)[3] = (const GLchan (*)[3]) srcRowB;
+ GLchan (*dst)[3] = (GLchan (*)[3]) dstRow;
+ for (i = j = 0, k = k0; i < (GLuint) dstWidth;
+ i++, j += colStride, k += colStride) {
+ dst[i][0] = (rowA[j][0] + rowA[k][0] +
+ rowB[j][0] + rowB[k][0]) / 4;
+ dst[i][1] = (rowA[j][1] + rowA[k][1] +
+ rowB[j][1] + rowB[k][1]) / 4;
+ dst[i][2] = (rowA[j][2] + rowA[k][2] +
+ rowB[j][2] + rowB[k][2]) / 4;
+ }
+ }
+ return;
+ case MESA_FORMAT_ALPHA:
+ case MESA_FORMAT_LUMINANCE:
+ case MESA_FORMAT_INTENSITY:
+ {
+ GLuint i, j, k;
+ const GLchan *rowA = (const GLchan *) srcRowA;
+ const GLchan *rowB = (const GLchan *) srcRowB;
+ GLchan *dst = (GLchan *) dstRow;
+ for (i = j = 0, k = k0; i < (GLuint) dstWidth;
+ i++, j += colStride, k += colStride) {
+ dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4;
+ }
+ }
+ return;
+ case MESA_FORMAT_LUMINANCE_ALPHA:
+ {
+ GLuint i, j, k;
+ const GLchan (*rowA)[2] = (const GLchan (*)[2]) srcRowA;
+ const GLchan (*rowB)[2] = (const GLchan (*)[2]) srcRowB;
+ GLchan (*dst)[2] = (GLchan (*)[2]) dstRow;
+ for (i = j = 0, k = k0; i < (GLuint) dstWidth;
+ i++, j += colStride, k += colStride) {
+ dst[i][0] = (rowA[j][0] + rowA[k][0] +
+ rowB[j][0] + rowB[k][0]) / 4;
+ dst[i][1] = (rowA[j][1] + rowA[k][1] +
+ rowB[j][1] + rowB[k][1]) / 4;
+ }
+ }
+ return;
+ case MESA_FORMAT_DEPTH_COMPONENT_FLOAT32:
+ {
+ GLuint i, j, k;
+ const GLfloat *rowA = (const GLfloat *) srcRowA;
+ const GLfloat *rowB = (const GLfloat *) srcRowB;
+ GLfloat *dst = (GLfloat *) dstRow;
+ for (i = j = 0, k = k0; i < (GLuint) dstWidth;
+ i++, j += colStride, k += colStride) {
+ dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) * 0.25F;
+ }
+ }
+ return;
+ case MESA_FORMAT_DEPTH_COMPONENT16:
+ {
+ GLuint i, j, k;
+ const GLushort *rowA = (const GLushort *) srcRowA;
+ const GLushort *rowB = (const GLushort *) srcRowB;
+ GLushort *dst = (GLushort *) dstRow;
+ for (i = j = 0, k = k0; i < (GLuint) dstWidth;
+ i++, j += colStride, k += colStride) {
+ dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4;
+ }
+ }
+ return;
+ /* Begin hardware formats */
+ case MESA_FORMAT_RGBA8888:
+ case MESA_FORMAT_RGBA8888_REV:
+ case MESA_FORMAT_ARGB8888:
+ case MESA_FORMAT_ARGB8888_REV:
+ {
+ GLuint i, j, k;
+ const GLubyte (*rowA)[4] = (const GLubyte (*)[4]) srcRowA;
+ const GLubyte (*rowB)[4] = (const GLubyte (*)[4]) srcRowB;
+ GLubyte (*dst)[4] = (GLubyte (*)[4]) dstRow;
+ for (i = j = 0, k = k0; i < (GLuint) dstWidth;
+ i++, j += colStride, k += colStride) {
+ dst[i][0] = (rowA[j][0] + rowA[k][0] +
+ rowB[j][0] + rowB[k][0]) / 4;
+ dst[i][1] = (rowA[j][1] + rowA[k][1] +
+ rowB[j][1] + rowB[k][1]) / 4;
+ dst[i][2] = (rowA[j][2] + rowA[k][2] +
+ rowB[j][2] + rowB[k][2]) / 4;
+ dst[i][3] = (rowA[j][3] + rowA[k][3] +
+ rowB[j][3] + rowB[k][3]) / 4;
+ }
+ }
+ return;
+ case MESA_FORMAT_RGB888:
+ case MESA_FORMAT_BGR888:
+ {
+ GLuint i, j, k;
+ const GLubyte (*rowA)[3] = (const GLubyte (*)[3]) srcRowA;
+ const GLubyte (*rowB)[3] = (const GLubyte (*)[3]) srcRowB;
+ GLubyte (*dst)[3] = (GLubyte (*)[3]) dstRow;
+ for (i = j = 0, k = k0; i < (GLuint) dstWidth;
+ i++, j += colStride, k += colStride) {
+ dst[i][0] = (rowA[j][0] + rowA[k][0] +
+ rowB[j][0] + rowB[k][0]) / 4;
+ dst[i][1] = (rowA[j][1] + rowA[k][1] +
+ rowB[j][1] + rowB[k][1]) / 4;
+ dst[i][2] = (rowA[j][2] + rowA[k][2] +
+ rowB[j][2] + rowB[k][2]) / 4;
+ }
+ }
+ return;
+ case MESA_FORMAT_RGB565:
+ case MESA_FORMAT_RGB565_REV:
+ {
+ GLuint i, j, k;
+ const GLushort *rowA = (const GLushort *) srcRowA;
+ const GLushort *rowB = (const GLushort *) srcRowB;
+ GLushort *dst = (GLushort *) dstRow;
+ for (i = j = 0, k = k0; i < (GLuint) dstWidth;
+ i++, j += colStride, k += colStride) {
+ const GLint rowAr0 = rowA[j] & 0x1f;
+ const GLint rowAr1 = rowA[k] & 0x1f;
+ const GLint rowBr0 = rowB[j] & 0x1f;
+ const GLint rowBr1 = rowB[k] & 0x1f;
+ const GLint rowAg0 = (rowA[j] >> 5) & 0x3f;
+ const GLint rowAg1 = (rowA[k] >> 5) & 0x3f;
+ const GLint rowBg0 = (rowB[j] >> 5) & 0x3f;
+ const GLint rowBg1 = (rowB[k] >> 5) & 0x3f;
+ const GLint rowAb0 = (rowA[j] >> 11) & 0x1f;
+ const GLint rowAb1 = (rowA[k] >> 11) & 0x1f;
+ const GLint rowBb0 = (rowB[j] >> 11) & 0x1f;
+ const GLint rowBb1 = (rowB[k] >> 11) & 0x1f;
+ const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
+ const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
+ const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
+ dst[i] = (blue << 11) | (green << 5) | red;
+ }
+ }
+ return;
+ case MESA_FORMAT_ARGB4444:
+ case MESA_FORMAT_ARGB4444_REV:
+ {
+ GLuint i, j, k;
+ const GLushort *rowA = (const GLushort *) srcRowA;
+ const GLushort *rowB = (const GLushort *) srcRowB;
+ GLushort *dst = (GLushort *) dstRow;
+ for (i = j = 0, k = k0; i < (GLuint) dstWidth;
+ i++, j += colStride, k += colStride) {
+ const GLint rowAr0 = rowA[j] & 0xf;
+ const GLint rowAr1 = rowA[k] & 0xf;
+ const GLint rowBr0 = rowB[j] & 0xf;
+ const GLint rowBr1 = rowB[k] & 0xf;
+ const GLint rowAg0 = (rowA[j] >> 4) & 0xf;
+ const GLint rowAg1 = (rowA[k] >> 4) & 0xf;
+ const GLint rowBg0 = (rowB[j] >> 4) & 0xf;
+ const GLint rowBg1 = (rowB[k] >> 4) & 0xf;
+ const GLint rowAb0 = (rowA[j] >> 8) & 0xf;
+ const GLint rowAb1 = (rowA[k] >> 8) & 0xf;
+ const GLint rowBb0 = (rowB[j] >> 8) & 0xf;
+ const GLint rowBb1 = (rowB[k] >> 8) & 0xf;
+ const GLint rowAa0 = (rowA[j] >> 12) & 0xf;
+ const GLint rowAa1 = (rowA[k] >> 12) & 0xf;
+ const GLint rowBa0 = (rowB[j] >> 12) & 0xf;
+ const GLint rowBa1 = (rowB[k] >> 12) & 0xf;
+ const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
+ const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
+ const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
+ const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2;
+ dst[i] = (alpha << 12) | (blue << 8) | (green << 4) | red;
+ }
+ }
+ return;
+ case MESA_FORMAT_ARGB1555:
+ case MESA_FORMAT_ARGB1555_REV: /* XXX broken? */
+ {
+ GLuint i, j, k;
+ const GLushort *rowA = (const GLushort *) srcRowA;
+ const GLushort *rowB = (const GLushort *) srcRowB;
+ GLushort *dst = (GLushort *) dstRow;
+ for (i = j = 0, k = k0; i < (GLuint) dstWidth;
+ i++, j += colStride, k += colStride) {
+ const GLint rowAr0 = rowA[j] & 0x1f;
+ const GLint rowAr1 = rowA[k] & 0x1f;
+ const GLint rowBr0 = rowB[j] & 0x1f;
+ const GLint rowBr1 = rowB[k] & 0xf;
+ const GLint rowAg0 = (rowA[j] >> 5) & 0x1f;
+ const GLint rowAg1 = (rowA[k] >> 5) & 0x1f;
+ const GLint rowBg0 = (rowB[j] >> 5) & 0x1f;
+ const GLint rowBg1 = (rowB[k] >> 5) & 0x1f;
+ const GLint rowAb0 = (rowA[j] >> 10) & 0x1f;
+ const GLint rowAb1 = (rowA[k] >> 10) & 0x1f;
+ const GLint rowBb0 = (rowB[j] >> 10) & 0x1f;
+ const GLint rowBb1 = (rowB[k] >> 10) & 0x1f;
+ const GLint rowAa0 = (rowA[j] >> 15) & 0x1;
+ const GLint rowAa1 = (rowA[k] >> 15) & 0x1;
+ const GLint rowBa0 = (rowB[j] >> 15) & 0x1;
+ const GLint rowBa1 = (rowB[k] >> 15) & 0x1;
+ const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
+ const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
+ const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
+ const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2;
+ dst[i] = (alpha << 15) | (blue << 10) | (green << 5) | red;
+ }
+ }
+ return;
+ case MESA_FORMAT_AL88:
+ case MESA_FORMAT_AL88_REV:
+ {
+ GLuint i, j, k;
+ const GLubyte (*rowA)[2] = (const GLubyte (*)[2]) srcRowA;
+ const GLubyte (*rowB)[2] = (const GLubyte (*)[2]) srcRowB;
+ GLubyte (*dst)[2] = (GLubyte (*)[2]) dstRow;
+ for (i = j = 0, k = k0; i < (GLuint) dstWidth;
+ i++, j += colStride, k += colStride) {
+ dst[i][0] = (rowA[j][0] + rowA[k][0] +
+ rowB[j][0] + rowB[k][0]) >> 2;
+ dst[i][1] = (rowA[j][1] + rowA[k][1] +
+ rowB[j][1] + rowB[k][1]) >> 2;
+ }
+ }
+ return;
+ case MESA_FORMAT_RGB332:
+ {
+ GLuint i, j, k;
+ const GLubyte *rowA = (const GLubyte *) srcRowA;
+ const GLubyte *rowB = (const GLubyte *) srcRowB;
+ GLubyte *dst = (GLubyte *) dstRow;
+ for (i = j = 0, k = k0; i < (GLuint) dstWidth;
+ i++, j += colStride, k += colStride) {
+ const GLint rowAr0 = rowA[j] & 0x3;
+ const GLint rowAr1 = rowA[k] & 0x3;
+ const GLint rowBr0 = rowB[j] & 0x3;
+ const GLint rowBr1 = rowB[k] & 0x3;
+ const GLint rowAg0 = (rowA[j] >> 2) & 0x7;
+ const GLint rowAg1 = (rowA[k] >> 2) & 0x7;
+ const GLint rowBg0 = (rowB[j] >> 2) & 0x7;
+ const GLint rowBg1 = (rowB[k] >> 2) & 0x7;
+ const GLint rowAb0 = (rowA[j] >> 5) & 0x7;
+ const GLint rowAb1 = (rowA[k] >> 5) & 0x7;
+ const GLint rowBb0 = (rowB[j] >> 5) & 0x7;
+ const GLint rowBb1 = (rowB[k] >> 5) & 0x7;
+ const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
+ const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
+ const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
+ dst[i] = (blue << 5) | (green << 2) | red;
+ }
+ }
+ return;
+ case MESA_FORMAT_A8:
+ case MESA_FORMAT_L8:
+ case MESA_FORMAT_I8:
+ case MESA_FORMAT_CI8:
+ {
+ GLuint i, j, k;
+ const GLubyte *rowA = (const GLubyte *) srcRowA;
+ const GLubyte *rowB = (const GLubyte *) srcRowB;
+ GLubyte *dst = (GLubyte *) dstRow;
+ for (i = j = 0, k = k0; i < (GLuint) dstWidth;
+ i++, j += colStride, k += colStride) {
+ dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) >> 2;
+ }
+ }
+ return;
+ case MESA_FORMAT_RGBA_FLOAT32:
+ {
+ GLuint i, j, k;
+ const GLfloat (*rowA)[4] = (const GLfloat (*)[4]) srcRowA;
+ const GLfloat (*rowB)[4] = (const GLfloat (*)[4]) srcRowB;
+ GLfloat (*dst)[4] = (GLfloat (*)[4]) dstRow;
+ for (i = j = 0, k = k0; i < (GLuint) dstWidth;
+ i++, j += colStride, k += colStride) {
+ dst[i][0] = (rowA[j][0] + rowA[k][0] +
+ rowB[j][0] + rowB[k][0]) * 0.25F;
+ dst[i][1] = (rowA[j][1] + rowA[k][1] +
+ rowB[j][1] + rowB[k][1]) * 0.25F;
+ dst[i][2] = (rowA[j][2] + rowA[k][2] +
+ rowB[j][2] + rowB[k][2]) * 0.25F;
+ dst[i][3] = (rowA[j][3] + rowA[k][3] +
+ rowB[j][3] + rowB[k][3]) * 0.25F;
+ }
+ }
+ return;
+ case MESA_FORMAT_RGBA_FLOAT16:
+ {
+ GLuint i, j, k, comp;
+ const GLhalfARB (*rowA)[4] = (const GLhalfARB (*)[4]) srcRowA;
+ const GLhalfARB (*rowB)[4] = (const GLhalfARB (*)[4]) srcRowB;
+ GLhalfARB (*dst)[4] = (GLhalfARB (*)[4]) dstRow;
+ for (i = j = 0, k = k0; i < (GLuint) dstWidth;
+ i++, j += colStride, k += colStride) {
+ for (comp = 0; comp < 4; comp++) {
+ GLfloat aj, ak, bj, bk;
+ aj = _mesa_half_to_float(rowA[j][comp]);
+ ak = _mesa_half_to_float(rowA[k][comp]);
+ bj = _mesa_half_to_float(rowB[j][comp]);
+ bk = _mesa_half_to_float(rowB[k][comp]);
+ dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
+ }
+ }
+ }
+ return;
+ case MESA_FORMAT_RGB_FLOAT32:
+ {
+ GLuint i, j, k;
+ const GLfloat (*rowA)[3] = (const GLfloat (*)[3]) srcRowA;
+ const GLfloat (*rowB)[3] = (const GLfloat (*)[3]) srcRowB;
+ GLfloat (*dst)[3] = (GLfloat (*)[3]) dstRow;
+ for (i = j = 0, k = k0; i < (GLuint) dstWidth;
+ i++, j += colStride, k += colStride) {
+ dst[i][0] = (rowA[j][0] + rowA[k][0] +
+ rowB[j][0] + rowB[k][0]) * 0.25F;
+ dst[i][1] = (rowA[j][1] + rowA[k][1] +
+ rowB[j][1] + rowB[k][1]) * 0.25F;
+ dst[i][2] = (rowA[j][2] + rowA[k][2] +
+ rowB[j][2] + rowB[k][2]) * 0.25F;
+ }
+ }
+ return;
+ case MESA_FORMAT_RGB_FLOAT16:
+ {
+ GLuint i, j, k, comp;
+ const GLhalfARB (*rowA)[3] = (const GLhalfARB (*)[3]) srcRowA;
+ const GLhalfARB (*rowB)[3] = (const GLhalfARB (*)[3]) srcRowB;
+ GLhalfARB (*dst)[3] = (GLhalfARB (*)[3]) dstRow;
+ for (i = j = 0, k = k0; i < (GLuint) dstWidth;
+ i++, j += colStride, k += colStride) {
+ for (comp = 0; comp < 3; comp++) {
+ GLfloat aj, ak, bj, bk;
+ aj = _mesa_half_to_float(rowA[j][comp]);
+ ak = _mesa_half_to_float(rowA[k][comp]);
+ bj = _mesa_half_to_float(rowB[j][comp]);
+ bk = _mesa_half_to_float(rowB[k][comp]);
+ dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
+ }
+ }
+ }
+ return;
+ case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32:
+ {
+ GLuint i, j, k;
+ const GLfloat (*rowA)[2] = (const GLfloat (*)[2]) srcRowA;
+ const GLfloat (*rowB)[2] = (const GLfloat (*)[2]) srcRowB;
+ GLfloat (*dst)[2] = (GLfloat (*)[2]) dstRow;
+ for (i = j = 0, k = k0; i < (GLuint) dstWidth;
+ i++, j += colStride, k += colStride) {
+ dst[i][0] = (rowA[j][0] + rowA[k][0] +
+ rowB[j][0] + rowB[k][0]) * 0.25F;
+ dst[i][1] = (rowA[j][1] + rowA[k][1] +
+ rowB[j][1] + rowB[k][1]) * 0.25F;
+ }
+ }
+ return;
+ case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16:
+ {
+ GLuint i, j, k, comp;
+ const GLhalfARB (*rowA)[2] = (const GLhalfARB (*)[2]) srcRowA;
+ const GLhalfARB (*rowB)[2] = (const GLhalfARB (*)[2]) srcRowB;
+ GLhalfARB (*dst)[2] = (GLhalfARB (*)[2]) dstRow;
+ for (i = j = 0, k = k0; i < (GLuint) dstWidth;
+ i++, j += colStride, k += colStride) {
+ for (comp = 0; comp < 2; comp++) {
+ GLfloat aj, ak, bj, bk;
+ aj = _mesa_half_to_float(rowA[j][comp]);
+ ak = _mesa_half_to_float(rowA[k][comp]);
+ bj = _mesa_half_to_float(rowB[j][comp]);
+ bk = _mesa_half_to_float(rowB[k][comp]);
+ dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
+ }
+ }
+ }
+ return;
+ case MESA_FORMAT_ALPHA_FLOAT32:
+ case MESA_FORMAT_LUMINANCE_FLOAT32:
+ case MESA_FORMAT_INTENSITY_FLOAT32:
+ {
+ GLuint i, j, k;
+ const GLfloat *rowA = (const GLfloat *) srcRowA;
+ const GLfloat *rowB = (const GLfloat *) srcRowB;
+ GLfloat *dst = (GLfloat *) dstRow;
+ for (i = j = 0, k = k0; i < (GLuint) dstWidth;
+ i++, j += colStride, k += colStride) {
+ dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) * 0.25F;
+ }
+ }
+ return;
+ case MESA_FORMAT_ALPHA_FLOAT16:
+ case MESA_FORMAT_LUMINANCE_FLOAT16:
+ case MESA_FORMAT_INTENSITY_FLOAT16:
+ {
+ GLuint i, j, k;
+ const GLhalfARB *rowA = (const GLhalfARB *) srcRowA;
+ const GLhalfARB *rowB = (const GLhalfARB *) srcRowB;
+ GLhalfARB *dst = (GLhalfARB *) dstRow;
+ for (i = j = 0, k = k0; i < (GLuint) dstWidth;
+ i++, j += colStride, k += colStride) {
+ GLfloat aj, ak, bj, bk;
+ aj = _mesa_half_to_float(rowA[j]);
+ ak = _mesa_half_to_float(rowA[k]);
+ bj = _mesa_half_to_float(rowB[j]);
+ bk = _mesa_half_to_float(rowB[k]);
+ dst[i] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
+ }
+ }
+ return;
+
+ default:
+ _mesa_problem(NULL, "bad format in do_row()");
+ }
+}
+
+
+/*
+ * These functions generate a 1/2-size mipmap image from a source image.
+ * Texture borders are handled by copying or averaging the source image's
+ * border texels, depending on the scale-down factor.
+ */
+
+static void
+make_1d_mipmap(const struct gl_texture_format *format, GLint border,
+ GLint srcWidth, const GLubyte *srcPtr,
+ GLint dstWidth, GLubyte *dstPtr)
+{
+ const GLint bpt = format->TexelBytes;
+ const GLubyte *src;
+ GLubyte *dst;
+
+ /* skip the border pixel, if any */
+ src = srcPtr + border * bpt;
+ dst = dstPtr + border * bpt;
+
+ /* we just duplicate the input row, kind of hack, saves code */
+ do_row(format, srcWidth - 2 * border, src, src,
+ dstWidth - 2 * border, dst);
+
+ if (border) {
+ /* copy left-most pixel from source */
+ MEMCPY(dstPtr, srcPtr, bpt);
+ /* copy right-most pixel from source */
+ MEMCPY(dstPtr + (dstWidth - 1) * bpt,
+ srcPtr + (srcWidth - 1) * bpt,
+ bpt);
+ }
+}
+
+
+static void
+make_2d_mipmap(const struct gl_texture_format *format, GLint border,
+ GLint srcWidth, GLint srcHeight, const GLubyte *srcPtr,
+ GLint dstWidth, GLint dstHeight, GLubyte *dstPtr)
+{
+ const GLint bpt = format->TexelBytes;
+ const GLint srcWidthNB = srcWidth - 2 * border; /* sizes w/out border */
+ const GLint dstWidthNB = dstWidth - 2 * border;
+ const GLint dstHeightNB = dstHeight - 2 * border;
+ const GLint srcRowStride = bpt * srcWidth;
+ const GLint dstRowStride = bpt * dstWidth;
+ const GLubyte *srcA, *srcB;
+ GLubyte *dst;
+ GLint row;
+
+ /* Compute src and dst pointers, skipping any border */
+ srcA = srcPtr + border * ((srcWidth + 1) * bpt);
+ if (srcHeight > 1)
+ srcB = srcA + srcRowStride;
+ else
+ srcB = srcA;
+ dst = dstPtr + border * ((dstWidth + 1) * bpt);
+
+ for (row = 0; row < dstHeightNB; row++) {
+ do_row(format, srcWidthNB, srcA, srcB,
+ dstWidthNB, dst);
+ srcA += 2 * srcRowStride;
+ srcB += 2 * srcRowStride;
+ dst += dstRowStride;
+ }
+
+ /* This is ugly but probably won't be used much */
+ if (border > 0) {
+ /* fill in dest border */
+ /* lower-left border pixel */
+ MEMCPY(dstPtr, srcPtr, bpt);
+ /* lower-right border pixel */
+ MEMCPY(dstPtr + (dstWidth - 1) * bpt,
+ srcPtr + (srcWidth - 1) * bpt, bpt);
+ /* upper-left border pixel */
+ MEMCPY(dstPtr + dstWidth * (dstHeight - 1) * bpt,
+ srcPtr + srcWidth * (srcHeight - 1) * bpt, bpt);
+ /* upper-right border pixel */
+ MEMCPY(dstPtr + (dstWidth * dstHeight - 1) * bpt,
+ srcPtr + (srcWidth * srcHeight - 1) * bpt, bpt);
+ /* lower border */
+ do_row(format, srcWidthNB,
+ srcPtr + bpt,
+ srcPtr + bpt,
+ dstWidthNB, dstPtr + bpt);
+ /* upper border */
+ do_row(format, srcWidthNB,
+ srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt,
+ srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt,
+ dstWidthNB,
+ dstPtr + (dstWidth * (dstHeight - 1) + 1) * bpt);
+ /* left and right borders */
+ if (srcHeight == dstHeight) {
+ /* copy border pixel from src to dst */
+ for (row = 1; row < srcHeight; row++) {
+ MEMCPY(dstPtr + dstWidth * row * bpt,
+ srcPtr + srcWidth * row * bpt, bpt);
+ MEMCPY(dstPtr + (dstWidth * row + dstWidth - 1) * bpt,
+ srcPtr + (srcWidth * row + srcWidth - 1) * bpt, bpt);
+ }
+ }
+ else {
+ /* average two src pixels each dest pixel */
+ for (row = 0; row < dstHeightNB; row += 2) {
+ do_row(format, 1,
+ srcPtr + (srcWidth * (row * 2 + 1)) * bpt,
+ srcPtr + (srcWidth * (row * 2 + 2)) * bpt,
+ 1, dstPtr + (dstWidth * row + 1) * bpt);
+ do_row(format, 1,
+ srcPtr + (srcWidth * (row * 2 + 1) + srcWidth - 1) * bpt,
+ srcPtr + (srcWidth * (row * 2 + 2) + srcWidth - 1) * bpt,
+ 1, dstPtr + (dstWidth * row + 1 + dstWidth - 1) * bpt);
+ }
+ }
+ }
+}
+
+
+static void
+make_3d_mipmap(const struct gl_texture_format *format, GLint border,
+ GLint srcWidth, GLint srcHeight, GLint srcDepth,
+ const GLubyte *srcPtr,
+ GLint dstWidth, GLint dstHeight, GLint dstDepth,
+ GLubyte *dstPtr)
+{
+ const GLint bpt = format->TexelBytes;
+ const GLint srcWidthNB = srcWidth - 2 * border; /* sizes w/out border */
+ const GLint srcDepthNB = srcDepth - 2 * border;
+ const GLint dstWidthNB = dstWidth - 2 * border;
+ const GLint dstHeightNB = dstHeight - 2 * border;
+ const GLint dstDepthNB = dstDepth - 2 * border;
+ GLvoid *tmpRowA, *tmpRowB;
+ GLint img, row;
+ GLint bytesPerSrcImage, bytesPerDstImage;
+ GLint bytesPerSrcRow, bytesPerDstRow;
+ GLint srcImageOffset, srcRowOffset;
+
+ (void) srcDepthNB; /* silence warnings */
+
+ /* Need two temporary row buffers */
+ tmpRowA = _mesa_malloc(srcWidth * bpt);
+ if (!tmpRowA)
+ return;
+ tmpRowB = _mesa_malloc(srcWidth * bpt);
+ if (!tmpRowB) {
+ _mesa_free(tmpRowA);
+ return;
+ }
+
+ bytesPerSrcImage = srcWidth * srcHeight * bpt;
+ bytesPerDstImage = dstWidth * dstHeight * bpt;
+
+ bytesPerSrcRow = srcWidth * bpt;
+ bytesPerDstRow = dstWidth * bpt;
+
+ /* Offset between adjacent src images to be averaged together */
+ srcImageOffset = (srcDepth == dstDepth) ? 0 : bytesPerSrcImage;
+
+ /* Offset between adjacent src rows to be averaged together */
+ srcRowOffset = (srcHeight == dstHeight) ? 0 : srcWidth * bpt;
+
+ /*
+ * Need to average together up to 8 src pixels for each dest pixel.
+ * Break that down into 3 operations:
+ * 1. take two rows from source image and average them together.
+ * 2. take two rows from next source image and average them together.
+ * 3. take the two averaged rows and average them for the final dst row.
+ */
+
+ /*
+ _mesa_printf("mip3d %d x %d x %d -> %d x %d x %d\n",
+ srcWidth, srcHeight, srcDepth, dstWidth, dstHeight, dstDepth);
+ */
+
+ for (img = 0; img < dstDepthNB; img++) {
+ /* first source image pointer, skipping border */
+ const GLubyte *imgSrcA = srcPtr
+ + (bytesPerSrcImage + bytesPerSrcRow + border) * bpt * border
+ + img * (bytesPerSrcImage + srcImageOffset);
+ /* second source image pointer, skipping border */
+ const GLubyte *imgSrcB = imgSrcA + srcImageOffset;
+ /* address of the dest image, skipping border */
+ GLubyte *imgDst = dstPtr
+ + (bytesPerDstImage + bytesPerDstRow + border) * bpt * border
+ + img * bytesPerDstImage;
+
+ /* setup the four source row pointers and the dest row pointer */
+ const GLubyte *srcImgARowA = imgSrcA;
+ const GLubyte *srcImgARowB = imgSrcA + srcRowOffset;
+ const GLubyte *srcImgBRowA = imgSrcB;
+ const GLubyte *srcImgBRowB = imgSrcB + srcRowOffset;
+ GLubyte *dstImgRow = imgDst;
+
+ for (row = 0; row < dstHeightNB; row++) {
+ /* Average together two rows from first src image */
+ do_row(format, srcWidthNB, srcImgARowA, srcImgARowB,
+ srcWidthNB, tmpRowA);
+ /* Average together two rows from second src image */
+ do_row(format, srcWidthNB, srcImgBRowA, srcImgBRowB,
+ srcWidthNB, tmpRowB);
+ /* Average together the temp rows to make the final row */
+ do_row(format, srcWidthNB, tmpRowA, tmpRowB,
+ dstWidthNB, dstImgRow);
+ /* advance to next rows */
+ srcImgARowA += bytesPerSrcRow + srcRowOffset;
+ srcImgARowB += bytesPerSrcRow + srcRowOffset;
+ srcImgBRowA += bytesPerSrcRow + srcRowOffset;
+ srcImgBRowB += bytesPerSrcRow + srcRowOffset;
+ dstImgRow += bytesPerDstRow;
+ }
+ }
+
+ _mesa_free(tmpRowA);
+ _mesa_free(tmpRowB);
+
+ /* Luckily we can leverage the make_2d_mipmap() function here! */
+ if (border > 0) {
+ /* do front border image */
+ make_2d_mipmap(format, 1, srcWidth, srcHeight, srcPtr,
+ dstWidth, dstHeight, dstPtr);
+ /* do back border image */
+ make_2d_mipmap(format, 1, srcWidth, srcHeight,
+ srcPtr + bytesPerSrcImage * (srcDepth - 1),
+ dstWidth, dstHeight,
+ dstPtr + bytesPerDstImage * (dstDepth - 1));
+ /* do four remaining border edges that span the image slices */
+ if (srcDepth == dstDepth) {
+ /* just copy border pixels from src to dst */
+ for (img = 0; img < dstDepthNB; img++) {
+ const GLubyte *src;
+ GLubyte *dst;
+
+ /* do border along [img][row=0][col=0] */
+ src = srcPtr + (img + 1) * bytesPerSrcImage;
+ dst = dstPtr + (img + 1) * bytesPerDstImage;
+ MEMCPY(dst, src, bpt);
+
+ /* do border along [img][row=dstHeight-1][col=0] */
+ src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
+ + (srcHeight - 1) * bytesPerSrcRow;
+ dst = dstPtr + (img + 1) * bytesPerDstImage
+ + (dstHeight - 1) * bytesPerDstRow;
+ MEMCPY(dst, src, bpt);
+
+ /* do border along [img][row=0][col=dstWidth-1] */
+ src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
+ + (srcWidth - 1) * bpt;
+ dst = dstPtr + (img + 1) * bytesPerDstImage
+ + (dstWidth - 1) * bpt;
+ MEMCPY(dst, src, bpt);
+
+ /* do border along [img][row=dstHeight-1][col=dstWidth-1] */
+ src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
+ + (bytesPerSrcImage - bpt);
+ dst = dstPtr + (img + 1) * bytesPerDstImage
+ + (bytesPerDstImage - bpt);
+ MEMCPY(dst, src, bpt);
+ }
+ }
+ else {
+ /* average border pixels from adjacent src image pairs */
+ ASSERT(srcDepthNB == 2 * dstDepthNB);
+ for (img = 0; img < dstDepthNB; img++) {
+ const GLubyte *src;
+ GLubyte *dst;
+
+ /* do border along [img][row=0][col=0] */
+ src = srcPtr + (img * 2 + 1) * bytesPerSrcImage;
+ dst = dstPtr + (img + 1) * bytesPerDstImage;
+ do_row(format, 1, src, src + srcImageOffset, 1, dst);
+
+ /* do border along [img][row=dstHeight-1][col=0] */
+ src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
+ + (srcHeight - 1) * bytesPerSrcRow;
+ dst = dstPtr + (img + 1) * bytesPerDstImage
+ + (dstHeight - 1) * bytesPerDstRow;
+ do_row(format, 1, src, src + srcImageOffset, 1, dst);
+
+ /* do border along [img][row=0][col=dstWidth-1] */
+ src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
+ + (srcWidth - 1) * bpt;
+ dst = dstPtr + (img + 1) * bytesPerDstImage
+ + (dstWidth - 1) * bpt;
+ do_row(format, 1, src, src + srcImageOffset, 1, dst);
+
+ /* do border along [img][row=dstHeight-1][col=dstWidth-1] */
+ src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
+ + (bytesPerSrcImage - bpt);
+ dst = dstPtr + (img + 1) * bytesPerDstImage
+ + (bytesPerDstImage - bpt);
+ do_row(format, 1, src, src + srcImageOffset, 1, dst);
+ }
+ }
+ }
+}
+
+
+/*
+ * For GL_SGIX_generate_mipmap:
+ * Generate a complete set of mipmaps from texObj's base-level image.
+ * Stop at texObj's MaxLevel or when we get to the 1x1 texture.
+ */
+void
+_mesa_generate_mipmap(GLcontext *ctx, GLenum target,
+ const struct gl_texture_unit *texUnit,
+ struct gl_texture_object *texObj)
+{
+ const struct gl_texture_image *srcImage;
+ const struct gl_texture_format *convertFormat;
+ const GLubyte *srcData = NULL;
+ GLubyte *dstData = NULL;
+ GLint level, maxLevels;
+
+ ASSERT(texObj);
+ /* XXX choose cube map face here??? */
+ srcImage = texObj->Image[0][texObj->BaseLevel];
+ ASSERT(srcImage);
+
+ maxLevels = _mesa_max_texture_levels(ctx, texObj->Target);
+ ASSERT(maxLevels > 0); /* bad target */
+
+ /* Find convertFormat - the format that do_row() will process */
+ if (srcImage->IsCompressed) {
+ /* setup for compressed textures */
+ GLuint row;
+ GLint components, size;
+ GLchan *dst;
+
+ assert(texObj->Target == GL_TEXTURE_2D);
+
+ if (srcImage->_BaseFormat == GL_RGB) {
+ convertFormat = &_mesa_texformat_rgb;
+ components = 3;
+ }
+ else if (srcImage->_BaseFormat == GL_RGBA) {
+ convertFormat = &_mesa_texformat_rgba;
+ components = 4;
+ }
+ else {
+ _mesa_problem(ctx, "bad srcImage->_BaseFormat in _mesa_generate_mipmaps");
+ return;
+ }
+
+ /* allocate storage for uncompressed GL_RGB or GL_RGBA images */
+ size = _mesa_bytes_per_pixel(srcImage->_BaseFormat, CHAN_TYPE)
+ * srcImage->Width * srcImage->Height * srcImage->Depth + 20;
+ /* 20 extra bytes, just be safe when calling last FetchTexel */
+ srcData = (GLubyte *) _mesa_malloc(size);
+ if (!srcData) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps");
+ return;
+ }
+ dstData = (GLubyte *) _mesa_malloc(size / 2); /* 1/4 would probably be OK */
+ if (!dstData) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps");
+ _mesa_free((void *) srcData);
+ return;
+ }
+
+ /* decompress base image here */
+ dst = (GLchan *) srcData;
+ for (row = 0; row < srcImage->Height; row++) {
+ GLuint col;
+ for (col = 0; col < srcImage->Width; col++) {
+ srcImage->FetchTexelc(srcImage, col, row, 0, dst);
+ dst += components;
+ }
+ }
+ }
+ else {
+ /* uncompressed */
+ convertFormat = srcImage->TexFormat;
+ }
+
+ for (level = texObj->BaseLevel; level < texObj->MaxLevel
+ && level < maxLevels - 1; level++) {
+ /* generate image[level+1] from image[level] */
+ const struct gl_texture_image *srcImage;
+ struct gl_texture_image *dstImage;
+ GLint srcWidth, srcHeight, srcDepth;
+ GLint dstWidth, dstHeight, dstDepth;
+ GLint border, bytesPerTexel;
+
+ /* get src image parameters */
+ srcImage = _mesa_select_tex_image(ctx, texUnit, target, level);
+ ASSERT(srcImage);
+ srcWidth = srcImage->Width;
+ srcHeight = srcImage->Height;
+ srcDepth = srcImage->Depth;
+ border = srcImage->Border;
+
+ /* compute next (level+1) image size */
+ if (srcWidth - 2 * border > 1) {
+ dstWidth = (srcWidth - 2 * border) / 2 + 2 * border;
+ }
+ else {
+ dstWidth = srcWidth; /* can't go smaller */
+ }
+ if (srcHeight - 2 * border > 1) {
+ dstHeight = (srcHeight - 2 * border) / 2 + 2 * border;
+ }
+ else {
+ dstHeight = srcHeight; /* can't go smaller */
+ }
+ if (srcDepth - 2 * border > 1) {
+ dstDepth = (srcDepth - 2 * border) / 2 + 2 * border;
+ }
+ else {
+ dstDepth = srcDepth; /* can't go smaller */
+ }
+
+ if (dstWidth == srcWidth &&
+ dstHeight == srcHeight &&
+ dstDepth == srcDepth) {
+ /* all done */
+ if (srcImage->IsCompressed) {
+ _mesa_free((void *) srcData);
+ _mesa_free(dstData);
+ }
+ return;
+ }
+
+ /* get dest gl_texture_image */
+ dstImage = _mesa_get_tex_image(ctx, texUnit, target, level + 1);
+ if (!dstImage) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
+ return;
+ }
+
+ /* Free old image data */
+ if (dstImage->Data)
+ ctx->Driver.FreeTexImageData(ctx, dstImage);
+
+ /* initialize new image */
+ _mesa_init_teximage_fields(ctx, target, dstImage, dstWidth, dstHeight,
+ dstDepth, border, srcImage->InternalFormat);
+ dstImage->DriverData = NULL;
+ dstImage->TexFormat = srcImage->TexFormat;
+ dstImage->FetchTexelc = srcImage->FetchTexelc;
+ dstImage->FetchTexelf = srcImage->FetchTexelf;
+ ASSERT(dstImage->TexFormat);
+ ASSERT(dstImage->FetchTexelc);
+ ASSERT(dstImage->FetchTexelf);
+
+ /* Alloc new teximage data buffer.
+ * Setup src and dest data pointers.
+ */
+ if (dstImage->IsCompressed) {
+ ASSERT(dstImage->CompressedSize > 0); /* set by init_teximage_fields*/
+ dstImage->Data = _mesa_alloc_texmemory(dstImage->CompressedSize);
+ if (!dstImage->Data) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
+ return;
+ }
+ /* srcData and dstData are already set */
+ ASSERT(srcData);
+ ASSERT(dstData);
+ }
+ else {
+ bytesPerTexel = srcImage->TexFormat->TexelBytes;
+ ASSERT(dstWidth * dstHeight * dstDepth * bytesPerTexel > 0);
+ dstImage->Data = _mesa_alloc_texmemory(dstWidth * dstHeight
+ * dstDepth * bytesPerTexel);
+ if (!dstImage->Data) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
+ return;
+ }
+ srcData = (const GLubyte *) srcImage->Data;
+ dstData = (GLubyte *) dstImage->Data;
+ }
+
+ /*
+ * We use simple 2x2 averaging to compute the next mipmap level.
+ */
+ switch (target) {
+ case GL_TEXTURE_1D:
+ make_1d_mipmap(convertFormat, border,
+ srcWidth, srcData,
+ dstWidth, dstData);
+ break;
+ case GL_TEXTURE_2D:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
+ make_2d_mipmap(convertFormat, border,
+ srcWidth, srcHeight, srcData,
+ dstWidth, dstHeight, dstData);
+ break;
+ case GL_TEXTURE_3D:
+ make_3d_mipmap(convertFormat, border,
+ srcWidth, srcHeight, srcDepth, srcData,
+ dstWidth, dstHeight, dstDepth, dstData);
+ break;
+ case GL_TEXTURE_RECTANGLE_NV:
+ /* no mipmaps, do nothing */
+ break;
+ default:
+ _mesa_problem(ctx, "bad dimensions in _mesa_generate_mipmaps");
+ return;
+ }
+
+ if (dstImage->IsCompressed) {
+ GLubyte *temp;
+ /* compress image from dstData into dstImage->Data */
+ const GLenum srcFormat = convertFormat->BaseFormat;
+ GLint dstRowStride
+ = _mesa_compressed_row_stride(srcImage->InternalFormat, dstWidth);
+ ASSERT(srcFormat == GL_RGB || srcFormat == GL_RGBA);
+ dstImage->TexFormat->StoreImage(ctx, 2, dstImage->_BaseFormat,
+ dstImage->TexFormat,
+ dstImage->Data,
+ 0, 0, 0, /* dstX/Y/Zoffset */
+ dstRowStride, 0, /* strides */
+ dstWidth, dstHeight, 1, /* size */
+ srcFormat, CHAN_TYPE,
+ dstData, /* src data, actually */
+ &ctx->DefaultPacking);
+ /* swap src and dest pointers */
+ temp = (GLubyte *) srcData;
+ srcData = dstData;
+ dstData = temp;
+ }
+
+ } /* loop over mipmap levels */
+}
+
+
+/**
+ * Helper function for drivers which need to rescale texture images to
+ * certain aspect ratios.
+ * Nearest filtering only (for broken hardware that can't support
+ * all aspect ratios). This can be made a lot faster, but I don't
+ * really care enough...
+ */
+void
+_mesa_rescale_teximage2d (GLuint bytesPerPixel,
+ GLuint srcStrideInPixels,
+ GLuint dstRowStride,
+ GLint srcWidth, GLint srcHeight,
+ GLint dstWidth, GLint dstHeight,
+ const GLvoid *srcImage, GLvoid *dstImage)
+{
+ GLint row, col;
+
+#define INNER_LOOP( TYPE, HOP, WOP ) \
+ for ( row = 0 ; row < dstHeight ; row++ ) { \
+ GLint srcRow = row HOP hScale; \
+ for ( col = 0 ; col < dstWidth ; col++ ) { \
+ GLint srcCol = col WOP wScale; \
+ dst[col] = src[srcRow * srcStrideInPixels + srcCol]; \
+ } \
+ dst = (TYPE *) ((GLubyte *) dst + dstRowStride); \
+ } \
+
+#define RESCALE_IMAGE( TYPE ) \
+do { \
+ const TYPE *src = (const TYPE *)srcImage; \
+ TYPE *dst = (TYPE *)dstImage; \
+ \
+ if ( srcHeight < dstHeight ) { \
+ const GLint hScale = dstHeight / srcHeight; \
+ if ( srcWidth < dstWidth ) { \
+ const GLint wScale = dstWidth / srcWidth; \
+ INNER_LOOP( TYPE, /, / ); \
+ } \
+ else { \
+ const GLint wScale = srcWidth / dstWidth; \
+ INNER_LOOP( TYPE, /, * ); \
+ } \
+ } \
+ else { \
+ const GLint hScale = srcHeight / dstHeight; \
+ if ( srcWidth < dstWidth ) { \
+ const GLint wScale = dstWidth / srcWidth; \
+ INNER_LOOP( TYPE, *, / ); \
+ } \
+ else { \
+ const GLint wScale = srcWidth / dstWidth; \
+ INNER_LOOP( TYPE, *, * ); \
+ } \
+ } \
+} while (0)
+
+ switch ( bytesPerPixel ) {
+ case 4:
+ RESCALE_IMAGE( GLuint );
+ break;
+
+ case 2:
+ RESCALE_IMAGE( GLushort );
+ break;
+
+ case 1:
+ RESCALE_IMAGE( GLubyte );
+ break;
+ default:
+ _mesa_problem(NULL,"unexpected bytes/pixel in _mesa_rescale_teximage2d");
+ }
+}
+
+
+/**
+ * Upscale an image by replication, not (typical) stretching.
+ * We use this when the image width or height is less than a
+ * certain size (4, 8) and we need to upscale an image.
+ */
+void
+_mesa_upscale_teximage2d (GLsizei inWidth, GLsizei inHeight,
+ GLsizei outWidth, GLsizei outHeight,
+ GLint comps, const GLchan *src, GLint srcRowStride,
+ GLchan *dest )
+{
+ GLint i, j, k;
+
+ ASSERT(outWidth >= inWidth);
+ ASSERT(outHeight >= inHeight);
+#if 0
+ ASSERT(inWidth == 1 || inWidth == 2 || inHeight == 1 || inHeight == 2);
+ ASSERT((outWidth & 3) == 0);
+ ASSERT((outHeight & 3) == 0);
+#endif
+
+ for (i = 0; i < outHeight; i++) {
+ const GLint ii = i % inHeight;
+ for (j = 0; j < outWidth; j++) {
+ const GLint jj = j % inWidth;
+ for (k = 0; k < comps; k++) {
+ dest[(i * outWidth + j) * comps + k]
+ = src[ii * srcRowStride + jj * comps + k];
+ }
+ }
+ }
+}
+
+
+
+/**
+ * This is the software fallback for Driver.GetTexImage().
+ * All error checking will have been done before this routine is called.
+ */
+void
+_mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level,
+ GLenum format, GLenum type, GLvoid *pixels,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ GLuint dimensions = (target == GL_TEXTURE_3D) ? 3 : 2;
+
+ if (ctx->Pack.BufferObj->Name) {
+ /* pack texture image into a PBO */
+ GLubyte *buf;
+ if (!_mesa_validate_pbo_access(dimensions, &ctx->Pack, texImage->Width,
+ texImage->Height, texImage->Depth,
+ format, type, pixels)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetTexImage(invalid PBO access)");
+ return;
+ }
+ buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
+ GL_WRITE_ONLY_ARB,
+ ctx->Pack.BufferObj);
+ if (!buf) {
+ /* buffer is already mapped - that's an error */
+ _mesa_error(ctx, GL_INVALID_OPERATION,"glGetTexImage(PBO is mapped)");
+ return;
+ }
+ pixels = ADD_POINTERS(buf, pixels);
+ }
+ else if (!pixels) {
+ /* not an error */
+ return;
+ }
+
+ {
+ const GLint width = texImage->Width;
+ const GLint height = texImage->Height;
+ const GLint depth = texImage->Depth;
+ GLint img, row;
+ for (img = 0; img < depth; img++) {
+ for (row = 0; row < height; row++) {
+ /* compute destination address in client memory */
+ GLvoid *dest = _mesa_image_address( dimensions, &ctx->Pack, pixels,
+ width, height, format, type,
+ img, row, 0);
+ assert(dest);
+
+ if (format == GL_COLOR_INDEX) {
+ GLuint indexRow[MAX_WIDTH];
+ GLint col;
+ /* Can't use FetchTexel here because that returns RGBA */
+ if (texImage->TexFormat->IndexBits == 8) {
+ const GLubyte *src = (const GLubyte *) texImage->Data;
+ src += width * (img * texImage->Height + row);
+ for (col = 0; col < width; col++) {
+ indexRow[col] = src[col];
+ }
+ }
+ else if (texImage->TexFormat->IndexBits == 16) {
+ const GLushort *src = (const GLushort *) texImage->Data;
+ src += width * (img * texImage->Height + row);
+ for (col = 0; col < width; col++) {
+ indexRow[col] = src[col];
+ }
+ }
+ else {
+ _mesa_problem(ctx,
+ "Color index problem in _mesa_GetTexImage");
+ }
+ _mesa_pack_index_span(ctx, width, type, dest,
+ indexRow, &ctx->Pack,
+ 0 /* no image transfer */);
+ }
+ else if (format == GL_DEPTH_COMPONENT) {
+ GLfloat depthRow[MAX_WIDTH];
+ GLint col;
+ for (col = 0; col < width; col++) {
+ (*texImage->FetchTexelf)(texImage, col, row, img,
+ depthRow + col);
+ }
+ _mesa_pack_depth_span(ctx, width, dest, type,
+ depthRow, &ctx->Pack);
+ }
+ else if (format == GL_DEPTH_STENCIL_EXT) {
+ /* XXX Note: we're bypassing texImage->FetchTexel()! */
+ const GLuint *src = (const GLuint *) texImage->Data;
+ src += width * row + width * height * img;
+ _mesa_memcpy(dest, src, width * sizeof(GLuint));
+ if (ctx->Pack.SwapBytes) {
+ _mesa_swap4((GLuint *) dest, width);
+ }
+ }
+ else if (format == GL_YCBCR_MESA) {
+ /* No pixel transfer */
+ const GLint rowstride = texImage->RowStride;
+ MEMCPY(dest,
+ (const GLushort *) texImage->Data + row * rowstride,
+ width * sizeof(GLushort));
+ /* check for byte swapping */
+ if ((texImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR
+ && type == GL_UNSIGNED_SHORT_8_8_REV_MESA) ||
+ (texImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR_REV
+ && type == GL_UNSIGNED_SHORT_8_8_MESA)) {
+ if (!ctx->Pack.SwapBytes)
+ _mesa_swap2((GLushort *) dest, width);
+ }
+ else if (ctx->Pack.SwapBytes) {
+ _mesa_swap2((GLushort *) dest, width);
+ }
+ }
+ else {
+ /* general case: convert row to RGBA format */
+ GLfloat rgba[MAX_WIDTH][4];
+ GLint col;
+ for (col = 0; col < width; col++) {
+ (*texImage->FetchTexelf)(texImage, col, row, img, rgba[col]);
+ }
+ _mesa_pack_rgba_span_float(ctx, width,
+ (const GLfloat (*)[4]) rgba,
+ format, type, dest, &ctx->Pack,
+ 0 /* no image transfer */);
+ } /* format */
+ } /* row */
+ } /* img */
+ }
+
+ if (ctx->Pack.BufferObj->Name) {
+ ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
+ ctx->Pack.BufferObj);
+ }
+}
+
+
+
+/**
+ * This is the software fallback for Driver.GetCompressedTexImage().
+ * All error checking will have been done before this routine is called.
+ */
+void
+_mesa_get_compressed_teximage(GLcontext *ctx, GLenum target, GLint level,
+ GLvoid *img,
+ const struct gl_texture_object *texObj,
+ const struct gl_texture_image *texImage)
+{
+ if (ctx->Pack.BufferObj->Name) {
+ /* pack texture image into a PBO */
+ GLubyte *buf;
+ if ((const GLubyte *) img + texImage->CompressedSize >
+ (const GLubyte *) ctx->Pack.BufferObj->Size) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetCompressedTexImage(invalid PBO access)");
+ return;
+ }
+ buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
+ GL_WRITE_ONLY_ARB,
+ ctx->Pack.BufferObj);
+ if (!buf) {
+ /* buffer is already mapped - that's an error */
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetCompressedTexImage(PBO is mapped)");
+ return;
+ }
+ img = ADD_POINTERS(buf, img);
+ }
+ else if (!img) {
+ /* not an error */
+ return;
+ }
+
+ /* just memcpy, no pixelstore or pixel transfer */
+ MEMCPY(img, texImage->Data, texImage->CompressedSize);
+
+ if (ctx->Pack.BufferObj->Name) {
+ ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
+ ctx->Pack.BufferObj);
+ }
+}
diff --git a/src/mesa/main/texstore.h b/src/mesa/main/texstore.h
new file mode 100644
index 00000000000..b71bae24eb1
--- /dev/null
+++ b/src/mesa/main/texstore.h
@@ -0,0 +1,262 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/**
+ * \file texstore.h
+ * Texture image storage routines.
+ *
+ * \author Brian Paul
+ */
+
+
+#ifndef TEXSTORE_H
+#define TEXSTORE_H
+
+
+#include "mtypes.h"
+
+/* Macro just to save some typing */
+#define STORE_PARAMS \
+ GLcontext *ctx, GLuint dims, \
+ GLenum baseInternalFormat, \
+ const struct gl_texture_format *dstFormat, \
+ GLvoid *dstAddr, \
+ GLint dstXoffset, GLint dstYoffset, GLint dstZoffset, \
+ GLint dstRowStride, GLint dstImageStride, \
+ GLint srcWidth, GLint srcHeight, GLint srcDepth, \
+ GLenum srcFormat, GLenum srcType, \
+ const GLvoid *srcAddr, \
+ const struct gl_pixelstore_attrib *srcPacking
+
+
+extern GLboolean _mesa_texstore_rgba(STORE_PARAMS);
+extern GLboolean _mesa_texstore_color_index(STORE_PARAMS);
+extern GLboolean _mesa_texstore_depth_component16(STORE_PARAMS);
+extern GLboolean _mesa_texstore_depth_component_float32(STORE_PARAMS);
+extern GLboolean _mesa_texstore_rgba8888(STORE_PARAMS);
+extern GLboolean _mesa_texstore_argb8888(STORE_PARAMS);
+extern GLboolean _mesa_texstore_rgb888(STORE_PARAMS);
+extern GLboolean _mesa_texstore_bgr888(STORE_PARAMS);
+extern GLboolean _mesa_texstore_rgb565(STORE_PARAMS);
+extern GLboolean _mesa_texstore_rgb565_rev(STORE_PARAMS);
+extern GLboolean _mesa_texstore_argb4444(STORE_PARAMS);
+extern GLboolean _mesa_texstore_argb4444_rev(STORE_PARAMS);
+extern GLboolean _mesa_texstore_argb1555(STORE_PARAMS);
+extern GLboolean _mesa_texstore_argb1555_rev(STORE_PARAMS);
+extern GLboolean _mesa_texstore_al88(STORE_PARAMS);
+extern GLboolean _mesa_texstore_al88_rev(STORE_PARAMS);
+extern GLboolean _mesa_texstore_rgb332(STORE_PARAMS);
+extern GLboolean _mesa_texstore_a8(STORE_PARAMS);
+extern GLboolean _mesa_texstore_ci8(STORE_PARAMS);
+extern GLboolean _mesa_texstore_ycbcr(STORE_PARAMS);
+extern GLboolean _mesa_texstore_z24_s8(STORE_PARAMS);
+extern GLboolean _mesa_texstore_rgba_float32(STORE_PARAMS);
+extern GLboolean _mesa_texstore_rgba_float16(STORE_PARAMS);
+extern GLboolean _mesa_texstore_rgb_fxt1(STORE_PARAMS);
+extern GLboolean _mesa_texstore_rgba_fxt1(STORE_PARAMS);
+extern GLboolean _mesa_texstore_rgb_dxt1(STORE_PARAMS);
+extern GLboolean _mesa_texstore_rgba_dxt1(STORE_PARAMS);
+extern GLboolean _mesa_texstore_rgba_dxt3(STORE_PARAMS);
+extern GLboolean _mesa_texstore_rgba_dxt5(STORE_PARAMS);
+
+
+extern GLchan *
+_mesa_make_temp_chan_image(GLcontext *ctx, GLuint dims,
+ GLenum logicalBaseFormat,
+ GLenum textureBaseFormat,
+ GLint srcWidth, GLint srcHeight, GLint srcDepth,
+ GLenum srcFormat, GLenum srcType,
+ const GLvoid *srcAddr,
+ const struct gl_pixelstore_attrib *srcPacking);
+
+
+extern void
+_mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint border,
+ GLenum format, GLenum type, const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage);
+
+
+extern void
+_mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint height, GLint border,
+ GLenum format, GLenum type, const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage);
+
+
+extern void
+_mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint height, GLint depth, GLint border,
+ GLenum format, GLenum type, const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage);
+
+
+extern void
+_mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
+ GLint xoffset, GLint width,
+ GLenum format, GLenum type, const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage);
+
+
+extern void
+_mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLint width, GLint height,
+ GLenum format, GLenum type, const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage);
+
+
+extern void
+_mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLint width, GLint height, GLint depth,
+ GLenum format, GLenum type, const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage);
+
+
+extern void
+_mesa_store_compressed_teximage1d(GLcontext *ctx, GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint border,
+ GLsizei imageSize, const GLvoid *data,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage);
+
+extern void
+_mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint height, GLint border,
+ GLsizei imageSize, const GLvoid *data,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage);
+
+extern void
+_mesa_store_compressed_teximage3d(GLcontext *ctx, GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint height, GLint depth,
+ GLint border,
+ GLsizei imageSize, const GLvoid *data,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage);
+
+
+extern void
+_mesa_store_compressed_texsubimage1d(GLcontext *ctx, GLenum target,
+ GLint level,
+ GLint xoffset, GLsizei width,
+ GLenum format,
+ GLsizei imageSize, const GLvoid *data,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage);
+
+extern void
+_mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target,
+ GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLenum format,
+ GLsizei imageSize, const GLvoid *data,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage);
+
+extern void
+_mesa_store_compressed_texsubimage3d(GLcontext *ctx, GLenum target,
+ GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format,
+ GLsizei imageSize, const GLvoid *data,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage);
+
+
+extern void
+_mesa_generate_mipmap(GLcontext *ctx, GLenum target,
+ const struct gl_texture_unit *texUnit,
+ struct gl_texture_object *texObj);
+
+
+extern void
+_mesa_rescale_teximage2d(GLuint bytesPerPixel,
+ GLuint srcStrideInPixels,
+ GLuint dstRowStride,
+ GLint srcWidth, GLint srcHeight,
+ GLint dstWidth, GLint dstHeight,
+ const GLvoid *srcImage, GLvoid *dstImage);
+
+extern void
+_mesa_upscale_teximage2d(GLsizei inWidth, GLsizei inHeight,
+ GLsizei outWidth, GLsizei outHeight,
+ GLint comps, const GLchan *src, GLint srcRowStride,
+ GLchan *dest);
+
+
+extern void
+_mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level,
+ GLenum format, GLenum type, GLvoid *pixels,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage);
+
+
+extern void
+_mesa_get_compressed_teximage(GLcontext *ctx, GLenum target, GLint level,
+ GLvoid *img,
+ const struct gl_texture_object *texObj,
+ const struct gl_texture_image *texImage);
+
+extern const GLvoid *
+_mesa_validate_pbo_teximage(GLcontext *ctx, GLuint dimensions,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type, const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *unpack,
+ const char *funcName);
+
+extern const GLvoid *
+_mesa_validate_pbo_compressed_teximage(GLcontext *ctx,
+ GLsizei imageSize, const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ const char *funcName);
+
+extern void
+_mesa_unmap_teximage_pbo(GLcontext *ctx,
+ const struct gl_pixelstore_attrib *unpack);
+
+
+#endif
diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c
new file mode 100644
index 00000000000..cf64fb23df7
--- /dev/null
+++ b/src/mesa/main/varray.c
@@ -0,0 +1,994 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.1
+ *
+ * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include "glheader.h"
+#include "imports.h"
+#include "bufferobj.h"
+#include "context.h"
+#include "enable.h"
+#include "enums.h"
+#include "dlist.h"
+#include "texstate.h"
+#include "mtypes.h"
+#include "varray.h"
+#include "dispatch.h"
+
+#ifndef GL_BOOLEAN
+#define GL_BOOLEAN 0x9999
+#endif
+
+
+/**
+ * Update the fields of a vertex array structure.
+ * We need to do a few special things for arrays that live in
+ * vertex buffer objects.
+ */
+static void
+update_array(GLcontext *ctx, struct gl_client_array *array,
+ GLuint dirtyFlag, GLsizei elementSize,
+ GLint size, GLenum type,
+ GLsizei stride, GLboolean normalized, const GLvoid *ptr)
+{
+ array->Size = size;
+ array->Type = type;
+ array->Stride = stride;
+ array->StrideB = stride ? stride : elementSize;
+ array->Normalized = normalized;
+ array->Ptr = (const GLubyte *) ptr;
+#if FEATURE_ARB_vertex_buffer_object
+ array->BufferObj->RefCount--;
+ if (array->BufferObj->RefCount <= 0) {
+ ASSERT(array->BufferObj->Name);
+ _mesa_remove_buffer_object( ctx, array->BufferObj );
+ (*ctx->Driver.DeleteBuffer)( ctx, array->BufferObj );
+ }
+ array->BufferObj = ctx->Array.ArrayBufferObj;
+ array->BufferObj->RefCount++;
+ /* Compute the index of the last array element that's inside the buffer.
+ * Later in glDrawArrays we'll check if start + count > _MaxElement to
+ * be sure we won't go out of bounds.
+ */
+ if (ctx->Array.ArrayBufferObj->Name)
+ array->_MaxElement = ((GLsizeiptrARB) ctx->Array.ArrayBufferObj->Size
+ - (GLsizeiptrARB) array->Ptr) / array->StrideB;
+ else
+#endif
+ array->_MaxElement = 2 * 1000 * 1000 * 1000; /* just a big number */
+
+ ctx->NewState |= _NEW_ARRAY;
+ ctx->Array.NewState |= dirtyFlag;
+}
+
+
+void GLAPIENTRY
+_mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
+{
+ GLsizei elementSize;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (size < 2 || size > 4) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glVertexPointer(size)" );
+ return;
+ }
+ if (stride < 0) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glVertexPointer(stride)" );
+ return;
+ }
+
+ if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
+ _mesa_debug(ctx, "glVertexPointer( sz %d type %s stride %d )\n", size,
+ _mesa_lookup_enum_by_nr( type ), stride);
+
+ /* always need to check that <type> is legal */
+ switch (type) {
+ case GL_SHORT:
+ elementSize = size * sizeof(GLshort);
+ break;
+ case GL_INT:
+ elementSize = size * sizeof(GLint);
+ break;
+ case GL_FLOAT:
+ elementSize = size * sizeof(GLfloat);
+ break;
+ case GL_DOUBLE:
+ elementSize = size * sizeof(GLdouble);
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glVertexPointer(type)" );
+ return;
+ }
+
+ update_array(ctx, &ctx->Array.Vertex, _NEW_ARRAY_VERTEX,
+ elementSize, size, type, stride, GL_FALSE, ptr);
+
+ if (ctx->Driver.VertexPointer)
+ ctx->Driver.VertexPointer( ctx, size, type, stride, ptr );
+}
+
+
+void GLAPIENTRY
+_mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr )
+{
+ GLsizei elementSize;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (stride < 0) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glNormalPointer(stride)" );
+ return;
+ }
+
+ if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
+ _mesa_debug(ctx, "glNormalPointer( type %s stride %d )\n",
+ _mesa_lookup_enum_by_nr( type ), stride);
+
+ switch (type) {
+ case GL_BYTE:
+ elementSize = 3 * sizeof(GLbyte);
+ break;
+ case GL_SHORT:
+ elementSize = 3 * sizeof(GLshort);
+ break;
+ case GL_INT:
+ elementSize = 3 * sizeof(GLint);
+ break;
+ case GL_FLOAT:
+ elementSize = 3 * sizeof(GLfloat);
+ break;
+ case GL_DOUBLE:
+ elementSize = 3 * sizeof(GLdouble);
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glNormalPointer(type)" );
+ return;
+ }
+
+ update_array(ctx, &ctx->Array.Normal, _NEW_ARRAY_NORMAL,
+ elementSize, 3, type, stride, GL_FALSE, ptr);
+
+ if (ctx->Driver.NormalPointer)
+ ctx->Driver.NormalPointer( ctx, type, stride, ptr );
+}
+
+
+void GLAPIENTRY
+_mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
+{
+ GLsizei elementSize;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (size < 3 || size > 4) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glColorPointer(size)" );
+ return;
+ }
+ if (stride < 0) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glColorPointer(stride)" );
+ return;
+ }
+
+ if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
+ _mesa_debug(ctx, "glColorPointer( sz %d type %s stride %d )\n", size,
+ _mesa_lookup_enum_by_nr( type ), stride);
+
+ switch (type) {
+ case GL_BYTE:
+ elementSize = size * sizeof(GLbyte);
+ break;
+ case GL_UNSIGNED_BYTE:
+ elementSize = size * sizeof(GLubyte);
+ break;
+ case GL_SHORT:
+ elementSize = size * sizeof(GLshort);
+ break;
+ case GL_UNSIGNED_SHORT:
+ elementSize = size * sizeof(GLushort);
+ break;
+ case GL_INT:
+ elementSize = size * sizeof(GLint);
+ break;
+ case GL_UNSIGNED_INT:
+ elementSize = size * sizeof(GLuint);
+ break;
+ case GL_FLOAT:
+ elementSize = size * sizeof(GLfloat);
+ break;
+ case GL_DOUBLE:
+ elementSize = size * sizeof(GLdouble);
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glColorPointer(type)" );
+ return;
+ }
+
+ update_array(ctx, &ctx->Array.Color, _NEW_ARRAY_COLOR0,
+ elementSize, size, type, stride, GL_FALSE, ptr);
+
+ if (ctx->Driver.ColorPointer)
+ ctx->Driver.ColorPointer( ctx, size, type, stride, ptr );
+}
+
+
+void GLAPIENTRY
+_mesa_FogCoordPointerEXT(GLenum type, GLsizei stride, const GLvoid *ptr)
+{
+ GLint elementSize;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (stride < 0) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glFogCoordPointer(stride)" );
+ return;
+ }
+
+ switch (type) {
+ case GL_FLOAT:
+ elementSize = sizeof(GLfloat);
+ break;
+ case GL_DOUBLE:
+ elementSize = sizeof(GLdouble);
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glFogCoordPointer(type)" );
+ return;
+ }
+
+ update_array(ctx, &ctx->Array.FogCoord, _NEW_ARRAY_FOGCOORD,
+ elementSize, 1, type, stride, GL_FALSE, ptr);
+
+ if (ctx->Driver.FogCoordPointer)
+ ctx->Driver.FogCoordPointer( ctx, type, stride, ptr );
+}
+
+
+void GLAPIENTRY
+_mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
+{
+ GLsizei elementSize;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (stride < 0) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glIndexPointer(stride)" );
+ return;
+ }
+
+ switch (type) {
+ case GL_UNSIGNED_BYTE:
+ elementSize = sizeof(GLubyte);
+ break;
+ case GL_SHORT:
+ elementSize = sizeof(GLshort);
+ break;
+ case GL_INT:
+ elementSize = sizeof(GLint);
+ break;
+ case GL_FLOAT:
+ elementSize = sizeof(GLfloat);
+ break;
+ case GL_DOUBLE:
+ elementSize = sizeof(GLdouble);
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glIndexPointer(type)" );
+ return;
+ }
+
+ update_array(ctx, &ctx->Array.Index, _NEW_ARRAY_INDEX,
+ elementSize, 1, type, stride, GL_FALSE, ptr);
+
+ if (ctx->Driver.IndexPointer)
+ ctx->Driver.IndexPointer( ctx, type, stride, ptr );
+}
+
+
+void GLAPIENTRY
+_mesa_SecondaryColorPointerEXT(GLint size, GLenum type,
+ GLsizei stride, const GLvoid *ptr)
+{
+ GLsizei elementSize;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (size != 3 && size != 4) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glSecondaryColorPointer(size)" );
+ return;
+ }
+ if (stride < 0) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glSecondaryColorPointer(stride)" );
+ return;
+ }
+
+ if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
+ _mesa_debug(ctx, "glSecondaryColorPointer( sz %d type %s stride %d )\n",
+ size, _mesa_lookup_enum_by_nr( type ), stride);
+
+ switch (type) {
+ case GL_BYTE:
+ elementSize = size * sizeof(GLbyte);
+ break;
+ case GL_UNSIGNED_BYTE:
+ elementSize = size * sizeof(GLubyte);
+ break;
+ case GL_SHORT:
+ elementSize = size * sizeof(GLshort);
+ break;
+ case GL_UNSIGNED_SHORT:
+ elementSize = size * sizeof(GLushort);
+ break;
+ case GL_INT:
+ elementSize = size * sizeof(GLint);
+ break;
+ case GL_UNSIGNED_INT:
+ elementSize = size * sizeof(GLuint);
+ break;
+ case GL_FLOAT:
+ elementSize = size * sizeof(GLfloat);
+ break;
+ case GL_DOUBLE:
+ elementSize = size * sizeof(GLdouble);
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glSecondaryColorPointer(type)" );
+ return;
+ }
+
+ update_array(ctx, &ctx->Array.SecondaryColor, _NEW_ARRAY_COLOR1,
+ elementSize, size, type, stride, GL_FALSE, ptr);
+
+ if (ctx->Driver.SecondaryColorPointer)
+ ctx->Driver.SecondaryColorPointer( ctx, size, type, stride, ptr );
+}
+
+
+void GLAPIENTRY
+_mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride,
+ const GLvoid *ptr)
+{
+ GLint elementSize;
+ GET_CURRENT_CONTEXT(ctx);
+ const GLuint unit = ctx->Array.ActiveTexture;
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (size < 1 || size > 4) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(size)" );
+ return;
+ }
+ if (stride < 0) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(stride)" );
+ return;
+ }
+
+ if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
+ _mesa_debug(ctx, "glTexCoordPointer(unit %u sz %d type %s stride %d)\n",
+ unit, size, _mesa_lookup_enum_by_nr( type ), stride);
+
+ /* always need to check that <type> is legal */
+ switch (type) {
+ case GL_SHORT:
+ elementSize = size * sizeof(GLshort);
+ break;
+ case GL_INT:
+ elementSize = size * sizeof(GLint);
+ break;
+ case GL_FLOAT:
+ elementSize = size * sizeof(GLfloat);
+ break;
+ case GL_DOUBLE:
+ elementSize = size * sizeof(GLdouble);
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexCoordPointer(type)" );
+ return;
+ }
+
+ update_array(ctx, &ctx->Array.TexCoord[unit], _NEW_ARRAY_TEXCOORD(unit),
+ elementSize, size, type, stride, GL_FALSE, ptr);
+
+ if (ctx->Driver.TexCoordPointer)
+ ctx->Driver.TexCoordPointer( ctx, size, type, stride, ptr );
+}
+
+
+void GLAPIENTRY
+_mesa_EdgeFlagPointer(GLsizei stride, const GLvoid *ptr)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (stride < 0) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glEdgeFlagPointer(stride)" );
+ return;
+ }
+
+ update_array(ctx, &ctx->Array.EdgeFlag, _NEW_ARRAY_EDGEFLAG,
+ sizeof(GLboolean), 1, GL_BOOLEAN, stride, GL_FALSE, ptr);
+
+ if (ctx->Driver.EdgeFlagPointer)
+ ctx->Driver.EdgeFlagPointer( ctx, stride, ptr );
+}
+
+
+#if FEATURE_NV_vertex_program
+void GLAPIENTRY
+_mesa_VertexAttribPointerNV(GLuint index, GLint size, GLenum type,
+ GLsizei stride, const GLvoid *ptr)
+{
+ GLsizei elementSize;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (index >= VERT_ATTRIB_MAX) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(index)");
+ return;
+ }
+
+ if (size < 1 || size > 4) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(size)");
+ return;
+ }
+
+ if (stride < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(stride)");
+ return;
+ }
+
+ if (type == GL_UNSIGNED_BYTE && size != 4) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(size!=4)");
+ return;
+ }
+
+ /* check for valid 'type' and compute StrideB right away */
+ switch (type) {
+ case GL_UNSIGNED_BYTE:
+ elementSize = size * sizeof(GLubyte);
+ break;
+ case GL_SHORT:
+ elementSize = size * sizeof(GLshort);
+ break;
+ case GL_FLOAT:
+ elementSize = size * sizeof(GLfloat);
+ break;
+ case GL_DOUBLE:
+ elementSize = size * sizeof(GLdouble);
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttribPointerNV(type)" );
+ return;
+ }
+
+ update_array(ctx, &ctx->Array.VertexAttrib[index], _NEW_ARRAY_ATTRIB(index),
+ elementSize, size, type, stride, GL_FALSE, ptr);
+
+ if (ctx->Driver.VertexAttribPointer)
+ ctx->Driver.VertexAttribPointer( ctx, index, size, type, stride, ptr );
+}
+#endif
+
+
+#if FEATURE_ARB_vertex_program
+void GLAPIENTRY
+_mesa_VertexAttribPointerARB(GLuint index, GLint size, GLenum type,
+ GLboolean normalized,
+ GLsizei stride, const GLvoid *ptr)
+{
+ GLsizei elementSize;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (index >= ctx->Const.VertexProgram.MaxAttribs) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(index)");
+ return;
+ }
+
+ if (size < 1 || size > 4) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(size)");
+ return;
+ }
+
+ if (stride < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(stride)");
+ return;
+ }
+
+ if (type == GL_UNSIGNED_BYTE && size != 4) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(size!=4)");
+ return;
+ }
+
+ /* check for valid 'type' and compute StrideB right away */
+ /* NOTE: more types are supported here than in the NV extension */
+ switch (type) {
+ case GL_BYTE:
+ elementSize = size * sizeof(GLbyte);
+ break;
+ case GL_UNSIGNED_BYTE:
+ elementSize = size * sizeof(GLubyte);
+ break;
+ case GL_SHORT:
+ elementSize = size * sizeof(GLshort);
+ break;
+ case GL_UNSIGNED_SHORT:
+ elementSize = size * sizeof(GLushort);
+ break;
+ case GL_INT:
+ elementSize = size * sizeof(GLint);
+ break;
+ case GL_UNSIGNED_INT:
+ elementSize = size * sizeof(GLuint);
+ break;
+ case GL_FLOAT:
+ elementSize = size * sizeof(GLfloat);
+ break;
+ case GL_DOUBLE:
+ elementSize = size * sizeof(GLdouble);
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttribPointerARB(type)" );
+ return;
+ }
+
+ update_array(ctx, &ctx->Array.VertexAttrib[index], _NEW_ARRAY_ATTRIB(index),
+ elementSize, size, type, stride, normalized, ptr);
+
+ /* XXX fix
+ if (ctx->Driver.VertexAttribPointer)
+ ctx->Driver.VertexAttribPointer( ctx, index, size, type, stride, ptr );
+ */
+}
+#endif
+
+
+void GLAPIENTRY
+_mesa_VertexPointerEXT(GLint size, GLenum type, GLsizei stride,
+ GLsizei count, const GLvoid *ptr)
+{
+ (void) count;
+ _mesa_VertexPointer(size, type, stride, ptr);
+}
+
+
+void GLAPIENTRY
+_mesa_NormalPointerEXT(GLenum type, GLsizei stride, GLsizei count,
+ const GLvoid *ptr)
+{
+ (void) count;
+ _mesa_NormalPointer(type, stride, ptr);
+}
+
+
+void GLAPIENTRY
+_mesa_ColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count,
+ const GLvoid *ptr)
+{
+ (void) count;
+ _mesa_ColorPointer(size, type, stride, ptr);
+}
+
+
+void GLAPIENTRY
+_mesa_IndexPointerEXT(GLenum type, GLsizei stride, GLsizei count,
+ const GLvoid *ptr)
+{
+ (void) count;
+ _mesa_IndexPointer(type, stride, ptr);
+}
+
+
+void GLAPIENTRY
+_mesa_TexCoordPointerEXT(GLint size, GLenum type, GLsizei stride,
+ GLsizei count, const GLvoid *ptr)
+{
+ (void) count;
+ _mesa_TexCoordPointer(size, type, stride, ptr);
+}
+
+
+void GLAPIENTRY
+_mesa_EdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *ptr)
+{
+ (void) count;
+ _mesa_EdgeFlagPointer(stride, ptr);
+}
+
+
+void GLAPIENTRY
+_mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLboolean tflag, cflag, nflag; /* enable/disable flags */
+ GLint tcomps, ccomps, vcomps; /* components per texcoord, color, vertex */
+ GLenum ctype = 0; /* color type */
+ GLint coffset = 0, noffset = 0, voffset;/* color, normal, vertex offsets */
+ const GLint toffset = 0; /* always zero */
+ GLint defstride; /* default stride */
+ GLint c, f;
+
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ f = sizeof(GLfloat);
+ c = f * ((4 * sizeof(GLubyte) + (f - 1)) / f);
+
+ if (stride < 0) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glInterleavedArrays(stride)" );
+ return;
+ }
+
+ switch (format) {
+ case GL_V2F:
+ tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE;
+ tcomps = 0; ccomps = 0; vcomps = 2;
+ voffset = 0;
+ defstride = 2*f;
+ break;
+ case GL_V3F:
+ tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE;
+ tcomps = 0; ccomps = 0; vcomps = 3;
+ voffset = 0;
+ defstride = 3*f;
+ break;
+ case GL_C4UB_V2F:
+ tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
+ tcomps = 0; ccomps = 4; vcomps = 2;
+ ctype = GL_UNSIGNED_BYTE;
+ coffset = 0;
+ voffset = c;
+ defstride = c + 2*f;
+ break;
+ case GL_C4UB_V3F:
+ tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
+ tcomps = 0; ccomps = 4; vcomps = 3;
+ ctype = GL_UNSIGNED_BYTE;
+ coffset = 0;
+ voffset = c;
+ defstride = c + 3*f;
+ break;
+ case GL_C3F_V3F:
+ tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
+ tcomps = 0; ccomps = 3; vcomps = 3;
+ ctype = GL_FLOAT;
+ coffset = 0;
+ voffset = 3*f;
+ defstride = 6*f;
+ break;
+ case GL_N3F_V3F:
+ tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_TRUE;
+ tcomps = 0; ccomps = 0; vcomps = 3;
+ noffset = 0;
+ voffset = 3*f;
+ defstride = 6*f;
+ break;
+ case GL_C4F_N3F_V3F:
+ tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_TRUE;
+ tcomps = 0; ccomps = 4; vcomps = 3;
+ ctype = GL_FLOAT;
+ coffset = 0;
+ noffset = 4*f;
+ voffset = 7*f;
+ defstride = 10*f;
+ break;
+ case GL_T2F_V3F:
+ tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE;
+ tcomps = 2; ccomps = 0; vcomps = 3;
+ voffset = 2*f;
+ defstride = 5*f;
+ break;
+ case GL_T4F_V4F:
+ tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE;
+ tcomps = 4; ccomps = 0; vcomps = 4;
+ voffset = 4*f;
+ defstride = 8*f;
+ break;
+ case GL_T2F_C4UB_V3F:
+ tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE;
+ tcomps = 2; ccomps = 4; vcomps = 3;
+ ctype = GL_UNSIGNED_BYTE;
+ coffset = 2*f;
+ voffset = c+2*f;
+ defstride = c+5*f;
+ break;
+ case GL_T2F_C3F_V3F:
+ tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE;
+ tcomps = 2; ccomps = 3; vcomps = 3;
+ ctype = GL_FLOAT;
+ coffset = 2*f;
+ voffset = 5*f;
+ defstride = 8*f;
+ break;
+ case GL_T2F_N3F_V3F:
+ tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_TRUE;
+ tcomps = 2; ccomps = 0; vcomps = 3;
+ noffset = 2*f;
+ voffset = 5*f;
+ defstride = 8*f;
+ break;
+ case GL_T2F_C4F_N3F_V3F:
+ tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE;
+ tcomps = 2; ccomps = 4; vcomps = 3;
+ ctype = GL_FLOAT;
+ coffset = 2*f;
+ noffset = 6*f;
+ voffset = 9*f;
+ defstride = 12*f;
+ break;
+ case GL_T4F_C4F_N3F_V4F:
+ tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE;
+ tcomps = 4; ccomps = 4; vcomps = 4;
+ ctype = GL_FLOAT;
+ coffset = 4*f;
+ noffset = 8*f;
+ voffset = 11*f;
+ defstride = 15*f;
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glInterleavedArrays(format)" );
+ return;
+ }
+
+ if (stride==0) {
+ stride = defstride;
+ }
+
+ _mesa_DisableClientState( GL_EDGE_FLAG_ARRAY );
+ _mesa_DisableClientState( GL_INDEX_ARRAY );
+
+ /* Texcoords */
+ if (tflag) {
+ _mesa_EnableClientState( GL_TEXTURE_COORD_ARRAY );
+ _mesa_TexCoordPointer( tcomps, GL_FLOAT, stride,
+ (GLubyte *) pointer + toffset );
+ }
+ else {
+ _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY );
+ }
+
+ /* Color */
+ if (cflag) {
+ _mesa_EnableClientState( GL_COLOR_ARRAY );
+ _mesa_ColorPointer( ccomps, ctype, stride,
+ (GLubyte *) pointer + coffset );
+ }
+ else {
+ _mesa_DisableClientState( GL_COLOR_ARRAY );
+ }
+
+
+ /* Normals */
+ if (nflag) {
+ _mesa_EnableClientState( GL_NORMAL_ARRAY );
+ _mesa_NormalPointer( GL_FLOAT, stride, (GLubyte *) pointer + noffset );
+ }
+ else {
+ _mesa_DisableClientState( GL_NORMAL_ARRAY );
+ }
+
+ /* Vertices */
+ _mesa_EnableClientState( GL_VERTEX_ARRAY );
+ _mesa_VertexPointer( vcomps, GL_FLOAT, stride,
+ (GLubyte *) pointer + voffset );
+}
+
+
+void GLAPIENTRY
+_mesa_LockArraysEXT(GLint first, GLsizei count)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx, "glLockArrays %d %d\n", first, count);
+
+ if (first == 0 && count > 0 &&
+ count <= (GLint) ctx->Const.MaxArrayLockSize) {
+ ctx->Array.LockFirst = first;
+ ctx->Array.LockCount = count;
+ }
+ else {
+ ctx->Array.LockFirst = 0;
+ ctx->Array.LockCount = 0;
+ }
+
+ ctx->NewState |= _NEW_ARRAY;
+ ctx->Array.NewState |= _NEW_ARRAY_ALL;
+
+ if (ctx->Driver.LockArraysEXT)
+ ctx->Driver.LockArraysEXT( ctx, first, count );
+}
+
+
+void GLAPIENTRY
+_mesa_UnlockArraysEXT( void )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx, "glUnlockArrays\n");
+
+ ctx->Array.LockFirst = 0;
+ ctx->Array.LockCount = 0;
+ ctx->NewState |= _NEW_ARRAY;
+ ctx->Array.NewState |= _NEW_ARRAY_ALL;
+
+ if (ctx->Driver.UnlockArraysEXT)
+ ctx->Driver.UnlockArraysEXT( ctx );
+}
+
+
+/* GL_EXT_multi_draw_arrays */
+/* Somebody forgot to spec the first and count parameters as const! <sigh> */
+void GLAPIENTRY
+_mesa_MultiDrawArraysEXT( GLenum mode, GLint *first,
+ GLsizei *count, GLsizei primcount )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint i;
+
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ for (i = 0; i < primcount; i++) {
+ if (count[i] > 0) {
+ CALL_DrawArrays(ctx->Exec, (mode, first[i], count[i]));
+ }
+ }
+}
+
+
+/* GL_EXT_multi_draw_arrays */
+void GLAPIENTRY
+_mesa_MultiDrawElementsEXT( GLenum mode, const GLsizei *count, GLenum type,
+ const GLvoid **indices, GLsizei primcount )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint i;
+
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ for (i = 0; i < primcount; i++) {
+ if (count[i] > 0) {
+ CALL_DrawElements(ctx->Exec, (mode, count[i], type, indices[i]));
+ }
+ }
+}
+
+
+/* GL_IBM_multimode_draw_arrays */
+void GLAPIENTRY
+_mesa_MultiModeDrawArraysIBM( const GLenum * mode, const GLint * first,
+ const GLsizei * count,
+ GLsizei primcount, GLint modestride )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint i;
+
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ for ( i = 0 ; i < primcount ; i++ ) {
+ if ( count[i] > 0 ) {
+ GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride));
+ CALL_DrawArrays(ctx->Exec, ( m, first[i], count[i] ));
+ }
+ }
+}
+
+
+/* GL_IBM_multimode_draw_arrays */
+void GLAPIENTRY
+_mesa_MultiModeDrawElementsIBM( const GLenum * mode, const GLsizei * count,
+ GLenum type, const GLvoid * const * indices,
+ GLsizei primcount, GLint modestride )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint i;
+
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ /* XXX not sure about ARB_vertex_buffer_object handling here */
+
+ for ( i = 0 ; i < primcount ; i++ ) {
+ if ( count[i] > 0 ) {
+ GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride));
+ CALL_DrawElements(ctx->Exec, ( m, count[i], type, indices[i] ));
+ }
+ }
+}
+
+
+/**********************************************************************/
+/***** Initialization *****/
+/**********************************************************************/
+
+void
+_mesa_init_varray( GLcontext * ctx )
+{
+ GLuint i;
+
+ /* Vertex arrays */
+ ctx->Array.Vertex.Size = 4;
+ ctx->Array.Vertex.Type = GL_FLOAT;
+ ctx->Array.Vertex.Stride = 0;
+ ctx->Array.Vertex.StrideB = 0;
+ ctx->Array.Vertex.Ptr = NULL;
+ ctx->Array.Vertex.Enabled = GL_FALSE;
+ ctx->Array.Vertex.Flags = CA_CLIENT_DATA;
+ ctx->Array.Normal.Type = GL_FLOAT;
+ ctx->Array.Normal.Stride = 0;
+ ctx->Array.Normal.StrideB = 0;
+ ctx->Array.Normal.Ptr = NULL;
+ ctx->Array.Normal.Enabled = GL_FALSE;
+ ctx->Array.Normal.Flags = CA_CLIENT_DATA;
+ ctx->Array.Color.Size = 4;
+ ctx->Array.Color.Type = GL_FLOAT;
+ ctx->Array.Color.Stride = 0;
+ ctx->Array.Color.StrideB = 0;
+ ctx->Array.Color.Ptr = NULL;
+ ctx->Array.Color.Enabled = GL_FALSE;
+ ctx->Array.Color.Flags = CA_CLIENT_DATA;
+ ctx->Array.SecondaryColor.Size = 4;
+ ctx->Array.SecondaryColor.Type = GL_FLOAT;
+ ctx->Array.SecondaryColor.Stride = 0;
+ ctx->Array.SecondaryColor.StrideB = 0;
+ ctx->Array.SecondaryColor.Ptr = NULL;
+ ctx->Array.SecondaryColor.Enabled = GL_FALSE;
+ ctx->Array.SecondaryColor.Flags = CA_CLIENT_DATA;
+ ctx->Array.FogCoord.Size = 1;
+ ctx->Array.FogCoord.Type = GL_FLOAT;
+ ctx->Array.FogCoord.Stride = 0;
+ ctx->Array.FogCoord.StrideB = 0;
+ ctx->Array.FogCoord.Ptr = NULL;
+ ctx->Array.FogCoord.Enabled = GL_FALSE;
+ ctx->Array.FogCoord.Flags = CA_CLIENT_DATA;
+ ctx->Array.Index.Type = GL_FLOAT;
+ ctx->Array.Index.Stride = 0;
+ ctx->Array.Index.StrideB = 0;
+ ctx->Array.Index.Ptr = NULL;
+ ctx->Array.Index.Enabled = GL_FALSE;
+ ctx->Array.Index.Flags = CA_CLIENT_DATA;
+ for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
+ ctx->Array.TexCoord[i].Size = 4;
+ ctx->Array.TexCoord[i].Type = GL_FLOAT;
+ ctx->Array.TexCoord[i].Stride = 0;
+ ctx->Array.TexCoord[i].StrideB = 0;
+ ctx->Array.TexCoord[i].Ptr = NULL;
+ ctx->Array.TexCoord[i].Enabled = GL_FALSE;
+ ctx->Array.TexCoord[i].Flags = CA_CLIENT_DATA;
+ }
+ ctx->Array.EdgeFlag.Stride = 0;
+ ctx->Array.EdgeFlag.StrideB = 0;
+ ctx->Array.EdgeFlag.Ptr = NULL;
+ ctx->Array.EdgeFlag.Enabled = GL_FALSE;
+ ctx->Array.EdgeFlag.Flags = CA_CLIENT_DATA;
+ ctx->Array.ActiveTexture = 0; /* GL_ARB_multitexture */
+ for (i = 0; i < VERT_ATTRIB_MAX; i++) {
+ ctx->Array.VertexAttrib[i].Size = 4;
+ ctx->Array.VertexAttrib[i].Type = GL_FLOAT;
+ ctx->Array.VertexAttrib[i].Stride = 0;
+ ctx->Array.VertexAttrib[i].StrideB = 0;
+ ctx->Array.VertexAttrib[i].Ptr = NULL;
+ ctx->Array.VertexAttrib[i].Enabled = GL_FALSE;
+ ctx->Array.VertexAttrib[i].Flags = CA_CLIENT_DATA;
+ }
+}
diff --git a/src/mesa/main/varray.h b/src/mesa/main/varray.h
new file mode 100644
index 00000000000..3589735f684
--- /dev/null
+++ b/src/mesa/main/varray.h
@@ -0,0 +1,160 @@
+/**
+ * \file varray.h
+ * Vertex arrays.
+ *
+ * \if subset
+ * (No-op)
+ *
+ * \endif
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 4.1
+ *
+ * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef VARRAY_H
+#define VARRAY_H
+
+
+#include "mtypes.h"
+
+#if _HAVE_FULL_GL
+
+extern void GLAPIENTRY
+_mesa_VertexPointer(GLint size, GLenum type, GLsizei stride,
+ const GLvoid *ptr);
+
+extern void GLAPIENTRY
+_mesa_UnlockArraysEXT( void );
+
+extern void GLAPIENTRY
+_mesa_LockArraysEXT(GLint first, GLsizei count);
+
+
+extern void GLAPIENTRY
+_mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr);
+
+
+extern void GLAPIENTRY
+_mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr);
+
+
+extern void GLAPIENTRY
+_mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr);
+
+
+extern void GLAPIENTRY
+_mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride,
+ const GLvoid *ptr);
+
+
+extern void GLAPIENTRY
+_mesa_EdgeFlagPointer(GLsizei stride, const GLvoid *ptr);
+
+
+extern void GLAPIENTRY
+_mesa_VertexPointerEXT(GLint size, GLenum type, GLsizei stride,
+ GLsizei count, const GLvoid *ptr);
+
+
+extern void GLAPIENTRY
+_mesa_NormalPointerEXT(GLenum type, GLsizei stride, GLsizei count,
+ const GLvoid *ptr);
+
+
+extern void GLAPIENTRY
+_mesa_ColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count,
+ const GLvoid *ptr);
+
+
+extern void GLAPIENTRY
+_mesa_IndexPointerEXT(GLenum type, GLsizei stride, GLsizei count,
+ const GLvoid *ptr);
+
+
+extern void GLAPIENTRY
+_mesa_TexCoordPointerEXT(GLint size, GLenum type, GLsizei stride,
+ GLsizei count, const GLvoid *ptr);
+
+
+extern void GLAPIENTRY
+_mesa_EdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *ptr);
+
+
+extern void GLAPIENTRY
+_mesa_FogCoordPointerEXT(GLenum type, GLsizei stride, const GLvoid *ptr);
+
+
+extern void GLAPIENTRY
+_mesa_SecondaryColorPointerEXT(GLint size, GLenum type,
+ GLsizei stride, const GLvoid *ptr);
+
+
+extern void GLAPIENTRY
+_mesa_VertexAttribPointerNV(GLuint index, GLint size, GLenum type,
+ GLsizei stride, const GLvoid *pointer);
+
+
+extern void GLAPIENTRY
+_mesa_VertexAttribPointerARB(GLuint index, GLint size, GLenum type,
+ GLboolean normalized, GLsizei stride,
+ const GLvoid *pointer);
+
+
+extern void GLAPIENTRY
+_mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer);
+
+
+extern void GLAPIENTRY
+_mesa_MultiDrawArraysEXT( GLenum mode, GLint *first,
+ GLsizei *count, GLsizei primcount );
+
+extern void GLAPIENTRY
+_mesa_MultiDrawElementsEXT( GLenum mode, const GLsizei *count, GLenum type,
+ const GLvoid **indices, GLsizei primcount );
+
+
+extern void GLAPIENTRY
+_mesa_MultiModeDrawArraysIBM( const GLenum * mode, const GLint * first,
+ const GLsizei * count,
+ GLsizei primcount, GLint modestride );
+
+
+extern void GLAPIENTRY
+_mesa_MultiModeDrawElementsIBM( const GLenum * mode, const GLsizei * count,
+ GLenum type, const GLvoid * const * indices,
+ GLsizei primcount, GLint modestride );
+
+
+extern void
+_mesa_init_varray( GLcontext * ctx );
+
+#else
+
+/** No-op */
+#define _mesa_init_varray( c ) ((void)0)
+
+#endif
+
+#endif
diff --git a/src/mesa/main/version.h b/src/mesa/main/version.h
new file mode 100644
index 00000000000..578406401a5
--- /dev/null
+++ b/src/mesa/main/version.h
@@ -0,0 +1,52 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef VERSION_H
+#define VERSION_H
+
+
+/* Mesa version */
+#define MESA_MAJOR 6
+#define MESA_MINOR 5
+#define MESA_PATCH 0
+#define MESA_VERSION_STRING "6.5"
+
+/* To make version comparison easy */
+#define MESA_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
+#define MESA_VERSION_CODE MESA_VERSION(MESA_MAJOR, MESA_MINOR, MESA_PATCH)
+
+
+/* OpenGL API version */
+#define OPENGL_MAJOR 1
+#define OPENGL_MINOR 5
+#define OPENGL_PATCH 0
+#define OPENGL_VERSION_STRING "1.5"
+
+/* To make version comparison easy */
+#define OPENGL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
+#define OPENGL_VERSION_CODE OPENGL_VERSION(OPENGL_MAJOR, OPENGL_MINOR, OPENGL_PATCH)
+
+
+#endif /* VERSION_H */
diff --git a/src/mesa/main/vsnprintf.c b/src/mesa/main/vsnprintf.c
new file mode 100644
index 00000000000..ab6c740d772
--- /dev/null
+++ b/src/mesa/main/vsnprintf.c
@@ -0,0 +1,165 @@
+/*
+ * Revision 12: http://theos.com/~deraadt/snprintf.c
+ *
+ * Copyright (c) 1997 Theo de Raadt
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __VMS
+# include <sys/param.h>
+#endif
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <signal.h>
+#include <stdio.h>
+#if __STDC__
+#include <stdarg.h>
+#include <stdlib.h>
+#else
+#include <varargs.h>
+#endif
+#include <setjmp.h>
+#include <unistd.h>
+#include <string.h>
+
+#ifndef roundup
+#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
+#endif
+
+#ifdef __sgi
+#define size_t ssize_t
+#endif
+
+static int pgsize;
+static char *curobj;
+static int caught;
+static sigjmp_buf bail;
+
+#define EXTRABYTES 2 /* XXX: why 2? you don't want to know */
+
+static char *
+msetup(str, n)
+ char *str;
+ size_t n;
+{
+ char *e;
+
+ if (n == 0)
+ return NULL;
+ if (pgsize == 0)
+ pgsize = getpagesize();
+ curobj = (char *)malloc(n + EXTRABYTES + pgsize * 2);
+ if (curobj == NULL)
+ return NULL;
+ e = curobj + n + EXTRABYTES;
+ e = (char *)roundup((unsigned long)e, pgsize);
+ if (mprotect(e, pgsize, PROT_NONE) == -1) {
+ free(curobj);
+ curobj = NULL;
+ return NULL;
+ }
+ e = e - n - EXTRABYTES;
+ *e = '\0';
+ return (e);
+}
+
+static void
+ mcatch( int a )
+{
+ siglongjmp(bail, 1);
+}
+
+static void
+mcleanup(str, n, p)
+ char *str;
+ size_t n;
+ char *p;
+{
+ strncpy(str, p, n-1);
+ str[n-1] = '\0';
+ if (mprotect((caddr_t)(p + n + EXTRABYTES), pgsize,
+ PROT_READ|PROT_WRITE|PROT_EXEC) == -1)
+ mprotect((caddr_t)(p + n + EXTRABYTES), pgsize,
+ PROT_READ|PROT_WRITE);
+ free(curobj);
+}
+
+int
+#if __STDC__
+vsnprintf(char *str, size_t n, char const *fmt, va_list ap)
+#else
+vsnprintf(str, n, fmt, ap)
+ char *str;
+ size_t n;
+ char *fmt;
+ char *ap;
+#endif
+{
+ struct sigaction osa, nsa;
+ char *p;
+ int ret = n + 1; /* if we bail, indicated we overflowed */
+
+ memset(&nsa, 0, sizeof nsa);
+ nsa.sa_handler = mcatch;
+ sigemptyset(&nsa.sa_mask);
+
+ p = msetup(str, n);
+ if (p == NULL) {
+ *str = '\0';
+ return 0;
+ }
+ if (sigsetjmp(bail, 1) == 0) {
+ if (sigaction(SIGSEGV, &nsa, &osa) == -1) {
+ mcleanup(str, n, p);
+ return (0);
+ }
+ ret = vsprintf(p, fmt, ap);
+ }
+ mcleanup(str, n, p);
+ (void) sigaction(SIGSEGV, &osa, NULL);
+ return (ret);
+}
+
+int
+#if __STDC__
+snprintf(char *str, size_t n, char const *fmt, ...)
+#else
+snprintf(str, n, fmt, va_alist)
+ char *str;
+ size_t n;
+ char *fmt;
+ va_dcl
+#endif
+{
+ va_list ap;
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+
+ return (vsnprintf(str, n, fmt, ap));
+ va_end(ap);
+}
+
+
+
diff --git a/src/mesa/main/vtxfmt.c b/src/mesa/main/vtxfmt.c
new file mode 100644
index 00000000000..b3c63982911
--- /dev/null
+++ b/src/mesa/main/vtxfmt.c
@@ -0,0 +1,185 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.3
+ *
+ * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ * Gareth Hughes
+ */
+
+#include "glheader.h"
+#include "api_loopback.h"
+#include "context.h"
+#include "imports.h"
+#include "mtypes.h"
+#include "state.h"
+#include "vtxfmt.h"
+
+
+/* The neutral vertex format. This wraps all tnl module functions,
+ * verifying that the currently-installed module is valid and then
+ * installing the function pointers in a lazy fashion. It records the
+ * function pointers that have been swapped out, which allows a fast
+ * restoration of the neutral module in almost all cases -- a typical
+ * app might only require 4-6 functions to be modified from the neutral
+ * baseline, and only restoring these is certainly preferable to doing
+ * the entire module's 60 or so function pointers.
+ */
+
+#define PRE_LOOPBACK( FUNC ) \
+{ \
+ GET_CURRENT_CONTEXT(ctx); \
+ struct gl_tnl_module * const tnl = &(ctx->TnlModule); \
+ const int tmp_offset = _gloffset_ ## FUNC ; \
+ \
+ ASSERT( tnl->Current ); \
+ ASSERT( tnl->SwapCount < NUM_VERTEX_FORMAT_ENTRIES ); \
+ ASSERT( tmp_offset >= 0 ); \
+ \
+ /* Save the swapped function's dispatch entry so it can be */ \
+ /* restored later. */ \
+ tnl->Swapped[tnl->SwapCount].location = & (((_glapi_proc *)ctx->Exec)[tmp_offset]); \
+ tnl->Swapped[tnl->SwapCount].function = (_glapi_proc)TAG(FUNC); \
+ tnl->SwapCount++; \
+ \
+ if ( 0 ) \
+ _mesa_debug(ctx, " swapping gl" #FUNC"...\n" ); \
+ \
+ /* Install the tnl function pointer. */ \
+ SET_ ## FUNC(ctx->Exec, tnl->Current->FUNC); \
+}
+
+#define TAG(x) neutral_##x
+#include "vtxfmt_tmp.h"
+
+
+
+static void
+install_vtxfmt( struct _glapi_table *tab, const GLvertexformat *vfmt )
+{
+ SET_ArrayElement(tab, vfmt->ArrayElement);
+ SET_Color3f(tab, vfmt->Color3f);
+ SET_Color3fv(tab, vfmt->Color3fv);
+ SET_Color4f(tab, vfmt->Color4f);
+ SET_Color4fv(tab, vfmt->Color4fv);
+ SET_EdgeFlag(tab, vfmt->EdgeFlag);
+ SET_EdgeFlagv(tab, vfmt->EdgeFlagv);
+ SET_EvalCoord1f(tab, vfmt->EvalCoord1f);
+ SET_EvalCoord1fv(tab, vfmt->EvalCoord1fv);
+ SET_EvalCoord2f(tab, vfmt->EvalCoord2f);
+ SET_EvalCoord2fv(tab, vfmt->EvalCoord2fv);
+ SET_EvalPoint1(tab, vfmt->EvalPoint1);
+ SET_EvalPoint2(tab, vfmt->EvalPoint2);
+ SET_FogCoordfEXT(tab, vfmt->FogCoordfEXT);
+ SET_FogCoordfvEXT(tab, vfmt->FogCoordfvEXT);
+ SET_Indexf(tab, vfmt->Indexf);
+ SET_Indexfv(tab, vfmt->Indexfv);
+ SET_Materialfv(tab, vfmt->Materialfv);
+ SET_MultiTexCoord1fARB(tab, vfmt->MultiTexCoord1fARB);
+ SET_MultiTexCoord1fvARB(tab, vfmt->MultiTexCoord1fvARB);
+ SET_MultiTexCoord2fARB(tab, vfmt->MultiTexCoord2fARB);
+ SET_MultiTexCoord2fvARB(tab, vfmt->MultiTexCoord2fvARB);
+ SET_MultiTexCoord3fARB(tab, vfmt->MultiTexCoord3fARB);
+ SET_MultiTexCoord3fvARB(tab, vfmt->MultiTexCoord3fvARB);
+ SET_MultiTexCoord4fARB(tab, vfmt->MultiTexCoord4fARB);
+ SET_MultiTexCoord4fvARB(tab, vfmt->MultiTexCoord4fvARB);
+ SET_Normal3f(tab, vfmt->Normal3f);
+ SET_Normal3fv(tab, vfmt->Normal3fv);
+ SET_SecondaryColor3fEXT(tab, vfmt->SecondaryColor3fEXT);
+ SET_SecondaryColor3fvEXT(tab, vfmt->SecondaryColor3fvEXT);
+ SET_TexCoord1f(tab, vfmt->TexCoord1f);
+ SET_TexCoord1fv(tab, vfmt->TexCoord1fv);
+ SET_TexCoord2f(tab, vfmt->TexCoord2f);
+ SET_TexCoord2fv(tab, vfmt->TexCoord2fv);
+ SET_TexCoord3f(tab, vfmt->TexCoord3f);
+ SET_TexCoord3fv(tab, vfmt->TexCoord3fv);
+ SET_TexCoord4f(tab, vfmt->TexCoord4f);
+ SET_TexCoord4fv(tab, vfmt->TexCoord4fv);
+ SET_Vertex2f(tab, vfmt->Vertex2f);
+ SET_Vertex2fv(tab, vfmt->Vertex2fv);
+ SET_Vertex3f(tab, vfmt->Vertex3f);
+ SET_Vertex3fv(tab, vfmt->Vertex3fv);
+ SET_Vertex4f(tab, vfmt->Vertex4f);
+ SET_Vertex4fv(tab, vfmt->Vertex4fv);
+ SET_CallList(tab, vfmt->CallList);
+ SET_CallLists(tab, vfmt->CallLists);
+ SET_Begin(tab, vfmt->Begin);
+ SET_End(tab, vfmt->End);
+ SET_VertexAttrib1fNV(tab, vfmt->VertexAttrib1fNV);
+ SET_VertexAttrib1fvNV(tab, vfmt->VertexAttrib1fvNV);
+ SET_VertexAttrib2fNV(tab, vfmt->VertexAttrib2fNV);
+ SET_VertexAttrib2fvNV(tab, vfmt->VertexAttrib2fvNV);
+ SET_VertexAttrib3fNV(tab, vfmt->VertexAttrib3fNV);
+ SET_VertexAttrib3fvNV(tab, vfmt->VertexAttrib3fvNV);
+ SET_VertexAttrib4fNV(tab, vfmt->VertexAttrib4fNV);
+ SET_VertexAttrib4fvNV(tab, vfmt->VertexAttrib4fvNV);
+ SET_VertexAttrib1fARB(tab, vfmt->VertexAttrib1fARB);
+ SET_VertexAttrib1fvARB(tab, vfmt->VertexAttrib1fvARB);
+ SET_VertexAttrib2fARB(tab, vfmt->VertexAttrib2fARB);
+ SET_VertexAttrib2fvARB(tab, vfmt->VertexAttrib2fvARB);
+ SET_VertexAttrib3fARB(tab, vfmt->VertexAttrib3fARB);
+ SET_VertexAttrib3fvARB(tab, vfmt->VertexAttrib3fvARB);
+ SET_VertexAttrib4fARB(tab, vfmt->VertexAttrib4fARB);
+ SET_VertexAttrib4fvARB(tab, vfmt->VertexAttrib4fvARB);
+ SET_Rectf(tab, vfmt->Rectf);
+ SET_DrawArrays(tab, vfmt->DrawArrays);
+ SET_DrawElements(tab, vfmt->DrawElements);
+ SET_DrawRangeElements(tab, vfmt->DrawRangeElements);
+ SET_EvalMesh1(tab, vfmt->EvalMesh1);
+ SET_EvalMesh2(tab, vfmt->EvalMesh2);
+ ASSERT(tab->EvalMesh2);
+}
+
+
+void _mesa_init_exec_vtxfmt( GLcontext *ctx )
+{
+ install_vtxfmt( ctx->Exec, &neutral_vtxfmt );
+ ctx->TnlModule.SwapCount = 0;
+}
+
+
+void _mesa_install_exec_vtxfmt( GLcontext *ctx, const GLvertexformat *vfmt )
+{
+ ctx->TnlModule.Current = vfmt;
+ _mesa_restore_exec_vtxfmt( ctx );
+}
+
+
+void _mesa_install_save_vtxfmt( GLcontext *ctx, const GLvertexformat *vfmt )
+{
+ install_vtxfmt( ctx->Save, vfmt );
+}
+
+
+void _mesa_restore_exec_vtxfmt( GLcontext *ctx )
+{
+ struct gl_tnl_module *tnl = &(ctx->TnlModule);
+ GLuint i;
+
+ /* Restore the neutral tnl module wrapper.
+ */
+ for ( i = 0 ; i < tnl->SwapCount ; i++ ) {
+ *(tnl->Swapped[i].location) = tnl->Swapped[i].function;
+ }
+
+ tnl->SwapCount = 0;
+}
diff --git a/src/mesa/main/vtxfmt.h b/src/mesa/main/vtxfmt.h
new file mode 100644
index 00000000000..76f108e0232
--- /dev/null
+++ b/src/mesa/main/vtxfmt.h
@@ -0,0 +1,43 @@
+/**
+ * \file vtxfmt.h
+ *
+ * \author Keith Whitwell <keith@tungstengraphics.com>
+ * \author Gareth Hughes
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.1
+ *
+ * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef _VTXFMT_H_
+#define _VTXFMT_H_
+
+extern void _mesa_init_exec_vtxfmt( GLcontext *ctx );
+
+extern void _mesa_install_exec_vtxfmt( GLcontext *ctx, const GLvertexformat *vfmt );
+extern void _mesa_install_save_vtxfmt( GLcontext *ctx, const GLvertexformat *vfmt );
+
+extern void _mesa_restore_exec_vtxfmt( GLcontext *ctx );
+
+#endif
diff --git a/src/mesa/main/vtxfmt_tmp.h b/src/mesa/main/vtxfmt_tmp.h
new file mode 100644
index 00000000000..2a0fdde4665
--- /dev/null
+++ b/src/mesa/main/vtxfmt_tmp.h
@@ -0,0 +1,537 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.3
+ *
+ * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Gareth Hughes
+ */
+
+#ifndef PRE_LOOPBACK
+#define PRE_LOOPBACK( FUNC )
+#endif
+
+#include "dispatch.h"
+#include "glapioffsets.h"
+
+static void GLAPIENTRY TAG(ArrayElement)( GLint i )
+{
+ PRE_LOOPBACK( ArrayElement );
+ CALL_ArrayElement(GET_DISPATCH(), ( i ));
+}
+
+static void GLAPIENTRY TAG(Color3f)( GLfloat r, GLfloat g, GLfloat b )
+{
+ PRE_LOOPBACK( Color3f );
+ CALL_Color3f(GET_DISPATCH(), ( r, g, b ));
+}
+
+static void GLAPIENTRY TAG(Color3fv)( const GLfloat *v )
+{
+ PRE_LOOPBACK( Color3fv );
+ CALL_Color3fv(GET_DISPATCH(), ( v ));
+}
+
+static void GLAPIENTRY TAG(Color4f)( GLfloat r, GLfloat g, GLfloat b, GLfloat a )
+{
+ PRE_LOOPBACK( Color4f );
+ CALL_Color4f(GET_DISPATCH(), ( r, g, b, a ));
+}
+
+static void GLAPIENTRY TAG(Color4fv)( const GLfloat *v )
+{
+ PRE_LOOPBACK( Color4fv );
+ CALL_Color4fv(GET_DISPATCH(), ( v ));
+}
+
+static void GLAPIENTRY TAG(EdgeFlag)( GLboolean e )
+{
+ PRE_LOOPBACK( EdgeFlag );
+ CALL_EdgeFlag(GET_DISPATCH(), ( e ));
+}
+
+static void GLAPIENTRY TAG(EdgeFlagv)( const GLboolean *v )
+{
+ PRE_LOOPBACK( EdgeFlagv );
+ CALL_EdgeFlagv(GET_DISPATCH(), ( v ));
+}
+
+static void GLAPIENTRY TAG(EvalCoord1f)( GLfloat s )
+{
+ PRE_LOOPBACK( EvalCoord1f );
+ CALL_EvalCoord1f(GET_DISPATCH(), ( s ));
+}
+
+static void GLAPIENTRY TAG(EvalCoord1fv)( const GLfloat *v )
+{
+ PRE_LOOPBACK( EvalCoord1fv );
+ CALL_EvalCoord1fv(GET_DISPATCH(), ( v ));
+}
+
+static void GLAPIENTRY TAG(EvalCoord2f)( GLfloat s, GLfloat t )
+{
+ PRE_LOOPBACK( EvalCoord2f );
+ CALL_EvalCoord2f(GET_DISPATCH(), ( s, t ));
+}
+
+static void GLAPIENTRY TAG(EvalCoord2fv)( const GLfloat *v )
+{
+ PRE_LOOPBACK( EvalCoord2fv );
+ CALL_EvalCoord2fv(GET_DISPATCH(), ( v ));
+}
+
+static void GLAPIENTRY TAG(EvalPoint1)( GLint i )
+{
+ PRE_LOOPBACK( EvalPoint1 );
+ CALL_EvalPoint1(GET_DISPATCH(), ( i ));
+}
+
+static void GLAPIENTRY TAG(EvalPoint2)( GLint i, GLint j )
+{
+ PRE_LOOPBACK( EvalPoint2 );
+ CALL_EvalPoint2(GET_DISPATCH(), ( i, j ));
+}
+
+static void GLAPIENTRY TAG(FogCoordfEXT)( GLfloat f )
+{
+ PRE_LOOPBACK( FogCoordfEXT );
+ CALL_FogCoordfEXT(GET_DISPATCH(), ( f ));
+}
+
+static void GLAPIENTRY TAG(FogCoordfvEXT)( const GLfloat *v )
+{
+ PRE_LOOPBACK( FogCoordfvEXT );
+ CALL_FogCoordfvEXT(GET_DISPATCH(), ( v ));
+}
+
+static void GLAPIENTRY TAG(Indexf)( GLfloat f )
+{
+ PRE_LOOPBACK( Indexf );
+ CALL_Indexf(GET_DISPATCH(), ( f ));
+}
+
+static void GLAPIENTRY TAG(Indexfv)( const GLfloat *v )
+{
+ PRE_LOOPBACK( Indexfv );
+ CALL_Indexfv(GET_DISPATCH(), ( v ));
+}
+
+static void GLAPIENTRY TAG(Materialfv)( GLenum face, GLenum pname, const GLfloat *v )
+{
+ PRE_LOOPBACK( Materialfv );
+ CALL_Materialfv(GET_DISPATCH(), ( face, pname, v ));
+}
+
+static void GLAPIENTRY TAG(MultiTexCoord1fARB)( GLenum target, GLfloat a )
+{
+ PRE_LOOPBACK( MultiTexCoord1fARB );
+ CALL_MultiTexCoord1fARB(GET_DISPATCH(), ( target, a ));
+}
+
+static void GLAPIENTRY TAG(MultiTexCoord1fvARB)( GLenum target, const GLfloat *tc )
+{
+ PRE_LOOPBACK( MultiTexCoord1fvARB );
+ CALL_MultiTexCoord1fvARB(GET_DISPATCH(), ( target, tc ));
+}
+
+static void GLAPIENTRY TAG(MultiTexCoord2fARB)( GLenum target, GLfloat s, GLfloat t )
+{
+ PRE_LOOPBACK( MultiTexCoord2fARB );
+ CALL_MultiTexCoord2fARB(GET_DISPATCH(), ( target, s, t ));
+}
+
+static void GLAPIENTRY TAG(MultiTexCoord2fvARB)( GLenum target, const GLfloat *tc )
+{
+ PRE_LOOPBACK( MultiTexCoord2fvARB );
+ CALL_MultiTexCoord2fvARB(GET_DISPATCH(), ( target, tc ));
+}
+
+static void GLAPIENTRY TAG(MultiTexCoord3fARB)( GLenum target, GLfloat s,
+ GLfloat t, GLfloat r )
+{
+ PRE_LOOPBACK( MultiTexCoord3fARB );
+ CALL_MultiTexCoord3fARB(GET_DISPATCH(), ( target, s, t, r ));
+}
+
+static void GLAPIENTRY TAG(MultiTexCoord3fvARB)( GLenum target, const GLfloat *tc )
+{
+ PRE_LOOPBACK( MultiTexCoord3fvARB );
+ CALL_MultiTexCoord3fvARB(GET_DISPATCH(), ( target, tc ));
+}
+
+static void GLAPIENTRY TAG(MultiTexCoord4fARB)( GLenum target, GLfloat s,
+ GLfloat t, GLfloat r, GLfloat q )
+{
+ PRE_LOOPBACK( MultiTexCoord4fARB );
+ CALL_MultiTexCoord4fARB(GET_DISPATCH(), ( target, s, t, r, q ));
+}
+
+static void GLAPIENTRY TAG(MultiTexCoord4fvARB)( GLenum target, const GLfloat *tc )
+{
+ PRE_LOOPBACK( MultiTexCoord4fvARB );
+ CALL_MultiTexCoord4fvARB(GET_DISPATCH(), ( target, tc ));
+}
+
+static void GLAPIENTRY TAG(Normal3f)( GLfloat x, GLfloat y, GLfloat z )
+{
+ PRE_LOOPBACK( Normal3f );
+ CALL_Normal3f(GET_DISPATCH(), ( x, y, z ));
+}
+
+static void GLAPIENTRY TAG(Normal3fv)( const GLfloat *v )
+{
+ PRE_LOOPBACK( Normal3fv );
+ CALL_Normal3fv(GET_DISPATCH(), ( v ));
+}
+
+static void GLAPIENTRY TAG(SecondaryColor3fEXT)( GLfloat r, GLfloat g, GLfloat b )
+{
+ PRE_LOOPBACK( SecondaryColor3fEXT );
+ CALL_SecondaryColor3fEXT(GET_DISPATCH(), ( r, g, b ));
+}
+
+static void GLAPIENTRY TAG(SecondaryColor3fvEXT)( const GLfloat *v )
+{
+ PRE_LOOPBACK( SecondaryColor3fvEXT );
+ CALL_SecondaryColor3fvEXT(GET_DISPATCH(), ( v ));
+}
+
+static void GLAPIENTRY TAG(TexCoord1f)( GLfloat s )
+{
+ PRE_LOOPBACK( TexCoord1f );
+ CALL_TexCoord1f(GET_DISPATCH(), ( s ));
+}
+
+static void GLAPIENTRY TAG(TexCoord1fv)( const GLfloat *tc )
+{
+ PRE_LOOPBACK( TexCoord1fv );
+ CALL_TexCoord1fv(GET_DISPATCH(), ( tc ));
+}
+
+static void GLAPIENTRY TAG(TexCoord2f)( GLfloat s, GLfloat t )
+{
+ PRE_LOOPBACK( TexCoord2f );
+ CALL_TexCoord2f(GET_DISPATCH(), ( s, t ));
+}
+
+static void GLAPIENTRY TAG(TexCoord2fv)( const GLfloat *tc )
+{
+ PRE_LOOPBACK( TexCoord2fv );
+ CALL_TexCoord2fv(GET_DISPATCH(), ( tc ));
+}
+
+static void GLAPIENTRY TAG(TexCoord3f)( GLfloat s, GLfloat t, GLfloat r )
+{
+ PRE_LOOPBACK( TexCoord3f );
+ CALL_TexCoord3f(GET_DISPATCH(), ( s, t, r ));
+}
+
+static void GLAPIENTRY TAG(TexCoord3fv)( const GLfloat *tc )
+{
+ PRE_LOOPBACK( TexCoord3fv );
+ CALL_TexCoord3fv(GET_DISPATCH(), ( tc ));
+}
+
+static void GLAPIENTRY TAG(TexCoord4f)( GLfloat s, GLfloat t, GLfloat r, GLfloat q )
+{
+ PRE_LOOPBACK( TexCoord4f );
+ CALL_TexCoord4f(GET_DISPATCH(), ( s, t, r, q ));
+}
+
+static void GLAPIENTRY TAG(TexCoord4fv)( const GLfloat *tc )
+{
+ PRE_LOOPBACK( TexCoord4fv );
+ CALL_TexCoord4fv(GET_DISPATCH(), ( tc ));
+}
+
+static void GLAPIENTRY TAG(Vertex2f)( GLfloat x, GLfloat y )
+{
+ PRE_LOOPBACK( Vertex2f );
+ CALL_Vertex2f(GET_DISPATCH(), ( x, y ));
+}
+
+static void GLAPIENTRY TAG(Vertex2fv)( const GLfloat *v )
+{
+ PRE_LOOPBACK( Vertex2fv );
+ CALL_Vertex2fv(GET_DISPATCH(), ( v ));
+}
+
+static void GLAPIENTRY TAG(Vertex3f)( GLfloat x, GLfloat y, GLfloat z )
+{
+ PRE_LOOPBACK( Vertex3f );
+ CALL_Vertex3f(GET_DISPATCH(), ( x, y, z ));
+}
+
+static void GLAPIENTRY TAG(Vertex3fv)( const GLfloat *v )
+{
+ PRE_LOOPBACK( Vertex3fv );
+ CALL_Vertex3fv(GET_DISPATCH(), ( v ));
+}
+
+static void GLAPIENTRY TAG(Vertex4f)( GLfloat x, GLfloat y, GLfloat z, GLfloat w )
+{
+ PRE_LOOPBACK( Vertex4f );
+ CALL_Vertex4f(GET_DISPATCH(), ( x, y, z, w ));
+}
+
+static void GLAPIENTRY TAG(Vertex4fv)( const GLfloat *v )
+{
+ PRE_LOOPBACK( Vertex4fv );
+ CALL_Vertex4fv(GET_DISPATCH(), ( v ));
+}
+
+static void GLAPIENTRY TAG(CallList)( GLuint i )
+{
+ PRE_LOOPBACK( CallList );
+ CALL_CallList(GET_DISPATCH(), ( i ));
+}
+
+static void GLAPIENTRY TAG(CallLists)( GLsizei sz, GLenum type, const GLvoid *v )
+{
+ PRE_LOOPBACK( CallLists );
+ CALL_CallLists(GET_DISPATCH(), ( sz, type, v ));
+}
+
+static void GLAPIENTRY TAG(Begin)( GLenum mode )
+{
+ PRE_LOOPBACK( Begin );
+ CALL_Begin(GET_DISPATCH(), ( mode ));
+}
+
+static void GLAPIENTRY TAG(End)( void )
+{
+ PRE_LOOPBACK( End );
+ CALL_End(GET_DISPATCH(), ());
+}
+
+static void GLAPIENTRY TAG(Rectf)( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 )
+{
+ PRE_LOOPBACK( Rectf );
+ CALL_Rectf(GET_DISPATCH(), ( x1, y1, x2, y2 ));
+}
+
+static void GLAPIENTRY TAG(DrawArrays)( GLenum mode, GLint start, GLsizei count )
+{
+ PRE_LOOPBACK( DrawArrays );
+ CALL_DrawArrays(GET_DISPATCH(), ( mode, start, count ));
+}
+
+static void GLAPIENTRY TAG(DrawElements)( GLenum mode, GLsizei count, GLenum type,
+ const GLvoid *indices )
+{
+ PRE_LOOPBACK( DrawElements );
+ CALL_DrawElements(GET_DISPATCH(), ( mode, count, type, indices ));
+}
+
+static void GLAPIENTRY TAG(DrawRangeElements)( GLenum mode, GLuint start,
+ GLuint end, GLsizei count,
+ GLenum type, const GLvoid *indices )
+{
+ PRE_LOOPBACK( DrawRangeElements );
+ CALL_DrawRangeElements(GET_DISPATCH(), ( mode, start, end, count, type, indices ));
+}
+
+static void GLAPIENTRY TAG(EvalMesh1)( GLenum mode, GLint i1, GLint i2 )
+{
+ PRE_LOOPBACK( EvalMesh1 );
+ CALL_EvalMesh1(GET_DISPATCH(), ( mode, i1, i2 ));
+}
+
+static void GLAPIENTRY TAG(EvalMesh2)( GLenum mode, GLint i1, GLint i2,
+ GLint j1, GLint j2 )
+{
+ PRE_LOOPBACK( EvalMesh2 );
+ CALL_EvalMesh2(GET_DISPATCH(), ( mode, i1, i2, j1, j2 ));
+}
+
+static void GLAPIENTRY TAG(VertexAttrib1fNV)( GLuint index, GLfloat x )
+{
+ PRE_LOOPBACK( VertexAttrib1fNV );
+ CALL_VertexAttrib1fNV(GET_DISPATCH(), ( index, x ));
+}
+
+static void GLAPIENTRY TAG(VertexAttrib1fvNV)( GLuint index, const GLfloat *v )
+{
+ PRE_LOOPBACK( VertexAttrib1fvNV );
+ CALL_VertexAttrib1fvNV(GET_DISPATCH(), ( index, v ));
+}
+
+static void GLAPIENTRY TAG(VertexAttrib2fNV)( GLuint index, GLfloat x, GLfloat y )
+{
+ PRE_LOOPBACK( VertexAttrib2fNV );
+ CALL_VertexAttrib2fNV(GET_DISPATCH(), ( index, x, y ));
+}
+
+static void GLAPIENTRY TAG(VertexAttrib2fvNV)( GLuint index, const GLfloat *v )
+{
+ PRE_LOOPBACK( VertexAttrib2fvNV );
+ CALL_VertexAttrib2fvNV(GET_DISPATCH(), ( index, v ));
+}
+
+static void GLAPIENTRY TAG(VertexAttrib3fNV)( GLuint index, GLfloat x, GLfloat y, GLfloat z )
+{
+ PRE_LOOPBACK( VertexAttrib3fNV );
+ CALL_VertexAttrib3fNV(GET_DISPATCH(), ( index, x, y, z ));
+}
+
+static void GLAPIENTRY TAG(VertexAttrib3fvNV)( GLuint index, const GLfloat *v )
+{
+ PRE_LOOPBACK( VertexAttrib3fvNV );
+ CALL_VertexAttrib3fvNV(GET_DISPATCH(), ( index, v ));
+}
+
+static void GLAPIENTRY TAG(VertexAttrib4fNV)( GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w )
+{
+ PRE_LOOPBACK( VertexAttrib4fNV );
+ CALL_VertexAttrib4fNV(GET_DISPATCH(), ( index, x, y, z, w ));
+}
+
+static void GLAPIENTRY TAG(VertexAttrib4fvNV)( GLuint index, const GLfloat *v )
+{
+ PRE_LOOPBACK( VertexAttrib4fvNV );
+ CALL_VertexAttrib4fvNV(GET_DISPATCH(), ( index, v ));
+}
+
+
+static void GLAPIENTRY TAG(VertexAttrib1fARB)( GLuint index, GLfloat x )
+{
+ PRE_LOOPBACK( VertexAttrib1fARB );
+ CALL_VertexAttrib1fARB(GET_DISPATCH(), ( index, x ));
+}
+
+static void GLAPIENTRY TAG(VertexAttrib1fvARB)( GLuint index, const GLfloat *v )
+{
+ PRE_LOOPBACK( VertexAttrib1fvARB );
+ CALL_VertexAttrib1fvARB(GET_DISPATCH(), ( index, v ));
+}
+
+static void GLAPIENTRY TAG(VertexAttrib2fARB)( GLuint index, GLfloat x, GLfloat y )
+{
+ PRE_LOOPBACK( VertexAttrib2fARB );
+ CALL_VertexAttrib2fARB(GET_DISPATCH(), ( index, x, y ));
+}
+
+static void GLAPIENTRY TAG(VertexAttrib2fvARB)( GLuint index, const GLfloat *v )
+{
+ PRE_LOOPBACK( VertexAttrib2fvARB );
+ CALL_VertexAttrib2fvARB(GET_DISPATCH(), ( index, v ));
+}
+
+static void GLAPIENTRY TAG(VertexAttrib3fARB)( GLuint index, GLfloat x, GLfloat y, GLfloat z )
+{
+ PRE_LOOPBACK( VertexAttrib3fARB );
+ CALL_VertexAttrib3fARB(GET_DISPATCH(), ( index, x, y, z ));
+}
+
+static void GLAPIENTRY TAG(VertexAttrib3fvARB)( GLuint index, const GLfloat *v )
+{
+ PRE_LOOPBACK( VertexAttrib3fvARB );
+ CALL_VertexAttrib3fvARB(GET_DISPATCH(), ( index, v ));
+}
+
+static void GLAPIENTRY TAG(VertexAttrib4fARB)( GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w )
+{
+ PRE_LOOPBACK( VertexAttrib4fARB );
+ CALL_VertexAttrib4fARB(GET_DISPATCH(), ( index, x, y, z, w ));
+}
+
+static void GLAPIENTRY TAG(VertexAttrib4fvARB)( GLuint index, const GLfloat *v )
+{
+ PRE_LOOPBACK( VertexAttrib4fvARB );
+ CALL_VertexAttrib4fvARB(GET_DISPATCH(), ( index, v ));
+}
+
+
+static GLvertexformat TAG(vtxfmt) = {
+ TAG(ArrayElement),
+ TAG(Color3f),
+ TAG(Color3fv),
+ TAG(Color4f),
+ TAG(Color4fv),
+ TAG(EdgeFlag),
+ TAG(EdgeFlagv),
+ TAG(EvalCoord1f),
+ TAG(EvalCoord1fv),
+ TAG(EvalCoord2f),
+ TAG(EvalCoord2fv),
+ TAG(EvalPoint1),
+ TAG(EvalPoint2),
+ TAG(FogCoordfEXT),
+ TAG(FogCoordfvEXT),
+ TAG(Indexf),
+ TAG(Indexfv),
+ TAG(Materialfv),
+ TAG(MultiTexCoord1fARB),
+ TAG(MultiTexCoord1fvARB),
+ TAG(MultiTexCoord2fARB),
+ TAG(MultiTexCoord2fvARB),
+ TAG(MultiTexCoord3fARB),
+ TAG(MultiTexCoord3fvARB),
+ TAG(MultiTexCoord4fARB),
+ TAG(MultiTexCoord4fvARB),
+ TAG(Normal3f),
+ TAG(Normal3fv),
+ TAG(SecondaryColor3fEXT),
+ TAG(SecondaryColor3fvEXT),
+ TAG(TexCoord1f),
+ TAG(TexCoord1fv),
+ TAG(TexCoord2f),
+ TAG(TexCoord2fv),
+ TAG(TexCoord3f),
+ TAG(TexCoord3fv),
+ TAG(TexCoord4f),
+ TAG(TexCoord4fv),
+ TAG(Vertex2f),
+ TAG(Vertex2fv),
+ TAG(Vertex3f),
+ TAG(Vertex3fv),
+ TAG(Vertex4f),
+ TAG(Vertex4fv),
+ TAG(CallList),
+ TAG(CallLists),
+ TAG(Begin),
+ TAG(End),
+ TAG(VertexAttrib1fNV),
+ TAG(VertexAttrib1fvNV),
+ TAG(VertexAttrib2fNV),
+ TAG(VertexAttrib2fvNV),
+ TAG(VertexAttrib3fNV),
+ TAG(VertexAttrib3fvNV),
+ TAG(VertexAttrib4fNV),
+ TAG(VertexAttrib4fvNV),
+ TAG(VertexAttrib1fARB),
+ TAG(VertexAttrib1fvARB),
+ TAG(VertexAttrib2fARB),
+ TAG(VertexAttrib2fvARB),
+ TAG(VertexAttrib3fARB),
+ TAG(VertexAttrib3fvARB),
+ TAG(VertexAttrib4fARB),
+ TAG(VertexAttrib4fvARB),
+ TAG(Rectf),
+ TAG(DrawArrays),
+ TAG(DrawElements),
+ TAG(DrawRangeElements),
+ TAG(EvalMesh1),
+ TAG(EvalMesh2)
+};
+
+#undef TAG
+#undef PRE_LOOPBACK