Merge commit 'origin/master' into gallium-0.2
[mesa.git] / src / mesa / main / dlist.c
index f933580b2d938f4be478ec62c21379e4d2e7807f..f7660930a9c39e8d7c90b9deef6f601591f25c1d 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.5.1
+ * Version:  7.1
  *
- * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2007  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"),
@@ -52,6 +52,7 @@
 #include "eval.h"
 #include "extensions.h"
 #include "feedback.h"
+#include "framebuffer.h"
 #include "get.h"
 #include "glapi/glapi.h"
 #include "hash.h"
@@ -611,9 +612,9 @@ destroy_list(GLcontext *ctx, GLuint list)
 
 
 /*
- * Translate the nth element of list from type to GLuint.
+ * Translate the nth element of list from <type> to GLint.
  */
-static GLuint
+static GLint
 translate_id(GLsizei n, GLenum type, const GLvoid * list)
 {
    GLbyte *bptr;
@@ -627,37 +628,40 @@ translate_id(GLsizei n, GLenum type, const GLvoid * list)
    switch (type) {
    case GL_BYTE:
       bptr = (GLbyte *) list;
-      return (GLuint) *(bptr + n);
+      return (GLint) bptr[n];
    case GL_UNSIGNED_BYTE:
       ubptr = (GLubyte *) list;
-      return (GLuint) *(ubptr + n);
+      return (GLint) ubptr[n];
    case GL_SHORT:
       sptr = (GLshort *) list;
-      return (GLuint) *(sptr + n);
+      return (GLint) sptr[n];
    case GL_UNSIGNED_SHORT:
       usptr = (GLushort *) list;
-      return (GLuint) *(usptr + n);
+      return (GLint) usptr[n];
    case GL_INT:
       iptr = (GLint *) list;
-      return (GLuint) *(iptr + n);
+      return iptr[n];
    case GL_UNSIGNED_INT:
       uiptr = (GLuint *) list;
-      return (GLuint) *(uiptr + n);
+      return (GLint) uiptr[n];
    case GL_FLOAT:
       fptr = (GLfloat *) list;
-      return (GLuint) *(fptr + n);
+      return (GLint) FLOORF(fptr[n]);
    case GL_2_BYTES:
       ubptr = ((GLubyte *) list) + 2 * n;
-      return (GLuint) *ubptr * 256 + (GLuint) * (ubptr + 1);
+      return (GLint) ubptr[0] * 256
+           + (GLint) ubptr[1];
    case GL_3_BYTES:
       ubptr = ((GLubyte *) list) + 3 * n;
-      return (GLuint) * ubptr * 65536
-           + (GLuint) *(ubptr + 1) * 256 + (GLuint) * (ubptr + 2);
+      return (GLint) ubptr[0] * 65536
+           + (GLint) ubptr[1] * 256
+           + (GLint) 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);
+      return (GLint) ubptr[0] * 16777216
+           + (GLint) ubptr[1] * 65536
+           + (GLint) ubptr[2] * 256
+           + (GLint) ubptr[3];
    default:
       return 0;
    }
@@ -924,6 +928,13 @@ save_BlendFuncSeparateEXT(GLenum sfactorRGB, GLenum dfactorRGB,
 }
 
 
+static void GLAPIENTRY
+save_BlendFunc(GLenum srcfactor, GLenum dstfactor)
+{
+   save_BlendFuncSeparateEXT(srcfactor, dstfactor, srcfactor, dstfactor);
+}
+
+
 static void GLAPIENTRY
 save_BlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
 {
@@ -992,10 +1003,10 @@ _mesa_save_CallLists(GLsizei n, GLenum type, const GLvoid * lists)
    }
 
    for (i = 0; i < n; i++) {
-      GLuint list = translate_id(i, type, lists);
+      GLint list = translate_id(i, type, lists);
       Node *n = ALLOC_INSTRUCTION(ctx, OPCODE_CALL_LIST_OFFSET, 2);
       if (n) {
-         n[1].ui = list;
+         n[1].i = list;
          n[2].b = typeErrorFlag;
       }
    }
