From: Mathias Fröhlich Date: Wed, 7 Feb 2018 07:59:13 +0000 (+0100) Subject: vbo: Make use of _DrawVAO from immediate mode draw X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=8a3a4b6fae75905088ce4fcb42fc50cb09763a10;p=mesa.git vbo: Make use of _DrawVAO from immediate mode draw 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 --- 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;