From 84cc07dc89c0ebce4ad55b4b3684d4420a202683 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 29 Feb 2008 15:03:57 +1100 Subject: nouveau: implement pipe_screen Untested on NV3x/NV5x. Quite possibly broken. --- src/gallium/drivers/nv50/nv50_screen.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/gallium/drivers/nv50/nv50_screen.h (limited to 'src/gallium/drivers/nv50/nv50_screen.h') diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h new file mode 100644 index 0000000000..45ebbb8051 --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_screen.h @@ -0,0 +1,20 @@ +#ifndef __NV50_SCREEN_H__ +#define __NV50_SCREEN_H__ + +#include "pipe/p_screen.h" + +struct nv50_screen { + struct pipe_screen pipe; + unsigned chipset; +}; + +static INLINE struct nv50_screen * +nv50_screen(struct pipe_screen *screen) +{ + return (struct nv50_screen *)screen; +} + +extern struct pipe_screen * +nv50_screen_create(struct pipe_winsys *winsys, unsigned chipset); + +#endif -- cgit v1.2.3 From baaae562f02563c5966b857c61b3eae7341950e3 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 29 Feb 2008 22:54:40 +1100 Subject: nouveau: hand nouveau_winsys in with pipe_screen init --- src/gallium/drivers/nouveau/nouveau_winsys.h | 15 +++++++++------ src/gallium/drivers/nv30/nv30_context.c | 3 ++- src/gallium/drivers/nv30/nv30_screen.c | 4 +++- src/gallium/drivers/nv30/nv30_screen.h | 5 ++--- src/gallium/drivers/nv40/nv40_context.c | 3 ++- src/gallium/drivers/nv40/nv40_screen.c | 4 +++- src/gallium/drivers/nv40/nv40_screen.h | 5 ++--- src/gallium/drivers/nv50/nv50_context.c | 3 ++- src/gallium/drivers/nv50/nv50_screen.c | 4 +++- src/gallium/drivers/nv50/nv50_screen.h | 5 ++--- src/gallium/winsys/dri/nouveau/nouveau_winsys.c | 8 ++++---- 11 files changed, 34 insertions(+), 25 deletions(-) (limited to 'src/gallium/drivers/nv50/nv50_screen.h') diff --git a/src/gallium/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h index 98d95e94a5..11ca7e80dd 100644 --- a/src/gallium/drivers/nouveau/nouveau_winsys.h +++ b/src/gallium/drivers/nouveau/nouveau_winsys.h @@ -50,21 +50,24 @@ struct nouveau_winsys { }; extern struct pipe_screen * -nv30_screen_create(struct pipe_winsys *ws, unsigned chipset); +nv30_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *, + unsigned chipset); extern struct pipe_context * -nv30_create(struct pipe_screen *, struct nouveau_winsys *); +nv30_create(struct pipe_screen *); extern struct pipe_screen * -nv40_screen_create(struct pipe_winsys *ws, unsigned chipset); +nv40_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *, + unsigned chipset); extern struct pipe_context * -nv40_create(struct pipe_screen *, struct nouveau_winsys *); +nv40_create(struct pipe_screen *); extern struct pipe_screen * -nv50_screen_create(struct pipe_winsys *ws, unsigned chipset); +nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *, + unsigned chipset); extern struct pipe_context * -nv50_create(struct pipe_screen *, struct nouveau_winsys *); +nv50_create(struct pipe_screen *); #endif diff --git a/src/gallium/drivers/nv30/nv30_context.c b/src/gallium/drivers/nv30/nv30_context.c index b8452e23b1..522fb13226 100644 --- a/src/gallium/drivers/nv30/nv30_context.c +++ b/src/gallium/drivers/nv30/nv30_context.c @@ -265,9 +265,10 @@ nv30_init_hwctx(struct nv30_context *nv30, int rankine_class) #define NV35TCL_CHIPSET_3X_MASK 0x000001e0 struct pipe_context * -nv30_create(struct pipe_screen *screen, struct nouveau_winsys *nvws) +nv30_create(struct pipe_screen *screen) { struct pipe_winsys *pipe_winsys = screen->winsys; + struct nouveau_winsys *nvws = nv30_screen(screen)->nvws; unsigned chipset = nv30_screen(screen)->chipset; struct nv30_context *nv30; int rankine_class = 0, ret; diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c index 6d64025528..39f2ac1af5 100644 --- a/src/gallium/drivers/nv30/nv30_screen.c +++ b/src/gallium/drivers/nv30/nv30_screen.c @@ -125,7 +125,8 @@ nv30_screen_destroy(struct pipe_screen *screen) } struct pipe_screen * -nv30_screen_create(struct pipe_winsys *winsys, unsigned chipset) +nv30_screen_create(struct pipe_winsys *winsys, struct nouveau_winsys *nvws, + unsigned chipset) { struct nv30_screen *nv30screen = CALLOC_STRUCT(nv30_screen); @@ -133,6 +134,7 @@ nv30_screen_create(struct pipe_winsys *winsys, unsigned chipset) return NULL; nv30screen->chipset = chipset; + nv30screen->nvws = nvws; nv30screen->screen.winsys = winsys; diff --git a/src/gallium/drivers/nv30/nv30_screen.h b/src/gallium/drivers/nv30/nv30_screen.h index e55242fbf7..f878f81e11 100644 --- a/src/gallium/drivers/nv30/nv30_screen.h +++ b/src/gallium/drivers/nv30/nv30_screen.h @@ -5,6 +5,8 @@ struct nv30_screen { struct pipe_screen screen; + + struct nouveau_winsys *nvws; unsigned chipset; }; @@ -14,7 +16,4 @@ nv30_screen(struct pipe_screen *screen) return (struct nv30_screen *)screen; } -extern struct pipe_screen * -nv30_screen_create(struct pipe_winsys *winsys, unsigned chipset); - #endif diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c index a7f64c6e9e..679c2ddc6b 100644 --- a/src/gallium/drivers/nv40/nv40_context.c +++ b/src/gallium/drivers/nv40/nv40_context.c @@ -196,11 +196,12 @@ nv40_destroy(struct pipe_context *pipe) } struct pipe_context * -nv40_create(struct pipe_screen *pscreen, struct nouveau_winsys *nvws) +nv40_create(struct pipe_screen *pscreen) { struct pipe_winsys *ws = pscreen->winsys; struct nv40_context *nv40; unsigned chipset = nv40_screen(pscreen)->chipset; + struct nouveau_winsys *nvws = nv40_screen(pscreen)->nvws; nv40 = CALLOC(1, sizeof(struct nv40_context)); if (!nv40) diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index 1941598c64..66e84b6890 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -125,7 +125,8 @@ nv40_screen_destroy(struct pipe_screen *pscreen) } struct pipe_screen * -nv40_screen_create(struct pipe_winsys *ws, unsigned chipset) +nv40_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws, + unsigned chipset) { struct nv40_screen *screen = CALLOC_STRUCT(nv40_screen); @@ -133,6 +134,7 @@ nv40_screen_create(struct pipe_winsys *ws, unsigned chipset) return NULL; screen->chipset = chipset; + screen->nvws = nvws; screen->pipe.winsys = ws; screen->pipe.destroy = nv40_screen_destroy; diff --git a/src/gallium/drivers/nv40/nv40_screen.h b/src/gallium/drivers/nv40/nv40_screen.h index b30a6c5ad5..88b8fed26c 100644 --- a/src/gallium/drivers/nv40/nv40_screen.h +++ b/src/gallium/drivers/nv40/nv40_screen.h @@ -5,6 +5,8 @@ struct nv40_screen { struct pipe_screen pipe; + + struct nouveau_winsys *nvws; unsigned chipset; }; @@ -14,7 +16,4 @@ nv40_screen(struct pipe_screen *screen) return (struct nv40_screen *)screen; } -extern struct pipe_screen * -nv40_screen_create(struct pipe_winsys *winsys, unsigned chipset); - #endif diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c index 98022809a6..e5054e34f6 100644 --- a/src/gallium/drivers/nv50/nv50_context.c +++ b/src/gallium/drivers/nv50/nv50_context.c @@ -56,9 +56,10 @@ nv50_init_hwctx(struct nv50_context *nv50, int tesla_class) #define GRCLASS5097_CHIPSETS 0x00000000 #define GRCLASS8297_CHIPSETS 0x00000010 struct pipe_context * -nv50_create(struct pipe_screen *pscreen, struct nouveau_winsys *nvws) +nv50_create(struct pipe_screen *pscreen) { struct pipe_winsys *pipe_winsys = pscreen->winsys; + struct nouveau_winsys *nvws = nv50_screen(pscreen)->nvws; unsigned chipset = nv50_screen(pscreen)->chipset; struct nv50_context *nv50; int tesla_class, ret; diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 8bf82eb0bc..f091779e3b 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -90,7 +90,8 @@ nv50_screen_destroy(struct pipe_screen *pscreen) } struct pipe_screen * -nv50_screen_create(struct pipe_winsys *ws, unsigned chipset) +nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws, + unsigned chipset) { struct nv50_screen *screen = CALLOC_STRUCT(nv50_screen); @@ -98,6 +99,7 @@ nv50_screen_create(struct pipe_winsys *ws, unsigned chipset) return NULL; screen->chipset = chipset; + screen->nvws = nvws; screen->pipe.winsys = ws; diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h index 45ebbb8051..d664816a03 100644 --- a/src/gallium/drivers/nv50/nv50_screen.h +++ b/src/gallium/drivers/nv50/nv50_screen.h @@ -5,6 +5,8 @@ struct nv50_screen { struct pipe_screen pipe; + + struct nouveau_winsys *nvws; unsigned chipset; }; @@ -14,7 +16,4 @@ nv50_screen(struct pipe_screen *screen) return (struct nv50_screen *)screen; } -extern struct pipe_screen * -nv50_screen_create(struct pipe_winsys *winsys, unsigned chipset); - #endif diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c index 1d758e29e7..529f577181 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c @@ -73,9 +73,9 @@ nouveau_pipe_create(struct nouveau_context *nv) { struct nouveau_winsys *nvws = CALLOC_STRUCT(nouveau_winsys); struct pipe_screen *(*hws_create)(struct pipe_winsys *, + struct nouveau_winsys *, unsigned chipset); - struct pipe_context *(*hw_create)(struct pipe_screen *, - struct nouveau_winsys *); + struct pipe_context *(*hw_create)(struct pipe_screen *); struct pipe_winsys *ws; struct pipe_screen *pscreen; @@ -126,7 +126,7 @@ nouveau_pipe_create(struct nouveau_context *nv) nvws->surface_fill = nouveau_pipe_surface_fill; ws = nouveau_create_pipe_winsys(nv); - pscreen = hws_create(ws, nv->chipset); - return hw_create(pscreen, nvws); + pscreen = hws_create(ws, nvws, nv->chipset); + return hw_create(pscreen); } -- cgit v1.2.3 From b2e48f848496d5e315e536688c8c33dfb1fab7eb Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 12 Mar 2008 02:39:13 +1100 Subject: nv50: convert to hwctx-in-screen as nv40 is --- src/gallium/drivers/nv50/nv50_context.c | 61 ++++----------------------------- src/gallium/drivers/nv50/nv50_context.h | 11 +++--- src/gallium/drivers/nv50/nv50_screen.c | 49 +++++++++++++++++++++++++- src/gallium/drivers/nv50/nv50_screen.h | 5 +++ src/gallium/drivers/nv50/nv50_surface.c | 4 +-- 5 files changed, 67 insertions(+), 63 deletions(-) (limited to 'src/gallium/drivers/nv50/nv50_screen.h') diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c index c937b8de6d..980d066c84 100644 --- a/src/gallium/drivers/nv50/nv50_context.c +++ b/src/gallium/drivers/nv50/nv50_context.c @@ -10,10 +10,11 @@ static void nv50_flush(struct pipe_context *pipe, unsigned flags) { struct nv50_context *nv50 = (struct nv50_context *)pipe; - struct nouveau_winsys *nvws = nv50->nvws; + struct nv50_screen *screen = nv50->screen; + struct nouveau_winsys *nvws = screen->nvws; if (flags & PIPE_FLUSH_WAIT) { - nvws->notifier_reset(nv50->sync, 0); + nvws->notifier_reset(screen->sync, 0); BEGIN_RING(tesla, 0x104, 1); OUT_RING (0); BEGIN_RING(tesla, 0x100, 1); @@ -23,7 +24,7 @@ nv50_flush(struct pipe_context *pipe, unsigned flags) FIRE_RING(); if (flags & PIPE_FLUSH_WAIT) - nvws->notifier_wait(nv50->sync, 0, 0, 2000); + nvws->notifier_wait(screen->sync, 0, 0, 2000); } static void @@ -35,66 +36,18 @@ nv50_destroy(struct pipe_context *pipe) free(nv50); } -static boolean -nv50_init_hwctx(struct nv50_context *nv50, int tesla_class) -{ - struct nouveau_winsys *nvws = nv50->nvws; - int ret; - - if ((ret = nvws->grobj_alloc(nvws, tesla_class, &nv50->tesla))) { - NOUVEAU_ERR("Error creating 3D object: %d\n", ret); - return FALSE; - } - - BEGIN_RING(tesla, NV50TCL_DMA_NOTIFY, 1); - OUT_RING (nv50->sync->handle); - - FIRE_RING (); - return TRUE; -} - -#define GRCLASS5097_CHIPSETS 0x00000000 -#define GRCLASS8297_CHIPSETS 0x00000010 struct pipe_context * nv50_create(struct pipe_screen *pscreen, unsigned pctx_id) { struct pipe_winsys *pipe_winsys = pscreen->winsys; - struct nouveau_winsys *nvws = nv50_screen(pscreen)->nvws; - unsigned chipset = nv50_screen(pscreen)->chipset; + struct nv50_screen *screen = nv50_screen(pscreen); struct nv50_context *nv50; - int tesla_class, ret; - - if ((chipset & 0xf0) != 0x50 && (chipset & 0xf0) != 0x80) { - NOUVEAU_ERR("Not a G8x chipset\n"); - return NULL; - } - - if (GRCLASS5097_CHIPSETS & (1 << (chipset & 0x0f))) { - tesla_class = 0x5097; - } else - if (GRCLASS8297_CHIPSETS & (1 << (chipset & 0x0f))) { - tesla_class = 0x8297; - } else { - NOUVEAU_ERR("Unknown G8x chipset: NV%02x\n", chipset); - return NULL; - } nv50 = CALLOC_STRUCT(nv50_context); if (!nv50) return NULL; - nv50->chipset = chipset; - nv50->nvws = nvws; - - if ((ret = nvws->notifier_alloc(nvws, 1, &nv50->sync))) { - NOUVEAU_ERR("Error creating notifier object: %d\n", ret); - free(nv50); - return NULL; - } - - if (!nv50_init_hwctx(nv50, tesla_class)) { - free(nv50); - return NULL; - } + nv50->screen = screen; + nv50->pctx_id = pctx_id; nv50->pipe.winsys = pipe_winsys; nv50->pipe.screen = pscreen; diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index a529bf3c3e..e2656bd539 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -11,10 +11,11 @@ #include "nouveau/nouveau_gldefs.h" #define NOUVEAU_PUSH_CONTEXT(ctx) \ - struct nv50_context *ctx = nv50 + struct nv50_screen *ctx = nv50->screen #include "nouveau/nouveau_push.h" #include "nv50_state.h" +#include "nv50_screen.h" #define NOUVEAU_ERR(fmt, args...) \ fprintf(stderr, "%s:%d - "fmt, __func__, __LINE__, ##args); @@ -23,13 +24,11 @@ struct nv50_context { struct pipe_context pipe; - struct nouveau_winsys *nvws; - struct draw_context *draw; + struct nv50_screen *screen; + unsigned pctx_id; - int chipset; - struct nouveau_grobj *tesla; - struct nouveau_notifier *sync; + struct draw_context *draw; }; diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 77ceb678f2..f8fd11dc5f 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -4,6 +4,11 @@ #include "nv50_context.h" #include "nv50_screen.h" +#include "nouveau/nouveau_stateobj.h" + +#define GRCLASS5097_CHIPSETS 0x00000000 +#define GRCLASS8297_CHIPSETS 0x00000010 + static boolean nv50_screen_is_format_supported(struct pipe_screen *pscreen, enum pipe_format format, uint type) @@ -96,13 +101,55 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws, unsigned chipset) { struct nv50_screen *screen = CALLOC_STRUCT(nv50_screen); + struct nouveau_stateobj *so; + unsigned tesla_class = 0, ret; if (!screen) return NULL; - screen->chipset = chipset; screen->nvws = nvws; + /* 3D object */ + if ((chipset & 0xf0) != 0x50 && (chipset & 0xf0) != 0x80) { + NOUVEAU_ERR("Not a G8x chipset\n"); + nv50_screen_destroy(&screen->pipe); + return NULL; + } + + if (GRCLASS5097_CHIPSETS & (1 << (chipset & 0x0f))) { + tesla_class = 0x5097; + } else + if (GRCLASS8297_CHIPSETS & (1 << (chipset & 0x0f))) { + tesla_class = 0x8297; + } else { + NOUVEAU_ERR("Unknown G8x chipset: NV%02x\n", chipset); + nv50_screen_destroy(&screen->pipe); + return NULL; + } + + ret = nvws->grobj_alloc(nvws, tesla_class, &screen->tesla); + if (ret) { + NOUVEAU_ERR("Error creating 3D object: %d\n", ret); + nv50_screen_destroy(&screen->pipe); + return NULL; + } + + /* Sync notifier */ + ret = nvws->notifier_alloc(nvws, 1, &screen->sync); + if (ret) { + NOUVEAU_ERR("Error creating notifier object: %d\n", ret); + nv50_screen_destroy(&screen->pipe); + return NULL; + } + + /* Static tesla init */ + so = so_new(128, 0); + so_method(so, screen->tesla, NV50TCL_DMA_NOTIFY, 1); + so_data (so, screen->sync->handle); + so_emit(nvws, so); + so_ref(NULL, &so); + nvws->push_flush(nvws->channel, 0); + screen->pipe.winsys = ws; screen->pipe.destroy = nv50_screen_destroy; diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h index d664816a03..6e4120d669 100644 --- a/src/gallium/drivers/nv50/nv50_screen.h +++ b/src/gallium/drivers/nv50/nv50_screen.h @@ -8,6 +8,11 @@ struct nv50_screen { struct nouveau_winsys *nvws; unsigned chipset; + + unsigned cur_pctx; + + struct nouveau_grobj *tesla; + struct nouveau_notifier *sync; }; static INLINE struct nv50_screen * diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c index 39cf675a57..4e294198b0 100644 --- a/src/gallium/drivers/nv50/nv50_surface.c +++ b/src/gallium/drivers/nv50/nv50_surface.c @@ -40,7 +40,7 @@ nv50_surface_copy(struct pipe_context *pipe, unsigned flip, unsigned width, unsigned height) { struct nv50_context *nv50 = (struct nv50_context *)pipe; - struct nouveau_winsys *nvws = nv50->nvws; + struct nouveau_winsys *nvws = nv50->screen->nvws; nvws->surface_copy(nvws, dest, destx, desty, src, srcx, srcy, width, height); @@ -52,7 +52,7 @@ nv50_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest, unsigned height, unsigned value) { struct nv50_context *nv50 = (struct nv50_context *)pipe; - struct nouveau_winsys *nvws = nv50->nvws; + struct nouveau_winsys *nvws = nv50->screen->nvws; nvws->surface_fill(nvws, dest, destx, desty, width, height, value); } -- cgit v1.2.3 From 1ef08564d2a201a422db772a6bb23d1129888304 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 13 May 2008 12:16:35 +1000 Subject: nouveau: remove chipset fields in all nv pipe driver context/screen structs. --- src/gallium/drivers/nouveau/nouveau_winsys.h | 13 +++++-------- src/gallium/drivers/nv10/nv10_context.c | 2 -- src/gallium/drivers/nv10/nv10_context.h | 2 -- src/gallium/drivers/nv10/nv10_screen.c | 8 ++++---- src/gallium/drivers/nv10/nv10_screen.h | 1 - src/gallium/drivers/nv30/nv30_context.c | 2 -- src/gallium/drivers/nv30/nv30_context.h | 2 -- src/gallium/drivers/nv30/nv30_screen.c | 8 ++++---- src/gallium/drivers/nv30/nv30_screen.h | 1 - src/gallium/drivers/nv40/nv40_context.c | 2 -- src/gallium/drivers/nv40/nv40_context.h | 2 -- src/gallium/drivers/nv40/nv40_screen.c | 8 ++++---- src/gallium/drivers/nv40/nv40_screen.h | 1 - src/gallium/drivers/nv50/nv50_screen.c | 8 ++++---- src/gallium/drivers/nv50/nv50_screen.h | 1 - src/gallium/winsys/dri/nouveau/nouveau_winsys.c | 5 ++--- 16 files changed, 23 insertions(+), 43 deletions(-) (limited to 'src/gallium/drivers/nv50/nv50_screen.h') diff --git a/src/gallium/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h index fbde7adc6a..07a41dcf4a 100644 --- a/src/gallium/drivers/nouveau/nouveau_winsys.h +++ b/src/gallium/drivers/nouveau/nouveau_winsys.h @@ -8,6 +8,7 @@ #include "nouveau/nouveau_bo.h" #include "nouveau/nouveau_channel.h" #include "nouveau/nouveau_class.h" +#include "nouveau/nouveau_device.h" #include "nouveau/nouveau_grobj.h" #include "nouveau/nouveau_notifier.h" #include "nouveau/nouveau_resource.h" @@ -56,29 +57,25 @@ struct nouveau_winsys { }; extern struct pipe_screen * -nv10_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *, - unsigned chipset); +nv10_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *); extern struct pipe_context * nv10_create(struct pipe_screen *, unsigned pctx_id); extern struct pipe_screen * -nv30_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *, - unsigned chipset); +nv30_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *); extern struct pipe_context * nv30_create(struct pipe_screen *, unsigned pctx_id); extern struct pipe_screen * -nv40_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *, - unsigned chipset); +nv40_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *); extern struct pipe_context * nv40_create(struct pipe_screen *, unsigned pctx_id); extern struct pipe_screen * -nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *, - unsigned chipset); +nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *); extern struct pipe_context * nv50_create(struct pipe_screen *, unsigned pctx_id); diff --git a/src/gallium/drivers/nv10/nv10_context.c b/src/gallium/drivers/nv10/nv10_context.c index a25c082a5d..79253f8a2b 100644 --- a/src/gallium/drivers/nv10/nv10_context.c +++ b/src/gallium/drivers/nv10/nv10_context.c @@ -264,7 +264,6 @@ nv10_create(struct pipe_screen *pscreen, unsigned pctx_id) struct nv10_screen *screen = nv10_screen(pscreen); struct pipe_winsys *ws = pscreen->winsys; struct nv10_context *nv10; - unsigned chipset = screen->chipset; struct nouveau_winsys *nvws = screen->nvws; nv10 = CALLOC(1, sizeof(struct nv10_context)); @@ -273,7 +272,6 @@ nv10_create(struct pipe_screen *pscreen, unsigned pctx_id) nv10->screen = screen; nv10->pctx_id = pctx_id; - nv10->chipset = chipset; nv10->nvws = nvws; nv10->pipe.winsys = ws; diff --git a/src/gallium/drivers/nv10/nv10_context.h b/src/gallium/drivers/nv10/nv10_context.h index 1b794c1872..433d04dc2a 100644 --- a/src/gallium/drivers/nv10/nv10_context.h +++ b/src/gallium/drivers/nv10/nv10_context.h @@ -43,8 +43,6 @@ struct nv10_context { struct draw_context *draw; - int chipset; - uint32_t dirty; struct nv10_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS]; diff --git a/src/gallium/drivers/nv10/nv10_screen.c b/src/gallium/drivers/nv10/nv10_screen.c index cf6b2fac84..fad96058b8 100644 --- a/src/gallium/drivers/nv10/nv10_screen.c +++ b/src/gallium/drivers/nv10/nv10_screen.c @@ -8,9 +8,10 @@ static const char * nv10_screen_get_name(struct pipe_screen *screen) { struct nv10_screen *nv10screen = nv10_screen(screen); + struct nouveau_device *dev = nv10screen->nvws->channel->device; static char buffer[128]; - snprintf(buffer, sizeof(buffer), "NV%02X", nv10screen->chipset); + snprintf(buffer, sizeof(buffer), "NV%02X", dev->chipset); return buffer; } @@ -129,16 +130,15 @@ nv10_screen_destroy(struct pipe_screen *pscreen) } struct pipe_screen * -nv10_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws, - unsigned chipset) +nv10_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) { struct nv10_screen *screen = CALLOC_STRUCT(nv10_screen); unsigned celsius_class; + unsigned chipset = nvws->channel->device->chipset; int ret; if (!screen) return NULL; - screen->chipset = chipset; screen->nvws = nvws; /* 3D object */ diff --git a/src/gallium/drivers/nv10/nv10_screen.h b/src/gallium/drivers/nv10/nv10_screen.h index 4192fe11ef..3f8750a13f 100644 --- a/src/gallium/drivers/nv10/nv10_screen.h +++ b/src/gallium/drivers/nv10/nv10_screen.h @@ -7,7 +7,6 @@ struct nv10_screen { struct pipe_screen pipe; struct nouveau_winsys *nvws; - unsigned chipset; /* HW graphics objects */ struct nouveau_grobj *celsius; diff --git a/src/gallium/drivers/nv30/nv30_context.c b/src/gallium/drivers/nv30/nv30_context.c index 4b0892971e..7a2fee7875 100644 --- a/src/gallium/drivers/nv30/nv30_context.c +++ b/src/gallium/drivers/nv30/nv30_context.c @@ -44,7 +44,6 @@ nv30_create(struct pipe_screen *pscreen, unsigned pctx_id) struct nv30_screen *screen = nv30_screen(pscreen); struct pipe_winsys *ws = pscreen->winsys; struct nv30_context *nv30; - unsigned chipset = screen->chipset; struct nouveau_winsys *nvws = screen->nvws; nv30 = CALLOC(1, sizeof(struct nv30_context)); @@ -53,7 +52,6 @@ nv30_create(struct pipe_screen *pscreen, unsigned pctx_id) nv30->screen = screen; nv30->pctx_id = pctx_id; - nv30->chipset = chipset; nv30->nvws = nvws; nv30->pipe.winsys = ws; diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index 1a016405e6..f49450f82d 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -85,8 +85,6 @@ struct nv30_context { struct draw_context *draw; - int chipset; - uint32_t dirty; struct nv30_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS]; diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c index 1de4507904..9b0ac55ff8 100644 --- a/src/gallium/drivers/nv30/nv30_screen.c +++ b/src/gallium/drivers/nv30/nv30_screen.c @@ -12,9 +12,10 @@ static const char * nv30_screen_get_name(struct pipe_screen *pscreen) { struct nv30_screen *screen = nv30_screen(pscreen); + struct nouveau_device *dev = screen->nvws->channel->device; static char buffer[128]; - snprintf(buffer, sizeof(buffer), "NV%02X", screen->chipset); + snprintf(buffer, sizeof(buffer), "NV%02X", dev->chipset); return buffer; } @@ -140,17 +141,16 @@ nv30_screen_destroy(struct pipe_screen *pscreen) } struct pipe_screen * -nv30_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws, - unsigned chipset) +nv30_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) { struct nv30_screen *screen = CALLOC_STRUCT(nv30_screen); struct nouveau_stateobj *so; unsigned rankine_class = 0; + unsigned chipset = nvws->channel->device->chipset; int ret, i; if (!screen) return NULL; - screen->chipset = chipset; screen->nvws = nvws; /* 3D object */ diff --git a/src/gallium/drivers/nv30/nv30_screen.h b/src/gallium/drivers/nv30/nv30_screen.h index 56f8776a17..816ece94c4 100644 --- a/src/gallium/drivers/nv30/nv30_screen.h +++ b/src/gallium/drivers/nv30/nv30_screen.h @@ -7,7 +7,6 @@ struct nv30_screen { struct pipe_screen pipe; struct nouveau_winsys *nvws; - unsigned chipset; /* HW graphics objects */ struct nouveau_grobj *rankine; diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c index f9c93f7a2d..d9d9accea8 100644 --- a/src/gallium/drivers/nv40/nv40_context.c +++ b/src/gallium/drivers/nv40/nv40_context.c @@ -38,7 +38,6 @@ nv40_create(struct pipe_screen *pscreen, unsigned pctx_id) struct nv40_screen *screen = nv40_screen(pscreen); struct pipe_winsys *ws = pscreen->winsys; struct nv40_context *nv40; - unsigned chipset = screen->chipset; struct nouveau_winsys *nvws = screen->nvws; nv40 = CALLOC(1, sizeof(struct nv40_context)); @@ -47,7 +46,6 @@ nv40_create(struct pipe_screen *pscreen, unsigned pctx_id) nv40->screen = screen; nv40->pctx_id = pctx_id; - nv40->chipset = chipset; nv40->nvws = nvws; nv40->pipe.winsys = ws; diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 24e8cd2337..77b3da0ab9 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -111,8 +111,6 @@ struct nv40_context { struct draw_context *draw; - int chipset; - /* HW state derived from pipe states */ struct nv40_state state; struct { diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index 7f68539a85..1bf0931e4d 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -12,9 +12,10 @@ static const char * nv40_screen_get_name(struct pipe_screen *pscreen) { struct nv40_screen *screen = nv40_screen(pscreen); + struct nouveau_device *dev = screen->nvws->channel->device; static char buffer[128]; - snprintf(buffer, sizeof(buffer), "NV%02X", screen->chipset); + snprintf(buffer, sizeof(buffer), "NV%02X", dev->chipset); return buffer; } @@ -149,17 +150,16 @@ nv40_screen_destroy(struct pipe_screen *pscreen) } struct pipe_screen * -nv40_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws, - unsigned chipset) +nv40_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) { struct nv40_screen *screen = CALLOC_STRUCT(nv40_screen); struct nouveau_stateobj *so; unsigned curie_class; + unsigned chipset = nvws->channel->device; int ret; if (!screen) return NULL; - screen->chipset = chipset; screen->nvws = nvws; /* 3D object */ diff --git a/src/gallium/drivers/nv40/nv40_screen.h b/src/gallium/drivers/nv40/nv40_screen.h index 3ea78aadfd..c04a1275a0 100644 --- a/src/gallium/drivers/nv40/nv40_screen.h +++ b/src/gallium/drivers/nv40/nv40_screen.h @@ -7,7 +7,6 @@ struct nv40_screen { struct pipe_screen pipe; struct nouveau_winsys *nvws; - unsigned chipset; unsigned cur_pctx; diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index e4ca72c717..d069639dc4 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -45,9 +45,10 @@ static const char * nv50_screen_get_name(struct pipe_screen *pscreen) { struct nv50_screen *screen = nv50_screen(pscreen); + struct nouveau_device *dev = screen->nvws->channel->device; static char buffer[128]; - snprintf(buffer, sizeof(buffer), "NV%02X", screen->chipset); + snprintf(buffer, sizeof(buffer), "NV%02X", dev->chipset); return buffer; } @@ -123,17 +124,16 @@ nv50_screen_destroy(struct pipe_screen *pscreen) } struct pipe_screen * -nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws, - unsigned chipset) +nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) { struct nv50_screen *screen = CALLOC_STRUCT(nv50_screen); struct nouveau_stateobj *so; unsigned tesla_class = 0, ret; + unsigned chipset = nvws->channel->device->chipset; int i; if (!screen) return NULL; - screen->chipset = chipset; screen->nvws = nvws; /* 3D object */ diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h index 6e4120d669..5a2732e37f 100644 --- a/src/gallium/drivers/nv50/nv50_screen.h +++ b/src/gallium/drivers/nv50/nv50_screen.h @@ -7,7 +7,6 @@ struct nv50_screen { struct pipe_screen pipe; struct nouveau_winsys *nvws; - unsigned chipset; unsigned cur_pctx; diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c index 635fd478a9..5eabbc8893 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c @@ -91,8 +91,7 @@ nouveau_pipe_create(struct nouveau_context *nv) struct nouveau_channel_context *nvc = nv->nvc; struct nouveau_winsys *nvws = CALLOC_STRUCT(nouveau_winsys); struct pipe_screen *(*hws_create)(struct pipe_winsys *, - struct nouveau_winsys *, - unsigned chipset); + struct nouveau_winsys *); struct pipe_context *(*hw_create)(struct pipe_screen *, unsigned); struct pipe_winsys *ws; unsigned chipset = nv->nv_screen->device->chipset; @@ -152,7 +151,7 @@ nouveau_pipe_create(struct nouveau_context *nv) ws = nouveau_create_pipe_winsys(nv); if (!nvc->pscreen) - nvc->pscreen = hws_create(ws, nvws, chipset); + nvc->pscreen = hws_create(ws, nvws); nvc->pctx[nv->pctx_id] = hw_create(nvc->pscreen, nv->pctx_id); return nvc->pctx[nv->pctx_id]; } -- cgit v1.2.3 From f722fd937db2f3cacf1947d538c66528fd16eb89 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 1 Jun 2008 22:41:40 +1000 Subject: nv50: import current "state of the art" nv50 code --- src/gallium/drivers/nv50/Makefile | 1 + src/gallium/drivers/nv50/nv50_context.h | 18 + src/gallium/drivers/nv50/nv50_program.c | 742 +++++++++++++++++++++++++ src/gallium/drivers/nv50/nv50_screen.c | 68 ++- src/gallium/drivers/nv50/nv50_screen.h | 3 + src/gallium/drivers/nv50/nv50_state.c | 54 +- src/gallium/drivers/nv50/nv50_state.h | 30 + src/gallium/drivers/nv50/nv50_state_validate.c | 29 +- src/gallium/drivers/nv50/nv50_vbo.c | 85 ++- 9 files changed, 1017 insertions(+), 13 deletions(-) create mode 100644 src/gallium/drivers/nv50/nv50_program.c (limited to 'src/gallium/drivers/nv50/nv50_screen.h') diff --git a/src/gallium/drivers/nv50/Makefile b/src/gallium/drivers/nv50/Makefile index a62a4d961b..2cc6e9de28 100644 --- a/src/gallium/drivers/nv50/Makefile +++ b/src/gallium/drivers/nv50/Makefile @@ -9,6 +9,7 @@ DRIVER_SOURCES = \ nv50_draw.c \ nv50_miptree.c \ nv50_query.c \ + nv50_program.c \ nv50_screen.c \ nv50_state.c \ nv50_state_validate.c \ diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index e68c702dea..d4d716b94b 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -9,6 +9,7 @@ #include "nouveau/nouveau_winsys.h" #include "nouveau/nouveau_gldefs.h" +#include "nouveau/nouveau_stateobj.h" #define NOUVEAU_PUSH_CONTEXT(ctx) \ struct nv50_screen *ctx = nv50->screen @@ -30,6 +31,9 @@ #define NV50_NEW_VIEWPORT (1 << 5) #define NV50_NEW_RASTERIZER (1 << 6) #define NV50_NEW_FRAMEBUFFER (1 << 7) +#define NV50_NEW_VERTPROG (1 << 8) +#define NV50_NEW_FRAGPROG (1 << 9) +#define NV50_NEW_ARRAYS (1 << 10) struct nv50_blend_stateobj { struct pipe_blend_state pipe; @@ -63,6 +67,13 @@ struct nv50_context { struct pipe_scissor_state scissor; struct pipe_viewport_state viewport; struct pipe_framebuffer_state framebuffer; + struct nv50_program *vertprog; + struct nv50_program *fragprog; + struct pipe_buffer *constbuf[PIPE_SHADER_TYPES]; + struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS]; + unsigned vtxbuf_nr; + struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS]; + unsigned vtxelt_nr; }; static INLINE struct nv50_context * @@ -88,11 +99,18 @@ extern boolean nv50_draw_elements(struct pipe_context *pipe, unsigned indexSize, unsigned mode, unsigned start, unsigned count); +extern void nv50_vbo_validate(struct nv50_context *nv50); /* nv50_clear.c */ extern void nv50_clear(struct pipe_context *pipe, struct pipe_surface *ps, unsigned clearValue); +/* nv50_program.c */ +extern void nv50_vertprog_validate(struct nv50_context *nv50); +extern void nv50_fragprog_validate(struct nv50_context *nv50); +extern void nv50_program_destroy(struct nv50_context *nv50, struct nv50_program *p); + +/* nv50_state_validate.c */ extern boolean nv50_state_validate(struct nv50_context *nv50); #endif diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c new file mode 100644 index 0000000000..30953b7d8a --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -0,0 +1,742 @@ +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" +#include "pipe/p_inlines.h" + +#include "pipe/p_shader_tokens.h" +#include "tgsi/util/tgsi_parse.h" +#include "tgsi/util/tgsi_util.h" + +#include "nv50_context.h" +#include "nv50_state.h" + +#define OP_MOV 0x001 +#define OP_RCP 0x009 +#define OP_ADD 0x00b +#define OP_MUL 0x00c +#define NV50_SU_MAX_TEMP 64 + +struct nv50_reg { + enum { + P_TEMP, + P_ATTR, + P_RESULT, + P_CONST, + P_IMMD + } type; + int index; + + int hw; +}; + +struct nv50_pc { + struct nv50_program *p; + + /* hw resources */ + struct nv50_reg *r_temp[NV50_SU_MAX_TEMP]; + + /* tgsi resources */ + struct nv50_reg *temp; + int temp_nr; + struct nv50_reg *attr; + int attr_nr; + struct nv50_reg *result; + int result_nr; + struct nv50_reg *param; + int param_nr; + struct nv50_reg *immd; + float *immd_buf; + int immd_nr; +}; + +static void +alloc_reg(struct nv50_pc *pc, struct nv50_reg *reg) +{ + int i; + + if (reg->type != P_TEMP || reg->hw >= 0) + return; + + for (i = 0; i < NV50_SU_MAX_TEMP; i++) { + if (!(pc->r_temp[i])) { + pc->r_temp[i] = reg; + reg->hw = i; + if (pc->p->cfg.vp.high_temp < (i + 1)) + pc->p->cfg.vp.high_temp = i + 1; + return; + } + } + + assert(0); +} + +static struct nv50_reg * +alloc_temp(struct nv50_pc *pc, struct nv50_reg *dst) +{ + struct nv50_reg *r; + int i; + + if (dst && dst->type == P_TEMP && dst->hw == -1) + return dst; + + for (i = 0; i < NV50_SU_MAX_TEMP; i++) { + if (!pc->r_temp[i]) { + r = CALLOC_STRUCT(nv50_reg); + r->type = P_TEMP; + r->index = -1; + r->hw = i; + pc->r_temp[i] = r; + return r; + } + } + + assert(0); + return NULL; +} + +static void +free_temp(struct nv50_pc *pc, struct nv50_reg *r) +{ + if (r->index == -1) { + FREE(pc->r_temp[r->hw]); + pc->r_temp[r->hw] = NULL; + } +} + +#if 0 +static struct nv50_reg * +constant(struct nv50_pc *pc, int pipe, int c, float v) +{ + struct nv50_reg *r = CALLOC_STRUCT(nv50_reg); + struct nv50_program *p = pc->p; + struct nv50_program_data *pd; + int idx; + + if (pipe >= 0) { + for (idx = 0; idx < p->nr_consts; idx++) { + if (p->consts[idx].index == pipe) + return nv40_sr(NV40SR_CONST, idx); + } + } + + idx = p->nr_consts++; + p->consts = realloc(p->consts, sizeof(*pd) * p->nr_consts); + pd = &p->consts[idx]; + + pd->index = pipe; + pd->component = c; + pd->value = v; + return nv40_sr(NV40SR_CONST, idx); +} +#endif + +static void +emit(struct nv50_pc *pc, unsigned op, struct nv50_reg *dst, + struct nv50_reg *src0, struct nv50_reg *src1, struct nv50_reg *src2) +{ + struct nv50_program *p = pc->p; + struct nv50_reg *tmp = NULL, *tmp2 = NULL; + unsigned inst[2] = { 0, 0 }; + + /* Grr.. Fun restrictions on where attribs can be sourced from.. */ + if (src1 && src1->type == P_ATTR) { + tmp = alloc_temp(pc, dst); + emit(pc, 1, tmp, src1, NULL, NULL); + src1 = tmp; + } + + if (src2 && src2->type == P_ATTR) { + tmp2 = alloc_temp(pc, dst); + emit(pc, 1, tmp2, src2, NULL, NULL); + src2 = tmp2; + } + + /* Get this out of the way first. What type of opcode do we + * want/need to build? + */ + if ((op & 0x3f0) || dst->type == P_RESULT || + (src0 && src0->type == P_ATTR) || src1 || src2) + inst[0] |= 0x00000001; + + if (inst[0] & 0x00000001) { + inst[0] |= ((op & 0xf) << 28); + inst[1] |= ((op >> 4) << 26); + + alloc_reg(pc, dst); + if (dst->type == P_RESULT) + inst[1] |= 0x00000008; + inst[0] |= (dst->hw << 2); + + if (src0) { + if (src0->type == P_ATTR) + inst[1] |= 0x00200000; + else + if (src0->type == P_CONST || src0->type == P_IMMD) + assert(0); + alloc_reg(pc, src0); + inst[0] |= (src0->hw << 9); + } + + if (src1) { + if (src1->type == P_CONST || src1->type == P_IMMD) { + inst[0] |= 0x00800000; /* src1 is const */ + /*XXX: does src1 come from "src2" now? */ + alloc_reg(pc, src1); + inst[0] |= (src1->hw << 16); + } else { + alloc_reg(pc, src1); + if (op == 0xc || op == 0xe) + inst[0] |= (src1->hw << 16); + else + inst[1] |= (src1->hw << 14); + } + } else { + inst[1] |= 0x0003c000; /*XXX FIXME */ + } + + if (src2) { + if (src2->type == P_CONST || src2->type == P_IMMD) { + inst[0] |= 0x01000000; /* src2 is const */ + inst[1] |= (src2->hw << 14); + } else { + alloc_reg(pc, src2); + if (inst[0] & 0x00800000 || op ==0xe) + inst[1] |= (src2->hw << 14); + else + inst[0] |= (src2->hw << 16); + } + } + + /*XXX: FIXME */ + if (op == 0xb || op == 0xc || op == 0x9 || op == 0xe) { + /* 0x04000000 negates arg0 */ + /* 0x08000000 negates arg1 */ + /*XXX: true for !0xb also ? */ + inst[1] |= 0x00000780; + } else { + /* 0x04000000 == arg0 32 bit, otherwise 16 bit */ + inst[1] |= 0x04000780; + } + } else { + inst[0] |= ((op & 0xf) << 28); + + alloc_reg(pc, dst); + inst[0] |= (dst->hw << 2); + + if (src0) { + alloc_reg(pc, src0); + inst[0] |= (src0->hw << 9); + } + + /*XXX: NFI if this even works - probably not.. */ + if (src1) { + alloc_reg(pc, src1); + inst[0] |= (src1->hw << 16); + } + } + + if (tmp) free_temp(pc, tmp); + if (tmp2) free_temp(pc, tmp2); + + if (inst[0] & 1) { + p->insns_nr += 2; + p->insns = realloc(p->insns, sizeof(unsigned) * p->insns_nr); + memcpy(p->insns + (p->insns_nr - 2), inst, sizeof(unsigned)*2); + } else { + p->insns_nr += 1; + p->insns = realloc(p->insns, sizeof(unsigned) * p->insns_nr); + memcpy(p->insns + (p->insns_nr - 1), inst, sizeof(unsigned)); + } +} + +static struct nv50_reg * +tgsi_dst(struct nv50_pc *pc, int c, const struct tgsi_full_dst_register *dst) +{ + switch (dst->DstRegister.File) { + case TGSI_FILE_TEMPORARY: + return &pc->temp[dst->DstRegister.Index * 4 + c]; + case TGSI_FILE_OUTPUT: + return &pc->result[dst->DstRegister.Index * 4 + c]; + case TGSI_FILE_NULL: + return NULL; + default: + break; + } + + return NULL; +} + +static struct nv50_reg * +tgsi_src(struct nv50_pc *pc, int c, const struct tgsi_full_src_register *src) +{ + /* Handle swizzling */ + switch (c) { + case 0: c = src->SrcRegister.SwizzleX; break; + case 1: c = src->SrcRegister.SwizzleY; break; + case 2: c = src->SrcRegister.SwizzleZ; break; + case 3: c = src->SrcRegister.SwizzleW; break; + default: + assert(0); + } + + switch (src->SrcRegister.File) { + case TGSI_FILE_INPUT: + return &pc->attr[src->SrcRegister.Index * 4 + c]; + case TGSI_FILE_TEMPORARY: + return &pc->temp[src->SrcRegister.Index * 4 + c]; + case TGSI_FILE_CONSTANT: + return &pc->param[src->SrcRegister.Index * 4 + c]; + case TGSI_FILE_IMMEDIATE: + return &pc->immd[src->SrcRegister.Index * 4 + c]; + default: + break; + } + + return NULL; +} + +static boolean +nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) +{ + const struct tgsi_full_instruction *inst = &tok->FullInstruction; + struct nv50_reg *dst[4], *src[3][4], *none = NULL, *tmp; + unsigned mask; + int i, c; + + NOUVEAU_ERR("insn %p\n", tok); + + mask = inst->FullDstRegisters[0].DstRegister.WriteMask; + + for (c = 0; c < 4; c++) { + if (mask & (1 << c)) + dst[c] = tgsi_dst(pc, c, &inst->FullDstRegisters[0]); + else + dst[c] = NULL; + } + + for (i = 0; i < inst->Instruction.NumSrcRegs; i++) { + for (c = 0; c < 4; c++) + src[i][c] = tgsi_src(pc, c, &inst->FullSrcRegisters[i]); + } + + switch (inst->Instruction.Opcode) { + case TGSI_OPCODE_ADD: + for (c = 0; c < 4; c++) { + if (mask & (1 << c)) { + emit(pc, 0x0b, dst[c], + src[0][c], src[1][c], none); + } + } + break; + case TGSI_OPCODE_DP3: + tmp = alloc_temp(pc, NULL); + emit(pc, 0x0c, tmp, src[0][0], src[1][0], NULL); + emit(pc, 0x0e, tmp, src[0][1], src[1][1], tmp); + emit(pc, 0x0e, tmp, src[0][2], src[1][2], tmp); + for (c = 0; c < 4; c++) { + if (mask & (1 << c)) + emit(pc, 0x01, dst[c], tmp, none, none); + } + free_temp(pc, tmp); + break; + case TGSI_OPCODE_DP4: + tmp = alloc_temp(pc, NULL); + emit(pc, 0x0c, tmp, src[0][0], src[1][0], NULL); + emit(pc, 0x0e, tmp, src[0][1], src[1][1], tmp); + emit(pc, 0x0e, tmp, src[0][2], src[1][2], tmp); + emit(pc, 0x0e, tmp, src[0][3], src[1][3], tmp); + for (c = 0; c < 4; c++) { + if (mask & (1 << c)) + emit(pc, 0x01, dst[c], tmp, none, none); + } + free_temp(pc, tmp); + break; + case TGSI_OPCODE_MAD: + for (c = 0; c < 4; c++) { + if (mask & (1 << c)) + emit(pc, 0x0e, dst[c], + src[0][c], src[1][c], src[2][c]); + } + break; + case TGSI_OPCODE_MOV: + for (c = 0; c < 4; c++) { + if (mask & (1 << c)) + emit(pc, 0x01, dst[c], src[0][c], none, none); + } + break; + case TGSI_OPCODE_MUL: + for (c = 0; c < 4; c++) { + if (mask & (1 << c)) + emit(pc, 0x0c, dst[c], + src[0][c], src[1][c], none); + } + break; + case TGSI_OPCODE_RCP: + for (c = 0; c < 4; c++) { + if (mask & (1 << c)) + emit(pc, 0x09, dst[c], + src[0][c], none, none); + } + break; + case TGSI_OPCODE_END: + break; + default: + NOUVEAU_ERR("invalid opcode %d\n", inst->Instruction.Opcode); + return FALSE; + } + + return TRUE; +} + +static boolean +nv50_program_tx_prep(struct nv50_pc *pc) +{ + struct tgsi_parse_context p; + boolean ret = FALSE; + unsigned i, c; + + tgsi_parse_init(&p, pc->p->pipe.tokens); + while (!tgsi_parse_end_of_tokens(&p)) { + const union tgsi_full_token *tok = &p.FullToken; + + tgsi_parse_token(&p); + switch (tok->Token.Type) { + case TGSI_TOKEN_TYPE_IMMEDIATE: + { + const struct tgsi_full_immediate *imm = + &p.FullToken.FullImmediate; + + pc->immd_nr++; + pc->immd_buf = realloc(pc->immd_buf, 4 * pc->immd_nr * + sizeof(float)); + pc->immd_buf[4 * (pc->immd_nr - 1) + 0] = + imm->u.ImmediateFloat32[0].Float; + pc->immd_buf[4 * (pc->immd_nr - 1) + 1] = + imm->u.ImmediateFloat32[1].Float; + pc->immd_buf[4 * (pc->immd_nr - 1) + 2] = + imm->u.ImmediateFloat32[2].Float; + pc->immd_buf[4 * (pc->immd_nr - 1) + 3] = + imm->u.ImmediateFloat32[3].Float; + } + break; + case TGSI_TOKEN_TYPE_DECLARATION: + { + const struct tgsi_full_declaration *d; + unsigned last; + + d = &p.FullToken.FullDeclaration; + last = d->u.DeclarationRange.Last; + + switch (d->Declaration.File) { + case TGSI_FILE_TEMPORARY: + if (pc->temp_nr < (last + 1)) + pc->temp_nr = last + 1; + break; + case TGSI_FILE_OUTPUT: + if (pc->result_nr < (last + 1)) + pc->result_nr = last + 1; + break; + case TGSI_FILE_INPUT: + if (pc->attr_nr < (last + 1)) + pc->attr_nr = last + 1; + break; + case TGSI_FILE_CONSTANT: + if (pc->param_nr < (last + 1)) + pc->param_nr = last + 1; + break; + default: + NOUVEAU_ERR("bad decl file %d\n", + d->Declaration.File); + goto out_err; + } + } + break; + case TGSI_TOKEN_TYPE_INSTRUCTION: + break; + default: + break; + } + } + + NOUVEAU_ERR("%d temps\n", pc->temp_nr); + if (pc->temp_nr) { + pc->temp = calloc(pc->temp_nr * 4, sizeof(struct nv50_reg)); + if (!pc->temp) + goto out_err; + + for (i = 0; i < pc->temp_nr; i++) { + for (c = 0; c < 4; c++) { + pc->temp[i*4+c].type = P_TEMP; + pc->temp[i*4+c].hw = -1; + pc->temp[i*4+c].index = i; + } + } + } + + NOUVEAU_ERR("%d attrib regs\n", pc->attr_nr); + if (pc->attr_nr) { + int aid = 0; + + pc->attr = calloc(pc->attr_nr * 4, sizeof(struct nv50_reg)); + if (!pc->attr) + goto out_err; + + for (i = 0; i < pc->attr_nr; i++) { + for (c = 0; c < 4; c++) { + pc->p->cfg.vp.attr[aid/32] |= (1 << (aid % 32)); + pc->attr[i*4+c].type = P_ATTR; + pc->attr[i*4+c].hw = aid++; + pc->attr[i*4+c].index = i; + } + } + } + + NOUVEAU_ERR("%d result regs\n", pc->result_nr); + if (pc->result_nr) { + int rid = 0; + + pc->result = calloc(pc->result_nr * 4, sizeof(struct nv50_reg)); + if (!pc->result) + goto out_err; + + for (i = 0; i < pc->result_nr; i++) { + for (c = 0; c < 4; c++) { + pc->result[i*4+c].type = P_RESULT; + pc->result[i*4+c].hw = rid++; + pc->result[i*4+c].index = i; + } + } + } + + NOUVEAU_ERR("%d param regs\n", pc->param_nr); + if (pc->param_nr) { + int rid = 0; + + pc->param = calloc(pc->param_nr * 4, sizeof(struct nv50_reg)); + if (!pc->param) + goto out_err; + + for (i = 0; i < pc->param_nr; i++) { + for (c = 0; c < 4; c++) { + pc->param[i*4+c].type = P_CONST; + pc->param[i*4+c].hw = rid++; + pc->param[i*4+c].index = i; + } + } + } + + if (pc->immd_nr) { + int rid = pc->param_nr * 4; + + pc->immd = calloc(pc->immd_nr * 4, sizeof(struct nv50_reg)); + if (!pc->immd) + goto out_err; + + for (i = 0; i < pc->immd_nr; i++) { + for (c = 0; c < 4; c++) { + pc->immd[i*4+c].type = P_IMMD; + pc->immd[i*4+c].hw = rid++; + pc->immd[i*4+c].index = i; + } + } + } + + ret = TRUE; +out_err: + tgsi_parse_free(&p); + return ret; +} + +static boolean +nv50_program_tx(struct nv50_program *p) +{ + struct tgsi_parse_context parse; + struct nv50_pc *pc; + boolean ret; + + pc = CALLOC_STRUCT(nv50_pc); + if (!pc) + return FALSE; + pc->p = p; + pc->p->cfg.vp.high_temp = 4; + + ret = nv50_program_tx_prep(pc); + if (ret == FALSE) + goto out_cleanup; + + tgsi_parse_init(&parse, pc->p->pipe.tokens); + while (!tgsi_parse_end_of_tokens(&parse)) { + const union tgsi_full_token *tok = &parse.FullToken; + + tgsi_parse_token(&parse); + + switch (tok->Token.Type) { + case TGSI_TOKEN_TYPE_INSTRUCTION: + ret = nv50_program_tx_insn(pc, tok); + if (ret == FALSE) + goto out_err; + break; + default: + break; + } + } + + p->param_nr = pc->param_nr * 4; + p->immd_nr = pc->immd_nr * 4; + p->immd = pc->immd_buf; + +out_err: + tgsi_parse_free(&parse); + +out_cleanup: + return ret; +} + +static void +nv50_program_validate(struct nv50_context *nv50, struct nv50_program *p) +{ + struct tgsi_parse_context pc; + + tgsi_parse_init(&pc, p->pipe.tokens); + + if (pc.FullHeader.Processor.Processor == TGSI_PROCESSOR_FRAGMENT) { + p->insns_nr = 8; + p->insns = malloc(p->insns_nr * sizeof(unsigned)); + p->insns[0] = 0x80000000; + p->insns[1] = 0x9000000c; + p->insns[2] = 0x82010600; + p->insns[3] = 0x82020604; + p->insns[4] = 0x80030609; + p->insns[5] = 0x00020780; + p->insns[6] = 0x8004060d; + p->insns[7] = 0x00020781; + } else + if (pc.FullHeader.Processor.Processor == TGSI_PROCESSOR_VERTEX) { + int i; + + if (nv50_program_tx(p) == FALSE) + assert(0); + p->insns[p->insns_nr - 1] |= 0x00000001; + + for (i = 0; i < p->insns_nr; i++) + NOUVEAU_ERR("%d 0x%08x\n", i, p->insns[i]); + } else { + NOUVEAU_ERR("invalid TGSI processor\n"); + tgsi_parse_free(&pc); + return; + } + + tgsi_parse_free(&pc); + + p->translated = TRUE; +} + +void +nv50_vertprog_validate(struct nv50_context *nv50) +{ + struct pipe_winsys *ws = nv50->pipe.winsys; + struct nouveau_winsys *nvws = nv50->screen->nvws; + struct nouveau_grobj *tesla = nv50->screen->tesla; + struct nv50_program *p = nv50->vertprog; + struct nouveau_stateobj *so; + void *map; + int i; + + if (!p->translated) { + nv50_program_validate(nv50, p); + if (!p->translated) + assert(0); + } + + if (!p->buffer) + p->buffer = ws->buffer_create(ws, 0x100, 0, p->insns_nr * 4); + map = ws->buffer_map(ws, p->buffer, PIPE_BUFFER_USAGE_CPU_WRITE); + memcpy(map, p->insns, p->insns_nr * 4); + ws->buffer_unmap(ws, p->buffer); + + if (p->param_nr) { + float *cb; + + cb = ws->buffer_map(ws, nv50->constbuf[PIPE_SHADER_VERTEX], + PIPE_BUFFER_USAGE_CPU_READ); + for (i = 0; i < p->param_nr; i++) { + BEGIN_RING(tesla, 0x0f00, 2); + OUT_RING (i << 8); + OUT_RING (fui(cb[i])); + } + ws->buffer_unmap(ws, nv50->constbuf[PIPE_SHADER_VERTEX]); + } + + + for (i = 0; i < p->immd_nr; i++) { + BEGIN_RING(tesla, 0x0f00, 2); + OUT_RING ((p->param_nr + i) << 8); + OUT_RING (fui(p->immd[i])); + } + + so = so_new(11, 2); + so_method(so, tesla, NV50TCL_VP_ADDRESS_HIGH, 2); + so_reloc (so, p->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | + NOUVEAU_BO_HIGH, 0, 0); + so_reloc (so, p->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | + NOUVEAU_BO_LOW, 0, 0); + so_method(so, tesla, 0x1650, 2); + so_data (so, p->cfg.vp.attr[0]); + so_data (so, p->cfg.vp.attr[1]); + so_method(so, tesla, 0x16ac, 2); + so_data (so, 8); + so_data (so, p->cfg.vp.high_temp); + so_method(so, tesla, 0x140c, 1); + so_data (so, 0); /* program start offset */ + so_emit(nv50->screen->nvws, so); + so_ref(NULL, &so); +} + +void +nv50_fragprog_validate(struct nv50_context *nv50) +{ + struct pipe_winsys *ws = nv50->pipe.winsys; + struct nouveau_grobj *tesla = nv50->screen->tesla; + struct nv50_program *p = nv50->fragprog; + struct nouveau_stateobj *so; + void *map; + + if (!p->translated) { + nv50_program_validate(nv50, p); + if (!p->translated) + assert(0); + } + + if (!p->buffer) + p->buffer = ws->buffer_create(ws, 0x100, 0, p->insns_nr * 4); + map = ws->buffer_map(ws, p->buffer, PIPE_BUFFER_USAGE_CPU_WRITE); + memcpy(map, p->insns, p->insns_nr * 4); + ws->buffer_unmap(ws, p->buffer); + + so = so_new(3, 2); + so_method(so, tesla, NV50TCL_FP_ADDRESS_HIGH, 2); + so_reloc (so, p->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | + NOUVEAU_BO_HIGH, 0, 0); + so_reloc (so, p->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | + NOUVEAU_BO_LOW, 0, 0); + so_emit(nv50->screen->nvws, so); + so_ref(NULL, &so); +} + +void +nv50_program_destroy(struct nv50_context *nv50, struct nv50_program *p) +{ + struct pipe_winsys *ws = nv50->pipe.winsys; + + if (p->insns_nr) { + if (p->insns) + FREE(p->insns); + p->insns_nr = 0; + } + + if (p->buffer) + pipe_buffer_reference(ws, &p->buffer, NULL); + + p->translated = 0; +} + diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 29c057a145..fc3eeed913 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -203,8 +203,19 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) return NULL; } + /* Static constant buffer */ + screen->constbuf = ws->buffer_create(ws, 0, 0, 256 * 4 * 4); + if (nvws->res_init(&screen->vp_data_heap, 0, 256)) { + NOUVEAU_ERR("Error initialising constant buffer\n"); + nv50_screen_destroy(&screen->pipe); + return NULL; + } + /* Static tesla init */ - so = so_new(128, 0); + so = so_new(256, 20); + + so_method(so, screen->tesla, 0x1558, 1); + so_data (so, 1); so_method(so, screen->tesla, NV50TCL_DMA_NOTIFY, 1); so_data (so, screen->sync->handle); so_method(so, screen->tesla, NV50TCL_DMA_IN_MEMORY0(0), @@ -215,6 +226,61 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) NV50TCL_DMA_IN_MEMORY1__SIZE); for (i = 0; i < NV50TCL_DMA_IN_MEMORY1__SIZE; i++) so_data(so, nvws->channel->vram->handle); + so_method(so, screen->tesla, 0x121c, 1); + so_data (so, 1); + + so_method(so, screen->tesla, 0x13bc, 1); + so_data (so, 0x54); + so_method(so, screen->tesla, 0x13ac, 1); + so_data (so, 1); + so_method(so, screen->tesla, 0x16bc, 2); + so_data (so, 0x03020100); + so_data (so, 0x07060504); + so_method(so, screen->tesla, 0x1988, 2); + so_data (so, 0x08040404); + so_data (so, 0x00000004); + so_method(so, screen->tesla, 0x16ac, 2); + so_data (so, 8); + so_data (so, 4); + so_method(so, screen->tesla, 0x16b8, 1); + so_data (so, 8); + + so_method(so, screen->tesla, 0x1280, 3); + so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | + NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); + so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | + NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); + so_data (so, 0x00001000); + so_method(so, screen->tesla, 0x1280, 3); + so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | + NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); + so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | + NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); + so_data (so, 0x00014000); + so_method(so, screen->tesla, 0x1280, 3); + so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | + NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); + so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | + NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); + so_data (so, 0x00024000); + so_method(so, screen->tesla, 0x1280, 3); + so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | + NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); + so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | + NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); + so_data (so, 0x00034000); + so_method(so, screen->tesla, 0x1280, 3); + so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | + NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); + so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | + NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); + so_data (so, 0x00040100); + + for (i = 0; i < 16; i++) { + so_method(so, screen->tesla, 0x1080 + (i * 8), 2); + so_data (so, 0x000000ff); + so_data (so, 0xffffffff); + } so_emit(nvws, so); so_ref(NULL, &so); diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h index 5a2732e37f..d63dd48508 100644 --- a/src/gallium/drivers/nv50/nv50_screen.h +++ b/src/gallium/drivers/nv50/nv50_screen.h @@ -12,6 +12,9 @@ struct nv50_screen { struct nouveau_grobj *tesla; struct nouveau_notifier *sync; + + struct pipe_buffer *constbuf; + struct nouveau_resource *vp_data_heap; }; static INLINE struct nv50_screen * diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index f42bae0c28..fd10a38378 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -248,8 +248,8 @@ nv50_depth_stencil_alpha_state_create(struct pipe_context *pipe, struct nouveau_stateobj *so = so_new(64, 0); so_method(so, tesla, NV50TCL_DEPTH_WRITE_ENABLE, 1); - so_data (so, cso->depth.writemask ? 1 : 0); - if (cso->depth.enabled) { + so_data (so, 0); //cso->depth.writemask ? 1 : 0); + if (0 && cso->depth.enabled) { so_method(so, tesla, NV50TCL_DEPTH_TEST_ENABLE, 1); so_data (so, 1); so_method(so, tesla, NV50TCL_DEPTH_TEST_FUNC, 1); @@ -328,34 +328,58 @@ static void * nv50_vp_state_create(struct pipe_context *pipe, const struct pipe_shader_state *cso) { - return NULL; + struct nv50_program *p = CALLOC_STRUCT(nv50_program); + + p->pipe = *cso; + tgsi_scan_shader(p->pipe.tokens, &p->info); + return (void *)p; } static void nv50_vp_state_bind(struct pipe_context *pipe, void *hwcso) { + struct nv50_context *nv50 = nv50_context(pipe); + + nv50->vertprog = hwcso; + nv50->dirty |= NV50_NEW_VERTPROG; } static void nv50_vp_state_delete(struct pipe_context *pipe, void *hwcso) { + struct nv50_context *nv50 = nv50_context(pipe); + + nv50_program_destroy(nv50, hwcso); + FREE(hwcso); } static void * nv50_fp_state_create(struct pipe_context *pipe, const struct pipe_shader_state *cso) { - return NULL; + struct nv50_program *p = CALLOC_STRUCT(nv50_program); + + p->pipe = *cso; + tgsi_scan_shader(p->pipe.tokens, &p->info); + return (void *)p; } static void nv50_fp_state_bind(struct pipe_context *pipe, void *hwcso) { + struct nv50_context *nv50 = nv50_context(pipe); + + nv50->fragprog = hwcso; + nv50->dirty |= NV50_NEW_FRAGPROG; } static void nv50_fp_state_delete(struct pipe_context *pipe, void *hwcso) { + struct nv50_context *nv50 = nv50_context(pipe); + + nv50_program_destroy(nv50, hwcso); + FREE(hwcso); } static void @@ -378,6 +402,16 @@ static void nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, const struct pipe_constant_buffer *buf ) { + struct nv50_context *nv50 = nv50_context(pipe); + + if (shader == PIPE_SHADER_VERTEX) { + nv50->constbuf[PIPE_SHADER_VERTEX] = buf->buffer; + nv50->dirty |= NV50_NEW_VERTPROG; + } else + if (shader == PIPE_SHADER_FRAGMENT) { + nv50->constbuf[PIPE_SHADER_FRAGMENT] = buf->buffer; + nv50->dirty |= NV50_NEW_FRAGPROG; + } } static void @@ -424,12 +458,24 @@ static void nv50_set_vertex_buffers(struct pipe_context *pipe, unsigned count, const struct pipe_vertex_buffer *vb) { + struct nv50_context *nv50 = nv50_context(pipe); + + memcpy(nv50->vtxbuf, vb, sizeof(*vb) * count); + nv50->vtxbuf_nr = count; + + nv50->dirty |= NV50_NEW_ARRAYS; } static void nv50_set_vertex_elements(struct pipe_context *pipe, unsigned count, const struct pipe_vertex_element *ve) { + struct nv50_context *nv50 = nv50_context(pipe); + + memcpy(nv50->vtxelt, ve, sizeof(*ve) * count); + nv50->vtxelt_nr = count; + + nv50->dirty |= NV50_NEW_ARRAYS; } void diff --git a/src/gallium/drivers/nv50/nv50_state.h b/src/gallium/drivers/nv50/nv50_state.h index a3b781d4c6..be0c75ad6e 100644 --- a/src/gallium/drivers/nv50/nv50_state.h +++ b/src/gallium/drivers/nv50/nv50_state.h @@ -2,6 +2,36 @@ #define __NV50_STATE_H__ #include "pipe/p_state.h" +#include "tgsi/util/tgsi_scan.h" +struct nv50_program_data { + int index; + int component; + float value; +}; + +struct nv50_program { + struct pipe_shader_state pipe; + struct tgsi_shader_info info; + boolean translated; + + unsigned *insns; + unsigned insns_nr; + + struct pipe_buffer *buffer; + + unsigned param_nr; + float *immd; + unsigned immd_nr; + + struct nouveau_resource *data; + + union { + struct { + unsigned high_temp; + unsigned attr[2]; + } vp; + } cfg; +}; #endif diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index 68d419f9fc..4a548378b7 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -15,8 +15,8 @@ nv50_state_validate_fb(struct nv50_context *nv50) h = fb->cbufs[i]->height; gw = 1; } else { - assert(w != fb->cbufs[i]->width); - assert(h != fb->cbufs[i]->height); + assert(w == fb->cbufs[i]->width); + assert(h == fb->cbufs[i]->height); } so_method(so, tesla, NV50TCL_RT_HORIZ(i), 2); @@ -46,6 +46,9 @@ nv50_state_validate_fb(struct nv50_context *nv50) } so_data(so, 0x00000040); so_data(so, 0x00000000); + + so_method(so, tesla, 0x1224, 1); + so_data (so, 1); } if (fb->zsbuf) { @@ -54,11 +57,11 @@ nv50_state_validate_fb(struct nv50_context *nv50) h = fb->zsbuf->height; gw = 1; } else { - assert(w != fb->zsbuf->width); - assert(h != fb->zsbuf->height); + assert(w == fb->zsbuf->width); + assert(h == fb->zsbuf->height); } - so_method(so, tesla, NV50TCL_RT_ADDRESS_HIGH(i), 5); + so_method(so, tesla, NV50TCL_ZETA_ADDRESS_HIGH, 5); so_reloc (so, fb->zsbuf->buffer, fb->zsbuf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_HIGH, 0, 0); so_reloc (so, fb->zsbuf->buffer, fb->zsbuf->offset, @@ -83,9 +86,12 @@ nv50_state_validate_fb(struct nv50_context *nv50) so_method(so, tesla, NV50TCL_VIEWPORT_HORIZ, 2); so_data (so, w << 16); so_data (so, h << 16); - so_method(so, tesla, 0xff0, 2); + so_method(so, tesla, 0xff4, 2); so_data (so, w << 16); so_data (so, h << 16); + so_method(so, tesla, 0xdf8, 2); + so_data (so, 0); + so_data (so, h); so_emit(nv50->screen->nvws, so); so_ref(NULL, &so); @@ -108,6 +114,12 @@ nv50_state_validate(struct nv50_context *nv50) if (nv50->dirty & NV50_NEW_ZSA) so_emit(nvws, nv50->zsa->so); + if (nv50->dirty & NV50_NEW_VERTPROG) + nv50_vertprog_validate(nv50); + + if (nv50->dirty & NV50_NEW_FRAGPROG) + nv50_fragprog_validate(nv50); + if (nv50->dirty & NV50_NEW_RASTERIZER) so_emit(nvws, nv50->rasterizer->so); @@ -150,12 +162,15 @@ nv50_state_validate(struct nv50_context *nv50) so_data (so, fui(nv50->viewport.translate[2])); so_method(so, tesla, NV50TCL_VIEWPORT_UNK1(0), 3); so_data (so, fui(nv50->viewport.scale[0])); - so_data (so, fui(nv50->viewport.scale[1])); + so_data (so, fui(-nv50->viewport.scale[1])); so_data (so, fui(nv50->viewport.scale[2])); so_emit(nvws, so); so_ref(NULL, &so); } + if (nv50->dirty & NV50_NEW_ARRAYS) + nv50_vbo_validate(nv50); + nv50->dirty = 0; return TRUE; } diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index b01ce1d42c..f086c76258 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -5,6 +5,29 @@ #include "nv50_context.h" #include "nv50_state.h" +static INLINE unsigned +nv50_prim(unsigned mode) +{ + switch (mode) { + case PIPE_PRIM_POINTS: return NV50TCL_VERTEX_BEGIN_POINTS; + case PIPE_PRIM_LINES: return NV50TCL_VERTEX_BEGIN_LINES; + case PIPE_PRIM_LINE_LOOP: return NV50TCL_VERTEX_BEGIN_LINE_LOOP; + case PIPE_PRIM_LINE_STRIP: return NV50TCL_VERTEX_BEGIN_LINE_STRIP; + case PIPE_PRIM_TRIANGLES: return NV50TCL_VERTEX_BEGIN_TRIANGLES; + case PIPE_PRIM_TRIANGLE_STRIP: + return NV50TCL_VERTEX_BEGIN_TRIANGLE_STRIP; + case PIPE_PRIM_TRIANGLE_FAN: return NV50TCL_VERTEX_BEGIN_TRIANGLE_FAN; + case PIPE_PRIM_QUADS: return NV50TCL_VERTEX_BEGIN_QUADS; + case PIPE_PRIM_QUAD_STRIP: return NV50TCL_VERTEX_BEGIN_QUAD_STRIP; + case PIPE_PRIM_POLYGON: return NV50TCL_VERTEX_BEGIN_POLYGON; + default: + break; + } + + NOUVEAU_ERR("invalid primitive type %d\n", mode); + return NV50TCL_VERTEX_BEGIN_POINTS; +} + boolean nv50_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, unsigned count) @@ -12,8 +35,22 @@ nv50_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, struct nv50_context *nv50 = nv50_context(pipe); nv50_state_validate(nv50); - NOUVEAU_ERR("unimplemented\n"); + + BEGIN_RING(tesla, 0x142c, 1); + OUT_RING (0); + BEGIN_RING(tesla, 0x142c, 1); + OUT_RING (0); + + BEGIN_RING(tesla, NV50TCL_VERTEX_BEGIN, 1); + OUT_RING (nv50_prim(mode)); + BEGIN_RING(tesla, NV50TCL_VERTEX_BUFFER_FIRST, 2); + OUT_RING (start); + OUT_RING (count); + BEGIN_RING(tesla, NV50TCL_VERTEX_END, 1); + OUT_RING (0); + + pipe->flush(pipe, 0, NULL); return TRUE; } @@ -30,3 +67,49 @@ nv50_draw_elements(struct pipe_context *pipe, return TRUE; } +void +nv50_vbo_validate(struct nv50_context *nv50) +{ + struct nouveau_grobj *tesla = nv50->screen->tesla; + struct nouveau_stateobj *vtxbuf, *vtxfmt; + int i, vpi = 0; + + vtxbuf = so_new(nv50->vtxelt_nr * 4, nv50->vtxelt_nr * 2); + vtxfmt = so_new(nv50->vtxelt_nr + 1, 0); + so_method(vtxfmt, tesla, 0x1ac0, nv50->vtxelt_nr); + + for (i = 0; i < nv50->vtxelt_nr; i++) { + struct pipe_vertex_element *ve = &nv50->vtxelt[i]; + struct pipe_vertex_buffer *vb = + &nv50->vtxbuf[ve->vertex_buffer_index]; + + switch (ve->src_format) { + case PIPE_FORMAT_R32G32B32_FLOAT: + so_data(vtxfmt, 0x7e100000 | i); + break; + default: + { + char fmt[128]; + pf_sprint_name(fmt, ve->src_format); + NOUVEAU_ERR("invalid vbo format %s\n", fmt); + assert(0); + return; + } + } + + so_method(vtxbuf, tesla, 0x900 + (i * 16), 3); + so_data (vtxbuf, 0x20000000 | vb->pitch); + so_reloc (vtxbuf, vb->buffer, vb->buffer_offset + + ve->src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | + NOUVEAU_BO_HIGH, 0, 0); + so_reloc (vtxbuf, vb->buffer, vb->buffer_offset + + ve->src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | + NOUVEAU_BO_LOW, 0, 0); + } + + so_emit(nv50->screen->nvws, vtxfmt); + so_ref (NULL, &vtxfmt); + so_emit(nv50->screen->nvws, vtxbuf); + so_ref (NULL, &vtxbuf); +} + -- cgit v1.2.3 From 716c1cd2ecbc1e86c0fd747c9fa9e095ded5fd5d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 1 Jun 2008 23:10:31 +1000 Subject: nv50: use "real" constbufs for shaders + tcb uploads --- src/gallium/drivers/nv50/nv50_context.h | 14 ++++++- src/gallium/drivers/nv50/nv50_program.c | 27 +++++------- src/gallium/drivers/nv50/nv50_screen.c | 57 +++++++++++++++----------- src/gallium/drivers/nv50/nv50_screen.h | 3 ++ src/gallium/drivers/nv50/nv50_state.c | 4 +- src/gallium/drivers/nv50/nv50_state.h | 1 - src/gallium/drivers/nv50/nv50_state_validate.c | 29 +++++++++++++ 7 files changed, 90 insertions(+), 45 deletions(-) (limited to 'src/gallium/drivers/nv50/nv50_screen.h') diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index d4d716b94b..c4a8a4c064 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -23,6 +23,14 @@ #define NOUVEAU_MSG(fmt, args...) \ fprintf(stderr, "nouveau: "fmt, ##args); +/* Constant buffer assignment */ +#define NV50_CB_PMISC 0 +#define NV50_CB_PVP 1 +#define NV50_CB_PFP 2 +#define NV50_CB_PGP 3 +#define NV50_CB_TIC 4 +#define NV50_CB_TSC 5 + #define NV50_NEW_BLEND (1 << 0) #define NV50_NEW_ZSA (1 << 1) #define NV50_NEW_BLEND_COLOUR (1 << 2) @@ -32,8 +40,10 @@ #define NV50_NEW_RASTERIZER (1 << 6) #define NV50_NEW_FRAMEBUFFER (1 << 7) #define NV50_NEW_VERTPROG (1 << 8) -#define NV50_NEW_FRAGPROG (1 << 9) -#define NV50_NEW_ARRAYS (1 << 10) +#define NV50_NEW_VERTPROG_CB (1 << 9) +#define NV50_NEW_FRAGPROG (1 << 10) +#define NV50_NEW_FRAGPROG_CB (1 << 11) +#define NV50_NEW_ARRAYS (1 << 12) struct nv50_blend_stateobj { struct pipe_blend_state pipe; diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 30953b7d8a..0a43646923 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -179,6 +179,10 @@ emit(struct nv50_pc *pc, unsigned op, struct nv50_reg *dst, if (src1) { if (src1->type == P_CONST || src1->type == P_IMMD) { + if (src1->type == P_IMMD) + inst[1] |= (NV50_CB_PMISC << 22); + else + inst[1] |= (NV50_CB_PVP << 22); inst[0] |= 0x00800000; /* src1 is const */ /*XXX: does src1 come from "src2" now? */ alloc_reg(pc, src1); @@ -196,6 +200,10 @@ emit(struct nv50_pc *pc, unsigned op, struct nv50_reg *dst, if (src2) { if (src2->type == P_CONST || src2->type == P_IMMD) { + if (src2->type == P_IMMD) + inst[1] |= (NV50_CB_PMISC << 22); + else + inst[1] |= (NV50_CB_PVP << 22); inst[0] |= 0x01000000; /* src2 is const */ inst[1] |= (src2->hw << 14); } else { @@ -526,7 +534,7 @@ nv50_program_tx_prep(struct nv50_pc *pc) } if (pc->immd_nr) { - int rid = pc->param_nr * 4; + int rid = 0; pc->immd = calloc(pc->immd_nr * 4, sizeof(struct nv50_reg)); if (!pc->immd) @@ -581,7 +589,6 @@ nv50_program_tx(struct nv50_program *p) } } - p->param_nr = pc->param_nr * 4; p->immd_nr = pc->immd_nr * 4; p->immd = pc->immd_buf; @@ -654,23 +661,9 @@ nv50_vertprog_validate(struct nv50_context *nv50) memcpy(map, p->insns, p->insns_nr * 4); ws->buffer_unmap(ws, p->buffer); - if (p->param_nr) { - float *cb; - - cb = ws->buffer_map(ws, nv50->constbuf[PIPE_SHADER_VERTEX], - PIPE_BUFFER_USAGE_CPU_READ); - for (i = 0; i < p->param_nr; i++) { - BEGIN_RING(tesla, 0x0f00, 2); - OUT_RING (i << 8); - OUT_RING (fui(cb[i])); - } - ws->buffer_unmap(ws, nv50->constbuf[PIPE_SHADER_VERTEX]); - } - - for (i = 0; i < p->immd_nr; i++) { BEGIN_RING(tesla, 0x0f00, 2); - OUT_RING ((p->param_nr + i) << 8); + OUT_RING ((NV50_CB_PMISC << 16) | (i << 8)); OUT_RING (fui(p->immd[i])); } diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index fc3eeed913..6c0810a9cf 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -203,14 +203,6 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) return NULL; } - /* Static constant buffer */ - screen->constbuf = ws->buffer_create(ws, 0, 0, 256 * 4 * 4); - if (nvws->res_init(&screen->vp_data_heap, 0, 256)) { - NOUVEAU_ERR("Error initialising constant buffer\n"); - nv50_screen_destroy(&screen->pipe); - return NULL; - } - /* Static tesla init */ so = so_new(256, 20); @@ -245,37 +237,56 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) so_method(so, screen->tesla, 0x16b8, 1); so_data (so, 8); + /* Shared constant buffer */ + screen->constbuf = ws->buffer_create(ws, 0, 0, 256 * 4 * 4); + if (nvws->res_init(&screen->vp_data_heap, 0, 256)) { + NOUVEAU_ERR("Error initialising constant buffer\n"); + nv50_screen_destroy(&screen->pipe); + return NULL; + } + so_method(so, screen->tesla, 0x1280, 3); so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); - so_data (so, 0x00001000); + so_data (so, (NV50_CB_PMISC << 16) | 0x00001000); + + /* Texture sampler/image unit setup - we abuse the constant buffer + * upload mechanism for the moment to upload data to the tex config + * blocks. At some point we *may* want to go the NVIDIA way of doing + * things? + */ + screen->tic = ws->buffer_create(ws, 0, 0, 32 * 8 * 4); so_method(so, screen->tesla, 0x1280, 3); - so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | + so_reloc (so, screen->tic, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); - so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | + so_reloc (so, screen->tic, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); - so_data (so, 0x00014000); - so_method(so, screen->tesla, 0x1280, 3); - so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | + so_data (so, (NV50_CB_TIC << 16) | 0x0800); + so_method(so, screen->tesla, 0x1574, 3); + so_reloc (so, screen->tic, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); - so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | + so_reloc (so, screen->tic, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); - so_data (so, 0x00024000); + so_data (so, 0x00000800); + + screen->tsc = ws->buffer_create(ws, 0, 0, 32 * 8 * 4); so_method(so, screen->tesla, 0x1280, 3); - so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | + so_reloc (so, screen->tsc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); - so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | + so_reloc (so, screen->tsc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); - so_data (so, 0x00034000); - so_method(so, screen->tesla, 0x1280, 3); - so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | + so_data (so, (NV50_CB_TSC << 16) | 0x0800); + so_method(so, screen->tesla, 0x155c, 3); + so_reloc (so, screen->tsc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); - so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | + so_reloc (so, screen->tsc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); - so_data (so, 0x00040100); + so_data (so, 0x00000800); + + /* Vertex array limits - max them out */ for (i = 0; i < 16; i++) { so_method(so, screen->tesla, 0x1080 + (i * 8), 2); so_data (so, 0x000000ff); diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h index d63dd48508..5acb5003ba 100644 --- a/src/gallium/drivers/nv50/nv50_screen.h +++ b/src/gallium/drivers/nv50/nv50_screen.h @@ -15,6 +15,9 @@ struct nv50_screen { struct pipe_buffer *constbuf; struct nouveau_resource *vp_data_heap; + + struct pipe_buffer *tic; + struct pipe_buffer *tsc; }; static INLINE struct nv50_screen * diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index fd10a38378..ba3d04cede 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -406,11 +406,11 @@ nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, if (shader == PIPE_SHADER_VERTEX) { nv50->constbuf[PIPE_SHADER_VERTEX] = buf->buffer; - nv50->dirty |= NV50_NEW_VERTPROG; + nv50->dirty |= NV50_NEW_VERTPROG_CB; } else if (shader == PIPE_SHADER_FRAGMENT) { nv50->constbuf[PIPE_SHADER_FRAGMENT] = buf->buffer; - nv50->dirty |= NV50_NEW_FRAGPROG; + nv50->dirty |= NV50_NEW_FRAGPROG_CB; } } diff --git a/src/gallium/drivers/nv50/nv50_state.h b/src/gallium/drivers/nv50/nv50_state.h index be0c75ad6e..9e3876871b 100644 --- a/src/gallium/drivers/nv50/nv50_state.h +++ b/src/gallium/drivers/nv50/nv50_state.h @@ -20,7 +20,6 @@ struct nv50_program { struct pipe_buffer *buffer; - unsigned param_nr; float *immd; unsigned immd_nr; diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index 4a548378b7..05395c6df7 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -168,6 +168,35 @@ nv50_state_validate(struct nv50_context *nv50) so_ref(NULL, &so); } + if (nv50->dirty & NV50_NEW_VERTPROG_CB) { + so = so_new(4, 2); + so_method(so, tesla, 0x1280, 3); + so_reloc (so, nv50->constbuf[PIPE_SHADER_VERTEX], 0, + NOUVEAU_BO_HIGH | NOUVEAU_BO_RD | NOUVEAU_BO_VRAM, + 0, 0); + so_reloc (so, nv50->constbuf[PIPE_SHADER_VERTEX], 0, + NOUVEAU_BO_LOW | NOUVEAU_BO_RD | NOUVEAU_BO_VRAM, + 0, 0); + so_data (so, (NV50_CB_PVP << 16) | 0x1000); + so_emit(nvws, so); + so_ref(NULL, &so); + } + + if (nv50->dirty & NV50_NEW_FRAGPROG_CB) { + so = so_new(4, 2); + so_method(so, tesla, 0x1280, 3); + so_reloc (so, nv50->constbuf[PIPE_SHADER_FRAGMENT], 0, + NOUVEAU_BO_HIGH | NOUVEAU_BO_RD | NOUVEAU_BO_VRAM, + 0, 0); + so_reloc (so, nv50->constbuf[PIPE_SHADER_FRAGMENT], 0, + NOUVEAU_BO_LOW | NOUVEAU_BO_RD | NOUVEAU_BO_VRAM, + 0, 0); + so_data (so, (NV50_CB_PFP << 16) | 0x1000); + so_emit(nvws, so); + so_ref(NULL, &so); + } + + if (nv50->dirty & NV50_NEW_ARRAYS) nv50_vbo_validate(nv50); -- cgit v1.2.3 From 65ad8176ca91b5ed2a01b1b3ee145cfdce369419 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 17 Jun 2008 23:43:38 +1000 Subject: nv50: move surface_map/unmap into nv50_surface.c --- src/gallium/drivers/nv50/nv50_screen.c | 26 +------------------------ src/gallium/drivers/nv50/nv50_screen.h | 2 ++ src/gallium/drivers/nv50/nv50_surface.c | 34 +++++++++++++++++++++++++++++++-- 3 files changed, 35 insertions(+), 27 deletions(-) (limited to 'src/gallium/drivers/nv50/nv50_screen.h') diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 8affb0f073..18f22c5960 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -118,28 +118,6 @@ nv50_screen_get_paramf(struct pipe_screen *pscreen, int param) } } -static void * -nv50_surface_map(struct pipe_screen *screen, struct pipe_surface *surface, - unsigned flags ) -{ - struct pipe_winsys *ws = screen->winsys; - void *map; - - map = ws->buffer_map(ws, surface->buffer, flags); - if (!map) - return NULL; - - return map + surface->offset; -} - -static void -nv50_surface_unmap(struct pipe_screen *screen, struct pipe_surface *surface) -{ - struct pipe_winsys *ws = screen->winsys; - - ws->buffer_unmap(ws, surface->buffer); -} - static void nv50_screen_destroy(struct pipe_screen *pscreen) { @@ -309,10 +287,8 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) screen->pipe.is_format_supported = nv50_screen_is_format_supported; - screen->pipe.surface_map = nv50_surface_map; - screen->pipe.surface_unmap = nv50_surface_unmap; - nv50_screen_init_miptree_functions(&screen->pipe); + nv50_surface_init_screen_functions(&screen->pipe); return &screen->pipe; } diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h index 5acb5003ba..08d1f45089 100644 --- a/src/gallium/drivers/nv50/nv50_screen.h +++ b/src/gallium/drivers/nv50/nv50_screen.h @@ -26,4 +26,6 @@ nv50_screen(struct pipe_screen *screen) return (struct nv50_screen *)screen; } +void nv50_surface_init_screen_functions(struct pipe_screen *); + #endif diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c index 4e294198b0..acd7b501ef 100644 --- a/src/gallium/drivers/nv50/nv50_surface.c +++ b/src/gallium/drivers/nv50/nv50_surface.c @@ -57,9 +57,39 @@ nv50_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest, nvws->surface_fill(nvws, dest, destx, desty, width, height, value); } +static void * +nv50_surface_map(struct pipe_screen *screen, struct pipe_surface *surface, + unsigned flags ) +{ + struct pipe_winsys *ws = screen->winsys; + void *map; + + map = ws->buffer_map(ws, surface->buffer, flags); + if (!map) + return NULL; + + return map + surface->offset; +} + +static void +nv50_surface_unmap(struct pipe_screen *screen, struct pipe_surface *surface) +{ + struct pipe_winsys *ws = screen->winsys; + + ws->buffer_unmap(ws, surface->buffer); +} + void nv50_init_surface_functions(struct nv50_context *nv50) { - nv50->pipe.surface_copy = nv50_surface_copy; - nv50->pipe.surface_fill = nv50_surface_fill; + nv50->pipe.surface_copy = nv50_surface_copy; + nv50->pipe.surface_fill = nv50_surface_fill; } + +void +nv50_surface_init_screen_functions(struct pipe_screen *pscreen) +{ + pscreen->surface_map = nv50_surface_map; + pscreen->surface_unmap = nv50_surface_unmap; +} + -- cgit v1.2.3 From 714cb4a86c1f503334b37ca6c24272fa1bdf7899 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 17 Jun 2008 23:55:23 +1000 Subject: nv50: make sure static buffers (constbuf, tex control etc) get on reloc list --- src/gallium/drivers/nv50/nv50_screen.c | 2 +- src/gallium/drivers/nv50/nv50_screen.h | 2 ++ src/gallium/drivers/nv50/nv50_state_validate.c | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) (limited to 'src/gallium/drivers/nv50/nv50_screen.h') diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 18f22c5960..5b4c5f96ac 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -273,7 +273,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) so_data (so, 1); so_emit(nvws, so); - so_ref(NULL, &so); + so_ref(so, &screen->static_init); nvws->push_flush(nvws, 0, NULL); screen->pipe.winsys = ws; diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h index 08d1f45089..400ddcef06 100644 --- a/src/gallium/drivers/nv50/nv50_screen.h +++ b/src/gallium/drivers/nv50/nv50_screen.h @@ -18,6 +18,8 @@ struct nv50_screen { struct pipe_buffer *tic; struct pipe_buffer *tsc; + + struct nouveau_stateobj *static_init; }; static INLINE struct nv50_screen * diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index d99cdc73ca..8229bce89e 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -151,6 +151,7 @@ nv50_state_emit(struct nv50_context *nv50) so_emit_reloc_markers(nvws, nv50->state.vertprog); so_emit_reloc_markers(nvws, nv50->state.fragprog); so_emit_reloc_markers(nvws, nv50->state.vtxbuf); + so_emit_reloc_markers(nvws, nv50->screen->static_init); } boolean -- cgit v1.2.3