예제 #1
0
파일: nouveau_vbo_t.c 프로젝트: Sheph/mesa
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 {
예제 #2
0
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);
}