diff options
author | Ben Skeggs <skeggsb@gmail.com> | 2007-12-05 11:57:50 +1100 |
---|---|---|
committer | Ben Skeggs <skeggsb@gmail.com> | 2007-12-05 11:57:50 +1100 |
commit | 97f8c39d916e80c0dbb0eae9a6c5109555a1f1b5 (patch) | |
tree | 09dffe1e06b352135e81a44c66bc243b4f642a20 /src/mesa | |
parent | 042b7dfd0e15ccd0fcad0c141477091c006e0815 (diff) |
nouveau: g8x winsys support, yay softpipe!
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/drivers/dri/nouveau_winsys/nouveau_bo.c | 33 | ||||
-rw-r--r-- | src/mesa/drivers/dri/nouveau_winsys/nouveau_context.c | 30 | ||||
-rw-r--r-- | src/mesa/drivers/dri/nouveau_winsys/nouveau_context.h | 14 | ||||
-rw-r--r-- | src/mesa/drivers/dri/nouveau_winsys/nouveau_drmif.h | 6 | ||||
-rw-r--r-- | src/mesa/drivers/dri/nouveau_winsys/nouveau_screen.c | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/nouveau_winsys/nouveau_screen.h | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/nouveau_winsys/nouveau_swapbuffers.c | 18 | ||||
-rw-r--r-- | src/mesa/drivers/dri/nouveau_winsys/nouveau_winsys.c | 45 | ||||
-rw-r--r-- | src/mesa/drivers/dri/nouveau_winsys/nv04_region.c | 92 | ||||
-rw-r--r-- | src/mesa/drivers/dri/nouveau_winsys/nv50_region.c | 154 | ||||
-rw-r--r-- | src/mesa/pipe/nouveau/nouveau_winsys.h | 6 | ||||
-rw-r--r-- | src/mesa/pipe/nv40/nv40_fragprog.c | 1 | ||||
-rw-r--r-- | src/mesa/pipe/nv40/nv40_miptree.c | 1 | ||||
-rw-r--r-- | src/mesa/pipe/nv40/nv40_region.c | 6 | ||||
-rw-r--r-- | src/mesa/pipe/nv40/nv40_state_tex.c | 1 | ||||
-rw-r--r-- | src/mesa/pipe/nv40/nv40_vbo.c | 1 |
16 files changed, 285 insertions, 127 deletions
diff --git a/src/mesa/drivers/dri/nouveau_winsys/nouveau_bo.c b/src/mesa/drivers/dri/nouveau_winsys/nouveau_bo.c index 3b508cf92b..f1981b9777 100644 --- a/src/mesa/drivers/dri/nouveau_winsys/nouveau_bo.c +++ b/src/mesa/drivers/dri/nouveau_winsys/nouveau_bo.c @@ -31,45 +31,12 @@ int nouveau_bo_init(struct nouveau_device *userdev) { - struct nouveau_device_priv *nv = nouveau_device(userdev); - struct nouveau_channel *chan; - int ret; - - if ((ret = nouveau_channel_alloc(userdev, 0x80000001, 0x80000002, - &nv->bufmgr.channel))) - return ret; - chan = nv->bufmgr.channel; - - if ((ret = nouveau_notifier_alloc(nv->bufmgr.channel, 0x80000003, 1, - &nv->bufmgr.notify))) - return ret; - - if ((ret = nouveau_grobj_alloc(nv->bufmgr.channel, 0x80000004, 0x39, - &nv->bufmgr.m2mf))) - return ret; - - nouveau_notifier_reset(nv->bufmgr.notify, 0); - BEGIN_RING_CH(chan, nv->bufmgr.m2mf, 0x180, 1); - OUT_RING_CH (chan, nv->bufmgr.notify->handle); - BEGIN_RING_CH(chan, nv->bufmgr.m2mf, 0x104, 1); - OUT_RING_CH (chan, 0); - BEGIN_RING_CH(chan, nv->bufmgr.m2mf, 0x100, 1); - OUT_RING_CH (chan, 0); - FIRE_RING_CH (chan); - if ((ret = nouveau_notifier_wait_status(nv->bufmgr.notify, 0, 0, 2000))) - return ret; - return 0; } void nouveau_bo_takedown(struct nouveau_device *userdev) { - struct nouveau_device_priv *nv = nouveau_device(userdev); - - nouveau_notifier_free(&nv->bufmgr.notify); - nouveau_grobj_free(&nv->bufmgr.m2mf); - nouveau_channel_free(&nv->bufmgr.channel); } static int diff --git a/src/mesa/drivers/dri/nouveau_winsys/nouveau_context.c b/src/mesa/drivers/dri/nouveau_winsys/nouveau_context.c index 67df43647a..70655a1a7d 100644 --- a/src/mesa/drivers/dri/nouveau_winsys/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau_winsys/nouveau_context.c @@ -125,6 +125,36 @@ nouveau_context_create(const __GLcontextModes *glVis, debug_control); #endif + /*XXX: Hack up a fake region and buffer object for front buffer. + * This will go away with TTM, replaced with a simple reference + * of the front buffer handle passed to us by the DDX. + */ + { + struct pipe_region *fb_region; + struct nouveau_bo_priv *fb_bo; + + fb_bo = calloc(1, sizeof(struct nouveau_bo_priv)); + fb_bo->drm.offset = nv_screen->front_offset; + fb_bo->drm.flags = NOUVEAU_MEM_FB; + fb_bo->drm.size = nv_screen->front_pitch * + nv_screen->front_height; + fb_bo->refcount = 1; + fb_bo->base.flags = NOUVEAU_BO_PIN | NOUVEAU_BO_VRAM; + fb_bo->base.offset = fb_bo->drm.offset; + fb_bo->base.handle = (unsigned long)fb_bo; + fb_bo->base.size = fb_bo->drm.size; + fb_bo->base.device = nv_screen->device; + + fb_region = calloc(1, sizeof(struct pipe_region)); + fb_region->cpp = nv_screen->front_cpp; + fb_region->pitch = nv_screen->front_pitch / fb_region->cpp; + fb_region->height = nv_screen->front_height; + fb_region->refcount = 1; + fb_region->buffer = (void *)fb_bo; + + nv->frontbuffer = fb_region; + } + if ((ret = nouveau_grobj_alloc(nv->channel, 0x00000000, 0x30, &nv->NvNull))) { NOUVEAU_ERR("Error creating NULL object: %d\n", ret); diff --git a/src/mesa/drivers/dri/nouveau_winsys/nouveau_context.h b/src/mesa/drivers/dri/nouveau_winsys/nouveau_context.h index f2557af935..70110f9768 100644 --- a/src/mesa/drivers/dri/nouveau_winsys/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau_winsys/nouveau_context.h @@ -31,6 +31,7 @@ struct nouveau_context { drmLock drm_lock; GLboolean locked; struct nouveau_screen *nv_screen; + struct pipe_region *frontbuffer; /* Bufmgr */ struct { @@ -53,14 +54,19 @@ struct nouveau_context { struct nouveau_grobj *NvImageBlit; struct nouveau_grobj *NvGdiRect; struct nouveau_grobj *NvM2MF; + struct nouveau_grobj *Nv2D; uint32_t next_handle; uint32_t next_sequence; /* pipe_region accel */ - int (*region_display)(void); - int (*region_copy)(struct nouveau_context *, struct pipe_region *, - unsigned, unsigned, unsigned, struct pipe_region *, - unsigned, unsigned, unsigned, unsigned, unsigned); + struct pipe_region *region_src, *region_dst; + unsigned region_src_offset, region_dst_offset; + int (*region_copy_prep)(struct nouveau_context *, + struct pipe_region *dst, uint32_t dst_offset, + struct pipe_region *src, uint32_t src_offset); + void (*region_copy)(struct nouveau_context *, unsigned dx, unsigned dy, + unsigned sx, unsigned sy, unsigned w, unsigned h); + void (*region_copy_done)(struct nouveau_context *); int (*region_fill)(struct nouveau_context *, struct pipe_region *, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned); diff --git a/src/mesa/drivers/dri/nouveau_winsys/nouveau_drmif.h b/src/mesa/drivers/dri/nouveau_winsys/nouveau_drmif.h index 1a21da6985..df98890f8e 100644 --- a/src/mesa/drivers/dri/nouveau_winsys/nouveau_drmif.h +++ b/src/mesa/drivers/dri/nouveau_winsys/nouveau_drmif.h @@ -40,12 +40,6 @@ struct nouveau_device_priv { drm_context_t ctx; drmLock *lock; int needs_close; - - struct { - struct nouveau_channel *channel; - struct nouveau_notifier *notify; - struct nouveau_grobj *m2mf; - } bufmgr; }; #define nouveau_device(n) ((struct nouveau_device_priv *)(n)) diff --git a/src/mesa/drivers/dri/nouveau_winsys/nouveau_screen.c b/src/mesa/drivers/dri/nouveau_winsys/nouveau_screen.c index 16c4324164..6554082e62 100644 --- a/src/mesa/drivers/dri/nouveau_winsys/nouveau_screen.c +++ b/src/mesa/drivers/dri/nouveau_winsys/nouveau_screen.c @@ -61,6 +61,8 @@ nouveau_screen_create(__DRIscreenPrivate *driScrnPriv) nv_screen->front_offset = nv_dri->front_offset; nv_screen->front_pitch = nv_dri->front_pitch * (nv_dri->bpp / 8); + nv_screen->front_cpp = nv_dri->bpp / 8; + nv_screen->front_height = nv_dri->height; return GL_TRUE; } diff --git a/src/mesa/drivers/dri/nouveau_winsys/nouveau_screen.h b/src/mesa/drivers/dri/nouveau_winsys/nouveau_screen.h index e53cd873a7..019823bd44 100644 --- a/src/mesa/drivers/dri/nouveau_winsys/nouveau_screen.h +++ b/src/mesa/drivers/dri/nouveau_winsys/nouveau_screen.h @@ -12,6 +12,8 @@ struct nouveau_screen { uint32_t front_offset; uint32_t front_pitch; + uint32_t front_cpp; + uint32_t front_height; }; #endif diff --git a/src/mesa/drivers/dri/nouveau_winsys/nouveau_swapbuffers.c b/src/mesa/drivers/dri/nouveau_winsys/nouveau_swapbuffers.c index 57598f9cab..5b2e76b942 100644 --- a/src/mesa/drivers/dri/nouveau_winsys/nouveau_swapbuffers.c +++ b/src/mesa/drivers/dri/nouveau_winsys/nouveau_swapbuffers.c @@ -14,7 +14,6 @@ nouveau_copy_buffer(__DRIdrawablePrivate *dPriv, struct pipe_surface *surf, const drm_clip_rect_t *rect) { struct nouveau_context *nv = dPriv->driContextPriv->driverPrivate; - struct nouveau_screen *nv_screen = nv->nv_screen; struct pipe_region *p_region = surf->region; drm_clip_rect_t *pbox; int nbox, i; @@ -27,17 +26,7 @@ nouveau_copy_buffer(__DRIdrawablePrivate *dPriv, struct pipe_surface *surf, pbox = dPriv->pClipRects; nbox = dPriv->numClipRects; - BEGIN_RING(NvCtxSurf2D, 0x184, 2); - OUT_RELOCo(p_region->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RING (nv->channel->vram->handle); - - BEGIN_RING(NvCtxSurf2D, 0x300, 4); - OUT_RING ((p_region->cpp == 4) ? 6 : 4); - OUT_RING ((nv_screen->front_pitch << 16) | - (p_region->pitch * p_region->cpp)); - OUT_RELOCl(p_region->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RING (nv_screen->front_offset); - + nv->region_copy_prep(nv, nv->frontbuffer, 0, p_region, 0); for (i = 0; i < nbox; i++, pbox++) { int sx, sy, dx, dy, w, h; @@ -48,10 +37,7 @@ nouveau_copy_buffer(__DRIdrawablePrivate *dPriv, struct pipe_surface *surf, w = pbox->x2 - pbox->x1; h = pbox->y2 - pbox->y1; - BEGIN_RING(NvImageBlit, 0x300, 3); - OUT_RING ((sy << 16) | sx); - OUT_RING ((dy << 16) | dx); - OUT_RING (( h << 16) | w); + nv->region_copy(nv, dx, dy, sx, sy, w, h); } FIRE_RING(); diff --git a/src/mesa/drivers/dri/nouveau_winsys/nouveau_winsys.c b/src/mesa/drivers/dri/nouveau_winsys/nouveau_winsys.c index bdc89b9531..6840ec5f75 100644 --- a/src/mesa/drivers/dri/nouveau_winsys/nouveau_winsys.c +++ b/src/mesa/drivers/dri/nouveau_winsys/nouveau_winsys.c @@ -127,6 +127,45 @@ nouveau_pipe_dma_kickoff(struct nouveau_channel *userchan) FIRE_RING_CH(userchan); } +static int +nouveau_pipe_region_copy(struct nouveau_winsys *nvws, struct pipe_region *dst, + unsigned dst_offset, unsigned dx, unsigned dy, + struct pipe_region *src, unsigned src_offset, + unsigned sx, unsigned sy, unsigned w, unsigned h) +{ + struct nouveau_context *nv = nvws->nv; + + if (nv->region_copy_prep(nv, dst, dst_offset, src, src_offset)) + return 1; + nv->region_copy(nv, dx, dy, sx, sy, w, h); + nv->region_copy_done(nv); + + return 0; +} + +static int +nouveau_pipe_region_fill(struct nouveau_winsys *nvws, struct pipe_region *dst, + unsigned dst_offset, unsigned dx, unsigned dy, + unsigned w, unsigned h, unsigned value) +{ + if (nvws->nv->region_fill(nvws->nv, dst, dst_offset, dx, dy, + w, h, value)) + return 1; + return 0; +} + +static int +nouveau_pipe_region_data(struct nouveau_winsys *nvws, struct pipe_region *dst, + unsigned dst_offset, unsigned dx, unsigned dy, + const void *src, unsigned src_pitch, + unsigned sx, unsigned sy, unsigned w, unsigned h) +{ + if (nvws->nv->region_data(nvws->nv, dst, dst_offset, dx, dy, src, + src_pitch, sx, sy, w, h)) + return 1; + return 0; +} + struct pipe_context * nouveau_pipe_create(struct nouveau_context *nv) { @@ -168,9 +207,9 @@ nouveau_pipe_create(struct nouveau_context *nv) nvws->notifier_retval = nouveau_notifier_return_val; nvws->notifier_wait = nouveau_notifier_wait_status; - nvws->region_copy = nv->region_copy; - nvws->region_fill = nv->region_fill; - nvws->region_data = nv->region_data; + nvws->region_copy = nouveau_pipe_region_copy; + nvws->region_fill = nouveau_pipe_region_fill; + nvws->region_data = nouveau_pipe_region_data; return hw_create(nouveau_create_pipe_winsys(nv), nvws, nv->chipset); } diff --git a/src/mesa/drivers/dri/nouveau_winsys/nv04_region.c b/src/mesa/drivers/dri/nouveau_winsys/nv04_region.c index 0fdb38e105..d41588d890 100644 --- a/src/mesa/drivers/dri/nouveau_winsys/nv04_region.c +++ b/src/mesa/drivers/dri/nouveau_winsys/nv04_region.c @@ -26,26 +26,19 @@ nv04_rect_format(int cpp) } } -static int -nv04_region_display(void) -{ - NOUVEAU_ERR("unimplemented\n"); - return 0; -} - -static int -nv04_region_copy_m2mf(struct nouveau_context *nv, struct pipe_region *dst, - unsigned dst_offset, struct pipe_region *src, - unsigned src_offset, unsigned line_len, unsigned height) +static void +nv04_region_copy_m2mf(struct nouveau_context *nv, unsigned dx, unsigned dy, + unsigned sx, unsigned sy, unsigned w, unsigned h) { - BEGIN_RING(NvM2MF, NV_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, 2); - OUT_RELOCo(src->buffer, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | - NOUVEAU_BO_RD); - OUT_RELOCo(dst->buffer, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | - NOUVEAU_BO_WR); + struct pipe_region *dst = nv->region_dst; + struct pipe_region *src = nv->region_dst; + unsigned dst_offset, src_offset; + + dst_offset = nv->region_dst_offset + (dy * dst->pitch + dx) * dst->cpp; + src_offset = nv->region_src_offset + (sy * src->pitch + sx) * src->cpp; - while (height) { - int count = (height > 2047) ? 2047 : height; + while (h) { + int count = (h > 2047) ? 2047 : h; BEGIN_RING(NvM2MF, NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); OUT_RELOCl(src->buffer, src_offset, NOUVEAU_BO_VRAM | @@ -54,32 +47,31 @@ nv04_region_copy_m2mf(struct nouveau_context *nv, struct pipe_region *dst, NOUVEAU_BO_GART | NOUVEAU_BO_WR); OUT_RING (src->pitch * src->cpp); OUT_RING (dst->pitch * dst->cpp); - OUT_RING (line_len); + OUT_RING (w * src->cpp); OUT_RING (count); OUT_RING (0x0101); OUT_RING (0); - height -= count; + h -= count; src_offset += src->pitch * count; dst_offset += dst->pitch * count; } +} - nouveau_notifier_reset(nv->sync_notifier, 0); - BEGIN_RING(NvM2MF, 0x104, 1); - OUT_RING (0); - BEGIN_RING(NvM2MF, 0x100, 1); - OUT_RING (0); - FIRE_RING(); - nouveau_notifier_wait_status(nv->sync_notifier, 0, 0, 2000); - - return 0; +static void +nv04_region_copy_blit(struct nouveau_context *nv, unsigned dx, unsigned dy, + unsigned sx, unsigned sy, unsigned w, unsigned h) +{ + BEGIN_RING(NvImageBlit, 0x0300, 3); + OUT_RING ((sy << 16) | sx); + OUT_RING ((dy << 16) | dx); + OUT_RING (( h << 16) | w); } static int -nv04_region_copy(struct nouveau_context *nv, struct pipe_region *dst, - unsigned dst_offset, unsigned dx, unsigned dy, - struct pipe_region *src, unsigned src_offset, - unsigned sx, unsigned sy, unsigned w, unsigned h) +nv04_region_copy_prep(struct nouveau_context *nv, + struct pipe_region *dst, unsigned dst_offset, + struct pipe_region *src, unsigned src_offset) { int format; @@ -90,10 +82,18 @@ nv04_region_copy(struct nouveau_context *nv, struct pipe_region *dst, * to NV_MEMORY_TO_MEMORY_FORMAT in this case. */ if ((src_offset & 63) || (dst_offset & 63)) { - dst_offset += (dy * dst->pitch + dx) * dst->cpp; - src_offset += (sy * src->pitch + sx) * src->cpp; - return nv04_region_copy_m2mf(nv, dst, dst_offset, src, - src_offset, w * src->cpp, h); + BEGIN_RING(NvM2MF, NV_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, 2); + OUT_RELOCo(src->buffer, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | + NOUVEAU_BO_RD); + OUT_RELOCo(dst->buffer, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | + NOUVEAU_BO_WR); + + nv->region_copy = nv04_region_copy_m2mf; + nv->region_dst = dst; + nv->region_dst_offset = dst_offset; + nv->region_src = src; + nv->region_src_offset = src_offset; + return 0; } @@ -101,21 +101,24 @@ nv04_region_copy(struct nouveau_context *nv, struct pipe_region *dst, NOUVEAU_ERR("Bad cpp = %d\n", dst->cpp); return 1; } + nv->region_copy = nv04_region_copy_blit; BEGIN_RING(NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); OUT_RELOCo(src->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); OUT_RELOCo(dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_FORMAT, 4); OUT_RING (format); OUT_RING (((dst->pitch * dst->cpp) << 16) | (src->pitch * src->cpp)); OUT_RELOCl(src->buffer, src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); OUT_RELOCl(dst->buffer, dst_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(NvImageBlit, 0x0300, 3); - OUT_RING ((sy << 16) | sx); - OUT_RING ((dy << 16) | dx); - OUT_RING (( h << 16) | w); + return 0; +} +static void +nv04_region_copy_done(struct nouveau_context *nv) +{ nouveau_notifier_reset(nv->sync_notifier, 0); BEGIN_RING(NvGdiRect, 0x104, 1); OUT_RING (0); @@ -123,8 +126,6 @@ nv04_region_copy(struct nouveau_context *nv, struct pipe_region *dst, OUT_RING (0); FIRE_RING(); nouveau_notifier_wait_status(nv->sync_notifier, 0, 0, 2000); - - return 0; } static int @@ -238,8 +239,9 @@ nouveau_region_init_nv04(struct nouveau_context *nv) BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT, 1); OUT_RING (NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE); - nv->region_display = nv04_region_display; - nv->region_copy = nv04_region_copy; + nv->region_copy_prep = nv04_region_copy_prep; + nv->region_copy = nv04_region_copy_blit; + nv->region_copy_done = nv04_region_copy_done; nv->region_fill = nv04_region_fill; nv->region_data = nv04_region_data; return 0; diff --git a/src/mesa/drivers/dri/nouveau_winsys/nv50_region.c b/src/mesa/drivers/dri/nouveau_winsys/nv50_region.c index c7450c5c8d..75bfcaf6c8 100644 --- a/src/mesa/drivers/dri/nouveau_winsys/nv50_region.c +++ b/src/mesa/drivers/dri/nouveau_winsys/nv50_region.c @@ -2,21 +2,94 @@ #include "nouveau_context.h" +static INLINE int +nv50_format(int cpp) +{ + switch (cpp) { + case 4: return NV50_2D_DST_FORMAT_32BPP; + case 3: return NV50_2D_DST_FORMAT_24BPP; + case 2: return NV50_2D_DST_FORMAT_16BPP; + case 1: return NV50_2D_DST_FORMAT_8BPP; + default: + return -1; + } +} + static int -nv50_region_display(void) +nv50_region_copy_prep(struct nouveau_context *nv, + struct pipe_region *dst, unsigned dst_offset, + struct pipe_region *src, unsigned src_offset) { - NOUVEAU_ERR("unimplemented\n"); + int surf_format; + + assert(src->cpp == dst->cpp); + + surf_format = nv50_format(dst->cpp); + assert(surf_format >= 0); + + BEGIN_RING(Nv2D, NV50_2D_DMA_IN_MEMORY0, 2); + OUT_RELOCo(src->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCo(dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + BEGIN_RING(Nv2D, NV50_2D_DST_FORMAT, 2); + OUT_RING (surf_format); + OUT_RING (1); + BEGIN_RING(Nv2D, NV50_2D_DST_PITCH, 5); + OUT_RING (dst->pitch * dst->cpp); + OUT_RING (dst->pitch); + OUT_RING (dst->height); + OUT_RELOCh(dst->buffer, dst_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCl(dst->buffer, dst_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(Nv2D, NV50_2D_CLIP_X, 4); + OUT_RING (0); + OUT_RING (0); + OUT_RING (dst->pitch); + OUT_RING (dst->height); + + BEGIN_RING(Nv2D, NV50_2D_SRC_FORMAT, 2); + OUT_RING (surf_format); + OUT_RING (1); + BEGIN_RING(Nv2D, NV50_2D_SRC_PITCH, 5); + OUT_RING (src->pitch * src->cpp); + OUT_RING (src->pitch); + OUT_RING (src->height); + OUT_RELOCh(src->buffer, src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCl(src->buffer, src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + return 0; } -static int -nv50_region_copy(struct nouveau_context *nv, struct pipe_region *dst, - unsigned dst_offset, unsigned dx, unsigned dy, - struct pipe_region *src, unsigned src_offset, +static void +nv50_region_copy(struct nouveau_context *nv, unsigned dx, unsigned dy, unsigned sx, unsigned sy, unsigned w, unsigned h) { - NOUVEAU_ERR("unimplemented!!\n"); - return 0; + BEGIN_RING(Nv2D, 0x0110, 1); + OUT_RING (0); + BEGIN_RING(Nv2D, NV50_2D_BLIT_DST_X, 12); + OUT_RING (dx); + OUT_RING (dy); + OUT_RING (w); + OUT_RING (h); + OUT_RING (0); + OUT_RING (1); + OUT_RING (0); + OUT_RING (1); + OUT_RING (0); + OUT_RING (sx); + OUT_RING (0); + OUT_RING (sy); +} + +static void +nv50_region_copy_done(struct nouveau_context *nv) +{ + nouveau_notifier_reset(nv->sync_notifier, 0); + BEGIN_RING(Nv2D, 0x104, 1); + OUT_RING (0); + BEGIN_RING(Nv2D, 0x100, 1); + OUT_RING (0); + FIRE_RING(); + nouveau_notifier_wait_status(nv->sync_notifier, 0, 0, 2000); } static int @@ -25,7 +98,52 @@ nv50_region_fill(struct nouveau_context *nv, unsigned dx, unsigned dy, unsigned w, unsigned h, unsigned value) { - NOUVEAU_ERR("unimplemented!!\n"); + int surf_format, rect_format; + + surf_format = nv50_format(dst->cpp); + if (surf_format < 0) + return 1; + + rect_format = nv50_format(dst->cpp); + if (rect_format < 0) + return 1; + + BEGIN_RING(Nv2D, NV50_2D_DMA_IN_MEMORY1, 1); + OUT_RELOCo(dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(Nv2D, NV50_2D_DST_FORMAT, 2); + OUT_RING (surf_format); + OUT_RING (1); + BEGIN_RING(Nv2D, NV50_2D_DST_PITCH, 5); + OUT_RING (dst->pitch * dst->cpp); + OUT_RING (dst->pitch); + OUT_RING (dst->height); + OUT_RELOCh(dst->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCl(dst->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(Nv2D, NV50_2D_CLIP_X, 4); + OUT_RING (0); + OUT_RING (0); + OUT_RING (dst->pitch); + OUT_RING (dst->height); + + BEGIN_RING(Nv2D, 0x0580, 4); + OUT_RING (4); + OUT_RING (rect_format); + OUT_RING (value); + + BEGIN_RING(Nv2D, NV50_2D_RECT_X1, 4); + OUT_RING (dx); + OUT_RING (dy); + OUT_RING (dx + w); + OUT_RING (dy + h); + + nouveau_notifier_reset(nv->sync_notifier, 0); + BEGIN_RING(Nv2D, 0x104, 1); + OUT_RING (0); + BEGIN_RING(Nv2D, 0x100, 1); + OUT_RING (0); + FIRE_RING(); + nouveau_notifier_wait_status(nv->sync_notifier, 0, 0, 2000); + return 0; } @@ -42,8 +160,24 @@ nv50_region_data(struct nouveau_context *nv, struct pipe_region *dst, int nouveau_region_init_nv50(struct nouveau_context *nv) { - nv->region_display = nv50_region_display; + int ret; + + ret = nouveau_grobj_alloc(nv->channel, nv->next_handle++, NV50_2D, + &nv->Nv2D); + if (ret) + return ret; + + BEGIN_RING(Nv2D, NV50_2D_DMA_NOTIFY, 1); + OUT_RING (nv->sync_notifier->handle); + BEGIN_RING(Nv2D, NV50_2D_DMA_IN_MEMORY0, 2); + OUT_RING (nv->channel->vram->handle); + OUT_RING (nv->channel->vram->handle); + BEGIN_RING(Nv2D, NV50_2D_OPERATION, 1); + OUT_RING (NV50_2D_OPERATION_SRCCOPY); + + nv->region_copy_prep = nv50_region_copy_prep; nv->region_copy = nv50_region_copy; + nv->region_copy_done = nv50_region_copy_done; nv->region_fill = nv50_region_fill; nv->region_data = nv50_region_data; return 0; diff --git a/src/mesa/pipe/nouveau/nouveau_winsys.h b/src/mesa/pipe/nouveau/nouveau_winsys.h index 28f17cdc8f..1dc15f93ec 100644 --- a/src/mesa/pipe/nouveau/nouveau_winsys.h +++ b/src/mesa/pipe/nouveau/nouveau_winsys.h @@ -53,13 +53,13 @@ struct nouveau_winsys { int (*notifier_wait)(struct nouveau_notifier *, int id, int status, int timeout); - int (*region_copy)(struct nouveau_context *, struct pipe_region *, + int (*region_copy)(struct nouveau_winsys *, struct pipe_region *, unsigned, unsigned, unsigned, struct pipe_region *, unsigned, unsigned, unsigned, unsigned, unsigned); - int (*region_fill)(struct nouveau_context *, struct pipe_region *, + int (*region_fill)(struct nouveau_winsys *, struct pipe_region *, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned); - int (*region_data)(struct nouveau_context *, struct pipe_region *, + int (*region_data)(struct nouveau_winsys *, struct pipe_region *, unsigned, unsigned, unsigned, const void *, unsigned, unsigned, unsigned, unsigned, unsigned); }; diff --git a/src/mesa/pipe/nv40/nv40_fragprog.c b/src/mesa/pipe/nv40/nv40_fragprog.c index ec8cac676e..8f3eeb1f48 100644 --- a/src/mesa/pipe/nv40/nv40_fragprog.c +++ b/src/mesa/pipe/nv40/nv40_fragprog.c @@ -620,7 +620,6 @@ nv40_fragprog_translate(struct nv40_context *nv40, { struct tgsi_parse_context parse; struct nv40_fpc *fpc = NULL; - int i; fpc = calloc(1, sizeof(struct nv40_fpc)); if (!fpc) diff --git a/src/mesa/pipe/nv40/nv40_miptree.c b/src/mesa/pipe/nv40/nv40_miptree.c index 15639f01e9..f5c4206f40 100644 --- a/src/mesa/pipe/nv40/nv40_miptree.c +++ b/src/mesa/pipe/nv40/nv40_miptree.c @@ -7,7 +7,6 @@ boolean nv40_miptree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree *mt) { - struct nv40_context *nv40 = (struct nv40_context *)pipe; boolean swizzled = FALSE; uint width = mt->width0, height = mt->height0, depth = mt->depth0; uint offset; diff --git a/src/mesa/pipe/nv40/nv40_region.c b/src/mesa/pipe/nv40/nv40_region.c index f62bf89d18..572b82bca3 100644 --- a/src/mesa/pipe/nv40/nv40_region.c +++ b/src/mesa/pipe/nv40/nv40_region.c @@ -42,7 +42,7 @@ nv40_region_data(struct pipe_context *pipe, struct nv40_context *nv40 = (struct nv40_context *)pipe; struct nouveau_winsys *nvws = nv40->nvws; - nvws->region_data(nvws->nv, dst, dst_offset, dstx, dsty, + nvws->region_data(nvws, dst, dst_offset, dstx, dsty, src, src_pitch, srcx, srcy, width, height); } @@ -56,7 +56,7 @@ nv40_region_copy(struct pipe_context *pipe, struct pipe_region *dst, struct nv40_context *nv40 = (struct nv40_context *)pipe; struct nouveau_winsys *nvws = nv40->nvws; - nvws->region_copy(nvws->nv, dst, dst_offset, dstx, dsty, + nvws->region_copy(nvws, dst, dst_offset, dstx, dsty, src, src_offset, srcx, srcy, width, height); } @@ -69,7 +69,7 @@ nv40_region_fill(struct pipe_context *pipe, struct nv40_context *nv40 = (struct nv40_context *)pipe; struct nouveau_winsys *nvws = nv40->nvws; - nvws->region_fill(nvws->nv, dst, dst_offset, dstx, dsty, + nvws->region_fill(nvws, dst, dst_offset, dstx, dsty, width, height, value); } diff --git a/src/mesa/pipe/nv40/nv40_state_tex.c b/src/mesa/pipe/nv40/nv40_state_tex.c index bd779df9b3..6902b41ba7 100644 --- a/src/mesa/pipe/nv40/nv40_state_tex.c +++ b/src/mesa/pipe/nv40/nv40_state_tex.c @@ -53,7 +53,6 @@ nv40_tex_format(uint pipe_format) static void nv40_tex_unit_enable(struct nv40_context *nv40, int unit) { - struct nouveau_winsys *nvws = nv40->nvws; struct nv40_sampler_state *ps = nv40->tex_sampler[unit]; struct pipe_mipmap_tree *mt = nv40->tex_miptree[unit]; struct nv40_texture_format *tf; diff --git a/src/mesa/pipe/nv40/nv40_vbo.c b/src/mesa/pipe/nv40/nv40_vbo.c index 2da0001b28..cc71fb99de 100644 --- a/src/mesa/pipe/nv40/nv40_vbo.c +++ b/src/mesa/pipe/nv40/nv40_vbo.c @@ -175,7 +175,6 @@ nv40_vbo_format_to_ncomp(uint format) void nv40_vbo_arrays_update(struct nv40_context *nv40) { - struct nouveau_winsys *nvws = nv40->nvws; struct nv40_vertex_program *vp = nv40->vertprog.active; uint32_t inputs, vtxfmt[16]; int hw, num_hw; |