summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mesa/drivers/dri/nouveau_winsys/nouveau_bo.c33
-rw-r--r--src/mesa/drivers/dri/nouveau_winsys/nouveau_context.c30
-rw-r--r--src/mesa/drivers/dri/nouveau_winsys/nouveau_context.h14
-rw-r--r--src/mesa/drivers/dri/nouveau_winsys/nouveau_drmif.h6
-rw-r--r--src/mesa/drivers/dri/nouveau_winsys/nouveau_screen.c2
-rw-r--r--src/mesa/drivers/dri/nouveau_winsys/nouveau_screen.h2
-rw-r--r--src/mesa/drivers/dri/nouveau_winsys/nouveau_swapbuffers.c18
-rw-r--r--src/mesa/drivers/dri/nouveau_winsys/nouveau_winsys.c45
-rw-r--r--src/mesa/drivers/dri/nouveau_winsys/nv04_region.c92
-rw-r--r--src/mesa/drivers/dri/nouveau_winsys/nv50_region.c154
-rw-r--r--src/mesa/pipe/nouveau/nouveau_winsys.h6
-rw-r--r--src/mesa/pipe/nv40/nv40_fragprog.c1
-rw-r--r--src/mesa/pipe/nv40/nv40_miptree.c1
-rw-r--r--src/mesa/pipe/nv40/nv40_region.c6
-rw-r--r--src/mesa/pipe/nv40/nv40_state_tex.c1
-rw-r--r--src/mesa/pipe/nv40/nv40_vbo.c1
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;