[Mesa-dev] [PATCH 09/10] mesa: Factor out struct gl_vertex_format.

Mathias.Froehlich at gmx.net Mathias.Froehlich at gmx.net
Sat Nov 17 12:14:57 UTC 2018


From: Mathias Fröhlich <mathias.froehlich at web.de>

Factor out struct gl_vertex_format from array attributes.
The data type is supposed to describe the type of a vertex
element. At this current stage the data type is only used
with the VAO, but actually is useful in various other places.
Due to the bitfields being used, special care needs to be
taken for the glGet code paths.

Signed-off-by: Mathias Fröhlich <Mathias.Froehlich at web.de>
---
 src/mesa/drivers/dri/i965/brw_context.h       |  2 +-
 src/mesa/drivers/dri/i965/brw_draw.c          | 14 ++--
 src/mesa/drivers/dri/i965/brw_draw_upload.c   | 60 ++++++++---------
 src/mesa/drivers/dri/i965/genX_state_upload.c | 14 ++--
 src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c  | 10 +--
 src/mesa/main/api_arrayelt.c                  | 34 +++++-----
 src/mesa/main/arrayobj.c                      | 21 +++---
 src/mesa/main/draw.c                          | 13 ++--
 src/mesa/main/get.c                           | 15 ++++-
 src/mesa/main/get_hash_params.py              | 20 +++---
 src/mesa/main/mtypes.h                        | 27 +++++---
 src/mesa/main/varray.c                        | 64 ++++++++++---------
 src/mesa/main/varray.h                        | 20 ++++++
 src/mesa/state_tracker/st_atom.h              |  2 +-
 src/mesa/state_tracker/st_atom_array.c        | 28 ++++----
 src/mesa/state_tracker/st_draw_feedback.c     |  2 +-
 src/mesa/tnl/t_draw.c                         | 22 +++----
 src/mesa/tnl/t_split_copy.c                   | 18 ++----
 src/mesa/vbo/vbo_context.c                    |  5 +-
 src/mesa/vbo/vbo_exec_api.c                   | 13 ++--
 src/mesa/vbo/vbo_private.h                    | 10 +++
 src/mesa/vbo/vbo_save_api.c                   | 12 ++--
 src/mesa/vbo/vbo_save_draw.c                  | 14 ++--
 src/mesa/vbo/vbo_save_loopback.c              |  2 +-
 24 files changed, 239 insertions(+), 203 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index 7fd15669eb..e5d57dd8df 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -1493,7 +1493,7 @@ gl_clip_plane *brw_select_clip_planes(struct gl_context *ctx);
 
 /* brw_draw_upload.c */
 unsigned brw_get_vertex_surface_type(struct brw_context *brw,
-                                     const struct gl_array_attributes *glattr);
+                                     const struct gl_vertex_format *glformat);
 
 static inline unsigned
 brw_get_index_type(unsigned index_size)
diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c
index 8536c04010..f080a9fefc 100644
--- a/src/mesa/drivers/dri/i965/brw_draw.c
+++ b/src/mesa/drivers/dri/i965/brw_draw.c
@@ -303,16 +303,16 @@ brw_merge_inputs(struct brw_context *brw)
        * 2_10_10_10_REV vertex formats.  Set appropriate workaround flags.
        */
       while (mask) {
-         const struct gl_array_attributes *glattrib;
+         const struct gl_vertex_format *glformat;
          uint8_t wa_flags = 0;
 
          i = u_bit_scan64(&mask);
-         glattrib = brw->vb.inputs[i].glattrib;
+         glformat = &brw->vb.inputs[i].glattrib->Format;
 
-         switch (glattrib->Type) {
+         switch (glformat->Type) {
 
          case GL_FIXED:
-            wa_flags = glattrib->Size;
+            wa_flags = glformat->Size;
             break;
 
          case GL_INT_2_10_10_10_REV:
@@ -320,12 +320,12 @@ brw_merge_inputs(struct brw_context *brw)
             /* fallthough */
 
          case GL_UNSIGNED_INT_2_10_10_10_REV:
-            if (glattrib->Format == GL_BGRA)
+            if (glformat->Format == GL_BGRA)
                wa_flags |= BRW_ATTRIB_WA_BGRA;
 
-            if (glattrib->Normalized)
+            if (glformat->Normalized)
                wa_flags |= BRW_ATTRIB_WA_NORMALIZE;
-            else if (!glattrib->Integer)
+            else if (!glformat->Integer)
                wa_flags |= BRW_ATTRIB_WA_SCALE;
 
             break;
diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c
index dc3022bc41..dfbc45fe93 100644
--- a/src/mesa/drivers/dri/i965/brw_draw_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c
@@ -249,21 +249,21 @@ double_types(int size, GLboolean doubles)
  */
 unsigned
 brw_get_vertex_surface_type(struct brw_context *brw,
-                            const struct gl_array_attributes *glattrib)
+                            const struct gl_vertex_format *glformat)
 {
-   int size = glattrib->Size;
+   int size = glformat->Size;
    const struct gen_device_info *devinfo = &brw->screen->devinfo;
    const bool is_ivybridge_or_older =
       devinfo->gen <= 7 && !devinfo->is_baytrail && !devinfo->is_haswell;
 
    if (unlikely(INTEL_DEBUG & DEBUG_VERTS))
       fprintf(stderr, "type %s size %d normalized %d\n",
-              _mesa_enum_to_string(glattrib->Type),
-              glattrib->Size, glattrib->Normalized);
+              _mesa_enum_to_string(glformat->Type),
+              glformat->Size, glformat->Normalized);
 
-   if (glattrib->Integer) {
-      assert(glattrib->Format == GL_RGBA); /* sanity check */
-      switch (glattrib->Type) {
+   if (glformat->Integer) {
+      assert(glformat->Format == GL_RGBA); /* sanity check */
+      switch (glformat->Type) {
       case GL_INT: return int_types_direct[size];
       case GL_SHORT:
          if (is_ivybridge_or_older && size == 3)
@@ -288,11 +288,11 @@ brw_get_vertex_surface_type(struct brw_context *brw,
             return ubyte_types_direct[size];
       default: unreachable("not reached");
       }
-   } else if (glattrib->Type == GL_UNSIGNED_INT_10F_11F_11F_REV) {
+   } else if (glformat->Type == GL_UNSIGNED_INT_10F_11F_11F_REV) {
       return ISL_FORMAT_R11G11B10_FLOAT;
-   } else if (glattrib->Normalized) {
-      switch (glattrib->Type) {
-      case GL_DOUBLE: return double_types(size, glattrib->Doubles);
+   } else if (glformat->Normalized) {
+      switch (glformat->Type) {
+      case GL_DOUBLE: return double_types(size, glformat->Doubles);
       case GL_FLOAT: return float_types[size];
       case GL_HALF_FLOAT:
       case GL_HALF_FLOAT_OES:
@@ -306,7 +306,7 @@ brw_get_vertex_surface_type(struct brw_context *brw,
       case GL_UNSIGNED_INT: return uint_types_norm[size];
       case GL_UNSIGNED_SHORT: return ushort_types_norm[size];
       case GL_UNSIGNED_BYTE:
-         if (glattrib->Format == GL_BGRA) {
+         if (glformat->Format == GL_BGRA) {
             /* See GL_EXT_vertex_array_bgra */
             assert(size == 4);
             return ISL_FORMAT_B8G8R8A8_UNORM;
@@ -330,7 +330,7 @@ brw_get_vertex_surface_type(struct brw_context *brw,
       case GL_INT_2_10_10_10_REV:
          assert(size == 4);
          if (devinfo->gen >= 8 || devinfo->is_haswell) {
-            return glattrib->Format == GL_BGRA
+            return glformat->Format == GL_BGRA
                ? ISL_FORMAT_B10G10R10A2_SNORM
                : ISL_FORMAT_R10G10B10A2_SNORM;
          }
@@ -338,7 +338,7 @@ brw_get_vertex_surface_type(struct brw_context *brw,
       case GL_UNSIGNED_INT_2_10_10_10_REV:
          assert(size == 4);
          if (devinfo->gen >= 8 || devinfo->is_haswell) {
-            return glattrib->Format == GL_BGRA
+            return glformat->Format == GL_BGRA
                ? ISL_FORMAT_B10G10R10A2_UNORM
                : ISL_FORMAT_R10G10B10A2_UNORM;
          }
@@ -352,26 +352,26 @@ brw_get_vertex_surface_type(struct brw_context *brw,
        * like to use here, so upload everything as UINT and fix
        * it in the shader
        */
-      if (glattrib->Type == GL_INT_2_10_10_10_REV) {
+      if (glformat->Type == GL_INT_2_10_10_10_REV) {
          assert(size == 4);
          if (devinfo->gen >= 8 || devinfo->is_haswell) {
-            return glattrib->Format == GL_BGRA
+            return glformat->Format == GL_BGRA
                ? ISL_FORMAT_B10G10R10A2_SSCALED
                : ISL_FORMAT_R10G10B10A2_SSCALED;
          }
          return ISL_FORMAT_R10G10B10A2_UINT;
-      } else if (glattrib->Type == GL_UNSIGNED_INT_2_10_10_10_REV) {
+      } else if (glformat->Type == GL_UNSIGNED_INT_2_10_10_10_REV) {
          assert(size == 4);
          if (devinfo->gen >= 8 || devinfo->is_haswell) {
-            return glattrib->Format == GL_BGRA
+            return glformat->Format == GL_BGRA
                ? ISL_FORMAT_B10G10R10A2_USCALED
                : ISL_FORMAT_R10G10B10A2_USCALED;
          }
          return ISL_FORMAT_R10G10B10A2_UINT;
       }
-      assert(glattrib->Format == GL_RGBA); /* sanity check */
-      switch (glattrib->Type) {
-      case GL_DOUBLE: return double_types(size, glattrib->Doubles);
+      assert(glformat->Format == GL_RGBA); /* sanity check */
+      switch (glformat->Type) {
+      case GL_DOUBLE: return double_types(size, glformat->Doubles);
       case GL_FLOAT: return float_types[size];
       case GL_HALF_FLOAT:
       case GL_HALF_FLOAT_OES:
@@ -407,6 +407,7 @@ copy_array_to_vbo_array(struct brw_context *brw,
 {
    const struct gl_vertex_buffer_binding *glbinding = element->glbinding;
    const struct gl_array_attributes *glattrib = element->glattrib;
+   const struct gl_vertex_format *glformat = &glattrib->Format;
    const int src_stride = glbinding->Stride;
 
    /* If the source stride is zero, we just want to upload the current
@@ -414,11 +415,11 @@ copy_array_to_vbo_array(struct brw_context *brw,
     * to replicate it out.
     */
    if (src_stride == 0) {
-      brw_upload_data(&brw->upload, glattrib->Ptr, glattrib->_ElementSize,
-                      glattrib->_ElementSize, &buffer->bo, &buffer->offset);
+      brw_upload_data(&brw->upload, glattrib->Ptr, glformat->_ElementSize,
+                      glformat->_ElementSize, &buffer->bo, &buffer->offset);
 
       buffer->stride = 0;
-      buffer->size = glattrib->_ElementSize;
+      buffer->size = glformat->_ElementSize;
       return;
    }
 
@@ -531,13 +532,13 @@ brw_prepare_vertices(struct brw_context *brw)
                start = offset + glbinding->Stride * brw->baseinstance;
                range = (glbinding->Stride * ((brw->num_instances - 1) /
                                             glbinding->InstanceDivisor) +
-                        glattrib->_ElementSize);
+                        glattrib->Format._ElementSize);
             }
          } else {
             if (brw->vb.index_bounds_valid) {
                start = offset + min_index * glbinding->Stride;
                range = (glbinding->Stride * (max_index - min_index) +
-                        glattrib->_ElementSize);
+                        glattrib->Format._ElementSize);
             }
          }
 
@@ -594,7 +595,8 @@ brw_prepare_vertices(struct brw_context *brw)
 	 else if (interleaved != glbinding->Stride ||
                   glbinding->InstanceDivisor != 0 ||
                   glattrib->Ptr < ptr ||
-                  (uintptr_t)(glattrib->Ptr - ptr) + glattrib->_ElementSize > interleaved)
+                  (uintptr_t)(glattrib->Ptr - ptr) +
+                  glattrib->Format._ElementSize > interleaved)
 	 {
             /* If our stride is different from the first attribute's stride,
              * or if we are using an instance divisor or if the first
@@ -677,7 +679,7 @@ brw_prepare_vertices(struct brw_context *brw)
       const struct gl_array_attributes *glattrib = upload[i]->glattrib;
       if (glbinding->InstanceDivisor == 0) {
          copy_array_to_vbo_array(brw, upload[i], min_index, max_index,
-                                 buffer, glattrib->_ElementSize);
+                                 buffer, glattrib->Format._ElementSize);
       } else {
          /* This is an instanced attribute, since its InstanceDivisor
           * is not zero. Therefore, its data will be stepped after the
@@ -686,7 +688,7 @@ brw_prepare_vertices(struct brw_context *brw)
          uint32_t instanced_attr_max_index =
             (brw->num_instances - 1) / glbinding->InstanceDivisor;
          copy_array_to_vbo_array(brw, upload[i], 0, instanced_attr_max_index,
-                                 buffer, glattrib->_ElementSize);
+                                 buffer, glattrib->Format._ElementSize);
       }
       buffer->offset -= delta * buffer->stride;
       buffer->size += delta * buffer->stride;
diff --git a/src/mesa/drivers/dri/i965/genX_state_upload.c b/src/mesa/drivers/dri/i965/genX_state_upload.c
index 5acd092292..8e3fcbf12e 100644
--- a/src/mesa/drivers/dri/i965/genX_state_upload.c
+++ b/src/mesa/drivers/dri/i965/genX_state_upload.c
@@ -620,7 +620,7 @@ genX(emit_vertices)(struct brw_context *brw)
    for (unsigned i = 0; i < brw->vb.nr_enabled; i++) {
       struct brw_vertex_element *input = brw->vb.enabled[i];
       const struct gl_array_attributes *glattrib = input->glattrib;
-      uint32_t format = brw_get_vertex_surface_type(brw, glattrib);
+      uint32_t format = brw_get_vertex_surface_type(brw, &glattrib->Format);
 
       if (uploads_needed(format, input->is_dual_slot) > 1)
          nr_elements++;
@@ -713,7 +713,7 @@ genX(emit_vertices)(struct brw_context *brw)
    for (i = 0; i < brw->vb.nr_enabled; i++) {
       const struct brw_vertex_element *input = brw->vb.enabled[i];
       const struct gl_array_attributes *glattrib = input->glattrib;
-      uint32_t format = brw_get_vertex_surface_type(brw, glattrib);
+      uint32_t format = brw_get_vertex_surface_type(brw, &glattrib->Format);
       uint32_t comp0 = VFCOMP_STORE_SRC;
       uint32_t comp1 = VFCOMP_STORE_SRC;
       uint32_t comp2 = VFCOMP_STORE_SRC;
@@ -756,16 +756,16 @@ genX(emit_vertices)(struct brw_context *brw)
 
          const struct gl_array_attributes *glattrib = input->glattrib;
          const int size = (GEN_GEN < 8 && is_passthru_format(format)) ?
-            upload_format_size(upload_format) : glattrib->Size;
+            upload_format_size(upload_format) : glattrib->Format.Size;
 
          switch (size) {
             case 0: comp0 = VFCOMP_STORE_0;
             case 1: comp1 = VFCOMP_STORE_0;
             case 2: comp2 = VFCOMP_STORE_0;
             case 3:
-               if (GEN_GEN >= 8 && glattrib->Doubles) {
+               if (GEN_GEN >= 8 && glattrib->Format.Doubles) {
                   comp3 = VFCOMP_STORE_0;
-               } else if (glattrib->Integer) {
+               } else if (glattrib->Format.Integer) {
                   comp3 = VFCOMP_STORE_1_INT;
                } else {
                   comp3 = VFCOMP_STORE_1_FP;
@@ -790,7 +790,7 @@ genX(emit_vertices)(struct brw_context *brw)
           *     to be specified as VFCOMP_STORE_0 in order to output a 256-bit
           *     vertex element."
           */
-         if (glattrib->Doubles && !input->is_dual_slot) {
+         if (glattrib->Format.Doubles && !input->is_dual_slot) {
             /* Store vertex elements which correspond to double and dvec2 vertex
              * shader inputs as 128-bit vertex elements, instead of 256-bits.
              */
@@ -877,7 +877,7 @@ genX(emit_vertices)(struct brw_context *brw)
 #if GEN_GEN >= 6
    if (gen6_edgeflag_input) {
       const struct gl_array_attributes *glattrib = gen6_edgeflag_input->glattrib;
-      const uint32_t format = brw_get_vertex_surface_type(brw, glattrib);
+      const uint32_t format = brw_get_vertex_surface_type(brw, &glattrib->Format);
 
       struct GENX(VERTEX_ELEMENT_STATE) elem_state = {
          .Valid = true,
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c b/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c
index 97ff07808b..f037bd2015 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c
@@ -49,7 +49,7 @@ get_array_stride(struct gl_context *ctx, const struct tnl_vertex_array *a)
 	if (render->mode == VBO && !_mesa_is_bufferobj(binding->BufferObj)) {
 		const struct gl_array_attributes *attrib = a->VertexAttrib;
 		/* Pack client buffers. */
-		return align(attrib->_ElementSize, 4);
+		return align(attrib->Format._ElementSize, 4);
 	} else {
 		return binding->Stride;
 	}
@@ -86,7 +86,7 @@ vbo_init_arrays(struct gl_context *ctx, const struct _mesa_index_buffer *ib,
 
 		nouveau_init_array(&render->attrs[attr], attr,
 				   get_array_stride(ctx, array),
-				   attrib->Size, attrib->Type,
+				   attrib->Format.Size, attrib->Format.Type,
 				   imm ? binding->BufferObj : NULL,
 				   p, imm, ctx);
 	}
@@ -154,8 +154,8 @@ vbo_emit_attr(struct gl_context *ctx, const struct tnl_vertex_array *arrays,
 			return;
 
 		/* Constant attribute. */
-		nouveau_init_array(a, attr, binding->Stride, attrib->Size,
-				   attrib->Type, binding->BufferObj, p,
+		nouveau_init_array(a, attr, binding->Stride, attrib->Format.Size,
+				   attrib->Format.Type, binding->BufferObj, p,
 				   GL_TRUE, ctx);
 		EMIT_IMM(ctx, a, 0);
 		nouveau_deinit_array(a);
@@ -166,7 +166,7 @@ vbo_emit_attr(struct gl_context *ctx, const struct tnl_vertex_array *arrays,
 
 		if (render->mode == VBO) {
 			render->map[info->vbo_index] = attr;
-			render->vertex_size += attrib->_ElementSize;
+			render->vertex_size += attrib->Format._ElementSize;
 			render->attr_count = MAX2(render->attr_count,
 						  info->vbo_index + 1);
 		} else {
diff --git a/src/mesa/main/api_arrayelt.c b/src/mesa/main/api_arrayelt.c
index 25cbc5326f..2b59c478d9 100644
--- a/src/mesa/main/api_arrayelt.c
+++ b/src/mesa/main/api_arrayelt.c
@@ -1575,7 +1575,7 @@ _ae_update_state(struct gl_context *ctx)
    if (vao->Enabled & VERT_BIT_COLOR_INDEX) {
       aa->array = &vao->VertexAttrib[VERT_ATTRIB_COLOR_INDEX];
       aa->binding = &vao->BufferBinding[aa->array->BufferBindingIndex];
-      aa->offset = IndexFuncs[TYPE_IDX(aa->array->Type)];
+      aa->offset = IndexFuncs[TYPE_IDX(aa->array->Format.Type)];
       check_vbo(actx, aa->binding->BufferObj);
       aa++;
    }
@@ -1591,7 +1591,7 @@ _ae_update_state(struct gl_context *ctx)
    if (vao->Enabled & VERT_BIT_NORMAL) {
       aa->array = &vao->VertexAttrib[VERT_ATTRIB_NORMAL];
       aa->binding = &vao->BufferBinding[aa->array->BufferBindingIndex];
-      aa->offset = NormalFuncs[TYPE_IDX(aa->array->Type)];
+      aa->offset = NormalFuncs[TYPE_IDX(aa->array->Format.Type)];
       check_vbo(actx, aa->binding->BufferObj);
       aa++;
    }
@@ -1599,7 +1599,7 @@ _ae_update_state(struct gl_context *ctx)
    if (vao->Enabled & VERT_BIT_COLOR0) {
       aa->array = &vao->VertexAttrib[VERT_ATTRIB_COLOR0];
       aa->binding = &vao->BufferBinding[aa->array->BufferBindingIndex];
-      aa->offset = ColorFuncs[aa->array->Size-3][TYPE_IDX(aa->array->Type)];
+      aa->offset = ColorFuncs[aa->array->Format.Size-3][TYPE_IDX(aa->array->Format.Type)];
       check_vbo(actx, aa->binding->BufferObj);
       aa++;
    }
@@ -1607,7 +1607,7 @@ _ae_update_state(struct gl_context *ctx)
    if (vao->Enabled & VERT_BIT_COLOR1) {
       aa->array = &vao->VertexAttrib[VERT_ATTRIB_COLOR1];
       aa->binding = &vao->BufferBinding[aa->array->BufferBindingIndex];
-      aa->offset = SecondaryColorFuncs[TYPE_IDX(aa->array->Type)];
+      aa->offset = SecondaryColorFuncs[TYPE_IDX(aa->array->Format.Type)];
       check_vbo(actx, aa->binding->BufferObj);
       aa++;
    }
@@ -1615,7 +1615,7 @@ _ae_update_state(struct gl_context *ctx)
    if (vao->Enabled & VERT_BIT_FOG) {
       aa->array = &vao->VertexAttrib[VERT_ATTRIB_FOG];
       aa->binding = &vao->BufferBinding[aa->array->BufferBindingIndex];
-      aa->offset = FogCoordFuncs[TYPE_IDX(aa->array->Type)];
+      aa->offset = FogCoordFuncs[TYPE_IDX(aa->array->Format.Type)];
       check_vbo(actx, aa->binding->BufferObj);
       aa++;
    }
@@ -1629,10 +1629,10 @@ _ae_update_state(struct gl_context *ctx)
           */
          at->array = attribArray;
          at->binding = &vao->BufferBinding[attribArray->BufferBindingIndex];
-         assert(!at->array->Normalized);
-         at->func = AttribFuncsNV[at->array->Normalized]
-                                 [at->array->Size-1]
-                                 [TYPE_IDX(at->array->Type)];
+         assert(!at->array->Format.Normalized);
+         at->func = AttribFuncsNV[at->array->Format.Normalized]
+                                 [at->array->Format.Size-1]
+                                 [TYPE_IDX(at->array->Format.Type)];
          at->index = VERT_ATTRIB_TEX0 + i;
 	 check_vbo(actx, at->binding->BufferObj);
          at++;
@@ -1652,18 +1652,18 @@ _ae_update_state(struct gl_context *ctx)
           * change from one execution of _ae_ArrayElement() to
           * the next.  Doing so caused UT to break.
           */
-         if (at->array->Doubles)
+         if (at->array->Format.Doubles)
             intOrNorm = 3;
-         else if (at->array->Integer)
+         else if (at->array->Format.Integer)
             intOrNorm = 2;
-         else if (at->array->Normalized)
+         else if (at->array->Format.Normalized)
             intOrNorm = 1;
          else
             intOrNorm = 0;
 
          at->func = AttribFuncsARB[intOrNorm]
-            [at->array->Size-1]
-            [TYPE_IDX(at->array->Type)];
+            [at->array->Format.Size-1]
+            [TYPE_IDX(at->array->Format.Type)];
 
          at->index = i;
 	 check_vbo(actx, at->binding->BufferObj);
@@ -1678,15 +1678,15 @@ _ae_update_state(struct gl_context *ctx)
        */
       aa->array = &vao->VertexAttrib[VERT_ATTRIB_GENERIC0];
       aa->binding = &vao->BufferBinding[aa->array->BufferBindingIndex];
-      assert(aa->array->Size >= 2); /* XXX fix someday? */
-      aa->offset = VertexFuncs[aa->array->Size-2][TYPE_IDX(aa->array->Type)];
+      assert(aa->array->Format.Size >= 2); /* XXX fix someday? */
+      aa->offset = VertexFuncs[aa->array->Format.Size-2][TYPE_IDX(aa->array->Format.Type)];
       check_vbo(actx, aa->binding->BufferObj);
       aa++;
    }
    else if (vao->Enabled & VERT_BIT_POS) {
       aa->array = &vao->VertexAttrib[VERT_ATTRIB_POS];
       aa->binding = &vao->BufferBinding[aa->array->BufferBindingIndex];
-      aa->offset = VertexFuncs[aa->array->Size-2][TYPE_IDX(aa->array->Type)];
+      aa->offset = VertexFuncs[aa->array->Format.Size-2][TYPE_IDX(aa->array->Format.Type)];
       check_vbo(actx, aa->binding->BufferObj);
       aa++;
    }
diff --git a/src/mesa/main/arrayobj.c b/src/mesa/main/arrayobj.c
index f80bf2c949..bfd6fce679 100644
--- a/src/mesa/main/arrayobj.c
+++ b/src/mesa/main/arrayobj.c
@@ -385,22 +385,17 @@ init_array(struct gl_context *ctx,
    assert(index < ARRAY_SIZE(vao->BufferBinding));
    struct gl_vertex_buffer_binding *binding = &vao->BufferBinding[index];
 
-   array->Size = size;
-   array->Type = type;
-   array->Format = GL_RGBA; /* only significant for GL_EXT_vertex_array_bgra */
+   _mesa_set_vertex_format(&array->Format, size, type, GL_RGBA,
+                           GL_FALSE, GL_FALSE, GL_FALSE);
    array->Stride = 0;
    array->Ptr = NULL;
    array->RelativeOffset = 0;
-   array->Normalized = GL_FALSE;
-   array->Integer = GL_FALSE;
-   array->Doubles = GL_FALSE;
-   array->_ElementSize = size * _mesa_sizeof_type(type);
    ASSERT_BITFIELD_SIZE(struct gl_array_attributes, BufferBindingIndex,
                         VERT_ATTRIB_MAX - 1);
    array->BufferBindingIndex = index;
 
    binding->Offset = 0;
-   binding->Stride = array->_ElementSize;
+   binding->Stride = array->Format._ElementSize;
    binding->BufferObj = NULL;
    binding->_BoundArrays = BITFIELD_BIT(index);
 
@@ -756,7 +751,7 @@ _mesa_update_vao_derived_arrays(struct gl_context *ctx,
          GLbitfield eff_bound_arrays = bound;
 
          const GLubyte *ptr = attrib->Ptr;
-         unsigned vertex_end = attrib->_ElementSize;
+         unsigned vertex_end = attrib->Format._ElementSize;
 
          /* Walk other user space arrays and see which are interleaved
           * using the same binding parameters.
@@ -778,9 +773,10 @@ _mesa_update_vao_derived_arrays(struct gl_context *ctx,
             if (binding->InstanceDivisor != binding2->InstanceDivisor)
                continue;
             if (ptr <= attrib2->Ptr) {
-               if (ptr + binding->Stride < attrib2->Ptr + attrib2->_ElementSize)
+               if (ptr + binding->Stride < attrib2->Ptr +
+                   attrib2->Format._ElementSize)
                   continue;
-               unsigned end = attrib2->Ptr + attrib2->_ElementSize - ptr;
+               unsigned end = attrib2->Ptr + attrib2->Format._ElementSize - ptr;
                vertex_end = MAX2(vertex_end, end);
             } else {
                if (attrib2->Ptr + binding->Stride < ptr + vertex_end)
@@ -823,7 +819,8 @@ _mesa_update_vao_derived_arrays(struct gl_context *ctx,
       /* Query the original api defined attrib/binding information ... */
       const unsigned char *const map =_mesa_vao_attribute_map[mode];
       if (vao->Enabled & VERT_BIT(map[attr])) {
-         const struct gl_array_attributes *attrib = &vao->VertexAttrib[map[attr]];
+         const struct gl_array_attributes *attrib =
+            &vao->VertexAttrib[map[attr]];
          const struct gl_vertex_buffer_binding *binding =
             &vao->BufferBinding[attrib->BufferBindingIndex];
          /* ... and compare that with the computed attrib/binding */
diff --git a/src/mesa/main/draw.c b/src/mesa/main/draw.c
index 313df6aa8b..bfc4b9c937 100644
--- a/src/mesa/main/draw.c
+++ b/src/mesa/main/draw.c
@@ -82,18 +82,19 @@ check_array_data(struct gl_context *ctx, struct gl_vertex_array_object *vao,
          data = ADD_POINTERS(_mesa_vertex_attrib_address(array, binding),
                              bo->Mappings[MAP_INTERNAL].Pointer);
       }
-      switch (array->Type) {
+      switch (array->Format.Type) {
       case GL_FLOAT:
          {
             GLfloat *f = (GLfloat *) ((GLubyte *) data + binding->Stride * j);
             GLint k;
-            for (k = 0; k < array->Size; k++) {
+            for (k = 0; k < array->Format.Size; k++) {
                if (IS_INF_OR_NAN(f[k]) || f[k] >= 1.0e20F || f[k] <= -1.0e10F) {
                   printf("Bad array data:\n");
                   printf("  Element[%u].%u = %f\n", j, k, f[k]);
                   printf("  Array %u at %p\n", attrib, (void *) array);
                   printf("  Type 0x%x, Size %d, Stride %d\n",
-                         array->Type, array->Size, binding->Stride);
+                         array->Format.Type, array->Format.Size,
+                         binding->Stride);
                   printf("  Address/offset %p in Buffer Object %u\n",
                          array->Ptr, bo->Name);
                   f[k] = 1.0F;  /* XXX replace the bad value! */
@@ -288,7 +289,7 @@ print_draw_arrays(struct gl_context *ctx,
       printf("attr %s: size %d stride %d  "
              "ptr %p  Bufobj %u\n",
              gl_vert_attrib_name((gl_vert_attrib) i),
-             array->Size, binding->Stride,
+             array->Format.Size, binding->Stride,
              array->Ptr, bufObj->Name);
 
       if (_mesa_is_bufferobj(bufObj)) {
@@ -299,7 +300,7 @@ print_draw_arrays(struct gl_context *ctx,
             _mesa_vertex_attrib_address(array, binding);
 
          unsigned multiplier;
-         switch (array->Type) {
+         switch (array->Format.Type) {
          case GL_DOUBLE:
          case GL_INT64_ARB:
          case GL_UNSIGNED_INT64_ARB:
@@ -313,7 +314,7 @@ print_draw_arrays(struct gl_context *ctx,
          int *k = (int *) f;
          int i = 0;
          int n = (count - 1) * (binding->Stride / (4 * multiplier))
-           + array->Size;
+            + array->Format.Size;
          if (n > 32)
             n = 32;
          printf("  Data at offset %d:\n", offset);
diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c
index ac17539f09..ee77c45d03 100644
--- a/src/mesa/main/get.c
+++ b/src/mesa/main/get.c
@@ -755,13 +755,22 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu
       v->value_bool = !!(ctx->Array.VAO->Enabled & VERT_BIT_POINT_SIZE);
       break;
 
-   case GL_TEXTURE_COORD_ARRAY_SIZE:
    case GL_TEXTURE_COORD_ARRAY_TYPE:
    case GL_TEXTURE_COORD_ARRAY_STRIDE:
       array = &ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_TEX(ctx->Array.ActiveTexture)];
       v->value_int = *(GLuint *) ((char *) array + d->offset);
       break;
 
+   case GL_TEXTURE_COORD_ARRAY_SIZE:
+      array = &ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_TEX(ctx->Array.ActiveTexture)];
+      v->value_int = array->Format.Size;
+      break;
+
+   case GL_VERTEX_ARRAY_SIZE:
+      array = &ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_POS];
+      v->value_int = array->Format.Size;
+      break;
+
    case GL_ACTIVE_TEXTURE_ARB:
       v->value_int = GL_TEXTURE0_ARB + ctx->Texture.CurrentUnit;
       break;
@@ -969,11 +978,11 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu
    /* ARB_vertex_array_bgra */
    case GL_COLOR_ARRAY_SIZE:
       array = &ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_COLOR0];
-      v->value_int = array->Format == GL_BGRA ? GL_BGRA : array->Size;
+      v->value_int = array->Format.Format == GL_BGRA ? GL_BGRA : array->Format.Size;
       break;
    case GL_SECONDARY_COLOR_ARRAY_SIZE:
       array = &ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_COLOR1];
-      v->value_int = array->Format == GL_BGRA ? GL_BGRA : array->Size;
+      v->value_int = array->Format.Format == GL_BGRA ? GL_BGRA : array->Format.Size;
       break;
 
    /* ARB_copy_buffer */
diff --git a/src/mesa/main/get_hash_params.py b/src/mesa/main/get_hash_params.py
index ec5eef5f19..0b8ec9ea0b 100644
--- a/src/mesa/main/get_hash_params.py
+++ b/src/mesa/main/get_hash_params.py
@@ -212,19 +212,19 @@ descriptor=[
   [ "TEXTURE_MATRIX", "LOC_CUSTOM, TYPE_MATRIX, 0, extra_valid_texture_unit" ],
   [ "TEXTURE_STACK_DEPTH", "LOC_CUSTOM, TYPE_INT, 0, extra_valid_texture_unit" ],
   [ "VERTEX_ARRAY", "LOC_CUSTOM, TYPE_BOOLEAN, 0, NO_EXTRA" ],
-  [ "VERTEX_ARRAY_SIZE", "ARRAY_UBYTE(VertexAttrib[VERT_ATTRIB_POS].Size), NO_EXTRA" ],
-  [ "VERTEX_ARRAY_TYPE", "ARRAY_ENUM16(VertexAttrib[VERT_ATTRIB_POS].Type), NO_EXTRA" ],
+  [ "VERTEX_ARRAY_SIZE", "LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA" ],
+  [ "VERTEX_ARRAY_TYPE", "ARRAY_ENUM16(VertexAttrib[VERT_ATTRIB_POS].Format.Type), NO_EXTRA" ],
   [ "VERTEX_ARRAY_STRIDE", "ARRAY_SHORT(VertexAttrib[VERT_ATTRIB_POS].Stride), NO_EXTRA" ],
   [ "NORMAL_ARRAY", "LOC_CUSTOM, TYPE_BOOLEAN, 0, NO_EXTRA" ],
-  [ "NORMAL_ARRAY_TYPE", "ARRAY_ENUM16(VertexAttrib[VERT_ATTRIB_NORMAL].Type), NO_EXTRA" ],
+  [ "NORMAL_ARRAY_TYPE", "ARRAY_ENUM16(VertexAttrib[VERT_ATTRIB_NORMAL].Format.Type), NO_EXTRA" ],
   [ "NORMAL_ARRAY_STRIDE", "ARRAY_SHORT(VertexAttrib[VERT_ATTRIB_NORMAL].Stride), NO_EXTRA" ],
   [ "COLOR_ARRAY", "LOC_CUSTOM, TYPE_BOOLEAN, 0, NO_EXTRA" ],
   [ "COLOR_ARRAY_SIZE", "LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA" ],
-  [ "COLOR_ARRAY_TYPE", "ARRAY_ENUM16(VertexAttrib[VERT_ATTRIB_COLOR0].Type), NO_EXTRA" ],
+  [ "COLOR_ARRAY_TYPE", "ARRAY_ENUM16(VertexAttrib[VERT_ATTRIB_COLOR0].Format.Type), NO_EXTRA" ],
   [ "COLOR_ARRAY_STRIDE", "ARRAY_SHORT(VertexAttrib[VERT_ATTRIB_COLOR0].Stride), NO_EXTRA" ],
   [ "TEXTURE_COORD_ARRAY", "LOC_CUSTOM, TYPE_BOOLEAN, 0, NO_EXTRA" ],
-  [ "TEXTURE_COORD_ARRAY_SIZE", "LOC_CUSTOM, TYPE_UBYTE, offsetof(struct gl_array_attributes, Size), NO_EXTRA" ],
-  [ "TEXTURE_COORD_ARRAY_TYPE", "LOC_CUSTOM, TYPE_ENUM16, offsetof(struct gl_array_attributes, Type), NO_EXTRA" ],
+  [ "TEXTURE_COORD_ARRAY_SIZE", "LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA" ],
+  [ "TEXTURE_COORD_ARRAY_TYPE", "LOC_CUSTOM, TYPE_ENUM16, offsetof(struct gl_array_attributes, Format.Type), NO_EXTRA" ],
   [ "TEXTURE_COORD_ARRAY_STRIDE", "LOC_CUSTOM, TYPE_SHORT, offsetof(struct gl_array_attributes, Stride), NO_EXTRA" ],
 
 # GL_ARB_multitexture
@@ -254,7 +254,7 @@ descriptor=[
 { "apis": ["GLES"], "params": [
 # OES_point_size_array
   [ "POINT_SIZE_ARRAY_OES", "LOC_CUSTOM, TYPE_BOOLEAN, 0, NO_EXTRA" ],
-  [ "POINT_SIZE_ARRAY_TYPE_OES", "ARRAY_FIELD(VertexAttrib[VERT_ATTRIB_POINT_SIZE].Type, TYPE_ENUM16), NO_EXTRA" ],
+  [ "POINT_SIZE_ARRAY_TYPE_OES", "ARRAY_FIELD(VertexAttrib[VERT_ATTRIB_POINT_SIZE].Format.Type, TYPE_ENUM16), NO_EXTRA" ],
   [ "POINT_SIZE_ARRAY_STRIDE_OES", "ARRAY_FIELD(VertexAttrib[VERT_ATTRIB_POINT_SIZE].Stride, TYPE_SHORT), NO_EXTRA" ],
   [ "POINT_SIZE_ARRAY_BUFFER_BINDING_OES", "LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA" ],
 ]},
@@ -794,7 +794,7 @@ descriptor=[
   [ "NORMAL_ARRAY_COUNT_EXT", "CONST(0), NO_EXTRA" ],
   [ "COLOR_ARRAY_COUNT_EXT", "CONST(0), NO_EXTRA" ],
   [ "INDEX_ARRAY", "LOC_CUSTOM, TYPE_BOOLEAN, 0, NO_EXTRA" ],
-  [ "INDEX_ARRAY_TYPE", "ARRAY_ENUM16(VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Type), NO_EXTRA" ],
+  [ "INDEX_ARRAY_TYPE", "ARRAY_ENUM16(VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Format.Type), NO_EXTRA" ],
   [ "INDEX_ARRAY_STRIDE", "ARRAY_SHORT(VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Stride), NO_EXTRA" ],
   [ "INDEX_ARRAY_COUNT_EXT", "CONST(0), NO_EXTRA" ],
   [ "TEXTURE_COORD_ARRAY_COUNT_EXT", "CONST(0), NO_EXTRA" ],
@@ -828,14 +828,14 @@ descriptor=[
   [ "COLOR_SUM", "CONTEXT_BOOL(Fog.ColorSumEnabled), NO_EXTRA" ],
   [ "CURRENT_SECONDARY_COLOR", "CONTEXT_FIELD(Current.Attrib[VERT_ATTRIB_COLOR1][0], TYPE_FLOATN_4), extra_flush_current" ],
   [ "SECONDARY_COLOR_ARRAY", "LOC_CUSTOM, TYPE_BOOLEAN, 0, NO_EXTRA" ],
-  [ "SECONDARY_COLOR_ARRAY_TYPE", "ARRAY_ENUM16(VertexAttrib[VERT_ATTRIB_COLOR1].Type), NO_EXTRA" ],
+  [ "SECONDARY_COLOR_ARRAY_TYPE", "ARRAY_ENUM16(VertexAttrib[VERT_ATTRIB_COLOR1].Format.Type), NO_EXTRA" ],
   [ "SECONDARY_COLOR_ARRAY_STRIDE", "ARRAY_SHORT(VertexAttrib[VERT_ATTRIB_COLOR1].Stride), NO_EXTRA" ],
   [ "SECONDARY_COLOR_ARRAY_SIZE", "LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA" ],
 
 # GL_EXT_fog_coord
   [ "CURRENT_FOG_COORDINATE", "CONTEXT_FLOAT(Current.Attrib[VERT_ATTRIB_FOG][0]), extra_flush_current" ],
   [ "FOG_COORDINATE_ARRAY", "LOC_CUSTOM, TYPE_BOOLEAN, 0, NO_EXTRA" ],
-  [ "FOG_COORDINATE_ARRAY_TYPE", "ARRAY_ENUM16(VertexAttrib[VERT_ATTRIB_FOG].Type), NO_EXTRA" ],
+  [ "FOG_COORDINATE_ARRAY_TYPE", "ARRAY_ENUM16(VertexAttrib[VERT_ATTRIB_FOG].Format.Type), NO_EXTRA" ],
   [ "FOG_COORDINATE_ARRAY_STRIDE", "ARRAY_SHORT(VertexAttrib[VERT_ATTRIB_FOG].Stride), NO_EXTRA" ],
   [ "FOG_COORDINATE_SOURCE", "CONTEXT_ENUM16(Fog.FogCoordinateSource), NO_EXTRA" ],
 
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index da6a261688..421b078337 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -456,6 +456,21 @@ struct gl_colorbuffer_attrib
 };
 
 
+/**
+ * Vertex format to describe a vertex element.
+ */
+struct gl_vertex_format
+{
+   GLenum16 Type;              /**< datatype: GL_FLOAT, GL_INT, etc */
+   GLenum16 Format;            /**< default: GL_RGBA, but may be GL_BGRA */
+   GLubyte Size:5;             /**< components per element (1,2,3,4) */
+   unsigned char Normalized:1; /**< GL_ARB_vertex_program */
+   unsigned char Integer:1;    /**< Integer-valued? */
+   unsigned char Doubles:1;    /**< double values are not converted to floats */
+   unsigned char _ElementSize; /**< Size of each element in bytes */
+};
+
+
 /**
  * Current attribute group (GL_CURRENT_BIT).
  */
@@ -1419,14 +1434,10 @@ struct gl_array_attributes
    const GLubyte *Ptr;
    /** Offset of the first element relative to the binding offset */
    GLuint RelativeOffset;
-   GLshort Stride;          /**< Stride as specified with gl*Pointer() */
-   GLenum16 Type;           /**< Datatype: GL_FLOAT, GL_INT, etc */
-   GLenum16 Format;         /**< Default: GL_RGBA, but may be GL_BGRA */
-   GLubyte Size;            /**< Components per element (1,2,3,4) */
-   unsigned Normalized:1;   /**< Fixed-point values are normalized when converted to floats */
-   unsigned Integer:1;      /**< Fixed-point values are not converted to floats */
-   unsigned Doubles:1;      /**< double precision values are not converted to floats */
-   unsigned _ElementSize:8; /**< Size of each element in bytes */
+   /** Vertex format */
+   struct gl_vertex_format Format;
+   /** Stride as specified with gl*Pointer() */
+   GLshort Stride;
    /** Index into gl_vertex_array_object::BufferBinding[] array */
    unsigned BufferBindingIndex:6;
 
diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c
index a6d00c6ef9..2507e5338c 100644
--- a/src/mesa/main/varray.c
+++ b/src/mesa/main/varray.c
@@ -33,6 +33,7 @@
 #include "context.h"
 #include "enable.h"
 #include "enums.h"
+#include "glformats.h"
 #include "hash.h"
 #include "image.h"
 #include "macros.h"
@@ -243,6 +244,24 @@ vertex_binding_divisor(struct gl_context *ctx,
 }
 
 
+void
+_mesa_set_vertex_format(struct gl_vertex_format *vertex_format,
+                        GLubyte size, GLenum16 type, GLenum16 format,
+                        GLboolean normalized, GLboolean integer,
+                        GLboolean doubles)
+{
+   assert(size <= 4);
+   vertex_format->Type = type;
+   vertex_format->Format = format;
+   vertex_format->Size = size;
+   vertex_format->Normalized = normalized;
+   vertex_format->Integer = integer;
+   vertex_format->Doubles = doubles;
+   vertex_format->_ElementSize = _mesa_bytes_per_vertex_attrib(size, type);
+   assert(vertex_format->_ElementSize <= 4*sizeof(double));
+}
+
+
 /**
  * Examine the API profile and extensions to determine which types are legal
  * for vertex arrays.  This is called once from update_array_format().
@@ -330,22 +349,13 @@ _mesa_update_array_format(struct gl_context *ctx,
                           GLuint relativeOffset)
 {
    struct gl_array_attributes *const array = &vao->VertexAttrib[attrib];
-   GLint elementSize;
 
    assert(!vao->SharedAndImmutable);
    assert(size <= 4);
 
-   elementSize = _mesa_bytes_per_vertex_attrib(size, type);
-   assert(elementSize != -1);
-
-   array->Size = size;
-   array->Type = type;
-   array->Format = format;
-   array->Normalized = normalized;
-   array->Integer = integer;
-   array->Doubles = doubles;
    array->RelativeOffset = relativeOffset;
-   array->_ElementSize = elementSize;
+   _mesa_set_vertex_format(&array->Format, size, type, format,
+                           normalized, integer, doubles);
 
    vao->NewArrays |= vao->Enabled & VERT_BIT(attrib);
    if (vao == ctx->Array.VAO)
@@ -609,7 +619,8 @@ update_array(struct gl_context *ctx,
    array->Ptr = ptr;
 
    /* Update the vertex buffer binding */
-   GLsizei effectiveStride = stride != 0 ? stride : array->_ElementSize;
+   GLsizei effectiveStride = stride != 0 ?
+      stride : array->Format._ElementSize;
    _mesa_bind_vertex_buffer(ctx, vao, attrib,
                             ctx->Array.ArrayBufferObj, (GLintptr) ptr,
                             effectiveStride);
@@ -1269,25 +1280,25 @@ get_vertex_array_attrib(struct gl_context *ctx,
    case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB:
       return !!(vao->Enabled & VERT_BIT_GENERIC(index));
    case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB:
-      return (array->Format == GL_BGRA) ? GL_BGRA : array->Size;
+      return (array->Format.Format == GL_BGRA) ? GL_BGRA : array->Format.Size;
    case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB:
       return array->Stride;
    case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB:
-      return array->Type;
+      return array->Format.Type;
    case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB:
-      return array->Normalized;
+      return array->Format.Normalized;
    case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB:
       return vao->BufferBinding[array->BufferBindingIndex].BufferObj->Name;
    case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
       if ((_mesa_is_desktop_gl(ctx)
            && (ctx->Version >= 30 || ctx->Extensions.EXT_gpu_shader4))
           || _mesa_is_gles3(ctx)) {
-         return array->Integer;
+         return array->Format.Integer;
       }
       goto error;
    case GL_VERTEX_ATTRIB_ARRAY_LONG:
       if (_mesa_is_desktop_gl(ctx)) {
-         return array->Doubles;
+         return array->Format.Doubles;
       }
       goto error;
    case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB:
@@ -2771,17 +2782,11 @@ _mesa_copy_vertex_attrib_array(struct gl_context *ctx,
                                struct gl_array_attributes *dst,
                                const struct gl_array_attributes *src)
 {
-   dst->Size           = src->Size;
-   dst->Type           = src->Type;
-   dst->Format         = src->Format;
-   dst->BufferBindingIndex = src->BufferBindingIndex;
-   dst->RelativeOffset = src->RelativeOffset;
-   dst->Format         = src->Format;
-   dst->Integer        = src->Integer;
-   dst->Doubles        = src->Doubles;
-   dst->Normalized     = src->Normalized;
    dst->Ptr            = src->Ptr;
-   dst->_ElementSize   = src->_ElementSize;
+   dst->RelativeOffset = src->RelativeOffset;
+   _mesa_copy_vertex_format(&dst->Format, &src->Format);
+   dst->Stride         = src->Stride;
+   dst->BufferBindingIndex = src->BufferBindingIndex;
    dst->_EffBufferBindingIndex = src->_EffBufferBindingIndex;
    dst->_EffRelativeOffset = src->_EffRelativeOffset;
 }
@@ -2823,8 +2828,9 @@ _mesa_print_arrays(struct gl_context *ctx)
       fprintf(stderr, "  %s: Ptr=%p, Type=%s, Size=%d, ElemSize=%u, "
               "Stride=%d, Buffer=%u(Size %lu)\n",
               gl_vert_attrib_name((gl_vert_attrib)i),
-              array->Ptr, _mesa_enum_to_string(array->Type), array->Size,
-              array->_ElementSize, binding->Stride, bo->Name,
+              array->Ptr, _mesa_enum_to_string(array->Format.Type),
+              array->Format.Size,
+              array->Format._ElementSize, binding->Stride, bo->Name,
               (unsigned long) bo->Size);
    }
 }
diff --git a/src/mesa/main/varray.h b/src/mesa/main/varray.h
index 823e4f408b..fcb688f89f 100644
--- a/src/mesa/main/varray.h
+++ b/src/mesa/main/varray.h
@@ -29,6 +29,26 @@
 
 #include "bufferobj.h"
 
+void
+_mesa_set_vertex_format(struct gl_vertex_format *vertex_format,
+                        GLubyte size, GLenum16 type, GLenum16 format,
+                        GLboolean normalized, GLboolean integer,
+                        GLboolean doubles);
+
+
+static inline void
+_mesa_copy_vertex_format(struct gl_vertex_format *dst,
+                         const struct gl_vertex_format *src)
+{
+   dst->Type = src->Type;
+   dst->Format = src->Format;
+   dst->Size = src->Size;
+   dst->Normalized = src->Normalized;
+   dst->Integer = src->Integer;
+   dst->Doubles = src->Doubles;
+   dst->_ElementSize = src->_ElementSize;
+}
+
 
 /**
  * Returns a pointer to the vertex attribute data in a client array,
diff --git a/src/mesa/state_tracker/st_atom.h b/src/mesa/state_tracker/st_atom.h
index 96e128d38c..9f3ca38c19 100644
--- a/src/mesa/state_tracker/st_atom.h
+++ b/src/mesa/state_tracker/st_atom.h
@@ -55,7 +55,7 @@ void st_validate_state( struct st_context *st, enum st_pipeline pipeline );
 GLuint st_compare_func_to_pipe(GLenum func);
 
 enum pipe_format
-st_pipe_vertex_format(const struct gl_array_attributes *attrib);
+st_pipe_vertex_format(const struct gl_vertex_format *glformat);
 
 
 /* Define ST_NEW_xxx_INDEX */
diff --git a/src/mesa/state_tracker/st_atom_array.c b/src/mesa/state_tracker/st_atom_array.c
index e4fc19eb5e..19a5ef29a9 100644
--- a/src/mesa/state_tracker/st_atom_array.c
+++ b/src/mesa/state_tracker/st_atom_array.c
@@ -238,18 +238,18 @@ static const uint16_t vertex_formats[][4][4] = {
  * Return a PIPE_FORMAT_x for the given GL datatype and size.
  */
 enum pipe_format
-st_pipe_vertex_format(const struct gl_array_attributes *attrib)
+st_pipe_vertex_format(const struct gl_vertex_format *vformat)
 {
-   const GLubyte size = attrib->Size;
-   const GLenum16 format = attrib->Format;
-   const bool normalized = attrib->Normalized;
-   const bool integer = attrib->Integer;
-   GLenum16 type = attrib->Type;
+   const GLubyte size = vformat->Size;
+   const GLenum16 format = vformat->Format;
+   const bool normalized = vformat->Normalized;
+   const bool integer = vformat->Integer;
+   GLenum16 type = vformat->Type;
    unsigned index;
 
    assert(size >= 1 && size <= 4);
    assert(format == GL_RGBA || format == GL_BGRA);
-   assert(attrib->_ElementSize == _mesa_bytes_per_vertex_attrib(size, type));
+   assert(vformat->_ElementSize == _mesa_bytes_per_vertex_attrib(size, type));
 
    switch (type) {
    case GL_HALF_FLOAT_OES:
@@ -320,13 +320,13 @@ static void init_velement(struct pipe_vertex_element *velement,
 
 static void init_velement_lowered(const struct st_vertex_program *vp,
                                   struct pipe_vertex_element *velements,
-                                  const struct gl_array_attributes *attrib,
+                                  const struct gl_vertex_format *vformat,
                                   int src_offset, int instance_divisor,
                                   int vbo_index, int idx)
 {
-   const GLubyte nr_components = attrib->Size;
+   const GLubyte nr_components = vformat->Size;
 
-   if (attrib->Doubles) {
+   if (vformat->Doubles) {
       int lower_format;
 
       if (nr_components < 2)
@@ -357,7 +357,7 @@ static void init_velement_lowered(const struct st_vertex_program *vp,
          }
       }
    } else {
-      const unsigned format = st_pipe_vertex_format(attrib);
+      const unsigned format = st_pipe_vertex_format(vformat);
 
       init_velement(&velements[idx], src_offset,
                     format, instance_divisor, vbo_index);
@@ -447,7 +447,7 @@ st_update_array(struct st_context *st)
          const struct gl_array_attributes *const attrib
             = _mesa_draw_array_attrib(vao, attr);
          const GLuint off = _mesa_draw_attributes_relative_offset(attrib);
-         init_velement_lowered(vp, velements, attrib, off,
+         init_velement_lowered(vp, velements, &attrib->Format, off,
                                binding->InstanceDivisor, bufidx,
                                input_to_index[attr]);
       }
@@ -468,14 +468,14 @@ st_update_array(struct st_context *st)
          const gl_vert_attrib attr = u_bit_scan(&curmask);
          const struct gl_array_attributes *const attrib
             = _mesa_draw_current_attrib(ctx, attr);
-         const unsigned size = attrib->_ElementSize;
+         const unsigned size = attrib->Format._ElementSize;
          const unsigned alignment = util_next_power_of_two(size);
          max_alignment = MAX2(max_alignment, alignment);
          memcpy(cursor, attrib->Ptr, size);
          if (alignment != size)
             memset(cursor + size, 0, alignment - size);
 
-         init_velement_lowered(vp, velements, attrib, cursor - data, 0,
+         init_velement_lowered(vp, velements, &attrib->Format, cursor - data, 0,
                                bufidx, input_to_index[attr]);
 
          cursor += alignment;
diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c
index eb05ac9669..11097b4cac 100644
--- a/src/mesa/state_tracker/st_draw_feedback.c
+++ b/src/mesa/state_tracker/st_draw_feedback.c
@@ -212,7 +212,7 @@ st_feedback_draw_vbo(struct gl_context *ctx,
       vbuffers[attr].stride = binding->Stride; /* in bytes */
       velements[attr].instance_divisor = 0;
       velements[attr].vertex_buffer_index = attr;
-      velements[attr].src_format = st_pipe_vertex_format(attrib);
+      velements[attr].src_format = st_pipe_vertex_format(&attrib->Format);
       assert(velements[attr].src_format);
 
       /* tell draw about this attribute */
diff --git a/src/mesa/tnl/t_draw.c b/src/mesa/tnl/t_draw.c
index 1fe2d405cb..009a0bf362 100644
--- a/src/mesa/tnl/t_draw.c
+++ b/src/mesa/tnl/t_draw.c
@@ -70,7 +70,7 @@ static void free_space(struct gl_context *ctx)
  */
 #define CONVERT( TYPE, MACRO ) do {		\
    GLuint i, j;					\
-   if (attrib->Normalized) {			\
+   if (attrib->Format.Normalized) {		\
       for (i = 0; i < count; i++) {		\
 	 const TYPE *in = (TYPE *)ptr;		\
 	 for (j = 0; j < sz; j++) {		\
@@ -104,8 +104,8 @@ convert_bgra_to_float(const struct gl_vertex_buffer_binding *binding,
                       GLuint count )
 {
    GLuint i;
-   assert(attrib->Normalized);
-   assert(attrib->Size == 4);
+   assert(attrib->Format.Normalized);
+   assert(attrib->Format.Size == 4);
    for (i = 0; i < count; i++) {
       const GLubyte *in = (GLubyte *) ptr;  /* in is in BGRA order */
       *fptr++ = UBYTE_TO_FLOAT(in[2]);  /* red */
@@ -152,9 +152,9 @@ convert_fixed_to_float(const struct gl_vertex_buffer_binding *binding,
 {
    GLuint i;
    GLint j;
-   const GLint size = attrib->Size;
+   const GLint size = attrib->Format.Size;
 
-   if (attrib->Normalized) {
+   if (attrib->Format.Normalized) {
       for (i = 0; i < count; ++i) {
          const GLfixed *in = (GLfixed *) ptr;
          for (j = 0; j < size; ++j) {
@@ -187,17 +187,17 @@ static void _tnl_import_array( struct gl_context *ctx,
    struct vertex_buffer *VB = &tnl->vb;
    GLuint stride = binding->Stride;
 
-   if (attrib->Type != GL_FLOAT) {
-      const GLuint sz = attrib->Size;
+   if (attrib->Format.Type != GL_FLOAT) {
+      const GLuint sz = attrib->Format.Size;
       GLubyte *buf = get_space(ctx, count * sz * sizeof(GLfloat));
       GLfloat *fptr = (GLfloat *)buf;
 
-      switch (attrib->Type) {
+      switch (attrib->Format.Type) {
       case GL_BYTE: 
 	 CONVERT(GLbyte, BYTE_TO_FLOAT); 
 	 break;
       case GL_UNSIGNED_BYTE: 
-         if (attrib->Format == GL_BGRA) {
+         if (attrib->Format.Format == GL_BGRA) {
             /* See GL_EXT_vertex_array_bgra */
             convert_bgra_to_float(binding, attrib, ptr, fptr, count);
          }
@@ -240,11 +240,11 @@ static void _tnl_import_array( struct gl_context *ctx,
    VB->AttribPtr[attr]->start = (GLfloat *)ptr;
    VB->AttribPtr[attr]->count = count;
    VB->AttribPtr[attr]->stride = stride;
-   VB->AttribPtr[attr]->size = attrib->Size;
+   VB->AttribPtr[attr]->size = attrib->Format.Size;
 
    /* This should die, but so should the whole GLvector4f concept: 
     */
-   VB->AttribPtr[attr]->flags = (((1<<attrib->Size)-1) |
+   VB->AttribPtr[attr]->flags = (((1<<attrib->Format.Size)-1) |
 				   VEC_NOT_WRITEABLE |
 				   (stride == 4*sizeof(GLfloat) ? 0 : VEC_BAD_STRIDE));
    
diff --git a/src/mesa/tnl/t_split_copy.c b/src/mesa/tnl/t_split_copy.c
index 1732b4c9ca..e04cfad049 100644
--- a/src/mesa/tnl/t_split_copy.c
+++ b/src/mesa/tnl/t_split_copy.c
@@ -169,7 +169,7 @@ dump_draw_info(struct gl_context *ctx,
          const GLubyte *ptr = _mesa_vertex_attrib_address(attrib, binding);
          printf("    array %d at %p:\n", j, (void*) &arrays[j]);
          printf("      ptr %p, size %d, type 0x%x, stride %d\n",
-                ptr, attrib->Size, attrib->Type, binding->Stride);
+                ptr, attrib->Format.Size, attrib->Format.Type, binding->Stride);
          if (0) {
             GLint k = prims[i].start + prims[i].count - 1;
             GLfloat *last = (GLfloat *) (ptr + binding->Stride * k);
@@ -269,7 +269,7 @@ elt(struct copy_context *copy, GLuint elt_idx)
          csr += copy->varying[i].size;
 
 #ifdef NAN_CHECK
-         if (srcarray->Type == GL_FLOAT) {
+         if (srcarray->Format.Type == GL_FLOAT) {
             GLuint k;
             GLfloat *f = (GLfloat *) srcptr;
             for (k = 0; k < srcarray->Size; k++) {
@@ -451,8 +451,8 @@ replay_init(struct copy_context *copy)
 
          copy->varying[j].attr = i;
          copy->varying[j].array = &copy->array[i];
-         copy->varying[j].size = attrib->_ElementSize;
-         copy->vertex_size += attrib->_ElementSize;
+         copy->varying[j].size = attrib->Format._ElementSize;
+         copy->vertex_size += attrib->Format._ElementSize;
 
          if (_mesa_is_bufferobj(vbo) &&
              !_mesa_bufferobj_mapped(vbo, MAP_INTERNAL))
@@ -528,16 +528,10 @@ replay_init(struct copy_context *copy)
       struct gl_vertex_buffer_binding *dstbind = &copy->varying[i].dstbinding;
       struct gl_array_attributes *dstattr = &copy->varying[i].dstattribs;
 
-      dstattr->Size = srcattr->Size;
-      dstattr->Type = srcattr->Type;
-      dstattr->Format = GL_RGBA;
-      dstbind->Stride = copy->vertex_size;
+      _mesa_copy_vertex_format(&dstattr->Format, &srcattr->Format);
       dstattr->Ptr = copy->dstbuf + offset;
-      dstattr->Normalized = srcattr->Normalized;
-      dstattr->Integer = srcattr->Integer;
-      dstattr->Doubles = srcattr->Doubles;
+      dstbind->Stride = copy->vertex_size;
       dstbind->BufferObj = ctx->Shared->NullBufferObj;
-      dstattr->_ElementSize = srcattr->_ElementSize;
       dst->BufferBinding = dstbind;
       dst->VertexAttrib = dstattr;
 
diff --git a/src/mesa/vbo/vbo_context.c b/src/mesa/vbo/vbo_context.c
index 364de2c507..484625d9ac 100644
--- a/src/mesa/vbo/vbo_context.c
+++ b/src/mesa/vbo/vbo_context.c
@@ -58,11 +58,8 @@ init_array(struct gl_context *ctx, struct gl_array_attributes *attrib,
 {
    memset(attrib, 0, sizeof(*attrib));
 
-   attrib->Size = size;
-   attrib->Type = GL_FLOAT;
-   attrib->Format = GL_RGBA;
+   vbo_set_vertex_format(&attrib->Format, size, GL_FLOAT);
    attrib->Stride = 0;
-   attrib->_ElementSize = size * sizeof(GLfloat);
    attrib->Ptr = pointer;
 }
 
diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c
index 24bd1f0ba1..fd88b7d2d4 100644
--- a/src/mesa/vbo/vbo_exec_api.c
+++ b/src/mesa/vbo/vbo_exec_api.c
@@ -195,7 +195,7 @@ vbo_exec_copy_to_current(struct vbo_exec_context *exec)
                                      exec->vtx.attrtype[i]);
       }
 
-      if (exec->vtx.attrtype[i] != vbo->current[i].Type ||
+      if (exec->vtx.attrtype[i] != vbo->current[i].Format.Type ||
           memcmp(current, tmp, 4 * sizeof(GLfloat) * dmul) != 0) {
          memcpy(current, tmp, 4 * sizeof(GLfloat) * dmul);
 
@@ -205,14 +205,9 @@ vbo_exec_copy_to_current(struct vbo_exec_context *exec)
           * directly.
           */
          /* Size here is in components - not bytes */
-         vbo->current[i].Size = exec->vtx.attrsz[i] / dmul;
-         vbo->current[i]._ElementSize =
-            vbo->current[i].Size * sizeof(GLfloat) * dmul;
-         vbo->current[i].Type = exec->vtx.attrtype[i];
-         vbo->current[i].Integer =
-            vbo_attrtype_to_integer_flag(exec->vtx.attrtype[i]);
-         vbo->current[i].Doubles =
-            vbo_attrtype_to_double_flag(exec->vtx.attrtype[i]);
+         vbo_set_vertex_format(&vbo->current[i].Format,
+                               exec->vtx.attrsz[i] / dmul,
+                               exec->vtx.attrtype[i]);
 
          /* This triggers rather too much recalculation of Mesa state
           * that doesn't get used (eg light positions).
diff --git a/src/mesa/vbo/vbo_private.h b/src/mesa/vbo/vbo_private.h
index 1fc2ab48fd..6110a6cc0e 100644
--- a/src/mesa/vbo/vbo_private.h
+++ b/src/mesa/vbo/vbo_private.h
@@ -115,6 +115,16 @@ vbo_attrtype_to_double_flag(GLenum format)
 }
 
 
+static inline void
+vbo_set_vertex_format(struct gl_vertex_format* vertex_format,
+                      GLubyte size, GLenum16 type)
+{
+   _mesa_set_vertex_format(vertex_format, size, type, GL_RGBA, GL_FALSE,
+                           vbo_attrtype_to_integer_flag(type),
+                           vbo_attrtype_to_double_flag(type));
+}
+
+
 /**
  * Return default component values for the given format.
  * The return type is an array of fi_types, because that's how we declare
diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c
index 8dc03b9f77..fb8d68d556 100644
--- a/src/mesa/vbo/vbo_save_api.c
+++ b/src/mesa/vbo/vbo_save_api.c
@@ -450,14 +450,14 @@ compare_vao(gl_vertex_processing_mode mode,
       const struct gl_array_attributes *attrib = &vao->VertexAttrib[attr];
       if (attrib->RelativeOffset + vao->BufferBinding[0].Offset != off)
          return false;
-      if (attrib->Type != tp)
+      if (attrib->Format.Type != tp)
          return false;
-      if (attrib->Size != size[vbo_attr])
+      if (attrib->Format.Size != size[vbo_attr])
          return false;
-      assert(attrib->Format == GL_RGBA);
-      assert(attrib->Normalized == GL_FALSE);
-      assert(attrib->Integer == vbo_attrtype_to_integer_flag(tp));
-      assert(attrib->Doubles == vbo_attrtype_to_double_flag(tp));
+      assert(attrib->Format.Format == GL_RGBA);
+      assert(attrib->Format.Normalized == GL_FALSE);
+      assert(attrib->Format.Integer == vbo_attrtype_to_integer_flag(tp));
+      assert(attrib->Format.Doubles == vbo_attrtype_to_double_flag(tp));
       assert(attrib->BufferBindingIndex == 0);
    }
 
diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c
index b3578cc27c..b5807bb377 100644
--- a/src/mesa/vbo/vbo_save_draw.c
+++ b/src/mesa/vbo/vbo_save_draw.c
@@ -52,8 +52,8 @@ copy_vao(struct gl_context *ctx, const struct gl_vertex_array_object *vao,
       const int i = u_bit_scan(&mask);
       const struct gl_array_attributes *attrib = &vao->VertexAttrib[i];
       struct gl_array_attributes *currval = &vbo->current[shift + i];
-      const GLubyte size = attrib->Size;
-      const GLenum16 type = attrib->Type;
+      const GLubyte size = attrib->Format.Size;
+      const GLenum16 type = attrib->Format.Type;
       fi_type tmp[8];
       int dmul = 1;
 
@@ -66,17 +66,11 @@ copy_vao(struct gl_context *ctx, const struct gl_vertex_array_object *vao,
       else
          COPY_CLEAN_4V_TYPE_AS_UNION(tmp, size, *data, type);
 
-      if (type != currval->Type ||
+      if (type != currval->Format.Type ||
           memcmp(currval->Ptr, tmp, 4 * sizeof(GLfloat) * dmul) != 0) {
          memcpy((fi_type*)currval->Ptr, tmp, 4 * sizeof(GLfloat) * dmul);
 
-         currval->Size = size;
-         currval->_ElementSize = size * sizeof(GLfloat) * dmul;
-         currval->Type = type;
-         currval->Integer = vbo_attrtype_to_integer_flag(type);
-         currval->Doubles = vbo_attrtype_to_double_flag(type);
-         currval->Normalized = GL_FALSE;
-         currval->Format = GL_RGBA;
+         vbo_set_vertex_format(&currval->Format, size, type);
 
          ctx->NewState |= state;
       }
diff --git a/src/mesa/vbo/vbo_save_loopback.c b/src/mesa/vbo/vbo_save_loopback.c
index 7e9296bae2..26a9f94fac 100644
--- a/src/mesa/vbo/vbo_save_loopback.c
+++ b/src/mesa/vbo/vbo_save_loopback.c
@@ -139,7 +139,7 @@ append_attr(GLuint *nr, struct loopback_attr la[], int i, int shift,
 {
    la[*nr].index = shift + i;
    la[*nr].offset = vao->VertexAttrib[i].RelativeOffset;
-   la[*nr].func = vert_attrfunc[vao->VertexAttrib[i].Size - 1];
+   la[*nr].func = vert_attrfunc[vao->VertexAttrib[i].Format.Size - 1];
    (*nr)++;
 }
 
-- 
2.17.2



More information about the mesa-dev mailing list