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/drivers/dri | |
parent | 042b7dfd0e15ccd0fcad0c141477091c006e0815 (diff) |
nouveau: g8x winsys support, yay softpipe!
Diffstat (limited to 'src/mesa/drivers/dri')
10 files changed, 279 insertions, 117 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; |