Beispiel #1
0
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 {
Beispiel #2
0
static GLboolean
nouveau_bufferobj_data(struct gl_context *ctx, GLenum target, GLsizeiptrARB size,
                       const GLvoid *data, GLenum usage,
                       struct gl_buffer_object *obj)
{
    struct nouveau_bufferobj *nbo = to_nouveau_bufferobj(obj);
    int ret;

    obj->Size = size;
    obj->Usage = usage;

    /* Free previous storage */
    nouveau_bo_ref(NULL, &nbo->bo);
    FREE(nbo->sys);

    if (target == GL_ELEMENT_ARRAY_BUFFER_ARB ||
            (size < 512 && usage == GL_DYNAMIC_DRAW_ARB) ||
            context_chipset(ctx) < 0x10) {
        /* Heuristic: keep it in system ram */
        nbo->sys = MALLOC(size);

    } else {
        /* Get a hardware BO */
        ret = nouveau_bo_new(context_dev(ctx),
                             NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0,
                             size, &nbo->bo);
        assert(!ret);
    }

    if (data)
        memcpy(get_bufferobj_map(obj, NOUVEAU_BO_WR), data, size);

    return GL_TRUE;
}
static GLboolean
nouveau_bufferobj_data(GLcontext *ctx, GLenum target, GLsizeiptrARB size,
		       const GLvoid *data, GLenum usage,
		       struct gl_buffer_object *obj)
{
	struct nouveau_bufferobj *nbo = to_nouveau_bufferobj(obj);
	int ret;

	obj->Size = size;
	obj->Usage = usage;

	nouveau_bo_ref(NULL, &nbo->bo);
	ret = nouveau_bo_new(context_dev(ctx),
			     NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0,
			     size, &nbo->bo);
	assert(!ret);

	if (data) {
		nouveau_bo_map(nbo->bo, NOUVEAU_BO_WR);
		memcpy(nbo->bo->map, data, size);
		nouveau_bo_unmap(nbo->bo);
	}

	return GL_TRUE;
}
static void *
nouveau_bufferobj_map_range(GLcontext *ctx, GLenum target, GLintptr offset,
			    GLsizeiptr length, GLenum access,
			    struct gl_buffer_object *obj)
{
	struct nouveau_bufferobj *nbo = to_nouveau_bufferobj(obj);
	uint32_t flags = 0;

	assert(!obj->Pointer);

	if (!nbo->bo)
		return NULL;

	if (access == GL_READ_ONLY_ARB ||
	    access == GL_READ_WRITE_ARB)
		flags |= NOUVEAU_BO_RD;
	if (access == GL_WRITE_ONLY_ARB ||
	    access == GL_READ_WRITE_ARB)
		flags |= NOUVEAU_BO_WR;

	nouveau_bo_map_range(nbo->bo, offset, length, flags);

	obj->Pointer = nbo->bo->map;
	obj->Offset = offset;
	obj->Length = length;
	obj->AccessFlags = access;

	return obj->Pointer;
}
static void
nouveau_bufferobj_del(GLcontext *ctx, struct gl_buffer_object *obj)
{
	struct nouveau_bufferobj *nbo = to_nouveau_bufferobj(obj);

	nouveau_bo_ref(NULL, &nbo->bo);
	FREE(nbo);
}
static void
nouveau_bufferobj_get_subdata(GLcontext *ctx, GLenum target, GLintptrARB offset,
			   GLsizeiptrARB size, GLvoid *data,
			   struct gl_buffer_object *obj)
{
	struct nouveau_bufferobj *nbo = to_nouveau_bufferobj(obj);

	nouveau_bo_map(nbo->bo, NOUVEAU_BO_RD);
	memcpy(data, nbo->bo->map + offset, size);
	nouveau_bo_unmap(nbo->bo);
}
Beispiel #7
0
static inline char *
get_bufferobj_map(struct gl_buffer_object *obj, unsigned flags)
{
    struct nouveau_bufferobj *nbo = to_nouveau_bufferobj(obj);
    void *map = NULL;

    if (nbo->sys) {
        map = nbo->sys;
    } else if (nbo->bo) {
        nouveau_bo_map(nbo->bo, flags);
        map = nbo->bo->map;
        nouveau_bo_unmap(nbo->bo);
    }

    return map;
}
static GLboolean
nouveau_bufferobj_unmap(GLcontext *ctx, GLenum target, struct gl_buffer_object *obj)
{
	struct nouveau_bufferobj *nbo = to_nouveau_bufferobj(obj);

	assert(obj->Pointer);

	nouveau_bo_unmap(nbo->bo);

	obj->Pointer = NULL;
	obj->Offset = 0;
	obj->Length = 0;
	obj->AccessFlags = 0;

	return GL_TRUE;
}
Beispiel #9
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);
}