const fi_type * src_buffer)
{
struct vbo_save_context *save = &vbo_context(ctx)->save;
- const struct _mesa_prim *prim = &node->prim[node->prim_count - 1];
+ const struct _mesa_prim *prim = &node->prims[node->prim_count - 1];
GLuint nr = prim->count;
GLuint sz = save->vertex_size;
const fi_type *src = src_buffer + prim->start * sz;
_mesa_install_save_vtxfmt(ctx, &save->vtxfmt_noop);
}
- vertex_store->buffer = NULL;
+ vertex_store->buffer_map = NULL;
vertex_store->used = 0;
vertex_store->refcount = 1;
free_vertex_store(struct gl_context *ctx,
struct vbo_save_vertex_store *vertex_store)
{
- assert(!vertex_store->buffer);
+ assert(!vertex_store->buffer_map);
if (vertex_store->bufferobj) {
_mesa_reference_buffer_object(ctx, &vertex_store->bufferobj, NULL);
GL_MAP_FLUSH_EXPLICIT_BIT);
assert(vertex_store->bufferobj);
- assert(!vertex_store->buffer); /* the buffer should not be mapped */
+ assert(!vertex_store->buffer_map); /* the buffer should not be mapped */
if (vertex_store->bufferobj->Size > 0) {
/* Map the remaining free space in the VBO */
MAP_INTERNAL);
if (range) {
/* compute address of start of whole buffer (needed elsewhere) */
- vertex_store->buffer = range - vertex_store->used;
- assert(vertex_store->buffer);
+ vertex_store->buffer_map = range - vertex_store->used;
+ assert(vertex_store->buffer_map);
return range;
}
else {
- vertex_store->buffer = NULL;
+ vertex_store->buffer_map = NULL;
return NULL;
}
}
ctx->Driver.UnmapBuffer(ctx, vertex_store->bufferobj, MAP_INTERNAL);
}
- vertex_store->buffer = NULL;
+ vertex_store->buffer_map = NULL;
}
static struct vbo_save_primitive_store *
-alloc_prim_store(struct gl_context *ctx)
+alloc_prim_store(void)
{
struct vbo_save_primitive_store *store =
CALLOC_STRUCT(vbo_save_primitive_store);
- (void) ctx;
store->used = 0;
store->refcount = 1;
return store;
{
struct vbo_save_context *save = &vbo_context(ctx)->save;
- save->prim = save->prim_store->buffer + save->prim_store->used;
- save->buffer = save->vertex_store->buffer + save->vertex_store->used;
+ save->prims = save->prim_store->prims + save->prim_store->used;
+ save->buffer_map = save->vertex_store->buffer_map + save->vertex_store->used;
- assert(save->buffer == save->buffer_ptr);
+ assert(save->buffer_map == save->buffer_ptr);
if (save->vertex_size)
save->max_vert = (VBO_SAVE_BUFFER_SIZE - save->vertex_store->used) /
convert_line_loop_to_strip(struct vbo_save_context *save,
struct vbo_save_vertex_list *node)
{
- struct _mesa_prim *prim = &node->prim[node->prim_count - 1];
+ struct _mesa_prim *prim = &node->prims[node->prim_count - 1];
assert(prim->mode == GL_LINE_LOOP);
*/
const GLuint sz = save->vertex_size;
/* 0th vertex: */
- const fi_type *src = save->buffer + prim->start * sz;
+ const fi_type *src = save->buffer_map + prim->start * sz;
/* end of buffer: */
- fi_type *dst = save->buffer + (prim->start + prim->count) * sz;
+ fi_type *dst = save->buffer_map + (prim->start + prim->count) * sz;
memcpy(dst, src, sz * sizeof(float));
prim->count++;
- node->count++;
+ node->vertex_count++;
save->vert_count++;
save->buffer_ptr += sz;
save->vertex_store->used += sz;
memcpy(node->attrtype, save->attrtype, sizeof(node->attrtype));
node->vertex_size = save->vertex_size;
node->buffer_offset =
- (save->buffer - save->vertex_store->buffer) * sizeof(GLfloat);
- node->count = save->vert_count;
+ (save->buffer_map - save->vertex_store->buffer_map) * sizeof(GLfloat);
+ node->vertex_count = save->vert_count;
node->wrap_count = save->copied.nr;
node->dangling_attr_ref = save->dangling_attr_ref;
- node->prim = save->prim;
+ node->prims = save->prims;
node->prim_count = save->prim_count;
node->vertex_store = save->vertex_store;
node->prim_store = save->prim_store;
node->vertex_store->refcount++;
node->prim_store->refcount++;
- if (node->prim[0].no_current_update) {
+ if (node->prims[0].no_current_update) {
node->current_size = 0;
node->current_data = NULL;
}
*/
node->current_data = malloc(node->current_size * sizeof(GLfloat));
if (node->current_data) {
- const char *buffer = (const char *) save->vertex_store->buffer;
+ const char *buffer = (const char *) save->vertex_store->buffer_map;
unsigned attr_offset = node->attrsz[0] * sizeof(GLfloat);
unsigned vertex_offset = 0;
- if (node->count)
+ if (node->vertex_count)
vertex_offset =
- (node->count - 1) * node->vertex_size * sizeof(GLfloat);
+ (node->vertex_count - 1) * node->vertex_size * sizeof(GLfloat);
memcpy(node->current_data,
buffer + node->buffer_offset + vertex_offset + attr_offset,
}
}
- assert(node->attrsz[VBO_ATTRIB_POS] != 0 || node->count == 0);
+ assert(node->attrsz[VBO_ATTRIB_POS] != 0 || node->vertex_count == 0);
if (save->dangling_attr_ref)
ctx->ListState.CurrentList->Flags |= DLIST_DANGLING_REFS;
- save->vertex_store->used += save->vertex_size * node->count;
+ save->vertex_store->used += save->vertex_size * node->vertex_count;
save->prim_store->used += node->prim_count;
/* Copy duplicated vertices
*/
- save->copied.nr = _save_copy_vertices(ctx, node, save->buffer);
+ save->copied.nr = _save_copy_vertices(ctx, node, save->buffer_map);
- if (node->prim[node->prim_count - 1].mode == GL_LINE_LOOP) {
+ if (node->prims[node->prim_count - 1].mode == GL_LINE_LOOP) {
convert_line_loop_to_strip(save, node);
}
- merge_prims(node->prim, &node->prim_count);
+ merge_prims(node->prims, &node->prim_count);
/* Deal with GL_COMPILE_AND_EXECUTE:
*/
vbo_loopback_vertex_list(ctx,
(const GLfloat *) ((const char *) save->
- vertex_store->buffer +
+ vertex_store->buffer_map +
node->buffer_offset),
- node->attrsz, node->prim, node->prim_count,
+ node->attrsz, node->prims, node->prim_count,
node->wrap_count, node->vertex_size);
_glapi_set_dispatch(dispatch);
}
else {
/* update buffer_ptr for next vertex */
- save->buffer_ptr = save->vertex_store->buffer + save->vertex_store->used;
+ save->buffer_ptr = save->vertex_store->buffer_map
+ + save->vertex_store->used;
}
if (save->prim_store->used > VBO_SAVE_PRIM_SIZE - 6) {
save->prim_store->refcount--;
assert(save->prim_store->refcount != 0);
- save->prim_store = alloc_prim_store(ctx);
+ save->prim_store = alloc_prim_store();
}
/* Reset our structures for the next run of vertices:
/* Close off in-progress primitive.
*/
- save->prim[i].count = (save->vert_count - save->prim[i].start);
- mode = save->prim[i].mode;
- weak = save->prim[i].weak;
- no_current_update = save->prim[i].no_current_update;
+ save->prims[i].count = (save->vert_count - save->prims[i].start);
+ mode = save->prims[i].mode;
+ weak = save->prims[i].weak;
+ no_current_update = save->prims[i].no_current_update;
/* store the copied vertices, and allocate a new list.
*/
/* Restart interrupted primitive
*/
- save->prim[0].mode = mode;
- save->prim[0].weak = weak;
- save->prim[0].no_current_update = no_current_update;
- save->prim[0].begin = 0;
- save->prim[0].end = 0;
- save->prim[0].pad = 0;
- save->prim[0].start = 0;
- save->prim[0].count = 0;
- save->prim[0].num_instances = 1;
- save->prim[0].base_instance = 0;
- save->prim[0].is_indirect = 0;
+ save->prims[0].mode = mode;
+ save->prims[0].weak = weak;
+ save->prims[0].no_current_update = no_current_update;
+ save->prims[0].begin = 0;
+ save->prims[0].end = 0;
+ save->prims[0].pad = 0;
+ save->prims[0].start = 0;
+ save->prims[0].count = 0;
+ save->prims[0].num_instances = 1;
+ save->prims[0].base_instance = 0;
+ save->prims[0].is_indirect = 0;
save->prim_count = 1;
}
*/
if (save->copied.nr) {
const fi_type *data = save->copied.buffer;
- fi_type *dest = save->buffer;
+ fi_type *dest = save->buffer_map;
/* Need to note this and fix up at runtime (or loopback):
*/
if (save->prim_count > 0) {
/* Close off in-progress primitive. */
GLint i = save->prim_count - 1;
- save->prim[i].count = save->vert_count - save->prim[i].start;
+ save->prims[i].count = save->vert_count - save->prims[i].start;
}
/* Need to replay this display list with loopback,
* Called when a glBegin is getting compiled into a display list.
* Updating of ctx->Driver.CurrentSavePrimitive is already taken care of.
*/
-GLboolean
+void
vbo_save_NotifyBegin(struct gl_context *ctx, GLenum mode)
{
struct vbo_save_context *save = &vbo_context(ctx)->save;
const GLuint i = save->prim_count++;
assert(i < save->prim_max);
- save->prim[i].mode = mode & VBO_SAVE_PRIM_MODE_MASK;
- save->prim[i].begin = 1;
- save->prim[i].end = 0;
- save->prim[i].weak = (mode & VBO_SAVE_PRIM_WEAK) ? 1 : 0;
- save->prim[i].no_current_update =
+ save->prims[i].mode = mode & VBO_SAVE_PRIM_MODE_MASK;
+ save->prims[i].begin = 1;
+ save->prims[i].end = 0;
+ save->prims[i].weak = (mode & VBO_SAVE_PRIM_WEAK) ? 1 : 0;
+ save->prims[i].no_current_update =
(mode & VBO_SAVE_PRIM_NO_CURRENT_UPDATE) ? 1 : 0;
- save->prim[i].pad = 0;
- save->prim[i].start = save->vert_count;
- save->prim[i].count = 0;
- save->prim[i].num_instances = 1;
- save->prim[i].base_instance = 0;
- save->prim[i].is_indirect = 0;
+ save->prims[i].pad = 0;
+ save->prims[i].start = save->vert_count;
+ save->prims[i].count = 0;
+ save->prims[i].num_instances = 1;
+ save->prims[i].base_instance = 0;
+ save->prims[i].is_indirect = 0;
if (save->out_of_memory) {
_mesa_install_save_vtxfmt(ctx, &save->vtxfmt_noop);
/* We need to call vbo_save_SaveFlushVertices() if there's state change */
ctx->Driver.SaveNeedFlush = GL_TRUE;
-
- /* GL_TRUE means we've handled this glBegin here; don't compile a BEGIN
- * opcode into the display list.
- */
- return GL_TRUE;
}
const GLint i = save->prim_count - 1;
ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END;
- save->prim[i].end = 1;
- save->prim[i].count = (save->vert_count - save->prim[i].start);
+ save->prims[i].end = 1;
+ save->prims[i].count = (save->vert_count - save->prims[i].start);
if (i == (GLint) save->prim_max - 1) {
_save_compile_vertex_list(ctx);
static void GLAPIENTRY
_save_PrimitiveRestartNV(void)
{
- GLenum curPrim;
GET_CURRENT_CONTEXT(ctx);
+ struct vbo_save_context *save = &vbo_context(ctx)->save;
- curPrim = ctx->Driver.CurrentSavePrimitive;
-
- _save_End();
- _save_Begin(curPrim);
+ if (save->prim_count == 0) {
+ /* We're not inside a glBegin/End pair, so calling glPrimitiverRestartNV
+ * is an error.
+ */
+ _mesa_compile_error(ctx, GL_INVALID_OPERATION,
+ "glPrimitiveRestartNV called outside glBegin/End");
+ } else {
+ /* get current primitive mode */
+ GLenum curPrim = save->prims[save->prim_count - 1].mode;
+
+ /* restart primitive */
+ CALL_End(GET_DISPATCH(), ());
+ vbo_save_NotifyBegin(ctx, curPrim);
+ }
}
}
+static void GLAPIENTRY
+_save_OBE_MultiDrawArrays(GLenum mode, const GLint *first,
+ const GLsizei *count, GLsizei primcount)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint i;
+
+ if (!_mesa_is_valid_prim_mode(ctx, mode)) {
+ _mesa_compile_error(ctx, GL_INVALID_ENUM, "glMultiDrawArrays(mode)");
+ return;
+ }
+
+ if (primcount < 0) {
+ _mesa_compile_error(ctx, GL_INVALID_VALUE,
+ "glMultiDrawArrays(primcount<0)");
+ return;
+ }
+
+ for (i = 0; i < primcount; i++) {
+ if (count[i] < 0) {
+ _mesa_compile_error(ctx, GL_INVALID_VALUE,
+ "glMultiDrawArrays(count[i]<0)");
+ return;
+ }
+ }
+
+ for (i = 0; i < primcount; i++) {
+ if (count[i] > 0) {
+ _save_OBE_DrawArrays(mode, first[i], count[i]);
+ }
+ }
+}
+
+
/* Could do better by copying the arrays and element list intact and
* then emitting an indexed prim at runtime.
*/
vfmt->VertexAttribL3dv = _save_VertexAttribL3dv;
vfmt->VertexAttribL4dv = _save_VertexAttribL4dv;
+ vfmt->VertexAttribL1ui64ARB = _save_VertexAttribL1ui64ARB;
+ vfmt->VertexAttribL1ui64vARB = _save_VertexAttribL1ui64vARB;
+
/* This will all require us to fallback to saving the list as opcodes:
*/
vfmt->CallList = _save_CallList;
struct _glapi_table *exec)
{
SET_DrawArrays(exec, _save_OBE_DrawArrays);
+ SET_MultiDrawArrays(exec, _save_OBE_MultiDrawArrays);
SET_DrawElements(exec, _save_OBE_DrawElements);
SET_DrawElementsBaseVertex(exec, _save_OBE_DrawElementsBaseVertex);
SET_DrawRangeElements(exec, _save_OBE_DrawRangeElements);
(void) mode;
if (!save->prim_store)
- save->prim_store = alloc_prim_store(ctx);
+ save->prim_store = alloc_prim_store();
if (!save->vertex_store)
save->vertex_store = alloc_vertex_store(ctx);
if (save->prim_count > 0) {
GLint i = save->prim_count - 1;
ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END;
- save->prim[i].end = 0;
- save->prim[i].count = save->vert_count - save->prim[i].start;
+ save->prims[i].end = 0;
+ save->prims[i].count = save->vert_count - save->prims[i].start;
}
/* Make sure this vertex list gets replayed by the "loopback"
fprintf(f, "VBO-VERTEX-LIST, %u vertices, %d primitives, %d vertsize, "
"buffer %p\n",
- node->count, node->prim_count, node->vertex_size,
+ node->vertex_count, node->prim_count, node->vertex_size,
buffer);
for (i = 0; i < node->prim_count; i++) {
- struct _mesa_prim *prim = &node->prim[i];
+ struct _mesa_prim *prim = &node->prims[i];
fprintf(f, " prim %d: %s%s %d..%d %s %s\n",
i,
_mesa_lookup_prim_by_nr(prim->mode),