From 06d87b44cffef9e335b9a0e70fd2aec61fcd171b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 Jul 2008 12:51:29 +1000 Subject: [PATCH] nv50: make use of nouveau drm 0.0.11 to get 3d going --- src/gallium/drivers/nouveau/nouveau_bo.h | 2 + .../drivers/nouveau/nouveau_stateobj.h | 3 + .../drivers/nv50/nv50_state_validate.c | 6 +- src/gallium/winsys/dri/nouveau/nouveau_bo.c | 16 ++ .../winsys/dri/nouveau/nouveau_drmif.h | 1 + .../winsys/dri/nouveau/nouveau_screen.c | 2 +- .../winsys/dri/nouveau/nouveau_winsys_pipe.c | 12 ++ src/gallium/winsys/dri/nouveau/nv50_surface.c | 158 +++++++++--------- 8 files changed, 120 insertions(+), 80 deletions(-) diff --git a/src/gallium/drivers/nouveau/nouveau_bo.h b/src/gallium/drivers/nouveau/nouveau_bo.h index 18020e9c652..65b138283c4 100644 --- a/src/gallium/drivers/nouveau/nouveau_bo.h +++ b/src/gallium/drivers/nouveau/nouveau_bo.h @@ -35,6 +35,8 @@ #define NOUVEAU_BO_HIGH (1 << 7) #define NOUVEAU_BO_OR (1 << 8) #define NOUVEAU_BO_LOCAL (1 << 9) +#define NOUVEAU_BO_TILED (1 << 10) +#define NOUVEAU_BO_ZTILE (1 << 11) #define NOUVEAU_BO_DUMMY (1 << 31) struct nouveau_bo { diff --git a/src/gallium/drivers/nouveau/nouveau_stateobj.h b/src/gallium/drivers/nouveau/nouveau_stateobj.h index 78b27380702..998ec2d4ad4 100644 --- a/src/gallium/drivers/nouveau/nouveau_stateobj.h +++ b/src/gallium/drivers/nouveau/nouveau_stateobj.h @@ -136,6 +136,9 @@ so_emit_reloc_markers(struct nouveau_winsys *nvws, struct nouveau_stateobj *so) struct nouveau_pushbuf *pb = nvws->channel->pushbuf; unsigned i; + if (!so) + return; + i = so->cur_reloc << 1; if (nvws->channel->pushbuf->remaining < i) nvws->push_flush(nvws, i, NULL); diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index cf5a071a8d6..88ef685bb1f 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -44,7 +44,7 @@ nv50_state_validate_fb(struct nv50_context *nv50) so_data(so, 0xe6); break; } - so_data(so, 0x00000040); + so_data(so, 0x00000000); so_data(so, 0x00000000); so_method(so, tesla, 0x1224, 1); @@ -82,7 +82,7 @@ nv50_state_validate_fb(struct nv50_context *nv50) so_data(so, 0x16); break; } - so_data(so, 0x00000040); + so_data(so, 0x00000000); so_data(so, 0x00000000); so_method(so, tesla, 0x1538, 1); @@ -265,7 +265,7 @@ scissor_uptodate: so_data (so, 0x2a712488); so_reloc(so, mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW, 0, 0); - so_data (so, 0xd0c05000); + so_data (so, 0xd0005000); so_data (so, 0x00300000); so_data (so, mt->base.width[0]); so_data (so, (mt->base.depth[0] << 16) | diff --git a/src/gallium/winsys/dri/nouveau/nouveau_bo.c b/src/gallium/winsys/dri/nouveau/nouveau_bo.c index 57f5b7d1ae1..b5942994d94 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_bo.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_bo.c @@ -182,6 +182,13 @@ nouveau_bo_new(struct nouveau_device *dev, uint32_t flags, int align, nvbo->drm.alignment = align; nvbo->refcount = 1; + if (flags & NOUVEAU_BO_TILED) { + nvbo->tiled = 1; + if (flags & NOUVEAU_BO_ZTILE) + nvbo->tiled |= 2; + flags &= ~NOUVEAU_BO_TILED; + } + ret = nouveau_bo_set_status(&nvbo->base, flags); if (ret) { free(nvbo); @@ -332,6 +339,12 @@ nouveau_bo_set_status(struct nouveau_bo *bo, uint32_t flags) else if (flags & NOUVEAU_BO_GART) new_flags |= (NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI); + + if (nvbo->tiled && flags) { + new_flags |= NOUVEAU_MEM_TILE; + if (nvbo->tiled & 2) + new_flags |= NOUVEAU_MEM_TILE_ZETA; + } if (new_flags) { ret = nouveau_mem_alloc(bo->device, bo->size, @@ -347,9 +360,12 @@ nouveau_bo_set_status(struct nouveau_bo *bo, uint32_t flags) /* Copy old -> new */ /*XXX: use M2MF */ if (nvbo->sysmem || nvbo->map) { + struct nouveau_pushbuf_bo *pbo = nvbo->pending; + nvbo->pending = NULL; nouveau_bo_map(bo, NOUVEAU_BO_RD); memcpy(new_map, bo->map, bo->size); nouveau_bo_unmap(bo); + nvbo->pending = pbo; } /* Free old memory */ diff --git a/src/gallium/winsys/dri/nouveau/nouveau_drmif.h b/src/gallium/winsys/dri/nouveau/nouveau_drmif.h index 5829f649cd5..dcd6a5eb0a4 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_drmif.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_drmif.h @@ -259,6 +259,7 @@ struct nouveau_bo_priv { uint64_t offset; uint64_t flags; + int tiled; }; #define nouveau_bo(n) ((struct nouveau_bo_priv *)(n)) diff --git a/src/gallium/winsys/dri/nouveau/nouveau_screen.c b/src/gallium/winsys/dri/nouveau/nouveau_screen.c index b15ee7509cc..df1fe7e69b4 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_screen.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_screen.c @@ -13,7 +13,7 @@ #include "nouveau_screen.h" #include "nouveau_swapbuffers.h" -#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 10 +#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 11 #error nouveau_drm.h version does not match expected version #endif diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c index ba5dd2eea4b..765ea36f881 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c @@ -76,6 +76,18 @@ nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment, if (usage & NOUVEAU_BUFFER_USAGE_TEXTURE) flags |= NOUVEAU_BO_GART; flags |= NOUVEAU_BO_VRAM; + + switch (dev->chipset & 0xf0) { + case 0x50: + case 0x80: + case 0x90: + flags |= NOUVEAU_BO_TILED; + if (usage & NOUVEAU_BUFFER_USAGE_ZETA) + flags |= NOUVEAU_BO_ZTILE; + break; + default: + break; + } } if (usage & PIPE_BUFFER_USAGE_VERTEX) { diff --git a/src/gallium/winsys/dri/nouveau/nv50_surface.c b/src/gallium/winsys/dri/nouveau/nv50_surface.c index cf76d76cf52..c8ab7f690f3 100644 --- a/src/gallium/winsys/dri/nouveau/nv50_surface.c +++ b/src/gallium/winsys/dri/nouveau/nv50_surface.c @@ -22,52 +22,70 @@ nv50_format(enum pipe_format format) } static int -nv50_surface_copy_prep(struct nouveau_context *nv, - struct pipe_surface *dst, struct pipe_surface *src) +nv50_surface_set(struct nouveau_context *nv, struct pipe_surface *surf, int dst) { struct nouveau_channel *chan = nv->nvc->channel; struct nouveau_grobj *eng2d = nv->nvc->Nv2D; - int surf_format; - - assert(src->format == dst->format); + struct nouveau_bo *bo = nouveau_buffer(surf->buffer)->bo; + int surf_format, mthd = dst ? NV50_2D_DST_FORMAT : NV50_2D_SRC_FORMAT; + int flags = NOUVEAU_BO_VRAM | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD); + + surf_format = nv50_format(surf->format); + if (surf_format < 0) + return 1; + + if (!nouveau_bo(bo)->tiled) { + BEGIN_RING(chan, eng2d, mthd, 2); + OUT_RING (chan, surf_format); + OUT_RING (chan, 1); + BEGIN_RING(chan, eng2d, mthd + 0x14, 5); + OUT_RING (chan, surf->stride); + OUT_RING (chan, surf->width); + OUT_RING (chan, surf->height); + OUT_RELOCh(chan, bo, surf->offset, flags); + OUT_RELOCl(chan, bo, surf->offset, flags); + } else { + BEGIN_RING(chan, eng2d, mthd, 5); + OUT_RING (chan, surf_format); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + OUT_RING (chan, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, eng2d, mthd + 0x18, 4); + OUT_RING (chan, surf->width); + OUT_RING (chan, surf->height); + OUT_RELOCh(chan, bo, surf->offset, flags); + OUT_RELOCl(chan, bo, surf->offset, flags); + } + +#if 0 + if (dst) { + BEGIN_RING(chan, eng2d, NV50_2D_CLIP_X, 4); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + OUT_RING (chan, surf->width); + OUT_RING (chan, surf->height); + } +#endif + + return 0; +} - surf_format = nv50_format(dst->format); - assert(surf_format >= 0); +static int +nv50_surface_copy_prep(struct nouveau_context *nv, + struct pipe_surface *dst, struct pipe_surface *src) +{ + int ret; - BEGIN_RING(chan, eng2d, NV50_2D_DMA_IN_MEMORY0, 2); - OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo, - NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + assert(src->format == dst->format); - BEGIN_RING(chan, eng2d, NV50_2D_DST_FORMAT, 2); - OUT_RING (chan, surf_format); - OUT_RING (chan, 1); - BEGIN_RING(chan, eng2d, NV50_2D_DST_PITCH, 5); - OUT_RING (chan, dst->stride); - OUT_RING (chan, dst->width); - OUT_RING (chan, dst->height); - OUT_RELOCh(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(chan, eng2d, NV50_2D_CLIP_X, 4); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, dst->width); - OUT_RING (chan, dst->height); + ret = nv50_surface_set(nv, dst, 1); + if (ret) + return ret; - BEGIN_RING(chan, eng2d, NV50_2D_SRC_FORMAT, 2); - OUT_RING (chan, surf_format); - OUT_RING (chan, 1); - BEGIN_RING(chan, eng2d, NV50_2D_SRC_PITCH, 5); - OUT_RING (chan, src->stride); - OUT_RING (chan, src->width); - OUT_RING (chan, src->height); - OUT_RELOCh(chan, nouveau_buffer(src->buffer)->bo, src->offset, - NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCl(chan, nouveau_buffer(src->buffer)->bo, src->offset, - NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + ret = nv50_surface_set(nv, src, 0); + if (ret) + return ret; return 0; } @@ -79,17 +97,19 @@ nv50_surface_copy(struct nouveau_context *nv, unsigned dx, unsigned dy, struct nouveau_channel *chan = nv->nvc->channel; struct nouveau_grobj *eng2d = nv->nvc->Nv2D; - BEGIN_RING(chan, eng2d, 0x0110, 1); + BEGIN_RING(chan, eng2d, 0x088c, 1); OUT_RING (chan, 0); - BEGIN_RING(chan, eng2d, NV50_2D_BLIT_DST_X, 12); + BEGIN_RING(chan, eng2d, NV50_2D_BLIT_DST_X, 4); OUT_RING (chan, dx); OUT_RING (chan, dy); OUT_RING (chan, w); OUT_RING (chan, h); + BEGIN_RING(chan, eng2d, 0x08c0, 4); OUT_RING (chan, 0); OUT_RING (chan, 1); OUT_RING (chan, 0); OUT_RING (chan, 1); + BEGIN_RING(chan, eng2d, 0x08d0, 4); OUT_RING (chan, 0); OUT_RING (chan, sx); OUT_RING (chan, 0); @@ -109,35 +129,15 @@ nv50_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, { struct nouveau_channel *chan = nv->nvc->channel; struct nouveau_grobj *eng2d = nv->nvc->Nv2D; - int surf_format, rect_format; - - surf_format = nv50_format(dst->format); - if (surf_format < 0) - return 1; + int rect_format, ret; rect_format = nv50_format(dst->format); if (rect_format < 0) return 1; - BEGIN_RING(chan, eng2d, NV50_2D_DMA_IN_MEMORY1, 1); - OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(chan, eng2d, NV50_2D_DST_FORMAT, 2); - OUT_RING (chan, surf_format); - OUT_RING (chan, 1); - BEGIN_RING(chan, eng2d, NV50_2D_DST_PITCH, 5); - OUT_RING (chan, dst->stride); - OUT_RING (chan, dst->width); - OUT_RING (chan, dst->height); - OUT_RELOCh(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(chan, eng2d, NV50_2D_CLIP_X, 4); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, dst->width); - OUT_RING (chan, dst->height); + ret = nv50_surface_set(nv, dst, 1); + if (ret) + return ret; BEGIN_RING(chan, eng2d, 0x0580, 3); OUT_RING (chan, 4); @@ -151,27 +151,33 @@ nv50_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, OUT_RING (chan, dy + h); FIRE_RING(chan); - return 0; } int nouveau_surface_channel_create_nv50(struct nouveau_channel_context *nvc) { + struct nouveau_channel *chan = nvc->channel; + struct nouveau_grobj *eng2d = NULL; int ret; - ret = nouveau_grobj_alloc(nvc->channel, nvc->next_handle++, NV50_2D, - &nvc->Nv2D); + ret = nouveau_grobj_alloc(chan, nvc->next_handle++, NV50_2D, &eng2d); if (ret) return ret; - BIND_RING (nvc->channel, nvc->Nv2D, nvc->next_subchannel++); - BEGIN_RING(nvc->channel, nvc->Nv2D, NV50_2D_DMA_NOTIFY, 1); - OUT_RING (nvc->channel, nvc->sync_notifier->handle); - BEGIN_RING(nvc->channel, nvc->Nv2D, NV50_2D_DMA_IN_MEMORY0, 2); - OUT_RING (nvc->channel, nvc->channel->vram->handle); - OUT_RING (nvc->channel, nvc->channel->vram->handle); - BEGIN_RING(nvc->channel, nvc->Nv2D, NV50_2D_OPERATION, 1); - OUT_RING (nvc->channel, NV50_2D_OPERATION_SRCCOPY); + nvc->Nv2D = eng2d; + + BIND_RING (chan, eng2d, nvc->next_subchannel++); + BEGIN_RING(chan, eng2d, NV50_2D_DMA_NOTIFY, 4); + OUT_RING (chan, nvc->sync_notifier->handle); + OUT_RING (chan, chan->vram->handle); + OUT_RING (chan, chan->vram->handle); + OUT_RING (chan, chan->vram->handle); + BEGIN_RING(chan, eng2d, NV50_2D_OPERATION, 1); + OUT_RING (chan, NV50_2D_OPERATION_SRCCOPY); + BEGIN_RING(chan, eng2d, 0x0290, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, eng2d, 0x0888, 1); + OUT_RING (chan, 1); return 0; } -- 2.30.2