summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancisco Jerez <currojerez@riseup.net>2010-10-31 01:37:47 +0200
committerFrancisco Jerez <currojerez@riseup.net>2010-10-31 02:01:24 +0100
commitf67fa5229331f6d4920175dd0d6e1e6a2c69c060 (patch)
tree994bf53e24c460e23ae2df780422e08813cd773a
parente89af209261e51988b99d954d09f2cbc59e55358 (diff)
dri/nouveau: Keep small DYNAMIC_DRAW vertex buffers in system ram.
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_array.c5
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c25
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h7
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c11
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 1fee360309..17e6d163a0 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 c145341634..e60b91f64b 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 acfc4cb9a9..01ef0bad0f 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 bf5885f8b1..9437fc9878 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]);