static void vbo_bind_vertices(struct gl_context *ctx, const struct gl_client_array **arrays, int base, unsigned min_index, unsigned max_index, int *pdelta) { struct nouveau_render_state *render = to_render_state(ctx); struct nouveau_pushbuf *push = context_push(ctx); struct nouveau_bo *bo[NUM_VERTEX_ATTRS]; unsigned offset[NUM_VERTEX_ATTRS]; GLboolean dirty = GL_FALSE; int i, j, attr; RENDER_LOCALS(ctx); *pdelta = -1; FOR_EACH_BOUND_ATTR(render, i, attr) { const struct gl_client_array *array = arrays[attr]; struct gl_buffer_object *obj = array->BufferObj; struct nouveau_array *a = &render->attrs[attr]; unsigned delta = (base + min_index) * array->StrideB; bo[i] = NULL; if (nouveau_bufferobj_hw(obj)) { /* Array in a buffer obj. */ nouveau_bo_ref(to_nouveau_bufferobj(obj)->bo, &bo[i]); offset[i] = delta + (intptr_t)array->Ptr; } else { int n = max_index - min_index + 1; char *sp = (char *)ADD_POINTERS( nouveau_bufferobj_sys(obj), array->Ptr) + delta; char *dp = nouveau_get_scratch(ctx, n * a->stride, &bo[i], &offset[i]); /* Array in client memory, move it to a * scratch buffer obj. */ for (j = 0; j < n; j++) memcpy(dp + j * a->stride, sp + j * array->StrideB, a->stride); } dirty |= check_update_array(a, offset[i], bo[i], pdelta); } *pdelta -= min_index; if (dirty) { /* Buffers changed, update the attribute binding. */ FOR_EACH_BOUND_ATTR(render, i, attr) { struct nouveau_array *a = &render->attrs[attr]; nouveau_bo_ref(NULL, &a->bo); a->offset = offset[i]; a->bo = bo[i]; } TAG(render_release_vertices)(ctx); TAG(render_bind_vertices)(ctx); } else {
void nouveau_init_array(struct nouveau_array *a, int attr, int stride, int fields, int type, struct gl_buffer_object *obj, const void *ptr, GLboolean map) { a->attr = attr; a->stride = stride; a->fields = fields; a->type = type; a->buf = NULL; if (obj) { if (nouveau_bufferobj_hw(obj)) { struct nouveau_bufferobj *nbo = to_nouveau_bufferobj(obj); nouveau_bo_ref(nbo->bo, &a->bo); a->offset = (intptr_t)ptr; if (map) { nouveau_bo_map(a->bo, NOUVEAU_BO_RD); a->buf = a->bo->map + a->offset; } } else { nouveau_bo_ref(NULL, &a->bo); a->offset = 0; if (map) a->buf = ADD_POINTERS( nouveau_bufferobj_sys(obj), ptr); } } if (a->buf) get_array_extract(a, &a->extract_u, &a->extract_f); }