st/mesa: fix fallout from xfb changes.
[mesa.git] / src / mesa / vbo / vbo_save_api.c
index 848eedaa4e54711301435a597f6574077693d6b4..97a1dfdeb3f926fb5ae75ab0a4fcb0fd54b507d0 100644 (file)
@@ -99,14 +99,14 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 static GLuint
 _save_copy_vertices(struct gl_context *ctx,
                     const struct vbo_save_vertex_list *node,
-                    const GLfloat * src_buffer)
+                    const fi_type * src_buffer)
 {
    struct vbo_save_context *save = &vbo_context(ctx)->save;
    const struct _mesa_prim *prim = &node->prim[node->prim_count - 1];
    GLuint nr = prim->count;
    GLuint sz = save->vertex_size;
-   const GLfloat *src = src_buffer + prim->start * sz;
-   GLfloat *dst = save->copied.buffer;
+   const fi_type *src = src_buffer + prim->start * sz;
+   fi_type *dst = save->copied.buffer;
    GLuint ovf, i;
 
    if (prim->end)
@@ -233,7 +233,7 @@ free_vertex_store(struct gl_context *ctx,
 }
 
 
-GLfloat *
+fi_type *
 vbo_save_map_vertex_store(struct gl_context *ctx,
                           struct vbo_save_vertex_store *vertex_store)
 {
@@ -249,7 +249,7 @@ vbo_save_map_vertex_store(struct gl_context *ctx,
       /* Map the remaining free space in the VBO */
       GLintptr offset = vertex_store->used * sizeof(GLfloat);
       GLsizeiptr size = vertex_store->bufferobj->Size - offset;
-      GLfloat *range = (GLfloat *)
+      fi_type *range = (fi_type *)
          ctx->Driver.MapBufferRange(ctx, offset, size, access,
                                     vertex_store->bufferobj,
                                     MAP_INTERNAL);
@@ -330,8 +330,7 @@ _save_reset_counters(struct gl_context *ctx)
  * previous prim.
  */
 static void
-merge_prims(struct gl_context *ctx,
-            struct _mesa_prim *prim_list,
+merge_prims(struct _mesa_prim *prim_list,
             GLuint *prim_count)
 {
    GLuint i;
@@ -361,6 +360,51 @@ merge_prims(struct gl_context *ctx,
    *prim_count = prev_prim - prim_list + 1;
 }
 
+
+/**
+ * Convert GL_LINE_LOOP primitive into GL_LINE_STRIP so that drivers
+ * don't have to worry about handling the _mesa_prim::begin/end flags.
+ * See https://bugs.freedesktop.org/show_bug.cgi?id=81174
+ */
+static void
+convert_line_loop_to_strip(struct vbo_save_context *save,
+                           struct vbo_save_vertex_list *node)
+{
+   struct _mesa_prim *prim = &node->prim[node->prim_count - 1];
+
+   assert(prim->mode == GL_LINE_LOOP);
+
+   if (prim->end) {
+      /* Copy the 0th vertex to end of the buffer and extend the
+       * vertex count by one to finish the line loop.
+       */
+      const GLuint sz = save->vertex_size;
+      /* 0th vertex: */
+      const fi_type *src = save->buffer + prim->start * sz;
+      /* end of buffer: */
+      fi_type *dst = save->buffer + (prim->start + prim->count) * sz;
+
+      memcpy(dst, src, sz * sizeof(float));
+
+      prim->count++;
+      node->count++;
+      save->vert_count++;
+      save->buffer_ptr += sz;
+      save->vertex_store->used += sz;
+   }
+
+   if (!prim->begin) {
+      /* Drawing the second or later section of a long line loop.
+       * Skip the 0th vertex.
+       */
+      prim->start++;
+      prim->count--;
+   }
+
+   prim->mode = GL_LINE_STRIP;
+}
+
+
 /**
  * Insert the active immediate struct onto the display list currently
  * being built.
@@ -375,11 +419,14 @@ _save_compile_vertex_list(struct gl_context *ctx)
     * being compiled.
     */
    node = (struct vbo_save_vertex_list *)
-      _mesa_dlist_alloc(ctx, save->opcode_vertex_list, sizeof(*node));
+      _mesa_dlist_alloc_aligned(ctx, save->opcode_vertex_list, sizeof(*node));
 
    if (!node)
       return;
 
+   /* Make sure the pointer is aligned to the size of a pointer */
+   assert((GLintptr) node % sizeof(void *) == 0);
+
    /* Duplicate our template, increment refcounts to the storage structs:
     */
    memcpy(node->attrsz, save->attrsz, sizeof(node->attrsz));
@@ -439,7 +486,11 @@ _save_compile_vertex_list(struct gl_context *ctx)
     */
    save->copied.nr = _save_copy_vertices(ctx, node, save->buffer);
 
-   merge_prims(ctx, node->prim, &node->prim_count);
+   if (node->prim[node->prim_count - 1].mode == GL_LINE_LOOP) {
+      convert_line_loop_to_strip(save, node);
+   }
+
+   merge_prims(node->prim, &node->prim_count);
 
    /* Deal with GL_COMPILE_AND_EXECUTE:
     */
@@ -480,6 +531,10 @@ _save_compile_vertex_list(struct gl_context *ctx)
       save->buffer_ptr = vbo_save_map_vertex_store(ctx, save->vertex_store);
       save->out_of_memory = save->buffer_ptr == NULL;
    }
+   else {
+      /* update buffer_ptr for next vertex */
+      save->buffer_ptr = save->vertex_store->buffer + save->vertex_store->used;
+   }
 
    if (save->prim_store->used > VBO_SAVE_PRIM_SIZE - 6) {
       save->prim_store->refcount--;
@@ -546,8 +601,7 @@ static void
 _save_wrap_filled_vertex(struct gl_context *ctx)
 {
    struct vbo_save_context *save = &vbo_context(ctx)->save;
-   GLfloat *data = save->copied.buffer;
-   GLuint i;
+   unsigned numComponents;
 
    /* Emit a glEnd to close off the last vertex list.
     */
@@ -557,12 +611,12 @@ _save_wrap_filled_vertex(struct gl_context *ctx)
     */
    assert(save->max_vert - save->vert_count > save->copied.nr);
 
-   for (i = 0; i < save->copied.nr; i++) {
-      memcpy(save->buffer_ptr, data, save->vertex_size * sizeof(GLfloat));
-      data += save->vertex_size;
-      save->buffer_ptr += save->vertex_size;
-      save->vert_count++;
-   }
+   numComponents = save->copied.nr * save->vertex_size;
+   memcpy(save->buffer_ptr,
+          save->copied.buffer,
+          numComponents * sizeof(fi_type));
+   save->buffer_ptr += numComponents;
+   save->vert_count += save->copied.nr;
 }
 
 
@@ -575,7 +629,7 @@ _save_copy_to_current(struct gl_context *ctx)
    for (i = VBO_ATTRIB_POS + 1; i < VBO_ATTRIB_MAX; i++) {
       if (save->attrsz[i]) {
          save->currentsz[i][0] = save->attrsz[i];
-         COPY_CLEAN_4V_TYPE_AS_FLOAT(save->current[i], save->attrsz[i],
+         COPY_CLEAN_4V_TYPE_AS_UNION(save->current[i], save->attrsz[i],
                                      save->attrptr[i], save->attrtype[i]);
       }
    }
@@ -617,7 +671,7 @@ _save_upgrade_vertex(struct gl_context *ctx, GLuint attr, GLuint newsz)
    struct vbo_save_context *save = &vbo_context(ctx)->save;
    GLuint oldsz;
    GLuint i;
-   GLfloat *tmp;
+   fi_type *tmp;
 
    /* Store the current run of vertices, and emit a GL_END.  Emit a
     * BEGIN in the new buffer.
@@ -645,7 +699,8 @@ _save_upgrade_vertex(struct gl_context *ctx, GLuint attr, GLuint newsz)
 
    /* Recalculate all the attrptr[] values:
     */
-   for (i = 0, tmp = save->vertex; i < VBO_ATTRIB_MAX; i++) {
+   tmp = save->vertex;
+   for (i = 0; i < VBO_ATTRIB_MAX; i++) {
       if (save->attrsz[i]) {
          save->attrptr[i] = tmp;
          tmp += save->attrsz[i];
@@ -666,8 +721,8 @@ _save_upgrade_vertex(struct gl_context *ctx, GLuint attr, GLuint newsz)
     * and will need fixup at runtime.
     */
    if (save->copied.nr) {
-      const GLfloat *data = save->copied.buffer;
-      GLfloat *dest = save->buffer;
+      const fi_type *data = save->copied.buffer;
+      fi_type *dest = save->buffer;
       GLuint j;
 
       /* Need to note this and fix up at runtime (or loopback):
@@ -682,7 +737,7 @@ _save_upgrade_vertex(struct gl_context *ctx, GLuint attr, GLuint newsz)
             if (save->attrsz[j]) {
                if (j == attr) {
                   if (oldsz) {
-                     COPY_CLEAN_4V_TYPE_AS_FLOAT(dest, oldsz, data,
+                     COPY_CLEAN_4V_TYPE_AS_UNION(dest, oldsz, data,
                                                  save->attrtype[j]);
                      data += oldsz;
                      dest += newsz;
@@ -726,7 +781,7 @@ save_fixup_vertex(struct gl_context *ctx, GLuint attr, GLuint sz)
    }
    else if (sz < save->active_sz[attr]) {
       GLuint i;
-      const GLfloat *id = vbo_get_default_vals_as_float(save->attrtype[attr]);
+      const fi_type *id = vbo_get_default_vals_as_union(save->attrtype[attr]);
 
       /* New size is equal or smaller - just need to fill in some
        * zeros.
@@ -760,7 +815,7 @@ _save_reset_vertex(struct gl_context *ctx)
 
 
 
-#define ERROR(err)   _mesa_compile_error(ctx, err, __FUNCTION__);
+#define ERROR(err)   _mesa_compile_error(ctx, err, __func__);
 
 
 /* Only one size for each attribute may be active at once.  Eg. if
@@ -769,7 +824,7 @@ _save_reset_vertex(struct gl_context *ctx)
  * 3f version won't otherwise set color[3] to 1.0 -- this is the job
  * of the chooser function when switching between Color4f and Color3f.
  */
-#define ATTR(A, N, T, V0, V1, V2, V3)                          \
+#define ATTR_UNION(A, N, T, C, V0, V1, V2, V3)                 \
 do {                                                           \
    struct vbo_save_context *save = &vbo_context(ctx)->save;    \
                                                                \
@@ -777,12 +832,12 @@ do {                                                              \
       save_fixup_vertex(ctx, A, N);                            \
                                                                \
    {                                                           \
-      GLfloat *dest = save->attrptr[A];                                \
+      C *dest = (C *)save->attrptr[A];                          \
       if (N>0) dest[0] = V0;                                   \
       if (N>1) dest[1] = V1;                                   \
       if (N>2) dest[2] = V2;                                   \
       if (N>3) dest[3] = V3;                                   \
-      save->attrtype[A] = T;                                    \
+      save->attrtype[A] = T;                                   \
    }                                                           \
                                                                \
    if ((A) == 0) {                                             \
@@ -967,8 +1022,7 @@ _save_CallLists(GLsizei n, GLenum type, const GLvoid * v)
 
 
 /**
- * Called via ctx->Driver.NotifySaveBegin() when a glBegin is getting
- * compiled into a display list.
+ * Called when a glBegin is getting compiled into a display list.
  * Updating of ctx->Driver.CurrentSavePrimitive is already taken care of.
  */
 GLboolean
@@ -998,7 +1052,7 @@ vbo_save_NotifyBegin(struct gl_context *ctx, GLenum mode)
       _mesa_install_save_vtxfmt(ctx, &save->vtxfmt);
    }
 
-   /* We need to call SaveFlushVertices() if there's state change */
+   /* We need to call vbo_save_SaveFlushVertices() if there's state change */
    ctx->Driver.SaveNeedFlush = GL_TRUE;
 
    /* GL_TRUE means we've handled this glBegin here; don't compile a BEGIN
@@ -1369,6 +1423,16 @@ _save_vtxfmt_init(struct gl_context *ctx)
    vfmt->VertexAttribP3uiv = _save_VertexAttribP3uiv;
    vfmt->VertexAttribP4uiv = _save_VertexAttribP4uiv;
 
+   vfmt->VertexAttribL1d = _save_VertexAttribL1d;
+   vfmt->VertexAttribL2d = _save_VertexAttribL2d;
+   vfmt->VertexAttribL3d = _save_VertexAttribL3d;
+   vfmt->VertexAttribL4d = _save_VertexAttribL4d;
+
+   vfmt->VertexAttribL1dv = _save_VertexAttribL1dv;
+   vfmt->VertexAttribL2dv = _save_VertexAttribL2dv;
+   vfmt->VertexAttribL3dv = _save_VertexAttribL3dv;
+   vfmt->VertexAttribL4dv = _save_VertexAttribL4dv;
+
    /* This will all require us to fallback to saving the list as opcodes:
     */
    vfmt->CallList = _save_CallList;
@@ -1523,18 +1587,22 @@ vbo_destroy_vertex_list(struct gl_context *ctx, void *data)
 
 
 static void
-vbo_print_vertex_list(struct gl_context *ctx, void *data)
+vbo_print_vertex_list(struct gl_context *ctx, void *data, FILE *f)
 {
    struct vbo_save_vertex_list *node = (struct vbo_save_vertex_list *) data;
    GLuint i;
+   struct gl_buffer_object *buffer = node->vertex_store ?
+      node->vertex_store->bufferobj : NULL;
    (void) ctx;
 
-   printf("VBO-VERTEX-LIST, %u vertices %d primitives, %d vertsize\n",
-          node->count, node->prim_count, node->vertex_size);
+   fprintf(f, "VBO-VERTEX-LIST, %u vertices, %d primitives, %d vertsize, "
+           "buffer %p\n",
+           node->count, node->prim_count, node->vertex_size,
+           buffer);
 
    for (i = 0; i < node->prim_count; i++) {
       struct _mesa_prim *prim = &node->prim[i];
-      printf("   prim %d: %s%s %d..%d %s %s\n",
+      fprintf(f, "   prim %d: %s%s %d..%d %s %s\n",
              i,
              _mesa_lookup_prim_by_nr(prim->mode),
              prim->weak ? " (weak)" : "",
@@ -1557,16 +1625,16 @@ _save_current_init(struct gl_context *ctx)
 
    for (i = VBO_ATTRIB_POS; i <= VBO_ATTRIB_GENERIC15; i++) {
       const GLuint j = i - VBO_ATTRIB_POS;
-      ASSERT(j < VERT_ATTRIB_MAX);
+      assert(j < VERT_ATTRIB_MAX);
       save->currentsz[i] = &ctx->ListState.ActiveAttribSize[j];
-      save->current[i] = ctx->ListState.CurrentAttrib[j];
+      save->current[i] = (fi_type *) ctx->ListState.CurrentAttrib[j];
    }
 
    for (i = VBO_ATTRIB_FIRST_MATERIAL; i <= VBO_ATTRIB_LAST_MATERIAL; i++) {
       const GLuint j = i - VBO_ATTRIB_FIRST_MATERIAL;
-      ASSERT(j < MAT_ATTRIB_MAX);
+      assert(j < MAT_ATTRIB_MAX);
       save->currentsz[i] = &ctx->ListState.ActiveMaterialSize[j];
-      save->current[i] = ctx->ListState.CurrentMaterial[j];
+      save->current[i] = (fi_type *) ctx->ListState.CurrentMaterial[j];
    }
 }
 
@@ -1587,8 +1655,6 @@ vbo_save_api_init(struct vbo_save_context *save)
                                vbo_destroy_vertex_list,
                                vbo_print_vertex_list);
 
-   ctx->Driver.NotifySaveBegin = vbo_save_NotifyBegin;
-
    _save_vtxfmt_init(ctx);
    _save_current_init(ctx);
    _mesa_noop_vtxfmt_init(&save->vtxfmt_noop);