diff --git a/src/mesa/main/arrayobj.c b/src/mesa/main/arrayobj.c index 42a059b9d68..85b6f000ee0 100644 --- a/src/mesa/main/arrayobj.c +++ b/src/mesa/main/arrayobj.c @@ -518,7 +518,7 @@ _mesa_update_vao_derived_arrays(struct gl_context *ctx, 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 = @@ -555,6 +555,8 @@ _mesa_update_vao_derived_arrays(struct gl_context *ctx, /* 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; } @@ -810,7 +812,8 @@ _mesa_set_vao_immutable(struct gl_context *ctx, 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; } diff --git a/src/mesa/main/arrayobj.h b/src/mesa/main/arrayobj.h index 721b5abc658..4145695d45b 100644 --- a/src/mesa/main/arrayobj.h +++ b/src/mesa/main/arrayobj.h @@ -188,7 +188,7 @@ static inline GLbitfield _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; } @@ -202,7 +202,7 @@ static inline GLbitfield _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; } @@ -216,7 +216,7 @@ static inline GLbitfield _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; } @@ -240,7 +240,7 @@ static inline const struct gl_vertex_buffer_binding* _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]; } @@ -252,7 +252,7 @@ static inline const struct gl_array_attributes* _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]]; } diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c index f9faf67df8e..2742c27e54f 100644 --- a/src/mesa/main/attrib.c +++ b/src/mesa/main/attrib.c @@ -1360,7 +1360,8 @@ copy_array_object(struct gl_context *ctx, 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 */ } diff --git a/src/mesa/main/draw.c b/src/mesa/main/draw.c index 1ab837e7361..6a47570e7d6 100644 --- a/src/mesa/main/draw.c +++ b/src/mesa/main/draw.c @@ -104,18 +104,20 @@ _mesa_set_draw_vao(struct gl_context *ctx, struct gl_vertex_array_object *vao, 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 == @@ -125,11 +127,14 @@ _mesa_set_draw_vao(struct gl_context *ctx, struct gl_vertex_array_object *vao, 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); } diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 64c70d95051..17e9deec153 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1639,8 +1639,9 @@ struct gl_vertex_array_object /** "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; @@ -1704,6 +1705,17 @@ struct gl_array_attrib * 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. diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index f4f5a5f5496..9a61d86c238 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -531,6 +531,7 @@ set_vertex_processing_mode(struct gl_context *ctx, gl_vertex_processing_mode m) /* 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; diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c index 0ccb50d2df1..000b8f8ea38 100644 --- a/src/mesa/main/varray.c +++ b/src/mesa/main/varray.c @@ -184,8 +184,11 @@ _mesa_vertex_attrib_binding(struct gl_context *ctx, 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); } } @@ -242,8 +245,13 @@ _mesa_bind_vertex_buffer(struct gl_context *ctx, 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); } } @@ -271,8 +279,11 @@ vertex_binding_divisor(struct gl_context *ctx, 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); } } @@ -656,7 +667,8 @@ _mesa_update_array_format(struct gl_context *ctx, array->Format = new_format; if (vao->Enabled & VERT_BIT(attrib)) - vao->NewArrays = true; + vao->NewVertexElements = true; + vao->NonDefaultStateMask |= BITFIELD_BIT(attrib); } @@ -916,8 +928,14 @@ update_array(struct gl_context *ctx, 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); } @@ -1889,7 +1907,8 @@ _mesa_enable_vertex_array_attribs(struct gl_context *ctx, 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 */ @@ -1990,7 +2009,8 @@ _mesa_disable_vertex_array_attribs(struct gl_context *ctx, 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)) diff --git a/src/mesa/state_tracker/st_cb_rasterpos.c b/src/mesa/state_tracker/st_cb_rasterpos.c index bb6a5f23774..39a7107886e 100644 --- a/src/mesa/state_tracker/st_cb_rasterpos.c +++ b/src/mesa/state_tracker/st_cb_rasterpos.c @@ -259,7 +259,10 @@ st_RasterPos(struct gl_context *ctx, const GLfloat v[4]) * 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. */ diff --git a/src/mesa/vbo/vbo_private.h b/src/mesa/vbo/vbo_private.h index 7e0e174b40f..57f896cd19c 100644 --- a/src/mesa/vbo/vbo_private.h +++ b/src/mesa/vbo/vbo_private.h @@ -255,8 +255,12 @@ _vbo_set_attrib_format(struct gl_context *ctx, 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); }