set table size to 1023 and use new HASH_FUNC() macro
[mesa.git] / src / mesa / main / dlist.c
index ef9c74fb7431b4613245f6c8956be8fe2168e30b..effdb7702a7de5faa8727f0983cc09681e92742d 100644 (file)
@@ -1,11 +1,6 @@
-/**
- * \file dlist.c
- * Display lists management functions.
- */
-
 /*
  * Mesa 3-D graphics library
- * Version:  6.0
+ * Version:  6.3
  *
  * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
  *
  */
 
 
+/**
+ * \file dlist.c
+ * Display lists management functions.
+ */
+
 #include "glheader.h"
 #include "imports.h"
 #include "api_arrayelt.h"
@@ -65,6 +65,7 @@
 #include "dlist.h"
 #include "macros.h"
 #include "matrix.h"
+#include "occlude.h"
 #include "pixel.h"
 #include "points.h"
 #include "polygon.h"
@@ -78,6 +79,9 @@
 #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"
@@ -164,6 +168,7 @@ do {                                                                        \
  * 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,
@@ -309,15 +314,30 @@ typedef enum {
         /* 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,
+       
        /* Vertex attributes -- fallback for when optimized display
         * list build isn't active.
         */
-       OPCODE_ATTR_1F,
-       OPCODE_ATTR_2F,
-       OPCODE_ATTR_3F,
-       OPCODE_ATTR_4F,
+       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,
@@ -392,11 +412,13 @@ void mesa_print_display_list( GLuint list );
  * Make an empty display list.  This is used by glGenLists() to
  * reserver display list IDs.
  */
-static Node *make_empty_list( void )
+static struct mesa_display_list *make_list( GLuint list, GLuint count )
 {
-   Node *n = (Node *) MALLOC( sizeof(Node) );
-   n[0].opcode = OPCODE_END_OF_LIST;
-   return n;
+   struct mesa_display_list *dlist = CALLOC_STRUCT( mesa_display_list );
+   dlist->id = list;
+   dlist->node = (Node *) MALLOC( sizeof(Node) * count );
+   dlist->node[0].opcode = OPCODE_END_OF_LIST;
+   return dlist;
 }
 
 
@@ -407,14 +429,18 @@ static Node *make_empty_list( void )
  */
 void _mesa_destroy_list( GLcontext *ctx, GLuint list )
 {
+   struct mesa_display_list *dlist;
    Node *n, *block;
    GLboolean done;
 
    if (list==0)
       return;
 
-   block = (Node *) _mesa_HashLookup(ctx->Shared->DisplayList, list);
-   n = block;
+   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) {
@@ -552,6 +578,7 @@ void _mesa_destroy_list( GLcontext *ctx, GLuint list )
       }
    }
 
+   FREE( dlist );
    _mesa_HashRemove(ctx->Shared->DisplayList, list);
 }
 
@@ -774,10 +801,28 @@ _mesa_init_lists( void )
       InstSize[OPCODE_PROGRAM_STRING_ARB] = 5;
       InstSize[OPCODE_PROGRAM_ENV_PARAMETER_ARB] = 7;
 #endif
-      InstSize[OPCODE_ATTR_1F] = 3;
-      InstSize[OPCODE_ATTR_2F] = 4;
-      InstSize[OPCODE_ATTR_3F] = 5;
-      InstSize[OPCODE_ATTR_4F] = 6;
+#if FEATURE_ARB_occlusion_query
+      InstSize[OPCODE_BEGIN_QUERY_ARB] = 3;
+      InstSize[OPCODE_END_QUERY_ARB] = 2;
+#endif
+      InstSize[OPCODE_DRAW_BUFFERS_ARB] = 2 + MAX_DRAW_BUFFERS;
+#if FEATURE_ATI_fragment_shader
+      InstSize[OPCODE_BIND_FRAGMENT_SHADER_ATI] = 2;
+      InstSize[OPCODE_SET_FRAGMENT_SHADER_CONSTANTS_ATI] = 6;
+#endif
+      /* OpenGL 2.0 */
+      InstSize[OPCODE_STENCIL_FUNC_SEPARATE] = 5;
+      InstSize[OPCODE_STENCIL_MASK_SEPARATE] = 3;
+      InstSize[OPCODE_STENCIL_OP_SEPARATE] = 5;
+
+      InstSize[OPCODE_ATTR_1F_NV] = 3;
+      InstSize[OPCODE_ATTR_2F_NV] = 4;
+      InstSize[OPCODE_ATTR_3F_NV] = 5;
+      InstSize[OPCODE_ATTR_4F_NV] = 6;
+      InstSize[OPCODE_ATTR_1F_ARB] = 3;
+      InstSize[OPCODE_ATTR_2F_ARB] = 4;
+      InstSize[OPCODE_ATTR_3F_ARB] = 5;
+      InstSize[OPCODE_ATTR_4F_ARB] = 6;
       InstSize[OPCODE_MATERIAL] = 7;
       InstSize[OPCODE_INDEX] = 2;
       InstSize[OPCODE_EDGEFLAG] = 2;
