summaryrefslogtreecommitdiffstats
path: root/src/mesa/tnl/t_draw.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/tnl/t_draw.c')
-rw-r--r--src/mesa/tnl/t_draw.c95
1 files changed, 89 insertions, 6 deletions
diff --git a/src/mesa/tnl/t_draw.c b/src/mesa/tnl/t_draw.c
index 9814cdcec18..1fe2d405cb6 100644
--- a/src/mesa/tnl/t_draw.c
+++ b/src/mesa/tnl/t_draw.c
@@ -28,6 +28,7 @@
#include <stdio.h>
#include "main/glheader.h"
+#include "main/arrayobj.h"
#include "main/bufferobj.h"
#include "main/condrender.h"
#include "main/context.h"
@@ -273,7 +274,7 @@ static GLboolean *_tnl_import_edgeflag( struct gl_context *ctx,
static void bind_inputs( struct gl_context *ctx,
- const struct gl_vertex_array *inputs,
+ const struct tnl_vertex_array *inputs,
GLint count,
struct gl_buffer_object **bo,
GLuint *nr_bo )
@@ -285,7 +286,7 @@ static void bind_inputs( struct gl_context *ctx,
/* Map all the VBOs
*/
for (i = 0; i < VERT_ATTRIB_MAX; i++) {
- const struct gl_vertex_array *array = &inputs[i];
+ const struct tnl_vertex_array *array = &inputs[i];
const struct gl_vertex_buffer_binding *binding = array->BufferBinding;
const struct gl_array_attributes *attrib = array->VertexAttrib;
const void *ptr;
@@ -426,7 +427,7 @@ static void unmap_vbos( struct gl_context *ctx,
/* This is the main workhorse doing all the rendering work.
*/
void _tnl_draw_prims(struct gl_context *ctx,
- const struct gl_vertex_array *arrays,
+ const struct tnl_vertex_array *arrays,
const struct _mesa_prim *prim,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,
@@ -537,11 +538,93 @@ void _tnl_draw_prims(struct gl_context *ctx,
}
-const struct gl_vertex_array*
+void
+_tnl_init_inputs(struct tnl_inputs *inputs)
+{
+ inputs->current = 0;
+ inputs->vertex_processing_mode = VP_MODE_FF;
+}
+
+
+/**
+ * Update the tnl_inputs's arrays to point to the vao->_VertexArray arrays
+ * according to the 'enable' bitmask.
+ * \param enable bitfield of VERT_BIT_x flags.
+ */
+static inline void
+update_vao_inputs(struct gl_context *ctx,
+ struct tnl_inputs *inputs, GLbitfield enable)
+{
+ const struct gl_vertex_array_object *vao = ctx->Array._DrawVAO;
+
+ /* Make sure we process only arrays enabled in the VAO */
+ assert((enable & ~_mesa_get_vao_vp_inputs(vao)) == 0);
+
+ /* Fill in the client arrays from the VAO */
+ const struct gl_vertex_buffer_binding *bindings = &vao->BufferBinding[0];
+ while (enable) {
+ const int attr = u_bit_scan(&enable);
+ struct tnl_vertex_array *input = &inputs->inputs[attr];
+ const struct gl_array_attributes *attrib;
+ attrib = _mesa_draw_array_attrib(vao, attr);
+ input->VertexAttrib = attrib;
+ input->BufferBinding = &bindings[attrib->BufferBindingIndex];
+ }
+}
+
+
+/**
+ * Update the tnl_inputs's arrays to point to the vbo->currval arrays
+ * according to the 'current' bitmask.
+ * \param current bitfield of VERT_BIT_x flags.
+ */
+static inline void
+update_current_inputs(struct gl_context *ctx,
+ struct tnl_inputs *inputs, GLbitfield current)
+{
+ gl_vertex_processing_mode mode = ctx->VertexProgram._VPMode;
+
+ /* All previously non current array pointers need update. */
+ GLbitfield mask = current & ~inputs->current;
+ /* On mode change, the slots aliasing with materials need update too */
+ if (mode != inputs->vertex_processing_mode)
+ mask |= current & VERT_BIT_MAT_ALL;
+
+ while (mask) {
+ const int attr = u_bit_scan(&mask);
+ struct tnl_vertex_array *input = &inputs->inputs[attr];
+ input->VertexAttrib = _vbo_current_attrib(ctx, attr);
+ input->BufferBinding = _vbo_current_binding(ctx);
+ }
+
+ inputs->current = current;
+ inputs->vertex_processing_mode = mode;
+}
+
+
+/**
+ * Update the tnl_inputs's arrays to point to the vao->_VertexArray and
+ * vbo->currval arrays according to Array._DrawVAO and
+ * Array._DrawVAOEnableAttribs.
+ */
+void
+_tnl_update_inputs(struct gl_context *ctx, struct tnl_inputs *inputs)
+{
+ const GLbitfield enable = ctx->Array._DrawVAOEnabledAttribs;
+
+ /* Update array input pointers */
+ update_vao_inputs(ctx, inputs, enable);
+
+ /* The rest must be current inputs. */
+ update_current_inputs(ctx, inputs, ~enable & VERT_BIT_ALL);
+}
+
+
+const struct tnl_vertex_array*
_tnl_bind_inputs( struct gl_context *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
- _vbo_update_inputs(ctx, &tnl->draw_arrays);
+ _tnl_update_inputs(ctx, &tnl->draw_arrays);
return tnl->draw_arrays.inputs;
}
@@ -560,7 +643,7 @@ _tnl_draw(struct gl_context *ctx,
{
/* Update TNLcontext::draw_arrays and return that pointer.
*/
- const struct gl_vertex_array* arrays = _tnl_bind_inputs(ctx);
+ const struct tnl_vertex_array* arrays = _tnl_bind_inputs(ctx);
_tnl_draw_prims(ctx, arrays, prim, nr_prims, ib,
index_bounds_valid, min_index, max_index,