newObj->EverBound = GL_TRUE;
}
- /* The _DrawArrays pointer is pointing at the VAO being unbound and
- * that VAO may be in the process of being deleted. If it's not going
- * to be deleted, this will have no effect, because the pointer needs
- * to be updated by the VBO module anyway.
- *
- * Before the VBO module can update the pointer, we have to set it
- * to NULL for drivers not to set up arrays which are not bound,
- * or to prevent a crash if the VAO being unbound is going to be
- * deleted.
- */
- _mesa_set_draw_vao(ctx, ctx->Array._EmptyVAO);
- _mesa_update_vao_state(ctx, 0);
-
_mesa_reference_vao(ctx, &ctx->Array.VAO, newObj);
+ _mesa_set_draw_vao(ctx, newObj);
/* Update the valid-to-render state if binding on unbinding default VAO
* if drawing with the default VAO is invalid.
if (ctx->Array.LastLookedUpVAO == obj)
_mesa_reference_vao(ctx, &ctx->Array.LastLookedUpVAO, NULL);
- if (ctx->Array._DrawVAO == obj) {
- _mesa_set_draw_vao(ctx, ctx->Array._EmptyVAO);
- _mesa_update_vao_state(ctx, 0);
- }
-
/* Unreference the array object.
* If refcount hits zero, the object will be deleted.
*/
copy_array_attrib(ctx, dest, src, true, 0);
}
- /* Invalidate array state. It will be updated during the next draw. */
- _mesa_set_draw_vao(ctx, ctx->Array._EmptyVAO);
- _mesa_update_vao_state(ctx, 0);
-
if (is_vao_name_zero || !src->VAO->IndexBufferObj ||
_mesa_IsBuffer(src->VAO->IndexBufferObj->Name)) {
_mesa_BindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB,
_mesa_reference_vao(ctx, &ctx->Array.VAO, NULL);
_mesa_reference_vao(ctx, &ctx->Array.DefaultVAO, NULL);
- _mesa_reference_vao(ctx, &ctx->Array._EmptyVAO, NULL);
_mesa_reference_vao(ctx, &ctx->Array._DrawVAO, NULL);
_mesa_free_attrib_data(ctx);
}
/**
+ * Other than setting the new VAO, this returns a VAO reference to
+ * the previously-bound VAO through the parameter. The caller must call
+ * _mesa_restore_draw_vao to ensure reference counting is done properly.
+ */
+void
+_mesa_save_and_set_draw_vao(struct gl_context *ctx,
+ struct gl_vertex_array_object *vao,
+ struct gl_vertex_array_object **old_vao)
+{
+ *old_vao = ctx->Array._DrawVAO;
+ ctx->Array._DrawVAO = NULL;
+ _mesa_set_draw_vao(ctx, vao);
+}
+
+void
+_mesa_restore_draw_vao(struct gl_context *ctx,
+ struct gl_vertex_array_object *saved)
+{
+ _mesa_reference_vao(ctx, &ctx->Array._DrawVAO, NULL);
+ ctx->Array._DrawVAO = saved;
+ ctx->Array.NewVAO = true;
+}
+
+/**
* Update derived VAO state. This determines whether to update gallium vertex
* buffers and vertex elements, and it sets which vertex attribs are enabled
* according to the filter.
GET_CURRENT_CONTEXT(ctx);
FLUSH_FOR_DRAW(ctx);
- _mesa_set_draw_vao(ctx, ctx->Array.VAO);
_mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
if (ctx->NewState)
GET_CURRENT_CONTEXT(ctx);
FLUSH_FOR_DRAW(ctx);
- _mesa_set_draw_vao(ctx, ctx->Array.VAO);
_mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
if (ctx->NewState)
GET_CURRENT_CONTEXT(ctx);
FLUSH_FOR_DRAW(ctx);
- _mesa_set_draw_vao(ctx, ctx->Array.VAO);
_mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
if (ctx->NewState)
GET_CURRENT_CONTEXT(ctx);
FLUSH_FOR_DRAW(ctx);
- _mesa_set_draw_vao(ctx, ctx->Array.VAO);
_mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
if (ctx->NewState)
GET_CURRENT_CONTEXT(ctx);
FLUSH_FOR_DRAW(ctx);
- _mesa_set_draw_vao(ctx, ctx->Array.VAO);
_mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
if (ctx->NewState)
GET_CURRENT_CONTEXT(ctx);
FLUSH_FOR_DRAW(ctx);
- _mesa_set_draw_vao(ctx, ctx->Array.VAO);
_mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
if (ctx->NewState)
GET_CURRENT_CONTEXT(ctx);
FLUSH_FOR_DRAW(ctx);
- _mesa_set_draw_vao(ctx, ctx->Array.VAO);
_mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
if (ctx->NewState)
GET_CURRENT_CONTEXT(ctx);
FLUSH_FOR_DRAW(ctx);
- _mesa_set_draw_vao(ctx, ctx->Array.VAO);
_mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
if (ctx->NewState)
GET_CURRENT_CONTEXT(ctx);
FLUSH_FOR_DRAW(ctx);
- _mesa_set_draw_vao(ctx, ctx->Array.VAO);
_mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
if (ctx->NewState)
GET_CURRENT_CONTEXT(ctx);
FLUSH_FOR_DRAW(ctx);
- _mesa_set_draw_vao(ctx, ctx->Array.VAO);
_mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
if (ctx->NewState)
GET_CURRENT_CONTEXT(ctx);
FLUSH_FOR_DRAW(ctx);
- _mesa_set_draw_vao(ctx, ctx->Array.VAO);
_mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
if (ctx->NewState)
GET_CURRENT_CONTEXT(ctx);
FLUSH_FOR_DRAW(ctx);
- _mesa_set_draw_vao(ctx, ctx->Array.VAO);
_mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
if (ctx->NewState)
GET_CURRENT_CONTEXT(ctx);
FLUSH_FOR_DRAW(ctx);
- _mesa_set_draw_vao(ctx, ctx->Array.VAO);
_mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
if (ctx->NewState)
{
FLUSH_FOR_DRAW(ctx);
- _mesa_set_draw_vao(ctx, ctx->Array.VAO);
_mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
if (ctx->NewState)
FLUSH_FOR_DRAW(ctx);
- _mesa_set_draw_vao(ctx, ctx->Array.VAO);
_mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
if (ctx->NewState)
FLUSH_FOR_DRAW(ctx);
- _mesa_set_draw_vao(ctx, ctx->Array.VAO);
_mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
if (ctx->NewState)
FLUSH_FOR_DRAW(ctx);
- _mesa_set_draw_vao(ctx, ctx->Array.VAO);
_mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
if (ctx->NewState)
FLUSH_FOR_DRAW(ctx);
- _mesa_set_draw_vao(ctx, ctx->Array.VAO);
_mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
if (ctx->NewState)
if (stride == 0)
stride = 4 * sizeof(GLuint); /* sizeof(DrawArraysIndirectCommand) */
- _mesa_set_draw_vao(ctx, ctx->Array.VAO);
_mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
if (ctx->NewState)
if (stride == 0)
stride = 5 * sizeof(GLuint); /* sizeof(DrawElementsIndirectCommand) */
- _mesa_set_draw_vao(ctx, ctx->Array.VAO);
_mesa_update_vao_state(ctx, ctx->VertexProgram._VPModeInputFilter);
if (ctx->NewState)
_mesa_set_draw_vao(struct gl_context *ctx, struct gl_vertex_array_object *vao);
void
+_mesa_save_and_set_draw_vao(struct gl_context *ctx,
+ struct gl_vertex_array_object *vao,
+ struct gl_vertex_array_object **old_vao);
+
+void
+_mesa_restore_draw_vao(struct gl_context *ctx,
+ struct gl_vertex_array_object *saved);
+
+void
_mesa_update_vao_state(struct gl_context *ctx, GLbitfield filter);
void
*/
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.
- */
- struct gl_vertex_array_object *_EmptyVAO;
-
/** Legal array datatypes and the API for which they have been computed */
GLbitfield LegalTypesMask;
gl_api LegalTypesMaskAPI;
ctx->Array.DefaultVAO = _mesa_new_vao(ctx, 0);
_mesa_reference_vao(ctx, &ctx->Array.VAO, ctx->Array.DefaultVAO);
- ctx->Array._EmptyVAO = _mesa_new_vao(ctx, ~0u);
- _mesa_reference_vao(ctx, &ctx->Array._DrawVAO, ctx->Array._EmptyVAO);
+ _mesa_set_draw_vao(ctx, ctx->Array.VAO);
ctx->Array.ActiveTexture = 0; /* GL_ARB_multitexture */
ctx->Array.Objects = _mesa_NewHashTable();
if (!rs->VAO->IsDynamic)
rs->VAO->NewVertexElements = true;
- _mesa_set_draw_vao(ctx, rs->VAO);
+ /* Save the Draw VAO before we override it. */
+ struct gl_vertex_array_object *old_vao;
+
+ _mesa_save_and_set_draw_vao(ctx, rs->VAO, &old_vao);
_mesa_update_vao_state(ctx, VERT_BIT_POS);
st_feedback_draw_vbo(ctx, &rs->info, 0, &rs->draw, 1);
+ _mesa_restore_draw_vao(ctx, old_vao);
+
/* restore draw's rasterization stage depending on rendermode */
if (ctx->RenderMode == GL_FEEDBACK) {
draw_set_rasterize_stage(draw, st->feedback_stage);
/* TODO: populate these as the vertex is defined:
*/
static void
-vbo_exec_bind_arrays(struct gl_context *ctx)
+vbo_exec_bind_arrays(struct gl_context *ctx,
+ struct gl_vertex_array_object **old_vao)
{
struct vbo_context *vbo = vbo_context(ctx);
struct gl_vertex_array_object *vao = vbo->VAO;
assert(!exec->vtx.bufferobj ||
(vao_enabled & ~vao->VertexAttribBufferMask) == 0);
- _mesa_set_draw_vao(ctx, vao);
+ _mesa_save_and_set_draw_vao(ctx, vao, old_vao);
_mesa_update_vao_state(ctx, vao_filter);
}
exec->vtx.copied.nr = vbo_exec_copy_vertices(exec);
if (exec->vtx.copied.nr != exec->vtx.vert_count) {
+ struct gl_vertex_array_object *old_vao;
+
/* Prepare and set the exec draws internal VAO for drawing. */
- vbo_exec_bind_arrays(ctx);
+ vbo_exec_bind_arrays(ctx, &old_vao);
if (ctx->NewState)
_mesa_update_state(ctx);
/* Get new storage -- unless asked not to. */
if (!persistent_mapping)
vbo_exec_vtx_map(exec);
+
+ _mesa_restore_draw_vao(ctx, old_vao);
}
}
}
-
-/**
- * Set the appropriate VAO to draw.
- */
-static void
-bind_vertex_list(struct gl_context *ctx,
- const struct vbo_save_vertex_list *node)
-{
- const gl_vertex_processing_mode mode = ctx->VertexProgram._VPMode;
-
- _mesa_set_draw_vao(ctx, node->cold->VAO[mode]);
- _mesa_update_vao_state(ctx, _vbo_get_vao_filter(mode));
-}
-
-
static void
loopback_vertex_list(struct gl_context *ctx,
const struct vbo_save_vertex_list *list)
if (vbo_save_playback_vertex_list_gallium(ctx, node, copy_to_current) == DONE)
return;
- bind_vertex_list(ctx, node);
+ /* Save the Draw VAO before we override it. */
+ const gl_vertex_processing_mode mode = ctx->VertexProgram._VPMode;
+ struct gl_vertex_array_object *old_vao;
+
+ _mesa_save_and_set_draw_vao(ctx, node->cold->VAO[mode], &old_vao);
+ _mesa_update_vao_state(ctx, _vbo_get_vao_filter(mode));
/* Need that at least one time. */
if (ctx->NewState)
/* Return precomputed GL errors such as invalid shaders. */
if (!ctx->ValidPrimMask) {
+ _mesa_restore_draw_vao(ctx, old_vao);
_mesa_error(ctx, ctx->DrawGLError, "glCallList");
return;
}
}
info->index.gl_bo = gl_bo;
+ _mesa_restore_draw_vao(ctx, old_vao);
+
if (copy_to_current)
playback_copy_to_current(ctx, node);
}