From 1befacc7647f51344f5cfbfa86b62e53625a436f Mon Sep 17 00:00:00 2001 From: Christoph Bumiller Date: Thu, 17 May 2012 14:43:47 +0200 Subject: [PATCH] nouveau: place static buffers in VRAM if preferred by the driver --- src/gallium/drivers/nouveau/nouveau_buffer.c | 29 +++++++++++++++++--- src/gallium/drivers/nouveau/nouveau_screen.c | 10 +++++++ src/gallium/drivers/nouveau/nouveau_screen.h | 8 +++++- src/gallium/drivers/nv30/nv30_screen.c | 10 +++++-- src/gallium/drivers/nv50/nv50_screen.c | 10 +++++-- src/gallium/drivers/nvc0/nvc0_screen.c | 7 +++-- 6 files changed, 62 insertions(+), 12 deletions(-) diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.c b/src/gallium/drivers/nouveau/nouveau_buffer.c index c396e3c3986..d04ac2f9f1c 100644 --- a/src/gallium/drivers/nouveau/nouveau_buffer.c +++ b/src/gallium/drivers/nouveau/nouveau_buffer.c @@ -363,10 +363,31 @@ nouveau_buffer_create(struct pipe_screen *pscreen, pipe_reference_init(&buffer->base.reference, 1); buffer->base.screen = pscreen; - if ((buffer->base.bind & screen->sysmem_bindings) == screen->sysmem_bindings) - ret = nouveau_buffer_allocate(screen, buffer, 0); - else - ret = nouveau_buffer_allocate(screen, buffer, NOUVEAU_BO_GART); + if (buffer->base.bind & + (screen->vidmem_bindings & screen->sysmem_bindings)) { + switch (buffer->base.usage) { + case PIPE_USAGE_DEFAULT: + case PIPE_USAGE_IMMUTABLE: + case PIPE_USAGE_STATIC: + buffer->domain = NOUVEAU_BO_VRAM; + break; + case PIPE_USAGE_DYNAMIC: + case PIPE_USAGE_STAGING: + case PIPE_USAGE_STREAM: + buffer->domain = NOUVEAU_BO_GART; + break; + default: + assert(0); + break; + } + } else { + if (buffer->base.bind & screen->vidmem_bindings) + buffer->domain = NOUVEAU_BO_VRAM; + else + if (buffer->base.bind & screen->sysmem_bindings) + buffer->domain = NOUVEAU_BO_GART; + } + ret = nouveau_buffer_allocate(screen, buffer, buffer->domain); if (ret == FALSE) goto fail; diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c index 74377799977..9baa68ce151 100644 --- a/src/gallium/drivers/nouveau/nouveau_screen.c +++ b/src/gallium/drivers/nouveau/nouveau_screen.c @@ -148,6 +148,16 @@ nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev) util_format_s3tc_init(); + screen->lowmem_bindings = PIPE_BIND_GLOBAL; /* gallium limit */ + screen->vidmem_bindings = + PIPE_BIND_RENDER_TARGET | PIPE_BIND_DEPTH_STENCIL | + PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT | PIPE_BIND_CURSOR | + PIPE_BIND_SAMPLER_VIEW | + PIPE_BIND_SHADER_RESOURCE | PIPE_BIND_COMPUTE_RESOURCE | + PIPE_BIND_GLOBAL; + screen->sysmem_bindings = + PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_STREAM_OUTPUT; + memset(&mm_config, 0, sizeof(mm_config)); screen->mm_GART = nouveau_mm_create(dev, diff --git a/src/gallium/drivers/nouveau/nouveau_screen.h b/src/gallium/drivers/nouveau/nouveau_screen.h index 4ca286bfe8d..5a3cfab92e9 100644 --- a/src/gallium/drivers/nouveau/nouveau_screen.h +++ b/src/gallium/drivers/nouveau/nouveau_screen.h @@ -17,7 +17,13 @@ struct nouveau_screen { struct nouveau_client *client; struct nouveau_pushbuf *pushbuf; - unsigned sysmem_bindings; + unsigned vidmem_bindings; /* PIPE_BIND_* where VRAM placement is desired */ + unsigned sysmem_bindings; /* PIPE_BIND_* where GART placement is desired */ + unsigned lowmem_bindings; /* PIPE_BIND_* that require an address < 4 GiB */ + /* + * For bindings with (vidmem & sysmem) bits set set, PIPE_USAGE_* decides + * placement. + */ uint16_t class_3d; diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c index f5120e74c5f..67de8c03f45 100644 --- a/src/gallium/drivers/nv30/nv30_screen.c +++ b/src/gallium/drivers/nv30/nv30_screen.c @@ -371,14 +371,18 @@ nv30_screen_create(struct nouveau_device *dev) screen->base.fence.emit = nv30_screen_fence_emit; screen->base.fence.update = nv30_screen_fence_update; - screen->base.sysmem_bindings = PIPE_BIND_CONSTANT_BUFFER; - if (oclass != NV40_3D_CLASS) - screen->base.sysmem_bindings |= PIPE_BIND_INDEX_BUFFER; ret = nouveau_screen_init(&screen->base, dev); if (ret) FAIL_SCREEN_INIT("nv30_screen_init failed: %d\n", ret); + screen->base.vidmem_bindings |= PIPE_BIND_VERTEX_BUFFER; + screen->base.sysmem_bindings |= PIPE_BIND_VERTEX_BUFFER; + if (oclass == NV40_3D_CLASS) { + screen->base.vidmem_bindings |= PIPE_BIND_INDEX_BUFFER; + screen->base.sysmem_bindings |= PIPE_BIND_INDEX_BUFFER; + } + fifo = screen->base.channel->data; push = screen->base.pushbuf; push->rsvd_kick = 16; diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index d7efa353381..9567abbf352 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -532,12 +532,18 @@ nv50_screen_create(struct nouveau_device *dev) return NULL; pscreen = &screen->base.base; - screen->base.sysmem_bindings = PIPE_BIND_CONSTANT_BUFFER; - ret = nouveau_screen_init(&screen->base, dev); if (ret) FAIL_SCREEN_INIT("nouveau_screen_init failed: %d\n", ret); + /* TODO: Prevent FIFO prefetch before transfer of index buffers and + * admit them to VRAM. + */ + screen->base.vidmem_bindings |= PIPE_BIND_CONSTANT_BUFFER | + PIPE_BIND_VERTEX_BUFFER; + screen->base.sysmem_bindings |= + PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER; + screen->base.pushbuf->user_priv = screen; screen->base.pushbuf->rsvd_kick = 5; diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c index 0717ac8f725..49d61184471 100644 --- a/src/gallium/drivers/nvc0/nvc0_screen.c +++ b/src/gallium/drivers/nvc0/nvc0_screen.c @@ -418,8 +418,6 @@ nvc0_screen_create(struct nouveau_device *dev) return NULL; pscreen = &screen->base.base; - screen->base.sysmem_bindings = PIPE_BIND_CONSTANT_BUFFER; - ret = nouveau_screen_init(&screen->base, dev); if (ret) { nvc0_screen_destroy(pscreen); @@ -429,6 +427,11 @@ nvc0_screen_create(struct nouveau_device *dev) push = screen->base.pushbuf; push->user_priv = screen; + screen->base.vidmem_bindings |= PIPE_BIND_CONSTANT_BUFFER | + PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER; + screen->base.sysmem_bindings |= + PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER; + pscreen->destroy = nvc0_screen_destroy; pscreen->context_create = nvc0_create; pscreen->is_format_supported = nvc0_screen_is_format_supported; -- 2.30.2