aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mesa/vbo/vbo_context.c8
-rw-r--r--src/mesa/vbo/vbo_exec.h8
-rw-r--r--src/mesa/vbo/vbo_exec_api.c47
-rw-r--r--src/mesa/vbo/vbo_exec_draw.c117
-rw-r--r--src/mesa/vbo/vbo_private.h2
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;