@@ -799,19 +844,19 @@ _mesa_init_lists( void )
  * \todo This won't suffice when the PBO is really in VRAM/GPU memory.
  */
 static GLvoid *
-unpack_image( GLsizei width, GLsizei height, GLsizei depth,
+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(width, height, depth, format, type,
+      return _mesa_unpack_image(dimensions, width, height, depth, format, type,
                                 pixels, unpack);
    }
-   else if (_mesa_validate_pbo_access(unpack, width, height, depth, format,
-                                      type, pixels)) {
+   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(width, height, depth, format, type,
+      return _mesa_unpack_image(dimensions, width, height, depth, format, type,
                                 src, unpack);
    }
    /* bad access! */
@@ -1285,7 +1330,7 @@ static void GLAPIENTRY save_ColorTable( GLenum target, GLenum internalFormat,
                                 format, type, table );
    }
    else {
-      GLvoid *image = unpack_image(width, 1, 1, format, type, table,
+      GLvoid *image = unpack_image(1, width, 1, 1, format, type, table,
                                    &ctx->Unpack);
       Node *n;
       ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
@@ -1374,7 +1419,7 @@ static void GLAPIENTRY save_ColorSubTable( GLenum target, GLsizei start, GLsizei
                                 const GLvoid *table)
 {
    GET_CURRENT_CONTEXT(ctx);
-   GLvoid *image = unpack_image(count, 1, 1, format, type, table,
+   GLvoid *image = unpack_image(1, count, 1, 1, format, type, table,
                                 &ctx->Unpack);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
@@ -1445,7 +1490,7 @@ save_ConvolutionFilter1D(GLenum target, GLenum internalFormat, GLsizei width,
                          GLenum format, GLenum type, const GLvoid *filter)
 {
    GET_CURRENT_CONTEXT(ctx);
-   GLvoid *image = unpack_image(width, 1, 1, format, type, filter,
+   GLvoid *image = unpack_image(1, width, 1, 1, format, type, filter,
                                 &ctx->Unpack);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
@@ -1474,7 +1519,7 @@ save_ConvolutionFilter2D(GLenum target, GLenum internalFormat,
                          GLenum type, const GLvoid *filter)
 {
    GET_CURRENT_CONTEXT(ctx);
-   GLvoid *image = unpack_image(width, height, 1, format, type, filter,
+   GLvoid *image = unpack_image(2, width, height, 1, format, type, filter,
                                 &ctx->Unpack);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
@@ -1839,7 +1884,7 @@ static void GLAPIENTRY save_DrawPixels( GLsizei width, GLsizei height,
                              const GLvoid *pixels )
 {
    GET_CURRENT_CONTEXT(ctx);
-   GLvoid *image = unpack_image(width, height, 1, format, type,
+   GLvoid *image = unpack_image(2, width, height, 1, format, type,
                                 pixels, &ctx->Unpack);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
@@ -3230,6 +3275,61 @@ static void GLAPIENTRY save_StencilOp( GLenum fail, GLenum zfail, GLenum 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) {
+      ctx->Exec->StencilFuncSeparate(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) {
+      ctx->Exec->StencilMaskSeparate(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) {
+      ctx->Exec->StencilOpSeparate(face, fail, zfail, zpass);
+   }
+}
+
+
 static void GLAPIENTRY save_TexEnvfv( GLenum target, GLenum pname, const GLfloat *params )
 {
    GET_CURRENT_CONTEXT(ctx);
@@ -3239,10 +3339,16 @@ static void GLAPIENTRY save_TexEnvfv( GLenum target, GLenum pname, const GLfloat
    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 (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) {
       (*ctx->Exec->TexEnvfv)( target, pname, params );
@@ -3268,10 +3374,16 @@ static void GLAPIENTRY save_TexEnvi( GLenum target, GLenum pname, GLint param )
 static void GLAPIENTRY save_TexEnviv( GLenum target, GLenum pname, const GLint *param )
 {
    GLfloat p[4];
-   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] );
+   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 );
 }
 
@@ -3395,7 +3507,7 @@ static void GLAPIENTRY save_TexImage1D( GLenum target,
                                border, format, type, pixels );
    }
    else {
-      GLvoid *image = unpack_image(width, 1, 1, format, type,
+      GLvoid *image = unpack_image(1, width, 1, 1, format, type,
                                    pixels, &ctx->Unpack);
       Node *n;
       ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
@@ -3434,7 +3546,7 @@ static void GLAPIENTRY save_TexImage2D( GLenum target,
                                height, border, format, type, pixels );
    }
    else {
-      GLvoid *image = unpack_image(width, height, 1, format, type,
+      GLvoid *image = unpack_image(2, width, height, 1, format, type,
                                    pixels, &ctx->Unpack);
       Node *n;
       ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
@@ -3476,7 +3588,7 @@ static void GLAPIENTRY save_TexImage3D( GLenum target,
    }
    else {
       Node *n;
-      GLvoid *image = unpack_image(width, height, depth, format, type,
+      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 );
@@ -3509,7 +3621,7 @@ static void GLAPIENTRY save_TexSubImage1D( GLenum target, GLint level, GLint xof
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   GLvoid *image = unpack_image(width, 1, 1, format, type,
+   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 );
@@ -3540,7 +3652,7 @@ static void GLAPIENTRY save_TexSubImage2D( GLenum target, GLint level,
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   GLvoid *image = unpack_image(width, height, 1, format, type,
+   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 );
@@ -3573,7 +3685,7 @@ static void GLAPIENTRY save_TexSubImage3D( GLenum target, GLint level,
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
-   GLvoid *image = unpack_image(width, height, depth, format, type,
+   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 );
@@ -4526,7 +4638,7 @@ 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_ACTIVE_STENCIL_FACE_EXT, 2 );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_DEPTH_BOUNDS_EXT, 2 );
    if (n) {
       n[1].f = (GLfloat) zmin;
       n[2].f = (GLfloat) zmax;
@@ -4626,19 +4738,112 @@ save_ProgramEnvParameter4dvARB(GLenum target, GLuint index,
 #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) {
+      (*ctx->Exec->BeginQueryARB)( 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) {
+      (*ctx->Exec->EndQueryARB)( target );
+   }
+}
 
+#endif /* FEATURE_ARB_occlusion_query */
 
-static void save_Attr1f( GLenum attr, GLfloat x )
+
+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) {
+      (*ctx->Exec->DrawBuffersARB)(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) {
+      (*ctx->Exec->BindFragmentShaderATI)(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) {
+      (*ctx->Exec->SetFragmentShaderConstantATI)(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, 2 );
+   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);
 
@@ -4647,18 +4852,19 @@ static void save_Attr1f( GLenum attr, GLfloat x )
    }
 }
 
-static void save_Attr2f( GLenum attr, GLfloat x, GLfloat y )
+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, 3 );
+   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);
 
@@ -4667,12 +4873,12 @@ static void save_Attr2f( GLenum attr, GLfloat x, GLfloat y )
    }
 }
 
-static void save_Attr3f( GLenum attr, GLfloat x, GLfloat y, GLfloat z )
+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, 4 );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_ATTR_3F_NV, 4 );
    if (n) {
       n[1].e = attr;
       n[2].f = x;
@@ -4680,6 +4886,7 @@ static void save_Attr3f( GLenum attr, GLfloat x, GLfloat y, GLfloat z )
       n[4].f = z;
    }
 
+   ASSERT(attr < VERT_ATTRIB_MAX);
    ctx->ListState.ActiveAttribSize[attr] = 3;
    ASSIGN_4V( ctx->ListState.CurrentAttrib[attr], x, y, z, 1);
 
@@ -4688,13 +4895,13 @@ static void save_Attr3f( GLenum attr, GLfloat x, GLfloat y, GLfloat z )
    }
 }
 
-static void save_Attr4f( GLenum attr, GLfloat x, GLfloat y, GLfloat z,
-                        GLfloat w )
+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, 5 );
+   n = ALLOC_INSTRUCTION( ctx, OPCODE_ATTR_4F_NV, 5 );
    if (n) {
       n[1].e = attr;
       n[2].f = x;
@@ -4703,6 +4910,7 @@ static void save_Attr4f( GLenum attr, GLfloat x, GLfloat y, GLfloat 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);
 
@@ -4711,6 +4919,95 @@ static void save_Attr4f( GLenum attr, GLfloat x, GLfloat y, GLfloat z,
    }
 }
 
+
+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) {
+      (*ctx->Exec->VertexAttrib1fARB)( 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) {
+      (*ctx->Exec->VertexAttrib2fARB)( 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) {
+      (*ctx->Exec->VertexAttrib3fARB)( 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) {
+      (*ctx->Exec->VertexAttrib4fARB)( attr, x, y, z, w );
+   }
+}
+
+
 static void GLAPIENTRY save_EvalCoord1f( GLfloat x )
 {
    GET_CURRENT_CONTEXT(ctx);
@@ -4872,7 +5169,7 @@ static void GLAPIENTRY save_Materialfv( GLenum face, GLenum pname, const GLfloat
    }
 
    {
-      GLuint bitmask = _mesa_material_bitmask( ctx, face, pname, ~0, 0 );
+      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;
@@ -4940,8 +5237,7 @@ static void GLAPIENTRY save_End( void )
    }
 }
 
-static void GLAPIENTRY save_Rectf( GLfloat a, GLfloat b,
-                       GLfloat c, GLfloat d )
+static void GLAPIENTRY save_Rectf( GLfloat a, GLfloat b, GLfloat c, GLfloat d )
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
@@ -4958,126 +5254,125 @@ static void GLAPIENTRY save_Rectf( GLfloat a, GLfloat b,
    }
 }
 
-/*
- */
+
 static void GLAPIENTRY save_Vertex2f( GLfloat x, GLfloat y )
 {
-   save_Attr2f( VERT_ATTRIB_POS, x, y );
+   save_Attr2fNV( VERT_ATTRIB_POS, x, y );
 }
 
 static void GLAPIENTRY save_Vertex2fv( const GLfloat *v )
 {
-   save_Attr2f( VERT_ATTRIB_POS, v[0], v[1] );
+   save_Attr2fNV( VERT_ATTRIB_POS, v[0], v[1] );
 }
 
 static void GLAPIENTRY save_Vertex3f( GLfloat x, GLfloat y, GLfloat z )
 {
-   save_Attr3f( VERT_ATTRIB_POS, x, y, z );
+   save_Attr3fNV( VERT_ATTRIB_POS, x, y, z );
 }
 
 static void GLAPIENTRY save_Vertex3fv( const GLfloat *v )
 {
-   save_Attr3f( VERT_ATTRIB_POS, v[0], v[1], v[2] );
+   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_Attr4f( VERT_ATTRIB_POS, x, y, z, w );
+   save_Attr4fNV( VERT_ATTRIB_POS, x, y, z, w );
 }
 
 static void GLAPIENTRY save_Vertex4fv( const GLfloat *v )
 {
-   save_Attr4f( VERT_ATTRIB_POS, v[0], v[1], v[2], v[3] );
+   save_Attr4fNV( VERT_ATTRIB_POS, v[0], v[1], v[2], v[3] );
 }
 
 static void GLAPIENTRY save_TexCoord1f( GLfloat x )
 {
-   save_Attr1f( VERT_ATTRIB_TEX0, x );
+   save_Attr1fNV( VERT_ATTRIB_TEX0, x );
 }
 
 static void GLAPIENTRY save_TexCoord1fv( const GLfloat *v )
 {
-   save_Attr1f( VERT_ATTRIB_TEX0, v[0] );
+   save_Attr1fNV( VERT_ATTRIB_TEX0, v[0] );
 }
 
 static void GLAPIENTRY save_TexCoord2f( GLfloat x, GLfloat y )
 {
-   save_Attr2f( VERT_ATTRIB_TEX0, x, y );
+   save_Attr2fNV( VERT_ATTRIB_TEX0, x, y );
 }
 
 static void GLAPIENTRY save_TexCoord2fv( const GLfloat *v )
 {
-   save_Attr2f( VERT_ATTRIB_TEX0, v[0], v[1] );
+   save_Attr2fNV( VERT_ATTRIB_TEX0, v[0], v[1] );
 }
 
 static void GLAPIENTRY save_TexCoord3f( GLfloat x, GLfloat y, GLfloat z )
 {
-   save_Attr3f( VERT_ATTRIB_TEX0, x, y, z );
+   save_Attr3fNV( VERT_ATTRIB_TEX0, x, y, z );
 }
 
 static void GLAPIENTRY save_TexCoord3fv( const GLfloat *v )
 {
-   save_Attr3f( VERT_ATTRIB_TEX0, v[0], v[1], v[2] );
+   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_Attr4f( VERT_ATTRIB_TEX0, x, y, z, w );
+   save_Attr4fNV( VERT_ATTRIB_TEX0, x, y, z, w );
 }
 
 static void GLAPIENTRY save_TexCoord4fv( const GLfloat *v )
 {
-   save_Attr4f( VERT_ATTRIB_TEX0, v[0], v[1], v[2], v[3] );
+   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_Attr3f( VERT_ATTRIB_NORMAL, x, y, z );
+   save_Attr3fNV( VERT_ATTRIB_NORMAL, x, y, z );
 }
 
 static void GLAPIENTRY save_Normal3fv( const GLfloat *v )
 {
-   save_Attr3f( VERT_ATTRIB_NORMAL, v[0], v[1], v[2] );
+   save_Attr3fNV( VERT_ATTRIB_NORMAL, v[0], v[1], v[2] );
 }
 
 static void GLAPIENTRY save_FogCoordfEXT( GLfloat x )
 {
-   save_Attr1f( VERT_ATTRIB_FOG, x );
+   save_Attr1fNV( VERT_ATTRIB_FOG, x );
 }
 
 static void GLAPIENTRY save_FogCoordfvEXT( const GLfloat *v )
 {
-   save_Attr1f( VERT_ATTRIB_FOG, v[0] );
+   save_Attr1fNV( VERT_ATTRIB_FOG, v[0] );
 }
 
 static void GLAPIENTRY save_Color3f( GLfloat x, GLfloat y, GLfloat z )
 {
-   save_Attr3f( VERT_ATTRIB_COLOR0, x, y, z );
+   save_Attr3fNV( VERT_ATTRIB_COLOR0, x, y, z );
 }
 
 static void GLAPIENTRY save_Color3fv( const GLfloat *v )
 {
-   save_Attr3f( VERT_ATTRIB_COLOR0, v[0], v[1], v[2] );
+   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_Attr4f( VERT_ATTRIB_COLOR0, x, y, z, w );
+   save_Attr4fNV( VERT_ATTRIB_COLOR0, x, y, z, w );
 }
 
 static void GLAPIENTRY save_Color4fv( const GLfloat *v )
 {
-   save_Attr4f( VERT_ATTRIB_COLOR0, v[0], v[1], v[2], v[3] );
+   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_Attr3f( VERT_ATTRIB_COLOR1, x, y, z );
+   save_Attr3fNV( VERT_ATTRIB_COLOR1, x, y, z );
 }
 
 static void GLAPIENTRY save_SecondaryColor3fvEXT( const GLfloat *v )
 {
-   save_Attr3f( VERT_ATTRIB_COLOR1, v[0], v[1], v[2] );
+   save_Attr3fNV( VERT_ATTRIB_COLOR1, v[0], v[1], v[2] );
 }
 
 
@@ -5086,51 +5381,51 @@ static void GLAPIENTRY save_SecondaryColor3fvEXT( const GLfloat *v )
 static void GLAPIENTRY save_MultiTexCoord1f( GLenum target, GLfloat x  )
 {
    GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
-   save_Attr1f( attr, x );
+   save_Attr1fNV( attr, x );
 }
 
 static void GLAPIENTRY save_MultiTexCoord1fv( GLenum target, const GLfloat *v )
 {
    GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
-   save_Attr1f( attr, v[0] );
+   save_Attr1fNV( attr, v[0] );
 }
 
 static void GLAPIENTRY save_MultiTexCoord2f( GLenum target, GLfloat x, GLfloat y )
 {
    GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
-   save_Attr2f( attr, x, y );
+   save_Attr2fNV( attr, x, y );
 }
 
 static void GLAPIENTRY save_MultiTexCoord2fv( GLenum target, const GLfloat *v )
 {
    GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
-   save_Attr2f( attr, v[0], v[1] );
+   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_Attr3f( attr, x, y, z );
+   save_Attr3fNV( attr, x, y, z );
 }
 
 static void GLAPIENTRY save_MultiTexCoord3fv( GLenum target, const GLfloat *v )
 {
    GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
-   save_Attr3f( attr, v[0], v[1], v[2] );
+   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_Attr4f( attr, x, y, z, w );
+   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_Attr4f( attr, v[0], v[1], v[2], v[3] );
+   save_Attr4fNV( attr, v[0], v[1], v[2], v[3] );
 }
 
 
@@ -5147,7 +5442,7 @@ static void enum_error( void )
 static void GLAPIENTRY save_VertexAttrib1fNV( GLuint index, GLfloat x )
 {
    if (index < VERT_ATTRIB_MAX)
-      save_Attr1f( index, x );
+      save_Attr1fNV( index, x );
    else
       enum_error(); 
 }
@@ -5155,7 +5450,7 @@ static void GLAPIENTRY save_VertexAttrib1fNV( GLuint index, GLfloat x )
 static void GLAPIENTRY save_VertexAttrib1fvNV( GLuint index, const GLfloat *v )
 {
    if (index < VERT_ATTRIB_MAX)
-      save_Attr1f( index, v[0] );
+      save_Attr1fNV( index, v[0] );
    else
       enum_error();
 }
@@ -5163,7 +5458,7 @@ static void GLAPIENTRY save_VertexAttrib1fvNV( GLuint index, const GLfloat *v )
 static void GLAPIENTRY save_VertexAttrib2fNV( GLuint index, GLfloat x, GLfloat y )
 {
    if (index < VERT_ATTRIB_MAX)
-      save_Attr2f( index, x, y );
+      save_Attr2fNV( index, x, y );
    else
       enum_error();
 }
@@ -5171,7 +5466,7 @@ static void GLAPIENTRY save_VertexAttrib2fNV( GLuint index, GLfloat x, GLfloat y
 static void GLAPIENTRY save_VertexAttrib2fvNV( GLuint index, const GLfloat *v )
 {
    if (index < VERT_ATTRIB_MAX)
-      save_Attr2f( index, v[0], v[1] );
+      save_Attr2fNV( index, v[0], v[1] );
    else
       enum_error();
 }
@@ -5180,7 +5475,7 @@ static void GLAPIENTRY save_VertexAttrib3fNV( GLuint index, GLfloat x, GLfloat y
                                   GLfloat z )
 {
    if (index < VERT_ATTRIB_MAX)
-      save_Attr3f( index, x, y, z );
+      save_Attr3fNV( index, x, y, z );
    else
       enum_error();
 }
@@ -5188,7 +5483,7 @@ static void GLAPIENTRY save_VertexAttrib3fNV( GLuint index, GLfloat x, GLfloat y
 static void GLAPIENTRY save_VertexAttrib3fvNV( GLuint index, const GLfloat *v )
 {
    if (index < VERT_ATTRIB_MAX)
-      save_Attr3f( index, v[0], v[1], v[2] );
+      save_Attr3fNV( index, v[0], v[1], v[2] );
    else
       enum_error();
 }
@@ -5197,7 +5492,7 @@ static void GLAPIENTRY save_VertexAttrib4fNV( GLuint index, GLfloat x, GLfloat y
                                   GLfloat z, GLfloat w )
 {
    if (index < VERT_ATTRIB_MAX)
-      save_Attr4f( index, x, y, z, w );
+      save_Attr4fNV( index, x, y, z, w );
    else
       enum_error();
 }
@@ -5205,7 +5500,82 @@ static void GLAPIENTRY save_VertexAttrib4fNV( GLuint index, GLfloat x, GLfloat y
 static void GLAPIENTRY save_VertexAttrib4fvNV( GLuint index, const GLfloat *v )
 {
    if (index < VERT_ATTRIB_MAX)
-      save_Attr4f( index, v[0], v[1], v[2], v[3] );
+      save_Attr4fNV( index, v[0], v[1], v[2], v[3] );
+   else
+      enum_error();
+}
+
+
+
+
+static void GLAPIENTRY
+save_VertexAttrib1fARB( GLuint index, GLfloat x )
+{
+   if (index < VERT_ATTRIB_MAX)
+      save_Attr1fARB( index, x );
+   else
+      enum_error(); 
+}
+
+static void GLAPIENTRY
+save_VertexAttrib1fvARB( GLuint index, const GLfloat *v )
+{
+   if (index < VERT_ATTRIB_MAX)
+      save_Attr1fARB( index, v[0] );
+   else
+      enum_error();
+}
+
+static void GLAPIENTRY
+save_VertexAttrib2fARB( GLuint index, GLfloat x, GLfloat y )
+{
+   if (index < VERT_ATTRIB_MAX)
+      save_Attr2fARB( index, x, y );
+   else
+      enum_error();
+}
+
+static void GLAPIENTRY
+save_VertexAttrib2fvARB( GLuint index, const GLfloat *v )
+{
+   if (index < VERT_ATTRIB_MAX)
+      save_Attr2fARB( index, v[0], v[1] );
+   else
+      enum_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
+      enum_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
+      enum_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
+      enum_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
       enum_error();
 }
@@ -5274,18 +5644,29 @@ islist(GLcontext *ctx, GLuint list)
 static void GLAPIENTRY
 execute_list( GLcontext *ctx, GLuint list )
 {
+   struct mesa_display_list *dlist;
    Node *n;
    GLboolean done;
 
    if (list == 0 || !islist(ctx,list))
       return;
 
-   if (ctx->Driver.BeginCallList)
-      ctx->Driver.BeginCallList( ctx, list );
+   if (ctx->ListState.CallDepth == MAX_LIST_NESTING) {
+      /* raise an error? */
+      return;
+   }
+
 
-   ctx->ListState.CallDepth++;
+   dlist = (struct mesa_display_list *) _mesa_HashLookup(ctx->Shared->DisplayList, list);
+   if (!dlist)
+      return;
+
+   ctx->ListState.CallStack[ctx->ListState.CallDepth++] = dlist;
 
-   n = (Node *) _mesa_HashLookup(ctx->Shared->DisplayList, list);
+   if (ctx->Driver.BeginCallList)
+      ctx->Driver.BeginCallList( ctx, dlist );
+
+   n = dlist->node;
 
    done = GL_FALSE;
    while (!done) {
@@ -5753,6 +6134,15 @@ execute_list( GLcontext *ctx, GLuint list )
         case OPCODE_STENCIL_OP:
            (*ctx->Exec->StencilOp)( n[1].e, n[2].e, n[3].e );
            break;
+        case OPCODE_STENCIL_FUNC_SEPARATE:
+           ctx->Exec->StencilFuncSeparate( n[1].e, n[2].e, n[3].i, n[4].ui );
+           break;
+        case OPCODE_STENCIL_MASK_SEPARATE:
+           ctx->Exec->StencilMaskSeparate( n[1].e, n[2].ui );
+           break;
+        case OPCODE_STENCIL_OP_SEPARATE:
+           ctx->Exec->StencilOpSeparate( n[1].e, n[2].e, n[3].e, n[4].e );
+           break;
          case OPCODE_TEXENV:
             {
                GLfloat params[4];
@@ -5975,21 +6365,107 @@ execute_list( GLcontext *ctx, GLuint list )
                                                    n[4].f, n[5].f, n[6].f);
             break;
 #endif
-
-        case OPCODE_ATTR_1F:
+#if FEATURE_ARB_occlusion_query
+         case OPCODE_BEGIN_QUERY_ARB:
+            ctx->Exec->BeginQueryARB(n[1].e, n[2].ui);
+            break;
+         case OPCODE_END_QUERY_ARB:
+            ctx->Exec->EndQueryARB(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;
+              ctx->Exec->DrawBuffersARB(n[1].i, buffers);
+           }
+            break;
+#if FEATURE_ATI_fragment_shader
+        case OPCODE_BIND_FRAGMENT_SHADER_ATI:
+           ctx->Exec->BindFragmentShaderATI(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;
+              ctx->Exec->SetFragmentShaderConstantATI(dst, values);
+           }
+           break;
+#endif
+        case OPCODE_ATTR_1F_NV:
            (*ctx->Exec->VertexAttrib1fNV)(n[1].e, n[2].f);
            break;
-        case OPCODE_ATTR_2F:
-           (*ctx->Exec->VertexAttrib2fvNV)(n[1].e, &n[2].f);
+        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)) 
+              (*ctx->Exec->VertexAttrib2fvNV)(n[1].e, &n[2].f);
+           else
+              (*ctx->Exec->VertexAttrib2fNV)(n[1].e, n[2].f, n[3].f);
+           break;
+        case OPCODE_ATTR_3F_NV:
+           if (sizeof(Node)==sizeof(GLfloat)) 
+              (*ctx->Exec->VertexAttrib3fvNV)(n[1].e, &n[2].f);
+           else
+              (*ctx->Exec->VertexAttrib3fNV)(n[1].e, n[2].f, n[3].f,
+                                             n[4].f);
+           break;
+        case OPCODE_ATTR_4F_NV:
+           if (sizeof(Node)==sizeof(GLfloat)) 
+              (*ctx->Exec->VertexAttrib4fvNV)(n[1].e, &n[2].f);
+           else
+              (*ctx->Exec->VertexAttrib4fNV)(n[1].e, n[2].f, n[3].f,
+                                             n[4].f, n[5].f);
+           break;
+        case OPCODE_ATTR_1F_ARB:
+           (*ctx->Exec->VertexAttrib1fARB)(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)) 
+              (*ctx->Exec->VertexAttrib2fvARB)(n[1].e, &n[2].f);
+           else
+              (*ctx->Exec->VertexAttrib2fARB)(n[1].e, n[2].f, n[3].f);
            break;
-        case OPCODE_ATTR_3F:
-           (*ctx->Exec->VertexAttrib3fvNV)(n[1].e, &n[2].f);
+        case OPCODE_ATTR_3F_ARB:
+           if (sizeof(Node)==sizeof(GLfloat)) 
+              (*ctx->Exec->VertexAttrib3fvARB)(n[1].e, &n[2].f);
+           else
+              (*ctx->Exec->VertexAttrib3fARB)(n[1].e, n[2].f, n[3].f,
+                                             n[4].f);
            break;
-        case OPCODE_ATTR_4F:
-           (*ctx->Exec->VertexAttrib4fvNV)(n[1].e, &n[2].f);
+        case OPCODE_ATTR_4F_ARB:
+           if (sizeof(Node)==sizeof(GLfloat)) 
+              (*ctx->Exec->VertexAttrib4fvARB)(n[1].e, &n[2].f);
+           else
+              (*ctx->Exec->VertexAttrib4fARB)(n[1].e, n[2].f, n[3].f,
+                                             n[4].f, n[5].f);
            break;
         case OPCODE_MATERIAL:
-           (*ctx->Exec->Materialfv)(n[1].e, n[2].e, &n[3].f);
+           if (sizeof(Node)==sizeof(GLfloat)) 
+              (*ctx->Exec->Materialfv)(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;
+              (*ctx->Exec->Materialfv)(n[1].e, n[2].e, f);
+           }
            break;
         case OPCODE_INDEX:
            (*ctx->Exec->Indexi)(n[1].i);
@@ -6010,7 +6486,7 @@ execute_list( GLcontext *ctx, GLuint list )
            (*ctx->Exec->EvalCoord1f)(n[1].f);
            break;
         case OPCODE_EVAL_C2:
-           (*ctx->Exec->EvalCoord2fv)(&n[1].f);
+           (*ctx->Exec->EvalCoord2f)(n[1].f, n[2].f);
            break;
         case OPCODE_EVAL_P1:
            (*ctx->Exec->EvalPoint1)(n[1].i);
@@ -6043,10 +6519,11 @@ execute_list( GLcontext *ctx, GLuint list )
         }
       }
    }
-   ctx->ListState.CallDepth--;
 
    if (ctx->Driver.EndCallList)
       ctx->Driver.EndCallList( ctx );
+
+   ctx->ListState.CallStack[ctx->ListState.CallDepth--] = NULL;
 }
 
 
@@ -6125,7 +6602,7 @@ _mesa_GenLists(GLsizei range )
       /* 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_empty_list());
+         _mesa_HashInsert(ctx->Shared->DisplayList, base+i, make_list(base+i, 1));
       }
    }
 
@@ -6173,7 +6650,8 @@ _mesa_NewList( GLuint list, GLenum mode )
 
    /* Allocate new display list */
    ctx->ListState.CurrentListNum = list;
-   ctx->ListState.CurrentBlock = (Node *) CALLOC( sizeof(Node) * BLOCK_SIZE );
+   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;
 
@@ -6221,19 +6699,20 @@ _mesa_EndList( void )
    /* 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.CurrentListPtr);
+   _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->Driver.EndList( ctx );
-
    ctx->CurrentDispatch = ctx->Exec;
    _glapi_set_dispatch( ctx->CurrentDispatch );
 }
@@ -7028,10 +7507,8 @@ static void GLAPIENTRY exec_MultiModeDrawElementsIBM(const GLenum *mode,
  * struct.
  */
 void
-_mesa_init_dlist_table( struct _glapi_table *table, GLuint tableSize )
+_mesa_init_dlist_table( struct _glapi_table *table )
 {
-   _mesa_init_no_op_table(table, tableSize);
-
    _mesa_loopback_init_api_table( table );
 
    /* GL 1.0 */
@@ -7245,6 +7722,11 @@ _mesa_init_dlist_table( struct _glapi_table *table, GLuint tableSize )
    table->TexImage3D = save_TexImage3D;
    table->TexSubImage3D = save_TexSubImage3D;
 
+   /* GL 2.0 */
+   table->StencilFuncSeparate = save_StencilFuncSeparate;
+   table->StencilMaskSeparate = save_StencilMaskSeparate;
+   table->StencilOpSeparate = save_StencilOpSeparate;
+
    /* GL_ARB_imaging */
    /* Not all are supported */
    table->BlendColor = save_BlendColor;
@@ -7430,6 +7912,12 @@ _mesa_init_dlist_table( struct _glapi_table *table, GLuint tableSize )
    table->VertexAttribPointerNV = _mesa_VertexAttribPointerNV;
 #endif
 
+   /* 245. GL_ATI_fragment_shader */
+#if FEATURE_ATI_fragment_shader
+   table->BindFragmentShaderATI = save_BindFragmentShaderATI;
+   table->SetFragmentShaderConstantATI = save_SetFragmentShaderConstantATI;
+#endif
+
    /* 282. GL_NV_fragment_program */
 #if FEATURE_NV_fragment_program
    table->ProgramNamedParameter4fNV = save_ProgramNamedParameter4fNV;
@@ -7532,6 +8020,18 @@ _mesa_init_dlist_table( struct _glapi_table *table, GLuint tableSize )
    table->UnmapBufferARB = _mesa_UnmapBufferARB;
 #endif
 
+#if FEATURE_ARB_occlusion_query
+   table->BeginQueryARB = save_BeginQueryARB;
+   table->EndQueryARB = save_EndQueryARB;
+   table->GenQueriesARB = _mesa_GenQueriesARB;
+   table->DeleteQueriesARB = _mesa_DeleteQueriesARB;
+   table->IsQueryARB = _mesa_IsQueryARB;
+   table->GetQueryivARB = _mesa_GetQueryivARB;
+   table->GetQueryObjectivARB = _mesa_GetQueryObjectivARB;
+   table->GetQueryObjectuivARB = _mesa_GetQueryObjectuivARB;
+#endif
+   table->DrawBuffersARB = save_DrawBuffersARB;
+
    /* 299. GL_EXT_blend_equation_separate */
    table->BlendEquationSeparateEXT = save_BlendEquationSeparateEXT;
 }
@@ -7553,16 +8053,21 @@ static const char *enum_string( GLenum k )
  */
 static void GLAPIENTRY print_list( GLcontext *ctx, GLuint list )
 {
+   struct mesa_display_list *dlist;
    Node *n;
    GLboolean done;
 
-   if (!glIsList(list)) {
+   if (!GL_CALL(IsList)(list)) {
       _mesa_printf("%u is not a display list ID\n", list);
       return;
    }
 
-   n = (Node *) _mesa_HashLookup(ctx->Shared->DisplayList, list);
+   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;
@@ -7711,6 +8216,73 @@ static void GLAPIENTRY print_list( GLcontext *ctx, GLuint list )
                          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
          */
@@ -7821,6 +8393,14 @@ void _mesa_save_vtxfmt_init( GLvertexformat *vfmt )
    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;