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