From 8a3a4b6fae75905088ce4fcb42fc50cb09763a10 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Mathias=20Fr=C3=B6hlich?= Date: Wed, 7 Feb 2018 08:59:13 +0100 Subject: [PATCH] vbo: Make use of _DrawVAO from immediate mode draw MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Finally use an internal VAO to execute immediate mode draws. Avoid duplicate state validation for immediate mode draws. Remove client arrays previously used exclusively for immediate mode draws. Signed-off-by: Mathias Fröhlich Reviewed-by: Brian Paul --- src/mesa/vbo/vbo_context.c | 8 +++ src/mesa/vbo/vbo_exec.h | 8 --- src/mesa/vbo/vbo_exec_api.c | 47 +------------- src/mesa/vbo/vbo_exec_draw.c | 117 ++++++++++++++++++++--------------- src/mesa/vbo/vbo_private.h | 2 + 5 files changed, 78 insertions(+), 104 deletions(-) diff --git a/src/mesa/vbo/vbo_context.c b/src/mesa/vbo/vbo_context.c index 222bdcf1f27..3dc3222c0db 100644 --- a/src/mesa/vbo/vbo_context.c +++ b/src/mesa/vbo/vbo_context.c @@ -30,6 +30,8 @@ #include "math/m_eval.h" #include "main/vtxfmt.h" #include "main/api_arrayelt.h" +#include "main/arrayobj.h" +#include "main/varray.h" #include "vbo.h" #include "vbo_private.h" @@ -252,6 +254,11 @@ _vbo_CreateContext(struct gl_context *ctx) if (ctx->API == API_OPENGL_COMPAT) vbo_save_init(ctx); + vbo->VAO = _mesa_new_vao(ctx, ~((GLuint)0)); + /* The exec VAO assumes to have all arributes bound to binding 0 */ + for (unsigned i = 0; i < VERT_ATTRIB_MAX; ++i) + _mesa_vertex_attrib_binding(ctx, vbo->VAO, i, 0, false); + _math_init_eval(); return GL_TRUE; @@ -278,6 +285,7 @@ _vbo_DestroyContext(struct gl_context *ctx) vbo_exec_destroy(ctx); if (ctx->API == API_OPENGL_COMPAT) vbo_save_destroy(ctx); + _mesa_reference_vao(ctx, &vbo->VAO, NULL); free(vbo); ctx->vbo_context = NULL; } diff --git a/src/mesa/vbo/vbo_exec.h b/src/mesa/vbo/vbo_exec.h index b00045c7c86..07ab5cc837b 100644 --- a/src/mesa/vbo/vbo_exec.h +++ b/src/mesa/vbo/vbo_exec.h @@ -101,14 +101,6 @@ struct vbo_exec_context /** pointers into the current 'vertex' array, declared above */ fi_type *attrptr[VBO_ATTRIB_MAX]; - - struct gl_vertex_array arrays[VERT_ATTRIB_MAX]; - - /* According to program mode, the values above plus current - * values are squashed down to the 32 attributes passed to the - * vertex program below: - */ - const struct gl_vertex_array *inputs[VERT_ATTRIB_MAX]; } vtx; struct { diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c index 64e792bfa2c..317fc43d1c5 100644 --- a/src/mesa/vbo/vbo_exec_api.c +++ b/src/mesa/vbo/vbo_exec_api.c @@ -758,7 +758,8 @@ static void GLAPIENTRY vbo_exec_Begin(GLenum mode) { GET_CURRENT_CONTEXT(ctx); - struct vbo_exec_context *exec = &vbo_context(ctx)->exec; + struct vbo_context *vbo = vbo_context(ctx); + struct vbo_exec_context *exec = &vbo->exec; int i; if (_mesa_inside_begin_end(ctx)) { @@ -770,8 +771,6 @@ vbo_exec_Begin(GLenum mode) return; } - _mesa_set_drawing_arrays(ctx, exec->vtx.inputs); - if (ctx->NewState) { _mesa_update_state(ctx); @@ -1162,7 +1161,6 @@ void vbo_exec_vtx_init(struct vbo_exec_context *exec) { struct gl_context *ctx = exec->ctx; - struct vbo_context *vbo = vbo_context(ctx); GLuint i; /* Allocate a buffer object. Will just reuse this object @@ -1189,38 +1187,6 @@ vbo_exec_vtx_init(struct vbo_exec_context *exec) assert(i < ARRAY_SIZE(exec->vtx.active_sz)); exec->vtx.active_sz[i] = 0; } - for (i = 0 ; i < VERT_ATTRIB_MAX; i++) { - assert(i < ARRAY_SIZE(exec->vtx.inputs)); - assert(i < ARRAY_SIZE(exec->vtx.arrays)); - exec->vtx.inputs[i] = &exec->vtx.arrays[i]; - } - - { - struct gl_vertex_array *arrays = exec->vtx.arrays; - unsigned i; - - memcpy(arrays, &vbo->currval[VBO_ATTRIB_POS], - VERT_ATTRIB_FF_MAX * sizeof(arrays[0])); - for (i = 0; i < VERT_ATTRIB_FF_MAX; ++i) { - struct gl_vertex_array *array; - array = &arrays[VERT_ATTRIB_FF(i)]; - array->BufferObj = NULL; - _mesa_reference_buffer_object(ctx, &array->BufferObj, - vbo->currval[VBO_ATTRIB_POS+i].BufferObj); - } - - memcpy(arrays + VERT_ATTRIB_GENERIC(0), - &vbo->currval[VBO_ATTRIB_GENERIC0], - VERT_ATTRIB_GENERIC_MAX * sizeof(arrays[0])); - - for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; ++i) { - struct gl_vertex_array *array; - array = &arrays[VERT_ATTRIB_GENERIC(i)]; - array->BufferObj = NULL; - _mesa_reference_buffer_object(ctx, &array->BufferObj, - vbo->currval[VBO_ATTRIB_GENERIC0+i].BufferObj); - } - } exec->vtx.vertex_size = 0; @@ -1233,7 +1199,6 @@ vbo_exec_vtx_destroy(struct vbo_exec_context *exec) { /* using a real VBO for vertex data */ struct gl_context *ctx = exec->ctx; - unsigned i; /* True VBOs should already be unmapped */ @@ -1247,14 +1212,6 @@ vbo_exec_vtx_destroy(struct vbo_exec_context *exec) } } - /* Drop any outstanding reference to the vertex buffer - */ - for (i = 0; i < ARRAY_SIZE(exec->vtx.arrays); i++) { - _mesa_reference_buffer_object(ctx, - &exec->vtx.arrays[i].BufferObj, - NULL); - } - /* Free the vertex buffer. Unmap first if needed. */ if (_mesa_bufferobj_mapped(exec->vtx.bufferobj, MAP_INTERNAL)) { diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c index 4421496072d..d02b33c8ee2 100644 --- a/src/mesa/vbo/vbo_exec_draw.c +++ b/src/mesa/vbo/vbo_exec_draw.c @@ -33,6 +33,7 @@ #include "main/context.h" #include "main/enums.h" #include "main/state.h" +#include "main/varray.h" #include "main/vtxfmt.h" #include "vbo_noop.h" @@ -173,61 +174,73 @@ static void vbo_exec_bind_arrays(struct gl_context *ctx) { struct vbo_context *vbo = vbo_context(ctx); + struct gl_vertex_array_object *vao = vbo->VAO; struct vbo_exec_context *exec = &vbo->exec; - struct gl_vertex_array *arrays = exec->vtx.arrays; - GLuint attr; - GLbitfield varying_inputs = 0x0; - - const gl_vertex_processing_mode processing_mode - = ctx->VertexProgram._VPMode; - const GLubyte * const map = _vbo_attribute_alias_map[processing_mode]; - - /* Grab VERT_ATTRIB_{POS,GENERIC0} from VBO_ATTRIB_POS */ - const gl_attribute_map_mode mode = ATTRIBUTE_MAP_MODE_POSITION; - const GLubyte *const array_map = _mesa_vao_attribute_map[mode]; - for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) { - const GLuint src = map[array_map[attr]]; - const GLubyte size = exec->vtx.attrsz[src]; - - if (size == 0) { - exec->vtx.inputs[attr] = &vbo->currval[map[attr]]; - } else { - GLsizeiptr offset = (GLbyte *)exec->vtx.attrptr[src] - - (GLbyte *)exec->vtx.vertex; - - /* override the default array set above */ - assert(attr < ARRAY_SIZE(exec->vtx.inputs)); - assert(attr < ARRAY_SIZE(exec->vtx.arrays)); /* arrays[] */ - exec->vtx.inputs[attr] = &arrays[attr]; - - if (_mesa_is_bufferobj(exec->vtx.bufferobj)) { - /* a real buffer obj: Ptr is an offset, not a pointer */ - assert(exec->vtx.bufferobj->Mappings[MAP_INTERNAL].Pointer); - assert(offset >= 0); - arrays[attr].Ptr = (GLubyte *) - exec->vtx.bufferobj->Mappings[MAP_INTERNAL].Offset + offset; - } - else { - /* Ptr into ordinary app memory */ - arrays[attr].Ptr = (GLubyte *)exec->vtx.buffer_map + offset; - } - arrays[attr].Size = size; - arrays[attr].StrideB = exec->vtx.vertex_size * sizeof(GLfloat); - const GLenum16 type = exec->vtx.attrtype[src]; - arrays[attr].Type = type; - arrays[attr].Integer = vbo_attrtype_to_integer_flag(type); - arrays[attr].Format = GL_RGBA; - arrays[attr]._ElementSize = size * sizeof(GLfloat); - _mesa_reference_buffer_object(ctx, - &arrays[attr].BufferObj, - exec->vtx.bufferobj); - - varying_inputs |= VERT_BIT(attr); - } + + GLintptr buffer_offset; + if (_mesa_is_bufferobj(exec->vtx.bufferobj)) { + assert(exec->vtx.bufferobj->Mappings[MAP_INTERNAL].Pointer); + buffer_offset = exec->vtx.bufferobj->Mappings[MAP_INTERNAL].Offset; + } else { + /* Ptr into ordinary app memory */ + buffer_offset = (GLbyte *)exec->vtx.buffer_map - (GLbyte *)NULL; + } + + const gl_vertex_processing_mode mode = ctx->VertexProgram._VPMode; + + /* Compute the bitmasks of vao_enabled arrays */ + GLbitfield vao_enabled = _vbo_get_vao_enabled_from_vbo(mode, exec->vtx.enabled); + + /* At first disable arrays no longer needed */ + GLbitfield mask = vao->_Enabled & ~vao_enabled; + while (mask) { + const int vao_attr = u_bit_scan(&mask); + _mesa_disable_vertex_array_attrib(ctx, vao, vao_attr, false); } + assert((~vao_enabled & vao->_Enabled) == 0); - _mesa_set_varying_vp_inputs(ctx, varying_inputs); + /* Bind the buffer object */ + _mesa_bind_vertex_buffer(ctx, vao, 0, exec->vtx.bufferobj, buffer_offset, + exec->vtx.vertex_size*sizeof(GLfloat), false); + + /* Retrieve the mapping from VBO_ATTRIB to VERT_ATTRIB space + * Note that the position/generic0 aliasing is done in the VAO. + */ + const GLubyte *const vao_to_vbo_map = _vbo_attribute_alias_map[mode]; + /* Now set the enabled arrays */ + mask = vao_enabled; + while (mask) { + const int vao_attr = u_bit_scan(&mask); + const GLubyte vbo_attr = vao_to_vbo_map[vao_attr]; + + const GLubyte size = exec->vtx.attrsz[vbo_attr]; + const GLenum16 type = exec->vtx.attrtype[vbo_attr]; + const GLuint offset = (GLuint)((GLbyte *)exec->vtx.attrptr[vbo_attr] - + (GLbyte *)exec->vtx.vertex); + + /* Set and enable */ + _vbo_set_attrib_format(ctx, vao, vao_attr, buffer_offset, + size, type, offset); + if ((vao->_Enabled & VERT_BIT(vao_attr)) == 0) + _mesa_enable_vertex_array_attrib(ctx, vao, vao_attr, false); + + /* The vao is initially created with all bindings set to 0. */ + assert(vao->VertexAttrib[vao_attr].BufferBindingIndex == 0); + } + assert(vao_enabled == vao->_Enabled); + assert(!_mesa_is_bufferobj(exec->vtx.bufferobj) || + (vao_enabled & ~vao->VertexAttribBufferMask) == 0); + + _mesa_update_vao_derived_arrays(ctx, vao); + vao->NewArrays = 0; + + _mesa_set_draw_vao(ctx, vao, _vbo_get_vao_filter(mode)); + /* The exec VAO is not immutable, so we need to set manually */ ctx->NewDriverState |= ctx->DriverFlags.NewArray; + + _mesa_set_drawing_arrays(ctx, vbo->draw_arrays.inputs); + /* Finally update the inputs array */ + _vbo_update_inputs(ctx, &vbo->draw_arrays); } @@ -379,6 +392,8 @@ vbo_exec_vtx_flush(struct vbo_exec_context *exec, GLboolean keepUnmapped) vbo_exec_vtx_unmap(exec); + assert(ctx->NewState == 0); + if (0) printf("%s %d %d\n", __func__, exec->vtx.prim_count, exec->vtx.vert_count); diff --git a/src/mesa/vbo/vbo_private.h b/src/mesa/vbo/vbo_private.h index 2640f3e21f9..1f3d31f577a 100644 --- a/src/mesa/vbo/vbo_private.h +++ b/src/mesa/vbo/vbo_private.h @@ -48,6 +48,8 @@ struct vbo_context { /* The array of inputs used for _DrawVAO draws. */ struct vbo_inputs draw_arrays; + struct gl_vertex_array_object *VAO; + struct vbo_exec_context exec; struct vbo_save_context save; -- 2.30.2