diff options
author | Keith Whitwell <[email protected]> | 2009-02-16 19:50:48 +0000 |
---|---|---|
committer | Keith Whitwell <[email protected]> | 2009-02-16 19:50:48 +0000 |
commit | 59d54334c96f44ed1d8bf660dc96221362a77d04 (patch) | |
tree | e9ab34e568256bcdc2a88602c47072ab769211e8 /src/gallium/drivers/nv50 | |
parent | 7c8836e9ef49d938aa55a1c385b95c6371c301f1 (diff) | |
parent | c5c383596ddb26cd75e4b355918ad16915283b59 (diff) |
Merge branch 'master' into gallium-texture-transfer
Conflicts:
src/mesa/state_tracker/st_cb_accum.c
src/mesa/state_tracker/st_cb_drawpixels.c
Diffstat (limited to 'src/gallium/drivers/nv50')
-rw-r--r-- | src/gallium/drivers/nv50/nv50_clear.c | 28 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_context.c | 2 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_context.h | 9 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_miptree.c | 34 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_program.c | 23 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_query.c | 25 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_screen.c | 24 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_screen.h | 1 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_state_validate.c | 12 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_surface.c | 152 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_tex.c | 6 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_vbo.c | 81 |
12 files changed, 309 insertions, 88 deletions
diff --git a/src/gallium/drivers/nv50/nv50_clear.c b/src/gallium/drivers/nv50/nv50_clear.c index 6380f397ea6..f9bc3b53caa 100644 --- a/src/gallium/drivers/nv50/nv50_clear.c +++ b/src/gallium/drivers/nv50/nv50_clear.c @@ -31,6 +31,8 @@ nv50_clear(struct pipe_context *pipe, struct pipe_surface *ps, unsigned clearValue) { struct nv50_context *nv50 = nv50_context(pipe); + struct nouveau_channel *chan = nv50->screen->nvws->channel; + struct nouveau_grobj *tesla = nv50->screen->tesla; struct pipe_framebuffer_state fb, s_fb = nv50->framebuffer; struct pipe_scissor_state sc, s_sc = nv50->scissor; unsigned dirty = nv50->dirty; @@ -59,21 +61,21 @@ nv50_clear(struct pipe_context *pipe, struct pipe_surface *ps, switch (ps->format) { case PIPE_FORMAT_A8R8G8B8_UNORM: - BEGIN_RING(tesla, 0x0d80, 4); - OUT_RINGf (ubyte_to_float((clearValue >> 16) & 0xff)); - OUT_RINGf (ubyte_to_float((clearValue >> 8) & 0xff)); - OUT_RINGf (ubyte_to_float((clearValue >> 0) & 0xff)); - OUT_RINGf (ubyte_to_float((clearValue >> 24) & 0xff)); - BEGIN_RING(tesla, 0x19d0, 1); - OUT_RING (0x3c); + BEGIN_RING(chan, tesla, 0x0d80, 4); + OUT_RINGf (chan, ubyte_to_float((clearValue >> 16) & 0xff)); + OUT_RINGf (chan, ubyte_to_float((clearValue >> 8) & 0xff)); + OUT_RINGf (chan, ubyte_to_float((clearValue >> 0) & 0xff)); + OUT_RINGf (chan, ubyte_to_float((clearValue >> 24) & 0xff)); + BEGIN_RING(chan, tesla, 0x19d0, 1); + OUT_RING (chan, 0x3c); break; case PIPE_FORMAT_Z24S8_UNORM: - BEGIN_RING(tesla, 0x0d90, 1); - OUT_RINGf ((float)(clearValue >> 8) * (1.0 / 16777215.0)); - BEGIN_RING(tesla, 0x0da0, 1); - OUT_RING (clearValue & 0xff); - BEGIN_RING(tesla, 0x19d0, 1); - OUT_RING (0x03); + BEGIN_RING(chan, tesla, 0x0d90, 1); + OUT_RINGf (chan, (float)(clearValue >> 8) * (1.0 / 16777215.0)); + BEGIN_RING(chan, tesla, 0x0da0, 1); + OUT_RING (chan, clearValue & 0xff); + BEGIN_RING(chan, tesla, 0x19d0, 1); + OUT_RING (chan, 0x03); break; default: pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c index 99776239d2b..565a5da668c 100644 --- a/src/gallium/drivers/nv50/nv50_context.c +++ b/src/gallium/drivers/nv50/nv50_context.c @@ -33,7 +33,7 @@ nv50_flush(struct pipe_context *pipe, unsigned flags, { struct nv50_context *nv50 = (struct nv50_context *)pipe; - FIRE_RING(fence); + FIRE_RING(nv50->screen->nvws->channel); } static void diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index 6c9e18429ac..1e9d45cb340 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -15,10 +15,6 @@ #include "nouveau/nouveau_gldefs.h" #include "nouveau/nouveau_stateobj.h" -#define NOUVEAU_PUSH_CONTEXT(ctx) \ - struct nv50_screen *ctx = nv50->screen -#include "nouveau/nouveau_push.h" - #include "nv50_screen.h" #include "nv50_program.h" @@ -171,6 +167,11 @@ extern void nv50_init_query_functions(struct nv50_context *nv50); extern void nv50_screen_init_miptree_functions(struct pipe_screen *pscreen); +extern int +nv50_surface_do_copy(struct nv50_screen *screen, struct pipe_surface *dst, + int dx, int dy, struct pipe_surface *src, int sx, int sy, + int w, int h); + /* nv50_draw.c */ extern struct draw_stage *nv50_draw_render_stage(struct nv50_context *nv50); diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c index c6e65c98160..91091d53f57 100644 --- a/src/gallium/drivers/nv50/nv50_miptree.c +++ b/src/gallium/drivers/nv50/nv50_miptree.c @@ -104,6 +104,31 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp) return &mt->base; } +static struct pipe_texture * +nv50_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt, + const unsigned *stride, struct pipe_buffer *pb) +{ + struct nv50_miptree *mt; + + /* Only supports 2D, non-mipmapped textures for the moment */ + if (pt->target != PIPE_TEXTURE_2D || pt->last_level != 0 || + pt->depth[0] != 1) + return NULL; + + mt = CALLOC_STRUCT(nv50_miptree); + if (!mt) + return NULL; + + mt->base = *pt; + mt->base.refcount = 1; + mt->base.screen = pscreen; + mt->image_nr = 1; + mt->level[0].image_offset = CALLOC(1, sizeof(unsigned)); + + pipe_buffer_reference(pscreen, &mt->buffer, pb); + return &mt->base; +} + static INLINE void mark_dirty(uint32_t *flags, unsigned image) { @@ -141,7 +166,7 @@ void nv50_miptree_sync(struct pipe_screen *pscreen, struct nv50_miptree *mt, unsigned level, unsigned image) { - struct nouveau_winsys *nvws = nv50_screen(pscreen)->nvws; + struct nv50_screen *nvscreen = nv50_screen(pscreen); struct nv50_miptree_level *lvl = &mt->level[level]; struct pipe_surface *dst, *src; unsigned face = 0, zslice = 0; @@ -172,7 +197,7 @@ nv50_miptree_sync(struct pipe_screen *pscreen, struct nv50_miptree *mt, dst = pscreen->get_tex_surface(pscreen, &mt->base, face, level, zslice, PIPE_BUFFER_USAGE_GPU_READ); - nvws->surface_copy(nvws, dst, 0, 0, src, 0, 0, dst->width, dst->height); + nv50_surface_do_copy(nvscreen, dst, 0, 0, src, 0, 0, dst->width, dst->height); pscreen->tex_surface_release(pscreen, &dst); pscreen->tex_surface_release(pscreen, &src); @@ -183,7 +208,7 @@ static void nv50_miptree_sync_cpu(struct pipe_screen *pscreen, struct nv50_miptree *mt, unsigned level, unsigned image) { - struct nouveau_winsys *nvws = nv50_screen(pscreen)->nvws; + struct nv50_screen *nvscreen = nv50_screen(pscreen); struct nv50_miptree_level *lvl = &mt->level[level]; struct pipe_surface *dst, *src; unsigned face = 0, zslice = 0; @@ -204,7 +229,7 @@ nv50_miptree_sync_cpu(struct pipe_screen *pscreen, struct nv50_miptree *mt, dst = pscreen->get_tex_surface(pscreen, &mt->base, face, level, zslice, PIPE_BUFFER_USAGE_CPU_READ); - nvws->surface_copy(nvws, dst, 0, 0, src, 0, 0, dst->width, dst->height); + nv50_surface_do_copy(nvscreen, dst, 0, 0, src, 0, 0, dst->width, dst->height); pscreen->tex_surface_release(pscreen, &dst); pscreen->tex_surface_release(pscreen, &src); @@ -287,6 +312,7 @@ void nv50_screen_init_miptree_functions(struct pipe_screen *pscreen) { pscreen->texture_create = nv50_miptree_create; + pscreen->texture_blanket = nv50_miptree_blanket; pscreen->texture_release = nv50_miptree_release; pscreen->get_tex_surface = nv50_miptree_surface_new; pscreen->tex_surface_release = nv50_miptree_surface_del; diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index b902c8cf53f..14c5d47e790 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -1545,13 +1545,16 @@ static void nv50_program_upload_data(struct nv50_context *nv50, float *map, unsigned start, unsigned count) { + struct nouveau_channel *chan = nv50->screen->nvws->channel; + struct nouveau_grobj *tesla = nv50->screen->tesla; + while (count) { unsigned nr = count > 2047 ? 2047 : count; - BEGIN_RING(tesla, 0x00000f00, 1); - OUT_RING ((NV50_CB_PMISC << 0) | (start << 8)); - BEGIN_RING(tesla, 0x40000f04, nr); - OUT_RINGp (map, nr); + BEGIN_RING(chan, tesla, 0x00000f00, 1); + OUT_RING (chan, (NV50_CB_PMISC << 0) | (start << 8)); + BEGIN_RING(chan, tesla, 0x40000f04, nr); + OUT_RINGp (chan, map, nr); map += nr; start += nr; @@ -1598,6 +1601,8 @@ nv50_program_validate_data(struct nv50_context *nv50, struct nv50_program *p) static void nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p) { + struct nouveau_channel *chan = nv50->screen->nvws->channel; + struct nouveau_grobj *tesla = nv50->screen->tesla; struct pipe_winsys *ws = nv50->pipe.winsys; struct nv50_program_exec *e; struct nouveau_stateobj *so; @@ -1664,14 +1669,14 @@ nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p) nr = MIN2(count, 2047); nr = MIN2(nvws->channel->pushbuf->remaining, nr); if (nvws->channel->pushbuf->remaining < (nr + 3)) { - FIRE_RING(NULL); + FIRE_RING(chan); continue; } - BEGIN_RING(tesla, 0x0f00, 1); - OUT_RING ((start << 8) | NV50_CB_PUPLOAD); - BEGIN_RING(tesla, 0x40000f04, nr); - OUT_RINGp (up + start, nr); + BEGIN_RING(chan, tesla, 0x0f00, 1); + OUT_RING (chan, (start << 8) | NV50_CB_PUPLOAD); + BEGIN_RING(chan, tesla, 0x40000f04, nr); + OUT_RINGp (chan, up + start, nr); start += nr; count -= nr; diff --git a/src/gallium/drivers/nv50/nv50_query.c b/src/gallium/drivers/nv50/nv50_query.c index 1b3a41340a9..20745ceab8b 100644 --- a/src/gallium/drivers/nv50/nv50_query.c +++ b/src/gallium/drivers/nv50/nv50_query.c @@ -71,12 +71,14 @@ static void nv50_query_begin(struct pipe_context *pipe, struct pipe_query *pq) { struct nv50_context *nv50 = nv50_context(pipe); + struct nouveau_channel *chan = nv50->screen->nvws->channel; + struct nouveau_grobj *tesla = nv50->screen->tesla; struct nv50_query *q = nv50_query(pq); - BEGIN_RING(tesla, 0x1530, 1); - OUT_RING (1); - BEGIN_RING(tesla, 0x1514, 1); - OUT_RING (1); + BEGIN_RING(chan, tesla, 0x1530, 1); + OUT_RING (chan, 1); + BEGIN_RING(chan, tesla, 0x1514, 1); + OUT_RING (chan, 1); q->ready = FALSE; } @@ -85,14 +87,17 @@ static void nv50_query_end(struct pipe_context *pipe, struct pipe_query *pq) { struct nv50_context *nv50 = nv50_context(pipe); + struct nouveau_channel *chan = nv50->screen->nvws->channel; + struct nouveau_grobj *tesla = nv50->screen->tesla; struct nv50_query *q = nv50_query(pq); - BEGIN_RING(tesla, 0x1b00, 4); - OUT_RELOCh(q->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCl(q->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RING (0x00000000); - OUT_RING (0x0100f002); - FIRE_RING (NULL); + WAIT_RING (chan, 5); + BEGIN_RING(chan, tesla, 0x1b00, 4); + OUT_RELOCh(chan, q->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCl(chan, q->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RING (chan, 0x00000000); + OUT_RING (chan, 0x0100f002); + FIRE_RING (chan); } static boolean diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 6cddddacd5b..58d7a621a80 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -173,6 +173,14 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) return NULL; screen->nvws = nvws; + /* 2D object */ + ret = nvws->grobj_alloc(nvws, NV50_2D, &screen->eng2d); + if (ret) { + NOUVEAU_ERR("Error creating 2D object: %d\n", ret); + nv50_screen_destroy(&screen->pipe); + return NULL; + } + /* 3D object */ if ((chipset & 0xf0) != 0x50 && (chipset & 0xf0) != 0x80) { NOUVEAU_ERR("Not a G8x chipset\n"); @@ -218,6 +226,22 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) return NULL; } + /* Static 2D init */ + so = so_new(64, 0); + so_method(so, screen->eng2d, NV50_2D_DMA_NOTIFY, 4); + so_data (so, screen->sync->handle); + so_data (so, screen->nvws->channel->vram->handle); + so_data (so, screen->nvws->channel->vram->handle); + so_data (so, screen->nvws->channel->vram->handle); + so_method(so, screen->eng2d, NV50_2D_OPERATION, 1); + so_data (so, NV50_2D_OPERATION_SRCCOPY); + so_method(so, screen->eng2d, 0x0290, 1); + so_data (so, 0); + so_method(so, screen->eng2d, 0x0888, 1); + so_data (so, 1); + so_emit(nvws, so); + so_ref(NULL, &so); + /* Static tesla init */ so = so_new(256, 20); diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h index 400ddcef06d..c888ca071c8 100644 --- a/src/gallium/drivers/nv50/nv50_screen.h +++ b/src/gallium/drivers/nv50/nv50_screen.h @@ -11,6 +11,7 @@ struct nv50_screen { unsigned cur_pctx; struct nouveau_grobj *tesla; + struct nouveau_grobj *eng2d; struct nouveau_notifier *sync; struct pipe_buffer *constbuf; diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index 602d76ac743..948112ffa9f 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -47,9 +47,11 @@ nv50_state_validate_fb(struct nv50_context *nv50) so_method(so, tesla, NV50TCL_RT_ADDRESS_HIGH(i), 5); so_reloc (so, nv50_surface_buffer(fb->cbufs[i]), fb->cbufs[i]->offset, - NOUVEAU_BO_VRAM | NOUVEAU_BO_HIGH, 0, 0); + NOUVEAU_BO_VRAM | NOUVEAU_BO_HIGH | + NOUVEAU_BO_RDWR, 0, 0); so_reloc (so, nv50_surface_buffer(fb->cbufs[i]), fb->cbufs[i]->offset, - NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW, 0, 0); + NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW | + NOUVEAU_BO_RDWR, 0, 0); switch (fb->cbufs[i]->format) { case PIPE_FORMAT_A8R8G8B8_UNORM: so_data(so, 0xcf); @@ -82,9 +84,11 @@ nv50_state_validate_fb(struct nv50_context *nv50) so_method(so, tesla, NV50TCL_ZETA_ADDRESS_HIGH, 5); so_reloc (so, nv50_surface_buffer(fb->zsbuf), fb->zsbuf->offset, - NOUVEAU_BO_VRAM | NOUVEAU_BO_HIGH, 0, 0); + NOUVEAU_BO_VRAM | NOUVEAU_BO_HIGH | + NOUVEAU_BO_RDWR, 0, 0); so_reloc (so, nv50_surface_buffer(fb->zsbuf), fb->zsbuf->offset, - NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW, 0, 0); + NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW | + NOUVEAU_BO_RDWR, 0, 0); switch (fb->zsbuf->format) { case PIPE_FORMAT_Z24S8_UNORM: so_data(so, 0x16); diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c index 8ebbc84817e..f2dd2eb30be 100644 --- a/src/gallium/drivers/nv50/nv50_surface.c +++ b/src/gallium/drivers/nv50/nv50_surface.c @@ -20,6 +20,9 @@ * SOFTWARE. */ +#define __NOUVEAU_PUSH_H__ +#include <stdint.h> +#include "nouveau/nouveau_pushbuf.h" #include "nv50_context.h" #include "pipe/p_defines.h" #include "pipe/internal/p_winsys_screen.h" @@ -27,6 +30,118 @@ #include "util/u_tile.h" +static INLINE int +nv50_format(enum pipe_format format) +{ + switch (format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + return NV50_2D_DST_FORMAT_32BPP; + case PIPE_FORMAT_X8R8G8B8_UNORM: + return NV50_2D_DST_FORMAT_24BPP; + case PIPE_FORMAT_R5G6B5_UNORM: + return NV50_2D_DST_FORMAT_16BPP; + case PIPE_FORMAT_A8_UNORM: + return NV50_2D_DST_FORMAT_8BPP; + default: + return -1; + } +} + +static int +nv50_surface_set(struct nv50_screen *screen, struct pipe_surface *ps, int dst) +{ + struct nouveau_channel *chan = screen->nvws->channel; + struct nouveau_grobj *eng2d = screen->eng2d; + struct nouveau_bo *bo; + int format, mthd = dst ? NV50_2D_DST_FORMAT : NV50_2D_SRC_FORMAT; + int flags = NOUVEAU_BO_VRAM | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD); + + bo = screen->nvws->get_bo(nv50_miptree(ps->texture)->buffer); + if (!bo) + return 1; + + format = nv50_format(ps->format); + if (format < 0) + return 1; + + if (!bo->tiled) { + BEGIN_RING(chan, eng2d, mthd, 2); + OUT_RING (chan, format); + OUT_RING (chan, 1); + BEGIN_RING(chan, eng2d, mthd + 0x14, 5); + OUT_RING (chan, ps->stride); + OUT_RING (chan, ps->width); + OUT_RING (chan, ps->height); + OUT_RELOCh(chan, bo, ps->offset, flags); + OUT_RELOCl(chan, bo, ps->offset, flags); + } else { + BEGIN_RING(chan, eng2d, mthd, 5); + OUT_RING (chan, 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, ps->width); + OUT_RING (chan, ps->height); + OUT_RELOCh(chan, bo, ps->offset, flags); + OUT_RELOCl(chan, bo, ps->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; +} + +int +nv50_surface_do_copy(struct nv50_screen *screen, struct pipe_surface *dst, + int dx, int dy, struct pipe_surface *src, int sx, int sy, + int w, int h) +{ + struct nouveau_channel *chan = screen->nvws->channel; + struct nouveau_grobj *eng2d = screen->eng2d; + int ret; + + WAIT_RING (chan, 32); + + ret = nv50_surface_set(screen, dst, 1); + if (ret) + return ret; + + ret = nv50_surface_set(screen, src, 0); + if (ret) + return ret; + + BEGIN_RING(chan, eng2d, 0x088c, 1); + OUT_RING (chan, 0); + 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); + OUT_RING (chan, sy); + + return 0; +} + static void nv50_surface_copy(struct pipe_context *pipe, boolean flip, struct pipe_surface *dest, unsigned destx, unsigned desty, @@ -34,17 +149,19 @@ nv50_surface_copy(struct pipe_context *pipe, boolean flip, unsigned width, unsigned height) { struct nv50_context *nv50 = (struct nv50_context *)pipe; - struct nouveau_winsys *nvws = nv50->screen->nvws; + struct nv50_screen *screen = nv50->screen; + + assert(src->format == dest->format); if (flip) { desty += height; while (height--) { - nvws->surface_copy(nvws, dest, destx, desty--, src, - srcx, srcy++, width, 1); + nv50_surface_do_copy(screen, dest, destx, desty--, src, + srcx, srcy++, width, 1); } } else { - nvws->surface_copy(nvws, dest, destx, desty, src, srcx, srcy, - width, height); + nv50_surface_do_copy(screen, dest, destx, desty, src, srcx, + srcy, width, height); } } @@ -54,9 +171,30 @@ 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->screen->nvws; + struct nv50_screen *screen = nv50->screen; + struct nouveau_channel *chan = screen->nvws->channel; + struct nouveau_grobj *eng2d = screen->eng2d; + int format, ret; + + format = nv50_format(dest->format); + if (format < 0) + return; + + WAIT_RING (chan, 32); + + ret = nv50_surface_set(screen, dest, 1); + if (ret) + return; - nvws->surface_fill(nvws, dest, destx, desty, width, height, value); + BEGIN_RING(chan, eng2d, 0x0580, 3); + OUT_RING (chan, 4); + OUT_RING (chan, format); + OUT_RING (chan, value); + BEGIN_RING(chan, eng2d, NV50_2D_RECT_X1, 4); + OUT_RING (chan, destx); + OUT_RING (chan, desty); + OUT_RING (chan, width); + OUT_RING (chan, height); } static void * diff --git a/src/gallium/drivers/nv50/nv50_tex.c b/src/gallium/drivers/nv50/nv50_tex.c index 239407c92bb..675f9b20cbc 100644 --- a/src/gallium/drivers/nv50/nv50_tex.c +++ b/src/gallium/drivers/nv50/nv50_tex.c @@ -117,13 +117,15 @@ nv50_tex_construct(struct nouveau_stateobj *so, struct nv50_miptree *mt) return 1; } - so_reloc(so, mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW, 0, 0); + so_reloc(so, mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW | + NOUVEAU_BO_RD, 0, 0); so_data (so, 0xd0005000); so_data (so, 0x00300000); so_data (so, mt->base.width[0]); so_data (so, (mt->base.depth[0] << 16) | mt->base.height[0]); so_data (so, 0x03000000); - so_reloc(so, mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_HIGH, 0, 0); + so_reloc(so, mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_HIGH | + NOUVEAU_BO_RD, 0, 0); return 0; } diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index c482a4c241e..0c970adb03a 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -53,25 +53,27 @@ nv50_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, unsigned count) { struct nv50_context *nv50 = nv50_context(pipe); + struct nouveau_channel *chan = nv50->screen->nvws->channel; + struct nouveau_grobj *tesla = nv50->screen->tesla; nv50_state_validate(nv50); - BEGIN_RING(tesla, 0x142c, 1); - OUT_RING (0); - BEGIN_RING(tesla, 0x142c, 1); - OUT_RING (0); - BEGIN_RING(tesla, 0x1440, 1); - OUT_RING (0); - BEGIN_RING(tesla, 0x1334, 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); + BEGIN_RING(chan, tesla, 0x142c, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, tesla, 0x142c, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, tesla, 0x1440, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, tesla, 0x1334, 1); + OUT_RING (chan, 0); + + BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1); + OUT_RING (chan, nv50_prim(mode)); + BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BUFFER_FIRST, 2); + OUT_RING (chan, start); + OUT_RING (chan, count); + BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1); + OUT_RING (chan, 0); pipe->flush(pipe, 0, NULL); return TRUE; @@ -81,11 +83,14 @@ static INLINE void nv50_draw_elements_inline_u08(struct nv50_context *nv50, uint8_t *map, unsigned start, unsigned count) { + struct nouveau_channel *chan = nv50->screen->nvws->channel; + struct nouveau_grobj *tesla = nv50->screen->tesla; + map += start; if (count & 1) { - BEGIN_RING(tesla, 0x15e8, 1); - OUT_RING (map[0]); + BEGIN_RING(chan, tesla, 0x15e8, 1); + OUT_RING (chan, map[0]); map++; count--; } @@ -94,9 +99,9 @@ nv50_draw_elements_inline_u08(struct nv50_context *nv50, uint8_t *map, unsigned nr = count > 2046 ? 2046 : count; int i; - BEGIN_RING(tesla, 0x400015f0, nr >> 1); + BEGIN_RING(chan, tesla, 0x400015f0, nr >> 1); for (i = 0; i < nr; i += 2) - OUT_RING ((map[1] << 16) | map[0]); + OUT_RING (chan, (map[1] << 16) | map[0]); count -= nr; map += nr; @@ -107,11 +112,14 @@ static INLINE void nv50_draw_elements_inline_u16(struct nv50_context *nv50, uint16_t *map, unsigned start, unsigned count) { + struct nouveau_channel *chan = nv50->screen->nvws->channel; + struct nouveau_grobj *tesla = nv50->screen->tesla; + map += start; if (count & 1) { - BEGIN_RING(tesla, 0x15e8, 1); - OUT_RING (map[0]); + BEGIN_RING(chan, tesla, 0x15e8, 1); + OUT_RING (chan, map[0]); map++; count--; } @@ -120,9 +128,9 @@ nv50_draw_elements_inline_u16(struct nv50_context *nv50, uint16_t *map, unsigned nr = count > 2046 ? 2046 : count; int i; - BEGIN_RING(tesla, 0x400015f0, nr >> 1); + BEGIN_RING(chan, tesla, 0x400015f0, nr >> 1); for (i = 0; i < nr; i += 2) - OUT_RING ((map[1] << 16) | map[0]); + OUT_RING (chan, (map[1] << 16) | map[0]); count -= nr; map += nr; @@ -133,13 +141,16 @@ static INLINE void nv50_draw_elements_inline_u32(struct nv50_context *nv50, uint8_t *map, unsigned start, unsigned count) { + struct nouveau_channel *chan = nv50->screen->nvws->channel; + struct nouveau_grobj *tesla = nv50->screen->tesla; + map += start; while (count) { unsigned nr = count > 2047 ? 2047 : count; - BEGIN_RING(tesla, 0x400015e8, nr); - OUT_RINGp (map, nr); + BEGIN_RING(chan, tesla, 0x400015e8, nr); + OUT_RINGp (chan, map, nr); count -= nr; map += nr; @@ -152,18 +163,20 @@ nv50_draw_elements(struct pipe_context *pipe, unsigned mode, unsigned start, unsigned count) { struct nv50_context *nv50 = nv50_context(pipe); + struct nouveau_channel *chan = nv50->screen->nvws->channel; + struct nouveau_grobj *tesla = nv50->screen->tesla; struct pipe_winsys *ws = pipe->winsys; void *map = ws->buffer_map(ws, indexBuffer, PIPE_BUFFER_USAGE_CPU_READ); nv50_state_validate(nv50); - BEGIN_RING(tesla, 0x142c, 1); - OUT_RING (0); - BEGIN_RING(tesla, 0x142c, 1); - OUT_RING (0); + BEGIN_RING(chan, tesla, 0x142c, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, tesla, 0x142c, 1); + OUT_RING (chan, 0); - BEGIN_RING(tesla, NV50TCL_VERTEX_BEGIN, 1); - OUT_RING (nv50_prim(mode)); + BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1); + OUT_RING (chan, nv50_prim(mode)); switch (indexSize) { case 1: nv50_draw_elements_inline_u08(nv50, map, start, count); @@ -177,8 +190,8 @@ nv50_draw_elements(struct pipe_context *pipe, default: assert(0); } - BEGIN_RING(tesla, NV50TCL_VERTEX_END, 1); - OUT_RING (0); + BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1); + OUT_RING (chan, 0); pipe->flush(pipe, 0, NULL); return TRUE; |