Merge commit 'origin/gallium-0.1' into gallium-0.2
[mesa.git] / src / mesa / vbo / vbo_save_draw.c
index a50d1cd9049862be3ab45595f38a254e80b100c3..0488c5d718295dac46ea38d6f4e07c90e2c2d33a 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.1
+ * Version:  7.2
  *
- * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2008  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"),
  *    Keith Whitwell <keith@tungstengraphics.com>
  */
 
-#include "glheader.h"
-#include "context.h"
-#include "imports.h"
-#include "mtypes.h"
-#include "macros.h"
-#include "light.h"
-#include "state.h"
+#include "main/glheader.h"
+#include "main/bufferobj.h"
+#include "main/context.h"
+#include "main/imports.h"
+#include "main/mtypes.h"
+#include "main/macros.h"
+#include "main/light.h"
+#include "main/state.h"
 
 #include "vbo_context.h"
 
@@ -58,21 +59,31 @@ static void _playback_copy_to_current( GLcontext *ctx,
                                 node->vertex_size * sizeof(GLfloat), 
                                 data, node->vertex_store->bufferobj );
 
+   data += node->attrsz[0]; /* skip vertex position */
+
    for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++) {
       if (node->attrsz[i]) {
         GLfloat *current = (GLfloat *)vbo->currval[i].Ptr;
+         GLfloat tmp[4];
 
-        COPY_CLEAN_4V(current, 
-                      node->attrsz[i], 
-                      data);
+         COPY_CLEAN_4V(tmp, 
+                       node->attrsz[i], 
+                       data);
+         
+         if (memcmp(current, tmp, 4 * sizeof(GLfloat)) != 0)
+         {
+            memcpy(current, tmp, 4 * sizeof(GLfloat));
 
-        vbo->currval[i].Size = node->attrsz[i];
+            vbo->currval[i].Size = node->attrsz[i];
 
-        data += node->attrsz[i];
+            if (i >= VBO_ATTRIB_FIRST_MATERIAL &&
+                i <= VBO_ATTRIB_LAST_MATERIAL)
+               ctx->NewState |= _NEW_LIGHT;
 
-        if (i >= VBO_ATTRIB_FIRST_MATERIAL &&
-            i <= VBO_ATTRIB_LAST_MATERIAL)
-           ctx->NewState |= _NEW_LIGHT;
+            ctx->NewState |= _NEW_CURRENT_ATTRIB;
+         }
+
+        data += node->attrsz[i];
       }
    }
 
@@ -107,14 +118,19 @@ static void vbo_bind_vertex_list( GLcontext *ctx,
    GLuint data = node->buffer_offset;
    const GLuint *map;
    GLuint attr;
+   GLbitfield varying_inputs = 0x0;
 
    /* Install the default (ie Current) attributes first, then overlay
     * all active ones.
     */
    switch (get_program_mode(ctx)) {
    case VP_NONE:
-      memcpy(arrays,      vbo->legacy_currval, 16 * sizeof(arrays[0]));
-      memcpy(arrays + 16, vbo->mat_currval,    MAT_ATTRIB_MAX * sizeof(arrays[0]));
+      for (attr = 0; attr < 16; attr++) {
+         save->inputs[attr] = &vbo->legacy_currval[attr];
+      }
+      for (attr = 0; attr < MAT_ATTRIB_MAX; attr++) {
+         save->inputs[attr + 16] = &vbo->mat_currval[attr];
+      }
       map = vbo->map_vp_none;
       break;
    case VP_NV:
@@ -123,28 +139,40 @@ static void vbo_bind_vertex_list( GLcontext *ctx,
        * occurred.  NV vertex programs cannot access material values,
        * nor attributes greater than VERT_ATTRIB_TEX7.  
        */
-      memcpy(arrays,      vbo->legacy_currval,  16 * sizeof(arrays[0]));
-      memcpy(arrays + 16, vbo->generic_currval, 16 * sizeof(arrays[0]));
+      for (attr = 0; attr < 16; attr++) {
+         save->inputs[attr] = &vbo->legacy_currval[attr];
+         save->inputs[attr + 16] = &vbo->generic_currval[attr];
+      }
       map = vbo->map_vp_arb;
       break;
    }
 
-   for (attr = 0; attr < VBO_ATTRIB_MAX; attr++) {
-      if (node->attrsz[attr]) {
-        arrays[attr].Ptr = (const GLubyte *)data;
-        arrays[attr].Size = node->attrsz[attr];
+   for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) {
+      GLuint src = map[attr];
+
+      if (node->attrsz[src]) {
+         /* override the default array set above */
+         save->inputs[attr] = &arrays[attr];
+
+        arrays[attr].Ptr = (const GLubyte *) data;
+        arrays[attr].Size = node->attrsz[src];
         arrays[attr].StrideB = node->vertex_size * sizeof(GLfloat);
         arrays[attr].Stride = node->vertex_size * sizeof(GLfloat);
         arrays[attr].Type = GL_FLOAT;
         arrays[attr].Enabled = 1;
-        arrays[attr].BufferObj = node->vertex_store->bufferobj;
+         _mesa_reference_buffer_object(ctx,
+                                       &arrays[attr].BufferObj,
+                                       node->vertex_store->bufferobj);
         arrays[attr]._MaxElement = node->count; /* ??? */
         
         assert(arrays[attr].BufferObj->Name);
 
-        data += node->attrsz[attr] * sizeof(GLfloat);
+        data += node->attrsz[src] * sizeof(GLfloat);
+         varying_inputs |= 1<<attr;
       }
    }
+
+   _mesa_set_varying_vp_inputs( ctx, varying_inputs );
 }
 
 static void vbo_save_loopback_vertex_list( GLcontext *ctx,
@@ -203,6 +231,7 @@ void vbo_save_playback_vertex_list( GLcontext *ctx, void *data )
       if (ctx->NewState)
         _mesa_update_state( ctx );
 
+      /* XXX also need to check if shader enabled, but invalid */
       if ((ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) ||
           (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled)) {
          _mesa_error(ctx, GL_INVALID_OPERATION,
@@ -212,13 +241,18 @@ void vbo_save_playback_vertex_list( GLcontext *ctx, void *data )
 
       vbo_bind_vertex_list( ctx, node );
 
+      /* Again...
+       */
+      if (ctx->NewState)
+        _mesa_update_state( ctx );
+
       vbo_context(ctx)->draw_prims( ctx, 
                                    save->inputs, 
                                    node->prim, 
                                    node->prim_count,
                                    NULL,
                                    0,  /* Node is a VBO, so this is ok */
-                                   node->count );
+                                   node->count - 1);
    }
 
    /* Copy to current?