radeon/r200/r300: don't clean non-emitted state.
[mesa.git] / src / mesa / vbo / vbo_save_draw.c
index 68f3a965a5df6873aa9d26e5d56db8cae1c4d13d..d834fa1f2e75994d76d33a1b9c67b52102b2eb0d 100644 (file)
@@ -46,20 +46,31 @@ static void _playback_copy_to_current( GLcontext *ctx,
                                       const struct vbo_save_vertex_list *node )
 {
    struct vbo_context *vbo = vbo_context(ctx);
-   GLfloat vertex[VBO_ATTRIB_MAX * 4], *data = vertex;
+   GLfloat vertex[VBO_ATTRIB_MAX * 4];
+   GLfloat *data;
    GLuint i, offset;
 
-   if (node->count)
-      offset = (node->buffer_offset + 
-               (node->count-1) * node->vertex_size * sizeof(GLfloat));
-   else
-      offset = node->buffer_offset;
+   if (node->current_size == 0)
+      return;
 
-   ctx->Driver.GetBufferSubData( ctx, 0, offset, 
-                                node->vertex_size * sizeof(GLfloat), 
-                                data, node->vertex_store->bufferobj );
+   if (node->current_data) {
+      data = node->current_data;
+   }
+   else {
+      data = vertex;
+
+      if (node->count)
+         offset = (node->buffer_offset + 
+                   (node->count-1) * node->vertex_size * sizeof(GLfloat));
+      else
+         offset = node->buffer_offset;
 
-   data += node->attrsz[0]; /* skip vertex position */
+      ctx->Driver.GetBufferSubData( ctx, 0, offset, 
+                                    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]) {
@@ -115,10 +126,13 @@ static void vbo_bind_vertex_list( GLcontext *ctx,
    struct vbo_context *vbo = vbo_context(ctx);
    struct vbo_save_context *save = &vbo->save;
    struct gl_client_array *arrays = save->arrays;
-   GLuint data = node->buffer_offset;
+   GLuint buffer_offset = node->buffer_offset;
    const GLuint *map;
    GLuint attr;
-   GLuint varying_inputs = 0;
+   GLubyte node_attrsz[VBO_ATTRIB_MAX];  /* copy of node->attrsz[] */
+   GLbitfield varying_inputs = 0x0;
+
+   memcpy(node_attrsz, node->attrsz, sizeof(node->attrsz));
 
    /* Install the default (ie Current) attributes first, then overlay
     * all active ones.
@@ -144,21 +158,35 @@ static void vbo_bind_vertex_list( GLcontext *ctx,
          save->inputs[attr + 16] = &vbo->generic_currval[attr];
       }
       map = vbo->map_vp_arb;
+
+      /* check if VERT_ATTRIB_POS is not read but VERT_BIT_GENERIC0 is read.
+       * In that case we effectively need to route the data from
+       * glVertexAttrib(0, val) calls to feed into the GENERIC0 input.
+       */
+      if ((ctx->VertexProgram._Current->Base.InputsRead & VERT_BIT_POS) == 0 &&
+          (ctx->VertexProgram._Current->Base.InputsRead & VERT_BIT_GENERIC0)) {
+         save->inputs[16] = save->inputs[0];
+         node_attrsz[16] = node_attrsz[0];
+         node_attrsz[0] = 0;
+      }
       break;
+   default:
+      assert(0);
    }
 
    for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) {
       GLuint src = map[attr];
 
-      if (node->attrsz[src]) {
+      if (node_attrsz[src]) {
          /* override the default array set above */
          save->inputs[attr] = &arrays[attr];
 
-        arrays[attr].Ptr = (const GLubyte *) data;
+        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 = GL_FLOAT;
+         arrays[attr].Format = GL_RGBA;
         arrays[attr].Enabled = 1;
          _mesa_reference_buffer_object(ctx,
                                        &arrays[attr].BufferObj,
@@ -167,7 +195,7 @@ static void vbo_bind_vertex_list( GLcontext *ctx,
         
         assert(arrays[attr].BufferObj->Name);
 
-        data += node->attrsz[src] * sizeof(GLfloat);
+        buffer_offset += node->attrsz[src] * sizeof(GLfloat);
          varying_inputs |= 1<<attr;
       }
    }
@@ -251,6 +279,7 @@ void vbo_save_playback_vertex_list( GLcontext *ctx, void *data )
                                    node->prim, 
                                    node->prim_count,
                                    NULL,
+                                   GL_TRUE,
                                    0,  /* Node is a VBO, so this is ok */
                                    node->count - 1);
    }