From f67fa5229331f6d4920175dd0d6e1e6a2c69c060 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sun, 31 Oct 2010 01:37:47 +0200 Subject: [PATCH] dri/nouveau: Keep small DYNAMIC_DRAW vertex buffers in system ram. --- src/mesa/drivers/dri/nouveau/nouveau_array.c | 5 ++-- .../drivers/dri/nouveau/nouveau_bufferobj.c | 25 +++++++++++++++---- .../drivers/dri/nouveau/nouveau_bufferobj.h | 7 ++++++ src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c | 11 ++++---- 4 files changed, 35 insertions(+), 13 deletions(-) diff --git a/src/mesa/drivers/dri/nouveau/nouveau_array.c b/src/mesa/drivers/dri/nouveau/nouveau_array.c index 1fee3603092..17e6d163a02 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_array.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_array.c @@ -90,7 +90,7 @@ nouveau_init_array(struct nouveau_array *a, int attr, int stride, a->buf = NULL; if (obj) { - if (_mesa_is_bufferobj(obj)) { + if (nouveau_bufferobj_hw(obj)) { struct nouveau_bufferobj *nbo = to_nouveau_bufferobj(obj); @@ -107,7 +107,8 @@ nouveau_init_array(struct nouveau_array *a, int attr, int stride, a->offset = 0; if (map) - a->buf = ptr; + a->buf = ADD_POINTERS( + nouveau_bufferobj_sys(obj), ptr); } } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c index c1453416347..e60b91f64be 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c @@ -36,7 +36,9 @@ get_bufferobj_map(struct gl_buffer_object *obj, unsigned flags) struct nouveau_bufferobj *nbo = to_nouveau_bufferobj(obj); void *map = NULL; - if (nbo->bo) { + 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); @@ -65,6 +67,7 @@ nouveau_bufferobj_del(struct gl_context *ctx, struct gl_buffer_object *obj) struct nouveau_bufferobj *nbo = to_nouveau_bufferobj(obj); nouveau_bo_ref(NULL, &nbo->bo); + FREE(nbo->sys); FREE(nbo); } @@ -79,11 +82,23 @@ nouveau_bufferobj_data(struct gl_context *ctx, GLenum target, GLsizeiptrARB size obj->Size = size; obj->Usage = usage; + /* Free previous storage */ 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); + 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); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h index acfc4cb9a90..01ef0bad0fd 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h @@ -30,9 +30,16 @@ struct nouveau_bufferobj { struct gl_buffer_object base; struct nouveau_bo *bo; + void *sys; }; #define to_nouveau_bufferobj(x) ((struct nouveau_bufferobj *)(x)) +#define nouveau_bufferobj_hw(x) \ + (_mesa_is_bufferobj(x) ? to_nouveau_bufferobj(x)->bo : NULL) + +#define nouveau_bufferobj_sys(x) \ + (_mesa_is_bufferobj(x) ? to_nouveau_bufferobj(x)->sys : NULL) + void nouveau_bufferobj_functions_init(struct dd_function_table *functions); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c b/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c index bf5885f8b17..9437fc98788 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c @@ -297,22 +297,21 @@ vbo_bind_vertices(struct gl_context *ctx, const struct gl_client_array **arrays, 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 (_mesa_is_bufferobj(array->BufferObj)) { - struct nouveau_bufferobj *nbo = - to_nouveau_bufferobj(array->BufferObj); - + if (nouveau_bufferobj_hw(obj)) { /* Array in a buffer obj. */ - nouveau_bo_ref(nbo->bo, &bo[i]); + 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 *)array->Ptr + delta; + 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]); -- 2.30.2