Alexandre Courbot
2015-Jun-22 02:39 UTC
[Nouveau] [PATCH v4 0/2] nouveau: support for custom VRAM domains
New (hopefully good to merge) revision of this patchset that prevents VRAM objects from being allocated on VRAM-less systems like Tegra's GK20A and GM20B. This is required for Mesa to work on such systems. Changes since v3: - Fixed change that would make a comment ambiguous - Added Reviewed-by tags Alexandre Courbot (2): nouveau: support for custom VRAM domains nvc0: use NV_VRAM_DOMAIN() macro src/gallium/drivers/nouveau/nouveau_buffer.c | 6 +++--- src/gallium/drivers/nouveau/nouveau_screen.c | 10 ++++++++++ src/gallium/drivers/nouveau/nouveau_screen.h | 4 ++++ src/gallium/drivers/nouveau/nv50/nv50_miptree.c | 2 +- src/gallium/drivers/nouveau/nvc0/nvc0_compute.c | 2 +- src/gallium/drivers/nouveau/nvc0/nvc0_context.c | 4 ++-- src/gallium/drivers/nouveau/nvc0/nvc0_miptree.c | 2 +- src/gallium/drivers/nouveau/nvc0/nvc0_program.c | 8 ++++---- src/gallium/drivers/nouveau/nvc0/nvc0_screen.c | 17 +++++++++++------ src/gallium/drivers/nouveau/nvc0/nvc0_shader_state.c | 2 +- src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c | 2 +- src/gallium/drivers/nouveau/nvc0/nvc0_tex.c | 2 +- src/gallium/drivers/nouveau/nvc0/nve4_compute.c | 2 +- 13 files changed, 41 insertions(+), 22 deletions(-) -- 2.4.4
Alexandre Courbot
2015-Jun-22 02:39 UTC
[Nouveau] [PATCH v4 1/2] nouveau: support for custom VRAM domains
Some GPUs (e.g. GK20A, GM20B) do not embed VRAM of their own and use the system memory as a backend instead. For such systems, allocating objects in VRAM results in errors since the kernel will not allow VRAM objects allocations. This patch adds a vram_domain member to struct nouveau_screen that can optionally be initialized to an alternative domain to use for VRAM allocations. If left untouched, NOUVEAU_BO_VRAM will be used for systems that embed VRAM, and NOUVEAU_BO_GART will be used for VRAM-less systems. Code that uses GPU objects is then expected to use the NV_VRAM_DOMAIN() macro in place of NOUVEAU_BO_VRAM to ensure correct behavior on VRAM-less chips. Signed-off-by: Alexandre Courbot <acourbot at nvidia.com> Reviewed-by: Ilia Mirkin <imirkin at alum.mit.edu> Reviewed-by: Martin Peres <martin.peres at free.fr> --- src/gallium/drivers/nouveau/nouveau_screen.c | 10 ++++++++++ src/gallium/drivers/nouveau/nouveau_screen.h | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c index b4f1413fd8ba..c6e5074db195 100644 --- a/src/gallium/drivers/nouveau/nouveau_screen.c +++ b/src/gallium/drivers/nouveau/nouveau_screen.c @@ -164,6 +164,16 @@ nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev) size = sizeof(nvc0_data); } + /* + * Set default VRAM domain if not overridden + */ + if (!screen->vram_domain) { + if (dev->vram_size > 0) + screen->vram_domain = NOUVEAU_BO_VRAM; + else + screen->vram_domain = NOUVEAU_BO_GART; + } + ret = nouveau_object_new(&dev->object, 0, NOUVEAU_FIFO_CHANNEL_CLASS, data, size, &screen->channel); if (ret) diff --git a/src/gallium/drivers/nouveau/nouveau_screen.h b/src/gallium/drivers/nouveau/nouveau_screen.h index cf06f7e88aa0..30041b271c94 100644 --- a/src/gallium/drivers/nouveau/nouveau_screen.h +++ b/src/gallium/drivers/nouveau/nouveau_screen.h @@ -51,6 +51,8 @@ struct nouveau_screen { boolean hint_buf_keep_sysmem_copy; + unsigned vram_domain; + struct { unsigned profiles_checked; unsigned profiles_present; @@ -94,6 +96,8 @@ struct nouveau_screen { #endif }; +#define NV_VRAM_DOMAIN(screen) ((screen)->vram_domain) + #ifdef NOUVEAU_ENABLE_DRIVER_STATISTICS # define NOUVEAU_DRV_STAT(s, n, v) do { \ (s)->stats.named.n += (v); \ -- 2.4.4
Alexandre Courbot
2015-Jun-22 02:39 UTC
[Nouveau] [PATCH v4 2/2] nvc0: use NV_VRAM_DOMAIN() macro
Use the newly-introduced NV_VRAM_DOMAIN() macro to support alternative VRAM domains for chips that do not have dedicated video memory. Signed-off-by: Alexandre Courbot <acourbot at nvidia.com> Reviewed-by: Ilia Mirkin <imirkin at alum.mit.edu> Reviewed-by: Martin Peres <martin.peres at free.fr> --- src/gallium/drivers/nouveau/nouveau_buffer.c | 6 +++--- src/gallium/drivers/nouveau/nv50/nv50_miptree.c | 2 +- src/gallium/drivers/nouveau/nvc0/nvc0_compute.c | 2 +- src/gallium/drivers/nouveau/nvc0/nvc0_context.c | 4 ++-- src/gallium/drivers/nouveau/nvc0/nvc0_miptree.c | 2 +- src/gallium/drivers/nouveau/nvc0/nvc0_program.c | 8 ++++---- src/gallium/drivers/nouveau/nvc0/nvc0_screen.c | 17 +++++++++++------ src/gallium/drivers/nouveau/nvc0/nvc0_shader_state.c | 2 +- src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c | 2 +- src/gallium/drivers/nouveau/nvc0/nvc0_tex.c | 2 +- src/gallium/drivers/nouveau/nvc0/nve4_compute.c | 2 +- 11 files changed, 27 insertions(+), 22 deletions(-) diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.c b/src/gallium/drivers/nouveau/nouveau_buffer.c index 32fa65c8a51c..09cdbb53ecb7 100644 --- a/src/gallium/drivers/nouveau/nouveau_buffer.c +++ b/src/gallium/drivers/nouveau/nouveau_buffer.c @@ -658,13 +658,13 @@ nouveau_buffer_create(struct pipe_screen *pscreen, switch (buffer->base.usage) { case PIPE_USAGE_DEFAULT: case PIPE_USAGE_IMMUTABLE: - buffer->domain = NOUVEAU_BO_VRAM; + buffer->domain = NV_VRAM_DOMAIN(screen); break; case PIPE_USAGE_DYNAMIC: /* For most apps, we'd have to do staging transfers to avoid sync * with this usage, and GART -> GART copies would be suboptimal. */ - buffer->domain = NOUVEAU_BO_VRAM; + buffer->domain = NV_VRAM_DOMAIN(screen); break; case PIPE_USAGE_STAGING: case PIPE_USAGE_STREAM: @@ -676,7 +676,7 @@ nouveau_buffer_create(struct pipe_screen *pscreen, } } else { if (buffer->base.bind & screen->vidmem_bindings) - buffer->domain = NOUVEAU_BO_VRAM; + buffer->domain = NV_VRAM_DOMAIN(screen); else if (buffer->base.bind & screen->sysmem_bindings) buffer->domain = NOUVEAU_BO_GART; diff --git a/src/gallium/drivers/nouveau/nv50/nv50_miptree.c b/src/gallium/drivers/nouveau/nv50/nv50_miptree.c index 10cebb17eee3..f15d8f3ecb69 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_miptree.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_miptree.c @@ -377,7 +377,7 @@ nv50_miptree_create(struct pipe_screen *pscreen, if (!bo_config.nv50.memtype && (pt->bind & PIPE_BIND_SHARED)) mt->base.domain = NOUVEAU_BO_GART; else - mt->base.domain = NOUVEAU_BO_VRAM; + mt->base.domain = NV_VRAM_DOMAIN(nouveau_screen(pscreen)); bo_flags = mt->base.domain | NOUVEAU_BO_NOSNOOP; if (mt->base.base.bind & (PIPE_BIND_CURSOR | PIPE_BIND_DISPLAY_TARGET)) diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c b/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c index ad287a2af6b6..56fc83d3679f 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c @@ -57,7 +57,7 @@ nvc0_screen_compute_setup(struct nvc0_screen *screen, return ret; } - ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, 1 << 12, NULL, + ret = nouveau_bo_new(dev, NV_VRAM_DOMAIN(&screen->base), 0, 1 << 12, NULL, &screen->parm); if (ret) return ret; diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_context.c b/src/gallium/drivers/nouveau/nvc0/nvc0_context.c index 7904984f5037..a35c3f661423 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_context.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_context.c @@ -329,7 +329,7 @@ nvc0_create(struct pipe_screen *pscreen, void *priv) /* add permanently resident buffers to bufctxts */ - flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD; + flags = NV_VRAM_DOMAIN(&screen->base) | NOUVEAU_BO_RD; BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->text); BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->uniform_bo); @@ -340,7 +340,7 @@ nvc0_create(struct pipe_screen *pscreen, void *priv) BCTX_REFN_bo(nvc0->bufctx_cp, CP_SCREEN, flags, screen->parm); } - flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR; + flags = NV_VRAM_DOMAIN(&screen->base) | NOUVEAU_BO_RDWR; if (screen->poly_cache) BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->poly_cache); diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_miptree.c b/src/gallium/drivers/nouveau/nvc0/nvc0_miptree.c index fc75fc6a4a17..3875bbf4ca4d 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_miptree.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_miptree.c @@ -302,7 +302,7 @@ nvc0_miptree_create(struct pipe_screen *pscreen, if (!bo_config.nvc0.memtype && (pt->usage == PIPE_USAGE_STAGING || pt->bind & PIPE_BIND_SHARED)) mt->base.domain = NOUVEAU_BO_GART; else - mt->base.domain = NOUVEAU_BO_VRAM; + mt->base.domain = NV_VRAM_DOMAIN(nouveau_screen(pscreen)); bo_flags = mt->base.domain | NOUVEAU_BO_NOSNOOP; diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_program.c b/src/gallium/drivers/nouveau/nvc0/nvc0_program.c index 4a47cb2d1649..e1f5a8c4416b 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_program.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_program.c @@ -735,12 +735,12 @@ nvc0_program_upload_code(struct nvc0_context *nvc0, struct nvc0_program *prog) if (!is_cp) nvc0->base.push_data(&nvc0->base, screen->text, prog->code_base, - NOUVEAU_BO_VRAM, NVC0_SHADER_HEADER_SIZE, prog->hdr); + NV_VRAM_DOMAIN(&screen->base), NVC0_SHADER_HEADER_SIZE, prog->hdr); nvc0->base.push_data(&nvc0->base, screen->text, code_pos, - NOUVEAU_BO_VRAM, prog->code_size, prog->code); + NV_VRAM_DOMAIN(&screen->base), prog->code_size, prog->code); if (prog->immd_size) nvc0->base.push_data(&nvc0->base, - screen->text, prog->immd_base, NOUVEAU_BO_VRAM, + screen->text, prog->immd_base, NV_VRAM_DOMAIN(&screen->base), prog->immd_size, prog->immd_data); BEGIN_NVC0(nvc0->base.pushbuf, NVC0_3D(MEM_BARRIER), 1); @@ -771,7 +771,7 @@ nvc0_program_library_upload(struct nvc0_context *nvc0) return; nvc0->base.push_data(&nvc0->base, - screen->text, screen->lib_code->start, NOUVEAU_BO_VRAM, + screen->text, screen->lib_code->start, NV_VRAM_DOMAIN(&screen->base), size, code); /* no need for a memory barrier, will be emitted with first program */ } diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c index 307cf5f9cd75..71cb5489433d 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c @@ -583,7 +583,7 @@ nvc0_screen_resize_tls_area(struct nvc0_screen *screen, size = align(size, 1 << 17); - ret = nouveau_bo_new(screen->base.device, NOUVEAU_BO_VRAM, 1 << 17, size, + ret = nouveau_bo_new(screen->base.device, NV_VRAM_DOMAIN(&screen->base), 1 << 17, size, NULL, &bo); if (ret) { NOUVEAU_ERR("failed to allocate TLS area, size: 0x%"PRIx64"\n", size); @@ -647,6 +647,11 @@ nvc0_screen_create(struct nouveau_device *dev) screen->base.sysmem_bindings | PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER; + if (screen->base.vram_domain & NOUVEAU_BO_GART) { + screen->base.sysmem_bindings |= screen->base.vidmem_bindings; + screen->base.vidmem_bindings = 0; + } + pscreen->destroy = nvc0_screen_destroy; pscreen->context_create = nvc0_create; pscreen->is_format_supported = nvc0_screen_is_format_supported; @@ -828,7 +833,7 @@ nvc0_screen_create(struct nouveau_device *dev) nvc0_magic_3d_init(push, screen->eng3d->oclass); - ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 20, NULL, + ret = nouveau_bo_new(dev, NV_VRAM_DOMAIN(&screen->base), 1 << 17, 1 << 20, NULL, &screen->text); if (ret) goto fail; @@ -838,12 +843,12 @@ nvc0_screen_create(struct nouveau_device *dev) */ nouveau_heap_init(&screen->text_heap, 0, (1 << 20) - 0x100); - ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 12, 6 << 16, NULL, + ret = nouveau_bo_new(dev, NV_VRAM_DOMAIN(&screen->base), 1 << 12, 6 << 16, NULL, &screen->uniform_bo); if (ret) goto fail; - PUSH_REFN (push, screen->uniform_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + PUSH_REFN (push, screen->uniform_bo, NV_VRAM_DOMAIN(&screen->base) | NOUVEAU_BO_WR); for (i = 0; i < 5; ++i) { /* TIC and TSC entries for each unit (nve4+ only) */ @@ -914,7 +919,7 @@ nvc0_screen_create(struct nouveau_device *dev) PUSH_DATA (push, 0); if (screen->eng3d->oclass < GM107_3D_CLASS) { - ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 20, NULL, + ret = nouveau_bo_new(dev, NV_VRAM_DOMAIN(&screen->base), 1 << 17, 1 << 20, NULL, &screen->poly_cache); if (ret) goto fail; @@ -925,7 +930,7 @@ nvc0_screen_create(struct nouveau_device *dev) PUSH_DATA (push, 3); } - ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 17, NULL, + ret = nouveau_bo_new(dev, NV_VRAM_DOMAIN(&screen->base), 1 << 17, 1 << 17, NULL, &screen->txc); if (ret) goto fail; diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_shader_state.c b/src/gallium/drivers/nouveau/nvc0/nvc0_shader_state.c index 516b33b76d55..c9b5a5cbfc16 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_shader_state.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_shader_state.c @@ -34,7 +34,7 @@ nvc0_program_update_context_state(struct nvc0_context *nvc0, struct nouveau_pushbuf *push = nvc0->base.pushbuf; if (prog && prog->need_tls) { - const uint32_t flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR; + const uint32_t flags = NV_VRAM_DOMAIN(&nvc0->screen->base) | NOUVEAU_BO_RDWR; if (!nvc0->state.tls_required) BCTX_REFN_bo(nvc0->bufctx_3d, TLS, flags, nvc0->screen->tls); nvc0->state.tls_required |= 1 << stage; diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c b/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c index d3ad81d2d669..c52399ab312e 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c @@ -439,7 +439,7 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0) BEGIN_NVC0(push, NVC0_3D(CB_BIND(s)), 1); PUSH_DATA (push, (0 << 4) | 1); } - nvc0_cb_push(&nvc0->base, bo, NOUVEAU_BO_VRAM, + nvc0_cb_push(&nvc0->base, bo, NV_VRAM_DOMAIN(&nvc0->screen->base), base, nvc0->state.uniform_buffer_bound[s], 0, (size + 3) / 4, nvc0->constbuf[s][0].u.data); diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_tex.c b/src/gallium/drivers/nouveau/nvc0/nvc0_tex.c index 457f27c8311f..ddc0409ca86d 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_tex.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_tex.c @@ -396,7 +396,7 @@ nvc0_validate_tsc(struct nvc0_context *nvc0, int s) tsc->id = nvc0_screen_tsc_alloc(nvc0->screen, tsc); nvc0_m2mf_push_linear(&nvc0->base, nvc0->screen->txc, - 65536 + tsc->id * 32, NOUVEAU_BO_VRAM, + 65536 + tsc->id * 32, NV_VRAM_DOMAIN(&nvc0->screen->base), 32, tsc->tsc); need_flush = TRUE; } diff --git a/src/gallium/drivers/nouveau/nvc0/nve4_compute.c b/src/gallium/drivers/nouveau/nvc0/nve4_compute.c index f243316b899c..fce02a7cc576 100644 --- a/src/gallium/drivers/nouveau/nvc0/nve4_compute.c +++ b/src/gallium/drivers/nouveau/nvc0/nve4_compute.c @@ -63,7 +63,7 @@ nve4_screen_compute_setup(struct nvc0_screen *screen, return ret; } - ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, NVE4_CP_PARAM_SIZE, NULL, + ret = nouveau_bo_new(dev, NV_VRAM_DOMAIN(&screen->base), 0, NVE4_CP_PARAM_SIZE, NULL, &screen->parm); if (ret) return ret; -- 2.4.4