@@ -2715,21 +2726,20 @@ save_PolygonMode(GLenum face, GLenum mode)
 }
 
 
-/*
- * Polygon stipple must have been upacked already!
- */
 static void GLAPIENTRY
 save_PolygonStipple(const GLubyte * pattern)
 {
    GET_CURRENT_CONTEXT(ctx);
+   GLvoid *image = unpack_image(2, 32, 32, 1, GL_COLOR_INDEX, GL_BITMAP,
+                                pattern, &ctx->Unpack);
    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);
+      n[1].data = image; 
+   }
+   else if (image) {
+      _mesa_free(image);
    }
    if (ctx->ExecuteFlag) {
       CALL_PolygonStipple(ctx->Exec, ((GLubyte *) pattern));
@@ -3245,6 +3255,36 @@ save_StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
 }
 
 
+static void GLAPIENTRY
+save_StencilFuncSeparateATI(GLenum frontfunc, GLenum backfunc, GLint ref,
+                            GLuint mask)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   /* GL_FRONT */
+   n = ALLOC_INSTRUCTION(ctx, OPCODE_STENCIL_FUNC_SEPARATE, 4);
+   if (n) {
+      n[1].e = GL_FRONT;
+      n[2].e = frontfunc;
+      n[3].i = ref;
+      n[4].ui = mask;
+   }
+   /* GL_BACK */
+   n = ALLOC_INSTRUCTION(ctx, OPCODE_STENCIL_FUNC_SEPARATE, 4);
+   if (n) {
+      n[1].e = GL_BACK;
+      n[2].e = backfunc;
+      n[3].i = ref;
+      n[4].ui = mask;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_StencilFuncSeparate(ctx->Exec, (GL_FRONT, frontfunc, ref, mask));
+      CALL_StencilFuncSeparate(ctx->Exec, (GL_BACK, backfunc, ref, mask));
+   }
+}
+
+
 static void GLAPIENTRY
 save_StencilMaskSeparate(GLenum face, GLuint mask)
 {
@@ -5579,6 +5619,27 @@ save_VertexAttrib4fvARB(GLuint index, const GLfloat * v)
 }
 
 
+/* GL_ARB_shader_objects, GL_ARB_vertex/fragment_shader */
+
+static void GLAPIENTRY
+exec_BindAttribLocationARB(GLuint program, GLuint index, const GLchar *name)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   FLUSH_VERTICES(ctx, 0);
+   CALL_BindAttribLocationARB(ctx->Exec, (program, index, name));
+}
+
+static GLint GLAPIENTRY
+exec_GetAttribLocationARB(GLuint program, const GLchar *name)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   FLUSH_VERTICES(ctx, 0);
+   return CALL_GetAttribLocationARB(ctx->Exec, (program, name));
+}
+/* XXX more shader functions needed here */
+
+
+
 #if FEATURE_EXT_framebuffer_blit
 static void GLAPIENTRY
 save_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
@@ -5687,7 +5748,7 @@ execute_list(GLcontext *ctx, GLuint list)
    if (!dlist)
       return;
 
-   ctx->ListState.CallStack[ctx->ListState.CallDepth++] = dlist;
+   ctx->ListState.CallDepth++;
 
    if (ctx->Driver.BeginCallList)
       ctx->Driver.BeginCallList(ctx, dlist);
@@ -5754,7 +5815,8 @@ execute_list(GLcontext *ctx, GLuint list)
                _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);
+               GLuint list = (GLuint) (ctx->List.ListBase + n[1].i);
+               execute_list(ctx, list);
             }
             break;
          case OPCODE_CLEAR:
@@ -6118,7 +6180,12 @@ execute_list(GLcontext *ctx, GLuint list)
             CALL_PolygonMode(ctx->Exec, (n[1].e, n[2].e));
             break;
          case OPCODE_POLYGON_STIPPLE:
