i965/vec4: Simplify src/dst_reg to brw_reg conversion by using byte_offset().
[mesa.git] / src / mesa / vbo / vbo_save_draw.c
index 51ccbd2c2cad8c489260a3b2ea276970307e2317..507ab82a9078fc1e9d7343fe020691c84baa8379 100644 (file)
@@ -1,6 +1,5 @@
 /*
  * Mesa 3-D graphics library
- * Version:  7.2
  *
  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
  *
  * 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
- * THE AUTHORS 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.
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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>
+ *    Keith Whitwell <keithw@vmware.com>
  */
 
 #include "main/glheader.h"
@@ -34,6 +34,7 @@
 #include "main/macros.h"
 #include "main/light.h"
 #include "main/state.h"
+#include "util/bitscan.h"
 
 #include "vbo_context.h"
 
@@ -47,9 +48,10 @@ _playback_copy_to_current(struct gl_context *ctx,
                           const struct vbo_save_vertex_list *node)
 {
    struct vbo_context *vbo = vbo_context(ctx);
-   GLfloat vertex[VBO_ATTRIB_MAX * 4];
-   GLfloat *data;
-   GLuint i, offset;
+   fi_type vertex[VBO_ATTRIB_MAX * 4];
+   fi_type *data;
+   GLbitfield64 mask;
+   GLuint offset;
 
    if (node->current_size == 0)
       return;
@@ -73,35 +75,36 @@ _playback_copy_to_current(struct gl_context *ctx,
       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_TYPE_AS_FLOAT(tmp,
-                                     node->attrsz[i],
-                                     data,
-                                     node->attrtype[i]);
+   mask = node->enabled & (~BITFIELD64_BIT(VBO_ATTRIB_POS));
+   while (mask) {
+      const int i = u_bit_scan64(&mask);
+      fi_type *current = (fi_type *)vbo->currval[i].Ptr;
+      fi_type tmp[4];
+      assert(node->attrsz[i]);
+
+      COPY_CLEAN_4V_TYPE_AS_UNION(tmp,
+                                  node->attrsz[i],
+                                  data,
+                                  node->attrtype[i]);
+
+      if (node->attrtype[i] != vbo->currval[i].Type ||
+          memcmp(current, tmp, 4 * sizeof(GLfloat)) != 0) {
+         memcpy(current, tmp, 4 * sizeof(GLfloat));
          
-         if (node->attrtype[i] != vbo->currval[i].Type ||
-             memcmp(current, tmp, 4 * sizeof(GLfloat)) != 0) {
-            memcpy(current, tmp, 4 * sizeof(GLfloat));
-
-            vbo->currval[i].Size = node->attrsz[i];
-            vbo->currval[i]._ElementSize = vbo->currval[i].Size * sizeof(GLfloat);
-            vbo->currval[i].Type = node->attrtype[i];
-            vbo->currval[i].Integer =
-                  vbo_attrtype_to_integer_flag(node->attrtype[i]);
-
-            if (i >= VBO_ATTRIB_FIRST_MATERIAL &&
-                i <= VBO_ATTRIB_LAST_MATERIAL)
-               ctx->NewState |= _NEW_LIGHT;
+         vbo->currval[i].Size = node->attrsz[i];
+         vbo->currval[i]._ElementSize = vbo->currval[i].Size * sizeof(GLfloat);
+         vbo->currval[i].Type = node->attrtype[i];
+         vbo->currval[i].Integer =
+            vbo_attrtype_to_integer_flag(node->attrtype[i]);
 
-            ctx->NewState |= _NEW_CURRENT_ATTRIB;
-         }
+         if (i >= VBO_ATTRIB_FIRST_MATERIAL &&
+             i <= VBO_ATTRIB_LAST_MATERIAL)
+            ctx->NewState |= _NEW_LIGHT;
 
-        data += node->attrsz[i];
+         ctx->NewState |= _NEW_CURRENT_ATTRIB;
       }
+
+      data += node->attrsz[i];
    }
 
    /* Colormaterial -- this kindof sucks.
@@ -193,17 +196,14 @@ static void vbo_bind_vertex_list(struct gl_context *ctx,
         arrays[attr].Ptr = (const GLubyte *) NULL + buffer_offset;
         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 = node_attrtype[src];
          arrays[attr].Integer =
                vbo_attrtype_to_integer_flag(node_attrtype[src]);
          arrays[attr].Format = GL_RGBA;
-        arrays[attr].Enabled = 1;
          arrays[attr]._ElementSize = arrays[attr].Size * sizeof(GLfloat);
          _mesa_reference_buffer_object(ctx,
                                        &arrays[attr].BufferObj,
                                        node->vertex_store->bufferobj);
-        arrays[attr]._MaxElement = node->count; /* ??? */
         
         assert(arrays[attr].BufferObj->Name);
 
@@ -225,7 +225,8 @@ vbo_save_loopback_vertex_list(struct gl_context *ctx,
       ctx->Driver.MapBufferRange(ctx, 0,
                                 list->vertex_store->bufferobj->Size,
                                 GL_MAP_READ_BIT, /* ? */
-                                list->vertex_store->bufferobj);
+                                list->vertex_store->bufferobj,
+                                 MAP_INTERNAL);
 
    vbo_loopback_vertex_list(ctx,
                             (const GLfloat *)(buffer + list->buffer_offset),
@@ -235,7 +236,8 @@ vbo_save_loopback_vertex_list(struct gl_context *ctx,
                             list->wrap_count,
                             list->vertex_size);
 
-   ctx->Driver.UnmapBuffer(ctx, list->vertex_store->bufferobj);
+   ctx->Driver.UnmapBuffer(ctx, list->vertex_store->bufferobj,
+                           MAP_INTERNAL);
 }
 
 
@@ -268,21 +270,16 @@ vbo_save_playback_vertex_list(struct gl_context *ctx, void *data)
 
    if (node->prim_count > 0) {
 
-      if (_mesa_inside_begin_end(ctx) &&
-         node->prim[0].begin) {
-
-        /* Degenerate case: list is called inside begin/end pair and
-         * includes operations such as glBegin or glDrawArrays.
-         */
-        if (0)
-           printf("displaylist recursive begin");
-
-        vbo_save_loopback_vertex_list( ctx, node );
-
+      if (_mesa_inside_begin_end(ctx) && node->prim[0].begin) {
+         /* Error: we're about to begin a new primitive but we're already
+          * inside a glBegin/End pair.
+          */
+         _mesa_error(ctx, GL_INVALID_OPERATION,
+                     "draw operation inside glBegin/End");
          goto end;
       }
       else if (save->replay_flags) {
-        /* Various degnerate cases: translate into immediate mode
+        /* Various degenerate cases: translate into immediate mode
          * calls rather than trying to execute in place.
          */
         vbo_save_loopback_vertex_list( ctx, node );
@@ -318,7 +315,7 @@ vbo_save_playback_vertex_list(struct gl_context *ctx, void *data)
                                       GL_TRUE,
                                       0,    /* Node is a VBO, so this is ok */
                                       node->count - 1,
-                                      NULL);
+                                      NULL, 0, NULL);
       }
    }