assert(sz == 1 || sz == 2); \
\
/* check if attribute size or type is changing */ \
- if (unlikely(exec->vtx.attr[A].active_size != N * sz) || \
- unlikely(exec->vtx.attr[A].type != T)) { \
+ if (unlikely(exec->vtx.attr[A].active_size != N * sz || \
+ exec->vtx.attr[A].type != T)) { \
vbo_exec_fixup_vertex(ctx, A, N * sz, T); \
} \
\
/* dst now points at the beginning of the next vertex */ \
exec->vtx.buffer_ptr = (fi_type*)dst; \
\
- /* Set FLUSH_STORED_VERTICES to indicate that there's now */ \
- /* something to draw (not just updating a color or texcoord).*/ \
/* Don't set FLUSH_UPDATE_CURRENT because */ \
/* Current.Attrib[VBO_ATTRIB_POS] is never used. */ \
- ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; \
\
- if (++exec->vtx.vert_count >= exec->vtx.max_vert) \
+ if (unlikely(++exec->vtx.vert_count >= exec->vtx.max_vert)) \
vbo_exec_vtx_wrap(exec); \
} else { \
/* we now have accumulated per-vertex attributes */ \
exec->vtx.prim[i].begin = 1;
exec->vtx.prim[i].end = 0;
exec->vtx.prim[i].indexed = 0;
- exec->vtx.prim[i].pad = 0;
exec->vtx.prim[i].start = exec->vtx.vert_count;
exec->vtx.prim[i].count = 0;
exec->vtx.prim[i].num_instances = 1;
exec->vtx.prim[i].base_instance = 0;
- exec->vtx.prim[i].is_indirect = 0;
ctx->Driver.CurrentExecPrimitive = mode;
if (exec->vtx.prim_count > 0) {
/* close off current primitive */
struct _mesa_prim *last_prim = &exec->vtx.prim[exec->vtx.prim_count - 1];
+ unsigned count = exec->vtx.vert_count - last_prim->start;
last_prim->end = 1;
- last_prim->count = exec->vtx.vert_count - last_prim->start;
+ last_prim->count = count;
+
+ if (count)
+ ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
/* Special handling for GL_LINE_LOOP */
if (last_prim->mode == GL_LINE_LOOP && last_prim->begin == 0) {
}
-/**
- * Tell the VBO module to use a real OpenGL vertex buffer object to
- * store accumulated immediate-mode vertex data.
- * This replaces the malloced buffer which was created in
- * vb_exec_vtx_init() below.
- */
-void
-vbo_use_buffer_objects(struct gl_context *ctx)
+static void
+vbo_reset_all_attr(struct vbo_exec_context *exec)
{
- struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
- /* Any buffer name but 0 can be used here since this bufferobj won't
- * go into the bufferobj hashtable.
- */
- GLuint bufName = IMM_BUFFER_NAME;
-
- /* Make sure this func is only used once */
- assert(exec->vtx.bufferobj == ctx->Shared->NullBufferObj);
-
- _mesa_align_free(exec->vtx.buffer_map);
- exec->vtx.buffer_map = NULL;
- exec->vtx.buffer_ptr = NULL;
+ while (exec->vtx.enabled) {
+ const int i = u_bit_scan64(&exec->vtx.enabled);
- /* Allocate a real buffer object now */
- _mesa_reference_buffer_object(ctx, &exec->vtx.bufferobj, NULL);
- exec->vtx.bufferobj = ctx->Driver.NewBufferObject(ctx, bufName);
+ /* Reset the vertex attribute by setting its size to zero. */
+ exec->vtx.attr[i].size = 0;
+ exec->vtx.attr[i].type = GL_FLOAT;
+ exec->vtx.attr[i].active_size = 0;
+ exec->vtx.attrptr[i] = NULL;
+ }
- /* Map the buffer. */
- vbo_exec_vtx_map(exec);
- assert(exec->vtx.buffer_ptr);
+ exec->vtx.vertex_size = 0;
}
void
-vbo_exec_vtx_init(struct vbo_exec_context *exec)
+vbo_exec_vtx_init(struct vbo_exec_context *exec, bool use_buffer_objects)
{
struct gl_context *ctx = exec->ctx;
- GLuint i;
- /* Allocate a buffer object. Will just reuse this object
- * continuously, unless vbo_use_buffer_objects() is called to enable
- * use of real VBOs.
- */
- _mesa_reference_buffer_object(ctx,
- &exec->vtx.bufferobj,
- ctx->Shared->NullBufferObj);
+ if (use_buffer_objects) {
+ /* Use buffer objects for immediate mode. */
+ struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
- assert(!exec->vtx.buffer_map);
- exec->vtx.buffer_map = _mesa_align_malloc(VBO_VERT_BUFFER_SIZE, 64);
- exec->vtx.buffer_ptr = exec->vtx.buffer_map;
+ exec->vtx.bufferobj = ctx->Driver.NewBufferObject(ctx, IMM_BUFFER_NAME);
- vbo_exec_vtxfmt_init(exec);
- _mesa_noop_vtxfmt_init(ctx, &exec->vtxfmt_noop);
+ /* Map the buffer. */
+ vbo_exec_vtx_map(exec);
+ assert(exec->vtx.buffer_ptr);
+ } else {
+ /* Use allocated memory for immediate mode. */
+ _mesa_reference_buffer_object(ctx,
+ &exec->vtx.bufferobj,
+ ctx->Shared->NullBufferObj);
- exec->vtx.enabled = 0;
- for (i = 0 ; i < ARRAY_SIZE(exec->vtx.attr); i++) {
- exec->vtx.attr[i].size = 0;
- exec->vtx.attr[i].type = GL_FLOAT;
- exec->vtx.attr[i].active_size = 0;
+ exec->vtx.buffer_map = _mesa_align_malloc(VBO_VERT_BUFFER_SIZE, 64);
+ exec->vtx.buffer_ptr = exec->vtx.buffer_map;
}
- exec->vtx.vertex_size = 0;
+ vbo_exec_vtxfmt_init(exec);
+ _mesa_noop_vtxfmt_init(ctx, &exec->vtxfmt_noop);
+
+ exec->vtx.enabled = u_bit_consecutive64(0, VBO_ATTRIB_MAX); /* reset all */
+ vbo_reset_all_attr(exec);
}
}
-/**
- * Reset the vertex attribute by setting its size to zero.
- */
-static void
-vbo_reset_attr(struct vbo_exec_context *exec, GLuint attr)
-{
- exec->vtx.attr[attr].size = 0;
- exec->vtx.attr[attr].type = GL_FLOAT;
- exec->vtx.attr[attr].active_size = 0;
-}
-
-
-static void
-vbo_reset_all_attr(struct vbo_exec_context *exec)
-{
- while (exec->vtx.enabled) {
- const int i = u_bit_scan64(&exec->vtx.enabled);
- vbo_reset_attr(exec, i);
- }
-
- exec->vtx.vertex_size = 0;
-}
-
-
void GLAPIENTRY
_es_Color4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a)
{