-            CALL_PolygonStipple(ctx->Exec, ((GLubyte *) n[1].data));
+            {
+               const struct gl_pixelstore_attrib save = ctx->Unpack;
+               ctx->Unpack = ctx->DefaultPacking;
+               CALL_PolygonStipple(ctx->Exec, ((GLubyte *) n[1].data));
+               ctx->Unpack = save;      /* restore */
+            }
             break;
          case OPCODE_POLYGON_OFFSET:
             CALL_PolygonOffset(ctx->Exec, (n[1].f, n[2].f));
@@ -6569,7 +6636,7 @@ execute_list(GLcontext *ctx, GLuint list)
    if (ctx->Driver.EndCallList)
       ctx->Driver.EndCallList(ctx);
 
-   ctx->ListState.CallStack[ctx->ListState.CallDepth--] = NULL;
+   ctx->ListState.CallDepth--;
 }
 
 
@@ -6729,6 +6796,11 @@ _mesa_EndList(void)
       _mesa_error(ctx, GL_INVALID_OPERATION, "glEndList");
       return;
    }
+   
+   /* Call before emitting END_OF_LIST, in case the driver wants to
+    * emit opcodes itself.
+    */
+   ctx->Driver.EndList(ctx);
 
    (void) ALLOC_INSTRUCTION(ctx, OPCODE_END_OF_LIST, 0);
 
@@ -6742,8 +6814,6 @@ _mesa_EndList(void)
    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;
@@ -6797,7 +6867,6 @@ void GLAPIENTRY
 _mesa_CallLists(GLsizei n, GLenum type, const GLvoid * lists)
 {
    GET_CURRENT_CONTEXT(ctx);
-   GLuint list;
    GLint i;
    GLboolean save_compile_flag;
 
@@ -6829,8 +6898,8 @@ _mesa_CallLists(GLsizei n, GLenum type, const GLvoid * lists)
    ctx->CompileFlag = GL_FALSE;
 
    for (i = 0; i < n; i++) {
-      list = translate_id(i, type, lists);
-      execute_list(ctx, ctx->List.ListBase + list);
+      GLuint list = (GLuint) (ctx->List.ListBase + translate_id(i, type, lists));
+      execute_list(ctx, list);
    }
 
    ctx->CompileFlag = save_compile_flag;
@@ -7601,7 +7670,7 @@ _mesa_init_dlist_table(struct _glapi_table *table)
    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_BlendFunc(table, save_BlendFunc);
    SET_CallList(table, _mesa_save_CallList);
    SET_CallLists(table, _mesa_save_CallLists);
    SET_Clear(table, save_Clear);
@@ -7810,6 +7879,9 @@ _mesa_init_dlist_table(struct _glapi_table *table)
    SET_StencilMaskSeparate(table, save_StencilMaskSeparate);
    SET_StencilOpSeparate(table, save_StencilOpSeparate);
 
+   /* ATI_separate_stencil */ 
+   SET_StencilFuncSeparateATI(table, save_StencilFuncSeparateATI);
+
    /* GL_ARB_imaging */
    /* Not all are supported */
    SET_BlendColor(table, save_BlendColor);
@@ -8107,6 +8179,11 @@ _mesa_init_dlist_table(struct _glapi_table *table)
    SET_BlitFramebufferEXT(table, save_BlitFramebufferEXT);
 #endif
 
+   /* ARB 30/31/32. GL_ARB_shader_objects, GL_ARB_vertex/fragment_shader */
+   SET_BindAttribLocationARB(table, exec_BindAttribLocationARB);
+   SET_GetAttribLocationARB(table, exec_GetAttribLocationARB);
+   /* XXX additional functions need to be implemented here! */
+
    /* 299. GL_EXT_blend_equation_separate */
    SET_BlendEquationSeparateEXT(table, save_BlendEquationSeparateEXT);