struct gl_vertex_array_object *vao)
{
/* Make sure we do not run into problems with shared objects */
- assert(!vao->SharedAndImmutable || !vao->NewArrays);
+ assert(!vao->SharedAndImmutable || (!vao->NewVertexBuffers && !vao->NewVertexElements));
/* Limit used for common binding scanning below. */
const GLsizeiptr MaxRelativeOffset =
/* More than 4 updates turn the VAO to dynamic. */
if (ctx->Const.AllowDynamicVAOFastPath && ++vao->NumUpdates > 4) {
vao->IsDynamic = true;
+ /* IsDynamic changes how vertex elements map to vertex buffers. */
+ vao->NewVertexElements = true;
return;
}
struct gl_vertex_array_object *vao)
{
_mesa_update_vao_derived_arrays(ctx, vao);
- vao->NewArrays = false;
+ vao->NewVertexBuffers = false;
+ vao->NewVertexElements = false;
vao->SharedAndImmutable = true;
}
_mesa_draw_vbo_array_bits(const struct gl_context *ctx)
{
const struct gl_vertex_array_object *const vao = ctx->Array._DrawVAO;
- assert(!vao->NewArrays);
+ assert(!vao->NewVertexBuffers && !vao->NewVertexElements);
return vao->_EffEnabledVBO & ctx->Array._DrawVAOEnabledAttribs;
}
_mesa_draw_user_array_bits(const struct gl_context *ctx)
{
const struct gl_vertex_array_object *const vao = ctx->Array._DrawVAO;
- assert(!vao->NewArrays);
+ assert(!vao->NewVertexBuffers && !vao->NewVertexElements);
return ~vao->_EffEnabledVBO & ctx->Array._DrawVAOEnabledAttribs;
}
_mesa_draw_nonzero_divisor_bits(const struct gl_context *ctx)
{
const struct gl_vertex_array_object *const vao = ctx->Array._DrawVAO;
- assert(!vao->NewArrays);
+ assert(!vao->NewVertexBuffers && !vao->NewVertexElements);
return vao->_EffEnabledNonZeroDivisor & ctx->Array._DrawVAOEnabledAttribs;
}
_mesa_draw_buffer_binding_from_attrib(const struct gl_vertex_array_object *vao,
const struct gl_array_attributes *attrib)
{
- assert(!vao->NewArrays);
+ assert(!vao->NewVertexBuffers && !vao->NewVertexElements);
return &vao->BufferBinding[attrib->_EffBufferBindingIndex];
}
_mesa_draw_array_attrib(const struct gl_vertex_array_object *vao,
gl_vert_attrib attr)
{
- assert(!vao->NewArrays);
+ assert(!vao->NewVertexBuffers && !vao->NewVertexElements);
const gl_attribute_map_mode map_mode = vao->_AttributeMapMode;
return &vao->VertexAttrib[_mesa_vao_attribute_map[map_mode][attr]];
}
dest->VertexAttribBufferMask = src->VertexAttribBufferMask;
dest->NonZeroDivisorMask = src->NonZeroDivisorMask;
dest->_AttributeMapMode = src->_AttributeMapMode;
- dest->NewArrays = src->NewArrays;
+ dest->NewVertexBuffers = src->NewVertexBuffers;
+ dest->NewVertexElements = src->NewVertexElements;
/* skip NumUpdates and IsDynamic because they can only increase, not decrease */
}
GLbitfield filter)
{
struct gl_vertex_array_object **ptr = &ctx->Array._DrawVAO;
- bool new_array = false;
+ bool new_vertex_buffers = false, new_vertex_elements = false;
+
if (*ptr != vao) {
_mesa_reference_vao_(ctx, ptr, vao);
-
- new_array = true;
+ new_vertex_buffers = true;
+ new_vertex_elements = true;
}
- if (vao->NewArrays) {
+ if (vao->NewVertexBuffers || vao->NewVertexElements) {
_mesa_update_vao_derived_arrays(ctx, vao);
- vao->NewArrays = false;
-
- new_array = true;
+ new_vertex_buffers |= vao->NewVertexBuffers;
+ new_vertex_elements |= vao->NewVertexElements;
+ vao->NewVertexBuffers = false;
+ vao->NewVertexElements = false;
}
assert(vao->_EnabledWithMapMode ==
const GLbitfield enabled = filter & vao->_EnabledWithMapMode;
if (ctx->Array._DrawVAOEnabledAttribs != enabled) {
ctx->Array._DrawVAOEnabledAttribs = enabled;
- new_array = true;
+ new_vertex_buffers = true;
+ new_vertex_elements = true;
}
- if (new_array)
+ if (new_vertex_buffers || new_vertex_elements) {
ctx->NewDriverState |= ctx->DriverFlags.NewArray;
+ ctx->Array.NewVertexElements |= new_vertex_elements;
+ }
_mesa_set_varying_vp_inputs(ctx, enabled);
}
/** "Enabled" with the position/generic0 attribute aliasing resolved */
GLbitfield _EnabledWithMapMode;
- /** Whether the VAO has been changed. */
- bool NewArrays;
+ /** Which states have been changed according to the gallium definitions. */
+ bool NewVertexBuffers;
+ bool NewVertexElements;
/** The index buffer (also known as the element array buffer in OpenGL). */
struct gl_buffer_object *IndexBufferObj;
* array draw is executed.
*/
GLbitfield _DrawVAOEnabledAttribs;
+
+ /**
+ * If gallium vertex buffers are dirty, this flag indicates whether gallium
+ * vertex elements are dirty too. If this is false, GL states corresponding
+ * to vertex elements have not been changed. Thus, this affects what will
+ * happen when gl_driver_flags::NewArray is set.
+ *
+ * The driver should clear this when it's done.
+ */
+ bool NewVertexElements;
+
/**
* Initially or if the VAO referenced by _DrawVAO is deleted the _DrawVAO
* pointer is set to the _EmptyVAO which is just an empty VAO all the time.
/* On change we may get new maps into the current values */
ctx->NewDriverState |= ctx->DriverFlags.NewArray;
+ ctx->Array.NewVertexElements = true;
/* Finally memorize the value */
ctx->VertexProgram._VPMode = m;
array->BufferBindingIndex = bindingIndex;
- if (vao->Enabled & array_bit)
- vao->NewArrays = true;
+ if (vao->Enabled & array_bit) {
+ vao->NewVertexBuffers = true;
+ vao->NewVertexElements = true;
+ }
+
vao->NonDefaultStateMask |= array_bit | BITFIELD_BIT(bindingIndex);
}
}
vbo->UsageHistory |= USAGE_ARRAY_BUFFER;
}
- if (vao->Enabled & binding->_BoundArrays)
- vao->NewArrays = true;
+ if (vao->Enabled & binding->_BoundArrays) {
+ vao->NewVertexBuffers = true;
+ /* Non-dynamic VAOs merge vertex buffers, which affects vertex elements. */
+ if (!vao->IsDynamic)
+ vao->NewVertexElements = true;
+ }
+
vao->NonDefaultStateMask |= BITFIELD_BIT(index);
}
}
else
vao->NonZeroDivisorMask &= ~binding->_BoundArrays;
- if (vao->Enabled & binding->_BoundArrays)
- vao->NewArrays = true;
+ if (vao->Enabled & binding->_BoundArrays) {
+ vao->NewVertexBuffers = true;
+ vao->NewVertexElements = true;
+ }
+
vao->NonDefaultStateMask |= BITFIELD_BIT(bindingIndex);
}
}
array->Format = new_format;
if (vao->Enabled & VERT_BIT(attrib))
- vao->NewArrays = true;
+ vao->NewVertexElements = true;
+
vao->NonDefaultStateMask |= BITFIELD_BIT(attrib);
}
if ((array->Stride != stride) || (array->Ptr != ptr)) {
array->Stride = stride;
array->Ptr = ptr;
- if (vao->Enabled & VERT_BIT(attrib))
- vao->NewArrays = true;
+
+ if (vao->Enabled & VERT_BIT(attrib)) {
+ vao->NewVertexBuffers = true;
+ /* Non-dynamic VAOs merge vertex buffers, which affects vertex elements. */
+ if (!vao->IsDynamic)
+ vao->NewVertexElements = true;
+ }
+
vao->NonDefaultStateMask |= BITFIELD_BIT(attrib);
}
if (attrib_bits) {
/* was disabled, now being enabled */
vao->Enabled |= attrib_bits;
- vao->NewArrays = true;
+ vao->NewVertexBuffers = true;
+ vao->NewVertexElements = true;
vao->NonDefaultStateMask |= attrib_bits;
/* Update the map mode if needed */
if (attrib_bits) {
/* was enabled, now being disabled */
vao->Enabled &= ~attrib_bits;
- vao->NewArrays = true;
+ vao->NewVertexBuffers = true;
+ vao->NewVertexElements = true;
/* Update the map mode if needed */
if (attrib_bits & (VERT_BIT_POS|VERT_BIT_GENERIC0))
* Just plug in position pointer now.
*/
rs->VAO->VertexAttrib[VERT_ATTRIB_POS].Ptr = (GLubyte *) v;
- rs->VAO->NewArrays = true;
+ rs->VAO->NewVertexBuffers = true;
+ /* Non-dynamic VAOs merge vertex buffers, which changes vertex elements. */
+ if (!rs->VAO->IsDynamic)
+ rs->VAO->NewVertexElements = true;
_mesa_set_draw_vao(ctx, rs->VAO, VERT_BIT_POS);
/* Draw the point. */
size /= 2;
_mesa_update_array_format(ctx, vao, attr, size, type, GL_RGBA,
GL_FALSE, integer, doubles, offset);
- if (vao->Enabled & VERT_BIT(attr))
- vao->NewArrays = true;
+
+ if (vao->Enabled & VERT_BIT(attr)) {
+ vao->NewVertexBuffers = true;
+ vao->NewVertexElements = true;
+ }
+
vao->VertexAttrib[attr].Ptr = ADD_POINTERS(buffer_offset, offset);
}