From e70d801ae9287eab5e82f4d467dc8cd4be1b31a8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 9 Dec 2011 18:15:32 +1000 Subject: WIP: port to new libdrm calim: nv50,nvc0/xv: fix src_w/h width/height confusion --- configure.ac | 2 +- src/Makefile.am | 2 +- src/drmmode_display.c | 30 +- src/nouveau_dri2.c | 30 +- src/nouveau_exa.c | 23 +- src/nouveau_local.h | 186 ++++--- src/nouveau_wfb.c | 4 +- src/nouveau_xv.c | 24 +- src/nv04_accel.h | 34 ++ src/nv04_exa.c | 524 ++++++++++---------- src/nv04_xv_blit.c | 262 +++++----- src/nv10_exa.c | 613 +++++++++++------------ src/nv30_exa.c | 563 ++++++++++----------- src/nv30_shaders.c | 82 ++-- src/nv30_xv_tex.c | 211 ++++---- src/nv40_exa.c | 391 +++++++-------- src/nv40_xv_tex.c | 178 +++---- src/nv50_accel.c | 666 +++++++++++++------------ src/nv50_accel.h | 41 +- src/nv50_exa.c | 728 +++++++++++++--------------- src/nv50_xv.c | 367 ++++++-------- src/nv_accel_common.c | 562 ++++++++++----------- src/nv_dma.c | 77 +-- src/nv_dma.h | 4 +- src/nv_driver.c | 43 +- src/nv_include.h | 11 +- src/nv_proto.h | 2 + src/nv_shadow.c | 3 +- src/nv_type.h | 46 +- src/nvc0_accel.c | 1288 ++++++++++++++++++++++++------------------------- src/nvc0_accel.h | 66 +-- src/nvc0_exa.c | 736 +++++++++++++--------------- src/nvc0_xv.c | 375 ++++++-------- 33 files changed, 3928 insertions(+), 4246 deletions(-) create mode 100644 src/nv04_accel.h diff --git a/configure.ac b/configure.ac index 6a143dc..afb6cde 100644 --- a/configure.ac +++ b/configure.ac @@ -67,7 +67,7 @@ XORG_DRIVER_CHECK_EXT(XV, videoproto) XORG_DRIVER_CHECK_EXT(DPMSExtension, xextproto) # Checks for pkg-config packages -PKG_CHECK_MODULES(LIBDRM_NOUVEAU, libdrm_nouveau) +PKG_CHECK_MODULES(LIBDRM_NOUVEAU, [libdrm_nouveau >= 2.4.25]) AC_SUBST(LIBDRM_NOUVEAU_CFLAGS) AC_SUBST(LIBDRM_NOUVEAU_LIBS) diff --git a/src/Makefile.am b/src/Makefile.am index e9e84ae..879f79c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -33,7 +33,7 @@ nouveau_drv_la_SOURCES = \ nouveau_class.h nouveau_local.h \ nouveau_exa.c nouveau_xv.c nouveau_dri2.c \ nouveau_wfb.c \ - nv_accel_common.c \ + nv_accel_common.c nv04_accel.h \ nv_const.h \ nv_dma.c \ nv_dma.h \ diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 9e15c29..23e8232 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -226,7 +226,7 @@ drmmode_fbcon_copy(ScreenPtr pScreen) if (!fbcon_id) goto fallback; - fb = drmModeGetFB(nouveau_device(pNv->dev)->fd, fbcon_id); + fb = drmModeGetFB(pNv->dev->fd, fbcon_id); if (!fb) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to retrieve fbcon fb: id %d\n", fbcon_id); @@ -272,13 +272,12 @@ drmmode_fbcon_copy(ScreenPtr pScreen) exa->PrepareCopy(pspix, pdpix, 0, 0, GXcopy, ~0); exa->Copy(pdpix, 0, 0, 0, 0, w, h); exa->DoneCopy(pdpix); - FIRE_RING (pNv->chan); + PUSH_KICK(pNv->pushbuf); /* wait for completion before continuing, avoids seeing a momentary * flash of "corruption" on occasion */ - nouveau_bo_map(pNv->scanout, NOUVEAU_BO_RDWR); - nouveau_bo_unmap(pNv->scanout); + nouveau_bo_wait(pNv->scanout, NOUVEAU_BO_RDWR, pNv->client); pScreen->DestroyPixmap(pdpix); pScreen->DestroyPixmap(pspix); @@ -287,10 +286,9 @@ drmmode_fbcon_copy(ScreenPtr pScreen) fallback: #endif - if (nouveau_bo_map(pNv->scanout, NOUVEAU_BO_WR)) + if (nouveau_bo_map(pNv->scanout, NOUVEAU_BO_WR, pNv->client)) return; memset(pNv->scanout->map, 0x00, pNv->scanout->size); - nouveau_bo_unmap(pNv->scanout); } static Bool @@ -410,9 +408,8 @@ drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image) struct nouveau_bo *cursor = drmmode_crtc->cursor; drmmode_ptr drmmode = drmmode_crtc->drmmode; - nouveau_bo_map(cursor, NOUVEAU_BO_WR); + nouveau_bo_map(cursor, NOUVEAU_BO_WR, pNv->client); convert_cursor(cursor->map, image, 64, nv_cursor_width(pNv)); - nouveau_bo_unmap(cursor); if (drmmode_crtc->cursor_visible) { drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, @@ -462,7 +459,8 @@ drmmode_crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height) return NULL; } - ret = nouveau_bo_map(drmmode_crtc->rotate_bo, NOUVEAU_BO_RDWR); + ret = nouveau_bo_map(drmmode_crtc->rotate_bo, NOUVEAU_BO_RDWR, + NVPTR(scrn)->client); if (ret) { xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, "Couldn't get virtual address of shadow scanout\n"); @@ -470,7 +468,6 @@ drmmode_crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height) return NULL; } virtual = drmmode_crtc->rotate_bo->map; - nouveau_bo_unmap(drmmode_crtc->rotate_bo); ret = drmModeAddFB(drmmode->fd, width, height, crtc->scrn->depth, crtc->scrn->bitsPerPixel, drmmode_crtc->rotate_pitch, @@ -571,7 +568,7 @@ drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num) drmmode_crtc->drmmode = drmmode; ret = nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_MAP, 0, - 64*64*4, &drmmode_crtc->cursor); + 64*64*4, NULL, &drmmode_crtc->cursor); assert(ret == 0); crtc->driver_private = drmmode_crtc; @@ -1112,15 +1109,13 @@ drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height) scrn->virtualY = height; scrn->displayWidth = pitch / (scrn->bitsPerPixel >> 3); - nouveau_bo_map(pNv->scanout, NOUVEAU_BO_RDWR); + nouveau_bo_map(pNv->scanout, NOUVEAU_BO_RDWR, pNv->client); ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth, scrn->bitsPerPixel, pitch, pNv->scanout->handle, &drmmode->fb_id); - if (ret) { - nouveau_bo_unmap(pNv->scanout); + if (ret) goto fail; - } if (pNv->ShadowPtr) { free(pNv->ShadowPtr); @@ -1139,17 +1134,14 @@ drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height) #endif if (!pNv->NoAccel) { - nouveau_bo_unmap(pNv->scanout); pNv->EXADriverPtr->PrepareSolid(ppix, GXcopy, ~0, 0); pNv->EXADriverPtr->Solid(ppix, 0, 0, width, height); pNv->EXADriverPtr->DoneSolid(ppix); - nouveau_bo_map(pNv->scanout, NOUVEAU_BO_RDWR); + nouveau_bo_map(pNv->scanout, NOUVEAU_BO_RDWR, pNv->client); } else { memset(pNv->scanout->map, 0x00, pNv->scanout->size); } - nouveau_bo_unmap(pNv->scanout); - for (i = 0; i < xf86_config->num_crtc; i++) { xf86CrtcPtr crtc = xf86_config->crtc[i]; diff --git a/src/nouveau_dri2.c b/src/nouveau_dri2.c index 7878a5a..73f2fc1 100644 --- a/src/nouveau_dri2.c +++ b/src/nouveau_dri2.c @@ -5,7 +5,6 @@ #include "xorg-server.h" #include "nv_include.h" -#include "nouveau_pushbuf.h" #ifdef DRI2 #include "dri2.h" #endif @@ -82,7 +81,7 @@ nouveau_dri2_create_buffer(DrawablePtr pDraw, unsigned int attachment, nvpix = nouveau_pixmap(ppix); if (!nvpix || !nvpix->bo || - nouveau_bo_handle_get(nvpix->bo, &nvbuf->base.name)) { + nouveau_bo_name_get(nvpix->bo, &nvbuf->base.name)) { pScreen->DestroyPixmap(nvbuf->ppix); free(nvbuf); return NULL; @@ -164,7 +163,7 @@ update_front(DrawablePtr draw, DRI2BufferPtr front) pixmap->refcnt++; exaMoveInPixmap(pixmap); - r = nouveau_bo_handle_get(nouveau_pixmap_bo(pixmap), &front->name); + r = nouveau_bo_name_get(nouveau_pixmap_bo(pixmap), &front->name); if (r) { (*draw->pScreen->DestroyPixmap)(pixmap); return FALSE; @@ -226,7 +225,7 @@ nouveau_wait_vblank(DrawablePtr draw, int type, CARD64 msc, vbl.request.sequence = msc; vbl.request.signal = (unsigned long)data; - ret = drmWaitVBlank(nouveau_device(pNv->dev)->fd, &vbl); + ret = drmWaitVBlank(pNv->dev->fd, &vbl); if (ret) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Wait for VBlank failed: %s\n", strerror(errno)); @@ -278,7 +277,7 @@ nouveau_dri2_finish_swap(DrawablePtr draw, unsigned int frame, PixmapPtr src_pix = nouveau_dri2_buffer(s->src)->ppix; struct nouveau_bo *dst_bo; struct nouveau_bo *src_bo = nouveau_pixmap_bo(src_pix); - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; RegionRec reg; int type, ret; Bool front_updated; @@ -308,21 +307,21 @@ nouveau_dri2_finish_swap(DrawablePtr draw, unsigned int frame, dst_bo = nouveau_pixmap_bo(dst_pix); /* Throttle on the previous frame before swapping */ - nouveau_bo_map(dst_bo, NOUVEAU_BO_RD); - nouveau_bo_unmap(dst_bo); + nouveau_bo_wait(dst_bo, NOUVEAU_BO_RD, push->client); if (can_sync_to_vblank(draw)) { /* Reference the back buffer to sync it to vblank */ - WAIT_RING(chan, 1); - OUT_RELOC(chan, src_bo, 0, - NOUVEAU_BO_VRAM | NOUVEAU_BO_RD, 0, 0); + nouveau_pushbuf_refn(push, &(struct nouveau_pushbuf_refn) { + src_bo, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD + }, 1); if (pNv->Architecture >= NV_ARCH_50) NV50SyncToVBlank(dst_pix, REGION_EXTENTS(0, ®)); else NV11SyncToVBlank(dst_pix, REGION_EXTENTS(0, ®)); - FIRE_RING(chan); + nouveau_pushbuf_kick(push, push->channel); } if (front_updated && can_exchange(draw, dst_pix, src_pix)) { @@ -351,9 +350,10 @@ nouveau_dri2_finish_swap(DrawablePtr draw, unsigned int frame, /* Reference the front buffer to let throttling work * on occluded drawables. */ - WAIT_RING(chan, 1); - OUT_RELOC(chan, dst_bo, 0, - NOUVEAU_BO_VRAM | NOUVEAU_BO_RD, 0, 0); + nouveau_pushbuf_refn(push, &(struct nouveau_pushbuf_refn) { + dst_bo, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD + }, 1); REGION_TRANSLATE(0, ®, -draw->x, -draw->y); nouveau_dri2_copy_region(draw, ®, s->dst, s->src); @@ -678,7 +678,7 @@ nouveau_dri2_init(ScreenPtr pScreen) dri2.numDrivers = 2; dri2.driverName = dri2.driverNames[0]; - dri2.fd = nouveau_device(pNv->dev)->fd; + dri2.fd = pNv->dev->fd; dri2.deviceName = pNv->drm_device_name; dri2.version = DRI2INFOREC_VERSION; diff --git a/src/nouveau_exa.c b/src/nouveau_exa.c index b31fb31..6ad1790 100644 --- a/src/nouveau_exa.c +++ b/src/nouveau_exa.c @@ -82,7 +82,7 @@ nouveau_exa_prepare_access(PixmapPtr ppix, int index) if (nv50_style_tiled_pixmap(ppix) && !pNv->wfb_enabled) return FALSE; - if (nouveau_bo_map(bo, NOUVEAU_BO_RDWR)) + if (nouveau_bo_map(bo, NOUVEAU_BO_RDWR, pNv->client)) return FALSE; ppix->devPrivate.ptr = bo->map; return TRUE; @@ -91,9 +91,6 @@ nouveau_exa_prepare_access(PixmapPtr ppix, int index) static void nouveau_exa_finish_access(PixmapPtr ppix, int index) { - struct nouveau_bo *bo = nouveau_pixmap_bo(ppix); - - nouveau_bo_unmap(bo); } static Bool @@ -114,8 +111,7 @@ nouveau_exa_create_pixmap(ScreenPtr pScreen, int width, int height, int depth, if (!width || !height) return calloc(1, sizeof(*nvpix)); - if (!pNv->exa_force_cp && - pNv->dev->vm_vram_size <= 32*1024*1024) + if (!pNv->exa_force_cp && pNv->dev->vram_size <= 32 * 1024 * 1024) return NULL; nvpix = calloc(1, sizeof(*nvpix)); @@ -151,8 +147,7 @@ nv50_style_tiled_pixmap(PixmapPtr ppix) NVPtr pNv = NVPTR(pScrn); return pNv->Architecture >= NV_ARCH_50 && - (nouveau_pixmap_bo(ppix)->tile_flags & - NOUVEAU_BO_TILE_LAYOUT_MASK); + nouveau_pixmap_bo(ppix)->config.nv50.memtype; } static Bool @@ -188,7 +183,7 @@ nouveau_exa_download_from_screen(PixmapPtr pspix, int x, int y, int w, int h, lines, 0, 0)) goto memcpy; - nouveau_bo_map(pNv->GART, NOUVEAU_BO_RD); + nouveau_bo_map(pNv->GART, NOUVEAU_BO_RD, pNv->client); if (src_pitch == tmp_pitch) { memcpy(dst, pNv->GART->map, dst_pitch * lines); dst += dst_pitch * lines; @@ -200,7 +195,6 @@ nouveau_exa_download_from_screen(PixmapPtr pspix, int x, int y, int w, int h, dst += dst_pitch; } } - nouveau_bo_unmap(pNv->GART); /* next! */ h -= lines; @@ -209,11 +203,10 @@ nouveau_exa_download_from_screen(PixmapPtr pspix, int x, int y, int w, int h, memcpy: bo = nouveau_pixmap_bo(pspix); - if (nouveau_bo_map(bo, NOUVEAU_BO_RD)) + if (nouveau_bo_map(bo, NOUVEAU_BO_RD, pNv->client)) return FALSE; src = (char *)bo->map + offset; ret = NVAccelMemcpyRect(dst, src, h, dst_pitch, src_pitch, w*cpp); - nouveau_bo_unmap(bo); return ret; } @@ -268,7 +261,7 @@ nouveau_exa_upload_to_screen(PixmapPtr pdpix, int x, int y, int w, int h, if (lines > h) lines = h; - nouveau_bo_map(pNv->GART, NOUVEAU_BO_WR); + nouveau_bo_map(pNv->GART, NOUVEAU_BO_WR, pNv->client); if (src_pitch == tmp_pitch) { memcpy(pNv->GART->map, src, src_pitch * lines); src += src_pitch * lines; @@ -280,7 +273,6 @@ nouveau_exa_upload_to_screen(PixmapPtr pdpix, int x, int y, int w, int h, dst += tmp_pitch; } } - nouveau_bo_unmap(pNv->GART); if (!NVAccelM2MF(pNv, w, lines, cpp, 0, 0, pNv->GART, NOUVEAU_BO_GART, tmp_pitch, lines, 0, 0, @@ -299,11 +291,10 @@ nouveau_exa_upload_to_screen(PixmapPtr pdpix, int x, int y, int w, int h, /* fallback to memcpy-based transfer */ memcpy: bo = nouveau_pixmap_bo(pdpix); - if (nouveau_bo_map(bo, NOUVEAU_BO_WR)) + if (nouveau_bo_map(bo, NOUVEAU_BO_WR, pNv->client)) return FALSE; dst = (char *)bo->map + (y * dst_pitch) + (x * cpp); ret = NVAccelMemcpyRect(dst, src, h, dst_pitch, src_pitch, w*cpp); - nouveau_bo_unmap(bo); return ret; } diff --git a/src/nouveau_local.h b/src/nouveau_local.h index cfce831..b8a4fea 100644 --- a/src/nouveau_local.h +++ b/src/nouveau_local.h @@ -26,7 +26,7 @@ #include "compiler.h" #include "xf86_OSproc.h" -#include "nouveau_pushbuf.h" +#include /* Debug output */ #define NOUVEAU_MSG(fmt,args...) ErrorF(fmt, ##args) @@ -45,6 +45,8 @@ #define NOUVEAU_ALIGN(x,bytes) (((x) + ((bytes) - 1)) & ~((bytes) - 1)) +#define NV50_TILE_PITCH(m) (64 << ((m) & 0xf)) +#define NV50_TILE_HEIGHT(m) (4 << ((m) >> 4)) #define NVC0_TILE_PITCH(m) (64 << ((m) & 0xf)) #define NVC0_TILE_HEIGHT(m) (8 << ((m) >> 4)) @@ -93,84 +95,158 @@ static inline int round_up_pow2(int x) (y) = __z; \ } while (0) +static inline uint32_t +PUSH_AVAIL(struct nouveau_pushbuf *push) +{ + return push->end - push->cur; +} + +static inline Bool +PUSH_SPACE(struct nouveau_pushbuf *push, uint32_t size) +{ + if (PUSH_AVAIL(push) < size) + return nouveau_pushbuf_space(push, size, 0, 0) == 0; + return TRUE; +} + +static inline void +PUSH_DATA(struct nouveau_pushbuf *push, uint32_t data) +{ + *push->cur++ = data; +} + static inline void -BEGIN_NV04(struct nouveau_channel *chan, int subc, int mthd, int size) +PUSH_DATAp(struct nouveau_pushbuf *push, const void *data, uint32_t size) { - WAIT_RING(chan, size + 1); - OUT_RING (chan, 0x00000000 | (size << 18) | (subc << 13) | mthd); + memcpy(push->cur, data, size * 4); + push->cur += size; } static inline void -BEGIN_NI04(struct nouveau_channel *chan, int subc, int mthd, int size) +PUSH_RELOC(struct nouveau_pushbuf *push, struct nouveau_bo *bo, uint32_t offset, + uint32_t flags, uint32_t vor, uint32_t tor) { - WAIT_RING(chan, size + 1); - OUT_RING (chan, 0x40000000 | (size << 18) | (subc << 13) | mthd); + nouveau_pushbuf_reloc(push, bo, offset, flags, vor, tor); } static inline void -BEGIN_NVC0(struct nouveau_channel *chan, int subc, int mthd, int size) +PUSH_KICK(struct nouveau_pushbuf *push) { - WAIT_RING(chan, size + 1); - OUT_RING (chan, 0x20000000 | (size << 16) | (subc << 13) | (mthd >> 2)); + nouveau_pushbuf_kick(push, push->channel); +} + +static inline struct nouveau_bufctx * +BUFCTX(struct nouveau_pushbuf *push) +{ + return push->user_priv; } static inline void -BEGIN_NIC0(struct nouveau_channel *chan, int subc, int mthd, int size) +PUSH_RESET(struct nouveau_pushbuf *push) { - WAIT_RING(chan, size + 1); - OUT_RING (chan, 0x60000000 | (size << 16) | (subc << 13) | (mthd >> 2)); + nouveau_bufctx_reset(BUFCTX(push), 0); } static inline void -BEGIN_IMC0(struct nouveau_channel *chan, int subc, int mthd, int data) +PUSH_REFN(struct nouveau_pushbuf *push, struct nouveau_bo *bo, uint32_t access) { - WAIT_RING(chan, 1); - OUT_RING (chan, 0x80000000 | (data << 16) | (subc << 13) | (mthd >> 2)); + nouveau_bufctx_refn(BUFCTX(push), 0, bo, access); } static inline void -BEGIN_1IC0(struct nouveau_channel *chan, int subc, int mthd, int size) +PUSH_MTHDl(struct nouveau_pushbuf *push, int subc, int mthd, + struct nouveau_bo *bo, uint32_t offset, uint32_t access) { - WAIT_RING(chan, size + 1); - OUT_RING (chan, 0xa0000000 | (size << 16) | (subc << 13) | (mthd >> 2)); + nouveau_bufctx_mthd(BUFCTX(push), 0, (1 << 18) | (subc << 13) | mthd, + bo, offset, access | NOUVEAU_BO_LOW, 0, 0); + PUSH_DATA (push, bo->offset + offset); } -/* subchannel assignment */ -#define SUBC_M2MF(mthd) 0, (mthd) /* nv04: */ -#define NV03_M2MF(mthd) SUBC_M2MF(NV03_M2MF_##mthd) -#define NV50_M2MF(mthd) SUBC_M2MF(NV50_M2MF_##mthd) -#define NVC0_M2MF(mthd) SUBC_M2MF(NVC0_M2MF_##mthd) -#define SUBC_NVSW(mthd) 1, (mthd) -#define SUBC_SF2D(mthd) 2, (mthd) /* nv04:nv50 */ -#define SUBC_2D(mthd) 2, (mthd) /* nv50: */ -#define NV04_SF2D(mthd) SUBC_SF2D(NV04_SURFACE_2D_##mthd) -#define NV10_SF2D(mthd) SUBC_SF2D(NV10_SURFACE_2D_##mthd) -#define NV50_2D(mthd) SUBC_2D(NV50_2D_##mthd) -#define NVC0_2D(mthd) SUBC_2D(NVC0_2D_##mthd) -#define SUBC_RECT(mthd) 3, (mthd) /* nv04:nv50 */ -#define NV04_RECT(mthd) SUBC_RECT(NV04_GDI_##mthd) -#define SUBC_BLIT(mthd) 4, (mthd) /* nv04:nv50 */ -#define NV01_BLIT(mthd) SUBC_BLIT(NV01_BLIT_##mthd) -#define NV04_BLIT(mthd) SUBC_BLIT(NV04_BLIT_##mthd) -#define NV15_BLIT(mthd) SUBC_BLIT(NV15_BLIT_##mthd) -#define SUBC_IFC(mthd) 5, (mthd) /* nv04:nv50 */ -#define NV01_IFC(mthd) SUBC_IFC(NV01_IFC_##mthd) -#define NV04_IFC(mthd) SUBC_IFC(NV04_IFC_##mthd) -#define SUBC_MISC(mthd) 6, (mthd) /* nv04:nv50 */ -#define NV03_SIFM(mthd) SUBC_MISC(NV03_SIFM_##mthd) -#define NV05_SIFM(mthd) SUBC_MISC(NV05_SIFM_##mthd) -#define NV01_BETA(mthd) SUBC_MISC(NV01_BETA_##mthd) -#define NV04_BETA4(mthd) SUBC_MISC(NV04_BETA4_##mthd) -#define NV01_PATT(mthd) SUBC_MISC(NV01_PATTERN_##mthd) -#define NV04_PATT(mthd) SUBC_MISC(NV04_PATTERN_##mthd) -#define NV01_ROP(mthd) SUBC_MISC(NV01_ROP_##mthd) -#define NV01_CLIP(mthd) SUBC_MISC(NV01_CLIP_##mthd) -#define SUBC_3D(mthd) 7, (mthd) /* nv10: */ -#define NV10_3D(mthd) SUBC_3D(NV10_3D_##mthd) -#define NV30_3D(mthd) SUBC_3D(NV30_3D_##mthd) -#define NV40_3D(mthd) SUBC_3D(NV40_3D_##mthd) -#define NV50_3D(mthd) SUBC_3D(NV50_3D_##mthd) -#define NVC0_3D(mthd) SUBC_3D(NVC0_3D_##mthd) +static inline void +PUSH_MTHDo(struct nouveau_pushbuf *push, int subc, int mthd, + struct nouveau_bo *bo, uint32_t access, uint32_t vor, uint32_t tor) +{ + nouveau_bufctx_mthd(BUFCTX(push), 0, (1 << 18) | (subc << 13) | mthd, + bo, 0, access | NOUVEAU_BO_OR, vor, tor); + if (bo->flags & NOUVEAU_BO_VRAM) + PUSH_DATA (push, vor); + else + PUSH_DATA (push, tor); +} + +static inline void +PUSH_MTHDs(struct nouveau_pushbuf *push, int subc, int mthd, + struct nouveau_bo *bo, uint32_t data, uint32_t access, + uint32_t vor, uint32_t tor) +{ + nouveau_bufctx_mthd(BUFCTX(push), 0, (1 << 18) | (subc << 13) | mthd, + bo, data, access | NOUVEAU_BO_OR, vor, tor); + if (bo->flags & NOUVEAU_BO_VRAM) + PUSH_DATA (push, data | vor); + else + PUSH_DATA (push, data | tor); +} + +static inline void +PUSH_MTHD(struct nouveau_pushbuf *push, int subc, int mthd, + struct nouveau_bo *bo, uint32_t data, uint32_t access, + uint32_t vor, uint32_t tor) +{ + nouveau_bufctx_mthd(BUFCTX(push), 0, (1 << 18) | (subc << 13) | mthd, + bo, data, access | NOUVEAU_BO_OR, vor, tor); + if (access & NOUVEAU_BO_LOW) + data += bo->offset; + if (access & NOUVEAU_BO_OR) { + if (bo->flags & NOUVEAU_BO_VRAM) + data |= vor; + else + data |= tor; + } + PUSH_DATA (push, data); +} + +static inline void +PUSH_DATAf(struct nouveau_pushbuf *push, float v) +{ + union { float f; uint32_t i; } d = { .f = v }; + PUSH_DATA (push, d.i); +} + +static inline void +BEGIN_NV04(struct nouveau_pushbuf *push, int subc, int mthd, int size) +{ + PUSH_DATA (push, 0x00000000 | (size << 18) | (subc << 13) | mthd); +} + +static inline void +BEGIN_NI04(struct nouveau_pushbuf *push, int subc, int mthd, int size) +{ + PUSH_DATA (push, 0x40000000 | (size << 18) | (subc << 13) | mthd); +} + +static inline void +BEGIN_NVC0(struct nouveau_pushbuf *push, int subc, int mthd, int size) +{ + PUSH_DATA (push, 0x20000000 | (size << 16) | (subc << 13) | (mthd / 4)); +} + +static inline void +BEGIN_NIC0(struct nouveau_pushbuf *push, int subc, int mthd, int size) +{ + PUSH_DATA (push, 0x60000000 | (size << 16) | (subc << 13) | (mthd / 4)); +} + +static inline void +BEGIN_IMC0(struct nouveau_pushbuf *push, int subc, int mthd, int data) +{ + PUSH_DATA (push, 0x80000000 | (data << 16) | (subc << 13) | (mthd / 4)); +} + +static inline void +BEGIN_1IC0(struct nouveau_pushbuf *push, int subc, int mthd, int size) +{ + PUSH_DATA (push, 0xa0000000 | (size << 16) | (subc << 13) | (mthd / 4)); +} #define NV01_SUBC(subc, mthd) SUBC_##subc((NV01_SUBCHAN_##mthd)) #define NV11_SUBC(subc, mthd) SUBC_##subc((NV11_SUBCHAN_##mthd)) diff --git a/src/nouveau_wfb.c b/src/nouveau_wfb.c index e02fd1c..d95d162 100644 --- a/src/nouveau_wfb.c +++ b/src/nouveau_wfb.c @@ -178,9 +178,9 @@ nouveau_wfb_setup_wrap(ReadMemoryProcPtr *pRead, WriteMemoryProcPtr *pWrite, /* 8192x8192x4 is 28 bits max, 64 - 28 == 36. */ wfb->multiply_factor = (((1ULL << 36) - 1) / wfb->pitch) + 1; if (bo->device->chipset < 0xc0) - wfb->tile_height = bo->tile_mode + 2; + wfb->tile_height = (bo->config.nv50.tile_mode >> 4) + 2; else - wfb->tile_height = (bo->tile_mode >> 4) + 3; + wfb->tile_height = (bo->config.nv50.tile_mode >> 4) + 3; wfb->horiz_tiles = wfb->pitch / 64; have_tiled = 1; } diff --git a/src/nouveau_xv.c b/src/nouveau_xv.c index 54ae3be..a43225c 100644 --- a/src/nouveau_xv.c +++ b/src/nouveau_xv.c @@ -243,9 +243,8 @@ static int nouveau_xv_bo_realloc(ScrnInfoPtr pScrn, unsigned flags, unsigned size, struct nouveau_bo **pbo) { + union nouveau_bo_config config = {}; NVPtr pNv = NVPTR(pScrn); - uint32_t tile_flags; - int ret; if (*pbo) { if ((*pbo)->size >= size) @@ -253,21 +252,16 @@ nouveau_xv_bo_realloc(ScrnInfoPtr pScrn, unsigned flags, unsigned size, nouveau_bo_ref(NULL, pbo); } - tile_flags = 0; if (flags & NOUVEAU_BO_VRAM) { if (pNv->Architecture == NV_ARCH_50) - tile_flags = 0x7000; + config.nv50.memtype = 0x70; else if (pNv->Architecture == NV_ARCH_C0) - tile_flags = 0xfe00; + config.nvc0.memtype = 0xfe; } + flags |= NOUVEAU_BO_MAP; - ret = nouveau_bo_new_tile(pNv->dev, flags | NOUVEAU_BO_MAP, 0, - size, 0, tile_flags, pbo); - if (ret) - return ret; - - return 0; + return nouveau_bo_new(pNv->dev, flags, 0, size, &config, pbo); } /** @@ -1080,7 +1074,7 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, short drw_x, int i = 0; /* Upload to GART */ - nouveau_bo_map(destination_buffer, NOUVEAU_BO_WR); + nouveau_bo_map(destination_buffer, NOUVEAU_BO_WR, pNv->client); dst = destination_buffer->map; if (action_flags & IS_YV12) { @@ -1116,8 +1110,6 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, short drw_x, } } - nouveau_bo_unmap(destination_buffer); - if (uv_offset) { NVAccelM2MF(pNv, line_len, nlines / 2, 1, line_len * nlines, uv_offset, @@ -1135,7 +1127,7 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, short drw_x, } else { CPU_copy: - nouveau_bo_map(pPriv->video_mem, NOUVEAU_BO_WR); + nouveau_bo_map(pPriv->video_mem, NOUVEAU_BO_WR, pNv->client); map = pPriv->video_mem->map + offset; if (action_flags & IS_YV12) { @@ -1201,8 +1193,6 @@ CPU_copy: buf += srcPitch - (npixels << 1); } } - - nouveau_bo_unmap(pPriv->video_mem); } if (skip) diff --git a/src/nv04_accel.h b/src/nv04_accel.h new file mode 100644 index 0000000..d9d0822 --- /dev/null +++ b/src/nv04_accel.h @@ -0,0 +1,34 @@ +#ifndef __NV04_ACCEL_H__ +#define __NV04_ACCEL_H__ + +/* subchannel assignments */ +#define SUBC_M2MF(mthd) 0, (mthd) +#define NV03_M2MF(mthd) SUBC_M2MF(NV03_M2MF_##mthd) +#define SUBC_NVSW(mthd) 1, (mthd) +#define SUBC_SF2D(mthd) 2, (mthd) +#define NV04_SF2D(mthd) SUBC_SF2D(NV04_SURFACE_2D_##mthd) +#define NV10_SF2D(mthd) SUBC_SF2D(NV10_SURFACE_2D_##mthd) +#define SUBC_RECT(mthd) 3, (mthd) +#define NV04_RECT(mthd) SUBC_RECT(NV04_GDI_##mthd) +#define SUBC_BLIT(mthd) 4, (mthd) +#define NV01_BLIT(mthd) SUBC_BLIT(NV01_BLIT_##mthd) +#define NV04_BLIT(mthd) SUBC_BLIT(NV04_BLIT_##mthd) +#define NV15_BLIT(mthd) SUBC_BLIT(NV15_BLIT_##mthd) +#define SUBC_IFC(mthd) 5, (mthd) +#define NV01_IFC(mthd) SUBC_IFC(NV01_IFC_##mthd) +#define NV04_IFC(mthd) SUBC_IFC(NV04_IFC_##mthd) +#define SUBC_MISC(mthd) 6, (mthd) +#define NV03_SIFM(mthd) SUBC_MISC(NV03_SIFM_##mthd) +#define NV05_SIFM(mthd) SUBC_MISC(NV05_SIFM_##mthd) +#define NV01_BETA(mthd) SUBC_MISC(NV01_BETA_##mthd) +#define NV04_BETA4(mthd) SUBC_MISC(NV04_BETA4_##mthd) +#define NV01_PATT(mthd) SUBC_MISC(NV01_PATTERN_##mthd) +#define NV04_PATT(mthd) SUBC_MISC(NV04_PATTERN_##mthd) +#define NV01_ROP(mthd) SUBC_MISC(NV01_ROP_##mthd) +#define NV01_CLIP(mthd) SUBC_MISC(NV01_CLIP_##mthd) +#define SUBC_3D(mthd) 7, (mthd) +#define NV10_3D(mthd) SUBC_3D(NV10_3D_##mthd) +#define NV30_3D(mthd) SUBC_3D(NV30_3D_##mthd) +#define NV40_3D(mthd) SUBC_3D(NV40_3D_##mthd) + +#endif diff --git a/src/nv04_exa.c b/src/nv04_exa.c index 29b8c10..77bb3b7 100644 --- a/src/nv04_exa.c +++ b/src/nv04_exa.c @@ -23,229 +23,206 @@ #include "nv_include.h" #include "nv_rop.h" - #include "hwdefs/nv_object.xml.h" #include "hwdefs/nv_m2mf.xml.h" #include "hwdefs/nv01_2d.xml.h" +#include "nv04_accel.h" static void -NV04EXASetPattern(ScrnInfoPtr pScrn, CARD32 clr0, CARD32 clr1, - CARD32 pat0, CARD32 pat1) +NV04EXASetPattern(NVPtr pNv, CARD32 clr0, CARD32 clr1, CARD32 pat0, CARD32 pat1) { - NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; - - BEGIN_NV04(chan, NV01_SUBC(MISC, OBJECT), 1); - OUT_RING (chan, pNv->NvImagePattern->handle); - BEGIN_NV04(chan, NV01_PATT(MONOCHROME_COLOR(0)), 4); - OUT_RING (chan, clr0); - OUT_RING (chan, clr1); - OUT_RING (chan, pat0); - OUT_RING (chan, pat1); + struct nouveau_pushbuf *push = pNv->pushbuf; + + BEGIN_NV04(push, NV01_SUBC(MISC, OBJECT), 1); + PUSH_DATA (push, pNv->NvImagePattern->handle); + BEGIN_NV04(push, NV01_PATT(MONOCHROME_COLOR(0)), 4); + PUSH_DATA (push, clr0); + PUSH_DATA (push, clr1); + PUSH_DATA (push, pat0); + PUSH_DATA (push, pat1); } -static void -NV04EXASetROP(ScrnInfoPtr pScrn, CARD32 alu, CARD32 planemask) +static Bool +NV04EXASetROP(PixmapPtr ppix, int subc, int mthd, int alu, Pixel planemask) { + ScrnInfoPtr pScrn = xf86Screens[ppix->drawable.pScreen->myNum]; NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; - - if (planemask != ~0) { - NV04EXASetPattern(pScrn, 0, planemask, ~0, ~0); - if (pNv->currentRop != (alu + 32)) { - BEGIN_NV04(chan, NV01_SUBC(MISC, OBJECT), 1); - OUT_RING (chan, pNv->NvRop->handle); - BEGIN_NV04(chan, NV01_ROP(ROP), 1); - OUT_RING (chan, NVROP[alu].copy_planemask); - pNv->currentRop = alu + 32; + struct nouveau_pushbuf *push = pNv->pushbuf; + + planemask |= ~0 << ppix->drawable.bitsPerPixel; + if (planemask != ~0 || alu != GXcopy) { + if (ppix->drawable.bitsPerPixel == 32) + return FALSE; + if (planemask != ~0) { + NV04EXASetPattern(pNv, 0, planemask, ~0, ~0); + if (pNv->currentRop != (alu + 32)) { + BEGIN_NV04(push, NV01_SUBC(MISC, OBJECT), 1); + PUSH_DATA (push, pNv->NvRop->handle); + BEGIN_NV04(push, NV01_ROP(ROP), 1); + PUSH_DATA (push, NVROP[alu].copy_planemask); + pNv->currentRop = alu + 32; + } + } else + if (pNv->currentRop != alu) { + if(pNv->currentRop >= 16) + NV04EXASetPattern(pNv, ~0, ~0, ~0, ~0); + BEGIN_NV04(push, NV01_SUBC(MISC, OBJECT), 1); + PUSH_DATA (push, pNv->NvRop->handle); + BEGIN_NV04(push, NV01_ROP(ROP), 1); + PUSH_DATA (push, NVROP[alu].copy); + pNv->currentRop = alu; } - } else - if (pNv->currentRop != alu) { - if(pNv->currentRop >= 16) - NV04EXASetPattern(pScrn, ~0, ~0, ~0, ~0); - BEGIN_NV04(chan, NV01_SUBC(MISC, OBJECT), 1); - OUT_RING (chan, pNv->NvRop->handle); - BEGIN_NV04(chan, NV01_ROP(ROP), 1); - OUT_RING (chan, NVROP[alu].copy); - pNv->currentRop = alu; - } -} -static void -NV04EXAStateSolidResubmit(struct nouveau_channel *chan) -{ - ScrnInfoPtr pScrn = chan->user_private; - NVPtr pNv = NVPTR(pScrn); + BEGIN_NV04(push, subc, mthd, 1); + PUSH_DATA (push, 1); /* ROP_AND */ + } else { + BEGIN_NV04(push, subc, mthd, 1); + PUSH_DATA (push, 3); /* SRCCOPY */ + } - NV04EXAPrepareSolid(pNv->pdpix, pNv->alu, pNv->planemask, pNv->fg_colour); + return TRUE; } Bool -NV04EXAPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg) +NV04EXAPrepareSolid(PixmapPtr ppix, int alu, Pixel planemask, Pixel fg) { - ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; + ScrnInfoPtr pScrn = xf86Screens[ppix->drawable.pScreen->myNum]; NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; - struct nouveau_bo *bo = nouveau_pixmap_bo(pPixmap); - unsigned int fmt, pitch, fmt2 = NV04_GDI_COLOR_FORMAT_A8R8G8B8; + struct nouveau_pushbuf *push = pNv->pushbuf; + struct nouveau_bo *bo = nouveau_pixmap_bo(ppix); + unsigned pitch = exaGetPixmapPitch(ppix); + unsigned surf_fmt, rect_fmt; - if (MARK_RING(chan, 64, 2)) + /* When SURFACE_FORMAT_A8R8G8B8 is used with GDI_RECTANGLE_TEXT, the + * alpha channel gets forced to 0xFF for some reason. We're using + * SURFACE_FORMAT_Y32 as a workaround + */ + if (!NVAccelGetCtxSurf2DFormatFromPixmap(ppix, (int*)&surf_fmt)) return FALSE; - - planemask |= ~0 << pPixmap->drawable.bitsPerPixel; - if (planemask != ~0 || alu != GXcopy) { - if (pPixmap->drawable.bitsPerPixel == 32) - return FALSE; - BEGIN_NV04(chan, NV04_RECT(OPERATION), 1); - OUT_RING (chan, 1); /* ROP_AND */ - NV04EXASetROP(pScrn, alu, planemask); - } else { - BEGIN_NV04(chan, NV04_RECT(OPERATION), 1); - OUT_RING (chan, 3); /* SRCCOPY */ + if (surf_fmt == NV04_SURFACE_2D_FORMAT_A8R8G8B8) + surf_fmt = NV04_SURFACE_2D_FORMAT_Y32; + + rect_fmt = NV04_GDI_COLOR_FORMAT_A8R8G8B8; + if (ppix->drawable.bitsPerPixel == 16) { + if (ppix->drawable.depth == 16) + rect_fmt = NV04_GDI_COLOR_FORMAT_A16R5G6B5; + else + rect_fmt = NV04_GDI_COLOR_FORMAT_X16A1R5G5B5; } - if (!NVAccelGetCtxSurf2DFormatFromPixmap(pPixmap, (int*)&fmt)) + if (!PUSH_SPACE(push, 64)) return FALSE; - pitch = exaGetPixmapPitch(pPixmap); + PUSH_RESET(push); - if (pPixmap->drawable.bitsPerPixel == 16) { - if (pPixmap->drawable.depth == 16) { - fmt2 = NV04_GDI_COLOR_FORMAT_A16R5G6B5; - } else if (pPixmap->drawable.depth == 15) { - fmt2 = NV04_GDI_COLOR_FORMAT_X16A1R5G5B5; - } - } + if (!NV04EXASetROP(ppix, NV04_RECT(OPERATION), alu, planemask)) + return FALSE; - /* When SURFACE_FORMAT_A8R8G8B8 is used with GDI_RECTANGLE_TEXT, the - * alpha channel gets forced to 0xFF for some reason. We're using - * SURFACE_FORMAT_Y32 as a workaround - */ - if (fmt == NV04_SURFACE_2D_FORMAT_A8R8G8B8) - fmt = NV04_SURFACE_2D_FORMAT_Y32; - - BEGIN_NV04(chan, NV04_SF2D(FORMAT), 4); - OUT_RING (chan, fmt); - OUT_RING (chan, (pitch << 16) | pitch); - if (OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR) || - OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR)) { - MARK_UNDO(chan); + BEGIN_NV04(push, NV04_SF2D(FORMAT), 4); + PUSH_DATA (push, surf_fmt); + PUSH_DATA (push, (pitch << 16) | pitch); + PUSH_MTHDl(push, NV04_SF2D(OFFSET_SOURCE), bo, 0, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + PUSH_MTHDl(push, NV04_SF2D(OFFSET_DESTIN), bo, 0, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_NV04(push, NV04_RECT(COLOR_FORMAT), 1); + PUSH_DATA (push, rect_fmt); + + nouveau_pushbuf_bufctx(push, pNv->bufctx); + if (nouveau_pushbuf_validate(push)) { + nouveau_pushbuf_bufctx(push, NULL); return FALSE; } - BEGIN_NV04(chan, NV04_RECT(COLOR_FORMAT), 1); - OUT_RING (chan, fmt2); - BEGIN_NV04(chan, NV04_RECT(COLOR1_A), 1); - OUT_RING (chan, fg); - - pNv->pdpix = pPixmap; - pNv->alu = alu; - pNv->planemask = planemask; pNv->fg_colour = fg; - chan->flush_notify = NV04EXAStateSolidResubmit; return TRUE; } void -NV04EXASolid (PixmapPtr pPixmap, int x1, int y1, int x2, int y2) +NV04EXASolid (PixmapPtr pPixmap, int x, int y, int x2, int y2) { ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; - int width = x2-x1; - int height = y2-y1; - - BEGIN_NV04(chan, NV04_RECT(UNCLIPPED_RECTANGLE_POINT(0)), 2); - OUT_RING (chan, (x1 << 16) | y1); - OUT_RING (chan, (width << 16) | height); - - if((width * height) >= 512) - FIRE_RING (chan); + struct nouveau_pushbuf *push = pNv->pushbuf; + int w = x2 - x; + int h = y2 - y; + + if (!PUSH_SPACE(push, 5)) + return; + + BEGIN_NV04(push, NV04_RECT(COLOR1_A), 1); + PUSH_DATA (push, pNv->fg_colour); + BEGIN_NV04(push, NV04_RECT(UNCLIPPED_RECTANGLE_POINT(0)), 2); + PUSH_DATA (push, (x << 16) | y); + PUSH_DATA (push, (w << 16) | h); + if ((w * h) >= 512) + PUSH_KICK(push); } void NV04EXADoneSolid (PixmapPtr pPixmap) { ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; - NVPtr pNv = NVPTR(pScrn); - - pNv->chan->flush_notify = NULL; -} - -static void -NV04EXAStateCopyResubmit(struct nouveau_channel *chan) -{ - ScrnInfoPtr pScrn = chan->user_private; - NVPtr pNv = NVPTR(pScrn); - - NV04EXAPrepareCopy(pNv->pspix, pNv->pdpix, 0, 0, pNv->alu, - pNv->planemask); + nouveau_pushbuf_bufctx(NVPTR(pScrn)->pushbuf, NULL); } Bool -NV04EXAPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int dx, int dy, +NV04EXAPrepareCopy(PixmapPtr pspix, PixmapPtr pdpix, int dx, int dy, int alu, Pixel planemask) { - ScrnInfoPtr pScrn = xf86Screens[pSrcPixmap->drawable.pScreen->myNum]; + ScrnInfoPtr pScrn = xf86Screens[pspix->drawable.pScreen->myNum]; NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; - struct nouveau_bo *src_bo = nouveau_pixmap_bo(pSrcPixmap); - struct nouveau_bo *dst_bo = nouveau_pixmap_bo(pDstPixmap); - int fmt; + struct nouveau_pushbuf *push = pNv->pushbuf; + struct nouveau_bo *src_bo = nouveau_pixmap_bo(pspix); + struct nouveau_bo *dst_bo = nouveau_pixmap_bo(pdpix); + int surf_fmt; - if (pSrcPixmap->drawable.bitsPerPixel != - pDstPixmap->drawable.bitsPerPixel) + if (pspix->drawable.bitsPerPixel != pdpix->drawable.bitsPerPixel) return FALSE; - if (!NVAccelGetCtxSurf2DFormatFromPixmap(pDstPixmap, &fmt)) + if (!NVAccelGetCtxSurf2DFormatFromPixmap(pdpix, &surf_fmt)) return FALSE; - if (MARK_RING(chan, 64, 2)) + if (!PUSH_SPACE(push, 64)) return FALSE; + PUSH_RESET(push); - planemask |= ~0 << pDstPixmap->drawable.bitsPerPixel; - if (planemask != ~0 || alu != GXcopy) { - if (pDstPixmap->drawable.bitsPerPixel == 32) { - MARK_UNDO(chan); - return FALSE; - } - - BEGIN_NV04(chan, NV01_BLIT(OPERATION), 1); - OUT_RING (chan, 1); /* ROP_AND */ - - NV04EXASetROP(pScrn, alu, planemask); - } else { - BEGIN_NV04(chan, NV01_BLIT(OPERATION), 1); - OUT_RING (chan, 3); /* SRCCOPY */ - } + if (!NV04EXASetROP(pdpix, NV01_BLIT(OPERATION), alu, planemask)) + return FALSE; - BEGIN_NV04(chan, NV04_SF2D(FORMAT), 4); - OUT_RING (chan, fmt); - OUT_RING (chan, (exaGetPixmapPitch(pDstPixmap) << 16) | - (exaGetPixmapPitch(pSrcPixmap))); - if (OUT_RELOCl(chan, src_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD) || - OUT_RELOCl(chan, dst_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR)) { - MARK_UNDO(chan); + BEGIN_NV04(push, NV04_SF2D(FORMAT), 4); + PUSH_DATA (push, surf_fmt); + PUSH_DATA (push, (exaGetPixmapPitch(pdpix) << 16) | + exaGetPixmapPitch(pspix)); + PUSH_MTHDl(push, NV04_SF2D(OFFSET_SOURCE), src_bo, 0, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + PUSH_MTHDl(push, NV04_SF2D(OFFSET_DESTIN), dst_bo, 0, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + nouveau_pushbuf_bufctx(push, pNv->bufctx); + if (nouveau_pushbuf_validate(push)) { + nouveau_pushbuf_bufctx(push, NULL); return FALSE; } - pNv->pspix = pSrcPixmap; - pNv->pdpix = pDstPixmap; - pNv->alu = alu; - pNv->planemask = planemask; - chan->flush_notify = NV04EXAStateCopyResubmit; + pNv->pspix = pspix; + pNv->pmpix = NULL; + pNv->pdpix = pdpix; return TRUE; } void -NV04EXACopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, +NV04EXACopy(PixmapPtr pdpix, int srcX, int srcY, int dstX, int dstY, int width, int height) { - ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; + ScrnInfoPtr pScrn = xf86Screens[pdpix->drawable.pScreen->myNum]; NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; int split_dstY = NOUVEAU_ALIGN(dstY + 1, 64); int split_height = split_dstY - dstY; + if (nouveau_pushbuf_space(push, 16, 1, 0)) + return; + if ((width * height) >= 200000 && pNv->pspix != pNv->pdpix && (dstY > srcY || dstX > srcX) && split_height < height) { /* @@ -257,90 +234,59 @@ NV04EXACopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, * different (not nicer) trick to achieve the same * effect. */ - struct nouveau_bo *dst_bo = nouveau_pixmap_bo(pNv->pdpix); - unsigned dst_pitch = exaGetPixmapPitch(pNv->pdpix); - - if (MARK_RING(chan, 10, 1)) - return; - - BEGIN_NV04(chan, NV01_BLIT(POINT_IN), 3); - OUT_RING (chan, (srcY << 16) | srcX); - OUT_RING (chan, (dstY << 16) | dstX); - OUT_RING (chan, (split_height << 16) | width); + struct nouveau_bo *dst_bo = nouveau_pixmap_bo(pdpix); + unsigned dst_pitch = exaGetPixmapPitch(pdpix); - BEGIN_NV04(chan, NV04_SF2D(OFFSET_DESTIN), 1); - OUT_RELOCl(chan, dst_bo, split_dstY * dst_pitch, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_NV04(push, NV01_BLIT(POINT_IN), 3); + PUSH_DATA (push, (srcY << 16) | srcX); + PUSH_DATA (push, (dstY << 16) | dstX); + PUSH_DATA (push, (split_height << 16) | width); + BEGIN_NV04(push, NV04_SF2D(OFFSET_DESTIN), 1); + PUSH_RELOC(push, dst_bo, split_dstY * dst_pitch, + NOUVEAU_BO_LOW, 0, 0); srcY += split_height; height -= split_height; dstY = 0; + pNv->pmpix = pdpix; + } else + if (pNv->pmpix) { + struct nouveau_bo *dst_bo = nouveau_pixmap_bo(pdpix); + + BEGIN_NV04(push, NV04_SF2D(OFFSET_DESTIN), 1); + PUSH_RELOC(push, dst_bo, 0, NOUVEAU_BO_LOW, 0, 0); + pNv->pmpix = NULL; } - BEGIN_NV04(chan, NV01_BLIT(POINT_IN), 3); - OUT_RING (chan, (srcY << 16) | srcX); - OUT_RING (chan, (dstY << 16) | dstX); - OUT_RING (chan, (height << 16) | width); + BEGIN_NV04(push, NV01_BLIT(POINT_IN), 3); + PUSH_DATA (push, (srcY << 16) | srcX); + PUSH_DATA (push, (dstY << 16) | dstX); + PUSH_DATA (push, (height << 16) | width); - if((width * height) >= 512) - FIRE_RING (chan); + if ((width * height) >= 512) + PUSH_KICK(push); } void -NV04EXADoneCopy(PixmapPtr pDstPixmap) +NV04EXADoneCopy(PixmapPtr pdpix) { - ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; - NVPtr pNv = NVPTR(pScrn); - - pNv->chan->flush_notify = NULL; -} - -static Bool -NV04EXAStateIFCSubmit(struct nouveau_channel *chan) -{ - ScrnInfoPtr pScrn = chan->user_private; - NVPtr pNv = NVPTR(pScrn); - struct nouveau_bo *bo = nouveau_pixmap_bo(pNv->pdpix); - int surf_fmt; - - NVAccelGetCtxSurf2DFormatFromPixmap(pNv->pdpix, &surf_fmt); - - if (MARK_RING(chan, 64, 2)) - return FALSE; - - BEGIN_NV04(chan, NV04_SF2D(FORMAT), 4); - OUT_RING (chan, surf_fmt); - OUT_RING (chan, (exaGetPixmapPitch(pNv->pdpix) << 16) | - exaGetPixmapPitch(pNv->pdpix)); - if (OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR) || - OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR)) { - MARK_UNDO(chan); - return FALSE; - } - BEGIN_NV04(chan, NV01_IFC(POINT), 3); - OUT_RING (chan, (pNv->point_y << 16) | pNv->point_x); - OUT_RING (chan, (pNv->height_out << 16) | pNv->width_out); - OUT_RING (chan, (pNv->height_in << 16) | pNv->width_in); - - return TRUE; -} - -static void -NV04EXAStateIFCResubmit(struct nouveau_channel *chan) -{ - NV04EXAStateIFCSubmit(chan); + ScrnInfoPtr pScrn = xf86Screens[pdpix->drawable.pScreen->myNum]; + nouveau_pushbuf_bufctx(NVPTR(pScrn)->pushbuf, NULL); } Bool NV04EXAUploadIFC(ScrnInfoPtr pScrn, const char *src, int src_pitch, - PixmapPtr pDst, int x, int y, int w, int h, int cpp) + PixmapPtr pdpix, int x, int y, int w, int h, int cpp) { NVPtr pNv = NVPTR(pScrn); - ScreenPtr pScreen = pDst->drawable.pScreen; - struct nouveau_channel *chan = pNv->chan; + ScreenPtr pScreen = pdpix->drawable.pScreen; + struct nouveau_bo *bo = nouveau_pixmap_bo(pdpix); + struct nouveau_pushbuf *push = pNv->pushbuf; int line_len = w * cpp; - int iw, id, surf_fmt, ifc_fmt; + int surf_fmt, ifc_fmt; + int iw, id, py, ph; int padbytes; + Bool ret = FALSE; if (pNv->Architecture >= NV_ARCH_50) return FALSE; @@ -348,7 +294,7 @@ NV04EXAUploadIFC(ScrnInfoPtr pScrn, const char *src, int src_pitch, if (h > 1024) return FALSE; - if (line_len<4) + if (line_len < 4) return FALSE; switch (cpp) { @@ -358,7 +304,7 @@ NV04EXAUploadIFC(ScrnInfoPtr pScrn, const char *src, int src_pitch, return FALSE; } - if (!NVAccelGetCtxSurf2DFormatFromPixmap(pDst, &surf_fmt)) + if (!NVAccelGetCtxSurf2DFormatFromPixmap(pdpix, &surf_fmt)) return FALSE; /* Pad out input width to cover both COLORA() and COLORB() */ @@ -371,49 +317,67 @@ NV04EXAUploadIFC(ScrnInfoPtr pScrn, const char *src, int src_pitch, if (id > 1792) return FALSE; - BEGIN_NV04(chan, NV01_SUBC(MISC, OBJECT), 1); - OUT_RING (chan, pNv->NvClipRectangle->handle); - BEGIN_NV04(chan, NV01_CLIP(POINT), 2); - OUT_RING (chan, (y << 16) | x); - OUT_RING (chan, (h << 16) | w); - BEGIN_NV04(chan, NV01_IFC(OPERATION), 2); - OUT_RING (chan, NV01_IFC_OPERATION_SRCCOPY); - OUT_RING (chan, ifc_fmt); - - pNv->point_x = x; - pNv->point_y = y; - pNv->height_in = pNv->height_out = h; - pNv->width_in = iw; - pNv->width_out = w; - pNv->pdpix = pDst; - chan->flush_notify = NV04EXAStateIFCResubmit; - if (!NV04EXAStateIFCSubmit(chan)) + if (!PUSH_SPACE(push, 16)) return FALSE; + PUSH_RESET(push); + + BEGIN_NV04(push, NV01_SUBC(MISC, OBJECT), 1); + PUSH_DATA (push, pNv->NvClipRectangle->handle); + BEGIN_NV04(push, NV01_CLIP(POINT), 2); + PUSH_DATA (push, (y << 16) | x); + PUSH_DATA (push, (h << 16) | w); + + BEGIN_NV04(push, NV04_SF2D(FORMAT), 4); + PUSH_DATA (push, surf_fmt); + PUSH_DATA (push, (exaGetPixmapPitch(pdpix) << 16) | + exaGetPixmapPitch(pdpix)); + PUSH_MTHDl(push, NV04_SF2D(OFFSET_SOURCE), bo, 0, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + PUSH_MTHDl(push, NV04_SF2D(OFFSET_DESTIN), bo, 0, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + nouveau_pushbuf_bufctx(push, pNv->bufctx); + if (nouveau_pushbuf_validate(push)) + goto out; + + py = y; + ph = h; + while (ph--) { + if (PUSH_AVAIL(push) < id + 1 || (py == y)) { + if (!PUSH_SPACE(push, id + 8)) + goto out; + BEGIN_NV04(push, NV01_IFC(OPERATION), 2); + PUSH_DATA (push, NV01_IFC_OPERATION_SRCCOPY); + PUSH_DATA (push, ifc_fmt); + BEGIN_NV04(push, NV01_IFC(POINT), 3); + PUSH_DATA (push, (py << 16) | x); + PUSH_DATA (push, (h << 16) | w); + PUSH_DATA (push, (h << 16) | iw); + } - if (padbytes) - h--; - while (h--) { /* send a line */ - BEGIN_NV04(chan, NV01_IFC(COLOR(0)), id); - OUT_RINGp (chan, src, id); + if (ph > 0 || !padbytes) { + BEGIN_NV04(push, NV01_IFC(COLOR(0)), id); + PUSH_DATAp(push, src, id); + } else { + char padding[8]; + int aux = (padbytes + 7) >> 2; + memcpy(padding, src + (id - aux) * 4, padbytes); + BEGIN_NV04(push, NV01_IFC(COLOR(0)), id); + PUSH_DATAp(push, src, id - aux); + PUSH_DATAp(push, padding, aux); + } src += src_pitch; - pNv->point_y++; + py++; } - if (padbytes) { - char padding[8]; - int aux = (padbytes + 7) >> 2; - BEGIN_NV04(chan, NV01_IFC(COLOR(0)), id); - OUT_RINGp (chan, src, id - aux); - memcpy(padding, src + (id - aux) * 4, padbytes); - OUT_RINGp (chan, padding, aux); - } - - chan->flush_notify = NULL; - if (pDst == pScreen->GetScreenPixmap(pScreen)) - FIRE_RING(chan); - return TRUE; + ret = TRUE; +out: + nouveau_pushbuf_bufctx(push, NULL); + if (pdpix == pScreen->GetScreenPixmap(pScreen)) + PUSH_KICK(push); + return ret; } Bool @@ -423,7 +387,12 @@ NV04EXARectM2MF(NVPtr pNv, int w, int h, int cpp, struct nouveau_bo *dst, uint32_t dst_off, int dst_dom, int dst_pitch, int dst_h, int dst_x, int dst_y) { - struct nouveau_channel *chan = pNv->chan; + struct nv04_fifo *fifo = pNv->channel->data; + struct nouveau_pushbuf *push = pNv->pushbuf; + struct nouveau_pushbuf_refn refs[] = { + { src, src_dom | NOUVEAU_BO_RD }, + { dst, dst_dom | NOUVEAU_BO_WR }, + }; src_off += src_y * src_pitch + src_x * cpp; dst_off += dst_y * dst_pitch + dst_x * cpp; @@ -434,31 +403,26 @@ NV04EXARectM2MF(NVPtr pNv, int w, int h, int cpp, line_count = 2047; h -= line_count; - if (MARK_RING (chan, 16, 4)) + if (nouveau_pushbuf_space(push, 16, 4, 0) || + nouveau_pushbuf_refn (push, refs, 2)) return FALSE; - BEGIN_NV04(chan, NV03_M2MF(DMA_BUFFER_IN), 2); - if (OUT_RELOCo(chan, src, src_dom | NOUVEAU_BO_RD) || - OUT_RELOCo(chan, dst, dst_dom | NOUVEAU_BO_WR)) { - MARK_UNDO(chan); - return FALSE; - } - BEGIN_NV04(chan, NV03_M2MF(OFFSET_IN), 8); - if (OUT_RELOCl(chan, src, src_off, src_dom | NOUVEAU_BO_RD) || - OUT_RELOCl(chan, dst, dst_off, dst_dom | NOUVEAU_BO_WR)) { - MARK_UNDO(chan); - return FALSE; - } - OUT_RING (chan, src_pitch); - OUT_RING (chan, dst_pitch); - OUT_RING (chan, w * cpp); - OUT_RING (chan, line_count); - OUT_RING (chan, 0x00000101); - OUT_RING (chan, 0x00000000); - BEGIN_NV04(chan, NV04_GRAPH(M2MF, NOP), 1); - OUT_RING (chan, 0x00000000); - BEGIN_NV04(chan, NV03_M2MF(OFFSET_OUT), 1); - OUT_RING (chan, 0x00000000); + BEGIN_NV04(push, NV03_M2MF(DMA_BUFFER_IN), 2); + PUSH_RELOC(push, src, 0, NOUVEAU_BO_OR, fifo->vram, fifo->gart); + PUSH_RELOC(push, dst, 0, NOUVEAU_BO_OR, fifo->vram, fifo->gart); + BEGIN_NV04(push, NV03_M2MF(OFFSET_IN), 8); + PUSH_RELOC(push, src, src_off, NOUVEAU_BO_LOW, 0, 0); + PUSH_RELOC(push, dst, dst_off, NOUVEAU_BO_LOW, 0, 0); + PUSH_DATA (push, src_pitch); + PUSH_DATA (push, dst_pitch); + PUSH_DATA (push, w * cpp); + PUSH_DATA (push, line_count); + PUSH_DATA (push, 0x00000101); + PUSH_DATA (push, 0x00000000); + BEGIN_NV04(push, NV04_GRAPH(M2MF, NOP), 1); + PUSH_DATA (push, 0x00000000); + BEGIN_NV04(push, NV03_M2MF(OFFSET_OUT), 1); + PUSH_DATA (push, 0x00000000); src_off += src_pitch * line_count; dst_off += dst_pitch * line_count; diff --git a/src/nv04_xv_blit.c b/src/nv04_xv_blit.c index 4261a20..075b867 100644 --- a/src/nv04_xv_blit.c +++ b/src/nv04_xv_blit.c @@ -36,6 +36,7 @@ #include "hwdefs/nv_object.xml.h" #include "hwdefs/nv01_2d.xml.h" +#include "nv04_accel.h" #define FOURCC_RGB 0x0000003 @@ -43,140 +44,125 @@ extern Atom xvSetDefaults, xvSyncToVBlank; -/** - * NVPutBlitImage - * - * @param pScrn screen - * @param src_offset offset of image data in VRAM - * @param id pixel format - * @param src_pitch source pitch - * @param dstBox - * @param x1 - * @param y1 - * @param x2 - * @param y2 - * @param width - * @param height - * @param src_w - * @param src_h - * @param drw_w - * @param drw_h - * @param clipBoxes - * @param pDraw - */ Bool NVPutBlitImage(ScrnInfoPtr pScrn, struct nouveau_bo *src, int src_offset, int id, int src_pitch, BoxPtr dstBox, - int x1, int y1, int x2, int y2, - short width, short height, - short src_w, short src_h, - short drw_w, short drw_h, - RegionPtr clipBoxes, PixmapPtr ppix) + int x1, int y1, int x2, int y2, + short width, short height, + short src_w, short src_h, + short drw_w, short drw_h, + RegionPtr clipBoxes, PixmapPtr ppix) { - NVPtr pNv = NVPTR(pScrn); - NVPortPrivPtr pPriv = GET_BLIT_PRIVATE(pNv); - BoxPtr pbox; - int nbox; - CARD32 dsdx, dtdy; - CARD32 dst_size, dst_point; - CARD32 src_point, src_format; - struct nouveau_channel *chan = pNv->chan; + NVPtr pNv = NVPTR(pScrn); + NVPortPrivPtr pPriv = GET_BLIT_PRIVATE(pNv); + BoxPtr pbox; + int nbox; + CARD32 dsdx, dtdy; + CARD32 dst_size, dst_point; + CARD32 src_point, src_format; + struct nouveau_pushbuf *push = pNv->pushbuf; struct nouveau_bo *bo = nouveau_pixmap_bo(ppix); - int dst_format; + struct nv04_fifo *fifo = pNv->channel->data; + int dst_format; - if (!NVAccelGetCtxSurf2DFormatFromPixmap(ppix, &dst_format)) + if (!NVAccelGetCtxSurf2DFormatFromPixmap(ppix, &dst_format)) return BadImplementation; - if (MARK_RING(chan, 64, 4)) - return BadImplementation; + pbox = REGION_RECTS(clipBoxes); + nbox = REGION_NUM_RECTS(clipBoxes); + + dsdx = (src_w << 20) / drw_w; + dtdy = (src_h << 20) / drw_h; + + dst_size = ((dstBox->y2 - dstBox->y1) << 16) | + (dstBox->x2 - dstBox->x1); + dst_point = (dstBox->y1 << 16) | dstBox->x1; + + src_point = ((y1 << 4) & 0xffff0000) | (x1 >> 12); + + switch(id) { + case FOURCC_RGB: + src_format = NV03_SIFM_COLOR_FORMAT_X8R8G8B8; + break; + case FOURCC_UYVY: + src_format = NV03_SIFM_COLOR_FORMAT_YB8V8YA8U8; + break; + default: + src_format = NV03_SIFM_COLOR_FORMAT_V8YB8U8YA8; + break; + } - BEGIN_NV04(chan, NV04_SF2D(FORMAT), 4); - OUT_RING (chan, dst_format); - OUT_RING (chan, (exaGetPixmapPitch(ppix) << 16) | exaGetPixmapPitch(ppix)); - if (OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR) || - OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR)) { - MARK_UNDO(chan); + if (!PUSH_SPACE(push, 128)) return BadImplementation; + PUSH_RESET(push); + + BEGIN_NV04(push, NV04_SF2D(FORMAT), 4); + PUSH_DATA (push, dst_format); + PUSH_DATA (push, (exaGetPixmapPitch(ppix) << 16) | + exaGetPixmapPitch(ppix)); + PUSH_MTHDl(push, NV04_SF2D(OFFSET_SOURCE), bo, 0, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + PUSH_MTHDl(push, NV04_SF2D(OFFSET_DESTIN), bo, 0, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + BEGIN_NV04(push, NV01_SUBC(MISC, OBJECT), 1); + PUSH_DATA (push, pNv->NvScaledImage->handle); + BEGIN_NV04(push, NV03_SIFM(DMA_IMAGE), 1); + PUSH_MTHDo(push, NV03_SIFM(DMA_IMAGE), src, NOUVEAU_BO_RD | + NOUVEAU_BO_VRAM | NOUVEAU_BO_GART, + fifo->vram, fifo->gart); + if (pNv->dev->chipset >= 0x05) { + BEGIN_NV04(push, NV03_SIFM(COLOR_FORMAT), 2); + PUSH_DATA (push, src_format); + PUSH_DATA (push, NV03_SIFM_OPERATION_SRCCOPY); + } else { + BEGIN_NV04(push, NV03_SIFM(COLOR_FORMAT), 1); + PUSH_DATA (push, src_format); + } + + nouveau_pushbuf_bufctx(push, pNv->bufctx); + if (nouveau_pushbuf_validate(push)) { + nouveau_pushbuf_bufctx(push, NULL); + return BadAlloc; } - pbox = REGION_RECTS(clipBoxes); - nbox = REGION_NUM_RECTS(clipBoxes); - - dsdx = (src_w << 20) / drw_w; - dtdy = (src_h << 20) / drw_h; - - dst_size = ((dstBox->y2 - dstBox->y1) << 16) | - (dstBox->x2 - dstBox->x1); - dst_point = (dstBox->y1 << 16) | dstBox->x1; - - src_pitch |= (NV03_SIFM_FORMAT_ORIGIN_CENTER | - NV03_SIFM_FORMAT_FILTER_BILINEAR); - src_point = ((y1 << 4) & 0xffff0000) | (x1 >> 12); - - switch(id) { - case FOURCC_RGB: - src_format = NV03_SIFM_COLOR_FORMAT_X8R8G8B8; - break; - case FOURCC_UYVY: - src_format = NV03_SIFM_COLOR_FORMAT_YB8V8YA8U8; - break; - default: - src_format = NV03_SIFM_COLOR_FORMAT_V8YB8U8YA8; - break; - } - - if(pPriv->SyncToVBlank) { - FIRE_RING(chan); + if (pPriv->SyncToVBlank) NV11SyncToVBlank(ppix, dstBox); - } - - BEGIN_NV04(chan, NV01_SUBC(MISC, OBJECT), 1); - OUT_RING (chan, pNv->NvScaledImage->handle); - if (pNv->dev->chipset >= 0x05) { - BEGIN_NV04(chan, NV03_SIFM(COLOR_FORMAT), 2); - OUT_RING (chan, src_format); - OUT_RING (chan, NV03_SIFM_OPERATION_SRCCOPY); - } else { - BEGIN_NV04(chan, NV03_SIFM(COLOR_FORMAT), 1); - OUT_RING (chan, src_format); - } - - - BEGIN_NV04(chan, NV03_SIFM(DMA_IMAGE), 1); - OUT_RELOCo(chan, src, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | - NOUVEAU_BO_RD); - while (nbox--) { - BEGIN_NV04(chan, NV04_RECT(COLOR1_A), 1); - OUT_RING (chan, 0); - - BEGIN_NV04(chan, NV03_SIFM(CLIP_POINT), 6); - OUT_RING (chan, (pbox->y1 << 16) | pbox->x1); - OUT_RING (chan, ((pbox->y2 - pbox->y1) << 16) | - (pbox->x2 - pbox->x1)); - OUT_RING (chan, dst_point); - OUT_RING (chan, dst_size); - OUT_RING (chan, dsdx); - OUT_RING (chan, dtdy); - - BEGIN_NV04(chan, NV03_SIFM(SIZE), 4); - OUT_RING (chan, (height << 16) | width); - OUT_RING (chan, src_pitch); - if (OUT_RELOCl(chan, src, src_offset, NOUVEAU_BO_VRAM | - NOUVEAU_BO_GART | NOUVEAU_BO_RD)) { - MARK_UNDO(chan); + + while (nbox--) { + if (!PUSH_SPACE(push, 16)) { + nouveau_pushbuf_bufctx(push, NULL); return BadImplementation; } - OUT_RING (chan, src_point); - pbox++; - } - FIRE_RING (chan); + BEGIN_NV04(push, NV04_RECT(COLOR1_A), 1); + PUSH_DATA (push, 0); + + BEGIN_NV04(push, NV03_SIFM(CLIP_POINT), 6); + PUSH_DATA (push, (pbox->y1 << 16) | pbox->x1); + PUSH_DATA (push, (pbox->y2 - pbox->y1) << 16 | + (pbox->x2 - pbox->x1)); + PUSH_DATA (push, dst_point); + PUSH_DATA (push, dst_size); + PUSH_DATA (push, dsdx); + PUSH_DATA (push, dtdy); + BEGIN_NV04(push, NV03_SIFM(SIZE), 4); + PUSH_DATA (push, (height << 16) | width); + PUSH_DATA (push, NV03_SIFM_FORMAT_FILTER_BILINEAR | + NV03_SIFM_FORMAT_ORIGIN_CENTER | src_pitch); + PUSH_RELOC(push, src, src_offset, NOUVEAU_BO_LOW, 0, 0); + PUSH_DATA (push, src_point); + + pbox++; + } - exaMarkSync(pScrn->pScreen); + nouveau_pushbuf_bufctx(push, NULL); + PUSH_KICK(push); + exaMarkSync(pScrn->pScreen); - pPriv->videoStatus = FREE_TIMER; - pPriv->videoTime = currentTime.milliseconds + FREE_DELAY; - extern void NVVideoTimerCallback(ScrnInfoPtr, Time); + pPriv->videoStatus = FREE_TIMER; + pPriv->videoTime = currentTime.milliseconds + FREE_DELAY; + extern void NVVideoTimerCallback(ScrnInfoPtr, Time); pNv->VideoTimerCallback = NVVideoTimerCallback; return Success; } @@ -199,22 +185,22 @@ NVPutBlitImage(ScrnInfoPtr pScrn, struct nouveau_bo *src, int src_offset, */ int NVSetBlitPortAttribute(ScrnInfoPtr pScrn, Atom attribute, - INT32 value, pointer data) + INT32 value, pointer data) { - NVPortPrivPtr pPriv = (NVPortPrivPtr)data; - NVPtr pNv = NVPTR(pScrn); - - if ((attribute == xvSyncToVBlank) && VSYNC_POSSIBLE) { - if ((value < 0) || (value > 1)) - return BadValue; - pPriv->SyncToVBlank = value; - } else - if (attribute == xvSetDefaults) { - pPriv->SyncToVBlank = VSYNC_POSSIBLE; - } else - return BadMatch; - - return Success; + NVPortPrivPtr pPriv = (NVPortPrivPtr)data; + NVPtr pNv = NVPTR(pScrn); + + if ((attribute == xvSyncToVBlank) && VSYNC_POSSIBLE) { + if ((value < 0) || (value > 1)) + return BadValue; + pPriv->SyncToVBlank = value; + } else + if (attribute == xvSetDefaults) { + pPriv->SyncToVBlank = VSYNC_POSSIBLE; + } else + return BadMatch; + + return Success; } /** @@ -230,16 +216,16 @@ NVSetBlitPortAttribute(ScrnInfoPtr pScrn, Atom attribute, */ int NVGetBlitPortAttribute(ScrnInfoPtr pScrn, Atom attribute, - INT32 *value, pointer data) + INT32 *value, pointer data) { - NVPortPrivPtr pPriv = (NVPortPrivPtr)data; + NVPortPrivPtr pPriv = (NVPortPrivPtr)data; - if(attribute == xvSyncToVBlank) - *value = (pPriv->SyncToVBlank) ? 1 : 0; - else - return BadMatch; + if(attribute == xvSyncToVBlank) + *value = (pPriv->SyncToVBlank) ? 1 : 0; + else + return BadMatch; - return Success; + return Success; } /** diff --git a/src/nv10_exa.c b/src/nv10_exa.c index 2824f58..efbf4b5 100644 --- a/src/nv10_exa.c +++ b/src/nv10_exa.c @@ -31,6 +31,7 @@ #include "hwdefs/nv_object.xml.h" #include "hwdefs/nv10_3d.xml.h" +#include "nv04_accel.h" /* Texture/Render target formats. */ static struct pict_format { @@ -374,73 +375,63 @@ NV10EXACheckComposite(int op, PicturePtr src, PicturePtr mask, PicturePtr dst) static Bool setup_texture(NVPtr pNv, int unit, PicturePtr pict, PixmapPtr pixmap) { - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; struct nouveau_bo *bo = nouveau_pixmap_bo(pixmap); - unsigned tex_reloc = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; - long w = pict->pDrawable->width, - h = pict->pDrawable->height; - unsigned int txfmt = - NV10_3D_TEX_FORMAT_WRAP_T_CLAMP_TO_EDGE | - NV10_3D_TEX_FORMAT_WRAP_S_CLAMP_TO_EDGE | - log2i(w) << 20 | log2i(h) << 16 | - 1 << 12 | /* lod == 1 */ - get_tex_format(pict) | - 0x50 /* UNK */; - - BEGIN_NV04(chan, NV10_3D(TEX_OFFSET(unit)), 1); - if (OUT_RELOCl(chan, bo, 0, tex_reloc)) - return FALSE; - - if (pict->repeat == RepeatNone) { - /* NPOT_SIZE expects an even number for width, we can - * round up uneven numbers here because EXA always - * gives 64 byte aligned pixmaps and for all formats - * we support 64 bytes represents an even number of - * pixels - */ + unsigned reloc = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; + unsigned h = pict->pDrawable->height; + unsigned w = pict->pDrawable->width; + unsigned format; + + format = NV10_3D_TEX_FORMAT_WRAP_T_CLAMP_TO_EDGE | + NV10_3D_TEX_FORMAT_WRAP_S_CLAMP_TO_EDGE | + log2i(w) << 20 | log2i(h) << 16 | + 1 << 12 | /* lod == 1 */ + get_tex_format(pict) | + 0x50 /* UNK */; + + /* NPOT_SIZE expects an even number for width, we can round up uneven + * numbers here because EXA always gives 64 byte aligned pixmaps and + * for all formats we support 64 bytes represents an even number of + * pixels + */ +// if (pict->repeat == RepeatNone) w = (w + 1) &~ 1; - BEGIN_NV04(chan, NV10_3D(TEX_NPOT_PITCH(unit)), 1); - OUT_RING (chan, exaGetPixmapPitch(pixmap) << 16); - - BEGIN_NV04(chan, NV10_3D(TEX_NPOT_SIZE(unit)), 1); - OUT_RING (chan, w << 16 | h); - } - - BEGIN_NV04(chan, NV10_3D(TEX_FORMAT(unit)), 1 ); - if (OUT_RELOCd(chan, bo, txfmt, tex_reloc | NOUVEAU_BO_OR, - NV10_3D_TEX_FORMAT_DMA0, NV10_3D_TEX_FORMAT_DMA1)) - return FALSE; - BEGIN_NV04(chan, NV10_3D(TEX_ENABLE(unit)), 1 ); - OUT_RING (chan, NV10_3D_TEX_ENABLE_ENABLE); - - BEGIN_NV04(chan, NV10_3D(TEX_FILTER(unit)), 1); + BEGIN_NV04(push, NV10_3D(TEX_OFFSET(unit)), 1); + PUSH_MTHDl(push, NV10_3D(TEX_OFFSET(unit)), bo, 0, reloc); + BEGIN_NV04(push, NV10_3D(TEX_FORMAT(unit)), 1); + PUSH_MTHDs(push, NV10_3D(TEX_FORMAT(unit)), bo, format, reloc, + NV10_3D_TEX_FORMAT_DMA0, + NV10_3D_TEX_FORMAT_DMA1); + BEGIN_NV04(push, NV10_3D(TEX_ENABLE(unit)), 1 ); + PUSH_DATA (push, NV10_3D_TEX_ENABLE_ENABLE); + BEGIN_NV04(push, NV10_3D(TEX_NPOT_PITCH(unit)), 1); + PUSH_DATA (push, exaGetPixmapPitch(pixmap) << 16); + BEGIN_NV04(push, NV10_3D(TEX_NPOT_SIZE(unit)), 1); + PUSH_DATA (push, (w << 16) | h); + BEGIN_NV04(push, NV10_3D(TEX_FILTER(unit)), 1); if (pict->filter == PictFilterNearest) - OUT_RING(chan, (NV10_3D_TEX_FILTER_MAGNIFY_NEAREST | - NV10_3D_TEX_FILTER_MINIFY_NEAREST)); + PUSH_DATA(push, NV10_3D_TEX_FILTER_MAGNIFY_NEAREST | + NV10_3D_TEX_FILTER_MINIFY_NEAREST); else - OUT_RING(chan, (NV10_3D_TEX_FILTER_MAGNIFY_LINEAR | - NV10_3D_TEX_FILTER_MINIFY_LINEAR)); - + PUSH_DATA(push, NV10_3D_TEX_FILTER_MAGNIFY_LINEAR | + NV10_3D_TEX_FILTER_MINIFY_LINEAR); return TRUE; } static Bool setup_render_target(NVPtr pNv, PicturePtr pict, PixmapPtr pixmap) { - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; struct nouveau_bo *bo = nouveau_pixmap_bo(pixmap); - BEGIN_NV04(chan, NV10_3D(RT_FORMAT), 2); - OUT_RING (chan, get_rt_format(pict)); - OUT_RING (chan, (exaGetPixmapPitch(pixmap) << 16 | + BEGIN_NV04(push, NV10_3D(RT_FORMAT), 3); + PUSH_DATA (push, get_rt_format(pict)); + PUSH_DATA (push, (exaGetPixmapPitch(pixmap) << 16 | exaGetPixmapPitch(pixmap))); - - BEGIN_NV04(chan, NV10_3D(COLOR_OFFSET), 1); - if (OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR)) - return FALSE; - + PUSH_MTHDl(push, NV10_3D(COLOR_OFFSET), bo, 0, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); return TRUE; } @@ -482,9 +473,9 @@ setup_render_target(NVPtr pNv, PicturePtr pict, PixmapPtr pixmap) NV10_3D_RC_IN_RGB_##input##_COMPONENT_USAGE_##chan) static void -setup_combiners(NVPtr pNv, PicturePtr src, PicturePtr mask) +setup_combiners(NVPtr pNv, PicturePtr src, PicturePtr mask, int alu) { - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; uint32_t rc_in_alpha = 0, rc_in_rgb = 0; if (PICT_FORMAT_A(src->format)) @@ -498,7 +489,7 @@ setup_combiners(NVPtr pNv, PicturePtr src, PicturePtr mask) rc_in_alpha |= RC_IN_ONE(B); if (effective_component_alpha(mask)) { - if (!needs_src_alpha(pNv->alu)) { + if (!needs_src_alpha(alu)) { /* The alpha channels won't be used for blending. Drop * them, as our pixels only have 4 components... * output_i = src_i * mask_i @@ -528,22 +519,22 @@ setup_combiners(NVPtr pNv, PicturePtr src, PicturePtr mask) rc_in_rgb |= RC_IN_ONE(B); } - BEGIN_NV04(chan, NV10_3D(RC_IN_ALPHA(0)), 1); - OUT_RING (chan, rc_in_alpha); - BEGIN_NV04(chan, NV10_3D(RC_IN_RGB(0)), 1); - OUT_RING (chan, rc_in_rgb); + BEGIN_NV04(push, NV10_3D(RC_IN_ALPHA(0)), 1); + PUSH_DATA (push, rc_in_alpha); + BEGIN_NV04(push, NV10_3D(RC_IN_RGB(0)), 1); + PUSH_DATA (push, rc_in_rgb); } static void -setup_blend_function(NVPtr pNv) +setup_blend_function(NVPtr pNv, PicturePtr pdpict, int alu) { - struct nouveau_channel *chan = pNv->chan; - struct pict_op *op = &nv10_pict_op[pNv->alu]; + struct nouveau_pushbuf *push = pNv->pushbuf; + struct pict_op *op = &nv10_pict_op[alu]; int src_factor = op->src; int dst_factor = op->dst; if (src_factor == SF(ONE_MINUS_DST_ALPHA) && - !PICT_FORMAT_A(pNv->pdpict->format)) + !PICT_FORMAT_A(pdpict->format)) /* ONE_MINUS_DST_ALPHA doesn't always do the right thing for * framebuffers without alpha channel. But it's the same as * ZERO in that case. @@ -557,21 +548,11 @@ setup_blend_function(NVPtr pNv) dst_factor = DF(ONE_MINUS_SRC_COLOR); } - BEGIN_NV04(chan, NV10_3D(BLEND_FUNC_SRC), 2); - OUT_RING (chan, src_factor); - OUT_RING (chan, dst_factor); - BEGIN_NV04(chan, NV10_3D(BLEND_FUNC_ENABLE), 1); - OUT_RING (chan, 1); -} - -static void -NV10StateCompositeReemit(struct nouveau_channel *chan) -{ - ScrnInfoPtr pScrn = chan->user_private; - NVPtr pNv = NVPTR(pScrn); - - NV10EXAPrepareComposite(pNv->alu, pNv->pspict, pNv->pmpict, pNv->pdpict, - pNv->pspix, pNv->pmpix, pNv->pdpix); + BEGIN_NV04(push, NV10_3D(BLEND_FUNC_SRC), 2); + PUSH_DATA (push, src_factor); + PUSH_DATA (push, dst_factor); + BEGIN_NV04(push, NV10_3D(BLEND_FUNC_ENABLE), 1); + PUSH_DATA (push, 1); } Bool @@ -585,46 +566,39 @@ NV10EXAPrepareComposite(int op, { ScrnInfoPtr pScrn = xf86Screens[dst->drawable.pScreen->myNum]; NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; - if (MARK_RING(chan, 128, 5)) + if (!PUSH_SPACE(push, 128)) return FALSE; - - pNv->alu = op; - pNv->pspict = pict_src; - pNv->pmpict = pict_mask; - pNv->pdpict = pict_dst; - pNv->pspix = src; - pNv->pmpix = mask; - pNv->pdpix = dst; + PUSH_RESET(push); /* Set dst format */ if (!setup_render_target(pNv, pict_dst, dst)) - goto fail; + return FALSE; /* Set src format */ if (!setup_texture(pNv, 0, pict_src, src)) - goto fail; + return FALSE; /* Set mask format */ - if (mask && - !setup_texture(pNv, 1, pict_mask, mask)) - goto fail; + if (mask && !setup_texture(pNv, 1, pict_mask, mask)) + return FALSE; /* Set the register combiners up. */ - setup_combiners(pNv, pict_src, pict_mask); + setup_combiners(pNv, pict_src, pict_mask, op); /* Set PictOp */ - setup_blend_function(pNv); + setup_blend_function(pNv, pict_dst, op); - chan->flush_notify = NV10StateCompositeReemit; + nouveau_pushbuf_bufctx(push, pNv->bufctx); + if (nouveau_pushbuf_validate(push)) { + nouveau_pushbuf_bufctx(push, NULL); + return FALSE; + } + pNv->pspict = pict_src; + pNv->pmpict = pict_mask; return TRUE; - -fail: - MARK_UNDO(chan); - - return FALSE; } #define QUAD(x, y, w, h) \ @@ -642,29 +616,29 @@ fail: #define xFixedToFloat(v) \ ((float)xFixedToInt((v)) + ((float)xFixedFrac(v) / 65536.0)) -#define OUT_RINGi(chan, v, i) \ - OUT_RINGf(chan, xFixedToFloat((v).vector[i])) +#define PUSH_DATAi(push, v, i) \ + PUSH_DATAf(push, xFixedToFloat((v).vector[i])) static inline void emit_vertex(NVPtr pNv, int i, PictVector pos[], PictVector tex0[], PictVector tex1[]) { - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; - BEGIN_NV04(chan, NV10_3D(VERTEX_TX0_2F_S), 2); - OUT_RINGi (chan, tex0[i], 0); - OUT_RINGi (chan, tex0[i], 1); + BEGIN_NV04(push, NV10_3D(VERTEX_TX0_2F_S), 2); + PUSH_DATAi(push, tex0[i], 0); + PUSH_DATAi(push, tex0[i], 1); if (tex1) { - BEGIN_NV04(chan, NV10_3D(VERTEX_TX1_2F_S), 2); - OUT_RINGi (chan, tex1[i], 0); - OUT_RINGi (chan, tex1[i], 1); + BEGIN_NV04(push, NV10_3D(VERTEX_TX1_2F_S), 2); + PUSH_DATAi(push, tex1[i], 0); + PUSH_DATAi(push, tex1[i], 1); } - BEGIN_NV04(chan, NV10_3D(VERTEX_POS_3F_X), 3); - OUT_RINGi (chan, pos[i], 0); - OUT_RINGi (chan, pos[i], 1); - OUT_RINGf (chan, 0); + BEGIN_NV04(push, NV10_3D(VERTEX_POS_3F_X), 3); + PUSH_DATAi(push, pos[i], 0); + PUSH_DATAi(push, pos[i], 1); + PUSH_DATAf(push, 0.0); } static inline void @@ -683,7 +657,7 @@ NV10EXAComposite(PixmapPtr pix_dst, { ScrnInfoPtr pScrn = xf86Screens[pix_dst->drawable.pScreen->myNum]; NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; PicturePtr mask = pNv->pmpict, src = pNv->pspict; PictVector dstq[4] = QUAD(dstX, dstY, width, height), @@ -694,31 +668,29 @@ NV10EXAComposite(PixmapPtr pix_dst, if (mask) MAP(transform_vertex, mask->transform, maskq); - WAIT_RING (chan, 64); - BEGIN_NV04(chan, NV10_3D(VERTEX_BEGIN_END), 1); - OUT_RING (chan, NV10_3D_VERTEX_BEGIN_END_QUADS); + if (!PUSH_SPACE(push, 64)) + return; + BEGIN_NV04(push, NV10_3D(VERTEX_BEGIN_END), 1); + PUSH_DATA (push, NV10_3D_VERTEX_BEGIN_END_QUADS); MAP(emit_vertex, pNv, dstq, srcq, mask ? maskq : NULL); - - BEGIN_NV04(chan, NV10_3D(VERTEX_BEGIN_END), 1); - OUT_RING (chan, NV10_3D_VERTEX_BEGIN_END_STOP); + BEGIN_NV04(push, NV10_3D(VERTEX_BEGIN_END), 1); + PUSH_DATA (push, NV10_3D_VERTEX_BEGIN_END_STOP); } void NV10EXADoneComposite(PixmapPtr dst) { ScrnInfoPtr pScrn = xf86Screens[dst->drawable.pScreen->myNum]; - NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; - - chan->flush_notify = NULL; + nouveau_pushbuf_bufctx(NVPTR(pScrn)->pushbuf, NULL); } Bool NVAccelInitNV10TCL(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; + struct nv04_fifo *fifo = pNv->channel->data; uint32_t class = 0; int i; @@ -735,233 +707,234 @@ NVAccelInitNV10TCL(ScrnInfoPtr pScrn) else class = NV10_3D_CLASS; - if (!pNv->Nv3D) { - if (nouveau_grobj_alloc(pNv->chan, Nv3D, class, &pNv->Nv3D)) - return FALSE; - } + if (nouveau_object_new(pNv->channel, Nv3D, class, NULL, 0, &pNv->Nv3D)) + return FALSE; + + if (!PUSH_SPACE(push, 256)) + return FALSE; - BEGIN_NV04(chan, NV01_SUBC(3D, OBJECT), 1); - OUT_RING (chan, pNv->Nv3D->handle); - BEGIN_NV04(chan, NV10_3D(DMA_NOTIFY), 1); - OUT_RING (chan, chan->nullobj->handle); + BEGIN_NV04(push, NV01_SUBC(3D, OBJECT), 1); + PUSH_DATA (push, pNv->Nv3D->handle); + BEGIN_NV04(push, NV10_3D(DMA_NOTIFY), 1); + PUSH_DATA (push, pNv->NvNull->handle); - BEGIN_NV04(chan, NV10_3D(DMA_TEXTURE0), 2); - OUT_RING (chan, pNv->chan->vram->handle); - OUT_RING (chan, pNv->chan->gart->handle); + BEGIN_NV04(push, NV10_3D(DMA_TEXTURE0), 2); + PUSH_DATA (push, fifo->vram); + PUSH_DATA (push, fifo->gart); - BEGIN_NV04(chan, NV10_3D(DMA_COLOR), 2); - OUT_RING (chan, pNv->chan->vram->handle); - OUT_RING (chan, pNv->chan->vram->handle); + BEGIN_NV04(push, NV10_3D(DMA_COLOR), 2); + PUSH_DATA (push, fifo->vram); + PUSH_DATA (push, fifo->vram); - BEGIN_NV04(chan, NV04_GRAPH(3D, NOP), 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, NV04_GRAPH(3D, NOP), 1); + PUSH_DATA (push, 0); - BEGIN_NV04(chan, NV10_3D(RT_HORIZ), 2); - OUT_RING (chan, 2048 << 16 | 0); - OUT_RING (chan, 2048 << 16 | 0); + BEGIN_NV04(push, NV10_3D(RT_HORIZ), 2); + PUSH_DATA (push, 2048 << 16 | 0); + PUSH_DATA (push, 2048 << 16 | 0); - BEGIN_NV04(chan, NV10_3D(ZETA_OFFSET), 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, NV10_3D(ZETA_OFFSET), 1); + PUSH_DATA (push, 0); - BEGIN_NV04(chan, NV10_3D(VIEWPORT_CLIP_MODE), 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, NV10_3D(VIEWPORT_CLIP_MODE), 1); + PUSH_DATA (push, 0); - BEGIN_NV04(chan, NV10_3D(VIEWPORT_CLIP_HORIZ(0)), 1); - OUT_RING (chan, 0x7ff << 16 | 0x800800); - BEGIN_NV04(chan, NV10_3D(VIEWPORT_CLIP_VERT(0)), 1); - OUT_RING (chan, 0x7ff << 16 | 0x800800); + BEGIN_NV04(push, NV10_3D(VIEWPORT_CLIP_HORIZ(0)), 1); + PUSH_DATA (push, 0x7ff << 16 | 0x800800); + BEGIN_NV04(push, NV10_3D(VIEWPORT_CLIP_VERT(0)), 1); + PUSH_DATA (push, 0x7ff << 16 | 0x800800); for (i = 1; i < 8; i++) { - BEGIN_NV04(chan, NV10_3D(VIEWPORT_CLIP_HORIZ(i)), 1); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NV10_3D(VIEWPORT_CLIP_VERT(i)), 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, NV10_3D(VIEWPORT_CLIP_HORIZ(i)), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV10_3D(VIEWPORT_CLIP_VERT(i)), 1); + PUSH_DATA (push, 0); } - BEGIN_NV04(chan, SUBC_3D(0x290), 1); - OUT_RING (chan, (0x10<<16)|1); - BEGIN_NV04(chan, SUBC_3D(0x3f4), 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, SUBC_3D(0x290), 1); + PUSH_DATA (push, (0x10<<16)|1); + BEGIN_NV04(push, SUBC_3D(0x3f4), 1); + PUSH_DATA (push, 0); - BEGIN_NV04(chan, NV04_GRAPH(3D, NOP), 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, NV04_GRAPH(3D, NOP), 1); + PUSH_DATA (push, 0); if (class != NV10_3D_CLASS) { /* For nv11, nv17 */ - BEGIN_NV04(chan, SUBC_3D(0x120), 3); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - OUT_RING (chan, 2); - - BEGIN_NV04(chan, SUBC_BLIT(0x120), 3); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - OUT_RING (chan, 2); - - BEGIN_NV04(chan, NV04_GRAPH(3D, NOP), 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, SUBC_3D(0x120), 3); + PUSH_DATA (push, 0); + PUSH_DATA (push, 1); + PUSH_DATA (push, 2); + + BEGIN_NV04(push, SUBC_BLIT(0x120), 3); + PUSH_DATA (push, 0); + PUSH_DATA (push, 1); + PUSH_DATA (push, 2); + + BEGIN_NV04(push, NV04_GRAPH(3D, NOP), 1); + PUSH_DATA (push, 0); } - BEGIN_NV04(chan, NV04_GRAPH(3D, NOP), 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, NV04_GRAPH(3D, NOP), 1); + PUSH_DATA (push, 0); /* Set state */ - BEGIN_NV04(chan, NV10_3D(FOG_ENABLE), 1); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NV10_3D(ALPHA_FUNC_ENABLE), 1); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NV10_3D(ALPHA_FUNC_FUNC), 2); - OUT_RING (chan, 0x207); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NV10_3D(TEX_ENABLE(0)), 2); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NV10_3D(RC_IN_ALPHA(0)), 6); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NV10_3D(RC_OUT_ALPHA(0)), 6); - OUT_RING (chan, 0x00000c00); - OUT_RING (chan, 0); - OUT_RING (chan, 0x00000c00); - OUT_RING (chan, 0x18000000); - OUT_RING (chan, 0x300c0000); - OUT_RING (chan, 0x00001c80); - BEGIN_NV04(chan, NV10_3D(BLEND_FUNC_ENABLE), 1); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NV10_3D(DITHER_ENABLE), 2); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NV10_3D(LINE_SMOOTH_ENABLE), 1); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NV10_3D(VERTEX_WEIGHT_ENABLE), 2); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NV10_3D(BLEND_FUNC_SRC), 4); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, 0x8006); - BEGIN_NV04(chan, NV10_3D(STENCIL_MASK), 8); - OUT_RING (chan, 0xff); - OUT_RING (chan, 0x207); - OUT_RING (chan, 0); - OUT_RING (chan, 0xff); - OUT_RING (chan, 0x1e00); - OUT_RING (chan, 0x1e00); - OUT_RING (chan, 0x1e00); - OUT_RING (chan, 0x1d01); - BEGIN_NV04(chan, NV10_3D(NORMALIZE_ENABLE), 1); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NV10_3D(FOG_ENABLE), 2); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NV10_3D(LIGHT_MODEL), 1); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NV10_3D(SEPARATE_SPECULAR_ENABLE), 1); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NV10_3D(ENABLED_LIGHTS), 1); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NV10_3D(POLYGON_OFFSET_POINT_ENABLE), 3); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NV10_3D(DEPTH_FUNC), 1); - OUT_RING (chan, 0x201); - BEGIN_NV04(chan, NV10_3D(DEPTH_WRITE_ENABLE), 1); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NV10_3D(DEPTH_TEST_ENABLE), 1); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NV10_3D(POLYGON_OFFSET_FACTOR), 2); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NV10_3D(POINT_SIZE), 1); - OUT_RING (chan, 8); - BEGIN_NV04(chan, NV10_3D(POINT_PARAMETERS_ENABLE), 2); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NV10_3D(LINE_WIDTH), 1); - OUT_RING (chan, 8); - BEGIN_NV04(chan, NV10_3D(LINE_SMOOTH_ENABLE), 1); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NV10_3D(POLYGON_MODE_FRONT), 2); - OUT_RING (chan, 0x1b02); - OUT_RING (chan, 0x1b02); - BEGIN_NV04(chan, NV10_3D(CULL_FACE), 2); - OUT_RING (chan, 0x405); - OUT_RING (chan, 0x901); - BEGIN_NV04(chan, NV10_3D(POLYGON_SMOOTH_ENABLE), 1); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NV10_3D(CULL_FACE_ENABLE), 1); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NV10_3D(TEX_GEN_MODE(0, 0)), 8); + BEGIN_NV04(push, NV10_3D(FOG_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV10_3D(ALPHA_FUNC_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV10_3D(ALPHA_FUNC_FUNC), 2); + PUSH_DATA (push, 0x207); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV10_3D(TEX_ENABLE(0)), 2); + PUSH_DATA (push, 0); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV10_3D(RC_IN_ALPHA(0)), 6); + PUSH_DATA (push, 0); + PUSH_DATA (push, 0); + PUSH_DATA (push, 0); + PUSH_DATA (push, 0); + PUSH_DATA (push, 0); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV10_3D(RC_OUT_ALPHA(0)), 6); + PUSH_DATA (push, 0x00000c00); + PUSH_DATA (push, 0); + PUSH_DATA (push, 0x00000c00); + PUSH_DATA (push, 0x18000000); + PUSH_DATA (push, 0x300c0000); + PUSH_DATA (push, 0x00001c80); + BEGIN_NV04(push, NV10_3D(BLEND_FUNC_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV10_3D(DITHER_ENABLE), 2); + PUSH_DATA (push, 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV10_3D(LINE_SMOOTH_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV10_3D(VERTEX_WEIGHT_ENABLE), 2); + PUSH_DATA (push, 0); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV10_3D(BLEND_FUNC_SRC), 4); + PUSH_DATA (push, 1); + PUSH_DATA (push, 0); + PUSH_DATA (push, 0); + PUSH_DATA (push, 0x8006); + BEGIN_NV04(push, NV10_3D(STENCIL_MASK), 8); + PUSH_DATA (push, 0xff); + PUSH_DATA (push, 0x207); + PUSH_DATA (push, 0); + PUSH_DATA (push, 0xff); + PUSH_DATA (push, 0x1e00); + PUSH_DATA (push, 0x1e00); + PUSH_DATA (push, 0x1e00); + PUSH_DATA (push, 0x1d01); + BEGIN_NV04(push, NV10_3D(NORMALIZE_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV10_3D(FOG_ENABLE), 2); + PUSH_DATA (push, 0); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV10_3D(LIGHT_MODEL), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV10_3D(SEPARATE_SPECULAR_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV10_3D(ENABLED_LIGHTS), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV10_3D(POLYGON_OFFSET_POINT_ENABLE), 3); + PUSH_DATA (push, 0); + PUSH_DATA (push, 0); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV10_3D(DEPTH_FUNC), 1); + PUSH_DATA (push, 0x201); + BEGIN_NV04(push, NV10_3D(DEPTH_WRITE_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV10_3D(DEPTH_TEST_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV10_3D(POLYGON_OFFSET_FACTOR), 2); + PUSH_DATA (push, 0); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV10_3D(POINT_SIZE), 1); + PUSH_DATA (push, 8); + BEGIN_NV04(push, NV10_3D(POINT_PARAMETERS_ENABLE), 2); + PUSH_DATA (push, 0); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV10_3D(LINE_WIDTH), 1); + PUSH_DATA (push, 8); + BEGIN_NV04(push, NV10_3D(LINE_SMOOTH_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV10_3D(POLYGON_MODE_FRONT), 2); + PUSH_DATA (push, 0x1b02); + PUSH_DATA (push, 0x1b02); + BEGIN_NV04(push, NV10_3D(CULL_FACE), 2); + PUSH_DATA (push, 0x405); + PUSH_DATA (push, 0x901); + BEGIN_NV04(push, NV10_3D(POLYGON_SMOOTH_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV10_3D(CULL_FACE_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV10_3D(TEX_GEN_MODE(0, 0)), 8); for (i = 0; i < 8; i++) - OUT_RING (chan, 0); + PUSH_DATA (push, 0); - BEGIN_NV04(chan, NV10_3D(FOG_COEFF(0)), 3); - OUT_RING (chan, 0x3fc00000); /* -1.50 */ - OUT_RING (chan, 0xbdb8aa0a); /* -0.09 */ - OUT_RING (chan, 0); /* 0.00 */ + BEGIN_NV04(push, NV10_3D(FOG_COEFF(0)), 3); + PUSH_DATA (push, 0x3fc00000); /* -1.50 */ + PUSH_DATA (push, 0xbdb8aa0a); /* -0.09 */ + PUSH_DATA (push, 0); /* 0.00 */ - BEGIN_NV04(chan, NV04_GRAPH(3D, NOP), 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, NV04_GRAPH(3D, NOP), 1); + PUSH_DATA (push, 0); - BEGIN_NV04(chan, NV10_3D(FOG_MODE), 2); - OUT_RING (chan, 0x802); - OUT_RING (chan, 2); + BEGIN_NV04(push, NV10_3D(FOG_MODE), 2); + PUSH_DATA (push, 0x802); + PUSH_DATA (push, 2); /* for some reason VIEW_MATRIX_ENABLE need to be 6 instead of 4 when * using texturing, except when using the texture matrix */ - BEGIN_NV04(chan, NV10_3D(VIEW_MATRIX_ENABLE), 1); - OUT_RING (chan, 6); - BEGIN_NV04(chan, NV10_3D(COLOR_MASK), 1); - OUT_RING (chan, 0x01010101); + BEGIN_NV04(push, NV10_3D(VIEW_MATRIX_ENABLE), 1); + PUSH_DATA (push, 6); + BEGIN_NV04(push, NV10_3D(COLOR_MASK), 1); + PUSH_DATA (push, 0x01010101); - BEGIN_NV04(chan, NV10_3D(PROJECTION_MATRIX(0)), 16); + BEGIN_NV04(push, NV10_3D(PROJECTION_MATRIX(0)), 16); for(i = 0; i < 16; i++) - OUT_RINGf(chan, i/4 == i%4 ? 1.0 : 0.0); + PUSH_DATAf(push, i/4 == i%4 ? 1.0 : 0.0); - BEGIN_NV04(chan, NV10_3D(DEPTH_RANGE_NEAR), 2); - OUT_RING (chan, 0); - OUT_RINGf (chan, 65536.0); + BEGIN_NV04(push, NV10_3D(DEPTH_RANGE_NEAR), 2); + PUSH_DATA (push, 0); + PUSH_DATAf(push, 65536.0); - BEGIN_NV04(chan, NV10_3D(VIEWPORT_TRANSLATE_X), 4); - OUT_RINGf (chan, -2048.0); - OUT_RINGf (chan, -2048.0); - OUT_RINGf (chan, 0); - OUT_RING (chan, 0); + BEGIN_NV04(push, NV10_3D(VIEWPORT_TRANSLATE_X), 4); + PUSH_DATAf(push, -2048.0); + PUSH_DATAf(push, -2048.0); + PUSH_DATAf(push, 0); + PUSH_DATA (push, 0); /* Set vertex component */ - BEGIN_NV04(chan, NV10_3D(VERTEX_COL_4F_R), 4); - OUT_RINGf (chan, 1.0); - OUT_RINGf (chan, 1.0); - OUT_RINGf (chan, 1.0); - OUT_RINGf (chan, 1.0); - BEGIN_NV04(chan, NV10_3D(VERTEX_COL2_3F_R), 3); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NV10_3D(VERTEX_NOR_3F_X), 3); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RINGf (chan, 1.0); - BEGIN_NV04(chan, NV10_3D(VERTEX_TX0_4F_S), 4); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 1.0); - BEGIN_NV04(chan, NV10_3D(VERTEX_TX1_4F_S), 4); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 1.0); - BEGIN_NV04(chan, NV10_3D(VERTEX_FOG_1F), 1); - OUT_RINGf (chan, 0.0); - BEGIN_NV04(chan, NV10_3D(EDGEFLAG_ENABLE), 1); - OUT_RING (chan, 1); + BEGIN_NV04(push, NV10_3D(VERTEX_COL_4F_R), 4); + PUSH_DATAf(push, 1.0); + PUSH_DATAf(push, 1.0); + PUSH_DATAf(push, 1.0); + PUSH_DATAf(push, 1.0); + BEGIN_NV04(push, NV10_3D(VERTEX_COL2_3F_R), 3); + PUSH_DATA (push, 0); + PUSH_DATA (push, 0); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV10_3D(VERTEX_NOR_3F_X), 3); + PUSH_DATA (push, 0); + PUSH_DATA (push, 0); + PUSH_DATAf(push, 1.0); + BEGIN_NV04(push, NV10_3D(VERTEX_TX0_4F_S), 4); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 1.0); + BEGIN_NV04(push, NV10_3D(VERTEX_TX1_4F_S), 4); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 1.0); + BEGIN_NV04(push, NV10_3D(VERTEX_FOG_1F), 1); + PUSH_DATAf(push, 0.0); + BEGIN_NV04(push, NV10_3D(EDGEFLAG_ENABLE), 1); + PUSH_DATA (push, 1); return TRUE; } diff --git a/src/nv30_exa.c b/src/nv30_exa.c index ce9bbb3..725a66a 100644 --- a/src/nv30_exa.c +++ b/src/nv30_exa.c @@ -25,8 +25,10 @@ #include "nv_include.h" #include "nv30_shaders.h" + #include "hwdefs/nv_object.xml.h" #include "hwdefs/nv30-40_3d.xml.h" +#include "nv04_accel.h" typedef struct nv_pict_surface_format { int pict_fmt; @@ -258,7 +260,7 @@ NV30_SetupBlend(ScrnInfoPtr pScrn, nv_pict_op_t *blend, PictFormatShort dest_format, Bool component_alpha) { NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; uint32_t sblend, dblend; sblend = blend->src_card_op; @@ -289,13 +291,13 @@ NV30_SetupBlend(ScrnInfoPtr pScrn, nv_pict_op_t *blend, } if (sblend == BF(ONE) && dblend == BF(ZERO)) { - BEGIN_NV04(chan, NV30_3D(BLEND_FUNC_ENABLE), 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, NV30_3D(BLEND_FUNC_ENABLE), 1); + PUSH_DATA (push, 0); } else { - BEGIN_NV04(chan, NV30_3D(BLEND_FUNC_ENABLE), 3); - OUT_RING (chan, 1); - OUT_RING (chan, (sblend << 16) | sblend); - OUT_RING (chan, (dblend << 16) | dblend); + BEGIN_NV04(push, NV30_3D(BLEND_FUNC_ENABLE), 3); + PUSH_DATA (push, 1); + PUSH_DATA (push, (sblend << 16) | sblend); + PUSH_DATA (push, (dblend << 16) | dblend); } } @@ -303,11 +305,14 @@ static Bool NV30EXATexture(ScrnInfoPtr pScrn, PixmapPtr pPix, PicturePtr pPict, int unit) { NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; struct nouveau_bo *bo = nouveau_pixmap_bo(pPix); nv_pict_texture_format_t *fmt; + unsigned reloc = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; + uint32_t pitch = exaGetPixmapPitch(pPix); + uint32_t log2h = log2i(pPix->drawable.height); + uint32_t log2w = log2i(pPix->drawable.width); uint32_t card_filter, card_repeat; - uint32_t tex_reloc = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; NV30EXA_STATE; fmt = NV30_GetPictTextureFormat(pPict->format); @@ -321,34 +326,32 @@ NV30EXATexture(ScrnInfoPtr pScrn, PixmapPtr pPix, PicturePtr pPict, int unit) else card_filter = 1; - BEGIN_NV04(chan, NV30_3D(TEX_OFFSET(unit)), 8); - if (OUT_RELOCl(chan, bo, 0, tex_reloc) || - OUT_RELOCd(chan, bo, NV30_3D_TEX_FORMAT_DIMS_2D | (1 << 16) | 8 | - (fmt->card_fmt << NV30_3D_TEX_FORMAT_FORMAT__SHIFT) | - (log2i(pPix->drawable.width) << - NV30_3D_TEX_FORMAT_BASE_SIZE_U__SHIFT) | - (log2i(pPix->drawable.height) << - NV30_3D_TEX_FORMAT_BASE_SIZE_V__SHIFT), - tex_reloc | NOUVEAU_BO_OR, - NV30_3D_TEX_FORMAT_DMA0, NV30_3D_TEX_FORMAT_DMA1)) - return FALSE; - OUT_RING (chan, (card_repeat << NV30_3D_TEX_WRAP_S__SHIFT) | - (card_repeat << NV30_3D_TEX_WRAP_T__SHIFT) | - (card_repeat << NV30_3D_TEX_WRAP_R__SHIFT)); - OUT_RING (chan, NV30_3D_TEX_ENABLE_ENABLE); - OUT_RING (chan, (((uint32_t)exaGetPixmapPitch(pPix)) << NV30_3D_TEX_SWIZZLE_RECT_PITCH__SHIFT ) | - fmt->card_swz); - - OUT_RING (chan, (card_filter << NV30_3D_TEX_FILTER_MIN__SHIFT) /* min */ | - (card_filter << NV30_3D_TEX_FILTER_MAG__SHIFT) /* mag */ | - 0x2000 /* engine lock */); - OUT_RING (chan, (pPix->drawable.width << NV30_3D_TEX_NPOT_SIZE_W__SHIFT) | pPix->drawable.height); - OUT_RING (chan, 0); /* border ARGB */ + BEGIN_NV04(push, NV30_3D(TEX_OFFSET(unit)), 8); + PUSH_MTHDl(push, NV30_3D(TEX_OFFSET(unit)), bo, 0, reloc); + PUSH_MTHDs(push, NV30_3D(TEX_FORMAT(unit)), bo, (1 << 16) | 8 | + NV30_3D_TEX_FORMAT_DIMS_2D | + (fmt->card_fmt << NV30_3D_TEX_FORMAT_FORMAT__SHIFT) | + (log2w << NV30_3D_TEX_FORMAT_BASE_SIZE_U__SHIFT) | + (log2h << NV30_3D_TEX_FORMAT_BASE_SIZE_V__SHIFT), + reloc, NV30_3D_TEX_FORMAT_DMA0, + NV30_3D_TEX_FORMAT_DMA1); + PUSH_DATA (push, (card_repeat << NV30_3D_TEX_WRAP_S__SHIFT) | + (card_repeat << NV30_3D_TEX_WRAP_T__SHIFT) | + (card_repeat << NV30_3D_TEX_WRAP_R__SHIFT)); + PUSH_DATA (push, NV30_3D_TEX_ENABLE_ENABLE); + PUSH_DATA (push, (pitch << NV30_3D_TEX_SWIZZLE_RECT_PITCH__SHIFT ) | + fmt->card_swz); + PUSH_DATA (push, (card_filter << NV30_3D_TEX_FILTER_MIN__SHIFT) | + (card_filter << NV30_3D_TEX_FILTER_MAG__SHIFT) | + 0x2000 /* engine lock */); + PUSH_DATA (push, (pPix->drawable.width << + NV30_3D_TEX_NPOT_SIZE_W__SHIFT) | + pPix->drawable.height); + PUSH_DATA (push, 0x00000000); /* border ARGB */ state->unit[unit].width = (float)pPix->drawable.width; state->unit[unit].height = (float)pPix->drawable.height; state->unit[unit].transform = pPict->transform; - return TRUE; } @@ -356,8 +359,9 @@ static Bool NV30_SetupSurface(ScrnInfoPtr pScrn, PixmapPtr pPix, PicturePtr pPict) { NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; struct nouveau_bo *bo = nouveau_pixmap_bo(pPix); + uint32_t pitch = exaGetPixmapPitch(pPix); nv_pict_surface_format_t *fmt; fmt = NV30_GetPictSurfaceFormat(pPict->format); @@ -366,14 +370,11 @@ NV30_SetupSurface(ScrnInfoPtr pScrn, PixmapPtr pPix, PicturePtr pPict) return FALSE; } - uint32_t pitch = (uint32_t)exaGetPixmapPitch(pPix); - - BEGIN_NV04(chan, NV30_3D(RT_FORMAT), 3); - OUT_RING (chan, fmt->card_fmt); /* format */ - OUT_RING (chan, pitch << 16 | pitch); - if (OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR)) - return FALSE; - + BEGIN_NV04(push, NV30_3D(RT_FORMAT), 3); + PUSH_DATA (push, fmt->card_fmt); /* format */ + PUSH_DATA (push, pitch << 16 | pitch); + PUSH_MTHDl(push, NV30_3D(COLOR0_OFFSET), bo, 0, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); return TRUE; } @@ -449,16 +450,6 @@ NV30EXACheckComposite(int op, PicturePtr psPict, return TRUE; } -static void -NV30EXAStateCompositeReemit(struct nouveau_channel *chan) -{ - ScrnInfoPtr pScrn = chan->user_private; - NVPtr pNv = NVPTR(pScrn); - - NV30EXAPrepareComposite(pNv->alu, pNv->pspict, pNv->pmpict, pNv->pdpict, - pNv->pspix, pNv->pmpix, pNv->pdpix); -} - Bool NV30EXAPrepareComposite(int op, PicturePtr psPict, PicturePtr pmPict, @@ -469,45 +460,26 @@ NV30EXAPrepareComposite(int op, PicturePtr psPict, { ScrnInfoPtr pScrn = xf86Screens[psPix->drawable.pScreen->myNum]; NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; - nv_pict_op_t *blend; + nv_pict_op_t *blend = NV30_GetPictOpRec(op); + struct nouveau_pushbuf *push = pNv->pushbuf; int fpid = NV30EXA_FPID_PASS_COL0; NV30EXA_STATE; - if (MARK_RING(chan, 128, 1 + 1 + 4)) + if (!PUSH_SPACE(push, 128)) return FALSE; - - blend = NV30_GetPictOpRec(op); + PUSH_RESET(push); NV30_SetupBlend(pScrn, blend, pdPict->format, (pmPict && pmPict->componentAlpha && PICT_FORMAT_RGB(pmPict->format))); if (!NV30_SetupSurface(pScrn, pdPix, pdPict) || - !NV30EXATexture(pScrn, psPix, psPict, 0)) { - MARK_UNDO(chan); + !NV30EXATexture(pScrn, psPix, psPict, 0)) return FALSE; - } - -#if 0 -#define printformat(f) ErrorF("(%xh %s %dbpp A%dR%dG%dB%d)",f,(f>>16)&0xf==2?"ARGB":"ABGR",(f>>24),(f&0xf000)>>12,(f&0xf00)>>8,(f&0xf0)>>4,f&0xf) - ErrorF("Preparecomposite src(%dx%d)",psPict->pDrawable->width,psPict->pDrawable->height); - printformat((psPict->format)); - ErrorF(" dst(%dx%d)",pdPict->pDrawable->width,pdPict->pDrawable->height); - printformat((pdPict->format)); - if (pmPict) - { - ErrorF(" mask(%dx%d)",pmPict->pDrawable->width,pmPict->pDrawable->height); - printformat((pmPict->format)); - } - ErrorF("\n"); -#endif if (pmPict) { - if (!NV30EXATexture(pScrn, pmPix, pmPict, 1)) { - MARK_UNDO(chan); + if (!NV30EXATexture(pScrn, pmPix, pmPict, 1)) return FALSE; - } if (pmPict->componentAlpha && PICT_FORMAT_RGB(pmPict->format)) { if (blend->src_alpha) @@ -526,22 +498,18 @@ NV30EXAPrepareComposite(int op, PicturePtr psPict, } if (!NV30_LoadFragProg(pScrn, (pdPict->format == PICT_a8) ? - nv40_fp_map_a8[fpid] : nv40_fp_map[fpid])) { - MARK_UNDO(chan); + nv40_fp_map_a8[fpid] : nv40_fp_map[fpid])) + return FALSE; + + BEGIN_NV04(push, NV30_3D(TEX_UNITS_ENABLE), 1); + PUSH_DATA (push, pmPict ? 3 : 1); + + nouveau_pushbuf_bufctx(push, pNv->bufctx); + if (nouveau_pushbuf_validate(push)) { + nouveau_pushbuf_bufctx(push, NULL); return FALSE; } - BEGIN_NV04(chan, SUBC_3D(0x23c), 1); - OUT_RING (chan, pmPict?3:1); - - pNv->alu = op; - pNv->pspict = psPict; - pNv->pmpict = pmPict; - pNv->pdpict = pdPict; - pNv->pspix = psPix; - pNv->pmpix = pmPix; - pNv->pdpix = pdPix; - chan->flush_notify = NV30EXAStateCompositeReemit; return TRUE; } @@ -568,17 +536,17 @@ NV30EXATransformCoord(PictTransformPtr t, int x, int y, float sx, float sy, } #define CV_OUTm(sx,sy,mx,my,dx,dy) do { \ - BEGIN_NV04(chan, NV30_3D(VTX_ATTR_2F_X(8)), 4); \ - OUT_RINGf (chan, (sx)); OUT_RINGf (chan, (sy)); \ - OUT_RINGf (chan, (mx)); OUT_RINGf (chan, (my)); \ - BEGIN_NV04(chan, NV30_3D(VTX_ATTR_2I(0)), 1); \ - OUT_RING (chan, ((dy)<<16)|(dx)); \ + BEGIN_NV04(push, NV30_3D(VTX_ATTR_2F_X(8)), 4); \ + PUSH_DATAf(push, (sx)); PUSH_DATAf(push, (sy)); \ + PUSH_DATAf(push, (mx)); PUSH_DATAf(push, (my)); \ + BEGIN_NV04(push, NV30_3D(VTX_ATTR_2I(0)), 1); \ + PUSH_DATA (push, ((dy)<<16)|(dx)); \ } while(0) #define CV_OUT(sx,sy,dx,dy) do { \ - BEGIN_NV04(chan, NV30_3D(VTX_ATTR_2F_X(8)), 2); \ - OUT_RINGf (chan, (sx)); OUT_RINGf (chan, (sy)); \ - BEGIN_NV04(chan, NV30_3D(VTX_ATTR_2I(0)), 1); \ - OUT_RING (chan, ((dy)<<16)|(dx)); \ + BEGIN_NV04(push, NV30_3D(VTX_ATTR_2F_X(8)), 2); \ + PUSH_DATAf(push, (sx)); PUSH_DATAf(push, (sy)); \ + BEGIN_NV04(push, NV30_3D(VTX_ATTR_2I(0)), 1); \ + PUSH_DATA (push, ((dy)<<16)|(dx)); \ } while(0) void @@ -589,25 +557,24 @@ NV30EXAComposite(PixmapPtr pdPix, int srcX , int srcY, { ScrnInfoPtr pScrn = xf86Screens[pdPix->drawable.pScreen->myNum]; NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; float sX0, sX1, sX2, sY0, sY1, sY2; float mX0, mX1, mX2, mY0, mY1, mY2; NV30EXA_STATE; - WAIT_RING(chan, 64); + if (!PUSH_SPACE(push, 64)) + return; /* We're drawing a triangle, we need to scissor it to a quad. */ - /* The scissors are here for a good reason, we don't get the full image, but just a part. */ + /* The scissors are here for a good reason, we don't get the full + * image, but just a part. */ /* Handling the cliprects is done for us already. */ - BEGIN_NV04(chan, NV30_3D(SCISSOR_HORIZ), 2); - OUT_RING (chan, (width << 16) | dstX); - OUT_RING (chan, (height << 16) | dstY); - BEGIN_NV04(chan, NV30_3D(VERTEX_BEGIN_END), 1); - OUT_RING (chan, NV30_3D_VERTEX_BEGIN_END_TRIANGLES); + BEGIN_NV04(push, NV30_3D(SCISSOR_HORIZ), 2); + PUSH_DATA (push, (width << 16) | dstX); + PUSH_DATA (push, (height << 16) | dstY); + BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1); + PUSH_DATA (push, NV30_3D_VERTEX_BEGIN_END_TRIANGLES); -#if 0 - ErrorF("Composite [%dx%d] (%d,%d)IN(%d,%d)OP(%d,%d)\n",width,height,srcX,srcY,maskX,maskY,dstX,dstY); -#endif NV30EXATransformCoord(state->unit[0].transform, srcX, srcY - height, state->unit[0].width, @@ -635,34 +602,32 @@ NV30EXAComposite(PixmapPtr pdPix, int srcX , int srcY, state->unit[1].width, state->unit[1].height, &mX2, &mY2); - CV_OUTm(sX0 , sY0 , mX0, mY0, dstX , dstY - height); - CV_OUTm(sX1 , sY1 , mX1, mY1, dstX , dstY + height); - CV_OUTm(sX2 , sY2 , mX2, mY2, dstX + 2*width , dstY + height); + CV_OUTm(sX0, sY0, mX0, mY0, dstX, dstY - height); + CV_OUTm(sX1, sY1, mX1, mY1, dstX, dstY + height); + CV_OUTm(sX2, sY2, mX2, mY2, dstX + 2 * width, dstY + height); } else { - CV_OUT(sX0 , sY0 , dstX , dstY - height); - CV_OUT(sX1 , sY1 , dstX , dstY + height); - CV_OUT(sX2 , sY2 , dstX + 2*width , dstY + height); + CV_OUT(sX0, sY0, dstX , dstY - height); + CV_OUT(sX1, sY1, dstX , dstY + height); + CV_OUT(sX2, sY2, dstX + 2 * width, dstY + height); } - BEGIN_NV04(chan, NV30_3D(VERTEX_BEGIN_END), 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1); + PUSH_DATA (push, 0); } void NV30EXADoneComposite(PixmapPtr pdPix) { ScrnInfoPtr pScrn = xf86Screens[pdPix->drawable.pScreen->myNum]; - NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; - - chan->flush_notify = NULL; + nouveau_pushbuf_bufctx(NVPTR(pScrn)->pushbuf, NULL); } Bool NVAccelInitNV30TCL(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; + struct nv04_fifo *fifo = pNv->channel->data; uint32_t class = 0, chipset; int next_hw_offset = 0, i; @@ -690,133 +655,131 @@ NVAccelInitNV30TCL(ScrnInfoPtr pScrn) return FALSE; } + if (nouveau_object_new(pNv->channel, Nv3D, class, NULL, 0, &pNv->Nv3D)) + return FALSE; - if (!pNv->Nv3D) { - if (nouveau_grobj_alloc(chan, Nv3D, class, &pNv->Nv3D)) - return FALSE; + if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_MAP, + 0, 0x1000, NULL, &pNv->shader_mem)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Couldn't alloc fragprog buffer!\n"); + nouveau_object_del(&pNv->Nv3D); + return FALSE; } - if (!pNv->shader_mem) { - if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_MAP, - 0, 0x1000, &pNv->shader_mem)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Couldn't alloc fragprog buffer!\n"); - nouveau_grobj_free(&pNv->Nv3D); - return FALSE; - } - } + if (!PUSH_SPACE(push, 256)) + return FALSE; - BEGIN_NV04(chan, NV01_SUBC(3D, OBJECT), 1); - OUT_RING (chan, pNv->Nv3D->handle); - BEGIN_NV04(chan, NV30_3D(DMA_TEXTURE0), 3); - OUT_RING (chan, pNv->chan->vram->handle); - OUT_RING (chan, pNv->chan->gart->handle); - OUT_RING (chan, pNv->chan->vram->handle); - BEGIN_NV04(chan, NV30_3D(DMA_UNK1AC), 1); - OUT_RING (chan, pNv->chan->vram->handle); - BEGIN_NV04(chan, NV30_3D(DMA_COLOR0), 2); - OUT_RING (chan, pNv->chan->vram->handle); - OUT_RING (chan, pNv->chan->vram->handle); - BEGIN_NV04(chan, NV30_3D(DMA_UNK1B0), 1); - OUT_RING (chan, pNv->chan->vram->handle); + BEGIN_NV04(push, NV01_SUBC(3D, OBJECT), 1); + PUSH_DATA (push, pNv->Nv3D->handle); + BEGIN_NV04(push, NV30_3D(DMA_TEXTURE0), 3); + PUSH_DATA (push, fifo->vram); + PUSH_DATA (push, fifo->gart); + PUSH_DATA (push, fifo->vram); + BEGIN_NV04(push, NV30_3D(DMA_UNK1AC), 1); + PUSH_DATA (push, fifo->vram); + BEGIN_NV04(push, NV30_3D(DMA_COLOR0), 2); + PUSH_DATA (push, fifo->vram); + PUSH_DATA (push, fifo->vram); + BEGIN_NV04(push, NV30_3D(DMA_UNK1B0), 1); + PUSH_DATA (push, fifo->vram); for (i=1; i<8; i++) { - BEGIN_NV04(chan, NV30_3D(VIEWPORT_CLIP_HORIZ(i)), 2); - OUT_RING (chan, 0); - OUT_RING (chan, 0); + BEGIN_NV04(push, NV30_3D(VIEWPORT_CLIP_HORIZ(i)), 2); + PUSH_DATA (push, 0); + PUSH_DATA (push, 0); } - BEGIN_NV04(chan, SUBC_3D(0x220), 1); - OUT_RING (chan, 1); + BEGIN_NV04(push, SUBC_3D(0x220), 1); + PUSH_DATA (push, 1); - BEGIN_NV04(chan, SUBC_3D(0x03b0), 1); - OUT_RING (chan, 0x00100000); - BEGIN_NV04(chan, SUBC_3D(0x1454), 1); - OUT_RING (chan, 0); - BEGIN_NV04(chan, SUBC_3D(0x1d80), 1); - OUT_RING (chan, 3); - BEGIN_NV04(chan, SUBC_3D(0x1450), 1); - OUT_RING (chan, 0x00030004); + BEGIN_NV04(push, SUBC_3D(0x03b0), 1); + PUSH_DATA (push, 0x00100000); + BEGIN_NV04(push, SUBC_3D(0x1454), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, SUBC_3D(0x1d80), 1); + PUSH_DATA (push, 3); + BEGIN_NV04(push, SUBC_3D(0x1450), 1); + PUSH_DATA (push, 0x00030004); /* NEW */ - BEGIN_NV04(chan, SUBC_3D(0x1e98), 1); - OUT_RING (chan, 0); - BEGIN_NV04(chan, SUBC_3D(0x17e0), 3); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, 0x3f800000); - BEGIN_NV04(chan, SUBC_3D(0x1f80), 16); - OUT_RING (chan, 0); OUT_RING (chan, 0); OUT_RING (chan, 0); OUT_RING (chan, 0); - OUT_RING (chan, 0); OUT_RING (chan, 0); OUT_RING (chan, 0); OUT_RING (chan, 0); - OUT_RING (chan, 0x0000ffff); - OUT_RING (chan, 0); OUT_RING (chan, 0); OUT_RING (chan, 0); OUT_RING (chan, 0); - OUT_RING (chan, 0); OUT_RING (chan, 0); OUT_RING (chan, 0); - - BEGIN_NV04(chan, SUBC_3D(0x120), 3); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - OUT_RING (chan, 2); - - BEGIN_NV04(chan, SUBC_BLIT(0x120), 3); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - OUT_RING (chan, 2); - - BEGIN_NV04(chan, SUBC_3D(0x1d88), 1); - OUT_RING (chan, 0x00001200); - - BEGIN_NV04(chan, NV30_3D(RC_ENABLE), 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, SUBC_3D(0x1e98), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, SUBC_3D(0x17e0), 3); + PUSH_DATA (push, 0); + PUSH_DATA (push, 0); + PUSH_DATA (push, 0x3f800000); + BEGIN_NV04(push, SUBC_3D(0x1f80), 16); + PUSH_DATA (push, 0); PUSH_DATA (push, 0); PUSH_DATA (push, 0); PUSH_DATA (push, 0); + PUSH_DATA (push, 0); PUSH_DATA (push, 0); PUSH_DATA (push, 0); PUSH_DATA (push, 0); + PUSH_DATA (push, 0x0000ffff); + PUSH_DATA (push, 0); PUSH_DATA (push, 0); PUSH_DATA (push, 0); PUSH_DATA (push, 0); + PUSH_DATA (push, 0); PUSH_DATA (push, 0); PUSH_DATA (push, 0); + + BEGIN_NV04(push, SUBC_3D(0x120), 3); + PUSH_DATA (push, 0); + PUSH_DATA (push, 1); + PUSH_DATA (push, 2); + + BEGIN_NV04(push, SUBC_BLIT(0x120), 3); + PUSH_DATA (push, 0); + PUSH_DATA (push, 1); + PUSH_DATA (push, 2); + + BEGIN_NV04(push, SUBC_3D(0x1d88), 1); + PUSH_DATA (push, 0x00001200); + + BEGIN_NV04(push, NV30_3D(RC_ENABLE), 1); + PUSH_DATA (push, 0); /* Attempt to setup a known state.. Probably missing a heap of * stuff here.. */ - BEGIN_NV04(chan, NV30_3D(STENCIL_ENABLE(0)), 1); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NV30_3D(STENCIL_ENABLE(1)), 1); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NV30_3D(ALPHA_FUNC_ENABLE), 1); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NV30_3D(DEPTH_WRITE_ENABLE), 2); - OUT_RING (chan, 0); /* wr disable */ - OUT_RING (chan, 0); /* test disable */ - BEGIN_NV04(chan, NV30_3D(COLOR_MASK), 1); - OUT_RING (chan, 0x01010101); /* TR,TR,TR,TR */ - BEGIN_NV04(chan, NV30_3D(CULL_FACE_ENABLE), 1); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NV30_3D(BLEND_FUNC_ENABLE), 5); - OUT_RING (chan, 0); /* Blend enable */ - OUT_RING (chan, 0); /* Blend src */ - OUT_RING (chan, 0); /* Blend dst */ - OUT_RING (chan, 0x00000000); /* Blend colour */ - OUT_RING (chan, 0x8006); /* FUNC_ADD */ - BEGIN_NV04(chan, NV30_3D(COLOR_LOGIC_OP_ENABLE), 2); - OUT_RING (chan, 0); - OUT_RING (chan, 0x1503 /*GL_COPY*/); - BEGIN_NV04(chan, NV30_3D(DITHER_ENABLE), 1); - OUT_RING (chan, 1); - BEGIN_NV04(chan, NV30_3D(SHADE_MODEL), 1); - OUT_RING (chan, 0x1d01 /*GL_SMOOTH*/); - BEGIN_NV04(chan, NV30_3D(POLYGON_OFFSET_FACTOR),2); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); - BEGIN_NV04(chan, NV30_3D(POLYGON_MODE_FRONT), 2); - OUT_RING (chan, 0x1b02 /*GL_FILL*/); - OUT_RING (chan, 0x1b02 /*GL_FILL*/); + BEGIN_NV04(push, NV30_3D(STENCIL_ENABLE(0)), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV30_3D(STENCIL_ENABLE(1)), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV30_3D(ALPHA_FUNC_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV30_3D(DEPTH_WRITE_ENABLE), 2); + PUSH_DATA (push, 0); /* wr disable */ + PUSH_DATA (push, 0); /* test disable */ + BEGIN_NV04(push, NV30_3D(COLOR_MASK), 1); + PUSH_DATA (push, 0x01010101); /* TR,TR,TR,TR */ + BEGIN_NV04(push, NV30_3D(CULL_FACE_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV30_3D(BLEND_FUNC_ENABLE), 5); + PUSH_DATA (push, 0); /* Blend enable */ + PUSH_DATA (push, 0); /* Blend src */ + PUSH_DATA (push, 0); /* Blend dst */ + PUSH_DATA (push, 0x00000000); /* Blend colour */ + PUSH_DATA (push, 0x8006); /* FUNC_ADD */ + BEGIN_NV04(push, NV30_3D(COLOR_LOGIC_OP_ENABLE), 2); + PUSH_DATA (push, 0); + PUSH_DATA (push, 0x1503 /*GL_COPY*/); + BEGIN_NV04(push, NV30_3D(DITHER_ENABLE), 1); + PUSH_DATA (push, 1); + BEGIN_NV04(push, NV30_3D(SHADE_MODEL), 1); + PUSH_DATA (push, 0x1d01 /*GL_SMOOTH*/); + BEGIN_NV04(push, NV30_3D(POLYGON_OFFSET_FACTOR),2); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 0.0); + BEGIN_NV04(push, NV30_3D(POLYGON_MODE_FRONT), 2); + PUSH_DATA (push, 0x1b02 /*GL_FILL*/); + PUSH_DATA (push, 0x1b02 /*GL_FILL*/); /* - Disable texture units * - Set fragprog to MOVR result.color, fragment.color */ for (i=0;i<4;i++) { - BEGIN_NV04(chan, NV30_3D(TEX_ENABLE(i)), 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, NV30_3D(TEX_ENABLE(i)), 1); + PUSH_DATA (push, 0); } /* Polygon stipple */ - BEGIN_NV04(chan, NV30_3D(POLYGON_STIPPLE_PATTERN(0)), 0x20); + BEGIN_NV04(push, NV30_3D(POLYGON_STIPPLE_PATTERN(0)), 0x20); for (i=0;i<0x20;i++) - OUT_RING (chan, 0xFFFFFFFF); + PUSH_DATA (push, 0xFFFFFFFF); - BEGIN_NV04(chan, NV30_3D(DEPTH_RANGE_NEAR), 2); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 1.0); + BEGIN_NV04(push, NV30_3D(DEPTH_RANGE_NEAR), 2); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 1.0); /* Ok. If you start X with the nvidia driver, kill it, and then * start X with nouveau you will get black rendering instead of @@ -824,82 +787,82 @@ NVAccelInitNV30TCL(ScrnInfoPtr pScrn) * it's not needed between nouveau restarts - which suggests that * the 3D context (wherever it's stored?) survives somehow. */ - //BEGIN_NV04(chan, SUBC_3D(0x1d60),1); - //OUT_RING (chan, 0x03008000); + //BEGIN_NV04(push, SUBC_3D(0x1d60),1); + //PUSH_DATA (push, 0x03008000); int w=4096; int h=4096; int pitch=4096*4; - BEGIN_NV04(chan, NV30_3D(RT_HORIZ), 5); - OUT_RING (chan, w<<16); - OUT_RING (chan, h<<16); - OUT_RING (chan, 0x148); /* format */ - OUT_RING (chan, pitch << 16 | pitch); - OUT_RING (chan, 0x0); - BEGIN_NV04(chan, NV30_3D(VIEWPORT_TX_ORIGIN), 1); - OUT_RING (chan, 0); - BEGIN_NV04(chan, SUBC_3D(0x0a00), 2); - OUT_RING (chan, (w<<16) | 0); - OUT_RING (chan, (h<<16) | 0); - BEGIN_NV04(chan, NV30_3D(VIEWPORT_CLIP_HORIZ(0)), 2); - OUT_RING (chan, (w-1)<<16); - OUT_RING (chan, (h-1)<<16); - BEGIN_NV04(chan, NV30_3D(SCISSOR_HORIZ), 2); - OUT_RING (chan, w<<16); - OUT_RING (chan, h<<16); - BEGIN_NV04(chan, NV30_3D(VIEWPORT_HORIZ), 2); - OUT_RING (chan, w<<16); - OUT_RING (chan, h<<16); - - BEGIN_NV04(chan, NV30_3D(VIEWPORT_TRANSLATE_X), 8); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 1.0); - OUT_RINGf (chan, 1.0); - OUT_RINGf (chan, 1.0); - OUT_RINGf (chan, 0.0); - - BEGIN_NV04(chan, NV30_3D(MODELVIEW_MATRIX(0)), 16); - OUT_RINGf (chan, 1.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 1.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 1.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 1.0); - - BEGIN_NV04(chan, NV30_3D(PROJECTION_MATRIX(0)), 16); - OUT_RINGf (chan, 1.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 1.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 1.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 1.0); - - BEGIN_NV04(chan, NV30_3D(SCISSOR_HORIZ), 2); - OUT_RING (chan, 4096<<16); - OUT_RING (chan, 4096<<16); + BEGIN_NV04(push, NV30_3D(RT_HORIZ), 5); + PUSH_DATA (push, w<<16); + PUSH_DATA (push, h<<16); + PUSH_DATA (push, 0x148); /* format */ + PUSH_DATA (push, pitch << 16 | pitch); + PUSH_DATA (push, 0x0); + BEGIN_NV04(push, NV30_3D(VIEWPORT_TX_ORIGIN), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, SUBC_3D(0x0a00), 2); + PUSH_DATA (push, (w<<16) | 0); + PUSH_DATA (push, (h<<16) | 0); + BEGIN_NV04(push, NV30_3D(VIEWPORT_CLIP_HORIZ(0)), 2); + PUSH_DATA (push, (w-1)<<16); + PUSH_DATA (push, (h-1)<<16); + BEGIN_NV04(push, NV30_3D(SCISSOR_HORIZ), 2); + PUSH_DATA (push, w<<16); + PUSH_DATA (push, h<<16); + BEGIN_NV04(push, NV30_3D(VIEWPORT_HORIZ), 2); + PUSH_DATA (push, w<<16); + PUSH_DATA (push, h<<16); + + BEGIN_NV04(push, NV30_3D(VIEWPORT_TRANSLATE_X), 8); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 1.0); + PUSH_DATAf(push, 1.0); + PUSH_DATAf(push, 1.0); + PUSH_DATAf(push, 0.0); + + BEGIN_NV04(push, NV30_3D(MODELVIEW_MATRIX(0)), 16); + PUSH_DATAf(push, 1.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 1.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 1.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 1.0); + + BEGIN_NV04(push, NV30_3D(PROJECTION_MATRIX(0)), 16); + PUSH_DATAf(push, 1.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 1.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 1.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 1.0); + + BEGIN_NV04(push, NV30_3D(SCISSOR_HORIZ), 2); + PUSH_DATA (push, 4096<<16); + PUSH_DATA (push, 4096<<16); for (i = 0; i < NV30EXA_FPID_MAX; i++) { NV30_UploadFragProg(pNv, nv40_fp_map[i], &next_hw_offset); diff --git a/src/nv30_shaders.c b/src/nv30_shaders.c index e3d4dfb..baa70d7 100644 --- a/src/nv30_shaders.c +++ b/src/nv30_shaders.c @@ -24,6 +24,7 @@ #include "nv30_shaders.h" #include "hwdefs/nv30-40_3d.xml.h" +#include "nv04_accel.h" void NV30_UploadFragProg(NVPtr pNv, nv_shader_t *shader, int *hw_offset) { @@ -32,7 +33,7 @@ void NV30_UploadFragProg(NVPtr pNv, nv_shader_t *shader, int *hw_offset) shader->hw_id = *hw_offset; - nouveau_bo_map(pNv->shader_mem, NOUVEAU_BO_WR); + nouveau_bo_map(pNv->shader_mem, NOUVEAU_BO_WR, pNv->client); map = pNv->shader_mem->map + *hw_offset; for (i = 0; i < shader->size; i++) { data = shader->data[i]; @@ -41,7 +42,6 @@ void NV30_UploadFragProg(NVPtr pNv, nv_shader_t *shader, int *hw_offset) #endif map[i] = data; } - nouveau_bo_unmap(pNv->shader_mem); *hw_offset += (shader->size * sizeof(uint32_t)); *hw_offset = (*hw_offset + 63) & ~63; @@ -49,19 +49,19 @@ void NV30_UploadFragProg(NVPtr pNv, nv_shader_t *shader, int *hw_offset) void NV40_UploadVtxProg(NVPtr pNv, nv_shader_t *shader, int *hw_id) { - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; int i; shader->hw_id = *hw_id; - BEGIN_NV04(chan, NV30_3D(VP_UPLOAD_FROM_ID), 1); - OUT_RING (chan, (shader->hw_id)); + BEGIN_NV04(push, NV30_3D(VP_UPLOAD_FROM_ID), 1); + PUSH_DATA (push, (shader->hw_id)); for (i=0; isize; i+=4) { - BEGIN_NV04(chan, NV30_3D(VP_UPLOAD_INST(0)), 4); - OUT_RING (chan, shader->data[i + 0]); - OUT_RING (chan, shader->data[i + 1]); - OUT_RING (chan, shader->data[i + 2]); - OUT_RING (chan, shader->data[i + 3]); + BEGIN_NV04(push, NV30_3D(VP_UPLOAD_INST(0)), 4); + PUSH_DATA (push, shader->data[i + 0]); + PUSH_DATA (push, shader->data[i + 1]); + PUSH_DATA (push, shader->data[i + 2]); + PUSH_DATA (push, shader->data[i + 3]); (*hw_id)++; } } @@ -70,21 +70,20 @@ Bool NV30_LoadFragProg(ScrnInfoPtr pScrn, nv_shader_t *shader) { NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; - - BEGIN_NV04(chan, NV30_3D(FP_ACTIVE_PROGRAM), 1); - if (OUT_RELOC(chan, pNv->shader_mem, shader->hw_id, NOUVEAU_BO_VRAM | - NOUVEAU_BO_RD | NOUVEAU_BO_LOW | NOUVEAU_BO_OR, - NV30_3D_FP_ACTIVE_PROGRAM_DMA0, - NV30_3D_FP_ACTIVE_PROGRAM_DMA1)) - return FALSE; - BEGIN_NV04(chan, NV30_3D(FP_REG_CONTROL), 1); - OUT_RING (chan, (1 << 16)| 0xf); - BEGIN_NV04(chan, NV30_3D(MULTISAMPLE_CONTROL), 1); - OUT_RING (chan, 0xffff0000); - - BEGIN_NV04(chan, NV30_3D(FP_CONTROL),1); - OUT_RING (chan, (shader->card_priv.NV30FP.num_regs-1)/2); + struct nouveau_pushbuf *push = pNv->pushbuf; + + BEGIN_NV04(push, NV30_3D(FP_ACTIVE_PROGRAM), 1); + PUSH_MTHD (push, NV30_3D(FP_ACTIVE_PROGRAM), pNv->shader_mem, + shader->hw_id, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | + NOUVEAU_BO_LOW | NOUVEAU_BO_OR, + NV30_3D_FP_ACTIVE_PROGRAM_DMA0, + NV30_3D_FP_ACTIVE_PROGRAM_DMA1); + BEGIN_NV04(push, NV30_3D(FP_REG_CONTROL), 1); + PUSH_DATA (push, (1 << 16) | 0xf); + BEGIN_NV04(push, NV30_3D(MULTISAMPLE_CONTROL), 1); + PUSH_DATA (push, 0xffff0000); + BEGIN_NV04(push, NV30_3D(FP_CONTROL),1); + PUSH_DATA (push, (shader->card_priv.NV30FP.num_regs - 1) / 2); return TRUE; } @@ -93,30 +92,29 @@ void NV40_LoadVtxProg(ScrnInfoPtr pScrn, nv_shader_t *shader) { NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; - BEGIN_NV04(chan, NV30_3D(VP_START_FROM_ID), 1); - OUT_RING (chan, (shader->hw_id)); - BEGIN_NV04(chan, NV40_3D(VP_ATTRIB_EN), 2); - OUT_RING (chan, shader->card_priv.NV30VP.vp_in_reg); - OUT_RING (chan, shader->card_priv.NV30VP.vp_out_reg); + BEGIN_NV04(push, NV30_3D(VP_START_FROM_ID), 1); + PUSH_DATA (push, (shader->hw_id)); + BEGIN_NV04(push, NV40_3D(VP_ATTRIB_EN), 2); + PUSH_DATA (push, shader->card_priv.NV30VP.vp_in_reg); + PUSH_DATA (push, shader->card_priv.NV30VP.vp_out_reg); } Bool NV40_LoadFragProg(ScrnInfoPtr pScrn, nv_shader_t *shader) { NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; - - BEGIN_NV04(chan, NV30_3D(FP_ACTIVE_PROGRAM), 1); - if (OUT_RELOC(chan, pNv->shader_mem, shader->hw_id, NOUVEAU_BO_VRAM | - NOUVEAU_BO_GART | NOUVEAU_BO_RD | NOUVEAU_BO_LOW | - NOUVEAU_BO_OR, - NV30_3D_FP_ACTIVE_PROGRAM_DMA0, - NV30_3D_FP_ACTIVE_PROGRAM_DMA1)) - return FALSE; - BEGIN_NV04(chan, NV30_3D(FP_CONTROL), 1); - OUT_RING (chan, shader->card_priv.NV30FP.num_regs << + struct nouveau_pushbuf *push = pNv->pushbuf; + + BEGIN_NV04(push, NV30_3D(FP_ACTIVE_PROGRAM), 1); + PUSH_MTHD (push, NV30_3D(FP_ACTIVE_PROGRAM), pNv->shader_mem, + shader->hw_id, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | + NOUVEAU_BO_RD | NOUVEAU_BO_LOW | NOUVEAU_BO_OR, + NV30_3D_FP_ACTIVE_PROGRAM_DMA0, + NV30_3D_FP_ACTIVE_PROGRAM_DMA1); + BEGIN_NV04(push, NV30_3D(FP_CONTROL), 1); + PUSH_DATA (push, shader->card_priv.NV30FP.num_regs << NV40_3D_FP_CONTROL_TEMP_COUNT__SHIFT); return TRUE; diff --git a/src/nv30_xv_tex.c b/src/nv30_xv_tex.c index 7ade33c..59d60b6 100644 --- a/src/nv30_xv_tex.c +++ b/src/nv30_xv_tex.c @@ -39,6 +39,7 @@ #include "nv30_shaders.h" #include "hwdefs/nv30-40_3d.xml.h" +#include "nv04_accel.h" extern Atom xvSyncToVBlank, xvSetDefaults; @@ -96,14 +97,15 @@ NV30_LoadFilterTable(ScrnInfoPtr pScrn) if (!pNv->xv_filtertable_mem) { if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, - TABLE_SIZE * sizeof(float) * 4, + TABLE_SIZE * sizeof(float) * 4, NULL, &pNv->xv_filtertable_mem)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Couldn't alloc filter table!\n"); return; } - if (nouveau_bo_map(pNv->xv_filtertable_mem, NOUVEAU_BO_RDWR)) { + if (nouveau_bo_map(pNv->xv_filtertable_mem, NOUVEAU_BO_RDWR, + pNv->client)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Couldn't map filter table!\n"); return; @@ -111,7 +113,6 @@ NV30_LoadFilterTable(ScrnInfoPtr pScrn) int8_t *t=pNv->xv_filtertable_mem->map; compute_filter_table(t); - nouveau_bo_unmap(pNv->xv_filtertable_mem); } } @@ -133,78 +134,75 @@ NV30VideoTexture(ScrnInfoPtr pScrn, struct nouveau_bo *src, int offset, uint16_t width, uint16_t height, uint16_t src_pitch, int unit) { NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; - uint32_t tex_reloc = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; + unsigned reloc = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; + struct nouveau_pushbuf *push = pNv->pushbuf; uint32_t card_fmt = 0; uint32_t card_swz = 0; + int h = log2i(height); + int w = log2i(width); - switch(unit) { - case 0: + switch (unit) { + case 0: card_fmt = NV30_3D_TEX_FORMAT_FORMAT_A8R8G8B8; card_swz = SWIZZLE(S1, S1, S1, S1, X, Y, Z, W); break; - case 1: + case 1: card_fmt = NV30_3D_TEX_FORMAT_FORMAT_I8_RECT; card_swz = SWIZZLE(S1, S1, S1, S1, X, X, X, X); break; - case 2: + case 2: card_fmt = NV30_3D_TEX_FORMAT_FORMAT_A8L8_RECT; #if X_BYTE_ORDER == X_BIG_ENDIAN - card_swz = SWIZZLE(S1, S1, S1, S1, Z, W, X, Y); /* x = V, y = U */ + card_swz = SWIZZLE(S1, S1, S1, S1, Z, W, X, Y); #else - card_swz = SWIZZLE(S1, S1, S1, S1, W, Z, Y, X); /* x = V, y = U */ + card_swz = SWIZZLE(S1, S1, S1, S1, W, Z, Y, X); #endif break; } - BEGIN_NV04(chan, NV30_3D(TEX_OFFSET(unit)), 8); - if (OUT_RELOCl(chan, src, offset, tex_reloc)) - return FALSE; - + BEGIN_NV04(push, NV30_3D(TEX_OFFSET(unit)), 8); + PUSH_MTHDl(push, NV30_3D(TEX_OFFSET(unit)), src, offset, reloc); if (unit == 0) { - if (OUT_RELOCd(chan, src, NV30_3D_TEX_FORMAT_DIMS_1D | - card_fmt | (1 << 16) | - (log2i(width) << - NV30_3D_TEX_FORMAT_BASE_SIZE_U__SHIFT) | - (log2i(height) << - NV30_3D_TEX_FORMAT_BASE_SIZE_V__SHIFT) | - 8 /* no idea */, tex_reloc | NOUVEAU_BO_OR, - NV30_3D_TEX_FORMAT_DMA0, NV30_3D_TEX_FORMAT_DMA1)) - return FALSE; - OUT_RING (chan, NV30_3D_TEX_WRAP_S_REPEAT | + PUSH_MTHD (push, NV30_3D(TEX_FORMAT(unit)), src, + NV30_3D_TEX_FORMAT_DIMS_1D | + card_fmt | (1 << 16) | 8 /* no idea */ | + (w << NV30_3D_TEX_FORMAT_BASE_SIZE_U__SHIFT) | + (h << NV30_3D_TEX_FORMAT_BASE_SIZE_V__SHIFT), + reloc | NOUVEAU_BO_OR, + NV30_3D_TEX_FORMAT_DMA0, + NV30_3D_TEX_FORMAT_DMA1); + PUSH_DATA (push, NV30_3D_TEX_WRAP_S_REPEAT | NV30_3D_TEX_WRAP_T_CLAMP_TO_EDGE | NV30_3D_TEX_WRAP_R_CLAMP_TO_EDGE); } else { - if (OUT_RELOCd(chan, src, NV30_3D_TEX_FORMAT_DIMS_2D | - card_fmt | (1 << 16) | - (log2i(width) << - NV30_3D_TEX_FORMAT_BASE_SIZE_U__SHIFT) | - (log2i(height) << - NV30_3D_TEX_FORMAT_BASE_SIZE_V__SHIFT) | - 8 /* no idea */, tex_reloc | NOUVEAU_BO_OR, - NV30_3D_TEX_FORMAT_DMA0, NV30_3D_TEX_FORMAT_DMA1)) - return FALSE; - OUT_RING (chan, NV30_3D_TEX_WRAP_S_CLAMP_TO_EDGE | + PUSH_MTHD (push, NV30_3D(TEX_FORMAT(unit)), src, + NV30_3D_TEX_FORMAT_DIMS_2D | + card_fmt | (1 << 16) | 8 /* no idea */ | + (w << NV30_3D_TEX_FORMAT_BASE_SIZE_U__SHIFT) | + (h << NV30_3D_TEX_FORMAT_BASE_SIZE_V__SHIFT), + reloc | NOUVEAU_BO_OR, + NV30_3D_TEX_FORMAT_DMA0, + NV30_3D_TEX_FORMAT_DMA1); + PUSH_DATA (push, NV30_3D_TEX_WRAP_S_CLAMP_TO_EDGE | NV30_3D_TEX_WRAP_T_CLAMP_TO_EDGE | NV30_3D_TEX_WRAP_R_CLAMP_TO_EDGE); } - OUT_RING (chan, NV30_3D_TEX_ENABLE_ENABLE); - OUT_RING (chan, (src_pitch << NV30_3D_TEX_SWIZZLE_RECT_PITCH__SHIFT) | + PUSH_DATA (push, NV30_3D_TEX_ENABLE_ENABLE); + PUSH_DATA (push, (src_pitch << NV30_3D_TEX_SWIZZLE_RECT_PITCH__SHIFT) | card_swz); - if (unit==0) - OUT_RING (chan, NV30_3D_TEX_FILTER_SIGNED_ALPHA | + if (unit == 0) + PUSH_DATA (push, NV30_3D_TEX_FILTER_SIGNED_ALPHA | NV30_3D_TEX_FILTER_SIGNED_RED | NV30_3D_TEX_FILTER_SIGNED_GREEN | NV30_3D_TEX_FILTER_SIGNED_BLUE | NV30_3D_TEX_FILTER_MIN_LINEAR | NV30_3D_TEX_FILTER_MAG_LINEAR | 0x2000); else - OUT_RING (chan, NV30_3D_TEX_FILTER_MIN_LINEAR | + PUSH_DATA (push, NV30_3D_TEX_FILTER_MIN_LINEAR | NV30_3D_TEX_FILTER_MAG_LINEAR | 0x2000); - OUT_RING (chan, (width << NV30_3D_TEX_NPOT_SIZE_W__SHIFT) | height); - OUT_RING (chan, 0); /* border ARGB */ - + PUSH_DATA (push, (width << NV30_3D_TEX_NPOT_SIZE_W__SHIFT) | height); + PUSH_DATA (push, 0); /* border ARGB */ return TRUE; } @@ -237,11 +235,11 @@ NV30StopTexturedVideo(ScrnInfoPtr pScrn, pointer data, Bool Exit) } #define VERTEX_OUT(sx,sy,dx,dy) do { \ - BEGIN_NV04(chan, NV30_3D(VTX_ATTR_2F_X(8)), 4); \ - OUT_RINGf (chan, (sx)); OUT_RINGf (chan, (sy)); \ - OUT_RINGf (chan, (sx)/2.0); OUT_RINGf (chan, (sy)/2.0); \ - BEGIN_NV04(chan, NV30_3D(VTX_ATTR_2I(0)), 1); \ - OUT_RING (chan, ((dy)<<16)|(dx)); \ + BEGIN_NV04(push, NV30_3D(VTX_ATTR_2F_X(8)), 4); \ + PUSH_DATAf(push, (sx)); PUSH_DATAf(push, (sy)); \ + PUSH_DATAf(push, (sx)/2.0); PUSH_DATAf(push, (sy)/2.0); \ + BEGIN_NV04(push, NV30_3D(VTX_ATTR_2I(0)), 1); \ + PUSH_DATA (push, ((dy)<<16)|(dx)); \ } while(0) int @@ -256,7 +254,7 @@ NV30PutTextureImage(ScrnInfoPtr pScrn, struct nouveau_bo *src, int src_offset, NVPortPrivPtr pPriv) { NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; struct nouveau_bo *bo = nouveau_pixmap_bo(ppix); Bool bicubic = pPriv->bicubic; float X1, X2, Y1, Y2; @@ -278,24 +276,20 @@ NV30PutTextureImage(ScrnInfoPtr pScrn, struct nouveau_bo *src, int src_offset, pbox = REGION_RECTS(clipBoxes); nbox = REGION_NUM_RECTS(clipBoxes); - if (MARK_RING(chan, 128, 1 + 1 + 3)) - return BadImplementation; - - /* Disable blending */ - BEGIN_NV04(chan, NV30_3D(BLEND_FUNC_ENABLE), 1); - OUT_RING (chan, 0); + if (!PUSH_SPACE(push, 128)) + return FALSE; + PUSH_RESET(push); - /* Setup surface */ - BEGIN_NV04(chan, NV30_3D(RT_FORMAT), 3); - OUT_RING (chan, NV30_3D_RT_FORMAT_TYPE_LINEAR | + BEGIN_NV04(push, NV30_3D(BLEND_FUNC_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV30_3D(RT_FORMAT), 3); + PUSH_DATA (push, NV30_3D_RT_FORMAT_TYPE_LINEAR | NV30_3D_RT_FORMAT_ZETA_Z24S8 | dst_format); - OUT_RING (chan, (exaGetPixmapPitch(ppix) << 16) | + PUSH_DATA (push, (exaGetPixmapPitch(ppix) << 16) | exaGetPixmapPitch(ppix)); - if (OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR)) { - MARK_UNDO(chan); - return BadImplementation; - } + PUSH_MTHDl(push, NV30_3D(COLOR0_OFFSET), bo, 0, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); if (pNv->dev->chipset == 0x30) { int x = 0; @@ -303,55 +297,57 @@ NV30PutTextureImage(ScrnInfoPtr pScrn, struct nouveau_bo *src, int src_offset, int w = ppix->drawable.x + ppix->drawable.width; int h = ppix->drawable.y + ppix->drawable.height; - BEGIN_NV04(chan, NV30_3D(VIEWPORT_HORIZ), 2); - OUT_RING (chan, (w<<16)|x); - OUT_RING (chan, (h<<16)|y); - BEGIN_NV04(chan, NV30_3D(VIEWPORT_CLIP_HORIZ(0)), 2); - OUT_RING (chan, (w-1+x)<<16); - OUT_RING (chan, (h-1+y)<<16); - BEGIN_NV04(chan, NV30_3D(VIEWPORT_TX_ORIGIN), 1); - OUT_RING (chan, (y<<16)|x); + BEGIN_NV04(push, NV30_3D(VIEWPORT_HORIZ), 2); + PUSH_DATA (push, (w<<16)|x); + PUSH_DATA (push, (h<<16)|y); + BEGIN_NV04(push, NV30_3D(VIEWPORT_CLIP_HORIZ(0)), 2); + PUSH_DATA (push, (w-1+x)<<16); + PUSH_DATA (push, (h-1+y)<<16); + BEGIN_NV04(push, NV30_3D(VIEWPORT_TX_ORIGIN), 1); + PUSH_DATA (push, (y<<16)|x); } NV30_LoadFilterTable(pScrn); - BEGIN_NV04(chan, NV30_3D(TEX_UNITS_ENABLE), 1); - OUT_RING (chan, NV30_3D_TEX_UNITS_ENABLE_TX0 | + BEGIN_NV04(push, NV30_3D(TEX_UNITS_ENABLE), 1); + PUSH_DATA (push, NV30_3D_TEX_UNITS_ENABLE_TX0 | NV30_3D_TEX_UNITS_ENABLE_TX1); if (!NV30VideoTexture(pScrn, pNv->xv_filtertable_mem, 0, TABLE_SIZE, 1, 0 , 0) || !NV30VideoTexture(pScrn, src, src_offset, src_w, src_h, - src_pitch, 1)) { - MARK_UNDO(chan); + src_pitch, 1)) return BadImplementation; - } - /* We've got NV12 format, which means half width and half height texture of chroma channels. */ + /* We've got NV12 format, which means half width and half height + * texture of chroma channels. + */ if (!NV30VideoTexture(pScrn, src, src_offset2, src_w/2, src_h/2, src_pitch, 2)) { - MARK_UNDO(chan); + PUSH_RESET(push); return BadImplementation; } - BEGIN_NV04(chan, NV30_3D(TEX_ENABLE(3)), 1); - OUT_RING (chan, 0x0); + BEGIN_NV04(push, NV30_3D(TEX_ENABLE(3)), 1); + PUSH_DATA (push, 0x0); if (drw_w / 2 < src_w || drw_h / 2 < src_h) bicubic = FALSE; if (!NV30_LoadFragProg(pScrn, bicubic ? &nv30_fp_yv12_bicubic : - &nv30_fp_yv12_bilinear)) { - MARK_UNDO(chan); + &nv30_fp_yv12_bilinear)) return BadImplementation; + + nouveau_pushbuf_bufctx(push, pNv->bufctx); + if (nouveau_pushbuf_validate(push)) { + nouveau_pushbuf_bufctx(push, NULL); + return BadAlloc; } - /* Just before rendering we wait for vblank in the non-composited case. */ - if (pPriv->SyncToVBlank) { - FIRE_RING(chan); + /* Before rendering we wait for vblank in the non-composited case. */ + if (pPriv->SyncToVBlank) NV11SyncToVBlank(ppix, dstBox); - } /* These are fixed point values in the 16.16 format. */ X1 = (float)(x1>>16)+(float)(x1&0xFFFF)/(float)0x10000; @@ -359,10 +355,9 @@ NV30PutTextureImage(ScrnInfoPtr pScrn, struct nouveau_bo *src, int src_offset, X2 = (float)(x2>>16)+(float)(x2&0xFFFF)/(float)0x10000; Y2 = (float)(y2>>16)+(float)(y2&0xFFFF)/(float)0x10000; - BEGIN_NV04(chan, NV30_3D(VERTEX_BEGIN_END), 1); - OUT_RING (chan, NV30_3D_VERTEX_BEGIN_END_TRIANGLES); - - while(nbox--) { + BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1); + PUSH_DATA (push, NV30_3D_VERTEX_BEGIN_END_TRIANGLES); + while (nbox--) { float tx1=X1+(float)(pbox->x1 - dstBox->x1)*(X2-X1)/(float)(drw_w); float tx2=X1+(float)(pbox->x2 - dstBox->x1)*(src_w)/(float)(drw_w); float ty1=Y1+(float)(pbox->y1 - dstBox->y1)*(Y2-Y1)/(float)(drw_h); @@ -372,9 +367,14 @@ NV30PutTextureImage(ScrnInfoPtr pScrn, struct nouveau_bo *src, int src_offset, int sy1=pbox->y1; int sy2=pbox->y2; - BEGIN_NV04(chan, NV30_3D(SCISSOR_HORIZ), 2); - OUT_RING (chan, (sx2 << 16) | 0); - OUT_RING (chan, (sy2 << 16) | 0); + if (!PUSH_SPACE(push, 64)) { + nouveau_pushbuf_bufctx(push, NULL); + return BadImplementation; + } + + BEGIN_NV04(push, NV30_3D(SCISSOR_HORIZ), 2); + PUSH_DATA (push, (sx2 << 16) | 0); + PUSH_DATA (push, (sy2 << 16) | 0); VERTEX_OUT(tx1, ty1, sx1, sy1); VERTEX_OUT(tx2+(tx2-tx1), ty1, sx2+(sx2-sx1), sy1); @@ -382,23 +382,22 @@ NV30PutTextureImage(ScrnInfoPtr pScrn, struct nouveau_bo *src, int src_offset, pbox++; } - - BEGIN_NV04(chan, NV30_3D(VERTEX_BEGIN_END), 1); - OUT_RING (chan, NV30_3D_VERTEX_BEGIN_END_STOP); + BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1); + PUSH_DATA (push, NV30_3D_VERTEX_BEGIN_END_STOP); if (pNv->dev->chipset == 0x30) { - BEGIN_NV04(chan, NV30_3D(VIEWPORT_HORIZ), 2); - OUT_RING (chan, 4096 << 16); - OUT_RING (chan, 4096 << 16); - BEGIN_NV04(chan, NV30_3D(VIEWPORT_CLIP_HORIZ(0)), 2); - OUT_RING (chan, 4095 << 16); - OUT_RING (chan, 4095 << 16); - BEGIN_NV04(chan, NV30_3D(VIEWPORT_TX_ORIGIN), 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, NV30_3D(VIEWPORT_HORIZ), 2); + PUSH_DATA (push, 4096 << 16); + PUSH_DATA (push, 4096 << 16); + BEGIN_NV04(push, NV30_3D(VIEWPORT_CLIP_HORIZ(0)), 2); + PUSH_DATA (push, 4095 << 16); + PUSH_DATA (push, 4095 << 16); + BEGIN_NV04(push, NV30_3D(VIEWPORT_TX_ORIGIN), 1); + PUSH_DATA (push, 0); } - FIRE_RING (chan); - + nouveau_pushbuf_bufctx(push, NULL); + PUSH_KICK(push); return Success; } diff --git a/src/nv40_exa.c b/src/nv40_exa.c index 344c375..bbf15aa 100644 --- a/src/nv40_exa.c +++ b/src/nv40_exa.c @@ -25,6 +25,7 @@ #include "hwdefs/nv_object.xml.h" #include "hwdefs/nv30-40_3d.xml.h" +#include "nv04_accel.h" typedef struct nv_pict_surface_format { int pict_fmt; @@ -190,7 +191,7 @@ NV40_SetupBlend(ScrnInfoPtr pScrn, nv_pict_op_t *blend, PictFormatShort dest_format, Bool component_alpha) { NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; uint32_t sblend, dblend; sblend = blend->src_card_op; @@ -221,15 +222,15 @@ NV40_SetupBlend(ScrnInfoPtr pScrn, nv_pict_op_t *blend, } if (sblend == SF(ONE) && dblend == DF(ZERO)) { - BEGIN_NV04(chan, NV30_3D(BLEND_FUNC_ENABLE), 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, NV30_3D(BLEND_FUNC_ENABLE), 1); + PUSH_DATA (push, 0); } else { - BEGIN_NV04(chan, NV30_3D(BLEND_FUNC_ENABLE), 5); - OUT_RING (chan, 1); - OUT_RING (chan, sblend); - OUT_RING (chan, dblend); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, NV40_3D_BLEND_EQUATION_ALPHA_FUNC_ADD | + BEGIN_NV04(push, NV30_3D(BLEND_FUNC_ENABLE), 5); + PUSH_DATA (push, 1); + PUSH_DATA (push, sblend); + PUSH_DATA (push, dblend); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, NV40_3D_BLEND_EQUATION_ALPHA_FUNC_ADD | NV40_3D_BLEND_EQUATION_RGB_FUNC_ADD); } } @@ -238,9 +239,9 @@ static Bool NV40EXATexture(ScrnInfoPtr pScrn, PixmapPtr pPix, PicturePtr pPict, int unit) { NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; + unsigned reloc = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_WR; + struct nouveau_pushbuf *push = pNv->pushbuf; struct nouveau_bo *bo = nouveau_pixmap_bo(pPix); - unsigned tex_reloc = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; nv_pict_texture_format_t *fmt; NV40EXA_STATE; @@ -248,53 +249,52 @@ NV40EXATexture(ScrnInfoPtr pScrn, PixmapPtr pPix, PicturePtr pPict, int unit) if (!fmt) return FALSE; - BEGIN_NV04(chan, NV30_3D(TEX_OFFSET(unit)), 8); - if (OUT_RELOCl(chan, bo, 0, tex_reloc) || - OUT_RELOCd(chan, bo, fmt->card_fmt | NV40_3D_TEX_FORMAT_LINEAR | - NV30_3D_TEX_FORMAT_DIMS_2D | 0x8000 | - NV30_3D_TEX_FORMAT_NO_BORDER | - (1 << NV40_3D_TEX_FORMAT_MIPMAP_COUNT__SHIFT), - tex_reloc | NOUVEAU_BO_OR, - NV30_3D_TEX_FORMAT_DMA0, NV30_3D_TEX_FORMAT_DMA1)) - return FALSE; - + BEGIN_NV04(push, NV30_3D(TEX_OFFSET(unit)), 8); + PUSH_MTHDl(push, NV30_3D(TEX_OFFSET(unit)), bo, 0, reloc); + PUSH_MTHDs(push, NV30_3D(TEX_FORMAT(unit)), bo, fmt->card_fmt | + NV40_3D_TEX_FORMAT_LINEAR | + NV30_3D_TEX_FORMAT_DIMS_2D | 0x8000 | + NV30_3D_TEX_FORMAT_NO_BORDER | + (1 << NV40_3D_TEX_FORMAT_MIPMAP_COUNT__SHIFT), + reloc | NOUVEAU_BO_OR, + NV30_3D_TEX_FORMAT_DMA0, NV30_3D_TEX_FORMAT_DMA1); if (pPict->repeat) { switch(pPict->repeatType) { case RepeatPad: - OUT_RING (chan, NV30_3D_TEX_WRAP_S_CLAMP | + PUSH_DATA (push, NV30_3D_TEX_WRAP_S_CLAMP | NV30_3D_TEX_WRAP_T_CLAMP | NV30_3D_TEX_WRAP_R_CLAMP); break; case RepeatReflect: - OUT_RING (chan, NV30_3D_TEX_WRAP_S_MIRRORED_REPEAT | + PUSH_DATA (push, NV30_3D_TEX_WRAP_S_MIRRORED_REPEAT | NV30_3D_TEX_WRAP_T_MIRRORED_REPEAT | NV30_3D_TEX_WRAP_R_MIRRORED_REPEAT); break; case RepeatNormal: default: - OUT_RING (chan, NV30_3D_TEX_WRAP_S_REPEAT | + PUSH_DATA (push, NV30_3D_TEX_WRAP_S_REPEAT | NV30_3D_TEX_WRAP_T_REPEAT | NV30_3D_TEX_WRAP_R_REPEAT); break; } } else { - OUT_RING (chan, NV30_3D_TEX_WRAP_S_CLAMP_TO_BORDER | + PUSH_DATA (push, NV30_3D_TEX_WRAP_S_CLAMP_TO_BORDER | NV30_3D_TEX_WRAP_T_CLAMP_TO_BORDER | NV30_3D_TEX_WRAP_R_CLAMP_TO_BORDER); } - OUT_RING (chan, NV40_3D_TEX_ENABLE_ENABLE); - OUT_RING (chan, fmt->card_swz); + PUSH_DATA (push, NV40_3D_TEX_ENABLE_ENABLE); + PUSH_DATA (push, fmt->card_swz); if (pPict->filter == PictFilterBilinear) { - OUT_RING (chan, NV30_3D_TEX_FILTER_MIN_LINEAR | + PUSH_DATA (push, NV30_3D_TEX_FILTER_MIN_LINEAR | NV30_3D_TEX_FILTER_MAG_LINEAR | 0x3fd6); } else { - OUT_RING (chan, NV30_3D_TEX_FILTER_MIN_NEAREST | + PUSH_DATA (push, NV30_3D_TEX_FILTER_MIN_NEAREST | NV30_3D_TEX_FILTER_MAG_NEAREST | 0x3fd6); } - OUT_RING (chan, (pPix->drawable.width << 16) | pPix->drawable.height); - OUT_RING (chan, 0); /* border ARGB */ - BEGIN_NV04(chan, NV40_3D(TEX_SIZE1(unit)), 1); - OUT_RING (chan, (1 << NV40_3D_TEX_SIZE1_DEPTH__SHIFT) | + PUSH_DATA (push, (pPix->drawable.width << 16) | pPix->drawable.height); + PUSH_DATA (push, 0); /* border ARGB */ + BEGIN_NV04(push, NV40_3D(TEX_SIZE1(unit)), 1); + PUSH_DATA (push, (1 << NV40_3D_TEX_SIZE1_DEPTH__SHIFT) | (uint32_t)exaGetPixmapPitch(pPix)); state->unit[unit].width = (float)pPix->drawable.width; @@ -307,7 +307,7 @@ static Bool NV40_SetupSurface(ScrnInfoPtr pScrn, PixmapPtr pPix, PictFormatShort format) { NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; struct nouveau_bo *bo = nouveau_pixmap_bo(pPix); nv_pict_surface_format_t *fmt; @@ -317,14 +317,12 @@ NV40_SetupSurface(ScrnInfoPtr pScrn, PixmapPtr pPix, PictFormatShort format) return FALSE; } - BEGIN_NV04(chan, NV30_3D(RT_FORMAT), 3); - OUT_RING (chan, NV30_3D_RT_FORMAT_TYPE_LINEAR | - NV30_3D_RT_FORMAT_ZETA_Z24S8 | - fmt->card_fmt); - OUT_RING (chan, exaGetPixmapPitch(pPix)); - if (OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR)) - return FALSE; - + BEGIN_NV04(push, NV30_3D(RT_FORMAT), 3); + PUSH_DATA (push, NV30_3D_RT_FORMAT_TYPE_LINEAR | + NV30_3D_RT_FORMAT_ZETA_Z24S8 | fmt->card_fmt); + PUSH_DATA (push, exaGetPixmapPitch(pPix)); + PUSH_MTHDl(push, NV30_3D(COLOR0_OFFSET), bo, 0, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); return TRUE; } @@ -396,16 +394,6 @@ NV40EXACheckComposite(int op, PicturePtr psPict, return TRUE; } -static void -NV40EXAStateCompositeReemit(struct nouveau_channel *chan) -{ - ScrnInfoPtr pScrn = chan->user_private; - NVPtr pNv = NVPTR(pScrn); - - NV40EXAPrepareComposite(pNv->alu, pNv->pspict, pNv->pmpict, pNv->pdpict, - pNv->pspix, pNv->pmpix, pNv->pdpix); -} - Bool NV40EXAPrepareComposite(int op, PicturePtr psPict, PicturePtr pmPict, @@ -416,32 +404,27 @@ NV40EXAPrepareComposite(int op, PicturePtr psPict, { ScrnInfoPtr pScrn = xf86Screens[psPix->drawable.pScreen->myNum]; NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; - nv_pict_op_t *blend; + nv_pict_op_t *blend = NV40_GetPictOpRec(op); + struct nouveau_pushbuf *push = pNv->pushbuf; int fpid = NV40EXA_FPID_PASS_COL0; NV40EXA_STATE; - if (MARK_RING(chan, 128, 1 + 1 + 2*2)) - return FALSE; - - blend = NV40_GetPictOpRec(op); + if (!PUSH_SPACE(push, 128)) + NOUVEAU_FALLBACK("space\n"); + PUSH_RESET(push); NV40_SetupBlend(pScrn, blend, pdPict->format, (pmPict && pmPict->componentAlpha && PICT_FORMAT_RGB(pmPict->format))); if (!NV40_SetupSurface(pScrn, pdPix, pdPict->format) || - !NV40EXATexture(pScrn, psPix, psPict, 0)) { - MARK_UNDO(chan); + !NV40EXATexture(pScrn, psPix, psPict, 0)) return FALSE; - } NV40_LoadVtxProg(pScrn, &nv40_vp_exa_render); if (pmPict) { - if (!NV40EXATexture(pScrn, pmPix, pmPict, 1)) { - MARK_UNDO(chan); + if (!NV40EXATexture(pScrn, pmPix, pmPict, 1)) return FALSE; - } if (pmPict->componentAlpha && PICT_FORMAT_RGB(pmPict->format)) { if (blend->src_alpha) @@ -461,27 +444,23 @@ NV40EXAPrepareComposite(int op, PicturePtr psPict, if (!NV40_LoadFragProg(pScrn, (pdPict->format == PICT_a8) ? - nv40_fp_map_a8[fpid] : nv40_fp_map[fpid])) { - MARK_UNDO(chan); + nv40_fp_map_a8[fpid] : nv40_fp_map[fpid])) return FALSE; - } /* Appears to be some kind of cache flush, needed here at least * sometimes.. funky text rendering otherwise :) */ - BEGIN_NV04(chan, NV40_3D(TEX_CACHE_CTL), 1); - OUT_RING (chan, 2); - BEGIN_NV04(chan, NV40_3D(TEX_CACHE_CTL), 1); - OUT_RING (chan, 1); - - pNv->alu = op; - pNv->pspict = psPict; - pNv->pmpict = pmPict; - pNv->pdpict = pdPict; - pNv->pspix = psPix; - pNv->pmpix = pmPix; - pNv->pdpix = pdPix; - chan->flush_notify = NV40EXAStateCompositeReemit; + BEGIN_NV04(push, NV40_3D(TEX_CACHE_CTL), 1); + PUSH_DATA (push, 2); + BEGIN_NV04(push, NV40_3D(TEX_CACHE_CTL), 1); + PUSH_DATA (push, 1); + + nouveau_pushbuf_bufctx(push, pNv->bufctx); + if (nouveau_pushbuf_validate(push)) { + nouveau_pushbuf_bufctx(push, NULL); + return FALSE; + } + return TRUE; } @@ -507,17 +486,17 @@ NV40EXATransformCoord(PictTransformPtr t, int x, int y, float sx, float sy, } #define CV_OUTm(sx,sy,mx,my,dx,dy) do { \ - BEGIN_NV04(chan, NV30_3D(VTX_ATTR_2F_X(8)), 4); \ - OUT_RINGf (chan, (sx)); OUT_RINGf (chan, (sy)); \ - OUT_RINGf (chan, (mx)); OUT_RINGf (chan, (my)); \ - BEGIN_NV04(chan, NV30_3D(VTX_ATTR_2I(0)), 1); \ - OUT_RING (chan, ((dy)<<16)|(dx)); \ + BEGIN_NV04(push, NV30_3D(VTX_ATTR_2F_X(8)), 4); \ + PUSH_DATAf(push, (sx)); PUSH_DATAf(push, (sy)); \ + PUSH_DATAf(push, (mx)); PUSH_DATAf(push, (my)); \ + BEGIN_NV04(push, NV30_3D(VTX_ATTR_2I(0)), 1); \ + PUSH_DATA (push, ((dy)<<16)|(dx)); \ } while(0) #define CV_OUT(sx,sy,dx,dy) do { \ - BEGIN_NV04(chan, NV30_3D(VTX_ATTR_2F_X(8)), 2); \ - OUT_RINGf (chan, (sx)); OUT_RINGf (chan, (sy)); \ - BEGIN_NV04(chan, NV30_3D(VTX_ATTR_2I(0)), 1); \ - OUT_RING (chan, ((dy)<<16)|(dx)); \ + BEGIN_NV04(push, NV30_3D(VTX_ATTR_2F_X(8)), 2); \ + PUSH_DATAf(push, (sx)); PUSH_DATAf(push, (sy)); \ + BEGIN_NV04(push, NV30_3D(VTX_ATTR_2I(0)), 1); \ + PUSH_DATA (push, ((dy)<<16)|(dx)); \ } while(0) void @@ -528,23 +507,24 @@ NV40EXAComposite(PixmapPtr pdPix, int srcX , int srcY, { ScrnInfoPtr pScrn = xf86Screens[pdPix->drawable.pScreen->myNum]; NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; float sX0, sX1, sX2, sY0, sY1, sY2; float mX0, mX1, mX2, mY0, mY1, mY2; NV40EXA_STATE; - WAIT_RING(chan, 64); + if (!PUSH_SPACE(push, 64)) + return; /* We're drawing a triangle, we need to scissor it to a quad. */ /* The scissors are here for a good reason, we don't get the full * image, but just a part. */ /* Handling the cliprects is done for us already. */ - BEGIN_NV04(chan, NV30_3D(SCISSOR_HORIZ), 2); - OUT_RING (chan, (width << 16) | dstX); - OUT_RING (chan, (height << 16) | dstY); - BEGIN_NV04(chan, NV30_3D(VERTEX_BEGIN_END), 1); - OUT_RING (chan, NV30_3D_VERTEX_BEGIN_END_TRIANGLES); + BEGIN_NV04(push, NV30_3D(SCISSOR_HORIZ), 2); + PUSH_DATA (push, (width << 16) | dstX); + PUSH_DATA (push, (height << 16) | dstY); + BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1); + PUSH_DATA (push, NV30_3D_VERTEX_BEGIN_END_TRIANGLES); NV40EXATransformCoord(state->unit[0].transform, srcX, srcY - height, state->unit[0].width, state->unit[0].height, @@ -580,18 +560,15 @@ NV40EXAComposite(PixmapPtr pdPix, int srcX , int srcY, CV_OUT(sX2, sY2, dstX + 2*width, dstY + height); } - BEGIN_NV04(chan, NV30_3D(VERTEX_BEGIN_END), 1); - OUT_RING (chan, NV30_3D_VERTEX_BEGIN_END_STOP); + BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1); + PUSH_DATA (push, NV30_3D_VERTEX_BEGIN_END_STOP); } void NV40EXADoneComposite(PixmapPtr pdPix) { ScrnInfoPtr pScrn = xf86Screens[pdPix->drawable.pScreen->myNum]; - NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; - - chan->flush_notify = NULL; + nouveau_pushbuf_bufctx(NVPTR(pScrn)->pushbuf, NULL); } #define NV30_3D_CHIPSET_4X_MASK 0x00000baf @@ -600,7 +577,8 @@ Bool NVAccelInitNV40TCL(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; + struct nv04_fifo *fifo = pNv->channel->data; uint32_t class = 0, chipset; int next_hw_id = 0, next_hw_offset = 0, i; @@ -624,126 +602,125 @@ NVAccelInitNV40TCL(ScrnInfoPtr pScrn) } else return TRUE; - if (!pNv->Nv3D) { - if (nouveau_grobj_alloc(pNv->chan, Nv3D, class, &pNv->Nv3D)) - return FALSE; - } + if (nouveau_object_new(pNv->channel, Nv3D, class, NULL, 0, &pNv->Nv3D)) + return FALSE; - if (!pNv->shader_mem) { - if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | - NOUVEAU_BO_MAP, 0, 0x1000, - &pNv->shader_mem)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Couldn't alloc fragprog buffer!\n"); - nouveau_grobj_free(&pNv->Nv3D); - return FALSE; - } + if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | + NOUVEAU_BO_MAP, 0, 0x1000, NULL, + &pNv->shader_mem)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Couldn't alloc fragprog buffer!\n"); + nouveau_object_del(&pNv->Nv3D); + return FALSE; } - BEGIN_NV04(chan, NV01_SUBC(3D, OBJECT), 1); - OUT_RING (chan, pNv->Nv3D->handle); - BEGIN_NV04(chan, NV30_3D(DMA_NOTIFY), 1); - OUT_RING (chan, pNv->notify0->handle); - BEGIN_NV04(chan, NV30_3D(DMA_TEXTURE0), 2); - OUT_RING (chan, pNv->chan->vram->handle); - OUT_RING (chan, pNv->chan->gart->handle); - BEGIN_NV04(chan, NV30_3D(DMA_COLOR0), 2); - OUT_RING (chan, pNv->chan->vram->handle); - OUT_RING (chan, pNv->chan->vram->handle); + if (!PUSH_SPACE(push, 256)) + return FALSE; + + BEGIN_NV04(push, NV01_SUBC(3D, OBJECT), 1); + PUSH_DATA (push, pNv->Nv3D->handle); + BEGIN_NV04(push, NV30_3D(DMA_NOTIFY), 1); + PUSH_DATA (push, pNv->notify0->handle); + BEGIN_NV04(push, NV30_3D(DMA_TEXTURE0), 2); + PUSH_DATA (push, fifo->vram); + PUSH_DATA (push, fifo->gart); + BEGIN_NV04(push, NV30_3D(DMA_COLOR0), 2); + PUSH_DATA (push, fifo->vram); + PUSH_DATA (push, fifo->vram); /* voodoo */ - BEGIN_NV04(chan, SUBC_3D(0x1ea4), 3); - OUT_RING (chan, 0x00000010); - OUT_RING (chan, 0x01000100); - OUT_RING (chan, 0xff800006); - BEGIN_NV04(chan, SUBC_3D(0x1fc4), 1); - OUT_RING (chan, 0x06144321); - BEGIN_NV04(chan, SUBC_3D(0x1fc8), 2); - OUT_RING (chan, 0xedcba987); - OUT_RING (chan, 0x00000021); - BEGIN_NV04(chan, SUBC_3D(0x1fd0), 1); - OUT_RING (chan, 0x00171615); - BEGIN_NV04(chan, SUBC_3D(0x1fd4), 1); - OUT_RING (chan, 0x001b1a19); - BEGIN_NV04(chan, SUBC_3D(0x1ef8), 1); - OUT_RING (chan, 0x0020ffff); - BEGIN_NV04(chan, SUBC_3D(0x1d64), 1); - OUT_RING (chan, 0x00d30000); - BEGIN_NV04(chan, SUBC_3D(0x1e94), 1); - OUT_RING (chan, 0x00000001); + BEGIN_NV04(push, SUBC_3D(0x1ea4), 3); + PUSH_DATA (push, 0x00000010); + PUSH_DATA (push, 0x01000100); + PUSH_DATA (push, 0xff800006); + BEGIN_NV04(push, SUBC_3D(0x1fc4), 1); + PUSH_DATA (push, 0x06144321); + BEGIN_NV04(push, SUBC_3D(0x1fc8), 2); + PUSH_DATA (push, 0xedcba987); + PUSH_DATA (push, 0x00000021); + BEGIN_NV04(push, SUBC_3D(0x1fd0), 1); + PUSH_DATA (push, 0x00171615); + BEGIN_NV04(push, SUBC_3D(0x1fd4), 1); + PUSH_DATA (push, 0x001b1a19); + BEGIN_NV04(push, SUBC_3D(0x1ef8), 1); + PUSH_DATA (push, 0x0020ffff); + BEGIN_NV04(push, SUBC_3D(0x1d64), 1); + PUSH_DATA (push, 0x00d30000); + BEGIN_NV04(push, SUBC_3D(0x1e94), 1); + PUSH_DATA (push, 0x00000001); /* This removes the the stair shaped tearing that i get. */ /* Verified on one G70 card that it doesn't cause regressions for people without the problem. */ /* The blob sets this up by default for NV43. */ - BEGIN_NV04(chan, SUBC_3D(0x1450), 1); - OUT_RING (chan, 0x0000000F); - - BEGIN_NV04(chan, NV30_3D(VIEWPORT_TRANSLATE_X), 8); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 1.0); - OUT_RINGf (chan, 1.0); - OUT_RINGf (chan, 1.0); - OUT_RINGf (chan, 0.0); + BEGIN_NV04(push, SUBC_3D(0x1450), 1); + PUSH_DATA (push, 0x0000000F); + + BEGIN_NV04(push, NV30_3D(VIEWPORT_TRANSLATE_X), 8); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 1.0); + PUSH_DATAf(push, 1.0); + PUSH_DATAf(push, 1.0); + PUSH_DATAf(push, 0.0); /* default 3D state */ /*XXX: replace with the same state that the DRI emits on startup */ - BEGIN_NV04(chan, NV30_3D(STENCIL_ENABLE(0)), 1); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NV30_3D(STENCIL_ENABLE(1)), 1); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NV30_3D(ALPHA_FUNC_ENABLE), 1); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NV30_3D(DEPTH_WRITE_ENABLE), 2); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NV30_3D(COLOR_MASK), 1); - OUT_RING (chan, 0x01010101); /* TR,TR,TR,TR */ - BEGIN_NV04(chan, NV30_3D(CULL_FACE_ENABLE), 1); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NV30_3D(BLEND_FUNC_ENABLE), 1); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NV30_3D(COLOR_LOGIC_OP_ENABLE), 2); - OUT_RING (chan, 0); - OUT_RING (chan, NV30_3D_COLOR_LOGIC_OP_OP_COPY); - BEGIN_NV04(chan, NV30_3D(DITHER_ENABLE), 1); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NV30_3D(SHADE_MODEL), 1); - OUT_RING (chan, NV30_3D_SHADE_MODEL_SMOOTH); - BEGIN_NV04(chan, NV30_3D(POLYGON_OFFSET_FACTOR),2); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); - BEGIN_NV04(chan, NV30_3D(POLYGON_MODE_FRONT), 2); - OUT_RING (chan, NV30_3D_POLYGON_MODE_FRONT_FILL); - OUT_RING (chan, NV30_3D_POLYGON_MODE_BACK_FILL); - BEGIN_NV04(chan, NV30_3D(POLYGON_STIPPLE_PATTERN(0)), 0x20); + BEGIN_NV04(push, NV30_3D(STENCIL_ENABLE(0)), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV30_3D(STENCIL_ENABLE(1)), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV30_3D(ALPHA_FUNC_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV30_3D(DEPTH_WRITE_ENABLE), 2); + PUSH_DATA (push, 0); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV30_3D(COLOR_MASK), 1); + PUSH_DATA (push, 0x01010101); /* TR,TR,TR,TR */ + BEGIN_NV04(push, NV30_3D(CULL_FACE_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV30_3D(BLEND_FUNC_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV30_3D(COLOR_LOGIC_OP_ENABLE), 2); + PUSH_DATA (push, 0); + PUSH_DATA (push, NV30_3D_COLOR_LOGIC_OP_OP_COPY); + BEGIN_NV04(push, NV30_3D(DITHER_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV30_3D(SHADE_MODEL), 1); + PUSH_DATA (push, NV30_3D_SHADE_MODEL_SMOOTH); + BEGIN_NV04(push, NV30_3D(POLYGON_OFFSET_FACTOR),2); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 0.0); + BEGIN_NV04(push, NV30_3D(POLYGON_MODE_FRONT), 2); + PUSH_DATA (push, NV30_3D_POLYGON_MODE_FRONT_FILL); + PUSH_DATA (push, NV30_3D_POLYGON_MODE_BACK_FILL); + BEGIN_NV04(push, NV30_3D(POLYGON_STIPPLE_PATTERN(0)), 0x20); for (i=0;i<0x20;i++) - OUT_RING (chan, 0xFFFFFFFF); + PUSH_DATA (push, 0xFFFFFFFF); for (i=0;i<16;i++) { - BEGIN_NV04(chan, NV30_3D(TEX_ENABLE(i)), 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, NV30_3D(TEX_ENABLE(i)), 1); + PUSH_DATA (push, 0); } - BEGIN_NV04(chan, SUBC_3D(0x1d78), 1); - OUT_RING (chan, 0x110); - - BEGIN_NV04(chan, NV30_3D(RT_ENABLE), 1); - OUT_RING (chan, NV30_3D_RT_ENABLE_COLOR0); - - BEGIN_NV04(chan, NV30_3D(RT_HORIZ), 2); - OUT_RING (chan, (4096 << 16)); - OUT_RING (chan, (4096 << 16)); - BEGIN_NV04(chan, NV30_3D(SCISSOR_HORIZ), 2); - OUT_RING (chan, (4096 << 16)); - OUT_RING (chan, (4096 << 16)); - BEGIN_NV04(chan, NV30_3D(VIEWPORT_HORIZ), 2); - OUT_RING (chan, (4096 << 16)); - OUT_RING (chan, (4096 << 16)); - BEGIN_NV04(chan, NV30_3D(VIEWPORT_CLIP_HORIZ(0)), 2); - OUT_RING (chan, (4095 << 16)); - OUT_RING (chan, (4095 << 16)); + BEGIN_NV04(push, SUBC_3D(0x1d78), 1); + PUSH_DATA (push, 0x110); + + BEGIN_NV04(push, NV30_3D(RT_ENABLE), 1); + PUSH_DATA (push, NV30_3D_RT_ENABLE_COLOR0); + + BEGIN_NV04(push, NV30_3D(RT_HORIZ), 2); + PUSH_DATA (push, (4096 << 16)); + PUSH_DATA (push, (4096 << 16)); + BEGIN_NV04(push, NV30_3D(SCISSOR_HORIZ), 2); + PUSH_DATA (push, (4096 << 16)); + PUSH_DATA (push, (4096 << 16)); + BEGIN_NV04(push, NV30_3D(VIEWPORT_HORIZ), 2); + PUSH_DATA (push, (4096 << 16)); + PUSH_DATA (push, (4096 << 16)); + BEGIN_NV04(push, NV30_3D(VIEWPORT_CLIP_HORIZ(0)), 2); + PUSH_DATA (push, (4095 << 16)); + PUSH_DATA (push, (4095 << 16)); NV40_UploadVtxProg(pNv, &nv40_vp_exa_render, &next_hw_id); for (i = 0; i < NV40EXA_FPID_MAX; i++) { diff --git a/src/nv40_xv_tex.c b/src/nv40_xv_tex.c index e74cd2a..f0f7105 100644 --- a/src/nv40_xv_tex.c +++ b/src/nv40_xv_tex.c @@ -39,6 +39,7 @@ #include "nv30_shaders.h" #include "hwdefs/nv30-40_3d.xml.h" +#include "nv04_accel.h" extern Atom xvSyncToVBlank, xvSetDefaults; @@ -98,14 +99,15 @@ NV40_LoadFilterTable(ScrnInfoPtr pScrn) if (!pNv->xv_filtertable_mem) { if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, - TABLE_SIZE * sizeof(float) * 4, + TABLE_SIZE * sizeof(float) * 4, NULL, &pNv->xv_filtertable_mem)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Couldn't alloc filter table!\n"); return; } - if (nouveau_bo_map(pNv->xv_filtertable_mem, NOUVEAU_BO_RDWR)) { + if (nouveau_bo_map(pNv->xv_filtertable_mem, NOUVEAU_BO_RDWR, + pNv->client)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Couldn't map filter table!\n"); return; @@ -113,17 +115,15 @@ NV40_LoadFilterTable(ScrnInfoPtr pScrn) int8_t *t=pNv->xv_filtertable_mem->map; compute_filter_table(t); - nouveau_bo_unmap(pNv->xv_filtertable_mem); } } -#define SWIZZLE(ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w) \ - ( \ - NV30_3D_TEX_SWIZZLE_S0_X_##ts0x | NV30_3D_TEX_SWIZZLE_S0_Y_##ts0y | \ - NV30_3D_TEX_SWIZZLE_S0_Z_##ts0z | NV30_3D_TEX_SWIZZLE_S0_W_##ts0w | \ - NV30_3D_TEX_SWIZZLE_S1_X_##ts1x | NV30_3D_TEX_SWIZZLE_S1_Y_##ts1y | \ - NV30_3D_TEX_SWIZZLE_S1_Z_##ts1z | NV30_3D_TEX_SWIZZLE_S1_W_##ts1w \ - ) +#define SWIZZLE(ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w) ( \ + NV30_3D_TEX_SWIZZLE_S0_X_##ts0x | NV30_3D_TEX_SWIZZLE_S0_Y_##ts0y | \ + NV30_3D_TEX_SWIZZLE_S0_Z_##ts0z | NV30_3D_TEX_SWIZZLE_S0_W_##ts0w | \ + NV30_3D_TEX_SWIZZLE_S1_X_##ts1x | NV30_3D_TEX_SWIZZLE_S1_Y_##ts1y | \ + NV30_3D_TEX_SWIZZLE_S1_Z_##ts1z | NV30_3D_TEX_SWIZZLE_S1_W_##ts1w \ +) /* * Texture 0 : filter table @@ -135,8 +135,8 @@ NV40VideoTexture(ScrnInfoPtr pScrn, struct nouveau_bo *src, int offset, uint16_t width, uint16_t height, uint16_t src_pitch, int unit) { NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; - uint32_t tex_reloc = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; + unsigned reloc = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; + struct nouveau_pushbuf *push = pNv->pushbuf; uint32_t card_fmt = 0; uint32_t card_swz = 0; @@ -152,61 +152,60 @@ NV40VideoTexture(ScrnInfoPtr pScrn, struct nouveau_bo *src, int offset, case 2: card_fmt = NV40_3D_TEX_FORMAT_FORMAT_A8L8; #if X_BYTE_ORDER == X_BIG_ENDIAN - card_swz = SWIZZLE(S1, S1, S1, S1, Z, W, X, Y); /* x = V, y = U */ + card_swz = SWIZZLE(S1, S1, S1, S1, Z, W, X, Y); #else - card_swz = SWIZZLE(S1, S1, S1, S1, W, Z, Y, X); /* x = V, y = U */ + card_swz = SWIZZLE(S1, S1, S1, S1, W, Z, Y, X); #endif break; } - BEGIN_NV04(chan, NV30_3D(TEX_OFFSET(unit)), 8); - if (OUT_RELOCl(chan, src, offset, tex_reloc)) - return FALSE; + BEGIN_NV04(push, NV30_3D(TEX_OFFSET(unit)), 8); + PUSH_MTHDl(push, NV30_3D(TEX_OFFSET(unit)), src, offset, reloc); if (unit==0) { - if (OUT_RELOCd(chan, src, card_fmt | 0x8000 | - NV30_3D_TEX_FORMAT_DIMS_1D | - NV30_3D_TEX_FORMAT_NO_BORDER | - (1 << NV40_3D_TEX_FORMAT_MIPMAP_COUNT__SHIFT), - tex_reloc | NOUVEAU_BO_OR, - NV30_3D_TEX_FORMAT_DMA0, - NV30_3D_TEX_FORMAT_DMA1)) - return FALSE; - OUT_RING (chan, NV30_3D_TEX_WRAP_S_REPEAT | + PUSH_MTHDs(push, NV30_3D(TEX_FORMAT(unit)), src, + card_fmt | 0x8000 | + NV30_3D_TEX_FORMAT_DIMS_1D | + NV30_3D_TEX_FORMAT_NO_BORDER | + (1 << NV40_3D_TEX_FORMAT_MIPMAP_COUNT__SHIFT), + reloc | NOUVEAU_BO_OR, + NV30_3D_TEX_FORMAT_DMA0, + NV30_3D_TEX_FORMAT_DMA1); + PUSH_DATA (push, NV30_3D_TEX_WRAP_S_REPEAT | NV30_3D_TEX_WRAP_T_CLAMP_TO_EDGE | NV30_3D_TEX_WRAP_R_CLAMP_TO_EDGE); } else { - if (OUT_RELOCd(chan, src, card_fmt | 0x8000 | - NV40_3D_TEX_FORMAT_LINEAR | - NV40_3D_TEX_FORMAT_RECT | - NV30_3D_TEX_FORMAT_DIMS_2D | - NV30_3D_TEX_FORMAT_NO_BORDER | - (1 << NV40_3D_TEX_FORMAT_MIPMAP_COUNT__SHIFT), - tex_reloc | NOUVEAU_BO_OR, - NV30_3D_TEX_FORMAT_DMA0, - NV30_3D_TEX_FORMAT_DMA1)) - return FALSE; - OUT_RING (chan, NV30_3D_TEX_WRAP_S_CLAMP_TO_EDGE | + PUSH_MTHDs(push, NV30_3D(TEX_FORMAT(unit)), src, + card_fmt | 0x8000 | + NV40_3D_TEX_FORMAT_LINEAR | + NV40_3D_TEX_FORMAT_RECT | + NV30_3D_TEX_FORMAT_DIMS_2D | + NV30_3D_TEX_FORMAT_NO_BORDER | + (1 << NV40_3D_TEX_FORMAT_MIPMAP_COUNT__SHIFT), + reloc | NOUVEAU_BO_OR, + NV30_3D_TEX_FORMAT_DMA0, + NV30_3D_TEX_FORMAT_DMA1); + PUSH_DATA (push, NV30_3D_TEX_WRAP_S_CLAMP_TO_EDGE | NV30_3D_TEX_WRAP_T_CLAMP_TO_EDGE | NV30_3D_TEX_WRAP_R_CLAMP_TO_EDGE); } - OUT_RING (chan, NV40_3D_TEX_ENABLE_ENABLE); - OUT_RING (chan, card_swz); + PUSH_DATA (push, NV40_3D_TEX_ENABLE_ENABLE); + PUSH_DATA (push, card_swz); if (unit == 0) - OUT_RING (chan, NV30_3D_TEX_FILTER_SIGNED_ALPHA | + PUSH_DATA (push, NV30_3D_TEX_FILTER_SIGNED_ALPHA | NV30_3D_TEX_FILTER_SIGNED_RED | NV30_3D_TEX_FILTER_SIGNED_GREEN | NV30_3D_TEX_FILTER_SIGNED_BLUE | NV30_3D_TEX_FILTER_MIN_LINEAR | NV30_3D_TEX_FILTER_MAG_LINEAR | 0x3fd6); else - OUT_RING (chan, NV30_3D_TEX_FILTER_MIN_LINEAR | + PUSH_DATA (push, NV30_3D_TEX_FILTER_MIN_LINEAR | NV30_3D_TEX_FILTER_MAG_LINEAR | 0x3fd6); - OUT_RING (chan, (width << 16) | height); - OUT_RING (chan, 0); /* border ARGB */ + PUSH_DATA (push, (width << 16) | height); + PUSH_DATA (push, 0); /* border ARGB */ - BEGIN_NV04(chan, NV40_3D(TEX_SIZE1(unit)), 1); - OUT_RING (chan, (1 << NV40_3D_TEX_SIZE1_DEPTH__SHIFT) | + BEGIN_NV04(push, NV40_3D(TEX_SIZE1(unit)), 1); + PUSH_DATA (push, (1 << NV40_3D_TEX_SIZE1_DEPTH__SHIFT) | (uint16_t) src_pitch); return TRUE; @@ -241,11 +240,11 @@ NV40StopTexturedVideo(ScrnInfoPtr pScrn, pointer data, Bool Exit) } #define VERTEX_OUT(sx,sy,dx,dy) do { \ - BEGIN_NV04(chan, NV30_3D(VTX_ATTR_2F_X(8)), 4); \ - OUT_RINGf (chan, (sx)); OUT_RINGf (chan, (sy)); \ - OUT_RINGf (chan, (sx)/2.0); OUT_RINGf (chan, (sy)/2.0); \ - BEGIN_NV04(chan, NV30_3D(VTX_ATTR_2I(0)), 1); \ - OUT_RING (chan, ((dy)<<16)|(dx)); \ + BEGIN_NV04(push, NV30_3D(VTX_ATTR_2F_X(8)), 4); \ + PUSH_DATAf(push, (sx)); PUSH_DATAf(push, (sy)); \ + PUSH_DATAf(push, (sx)/2.0); PUSH_DATAf(push, (sy)/2.0); \ + BEGIN_NV04(push, NV30_3D(VTX_ATTR_2I(0)), 1); \ + PUSH_DATA (push, ((dy)<<16)|(dx)); \ } while(0) int @@ -260,7 +259,7 @@ NV40PutTextureImage(ScrnInfoPtr pScrn, NVPortPrivPtr pPriv) { NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; struct nouveau_bo *bo = nouveau_pixmap_bo(ppix); Bool bicubic = pPriv->bicubic; float X1, X2, Y1, Y2; @@ -282,22 +281,18 @@ NV40PutTextureImage(ScrnInfoPtr pScrn, pbox = REGION_RECTS(clipBoxes); nbox = REGION_NUM_RECTS(clipBoxes); - if (MARK_RING(chan, 128, 1 + 1 + 3*2)) + if (!PUSH_SPACE(push, 128)) return BadImplementation; + PUSH_RESET(push); - /* Disable blending */ - BEGIN_NV04(chan, NV30_3D(BLEND_FUNC_ENABLE), 1); - OUT_RING (chan, 0); - - /* Setup surface */ - BEGIN_NV04(chan, NV30_3D(RT_FORMAT), 3); - OUT_RING (chan, NV30_3D_RT_FORMAT_TYPE_LINEAR | + BEGIN_NV04(push, NV30_3D(BLEND_FUNC_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV30_3D(RT_FORMAT), 3); + PUSH_DATA (push, NV30_3D_RT_FORMAT_TYPE_LINEAR | NV30_3D_RT_FORMAT_ZETA_Z24S8 | dst_format); - OUT_RING (chan, exaGetPixmapPitch(ppix)); - if (OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR)) { - MARK_UNDO(chan); - return BadImplementation; - } + PUSH_DATA (push, exaGetPixmapPitch(ppix)); + PUSH_MTHDl(push, NV30_3D(COLOR0_OFFSET), bo, 0, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); NV40_LoadFilterTable(pScrn); @@ -305,14 +300,16 @@ NV40PutTextureImage(ScrnInfoPtr pScrn, 1, 0 , 0) || !NV40VideoTexture(pScrn, src, src_offset, src_w, src_h, src_pitch, 1)) { - MARK_UNDO(chan); + PUSH_RESET(push); return BadImplementation; } - /* We've got NV12 format, which means half width and half height texture of chroma channels. */ + /* We've got NV12 format, which means half width and half height + * texture of chroma channels. + */ if (!NV40VideoTexture(pScrn, src, src_offset2, src_w/2, src_h/2, src_pitch, 2)) { - MARK_UNDO(chan); + PUSH_RESET(push); return BadImplementation; } @@ -324,32 +321,36 @@ NV40PutTextureImage(ScrnInfoPtr pScrn, if (!NV40_LoadFragProg(pScrn, bicubic ? &nv40_fp_yv12_bicubic : &nv30_fp_yv12_bilinear)) { - MARK_UNDO(chan); + PUSH_RESET(push); return BadImplementation; } /* Appears to be some kind of cache flush, needed here at least * sometimes.. funky text rendering otherwise :) */ - BEGIN_NV04(chan, NV40_3D(TEX_CACHE_CTL), 1); - OUT_RING (chan, 2); - BEGIN_NV04(chan, NV40_3D(TEX_CACHE_CTL), 1); - OUT_RING (chan, 1); - - /* Just before rendering we wait for vblank in the non-composited case. */ - if (pPriv->SyncToVBlank) { - FIRE_RING(chan); - NV11SyncToVBlank(ppix, dstBox); + BEGIN_NV04(push, NV40_3D(TEX_CACHE_CTL), 1); + PUSH_DATA (push, 2); + BEGIN_NV04(push, NV40_3D(TEX_CACHE_CTL), 1); + PUSH_DATA (push, 1); + + nouveau_pushbuf_bufctx(push, pNv->bufctx); + if (nouveau_pushbuf_validate(push)) { + nouveau_pushbuf_bufctx(push, NULL); + return BadAlloc; } + /* Before rendering we wait for vblank in the non-composited case. */ + if (pPriv->SyncToVBlank) + NV11SyncToVBlank(ppix, dstBox); + /* These are fixed point values in the 16.16 format. */ X1 = (float)(x1>>16)+(float)(x1&0xFFFF)/(float)0x10000; Y1 = (float)(y1>>16)+(float)(y1&0xFFFF)/(float)0x10000; X2 = (float)(x2>>16)+(float)(x2&0xFFFF)/(float)0x10000; Y2 = (float)(y2>>16)+(float)(y2&0xFFFF)/(float)0x10000; - BEGIN_NV04(chan, NV30_3D(VERTEX_BEGIN_END), 1); - OUT_RING (chan, NV30_3D_VERTEX_BEGIN_END_TRIANGLES); + BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1); + PUSH_DATA (push, NV30_3D_VERTEX_BEGIN_END_TRIANGLES); while(nbox--) { float tx1=X1+(float)(pbox->x1 - dstBox->x1)*(X2-X1)/(float)(drw_w); @@ -361,9 +362,14 @@ NV40PutTextureImage(ScrnInfoPtr pScrn, int sy1=pbox->y1; int sy2=pbox->y2; - BEGIN_NV04(chan, NV30_3D(SCISSOR_HORIZ), 2); - OUT_RING (chan, (sx2 << 16) | 0); - OUT_RING (chan, (sy2 << 16) | 0); + if (!PUSH_SPACE(push, 64)) { + nouveau_pushbuf_bufctx(push, NULL); + return BadImplementation; + } + + BEGIN_NV04(push, NV30_3D(SCISSOR_HORIZ), 2); + PUSH_DATA (push, (sx2 << 16) | 0); + PUSH_DATA (push, (sy2 << 16) | 0); VERTEX_OUT(tx1, ty1, sx1, sy1); VERTEX_OUT(tx2+(tx2-tx1), ty1, sx2+(sx2-sx1), sy1); @@ -372,11 +378,11 @@ NV40PutTextureImage(ScrnInfoPtr pScrn, pbox++; } - BEGIN_NV04(chan, NV30_3D(VERTEX_BEGIN_END), 1); - OUT_RING (chan, NV30_3D_VERTEX_BEGIN_END_STOP); - - FIRE_RING (chan); + BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1); + PUSH_DATA (push, NV30_3D_VERTEX_BEGIN_END_STOP); + nouveau_pushbuf_bufctx(push, NULL); + PUSH_KICK(push); return Success; } diff --git a/src/nv50_accel.c b/src/nv50_accel.c index 8765f44..4a76e23 100644 --- a/src/nv50_accel.c +++ b/src/nv50_accel.c @@ -32,7 +32,7 @@ NV50SyncToVBlank(PixmapPtr ppix, BoxPtr box) { ScrnInfoPtr pScrn = xf86Screens[ppix->drawable.pScreen->myNum]; NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; int crtcs; if (!nouveau_exa_pixmap_is_onscreen(ppix)) @@ -44,23 +44,87 @@ NV50SyncToVBlank(PixmapPtr ppix, BoxPtr box) if (!crtcs) return; - BEGIN_NV04(chan, SUBC_NVSW(0x0060), 2); - OUT_RING (chan, pNv->vblank_sem->handle); - OUT_RING (chan, 0); - BEGIN_NV04(chan, SUBC_NVSW(0x006c), 1); - OUT_RING (chan, 0x22222222); - BEGIN_NV04(chan, SUBC_NVSW(0x0404), 2); - OUT_RING (chan, 0x11111111); - OUT_RING (chan, ffs(crtcs) - 1); - BEGIN_NV04(chan, SUBC_NVSW(0x0068), 1); - OUT_RING (chan, 0x11111111); + BEGIN_NV04(push, SUBC_NVSW(0x0060), 2); + PUSH_DATA (push, pNv->vblank_sem->handle); + PUSH_DATA (push, 0); + BEGIN_NV04(push, SUBC_NVSW(0x006c), 1); + PUSH_DATA (push, 0x22222222); + BEGIN_NV04(push, SUBC_NVSW(0x0404), 2); + PUSH_DATA (push, 0x11111111); + PUSH_DATA (push, ffs(crtcs) - 1); + BEGIN_NV04(push, SUBC_NVSW(0x0068), 1); + PUSH_DATA (push, 0x11111111); +} + +Bool +NVAccelInitM2MF_NV50(ScrnInfoPtr pScrn) +{ + NVPtr pNv = NVPTR(pScrn); + struct nouveau_pushbuf *push = pNv->pushbuf; + struct nv04_fifo *fifo = pNv->channel->data; + + if (nouveau_object_new(pNv->channel, NvMemFormat, NV50_M2MF_CLASS, + NULL, 0, &pNv->NvMemFormat)) + return FALSE; + + if (!PUSH_SPACE(push, 8)) + return FALSE; + + BEGIN_NV04(push, NV01_SUBC(M2MF, OBJECT), 1); + PUSH_DATA (push, pNv->NvMemFormat->handle); + BEGIN_NV04(push, NV03_M2MF(DMA_NOTIFY), 1); + PUSH_DATA (push, pNv->notify0->handle); + BEGIN_NV04(push, NV03_M2MF(DMA_BUFFER_IN), 2); + PUSH_DATA (push, fifo->vram); + PUSH_DATA (push, fifo->vram); + return TRUE; +} + +Bool +NVAccelInit2D_NV50(ScrnInfoPtr pScrn) +{ + NVPtr pNv = NVPTR(pScrn); + struct nouveau_pushbuf *push = pNv->pushbuf; + struct nv04_fifo *fifo = pNv->channel->data; + + if (nouveau_object_new(pNv->channel, Nv2D, NV50_2D_CLASS, + NULL, 0, &pNv->Nv2D)) + return FALSE; + + if (!PUSH_SPACE(push, 64)) + return FALSE; + + BEGIN_NV04(push, NV01_SUBC(2D, OBJECT), 1); + PUSH_DATA (push, pNv->Nv2D->handle); + BEGIN_NV04(push, NV50_2D(DMA_NOTIFY), 3); + PUSH_DATA (push, pNv->notify0->handle); + PUSH_DATA (push, fifo->vram); + PUSH_DATA (push, fifo->vram); + + /* Magics from nv, no clue what they do, but at least some + * of them are needed to avoid crashes. + */ + BEGIN_NV04(push, SUBC_2D(0x0260), 1); + PUSH_DATA (push, 1); + BEGIN_NV04(push, NV50_2D(CLIP_ENABLE), 1); + PUSH_DATA (push, 1); + BEGIN_NV04(push, NV50_2D(COLOR_KEY_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, SUBC_2D(0x058c), 1); + PUSH_DATA (push, 0x111); + + pNv->currentRop = 0xfffffffa; + return TRUE; } Bool NVAccelInitNV50TCL(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; + struct nv04_fifo *fifo = pNv->channel->data; + struct nouveau_pushbuf *push = pNv->pushbuf; + struct nv04_notify ntfy = { .length = 32 }; + struct nouveau_bo *bo; unsigned class; int i; @@ -91,328 +155,302 @@ NVAccelInitNV50TCL(ScrnInfoPtr pScrn) return FALSE; } - if (!pNv->Nv3D) { - if (nouveau_grobj_alloc(chan, Nv3D, class, &pNv->Nv3D)) - return FALSE; + if (nouveau_object_new(pNv->channel, Nv3D, class, NULL, 0, &pNv->Nv3D)) + return FALSE; - if (nouveau_grobj_alloc(chan, NvSW, 0x506e, &pNv->NvSW)) { - nouveau_grobj_free(&pNv->Nv3D); - return FALSE; - } + if (nouveau_object_new(pNv->channel, NvSW, 0x506e, NULL, 0, &pNv->NvSW)) { + nouveau_object_del(&pNv->Nv3D); + return FALSE; + } - if (nouveau_notifier_alloc(chan, NvVBlankSem, 1, - &pNv->vblank_sem)) { - nouveau_grobj_free(&pNv->NvSW); - nouveau_grobj_free(&pNv->Nv3D); - return FALSE; - } + if (nouveau_object_new(pNv->channel, NvVBlankSem, NOUVEAU_NOTIFIER_CLASS, + &ntfy, sizeof(ntfy), &pNv->vblank_sem)) { + nouveau_object_del(&pNv->NvSW); + nouveau_object_del(&pNv->Nv3D); + return FALSE; + } - if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM, 0, 65536, - &pNv->tesla_scratch)) { - nouveau_notifier_free(&pNv->vblank_sem); - nouveau_grobj_free(&pNv->NvSW); - nouveau_grobj_free(&pNv->Nv3D); - return FALSE; - } + if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM, 0, 65536, + NULL, &pNv->tesla_scratch)) { + nouveau_object_del(&pNv->vblank_sem); + nouveau_object_del(&pNv->NvSW); + nouveau_object_del(&pNv->Nv3D); + return FALSE; } + bo = pNv->tesla_scratch; - if (MARK_RING(chan, 512, 32)) + if (nouveau_pushbuf_space(push, 512, 0, 0) || + nouveau_pushbuf_refn (push, &(struct nouveau_pushbuf_refn) { + bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR + }, 1)) return FALSE; - BEGIN_NV04(chan, NV01_SUBC(NVSW, OBJECT), 1); - OUT_RING (chan, pNv->NvSW->handle); - BEGIN_NV04(chan, SUBC_NVSW(0x018c), 1); - OUT_RING (chan, pNv->vblank_sem->handle); - BEGIN_NV04(chan, SUBC_NVSW(0x0400), 1); - OUT_RING (chan, 0); - - BEGIN_NV04(chan, NV01_SUBC(3D, OBJECT), 1); - OUT_RING (chan, pNv->Nv3D->handle); - BEGIN_NV04(chan, NV50_3D(COND_MODE), 1); - OUT_RING (chan, NV50_3D_COND_MODE_ALWAYS); - BEGIN_NV04(chan, NV50_3D(DMA_NOTIFY), 1); - OUT_RING (chan, chan->nullobj->handle); - BEGIN_NV04(chan, NV50_3D(DMA_ZETA), 11); + BEGIN_NV04(push, NV01_SUBC(NVSW, OBJECT), 1); + PUSH_DATA (push, pNv->NvSW->handle); + BEGIN_NV04(push, SUBC_NVSW(0x018c), 1); + PUSH_DATA (push, pNv->vblank_sem->handle); + BEGIN_NV04(push, SUBC_NVSW(0x0400), 1); + PUSH_DATA (push, 0); + + BEGIN_NV04(push, NV01_SUBC(3D, OBJECT), 1); + PUSH_DATA (push, pNv->Nv3D->handle); + BEGIN_NV04(push, NV50_3D(COND_MODE), 1); + PUSH_DATA (push, NV50_3D_COND_MODE_ALWAYS); + BEGIN_NV04(push, NV50_3D(DMA_NOTIFY), 1); + PUSH_DATA (push, pNv->NvNull->handle); + BEGIN_NV04(push, NV50_3D(DMA_ZETA), 11); for (i = 0; i < 11; i++) - OUT_RING (chan, pNv->chan->vram->handle); - BEGIN_NV04(chan, NV50_3D(DMA_COLOR(0)), NV50_3D_DMA_COLOR__LEN); + PUSH_DATA (push, fifo->vram); + BEGIN_NV04(push, NV50_3D(DMA_COLOR(0)), NV50_3D_DMA_COLOR__LEN); for (i = 0; i < NV50_3D_DMA_COLOR__LEN; i++) - OUT_RING (chan, pNv->chan->vram->handle); - BEGIN_NV04(chan, NV50_3D(RT_CONTROL), 1); - OUT_RING (chan, 1); - - BEGIN_NV04(chan, NV50_3D(VIEWPORT_TRANSFORM_EN), 1); - OUT_RING (chan, 0); - BEGIN_NV04(chan, SUBC_3D(0x0f90), 1); - OUT_RING (chan, 1); - - BEGIN_NV04(chan, NV50_3D(LINKED_TSC), 1); - OUT_RING (chan, 1); - - BEGIN_NV04(chan, NV50_3D(TEX_LIMITS(2)), 1); - OUT_RING (chan, 0x54); - - BEGIN_NV04(chan, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); - if (OUT_RELOCh(chan, pNv->tesla_scratch, PVP_OFFSET, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR) || - OUT_RELOCl(chan, pNv->tesla_scratch, PVP_OFFSET, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR)) { - MARK_UNDO(chan); - return FALSE; - } - OUT_RING (chan, 0x00004000); - BEGIN_NV04(chan, NV50_3D(CB_ADDR), 1); - OUT_RING (chan, 0); - BEGIN_NI04(chan, NV50_3D(CB_DATA(0)), (3*2*2)); - OUT_RING (chan, 0x10000001); - OUT_RING (chan, 0x0423c788); - OUT_RING (chan, 0x10000205); - OUT_RING (chan, 0x0423c788); - OUT_RING (chan, 0x10000409); - OUT_RING (chan, 0x0423c788); - OUT_RING (chan, 0x1000060d); - OUT_RING (chan, 0x0423c788); - OUT_RING (chan, 0x10000811); - OUT_RING (chan, 0x0423c788); - OUT_RING (chan, 0x10000a15); - OUT_RING (chan, 0x0423c789); + PUSH_DATA (push, fifo->vram); + BEGIN_NV04(push, NV50_3D(RT_CONTROL), 1); + PUSH_DATA (push, 1); + + BEGIN_NV04(push, NV50_3D(VIEWPORT_TRANSFORM_EN), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, SUBC_3D(0x0f90), 1); + PUSH_DATA (push, 1); + + BEGIN_NV04(push, NV50_3D(TIC_ADDRESS_HIGH), 3); + PUSH_DATA (push, (bo->offset + TIC_OFFSET) >> 32); + PUSH_DATA (push, (bo->offset + TIC_OFFSET)); + PUSH_DATA (push, 0x00000800); + BEGIN_NV04(push, NV50_3D(TSC_ADDRESS_HIGH), 3); + PUSH_DATA (push, (bo->offset + TSC_OFFSET) >> 32); + PUSH_DATA (push, (bo->offset + TSC_OFFSET)); + PUSH_DATA (push, 0x00000000); + BEGIN_NV04(push, NV50_3D(LINKED_TSC), 1); + PUSH_DATA (push, 1); + BEGIN_NV04(push, NV50_3D(TEX_LIMITS(2)), 1); + PUSH_DATA (push, 0x54); + + BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); + PUSH_DATA (push, (bo->offset + PVP_OFFSET) >> 32); + PUSH_DATA (push, (bo->offset + PVP_OFFSET)); + PUSH_DATA (push, 0x00004000); + BEGIN_NV04(push, NV50_3D(CB_ADDR), 1); + PUSH_DATA (push, 0); + BEGIN_NI04(push, NV50_3D(CB_DATA(0)), (3*2*2)); + PUSH_DATA (push, 0x10000001); + PUSH_DATA (push, 0x0423c788); + PUSH_DATA (push, 0x10000205); + PUSH_DATA (push, 0x0423c788); + PUSH_DATA (push, 0x10000409); + PUSH_DATA (push, 0x0423c788); + PUSH_DATA (push, 0x1000060d); + PUSH_DATA (push, 0x0423c788); + PUSH_DATA (push, 0x10000811); + PUSH_DATA (push, 0x0423c788); + PUSH_DATA (push, 0x10000a15); + PUSH_DATA (push, 0x0423c789); /* fetch only VTX_ATTR[0,8,9].xy */ - BEGIN_NV04(chan, NV50_3D(VP_ATTR_EN(0)), 2); - OUT_RING (chan, 0x00000003); - OUT_RING (chan, 0x00000033); - BEGIN_NV04(chan, NV50_3D(VP_REG_ALLOC_RESULT), 1); - OUT_RING (chan, 6); - if (pNv->Nv3D->grclass != 0x8597) { - BEGIN_NV04(chan, NV50_3D(VP_RESULT_MAP_SIZE), 2); - OUT_RING (chan, 8); - OUT_RING (chan, 0); /* NV50_3D_VP_REG_ALLOC_TEMP */ + BEGIN_NV04(push, NV50_3D(VP_ATTR_EN(0)), 2); + PUSH_DATA (push, 0x00000003); + PUSH_DATA (push, 0x00000033); + BEGIN_NV04(push, NV50_3D(VP_REG_ALLOC_RESULT), 1); + PUSH_DATA (push, 6); + if (pNv->Nv3D->oclass != 0x8597) { + BEGIN_NV04(push, NV50_3D(VP_RESULT_MAP_SIZE), 2); + PUSH_DATA (push, 8); + PUSH_DATA (push, 0); /* NV50_3D_VP_REG_ALLOC_TEMP */ } else { - BEGIN_NV04(chan, NV50_3D(VP_RESULT_MAP_SIZE), 1); - OUT_RING (chan, 8); - } - BEGIN_NV04(chan, NV50_3D(VP_START_ID), 1); - OUT_RING (chan, 0); - - BEGIN_NV04(chan, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); - if (OUT_RELOCh(chan, pNv->tesla_scratch, - PFP_OFFSET + PFP_S, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR) || - OUT_RELOCl(chan, pNv->tesla_scratch, - PFP_OFFSET + PFP_S, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR)) { - MARK_UNDO(chan); - return FALSE; - } - OUT_RING (chan, (0 << NV50_3D_CB_DEF_SET_BUFFER__SHIFT) | 0x4000); - BEGIN_NV04(chan, NV50_3D(CB_ADDR), 1); - OUT_RING (chan, 0); - BEGIN_NI04(chan, NV50_3D(CB_DATA(0)), 6); - OUT_RING (chan, 0x80000000); - OUT_RING (chan, 0x90000004); - OUT_RING (chan, 0x82010200); - OUT_RING (chan, 0x82020204); - OUT_RING (chan, 0xf6400001); - OUT_RING (chan, 0x0000c785); - BEGIN_NV04(chan, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); - if (OUT_RELOCh(chan, pNv->tesla_scratch, - PFP_OFFSET + PFP_C, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR) || - OUT_RELOCl(chan, pNv->tesla_scratch, - PFP_OFFSET + PFP_C, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR)) { - MARK_UNDO(chan); - return FALSE; + BEGIN_NV04(push, NV50_3D(VP_RESULT_MAP_SIZE), 1); + PUSH_DATA (push, 8); } - OUT_RING (chan, (0 << NV50_3D_CB_DEF_SET_BUFFER__SHIFT) | 0x4000); - BEGIN_NV04(chan, NV50_3D(CB_ADDR), 1); - OUT_RING (chan, 0); - BEGIN_NI04(chan, NV50_3D(CB_DATA(0)), 16); - OUT_RING (chan, 0x80000000); - OUT_RING (chan, 0x90000004); - OUT_RING (chan, 0x82030210); - OUT_RING (chan, 0x82040214); - OUT_RING (chan, 0x82010200); - OUT_RING (chan, 0x82020204); - OUT_RING (chan, 0xf6400001); - OUT_RING (chan, 0x0000c784); - OUT_RING (chan, 0xf0400211); - OUT_RING (chan, 0x00008784); - OUT_RING (chan, 0xc0040000); - OUT_RING (chan, 0xc0040204); - OUT_RING (chan, 0xc0040409); - OUT_RING (chan, 0x00000780); - OUT_RING (chan, 0xc004060d); - OUT_RING (chan, 0x00000781); - BEGIN_NV04(chan, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); - if (OUT_RELOCh(chan, pNv->tesla_scratch, - PFP_OFFSET + PFP_CCA, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR) || - OUT_RELOCl(chan, pNv->tesla_scratch, - PFP_OFFSET + PFP_CCA, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR)) { - MARK_UNDO(chan); - return FALSE; - } - OUT_RING (chan, (0 << NV50_3D_CB_DEF_SET_BUFFER__SHIFT) | 0x4000); - BEGIN_NV04(chan, NV50_3D(CB_ADDR), 1); - OUT_RING (chan, 0); - BEGIN_NI04(chan, NV50_3D(CB_DATA(0)), 16); - OUT_RING (chan, 0x80000000); - OUT_RING (chan, 0x90000004); - OUT_RING (chan, 0x82030210); - OUT_RING (chan, 0x82040214); - OUT_RING (chan, 0x82010200); - OUT_RING (chan, 0x82020204); - OUT_RING (chan, 0xf6400001); - OUT_RING (chan, 0x0000c784); - OUT_RING (chan, 0xf6400211); - OUT_RING (chan, 0x0000c784); - OUT_RING (chan, 0xc0040000); - OUT_RING (chan, 0xc0050204); - OUT_RING (chan, 0xc0060409); - OUT_RING (chan, 0x00000780); - OUT_RING (chan, 0xc007060d); - OUT_RING (chan, 0x00000781); - BEGIN_NV04(chan, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); - if (OUT_RELOCh(chan, pNv->tesla_scratch, PFP_OFFSET + PFP_CCASA, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR) || - OUT_RELOCl(chan, pNv->tesla_scratch, PFP_OFFSET + PFP_CCASA, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR)) { - MARK_UNDO(chan); - return FALSE; - } - OUT_RING (chan, (0 << NV50_3D_CB_DEF_SET_BUFFER__SHIFT) | 0x4000); - BEGIN_NV04(chan, NV50_3D(CB_ADDR), 1); - OUT_RING (chan, 0); - BEGIN_NI04(chan, NV50_3D(CB_DATA(0)), 16); - OUT_RING (chan, 0x80000000); - OUT_RING (chan, 0x90000004); - OUT_RING (chan, 0x82030200); - OUT_RING (chan, 0x82040204); - OUT_RING (chan, 0x82010210); - OUT_RING (chan, 0x82020214); - OUT_RING (chan, 0xf6400201); - OUT_RING (chan, 0x0000c784); - OUT_RING (chan, 0xf0400011); - OUT_RING (chan, 0x00008784); - OUT_RING (chan, 0xc0040000); - OUT_RING (chan, 0xc0040204); - OUT_RING (chan, 0xc0040409); - OUT_RING (chan, 0x00000780); - OUT_RING (chan, 0xc004060d); - OUT_RING (chan, 0x00000781); - BEGIN_NV04(chan, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); - if (OUT_RELOCh(chan, pNv->tesla_scratch, PFP_OFFSET + PFP_S_A8, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR) || - OUT_RELOCl(chan, pNv->tesla_scratch, PFP_OFFSET + PFP_S_A8, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR)) { - MARK_UNDO(chan); - return FALSE; - } - OUT_RING (chan, (0 << NV50_3D_CB_DEF_SET_BUFFER__SHIFT) | 0x4000); - BEGIN_NV04(chan, NV50_3D(CB_ADDR), 1); - OUT_RING (chan, 0); - BEGIN_NI04(chan, NV50_3D(CB_DATA(0)), 10); - OUT_RING (chan, 0x80000000); - OUT_RING (chan, 0x90000004); - OUT_RING (chan, 0x82010200); - OUT_RING (chan, 0x82020204); - OUT_RING (chan, 0xf0400001); - OUT_RING (chan, 0x00008784); - OUT_RING (chan, 0x10008004); - OUT_RING (chan, 0x10008008); - OUT_RING (chan, 0x1000000d); - OUT_RING (chan, 0x0403c781); - BEGIN_NV04(chan, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); - if (OUT_RELOCh(chan, pNv->tesla_scratch, PFP_OFFSET + PFP_C_A8, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR) || - OUT_RELOCl(chan, pNv->tesla_scratch, PFP_OFFSET + PFP_C_A8, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR)) { - MARK_UNDO(chan); - return FALSE; - } - OUT_RING (chan, (0 << NV50_3D_CB_DEF_SET_BUFFER__SHIFT) | 0x4000); - BEGIN_NV04(chan, NV50_3D(CB_ADDR), 1); - OUT_RING (chan, 0); - BEGIN_NI04(chan, NV50_3D(CB_DATA(0)), 16); - OUT_RING (chan, 0x80000000); - OUT_RING (chan, 0x90000004); - OUT_RING (chan, 0x82030208); - OUT_RING (chan, 0x8204020c); - OUT_RING (chan, 0x82010200); - OUT_RING (chan, 0x82020204); - OUT_RING (chan, 0xf0400001); - OUT_RING (chan, 0x00008784); - OUT_RING (chan, 0xf0400209); - OUT_RING (chan, 0x00008784); - OUT_RING (chan, 0xc002000d); - OUT_RING (chan, 0x00000780); - OUT_RING (chan, 0x10008600); - OUT_RING (chan, 0x10008604); - OUT_RING (chan, 0x10000609); - OUT_RING (chan, 0x0403c781); - BEGIN_NV04(chan, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); - if (OUT_RELOCh(chan, pNv->tesla_scratch, PFP_OFFSET + PFP_NV12, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR) || - OUT_RELOCl(chan, pNv->tesla_scratch, PFP_OFFSET + PFP_NV12, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR)) { - MARK_UNDO(chan); - return FALSE; - } - OUT_RING (chan, (0 << NV50_3D_CB_DEF_SET_BUFFER__SHIFT) | 0x4000); - BEGIN_NV04(chan, NV50_3D(CB_ADDR), 1); - OUT_RING (chan, 0); - BEGIN_NI04(chan, NV50_3D(CB_DATA(0)), 24); - OUT_RING (chan, 0x80000008); - OUT_RING (chan, 0x90000408); - OUT_RING (chan, 0x82010400); - OUT_RING (chan, 0x82020404); - OUT_RING (chan, 0xf0400001); - OUT_RING (chan, 0x00008784); - OUT_RING (chan, 0xc0800014); - OUT_RING (chan, 0xb0810a0c); - OUT_RING (chan, 0xb0820a10); - OUT_RING (chan, 0xb0830a14); - OUT_RING (chan, 0x82030400); - OUT_RING (chan, 0x82040404); - OUT_RING (chan, 0xf0400201); - OUT_RING (chan, 0x0000c784); - OUT_RING (chan, 0xe084000c); - OUT_RING (chan, 0xe0850010); - OUT_RING (chan, 0xe0860015); - OUT_RING (chan, 0x00014780); - OUT_RING (chan, 0xe0870201); - OUT_RING (chan, 0x0000c780); - OUT_RING (chan, 0xe0890209); - OUT_RING (chan, 0x00014780); - OUT_RING (chan, 0xe0880205); - OUT_RING (chan, 0x00010781); + BEGIN_NV04(push, NV50_3D(VP_ADDRESS_HIGH), 2); + PUSH_DATA (push, (bo->offset + PVP_OFFSET) >> 32); + PUSH_DATA (push, (bo->offset + PVP_OFFSET)); + BEGIN_NV04(push, NV50_3D(VP_START_ID), 1); + PUSH_DATA (push, 0); + + BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); + PUSH_DATA (push, (bo->offset + PFP_OFFSET + PFP_S) >> 32); + PUSH_DATA (push, (bo->offset + PFP_OFFSET + PFP_S)); + PUSH_DATA (push, (0 << NV50_3D_CB_DEF_SET_BUFFER__SHIFT) | 0x4000); + BEGIN_NV04(push, NV50_3D(CB_ADDR), 1); + PUSH_DATA (push, 0); + BEGIN_NI04(push, NV50_3D(CB_DATA(0)), 6); + PUSH_DATA (push, 0x80000000); + PUSH_DATA (push, 0x90000004); + PUSH_DATA (push, 0x82010200); + PUSH_DATA (push, 0x82020204); + PUSH_DATA (push, 0xf6400001); + PUSH_DATA (push, 0x0000c785); + BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); + PUSH_DATA (push, (bo->offset + PFP_OFFSET + PFP_C) >> 32); + PUSH_DATA (push, (bo->offset + PFP_OFFSET + PFP_C)); + PUSH_DATA (push, (0 << NV50_3D_CB_DEF_SET_BUFFER__SHIFT) | 0x4000); + BEGIN_NV04(push, NV50_3D(CB_ADDR), 1); + PUSH_DATA (push, 0); + BEGIN_NI04(push, NV50_3D(CB_DATA(0)), 16); + PUSH_DATA (push, 0x80000000); + PUSH_DATA (push, 0x90000004); + PUSH_DATA (push, 0x82030210); + PUSH_DATA (push, 0x82040214); + PUSH_DATA (push, 0x82010200); + PUSH_DATA (push, 0x82020204); + PUSH_DATA (push, 0xf6400001); + PUSH_DATA (push, 0x0000c784); + PUSH_DATA (push, 0xf0400211); + PUSH_DATA (push, 0x00008784); + PUSH_DATA (push, 0xc0040000); + PUSH_DATA (push, 0xc0040204); + PUSH_DATA (push, 0xc0040409); + PUSH_DATA (push, 0x00000780); + PUSH_DATA (push, 0xc004060d); + PUSH_DATA (push, 0x00000781); + BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); + PUSH_DATA (push, (bo->offset + PFP_OFFSET + PFP_CCA) >> 32); + PUSH_DATA (push, (bo->offset + PFP_OFFSET + PFP_CCA)); + PUSH_DATA (push, (0 << NV50_3D_CB_DEF_SET_BUFFER__SHIFT) | 0x4000); + BEGIN_NV04(push, NV50_3D(CB_ADDR), 1); + PUSH_DATA (push, 0); + BEGIN_NI04(push, NV50_3D(CB_DATA(0)), 16); + PUSH_DATA (push, 0x80000000); + PUSH_DATA (push, 0x90000004); + PUSH_DATA (push, 0x82030210); + PUSH_DATA (push, 0x82040214); + PUSH_DATA (push, 0x82010200); + PUSH_DATA (push, 0x82020204); + PUSH_DATA (push, 0xf6400001); + PUSH_DATA (push, 0x0000c784); + PUSH_DATA (push, 0xf6400211); + PUSH_DATA (push, 0x0000c784); + PUSH_DATA (push, 0xc0040000); + PUSH_DATA (push, 0xc0050204); + PUSH_DATA (push, 0xc0060409); + PUSH_DATA (push, 0x00000780); + PUSH_DATA (push, 0xc007060d); + PUSH_DATA (push, 0x00000781); + BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); + PUSH_DATA (push, (bo->offset + PFP_OFFSET + PFP_CCASA) >> 32); + PUSH_DATA (push, (bo->offset + PFP_OFFSET + PFP_CCASA)); + PUSH_DATA (push, (0 << NV50_3D_CB_DEF_SET_BUFFER__SHIFT) | 0x4000); + BEGIN_NV04(push, NV50_3D(CB_ADDR), 1); + PUSH_DATA (push, 0); + BEGIN_NI04(push, NV50_3D(CB_DATA(0)), 16); + PUSH_DATA (push, 0x80000000); + PUSH_DATA (push, 0x90000004); + PUSH_DATA (push, 0x82030200); + PUSH_DATA (push, 0x82040204); + PUSH_DATA (push, 0x82010210); + PUSH_DATA (push, 0x82020214); + PUSH_DATA (push, 0xf6400201); + PUSH_DATA (push, 0x0000c784); + PUSH_DATA (push, 0xf0400011); + PUSH_DATA (push, 0x00008784); + PUSH_DATA (push, 0xc0040000); + PUSH_DATA (push, 0xc0040204); + PUSH_DATA (push, 0xc0040409); + PUSH_DATA (push, 0x00000780); + PUSH_DATA (push, 0xc004060d); + PUSH_DATA (push, 0x00000781); + BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); + PUSH_DATA (push, (bo->offset + PFP_OFFSET + PFP_S_A8) >> 32); + PUSH_DATA (push, (bo->offset + PFP_OFFSET + PFP_S_A8)); + PUSH_DATA (push, (0 << NV50_3D_CB_DEF_SET_BUFFER__SHIFT) | 0x4000); + BEGIN_NV04(push, NV50_3D(CB_ADDR), 1); + PUSH_DATA (push, 0); + BEGIN_NI04(push, NV50_3D(CB_DATA(0)), 10); + PUSH_DATA (push, 0x80000000); + PUSH_DATA (push, 0x90000004); + PUSH_DATA (push, 0x82010200); + PUSH_DATA (push, 0x82020204); + PUSH_DATA (push, 0xf0400001); + PUSH_DATA (push, 0x00008784); + PUSH_DATA (push, 0x10008004); + PUSH_DATA (push, 0x10008008); + PUSH_DATA (push, 0x1000000d); + PUSH_DATA (push, 0x0403c781); + BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); + PUSH_DATA (push, (bo->offset + PFP_OFFSET + PFP_C_A8) >> 32); + PUSH_DATA (push, (bo->offset + PFP_OFFSET + PFP_C_A8)); + PUSH_DATA (push, (0 << NV50_3D_CB_DEF_SET_BUFFER__SHIFT) | 0x4000); + BEGIN_NV04(push, NV50_3D(CB_ADDR), 1); + PUSH_DATA (push, 0); + BEGIN_NI04(push, NV50_3D(CB_DATA(0)), 16); + PUSH_DATA (push, 0x80000000); + PUSH_DATA (push, 0x90000004); + PUSH_DATA (push, 0x82030208); + PUSH_DATA (push, 0x8204020c); + PUSH_DATA (push, 0x82010200); + PUSH_DATA (push, 0x82020204); + PUSH_DATA (push, 0xf0400001); + PUSH_DATA (push, 0x00008784); + PUSH_DATA (push, 0xf0400209); + PUSH_DATA (push, 0x00008784); + PUSH_DATA (push, 0xc002000d); + PUSH_DATA (push, 0x00000780); + PUSH_DATA (push, 0x10008600); + PUSH_DATA (push, 0x10008604); + PUSH_DATA (push, 0x10000609); + PUSH_DATA (push, 0x0403c781); + BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); + PUSH_DATA (push, (bo->offset + PFP_OFFSET + PFP_NV12) >> 32); + PUSH_DATA (push, (bo->offset + PFP_OFFSET + PFP_NV12)); + PUSH_DATA (push, (0 << NV50_3D_CB_DEF_SET_BUFFER__SHIFT) | 0x4000); + BEGIN_NV04(push, NV50_3D(CB_ADDR), 1); + PUSH_DATA (push, 0); + BEGIN_NI04(push, NV50_3D(CB_DATA(0)), 24); + PUSH_DATA (push, 0x80000008); + PUSH_DATA (push, 0x90000408); + PUSH_DATA (push, 0x82010400); + PUSH_DATA (push, 0x82020404); + PUSH_DATA (push, 0xf0400001); + PUSH_DATA (push, 0x00008784); + PUSH_DATA (push, 0xc0800014); + PUSH_DATA (push, 0xb0810a0c); + PUSH_DATA (push, 0xb0820a10); + PUSH_DATA (push, 0xb0830a14); + PUSH_DATA (push, 0x82030400); + PUSH_DATA (push, 0x82040404); + PUSH_DATA (push, 0xf0400201); + PUSH_DATA (push, 0x0000c784); + PUSH_DATA (push, 0xe084000c); + PUSH_DATA (push, 0xe0850010); + PUSH_DATA (push, 0xe0860015); + PUSH_DATA (push, 0x00014780); + PUSH_DATA (push, 0xe0870201); + PUSH_DATA (push, 0x0000c780); + PUSH_DATA (push, 0xe0890209); + PUSH_DATA (push, 0x00014780); + PUSH_DATA (push, 0xe0880205); + PUSH_DATA (push, 0x00010781); /* HPOS.xy = ($o0, $o1), HPOS.zw = (0.0, 1.0), then map $o2 - $o5 */ - BEGIN_NV04(chan, NV50_3D(VP_RESULT_MAP(0)), 2); - OUT_RING (chan, 0x41400100); - OUT_RING (chan, 0x05040302); - BEGIN_NV04(chan, NV50_3D(POINT_SPRITE_ENABLE), 1); - OUT_RING (chan, 0x00000000); - BEGIN_NV04(chan, NV50_3D(FP_INTERPOLANT_CTRL), 2); - OUT_RING (chan, 0x08040404); - OUT_RING (chan, 0x00000008); /* NV50_3D_FP_REG_ALLOC_TEMP */ - - BEGIN_NV04(chan, NV50_3D(SCISSOR_ENABLE(0)), 1); - OUT_RING (chan, 1); - - BEGIN_NV04(chan, NV50_3D(VIEWPORT_HORIZ(0)), 2); - OUT_RING (chan, 8192 << NV50_3D_VIEWPORT_HORIZ_W__SHIFT); - OUT_RING (chan, 8192 << NV50_3D_VIEWPORT_VERT_H__SHIFT); + BEGIN_NV04(push, NV50_3D(VP_RESULT_MAP(0)), 2); + PUSH_DATA (push, 0x41400100); + PUSH_DATA (push, 0x05040302); + BEGIN_NV04(push, NV50_3D(POINT_SPRITE_ENABLE), 1); + PUSH_DATA (push, 0x00000000); + BEGIN_NV04(push, NV50_3D(FP_INTERPOLANT_CTRL), 2); + PUSH_DATA (push, 0x08040404); + PUSH_DATA (push, 0x00000008); /* NV50_3D_FP_REG_ALLOC_TEMP */ + BEGIN_NV04(push, NV50_3D(FP_ADDRESS_HIGH), 2); + PUSH_DATA (push, (bo->offset + PFP_OFFSET) >> 32); + PUSH_DATA (push, (bo->offset + PFP_OFFSET)); + + BEGIN_NV04(push, NV50_3D(SCISSOR_ENABLE(0)), 1); + PUSH_DATA (push, 1); + + BEGIN_NV04(push, NV50_3D(VIEWPORT_HORIZ(0)), 2); + PUSH_DATA (push, 8192 << NV50_3D_VIEWPORT_HORIZ_W__SHIFT); + PUSH_DATA (push, 8192 << NV50_3D_VIEWPORT_VERT_H__SHIFT); /* NV50_3D_SCISSOR_VERT_T_SHIFT is wrong, because it was deducted with * origin lying at the bottom left. This will be changed to _MIN_ and _MAX_ * later, because it is origin dependent. */ - BEGIN_NV04(chan, NV50_3D(SCISSOR_HORIZ(0)), 2); - OUT_RING (chan, 8192 << NV50_3D_SCISSOR_HORIZ_MAX__SHIFT); - OUT_RING (chan, 8192 << NV50_3D_SCISSOR_VERT_MAX__SHIFT); - BEGIN_NV04(chan, NV50_3D(SCREEN_SCISSOR_HORIZ), 2); - OUT_RING (chan, 8192 << NV50_3D_SCREEN_SCISSOR_HORIZ_W__SHIFT); - OUT_RING (chan, 8192 << NV50_3D_SCREEN_SCISSOR_VERT_H__SHIFT); - - BEGIN_NV04(chan, NV50_3D(SET_PROGRAM_CB), 1); - OUT_RING (chan, 0x00000031 | (CB_PFP << 12)); + BEGIN_NV04(push, NV50_3D(SCISSOR_HORIZ(0)), 2); + PUSH_DATA (push, 8192 << NV50_3D_SCISSOR_HORIZ_MAX__SHIFT); + PUSH_DATA (push, 8192 << NV50_3D_SCISSOR_VERT_MAX__SHIFT); + BEGIN_NV04(push, NV50_3D(SCREEN_SCISSOR_HORIZ), 2); + PUSH_DATA (push, 8192 << NV50_3D_SCREEN_SCISSOR_HORIZ_W__SHIFT); + PUSH_DATA (push, 8192 << NV50_3D_SCREEN_SCISSOR_VERT_H__SHIFT); + BEGIN_NV04(push, NV50_3D(SET_PROGRAM_CB), 1); + PUSH_DATA (push, 0x00000031 | (CB_PFP << 12)); return TRUE; } diff --git a/src/nv50_accel.h b/src/nv50_accel.h index 07a4ee1..b8d837f 100644 --- a/src/nv50_accel.h +++ b/src/nv50_accel.h @@ -9,6 +9,17 @@ #include "hwdefs/nv_3ddefs.xml.h" #include "hwdefs/nv_m2mf.xml.h" +/* subchannel assignments */ +#define SUBC_M2MF(mthd) 0, (mthd) +#define NV03_M2MF(mthd) SUBC_M2MF(NV03_M2MF_##mthd) +#define NV50_M2MF(mthd) SUBC_M2MF(NV50_M2MF_##mthd) +#define SUBC_NVSW(mthd) 1, (mthd) +#define SUBC_2D(mthd) 2, (mthd) +#define NV50_2D(mthd) SUBC_2D(NV50_2D_##mthd) +#define NVC0_2D(mthd) SUBC_2D(NVC0_2D_##mthd) +#define SUBC_3D(mthd) 7, (mthd) +#define NV50_3D(mthd) SUBC_3D(NV50_3D_##mthd) + /* "Tesla scratch buffer" offsets */ #define PVP_OFFSET 0x00000000 /* Vertex program */ #define PFP_OFFSET 0x00001000 /* Fragment program */ @@ -33,28 +44,28 @@ static __inline__ void VTX1s(NVPtr pNv, float sx, float sy, unsigned dx, unsigned dy) { - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; - BEGIN_NV04(chan, NV50_3D(VTX_ATTR_2F_X(8)), 2); - OUT_RINGf (chan, sx); - OUT_RINGf (chan, sy); - BEGIN_NV04(chan, NV50_3D(VTX_ATTR_2I(0)), 1); - OUT_RING (chan, (dy << 16) | dx); + BEGIN_NV04(push, NV50_3D(VTX_ATTR_2F_X(8)), 2); + PUSH_DATAf(push, sx); + PUSH_DATAf(push, sy); + BEGIN_NV04(push, NV50_3D(VTX_ATTR_2I(0)), 1); + PUSH_DATA (push, (dy << 16) | dx); } static __inline__ void VTX2s(NVPtr pNv, float s1x, float s1y, float s2x, float s2y, unsigned dx, unsigned dy) { - struct nouveau_channel *chan = pNv->chan; - - BEGIN_NV04(chan, NV50_3D(VTX_ATTR_2F_X(8)), 4); - OUT_RINGf (chan, s1x); - OUT_RINGf (chan, s1y); - OUT_RINGf (chan, s2x); - OUT_RINGf (chan, s2y); - BEGIN_NV04(chan, NV50_3D(VTX_ATTR_2I(0)), 1); - OUT_RING (chan, (dy << 16) | dx); + struct nouveau_pushbuf *push = pNv->pushbuf; + + BEGIN_NV04(push, NV50_3D(VTX_ATTR_2F_X(8)), 4); + PUSH_DATAf(push, s1x); + PUSH_DATAf(push, s1y); + PUSH_DATAf(push, s2x); + PUSH_DATAf(push, s2y); + BEGIN_NV04(push, NV50_3D(VTX_ATTR_2I(0)), 1); + PUSH_DATA (push, (dy << 16) | dx); } #endif diff --git a/src/nv50_exa.c b/src/nv50_exa.c index 7c670d4..6f87df9 100644 --- a/src/nv50_exa.c +++ b/src/nv50_exa.c @@ -37,10 +37,10 @@ struct nv50_exa_state { }; static struct nv50_exa_state exa_state; -#define NV50EXA_LOCALS(p) \ - ScrnInfoPtr pScrn = xf86Screens[(p)->drawable.pScreen->myNum]; \ - NVPtr pNv = NVPTR(pScrn); \ - struct nouveau_channel *chan = pNv->chan; (void)chan; \ +#define NV50EXA_LOCALS(p) \ + ScrnInfoPtr pScrn = xf86Screens[(p)->drawable.pScreen->myNum]; \ + NVPtr pNv = NVPTR(pScrn); \ + struct nouveau_pushbuf *push = pNv->pushbuf; (void)push; \ struct nv50_exa_state *state = &exa_state; (void)state #define BF(f) NV50_BLEND_FACTOR_##f @@ -94,53 +94,49 @@ static void NV50EXASetClip(PixmapPtr ppix, int x, int y, int w, int h) { NV50EXA_LOCALS(ppix); - BEGIN_NV04(chan, NV50_2D(CLIP_X), 4); - OUT_RING (chan, x); - OUT_RING (chan, y); - OUT_RING (chan, w); - OUT_RING (chan, h); + BEGIN_NV04(push, NV50_2D(CLIP_X), 4); + PUSH_DATA (push, x); + PUSH_DATA (push, y); + PUSH_DATA (push, w); + PUSH_DATA (push, h); } -static Bool -NV50EXAAcquireSurface2D(PixmapPtr ppix, int is_src) +static void +NV50EXAAcquireSurface2D(PixmapPtr ppix, int is_src, uint32_t fmt) { NV50EXA_LOCALS(ppix); struct nouveau_bo *bo = nouveau_pixmap_bo(ppix); int mthd = is_src ? NV50_2D_SRC_FORMAT : NV50_2D_DST_FORMAT; - uint32_t fmt, bo_flags; - - if (!NV50EXA2DSurfaceFormat(ppix, &fmt)) - return FALSE; + uint32_t bo_flags; bo_flags = NOUVEAU_BO_VRAM; bo_flags |= is_src ? NOUVEAU_BO_RD : NOUVEAU_BO_WR; if (!nv50_style_tiled_pixmap(ppix)) { - BEGIN_NV04(chan, SUBC_2D(mthd), 2); - OUT_RING (chan, fmt); - OUT_RING (chan, 1); - BEGIN_NV04(chan, SUBC_2D(mthd + 0x14), 1); - OUT_RING (chan, (uint32_t)exaGetPixmapPitch(ppix)); + BEGIN_NV04(push, SUBC_2D(mthd), 2); + PUSH_DATA (push, fmt); + PUSH_DATA (push, 1); + BEGIN_NV04(push, SUBC_2D(mthd + 0x14), 1); + PUSH_DATA (push, (uint32_t)exaGetPixmapPitch(ppix)); } else { - BEGIN_NV04(chan, SUBC_2D(mthd), 5); - OUT_RING (chan, fmt); - OUT_RING (chan, 0); - OUT_RING (chan, bo->tile_mode << 4); - OUT_RING (chan, 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, SUBC_2D(mthd), 5); + PUSH_DATA (push, fmt); + PUSH_DATA (push, 0); + PUSH_DATA (push, bo->config.nv50.tile_mode); + PUSH_DATA (push, 1); + PUSH_DATA (push, 0); } - BEGIN_NV04(chan, SUBC_2D(mthd + 0x18), 4); - OUT_RING (chan, ppix->drawable.width); - OUT_RING (chan, ppix->drawable.height); - if (OUT_RELOCh(chan, bo, 0, bo_flags) || - OUT_RELOCl(chan, bo, 0, bo_flags)) - return FALSE; + BEGIN_NV04(push, SUBC_2D(mthd + 0x18), 4); + PUSH_DATA (push, ppix->drawable.width); + PUSH_DATA (push, ppix->drawable.height); + PUSH_DATA (push, bo->offset >> 32); + PUSH_DATA (push, bo->offset); if (is_src == 0) NV50EXASetClip(ppix, 0, 0, ppix->drawable.width, ppix->drawable.height); - return TRUE; + PUSH_REFN (push, bo, bo_flags); } static void @@ -148,11 +144,11 @@ NV50EXASetPattern(PixmapPtr pdpix, int col0, int col1, int pat0, int pat1) { NV50EXA_LOCALS(pdpix); - BEGIN_NV04(chan, NV50_2D(PATTERN_COLOR(0)), 4); - OUT_RING (chan, col0); - OUT_RING (chan, col1); - OUT_RING (chan, pat0); - OUT_RING (chan, pat1); + BEGIN_NV04(push, NV50_2D(PATTERN_COLOR(0)), 4); + PUSH_DATA (push, col0); + PUSH_DATA (push, col1); + PUSH_DATA (push, pat0); + PUSH_DATA (push, pat1); } static void @@ -166,26 +162,26 @@ NV50EXASetROP(PixmapPtr pdpix, int alu, Pixel planemask) else rop = NVROP[alu].copy; - BEGIN_NV04(chan, NV50_2D(OPERATION), 1); + BEGIN_NV04(push, NV50_2D(OPERATION), 1); if (alu == GXcopy && EXA_PM_IS_SOLID(&pdpix->drawable, planemask)) { - OUT_RING (chan, NV50_2D_OPERATION_SRCCOPY); + PUSH_DATA (push, NV50_2D_OPERATION_SRCCOPY); return; } else { - OUT_RING (chan, NV50_2D_OPERATION_ROP); + PUSH_DATA (push, NV50_2D_OPERATION_ROP); } - BEGIN_NV04(chan, NV50_2D(PATTERN_COLOR_FORMAT), 2); + BEGIN_NV04(push, NV50_2D(PATTERN_COLOR_FORMAT), 2); switch (pdpix->drawable.bitsPerPixel) { - case 8: OUT_RING (chan, 3); break; - case 15: OUT_RING (chan, 1); break; - case 16: OUT_RING (chan, 0); break; + case 8: PUSH_DATA (push, 3); break; + case 15: PUSH_DATA (push, 1); break; + case 16: PUSH_DATA (push, 0); break; case 24: case 32: default: - OUT_RING (chan, 2); + PUSH_DATA (push, 2); break; } - OUT_RING (chan, 1); + PUSH_DATA (push, 1); /* There are 16 alu's. * 0-15: copy @@ -201,22 +197,12 @@ NV50EXASetROP(PixmapPtr pdpix, int alu, Pixel planemask) } if (pNv->currentRop != alu) { - BEGIN_NV04(chan, NV50_2D(ROP), 1); - OUT_RING (chan, rop); + BEGIN_NV04(push, NV50_2D(ROP), 1); + PUSH_DATA (push, rop); pNv->currentRop = alu; } } -static void -NV50EXAStateSolidResubmit(struct nouveau_channel *chan) -{ - ScrnInfoPtr pScrn = chan->user_private; - NVPtr pNv = NVPTR(pScrn); - - NV50EXAPrepareSolid(pNv->pdpix, pNv->alu, pNv->planemask, - pNv->fg_colour); -} - Bool NV50EXAPrepareSolid(PixmapPtr pdpix, int alu, Pixel planemask, Pixel fg) { @@ -226,26 +212,24 @@ NV50EXAPrepareSolid(PixmapPtr pdpix, int alu, Pixel planemask, Pixel fg) if (!NV50EXA2DSurfaceFormat(pdpix, &fmt)) NOUVEAU_FALLBACK("rect format\n"); - if (MARK_RING(chan, 64, 4)) - NOUVEAU_FALLBACK("ring space\n"); - - if (!NV50EXAAcquireSurface2D(pdpix, 0)) { - MARK_UNDO(chan); - NOUVEAU_FALLBACK("dest pixmap\n"); - } + if (!PUSH_SPACE(push, 64)) + NOUVEAU_FALLBACK("space\n"); + PUSH_RESET(push); + NV50EXAAcquireSurface2D(pdpix, 0, fmt); NV50EXASetROP(pdpix, alu, planemask); - BEGIN_NV04(chan, NV50_2D(DRAW_SHAPE), 3); - OUT_RING (chan, NV50_2D_DRAW_SHAPE_RECTANGLES); - OUT_RING (chan, fmt); - OUT_RING (chan, fg); + BEGIN_NV04(push, NV50_2D(DRAW_SHAPE), 3); + PUSH_DATA (push, NV50_2D_DRAW_SHAPE_RECTANGLES); + PUSH_DATA (push, fmt); + PUSH_DATA (push, fg); + + nouveau_pushbuf_bufctx(push, pNv->bufctx); + if (nouveau_pushbuf_validate(push)) { + nouveau_pushbuf_bufctx(push, NULL); + NOUVEAU_FALLBACK("validate\n"); + } - pNv->pdpix = pdpix; - pNv->alu = alu; - pNv->planemask = planemask; - pNv->fg_colour = fg; - chan->flush_notify = NV50EXAStateSolidResubmit; return TRUE; } @@ -254,33 +238,24 @@ NV50EXASolid(PixmapPtr pdpix, int x1, int y1, int x2, int y2) { NV50EXA_LOCALS(pdpix); - WAIT_RING (chan, 5); - BEGIN_NV04(chan, NV50_2D(DRAW_POINT32_X(0)), 4); - OUT_RING (chan, x1); - OUT_RING (chan, y1); - OUT_RING (chan, x2); - OUT_RING (chan, y2); + if (!PUSH_SPACE(push, 8)) + return; + + BEGIN_NV04(push, NV50_2D(DRAW_POINT32_X(0)), 4); + PUSH_DATA (push, x1); + PUSH_DATA (push, y1); + PUSH_DATA (push, x2); + PUSH_DATA (push, y2); - if((x2 - x1) * (y2 - y1) >= 512) - FIRE_RING (chan); + if ((x2 - x1) * (y2 - y1) >= 512) + PUSH_KICK(push); } void NV50EXADoneSolid(PixmapPtr pdpix) { NV50EXA_LOCALS(pdpix); - - chan->flush_notify = NULL; -} - -static void -NV50EXAStateCopyResubmit(struct nouveau_channel *chan) -{ - ScrnInfoPtr pScrn = chan->user_private; - NVPtr pNv = NVPTR(pScrn); - - NV50EXAPrepareCopy(pNv->pspix, pNv->pdpix, 0, 0, pNv->alu, - pNv->planemask); + nouveau_pushbuf_bufctx(push, NULL); } Bool @@ -288,27 +263,27 @@ NV50EXAPrepareCopy(PixmapPtr pspix, PixmapPtr pdpix, int dx, int dy, int alu, Pixel planemask) { NV50EXA_LOCALS(pdpix); + uint32_t src, dst; - if (MARK_RING(chan, 64, 4)) - NOUVEAU_FALLBACK("ring space\n"); - - if (!NV50EXAAcquireSurface2D(pspix, 1)) { - MARK_UNDO(chan); - NOUVEAU_FALLBACK("src pixmap\n"); - } + if (!NV50EXA2DSurfaceFormat(pspix, &src)) + NOUVEAU_FALLBACK("src format\n"); + if (!NV50EXA2DSurfaceFormat(pdpix, &dst)) + NOUVEAU_FALLBACK("dst format\n"); - if (!NV50EXAAcquireSurface2D(pdpix, 0)) { - MARK_UNDO(chan); - NOUVEAU_FALLBACK("dest pixmap\n"); - } + if (!PUSH_SPACE(push, 64)) + NOUVEAU_FALLBACK("space\n"); + PUSH_RESET(push); + NV50EXAAcquireSurface2D(pspix, 1, src); + NV50EXAAcquireSurface2D(pdpix, 0, dst); NV50EXASetROP(pdpix, alu, planemask); - pNv->pspix = pspix; - pNv->pdpix = pdpix; - pNv->alu = alu; - pNv->planemask = planemask; - chan->flush_notify = NV50EXAStateCopyResubmit; + nouveau_pushbuf_bufctx(push, pNv->bufctx); + if (nouveau_pushbuf_validate(push)) { + nouveau_pushbuf_bufctx(push, NULL); + NOUVEAU_FALLBACK("validate\n"); + } + return TRUE; } @@ -319,48 +294,36 @@ NV50EXACopy(PixmapPtr pdpix, int srcX , int srcY, { NV50EXA_LOCALS(pdpix); - WAIT_RING (chan, 17); - BEGIN_NV04(chan, SUBC_2D(0x0110), 1); - OUT_RING (chan, 0); - BEGIN_NV04(chan, SUBC_2D(0x088c), 1); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NV50_2D(BLIT_DST_X), 12); - OUT_RING (chan, dstX); - OUT_RING (chan, dstY); - OUT_RING (chan, width); - OUT_RING (chan, height); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - OUT_RING (chan, srcX); - OUT_RING (chan, 0); - OUT_RING (chan, srcY); - - if(width * height >= 512) - FIRE_RING (chan); + if (!PUSH_SPACE(push, 32)) + return; + + BEGIN_NV04(push, SUBC_2D(0x0110), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, SUBC_2D(0x088c), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV50_2D(BLIT_DST_X), 12); + PUSH_DATA (push, dstX); + PUSH_DATA (push, dstY); + PUSH_DATA (push, width); + PUSH_DATA (push, height); + PUSH_DATA (push, 0); + PUSH_DATA (push, 1); + PUSH_DATA (push, 0); + PUSH_DATA (push, 1); + PUSH_DATA (push, 0); + PUSH_DATA (push, srcX); + PUSH_DATA (push, 0); + PUSH_DATA (push, srcY); + + if (width * height >= 512) + PUSH_KICK(push); } void NV50EXADoneCopy(PixmapPtr pdpix) { NV50EXA_LOCALS(pdpix); - - chan->flush_notify = NULL; -} - -static void -NV50EXAStateSIFCResubmit(struct nouveau_channel *chan) -{ - ScrnInfoPtr pScrn = chan->user_private; - NVPtr pNv = NVPTR(pScrn); - - if (MARK_RING(pNv->chan, 32, 2)) - return; - - if (!NV50EXAAcquireSurface2D(pNv->pdpix, 0)) - MARK_UNDO(pNv->chan); + nouveau_pushbuf_bufctx(push, NULL); } Bool @@ -371,40 +334,38 @@ NV50EXAUploadSIFC(const char *src, int src_pitch, ScreenPtr pScreen = pdpix->drawable.pScreen; int line_dwords = (w * cpp + 3) / 4; uint32_t sifc_fmt; + Bool ret = FALSE; if (!NV50EXA2DSurfaceFormat(pdpix, &sifc_fmt)) NOUVEAU_FALLBACK("hostdata format\n"); - if (MARK_RING(chan, 64, 2)) - return FALSE; - - if (!NV50EXAAcquireSurface2D(pdpix, 0)) { - MARK_UNDO(chan); - NOUVEAU_FALLBACK("dest pixmap\n"); - } + if (!PUSH_SPACE(push, 64)) + NOUVEAU_FALLBACK("space\n"); + PUSH_RESET(push); - /* If the pitch isn't aligned to a dword, then you can get corruption at the end of a line. */ + NV50EXAAcquireSurface2D(pdpix, 0, sifc_fmt); NV50EXASetClip(pdpix, x, y, w, h); - BEGIN_NV04(chan, NV50_2D(OPERATION), 1); - OUT_RING (chan, NV50_2D_OPERATION_SRCCOPY); - BEGIN_NV04(chan, NV50_2D(SIFC_BITMAP_ENABLE), 2); - OUT_RING (chan, 0); - OUT_RING (chan, sifc_fmt); - BEGIN_NV04(chan, NV50_2D(SIFC_WIDTH), 10); - OUT_RING (chan, (line_dwords * 4) / cpp); - OUT_RING (chan, h); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - OUT_RING (chan, x); - OUT_RING (chan, 0); - OUT_RING (chan, y); - - pNv->pdpix = pdpix; - chan->flush_notify = NV50EXAStateSIFCResubmit; + BEGIN_NV04(push, NV50_2D(OPERATION), 1); + PUSH_DATA (push, NV50_2D_OPERATION_SRCCOPY); + BEGIN_NV04(push, NV50_2D(SIFC_BITMAP_ENABLE), 2); + PUSH_DATA (push, 0); + PUSH_DATA (push, sifc_fmt); + BEGIN_NV04(push, NV50_2D(SIFC_WIDTH), 10); + PUSH_DATA (push, (line_dwords * 4) / cpp); + PUSH_DATA (push, h); + PUSH_DATA (push, 0); + PUSH_DATA (push, 1); + PUSH_DATA (push, 0); + PUSH_DATA (push, 1); + PUSH_DATA (push, 0); + PUSH_DATA (push, x); + PUSH_DATA (push, 0); + PUSH_DATA (push, y); + + nouveau_pushbuf_bufctx(push, pNv->bufctx); + if (nouveau_pushbuf_validate(push)) + goto out; while (h--) { int count = line_dwords; @@ -413,9 +374,10 @@ NV50EXAUploadSIFC(const char *src, int src_pitch, while(count) { int size = count > 1792 ? 1792 : count; - WAIT_RING (chan, size + 1); - BEGIN_NI04(chan, NV50_2D(SIFC_DATA), size); - OUT_RINGp (chan, p, size); + if (!PUSH_SPACE(push, size + 1)) + goto out; + BEGIN_NI04(push, NV50_2D(SIFC_DATA), size); + PUSH_DATAp(push, p, size); p += size * 4; count -= size; @@ -424,11 +386,12 @@ NV50EXAUploadSIFC(const char *src, int src_pitch, src += src_pitch; } - chan->flush_notify = NULL; - + ret = TRUE; +out: + nouveau_pushbuf_bufctx(push, NULL); if (pdpix == pScreen->GetScreenPixmap(pScreen)) - FIRE_RING(chan); - return TRUE; + PUSH_KICK(push); + return ret; } static Bool @@ -493,18 +456,17 @@ NV50EXARenderTarget(PixmapPtr ppix, PicturePtr ppict) NOUVEAU_FALLBACK("invalid picture format\n"); } - BEGIN_NV04(chan, NV50_3D(RT_ADDRESS_HIGH(0)), 5); - if (OUT_RELOCh(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR) || - OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR)) - return FALSE; - OUT_RING (chan, format); - OUT_RING (chan, bo->tile_mode << 4); - OUT_RING (chan, 0x00000000); - BEGIN_NV04(chan, NV50_3D(RT_HORIZ(0)), 2); - OUT_RING (chan, ppix->drawable.width); - OUT_RING (chan, ppix->drawable.height); - BEGIN_NV04(chan, NV50_3D(RT_ARRAY_MODE), 1); - OUT_RING (chan, 0x00000001); + BEGIN_NV04(push, NV50_3D(RT_ADDRESS_HIGH(0)), 5); + PUSH_DATA (push, bo->offset >> 32); + PUSH_DATA (push, bo->offset); + PUSH_DATA (push, format); + PUSH_DATA (push, bo->config.nv50.tile_mode); + PUSH_DATA (push, 0x00000000); + BEGIN_NV04(push, NV50_3D(RT_HORIZ(0)), 2); + PUSH_DATA (push, ppix->drawable.width); + PUSH_DATA (push, ppix->drawable.height); + BEGIN_NV04(push, NV50_3D(RT_ARRAY_MODE), 1); + PUSH_DATA (push, 0x00000001); return TRUE; } @@ -578,159 +540,143 @@ NV50EXATexture(PixmapPtr ppix, PicturePtr ppict, unsigned unit) { NV50EXA_LOCALS(ppix); struct nouveau_bo *bo = nouveau_pixmap_bo(ppix); - const unsigned tcb_flags = NOUVEAU_BO_RDWR | NOUVEAU_BO_VRAM; - uint32_t mode; /*XXX: Scanout buffer not tiled, someone needs to figure it out */ if (!nv50_style_tiled_pixmap(ppix)) NOUVEAU_FALLBACK("pixmap is scanout buffer\n"); - BEGIN_NV04(chan, NV50_3D(TIC_ADDRESS_HIGH), 3); - if (OUT_RELOCh(chan, pNv->tesla_scratch, TIC_OFFSET, tcb_flags) || - OUT_RELOCl(chan, pNv->tesla_scratch, TIC_OFFSET, tcb_flags)) - return FALSE; - OUT_RING (chan, 0x00000800); - BEGIN_NV04(chan, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); - if (OUT_RELOCh(chan, pNv->tesla_scratch, TIC_OFFSET, tcb_flags) || - OUT_RELOCl(chan, pNv->tesla_scratch, TIC_OFFSET, tcb_flags)) - return FALSE; - OUT_RING (chan, (CB_TIC << NV50_3D_CB_DEF_SET_BUFFER__SHIFT) | 0x4000); - BEGIN_NV04(chan, NV50_3D(CB_ADDR), 1); - OUT_RING (chan, CB_TIC | ((unit * 8) << NV50_3D_CB_ADDR_ID__SHIFT)); - BEGIN_NI04(chan, NV50_3D(CB_DATA(0)), 8); - + BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); + PUSH_DATA (push, (pNv->tesla_scratch->offset + TIC_OFFSET) >> 32); + PUSH_DATA (push, (pNv->tesla_scratch->offset + TIC_OFFSET)); + PUSH_DATA (push, (CB_TIC << NV50_3D_CB_DEF_SET_BUFFER__SHIFT) | 0x4000); + BEGIN_NV04(push, NV50_3D(CB_ADDR), 1); + PUSH_DATA (push, CB_TIC | ((unit * 8) << NV50_3D_CB_ADDR_ID__SHIFT)); + BEGIN_NI04(push, NV50_3D(CB_DATA(0)), 8); switch (ppict->format) { case PICT_a8r8g8b8: - OUT_RING(chan, _(B_C0, G_C1, R_C2, A_C3, 8_8_8_8)); + PUSH_DATA (push, _(B_C0, G_C1, R_C2, A_C3, 8_8_8_8)); break; case PICT_a8b8g8r8: - OUT_RING(chan, _(R_C0, G_C1, B_C2, A_C3, 8_8_8_8)); + PUSH_DATA (push, _(R_C0, G_C1, B_C2, A_C3, 8_8_8_8)); break; case PICT_x8r8g8b8: - OUT_RING(chan, _(B_C0, G_C1, R_C2, A_ONE, 8_8_8_8)); + PUSH_DATA (push, _(B_C0, G_C1, R_C2, A_ONE, 8_8_8_8)); break; case PICT_x8b8g8r8: - OUT_RING(chan, _(R_C0, G_C1, B_C2, A_ONE, 8_8_8_8)); + PUSH_DATA (push, _(R_C0, G_C1, B_C2, A_ONE, 8_8_8_8)); break; case PICT_r5g6b5: - OUT_RING(chan, _(B_C0, G_C1, R_C2, A_ONE, 5_6_5)); + PUSH_DATA (push, _(B_C0, G_C1, R_C2, A_ONE, 5_6_5)); break; case PICT_a8: - OUT_RING(chan, _(A_C0, B_ZERO, G_ZERO, R_ZERO, 8)); + PUSH_DATA (push, _(A_C0, B_ZERO, G_ZERO, R_ZERO, 8)); break; case PICT_x1r5g5b5: - OUT_RING(chan, _(B_C0, G_C1, R_C2, A_ONE, 1_5_5_5)); + PUSH_DATA (push, _(B_C0, G_C1, R_C2, A_ONE, 1_5_5_5)); break; case PICT_x1b5g5r5: - OUT_RING(chan, _(R_C0, G_C1, B_C2, A_ONE, 1_5_5_5)); + PUSH_DATA (push, _(R_C0, G_C1, B_C2, A_ONE, 1_5_5_5)); break; case PICT_a1r5g5b5: - OUT_RING(chan, _(B_C0, G_C1, R_C2, A_C3, 1_5_5_5)); + PUSH_DATA (push, _(B_C0, G_C1, R_C2, A_C3, 1_5_5_5)); break; case PICT_a1b5g5r5: - OUT_RING(chan, _(R_C0, G_C1, B_C2, A_C3, 1_5_5_5)); + PUSH_DATA (push, _(R_C0, G_C1, B_C2, A_C3, 1_5_5_5)); break; case PICT_b5g6r5: - OUT_RING(chan, _(R_C0, G_C1, B_C2, A_ONE, 5_6_5)); + PUSH_DATA (push, _(R_C0, G_C1, B_C2, A_ONE, 5_6_5)); break; case PICT_b8g8r8x8: - OUT_RING(chan, _(A_ONE, R_C1, G_C2, B_C3, 8_8_8_8)); + PUSH_DATA (push, _(A_ONE, R_C1, G_C2, B_C3, 8_8_8_8)); break; case PICT_b8g8r8a8: - OUT_RING(chan, _(A_C0, R_C1, G_C2, B_C3, 8_8_8_8)); + PUSH_DATA (push, _(A_C0, R_C1, G_C2, B_C3, 8_8_8_8)); break; case PICT_a2b10g10r10: - OUT_RING(chan, _(R_C0, G_C1, B_C2, A_C3, 2_10_10_10)); + PUSH_DATA (push, _(R_C0, G_C1, B_C2, A_C3, 2_10_10_10)); break; case PICT_x2b10g10r10: - OUT_RING(chan, _(R_C0, G_C1, B_C2, A_ONE, 2_10_10_10)); + PUSH_DATA (push, _(R_C0, G_C1, B_C2, A_ONE, 2_10_10_10)); break; case PICT_x2r10g10b10: - OUT_RING(chan, _(B_C0, G_C1, R_C2, A_ONE, 2_10_10_10)); + PUSH_DATA (push, _(B_C0, G_C1, R_C2, A_ONE, 2_10_10_10)); break; case PICT_a2r10g10b10: - OUT_RING(chan, _(B_C0, G_C1, R_C2, A_C3, 2_10_10_10)); + PUSH_DATA (push, _(B_C0, G_C1, R_C2, A_C3, 2_10_10_10)); break; case PICT_x4r4g4b4: - OUT_RING(chan, _(B_C0, G_C1, R_C2, A_ONE, 4_4_4_4)); + PUSH_DATA (push, _(B_C0, G_C1, R_C2, A_ONE, 4_4_4_4)); break; case PICT_x4b4g4r4: - OUT_RING(chan, _(R_C0, G_C1, B_C2, A_ONE, 4_4_4_4)); + PUSH_DATA (push, _(R_C0, G_C1, B_C2, A_ONE, 4_4_4_4)); break; case PICT_a4r4g4b4: - OUT_RING(chan, _(B_C0, G_C1, R_C2, A_C3, 4_4_4_4)); + PUSH_DATA (push, _(B_C0, G_C1, R_C2, A_C3, 4_4_4_4)); break; case PICT_a4b4g4r4: - OUT_RING(chan, _(R_C0, G_C1, B_C2, A_C3, 4_4_4_4)); + PUSH_DATA (push, _(R_C0, G_C1, B_C2, A_C3, 4_4_4_4)); break; default: NOUVEAU_FALLBACK("invalid picture format, this SHOULD NOT HAPPEN. Expect trouble.\n"); } #undef _ - mode = 0xd0005000 | (bo->tile_mode << 22); - if (OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD) || - OUT_RELOCd(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | - NOUVEAU_BO_HIGH | NOUVEAU_BO_OR, mode, mode)) - return FALSE; - OUT_RING (chan, 0x00300000); - OUT_RING (chan, ppix->drawable.width); - OUT_RING (chan, (1 << NV50TIC_0_5_DEPTH_SHIFT) | ppix->drawable.height); - OUT_RING (chan, 0x03000000); - OUT_RING (chan, 0x00000000); - - BEGIN_NV04(chan, NV50_3D(TSC_ADDRESS_HIGH), 3); - if (OUT_RELOCh(chan, pNv->tesla_scratch, TSC_OFFSET, tcb_flags) || - OUT_RELOCl(chan, pNv->tesla_scratch, TSC_OFFSET, tcb_flags)) - return FALSE; - OUT_RING (chan, 0x00000000); - BEGIN_NV04(chan, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); - if (OUT_RELOCh(chan, pNv->tesla_scratch, TSC_OFFSET, tcb_flags) || - OUT_RELOCl(chan, pNv->tesla_scratch, TSC_OFFSET, tcb_flags)) - return FALSE; - OUT_RING (chan, (CB_TSC << NV50_3D_CB_DEF_SET_BUFFER__SHIFT) | 0x4000); - BEGIN_NV04(chan, NV50_3D(CB_ADDR), 1); - OUT_RING (chan, CB_TSC | ((unit * 8) << NV50_3D_CB_ADDR_ID__SHIFT)); - BEGIN_NI04(chan, NV50_3D(CB_DATA(0)), 8); + PUSH_DATA (push, bo->offset); + PUSH_DATA (push, (bo->offset >> 32) | + (bo->config.nv50.tile_mode << 18) | + 0xd0005000); + PUSH_DATA (push, 0x00300000); + PUSH_DATA (push, ppix->drawable.width); + PUSH_DATA (push, (1 << NV50TIC_0_5_DEPTH_SHIFT) | ppix->drawable.height); + PUSH_DATA (push, 0x03000000); + PUSH_DATA (push, 0x00000000); + + BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); + PUSH_DATA (push, (pNv->tesla_scratch->offset + TSC_OFFSET) >> 32); + PUSH_DATA (push, (pNv->tesla_scratch->offset + TSC_OFFSET)); + PUSH_DATA (push, (CB_TSC << NV50_3D_CB_DEF_SET_BUFFER__SHIFT) | 0x4000); + BEGIN_NV04(push, NV50_3D(CB_ADDR), 1); + PUSH_DATA (push, CB_TSC | ((unit * 8) << NV50_3D_CB_ADDR_ID__SHIFT)); + BEGIN_NI04(push, NV50_3D(CB_DATA(0)), 8); if (ppict->repeat) { switch (ppict->repeatType) { case RepeatPad: - OUT_RING (chan, NV50TSC_1_0_WRAPS_CLAMP | + PUSH_DATA (push, NV50TSC_1_0_WRAPS_CLAMP | NV50TSC_1_0_WRAPT_CLAMP | NV50TSC_1_0_WRAPR_CLAMP | 0x00024000); break; case RepeatReflect: - OUT_RING (chan, NV50TSC_1_0_WRAPS_MIRROR_REPEAT | + PUSH_DATA (push, NV50TSC_1_0_WRAPS_MIRROR_REPEAT | NV50TSC_1_0_WRAPT_MIRROR_REPEAT | NV50TSC_1_0_WRAPR_MIRROR_REPEAT | 0x00024000); break; case RepeatNormal: default: - OUT_RING (chan, NV50TSC_1_0_WRAPS_REPEAT | + PUSH_DATA (push, NV50TSC_1_0_WRAPS_REPEAT | NV50TSC_1_0_WRAPT_REPEAT | NV50TSC_1_0_WRAPR_REPEAT | 0x00024000); break; } } else { - OUT_RING (chan, NV50TSC_1_0_WRAPS_CLAMP_TO_BORDER | + PUSH_DATA (push, NV50TSC_1_0_WRAPS_CLAMP_TO_BORDER | NV50TSC_1_0_WRAPT_CLAMP_TO_BORDER | NV50TSC_1_0_WRAPR_CLAMP_TO_BORDER | 0x00024000); } if (ppict->filter == PictFilterBilinear) { - OUT_RING (chan, NV50TSC_1_1_MAGF_LINEAR | + PUSH_DATA (push, NV50TSC_1_1_MAGF_LINEAR | NV50TSC_1_1_MINF_LINEAR | NV50TSC_1_1_MIPF_NONE); } else { - OUT_RING (chan, NV50TSC_1_1_MAGF_NEAREST | + PUSH_DATA (push, NV50TSC_1_1_MAGF_NEAREST | NV50TSC_1_1_MINF_NEAREST | NV50TSC_1_1_MIPF_NONE); } - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); state->unit[unit].width = ppix->drawable.width; state->unit[unit].height = ppix->drawable.height; @@ -773,19 +719,19 @@ NV50EXABlend(PixmapPtr ppix, PicturePtr ppict, int op, int component_alpha) } if (sblend == BF(ONE) && dblend == BF(ZERO)) { - BEGIN_NV04(chan, NV50_3D(BLEND_ENABLE(0)), 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, NV50_3D(BLEND_ENABLE(0)), 1); + PUSH_DATA (push, 0); } else { - BEGIN_NV04(chan, NV50_3D(BLEND_ENABLE(0)), 1); - OUT_RING (chan, 1); - BEGIN_NV04(chan, NV50_3D(BLEND_EQUATION_RGB), 5); - OUT_RING (chan, NV50_3D_BLEND_EQUATION_RGB_FUNC_ADD); - OUT_RING (chan, sblend); - OUT_RING (chan, dblend); - OUT_RING (chan, NV50_3D_BLEND_EQUATION_ALPHA_FUNC_ADD); - OUT_RING (chan, sblend); - BEGIN_NV04(chan, NV50_3D(BLEND_FUNC_DST_ALPHA), 1); - OUT_RING (chan, dblend); + BEGIN_NV04(push, NV50_3D(BLEND_ENABLE(0)), 1); + PUSH_DATA (push, 1); + BEGIN_NV04(push, NV50_3D(BLEND_EQUATION_RGB), 5); + PUSH_DATA (push, NV50_3D_BLEND_EQUATION_RGB_FUNC_ADD); + PUSH_DATA (push, sblend); + PUSH_DATA (push, dblend); + PUSH_DATA (push, NV50_3D_BLEND_EQUATION_ALPHA_FUNC_ADD); + PUSH_DATA (push, sblend); + BEGIN_NV04(push, NV50_3D(BLEND_FUNC_DST_ALPHA), 1); + PUSH_DATA (push, dblend); } } @@ -816,104 +762,81 @@ NV50EXACheckComposite(int op, return TRUE; } -static void -NV50EXAStateCompositeResubmit(struct nouveau_channel *chan) -{ - ScrnInfoPtr pScrn = chan->user_private; - NVPtr pNv = NVPTR(pScrn); - - NV50EXAPrepareComposite(pNv->alu, pNv->pspict, pNv->pmpict, pNv->pdpict, - pNv->pspix, pNv->pmpix, pNv->pdpix); -} - Bool NV50EXAPrepareComposite(int op, PicturePtr pspict, PicturePtr pmpict, PicturePtr pdpict, PixmapPtr pspix, PixmapPtr pmpix, PixmapPtr pdpix) { NV50EXA_LOCALS(pspix); - const unsigned shd_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD; + struct nouveau_bo *src = nouveau_pixmap_bo(pspix); + struct nouveau_bo *dst = nouveau_pixmap_bo(pdpix); + struct nouveau_bo *mask = pmpix ? nouveau_pixmap_bo(pmpix) : NULL; - if (MARK_RING (chan, 144, 4 + 2 + 2 * 10)) - NOUVEAU_FALLBACK("ring space\n"); + if (!PUSH_SPACE(push, 256)) + NOUVEAU_FALLBACK("space\n"); - BEGIN_NV04(chan, SUBC_2D(0x0110), 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, SUBC_2D(0x0110), 1); + PUSH_DATA (push, 0); - if (!NV50EXARenderTarget(pdpix, pdpict)) { - MARK_UNDO(chan); + if (!NV50EXARenderTarget(pdpix, pdpict)) NOUVEAU_FALLBACK("render target invalid\n"); - } NV50EXABlend(pdpix, pdpict, op, pmpict && pmpict->componentAlpha && PICT_FORMAT_RGB(pmpict->format)); - BEGIN_NV04(chan, NV50_3D(VP_ADDRESS_HIGH), 2); - if (OUT_RELOCh(chan, pNv->tesla_scratch, PVP_OFFSET, shd_flags) || - OUT_RELOCl(chan, pNv->tesla_scratch, PVP_OFFSET, shd_flags)) { - MARK_UNDO(chan); - return FALSE; - } - - BEGIN_NV04(chan, NV50_3D(FP_ADDRESS_HIGH), 2); - if (OUT_RELOCh(chan, pNv->tesla_scratch, PFP_OFFSET, shd_flags) || - OUT_RELOCl(chan, pNv->tesla_scratch, PFP_OFFSET, shd_flags)) { - MARK_UNDO(chan); - return FALSE; - } - - if (!NV50EXATexture(pspix, pspict, 0)) { - MARK_UNDO(chan); + if (!NV50EXATexture(pspix, pspict, 0)) NOUVEAU_FALLBACK("src picture invalid\n"); - } if (pmpict) { - if (!NV50EXATexture(pmpix, pmpict, 1)) { - MARK_UNDO(chan); + if (!NV50EXATexture(pmpix, pmpict, 1)) NOUVEAU_FALLBACK("mask picture invalid\n"); - } state->have_mask = TRUE; - BEGIN_NV04(chan, NV50_3D(FP_START_ID), 1); + BEGIN_NV04(push, NV50_3D(FP_START_ID), 1); if (pdpict->format == PICT_a8) { - OUT_RING (chan, PFP_C_A8); + PUSH_DATA (push, PFP_C_A8); } else { if (pmpict->componentAlpha && PICT_FORMAT_RGB(pmpict->format)) { if (NV50EXABlendOp[op].src_alpha) - OUT_RING (chan, PFP_CCASA); + PUSH_DATA (push, PFP_CCASA); else - OUT_RING (chan, PFP_CCA); + PUSH_DATA (push, PFP_CCA); } else { - OUT_RING (chan, PFP_C); + PUSH_DATA (push, PFP_C); } } } else { state->have_mask = FALSE; - BEGIN_NV04(chan, NV50_3D(FP_START_ID), 1); + BEGIN_NV04(push, NV50_3D(FP_START_ID), 1); if (pdpict->format == PICT_a8) - OUT_RING (chan, PFP_S_A8); + PUSH_DATA (push, PFP_S_A8); else - OUT_RING (chan, PFP_S); + PUSH_DATA (push, PFP_S); + } + + BEGIN_NV04(push, SUBC_3D(0x1334), 1); + PUSH_DATA (push, 0); + + BEGIN_NV04(push, NV50_3D(BIND_TIC(2)), 1); + PUSH_DATA (push, 1); + BEGIN_NV04(push, NV50_3D(BIND_TIC(2)), 1); + PUSH_DATA (push, 0x203); + + PUSH_RESET(push); + PUSH_REFN (push, pNv->tesla_scratch, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); + PUSH_REFN (push, src, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + PUSH_REFN (push, dst, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + if (pmpict) + PUSH_REFN (push, mask, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + + nouveau_pushbuf_bufctx(push, pNv->bufctx); + if (nouveau_pushbuf_validate(push)) { + nouveau_pushbuf_bufctx(push, NULL); + NOUVEAU_FALLBACK("validate\n"); } - BEGIN_NV04(chan, SUBC_3D(0x1334), 1); - OUT_RING (chan, 0); - - BEGIN_NV04(chan, NV50_3D(BIND_TIC(2)), 1); - OUT_RING (chan, 1); - BEGIN_NV04(chan, NV50_3D(BIND_TIC(2)), 1); - OUT_RING (chan, 0x203); - - pNv->alu = op; - pNv->pspict = pspict; - pNv->pmpict = pmpict; - pNv->pdpict = pdpict; - pNv->pspix = pspix; - pNv->pmpix = pmpix; - pNv->pdpix = pdpix; - chan->flush_notify = NV50EXAStateCompositeResubmit; return TRUE; } @@ -945,12 +868,14 @@ NV50EXAComposite(PixmapPtr pdpix, int sx, int sy, int mx, int my, NV50EXA_LOCALS(pdpix); float sX0, sX1, sX2, sY0, sY1, sY2; - WAIT_RING (chan, 28); - BEGIN_NV04(chan, NV50_3D(SCISSOR_HORIZ(0)), 2); - OUT_RING (chan, (dx + w) << 16 | dx); - OUT_RING (chan, (dy + h) << 16 | dy); - BEGIN_NV04(chan, NV50_3D(VERTEX_BEGIN_GL), 1); - OUT_RING (chan, NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_TRIANGLES); + if (!PUSH_SPACE(push, 64)) + return; + + BEGIN_NV04(push, NV50_3D(SCISSOR_HORIZ(0)), 2); + PUSH_DATA (push, (dx + w) << 16 | dx); + PUSH_DATA (push, (dy + h) << 16 | dy); + BEGIN_NV04(push, NV50_3D(VERTEX_BEGIN_GL), 1); + PUSH_DATA (push, NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_TRIANGLES); NV50EXATransform(state->unit[0].transform, sx, sy + (h * 2), state->unit[0].width, state->unit[0].height, @@ -984,16 +909,15 @@ NV50EXAComposite(PixmapPtr pdpix, int sx, int sy, int mx, int my, VTX1s(pNv, sX2, sY2, dx + (w * 2), dy); } - BEGIN_NV04(chan, NV50_3D(VERTEX_END_GL), 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, NV50_3D(VERTEX_END_GL), 1); + PUSH_DATA (push, 0); } void NV50EXADoneComposite(PixmapPtr pdpix) { NV50EXA_LOCALS(pdpix); - - chan->flush_notify = NULL; + nouveau_pushbuf_bufctx(push, NULL); } Bool @@ -1003,38 +927,44 @@ NV50EXARectM2MF(NVPtr pNv, int w, int h, int cpp, struct nouveau_bo *dst, uint32_t dst_off, int dst_dom, int dst_pitch, int dst_h, int dst_x, int dst_y) { - struct nouveau_grobj *m2mf = pNv->NvMemFormat; - struct nouveau_channel *chan = m2mf->channel; - - if (src->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK) { - BEGIN_NV04(chan, NV50_M2MF(LINEAR_IN), 6); - OUT_RING (chan, 0); - OUT_RING (chan, src->tile_mode << 4); - OUT_RING (chan, src_pitch); - OUT_RING (chan, src_h); - OUT_RING (chan, 1); - OUT_RING (chan, 0); + struct nouveau_pushbuf *push = pNv->pushbuf; + struct nouveau_pushbuf_refn refs[] = { + { src, src_dom | NOUVEAU_BO_RD }, + { dst, dst_dom | NOUVEAU_BO_WR }, + }; + + if (!PUSH_SPACE(push, 64)) + return FALSE; + + if (src->config.nv50.memtype) { + BEGIN_NV04(push, NV50_M2MF(LINEAR_IN), 6); + PUSH_DATA (push, 0); + PUSH_DATA (push, src->config.nv50.tile_mode); + PUSH_DATA (push, src_pitch); + PUSH_DATA (push, src_h); + PUSH_DATA (push, 1); + PUSH_DATA (push, 0); } else { - BEGIN_NV04(chan, NV50_M2MF(LINEAR_IN), 1); - OUT_RING (chan, 1); - BEGIN_NV04(chan, NV03_M2MF(PITCH_IN), 1); - OUT_RING (chan, src_pitch); + BEGIN_NV04(push, NV50_M2MF(LINEAR_IN), 1); + PUSH_DATA (push, 1); + BEGIN_NV04(push, NV03_M2MF(PITCH_IN), 1); + PUSH_DATA (push, src_pitch); src_off += src_y * src_pitch + src_x * cpp; } - if (dst->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK) { - BEGIN_NV04(chan, NV50_M2MF(LINEAR_OUT), 6); - OUT_RING (chan, 0); - OUT_RING (chan, dst->tile_mode << 4); - OUT_RING (chan, dst_pitch); - OUT_RING (chan, dst_h); - OUT_RING (chan, 1); - OUT_RING (chan, 0); + if (dst->config.nv50.memtype) { + BEGIN_NV04(push, NV50_M2MF(LINEAR_OUT), 6); + PUSH_DATA (push, 0); + PUSH_DATA (push, dst->config.nv50.tile_mode); + PUSH_DATA (push, dst_pitch); + PUSH_DATA (push, dst_h); + PUSH_DATA (push, 1); + PUSH_DATA (push, 0); } else { - BEGIN_NV04(chan, NV50_M2MF(LINEAR_OUT), 1); - OUT_RING (chan, 1); - BEGIN_NV04(chan, NV03_M2MF(PITCH_OUT), 1); - OUT_RING (chan, dst_pitch); + BEGIN_NV04(push, NV50_M2MF(LINEAR_OUT), 1); + PUSH_DATA (push, 1); + BEGIN_NV04(push, NV03_M2MF(PITCH_OUT), 1); + PUSH_DATA (push, dst_pitch); dst_off += dst_y * dst_pitch + dst_x * cpp; } @@ -1043,42 +973,36 @@ NV50EXARectM2MF(NVPtr pNv, int w, int h, int cpp, if (line_count > 2047) line_count = 2047; - if (MARK_RING (chan, 32, 4)) + if (nouveau_pushbuf_space(push, 32, 0, 0) || + nouveau_pushbuf_refn (push, refs, 2)) return FALSE; - BEGIN_NV04(chan, NV50_M2MF(OFFSET_IN_HIGH), 2); - if (OUT_RELOCh(chan, src, src_off, src_dom | NOUVEAU_BO_RD) || - OUT_RELOCh(chan, dst, dst_off, dst_dom | NOUVEAU_BO_WR)) { - MARK_UNDO(chan); - return FALSE; - } - - BEGIN_NV04(chan, NV03_M2MF(OFFSET_IN), 2); - if (OUT_RELOCl(chan, src, src_off, src_dom | NOUVEAU_BO_RD) || - OUT_RELOCl(chan, dst, dst_off, dst_dom | NOUVEAU_BO_WR)) { - MARK_UNDO(chan); - return FALSE; - } + BEGIN_NV04(push, NV50_M2MF(OFFSET_IN_HIGH), 2); + PUSH_DATA (push, (src->offset + src_off) >> 32); + PUSH_DATA (push, (dst->offset + dst_off) >> 32); + BEGIN_NV04(push, NV03_M2MF(OFFSET_IN), 2); + PUSH_DATA (push, (src->offset + src_off)); + PUSH_DATA (push, (dst->offset + dst_off)); - if (src->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK) { - BEGIN_NV04(chan, NV50_M2MF(TILING_POSITION_IN), 1); - OUT_RING (chan, (src_y << 16) | (src_x * cpp)); + if (src->config.nv50.memtype) { + BEGIN_NV04(push, NV50_M2MF(TILING_POSITION_IN), 1); + PUSH_DATA (push, (src_y << 16) | (src_x * cpp)); } else { src_off += line_count * src_pitch; } - if (dst->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK) { - BEGIN_NV04(chan, NV50_M2MF(TILING_POSITION_OUT), 1); - OUT_RING (chan, (dst_y << 16) | (dst_x * cpp)); + if (dst->config.nv50.memtype) { + BEGIN_NV04(push, NV50_M2MF(TILING_POSITION_OUT), 1); + PUSH_DATA (push, (dst_y << 16) | (dst_x * cpp)); } else { dst_off += line_count * dst_pitch; } - BEGIN_NV04(chan, NV03_M2MF(LINE_LENGTH_IN), 4); - OUT_RING (chan, w * cpp); - OUT_RING (chan, line_count); - OUT_RING (chan, 0x00000101); - OUT_RING (chan, 0x00000000); + BEGIN_NV04(push, NV03_M2MF(LINE_LENGTH_IN), 4); + PUSH_DATA (push, w * cpp); + PUSH_DATA (push, line_count); + PUSH_DATA (push, 0x00000101); + PUSH_DATA (push, 0x00000000); src_y += line_count; dst_y += line_count; diff --git a/src/nv50_xv.c b/src/nv50_xv.c index a6ca941..a5a7c51 100644 --- a/src/nv50_xv.c +++ b/src/nv50_xv.c @@ -58,238 +58,176 @@ nv50_xv_check_image_put(PixmapPtr ppix) return TRUE; } -static Bool -nv50_xv_state_emit(PixmapPtr ppix, int id, struct nouveau_bo *src, - int packed_y, int uv, int src_w, int src_h) +int +nv50_xv_image_put(ScrnInfoPtr pScrn, + struct nouveau_bo *src, int packed_y, int uv, + int id, int src_pitch, BoxPtr dstBox, + int x1, int y1, int x2, int y2, + uint16_t width, uint16_t height, + uint16_t src_w, uint16_t src_h, + uint16_t drw_w, uint16_t drw_h, + RegionPtr clipBoxes, PixmapPtr ppix, + NVPortPrivPtr pPriv) { - ScrnInfoPtr pScrn = xf86Screens[ppix->drawable.pScreen->myNum]; NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; - struct nouveau_bo *bo = nouveau_pixmap_bo(ppix); - const unsigned shd_flags = NOUVEAU_BO_RD | NOUVEAU_BO_VRAM; - const unsigned tcb_flags = NOUVEAU_BO_RDWR | NOUVEAU_BO_VRAM; - uint32_t mode = 0xd0005000 | (src->tile_mode << 22); + struct nouveau_bo *dst = nouveau_pixmap_bo(ppix); + struct nouveau_pushbuf *push = pNv->pushbuf; + struct nouveau_pushbuf_refn refs[] = { + { pNv->tesla_scratch, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR }, + { src, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD }, + { dst, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR }, + }; + uint32_t mode = 0xd0005000 | (src->config.nv50.tile_mode << 18); + float X1, X2, Y1, Y2; + BoxPtr pbox; + int nbox; - if (MARK_RING(chan, 256, 18)) - return FALSE; + if (!nv50_xv_check_image_put(ppix)) + return BadMatch; - BEGIN_NV04(chan, NV50_3D(RT_ADDRESS_HIGH(0)), 5); - if (OUT_RELOCh(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR) || - OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR)) { - MARK_UNDO(chan); - return FALSE; - } + if (!PUSH_SPACE(push, 256)) + return BadImplementation; + + BEGIN_NV04(push, NV50_3D(RT_ADDRESS_HIGH(0)), 5); + PUSH_DATA (push, dst->offset >> 32); + PUSH_DATA (push, dst->offset); switch (ppix->drawable.bitsPerPixel) { - case 32: OUT_RING (chan, NV50_SURFACE_FORMAT_BGRA8_UNORM); break; - case 24: OUT_RING (chan, NV50_SURFACE_FORMAT_BGRX8_UNORM); break; - case 16: OUT_RING (chan, NV50_SURFACE_FORMAT_B5G6R5_UNORM); break; - case 15: OUT_RING (chan, NV50_SURFACE_FORMAT_BGR5_X1_UNORM); break; - } - OUT_RING (chan, bo->tile_mode << 4); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NV50_3D(RT_HORIZ(0)), 2); - OUT_RING (chan, ppix->drawable.width); - OUT_RING (chan, ppix->drawable.height); - BEGIN_NV04(chan, NV50_3D(RT_ARRAY_MODE), 1); - OUT_RING (chan, 1); - - BEGIN_NV04(chan, NV50_3D(BLEND_ENABLE(0)), 1); - OUT_RING (chan, 0); - - BEGIN_NV04(chan, NV50_3D(TIC_ADDRESS_HIGH), 3); - if (OUT_RELOCh(chan, pNv->tesla_scratch, TIC_OFFSET, tcb_flags) || - OUT_RELOCl(chan, pNv->tesla_scratch, TIC_OFFSET, tcb_flags)) { - MARK_UNDO(chan); - return FALSE; - } - OUT_RING (chan, 0x00000800); - BEGIN_NV04(chan, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); - if (OUT_RELOCh(chan, pNv->tesla_scratch, TIC_OFFSET, tcb_flags) || - OUT_RELOCl(chan, pNv->tesla_scratch, TIC_OFFSET, tcb_flags)) { - MARK_UNDO(chan); - return FALSE; + case 32: PUSH_DATA (push, NV50_SURFACE_FORMAT_BGRA8_UNORM); break; + case 24: PUSH_DATA (push, NV50_SURFACE_FORMAT_BGRX8_UNORM); break; + case 16: PUSH_DATA (push, NV50_SURFACE_FORMAT_B5G6R5_UNORM); break; + case 15: PUSH_DATA (push, NV50_SURFACE_FORMAT_BGR5_X1_UNORM); break; } - OUT_RING (chan, (CB_TIC << NV50_3D_CB_DEF_SET_BUFFER__SHIFT) | 0x4000); - BEGIN_NV04(chan, NV50_3D(CB_ADDR), 1); - OUT_RING (chan, CB_TIC); - BEGIN_NI04(chan, NV50_3D(CB_DATA(0)), 16); + PUSH_DATA (push, dst->config.nv50.tile_mode); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV50_3D(RT_HORIZ(0)), 2); + PUSH_DATA (push, ppix->drawable.width); + PUSH_DATA (push, ppix->drawable.height); + BEGIN_NV04(push, NV50_3D(RT_ARRAY_MODE), 1); + PUSH_DATA (push, 1); + + BEGIN_NV04(push, NV50_3D(BLEND_ENABLE(0)), 1); + PUSH_DATA (push, 0); + + BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); + PUSH_DATA (push, (pNv->tesla_scratch->offset + TIC_OFFSET) >> 32); + PUSH_DATA (push, (pNv->tesla_scratch->offset + TIC_OFFSET)); + PUSH_DATA (push, (CB_TIC << NV50_3D_CB_DEF_SET_BUFFER__SHIFT) | 0x4000); + BEGIN_NV04(push, NV50_3D(CB_ADDR), 1); + PUSH_DATA (push, CB_TIC); + BEGIN_NI04(push, NV50_3D(CB_DATA(0)), 16); if (id == FOURCC_YV12 || id == FOURCC_I420) { - OUT_RING (chan, NV50TIC_0_0_MAPA_C0 | NV50TIC_0_0_TYPEA_UNORM | + PUSH_DATA (push, NV50TIC_0_0_MAPA_C0 | NV50TIC_0_0_TYPEA_UNORM | NV50TIC_0_0_MAPB_ZERO | NV50TIC_0_0_TYPEB_UNORM | NV50TIC_0_0_MAPG_ZERO | NV50TIC_0_0_TYPEG_UNORM | NV50TIC_0_0_MAPR_ZERO | NV50TIC_0_0_TYPER_UNORM | NV50TIC_0_0_FMT_8); - if (OUT_RELOCl(chan, src, packed_y, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD) || - OUT_RELOC (chan, src, packed_y, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | - NOUVEAU_BO_HIGH | NOUVEAU_BO_OR, mode, mode)) { - MARK_UNDO(chan); - return FALSE; - } - OUT_RING (chan, 0x00300000); - OUT_RING (chan, src_w); - OUT_RING (chan, (1 << NV50TIC_0_5_DEPTH_SHIFT) | src_h); - OUT_RING (chan, 0x03000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, NV50TIC_0_0_MAPA_C1 | NV50TIC_0_0_TYPEA_UNORM | + PUSH_DATA (push, (src->offset + packed_y)); + PUSH_DATA (push, (src->offset + packed_y) >> 32 | mode); + PUSH_DATA (push, 0x00300000); + PUSH_DATA (push, width); + PUSH_DATA (push, (1 << NV50TIC_0_5_DEPTH_SHIFT) | height); + PUSH_DATA (push, 0x03000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, NV50TIC_0_0_MAPA_C1 | NV50TIC_0_0_TYPEA_UNORM | NV50TIC_0_0_MAPB_C0 | NV50TIC_0_0_TYPEB_UNORM | NV50TIC_0_0_MAPG_ZERO | NV50TIC_0_0_TYPEG_UNORM | NV50TIC_0_0_MAPR_ZERO | NV50TIC_0_0_TYPER_UNORM | NV50TIC_0_0_FMT_8_8); - if (OUT_RELOCl(chan, src, uv, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD) || - OUT_RELOC (chan, src, uv, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | - NOUVEAU_BO_HIGH | NOUVEAU_BO_OR, mode, mode)) { - MARK_UNDO(chan); - return FALSE; - } - OUT_RING (chan, 0x00300000); - OUT_RING (chan, src_w >> 1); - OUT_RING (chan, (1 << NV50TIC_0_5_DEPTH_SHIFT) | (src_h >> 1)); - OUT_RING (chan, 0x03000000); - OUT_RING (chan, 0x00000000); + PUSH_DATA (push, (src->offset + uv)); + PUSH_DATA (push, (src->offset + uv) >> 32 | mode); + PUSH_DATA (push, 0x00300000); + PUSH_DATA (push, width >> 1); + PUSH_DATA (push, (1 << NV50TIC_0_5_DEPTH_SHIFT) | (height >> 1)); + PUSH_DATA (push, 0x03000000); + PUSH_DATA (push, 0x00000000); } else { if (id == FOURCC_UYVY) { - OUT_RING (chan, NV50TIC_0_0_MAPA_C1 | NV50TIC_0_0_TYPEA_UNORM | + PUSH_DATA (push, NV50TIC_0_0_MAPA_C1 | NV50TIC_0_0_TYPEA_UNORM | NV50TIC_0_0_MAPB_ZERO | NV50TIC_0_0_TYPEB_UNORM | NV50TIC_0_0_MAPG_ZERO | NV50TIC_0_0_TYPEG_UNORM | NV50TIC_0_0_MAPR_ZERO | NV50TIC_0_0_TYPER_UNORM | NV50TIC_0_0_FMT_8_8); } else { - OUT_RING (chan, NV50TIC_0_0_MAPA_C0 | NV50TIC_0_0_TYPEA_UNORM | + PUSH_DATA (push, NV50TIC_0_0_MAPA_C0 | NV50TIC_0_0_TYPEA_UNORM | NV50TIC_0_0_MAPB_ZERO | NV50TIC_0_0_TYPEB_UNORM | NV50TIC_0_0_MAPG_ZERO | NV50TIC_0_0_TYPEG_UNORM | NV50TIC_0_0_MAPR_ZERO | NV50TIC_0_0_TYPER_UNORM | NV50TIC_0_0_FMT_8_8); } - if (OUT_RELOCl(chan, src, packed_y, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD) || - OUT_RELOC (chan, src, packed_y, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | - NOUVEAU_BO_HIGH | NOUVEAU_BO_OR, mode, mode)) { - MARK_UNDO(chan); - return FALSE; - } - OUT_RING (chan, 0x00300000); - OUT_RING (chan, src_w); - OUT_RING (chan, (1 << NV50TIC_0_5_DEPTH_SHIFT) | src_h); - OUT_RING (chan, 0x03000000); - OUT_RING (chan, 0x00000000); + PUSH_DATA (push, (src->offset + packed_y)); + PUSH_DATA (push, (src->offset + packed_y) >> 32 | mode); + PUSH_DATA (push, 0x00300000); + PUSH_DATA (push, width); + PUSH_DATA (push, (1 << NV50TIC_0_5_DEPTH_SHIFT) | height); + PUSH_DATA (push, 0x03000000); + PUSH_DATA (push, 0x00000000); if (id == FOURCC_UYVY) { - OUT_RING (chan, NV50TIC_0_0_MAPA_C2 | NV50TIC_0_0_TYPEA_UNORM | + PUSH_DATA (push, NV50TIC_0_0_MAPA_C2 | NV50TIC_0_0_TYPEA_UNORM | NV50TIC_0_0_MAPB_C0 | NV50TIC_0_0_TYPEB_UNORM | NV50TIC_0_0_MAPG_ZERO | NV50TIC_0_0_TYPEG_UNORM | NV50TIC_0_0_MAPR_ZERO | NV50TIC_0_0_TYPER_UNORM | NV50TIC_0_0_FMT_8_8_8_8); } else { - OUT_RING (chan, NV50TIC_0_0_MAPA_C3 | NV50TIC_0_0_TYPEA_UNORM | + PUSH_DATA (push, NV50TIC_0_0_MAPA_C3 | NV50TIC_0_0_TYPEA_UNORM | NV50TIC_0_0_MAPB_C1 | NV50TIC_0_0_TYPEB_UNORM | NV50TIC_0_0_MAPG_ZERO | NV50TIC_0_0_TYPEG_UNORM | NV50TIC_0_0_MAPR_ZERO | NV50TIC_0_0_TYPER_UNORM | NV50TIC_0_0_FMT_8_8_8_8); } - if (OUT_RELOCl(chan, src, packed_y, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD) || - OUT_RELOC (chan, src, packed_y, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | - NOUVEAU_BO_HIGH | NOUVEAU_BO_OR, mode, mode)) { - MARK_UNDO(chan); - return FALSE; - } - OUT_RING (chan, 0x00300000); - OUT_RING (chan, (src_w >> 1)); - OUT_RING (chan, (1 << NV50TIC_0_5_DEPTH_SHIFT) | src_h); - OUT_RING (chan, 0x03000000); - OUT_RING (chan, 0x00000000); + PUSH_DATA (push, (src->offset + packed_y)); + PUSH_DATA (push, (src->offset + packed_y) >> 32 | mode); + PUSH_DATA (push, 0x00300000); + PUSH_DATA (push, (width >> 1)); + PUSH_DATA (push, (1 << NV50TIC_0_5_DEPTH_SHIFT) | height); + PUSH_DATA (push, 0x03000000); + PUSH_DATA (push, 0x00000000); } - BEGIN_NV04(chan, NV50_3D(TSC_ADDRESS_HIGH), 3); - if (OUT_RELOCh(chan, pNv->tesla_scratch, TSC_OFFSET, tcb_flags) || - OUT_RELOCl(chan, pNv->tesla_scratch, TSC_OFFSET, tcb_flags)) { - MARK_UNDO(chan); - return FALSE; - } - OUT_RING (chan, 0x00000000); - BEGIN_NV04(chan, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); - if (OUT_RELOCh(chan, pNv->tesla_scratch, TSC_OFFSET, tcb_flags) || - OUT_RELOCl(chan, pNv->tesla_scratch, TSC_OFFSET, tcb_flags)) { - MARK_UNDO(chan); - return FALSE; - } - OUT_RING (chan, (CB_TSC << NV50_3D_CB_DEF_SET_BUFFER__SHIFT) | 0x4000); - BEGIN_NV04(chan, NV50_3D(CB_ADDR), 1); - OUT_RING (chan, CB_TSC); - BEGIN_NI04(chan, NV50_3D(CB_DATA(0)), 16); - OUT_RING (chan, NV50TSC_1_0_WRAPS_CLAMP_TO_EDGE | + BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); + PUSH_DATA (push, (pNv->tesla_scratch->offset + TSC_OFFSET) >> 32); + PUSH_DATA (push, (pNv->tesla_scratch->offset + TSC_OFFSET)); + PUSH_DATA (push, (CB_TSC << NV50_3D_CB_DEF_SET_BUFFER__SHIFT) | 0x4000); + BEGIN_NV04(push, NV50_3D(CB_ADDR), 1); + PUSH_DATA (push, CB_TSC); + BEGIN_NI04(push, NV50_3D(CB_DATA(0)), 16); + PUSH_DATA (push, NV50TSC_1_0_WRAPS_CLAMP_TO_EDGE | NV50TSC_1_0_WRAPT_CLAMP_TO_EDGE | NV50TSC_1_0_WRAPR_CLAMP_TO_EDGE); - OUT_RING (chan, NV50TSC_1_1_MAGF_LINEAR | + PUSH_DATA (push, NV50TSC_1_1_MAGF_LINEAR | NV50TSC_1_1_MINF_LINEAR | NV50TSC_1_1_MIPF_NONE); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, NV50TSC_1_0_WRAPS_CLAMP_TO_EDGE | + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, NV50TSC_1_0_WRAPS_CLAMP_TO_EDGE | NV50TSC_1_0_WRAPT_CLAMP_TO_EDGE | NV50TSC_1_0_WRAPR_CLAMP_TO_EDGE); - OUT_RING (chan, NV50TSC_1_1_MAGF_LINEAR | + PUSH_DATA (push, NV50TSC_1_1_MAGF_LINEAR | NV50TSC_1_1_MINF_LINEAR | NV50TSC_1_1_MIPF_NONE); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - - BEGIN_NV04(chan, NV50_3D(VP_ADDRESS_HIGH), 2); - if (OUT_RELOCh(chan, pNv->tesla_scratch, PVP_OFFSET, shd_flags) || - OUT_RELOCl(chan, pNv->tesla_scratch, PVP_OFFSET, shd_flags)) { - MARK_UNDO(chan); - return FALSE; - } - BEGIN_NV04(chan, NV50_3D(FP_ADDRESS_HIGH), 2); - if (OUT_RELOCh(chan, pNv->tesla_scratch, PFP_OFFSET, shd_flags) || - OUT_RELOCl(chan, pNv->tesla_scratch, PFP_OFFSET, shd_flags)) { - MARK_UNDO(chan); - return FALSE; - } - BEGIN_NV04(chan, NV50_3D(FP_START_ID), 1); - OUT_RING (chan, PFP_NV12); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); - BEGIN_NV04(chan, SUBC_3D(0x1334), 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, NV50_3D(FP_START_ID), 1); + PUSH_DATA (push, PFP_NV12); - BEGIN_NV04(chan, NV50_3D(BIND_TIC(2)), 1); - OUT_RING (chan, 1); - BEGIN_NV04(chan, NV50_3D(BIND_TIC(2)), 1); - OUT_RING (chan, 0x203); - - return TRUE; -} - -int -nv50_xv_image_put(ScrnInfoPtr pScrn, - struct nouveau_bo *src, int packed_y, int uv, - int id, int src_pitch, BoxPtr dstBox, - int x1, int y1, int x2, int y2, - uint16_t width, uint16_t height, - uint16_t src_w, uint16_t src_h, - uint16_t drw_w, uint16_t drw_h, - RegionPtr clipBoxes, PixmapPtr ppix, - NVPortPrivPtr pPriv) -{ - NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; - float X1, X2, Y1, Y2; - BoxPtr pbox; - int nbox; + BEGIN_NV04(push, SUBC_3D(0x1334), 1); + PUSH_DATA (push, 0); - if (!nv50_xv_check_image_put(ppix)) - return BadMatch; - if (!nv50_xv_state_emit(ppix, id, src, packed_y, uv, width, height)) - return BadAlloc; + BEGIN_NV04(push, NV50_3D(BIND_TIC(2)), 1); + PUSH_DATA (push, 1); + BEGIN_NV04(push, NV50_3D(BIND_TIC(2)), 1); + PUSH_DATA (push, 0x203); - if (pPriv->SyncToVBlank) { + if (pPriv->SyncToVBlank) NV50SyncToVBlank(ppix, dstBox); - } /* These are fixed point values in the 16.16 format. */ X1 = (float)(x1>>16)+(float)(x1&0xFFFF)/(float)0x10000; @@ -314,32 +252,30 @@ nv50_xv_image_put(ScrnInfoPtr pScrn, ty1 = ty1 / height; ty2 = ty2 / height; - if (AVAIL_RING(chan) < 64) { - if (!nv50_xv_state_emit(ppix, id, src, packed_y, uv, - width, height)) - return BadAlloc; - } + if (nouveau_pushbuf_space(push, 64, 0, 0) || + nouveau_pushbuf_refn (push, refs, 3)) + return BadImplementation; /* NV50_3D_SCISSOR_VERT_T_SHIFT is wrong, because it was deducted with * origin lying at the bottom left. This will be changed to _MIN_ and _MAX_ * later, because it is origin dependent. */ - BEGIN_NV04(chan, NV50_3D(SCISSOR_HORIZ(0)), 2); - OUT_RING (chan, sx2 << NV50_3D_SCISSOR_HORIZ_MAX__SHIFT | sx1); - OUT_RING (chan, sy2 << NV50_3D_SCISSOR_VERT_MAX__SHIFT | sy1 ); + BEGIN_NV04(push, NV50_3D(SCISSOR_HORIZ(0)), 2); + PUSH_DATA (push, sx2 << NV50_3D_SCISSOR_HORIZ_MAX__SHIFT | sx1); + PUSH_DATA (push, sy2 << NV50_3D_SCISSOR_VERT_MAX__SHIFT | sy1 ); - BEGIN_NV04(chan, NV50_3D(VERTEX_BEGIN_GL), 1); - OUT_RING (chan, NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_TRIANGLES); + BEGIN_NV04(push, NV50_3D(VERTEX_BEGIN_GL), 1); + PUSH_DATA (push, NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_TRIANGLES); VTX2s(pNv, tx1, ty1, tx1, ty1, sx1, sy1); VTX2s(pNv, tx2+(tx2-tx1), ty1, tx2+(tx2-tx1), ty1, sx2+(sx2-sx1), sy1); VTX2s(pNv, tx1, ty2+(ty2-ty1), tx1, ty2+(ty2-ty1), sx1, sy2+(sy2-sy1)); - BEGIN_NV04(chan, NV50_3D(VERTEX_END_GL), 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, NV50_3D(VERTEX_END_GL), 1); + PUSH_DATA (push, 0); pbox++; } - FIRE_RING (chan); + PUSH_KICK(push); return Success; } @@ -371,7 +307,7 @@ void nv50_xv_csc_update(ScrnInfoPtr pScrn, NVPortPrivPtr pPriv) { NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; const float Loff = -0.0627; const float Coff = -0.502; float yco, off[3], uco[3], vco[3]; @@ -400,31 +336,30 @@ nv50_xv_csc_update(ScrnInfoPtr pScrn, NVPortPrivPtr pPriv) return; } - if (MARK_RING(chan, 64, 2)) + if (nouveau_pushbuf_space(push, 64, 0, 0) || + nouveau_pushbuf_refn (push, &(struct nouveau_pushbuf_refn) { + pNv->tesla_scratch, NOUVEAU_BO_WR | + NOUVEAU_BO_VRAM }, 1)) return; - BEGIN_NV04(chan, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); - if (OUT_RELOCh(chan, pNv->tesla_scratch, PFP_DATA, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR) || - OUT_RELOCl(chan, pNv->tesla_scratch, PFP_DATA, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR)) { - MARK_UNDO(chan); - return; - } - OUT_RING (chan, (CB_PFP << NV50_3D_CB_DEF_SET_BUFFER__SHIFT) | 0x4000); - BEGIN_NV04(chan, NV50_3D(CB_ADDR), 1); - OUT_RING (chan, CB_PFP); - BEGIN_NI04(chan, NV50_3D(CB_DATA(0)), 10); - OUT_RINGf (chan, yco); - OUT_RINGf (chan, off[0]); - OUT_RINGf (chan, off[1]); - OUT_RINGf (chan, off[2]); - OUT_RINGf (chan, uco[0]); - OUT_RINGf (chan, uco[1]); - OUT_RINGf (chan, uco[2]); - OUT_RINGf (chan, vco[0]); - OUT_RINGf (chan, vco[1]); - OUT_RINGf (chan, vco[2]); + BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); + PUSH_DATA (push, (pNv->tesla_scratch->offset + PFP_DATA) >> 32); + PUSH_DATA (push, (pNv->tesla_scratch->offset + PFP_DATA)); + PUSH_DATA (push, (CB_PFP << NV50_3D_CB_DEF_SET_BUFFER__SHIFT) | + 0x00004000); + BEGIN_NV04(push, NV50_3D(CB_ADDR), 1); + PUSH_DATA (push, CB_PFP); + BEGIN_NI04(push, NV50_3D(CB_DATA(0)), 10); + PUSH_DATAf(push, yco); + PUSH_DATAf(push, off[0]); + PUSH_DATAf(push, off[1]); + PUSH_DATAf(push, off[2]); + PUSH_DATAf(push, uco[0]); + PUSH_DATAf(push, uco[1]); + PUSH_DATAf(push, uco[2]); + PUSH_DATAf(push, vco[0]); + PUSH_DATAf(push, vco[1]); + PUSH_DATAf(push, vco[2]); } void diff --git a/src/nv_accel_common.c b/src/nv_accel_common.c index 51cc66a..09272b9 100644 --- a/src/nv_accel_common.c +++ b/src/nv_accel_common.c @@ -26,6 +26,7 @@ #include "hwdefs/nv_m2mf.xml.h" #include "hwdefs/nv01_2d.xml.h" #include "hwdefs/nv50_2d.xml.h" +#include "nv04_accel.h" Bool nouveau_allocate_surface(ScrnInfoPtr scrn, int width, int height, int bpp, @@ -34,7 +35,7 @@ nouveau_allocate_surface(ScrnInfoPtr scrn, int width, int height, int bpp, NVPtr pNv = NVPTR(scrn); Bool scanout = (usage_hint & NOUVEAU_CREATE_PIXMAP_SCANOUT); Bool tiled = (usage_hint & NOUVEAU_CREATE_PIXMAP_TILED); - int tile_mode = 0, tile_flags = 0; + union nouveau_bo_config cfg = {}; int flags = NOUVEAU_BO_MAP | (bpp >= 8 ? NOUVEAU_BO_VRAM : 0); int cpp = bpp / 8, ret; @@ -59,69 +60,62 @@ nouveau_allocate_surface(ScrnInfoPtr scrn, int width, int height, int bpp, if (tiled) { if (pNv->Architecture >= NV_ARCH_C0) { - if (height > 64) - tile_mode = 0x40; - else if (height > 32) - tile_mode = 0x30; - else if (height > 16) - tile_mode = 0x20; - else if (height > 8) - tile_mode = 0x10; - else - tile_mode = 0x00; + if (height > 64) cfg.nvc0.tile_mode = 0x040; + else if (height > 32) cfg.nvc0.tile_mode = 0x030; + else if (height > 16) cfg.nvc0.tile_mode = 0x020; + else if (height > 8) cfg.nvc0.tile_mode = 0x010; + else cfg.nvc0.tile_mode = 0x000; if (usage_hint & NOUVEAU_CREATE_PIXMAP_ZETA) - tile_flags = (bpp == 16) ? 0x0100 : 0x1100; /* Z16 : Z24S8 */ + cfg.nvc0.memtype = (bpp == 16) ? 0x01 : 0x11; else - tile_flags = 0xfe00; + cfg.nvc0.memtype = 0xfe; - height = NOUVEAU_ALIGN( - height, NVC0_TILE_HEIGHT(tile_mode)); + height = NOUVEAU_ALIGN(height, + NVC0_TILE_HEIGHT(cfg.nv50.tile_mode)); } else if (pNv->Architecture >= NV_ARCH_50) { - if (height > 32) - tile_mode = 4; - else if (height > 16) - tile_mode = 3; - else if (height > 8) - tile_mode = 2; - else if (height > 4) - tile_mode = 1; - else - tile_mode = 0; + if (height > 32) cfg.nv50.tile_mode = 0x040; + else if (height > 16) cfg.nv50.tile_mode = 0x030; + else if (height > 8) cfg.nv50.tile_mode = 0x020; + else if (height > 4) cfg.nv50.tile_mode = 0x010; + else cfg.nv50.tile_mode = 0x000; if (usage_hint & NOUVEAU_CREATE_PIXMAP_ZETA) - tile_flags = (bpp == 16) ? 0x26c00 : 0x22800; + cfg.nv50.memtype = (bpp == 16) ? 0x16c : 0x128; else if (usage_hint & NOUVEAU_CREATE_PIXMAP_SCANOUT) - tile_flags = (bpp == 16 ? 0x7000 : 0x7a00); + cfg.nv50.memtype = (bpp == 16) ? 0x070 : 0x07a; else - tile_flags = 0x7000; + cfg.nv50.memtype = 0x070; - height = NOUVEAU_ALIGN(height, 1 << (tile_mode + 2)); + height = NOUVEAU_ALIGN(height, + NV50_TILE_HEIGHT(cfg.nv50.tile_mode)); } else { int pitch_align = max( pNv->dev->chipset >= 0x40 ? 1024 : 256, round_down_pow2(*pitch / 4)); - tile_mode = *pitch = - NOUVEAU_ALIGN(*pitch, pitch_align); + *pitch = NOUVEAU_ALIGN(*pitch, pitch_align); + cfg.nv04.surf_pitch = *pitch; } } - if (bpp == 32) - tile_flags |= NOUVEAU_BO_TILE_32BPP; - else if (bpp == 16) - tile_flags |= NOUVEAU_BO_TILE_16BPP; - - if (usage_hint & NOUVEAU_CREATE_PIXMAP_ZETA) - tile_flags |= NOUVEAU_BO_TILE_ZETA; + if (pNv->Architecture < NV_ARCH_50) { + if (bpp == 16) + cfg.nv04.surf_flags |= NV04_BO_16BPP; + if (bpp == 32) + cfg.nv04.surf_flags |= NV04_BO_32BPP; + if (usage_hint & NOUVEAU_CREATE_PIXMAP_ZETA) + cfg.nv04.surf_flags |= NV04_BO_ZETA; + } if (usage_hint & NOUVEAU_CREATE_PIXMAP_SCANOUT) - tile_flags |= NOUVEAU_BO_TILE_SCANOUT; + flags |= NOUVEAU_BO_CONTIG; - ret = nouveau_bo_new_tile(pNv->dev, flags, 0, *pitch * height, - tile_mode, tile_flags, bo); - if (ret) + ret = nouveau_bo_new(pNv->dev, flags, 0, *pitch * height, &cfg, bo); + if (ret) { + ErrorF("%d\n", ret); return FALSE; + } return TRUE; } @@ -131,7 +125,7 @@ NV11SyncToVBlank(PixmapPtr ppix, BoxPtr box) { ScrnInfoPtr pScrn = xf86Screens[ppix->drawable.pScreen->myNum]; NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; int crtcs; if (!nouveau_exa_pixmap_is_onscreen(ppix)) @@ -143,76 +137,90 @@ NV11SyncToVBlank(PixmapPtr ppix, BoxPtr box) if (!crtcs) return; - BEGIN_NV04(chan, SUBC_BLIT(0x0000012C), 1); - OUT_RING (chan, 0); - BEGIN_NV04(chan, SUBC_BLIT(0x00000134), 1); - OUT_RING (chan, ffs(crtcs) - 1); - BEGIN_NV04(chan, SUBC_BLIT(0x00000100), 1); - OUT_RING (chan, 0); - BEGIN_NV04(chan, SUBC_BLIT(0x00000130), 1); - OUT_RING (chan, 0); + if (!PUSH_SPACE(push, 8)) + return; + + BEGIN_NV04(push, SUBC_BLIT(0x0000012C), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, SUBC_BLIT(0x00000134), 1); + PUSH_DATA (push, ffs(crtcs) - 1); + BEGIN_NV04(push, SUBC_BLIT(0x00000100), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, SUBC_BLIT(0x00000130), 1); + PUSH_DATA (push, 0); } static Bool NVAccelInitDmaNotifier0(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); + struct nouveau_object *chan = pNv->channel; + struct nv04_notify ntfy = { .length = 32 }; - if (!pNv->notify0) { - if (nouveau_notifier_alloc(pNv->chan, NvDmaNotifier0, 1, - &pNv->notify0)) - return FALSE; - } + if (nouveau_object_new(chan, NvDmaNotifier0, NOUVEAU_NOTIFIER_CLASS, + &ntfy, sizeof(ntfy), &pNv->notify0)) + return FALSE; + + return TRUE; +} + +static Bool +NVAccelInitNull(ScrnInfoPtr pScrn) +{ + NVPtr pNv = NVPTR(pScrn); + + if (nouveau_object_new(pNv->channel, NvNullObject, NV01_NULL_CLASS, + NULL, 0, &pNv->NvNull)) + return FALSE; return TRUE; } -/* FLAGS_ROP_AND, DmaFB, DmaFB, 0 */ static Bool NVAccelInitContextSurfaces(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; + struct nv04_fifo *fifo = pNv->channel->data; uint32_t class; class = (pNv->Architecture >= NV_ARCH_10) ? NV10_SURFACE_2D_CLASS : NV04_SURFACE_2D_CLASS; - if (!pNv->NvContextSurfaces) { - if (nouveau_grobj_alloc(chan, NvContextSurfaces, class, - &pNv->NvContextSurfaces)) - return FALSE; - } + if (nouveau_object_new(pNv->channel, NvContextSurfaces, class, + NULL, 0, &pNv->NvContextSurfaces)) + return FALSE; - BEGIN_NV04(chan, NV01_SUBC(SF2D, OBJECT), 1); - OUT_RING (chan, pNv->NvContextSurfaces->handle); - BEGIN_NV04(chan, NV04_SF2D(DMA_NOTIFY), 1); - OUT_RING (chan, chan->nullobj->handle); - BEGIN_NV04(chan, NV04_SF2D(DMA_IMAGE_SOURCE), 2); - OUT_RING (chan, pNv->chan->vram->handle); - OUT_RING (chan, pNv->chan->vram->handle); + if (!PUSH_SPACE(push, 8)) + return FALSE; + BEGIN_NV04(push, NV01_SUBC(SF2D, OBJECT), 1); + PUSH_DATA (push, pNv->NvContextSurfaces->handle); + BEGIN_NV04(push, NV04_SF2D(DMA_NOTIFY), 1); + PUSH_DATA (push, pNv->NvNull->handle); + BEGIN_NV04(push, NV04_SF2D(DMA_IMAGE_SOURCE), 2); + PUSH_DATA (push, fifo->vram); + PUSH_DATA (push, fifo->vram); return TRUE; } -/* FLAGS_ROP_AND, DmaFB, DmaFB, 0 */ static Bool NVAccelInitContextBeta1(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; - if (!pNv->NvContextBeta1) { - if (nouveau_grobj_alloc(chan, NvContextBeta1, 0x12, - &pNv->NvContextBeta1)) - return FALSE; - } + if (nouveau_object_new(pNv->channel, NvContextBeta1, NV01_BETA_CLASS, + NULL, 0, &pNv->NvContextBeta1)) + return FALSE; - BEGIN_NV04(chan, NV01_SUBC(MISC, OBJECT), 1); - OUT_RING (chan, pNv->NvContextBeta1->handle); - BEGIN_NV04(chan, NV01_BETA(BETA_1D31), 1); /*alpha factor*/ - OUT_RING (chan, 0xff << 23); + if (!PUSH_SPACE(push, 4)) + return FALSE; + BEGIN_NV04(push, NV01_SUBC(MISC, OBJECT), 1); + PUSH_DATA (push, pNv->NvContextBeta1->handle); + BEGIN_NV04(push, NV01_BETA(BETA_1D31), 1); /*alpha factor*/ + PUSH_DATA (push, 0xff << 23); return TRUE; } @@ -221,18 +229,19 @@ static Bool NVAccelInitContextBeta4(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; - if (!pNv->NvContextBeta4) { - if (nouveau_grobj_alloc(chan, NvContextBeta4, 0x72, - &pNv->NvContextBeta4)) - return FALSE; - } + if (nouveau_object_new(pNv->channel, NvContextBeta4, NV04_BETA4_CLASS, + NULL, 0, &pNv->NvContextBeta4)) + return FALSE; - BEGIN_NV04(chan, NV01_SUBC(MISC, OBJECT), 1); - OUT_RING (chan, pNv->NvContextBeta4->handle); - BEGIN_NV04(chan, NV04_BETA4(BETA_FACTOR), 1); /*RGBA factor*/ - OUT_RING (chan, 0xffff0000); + if (!PUSH_SPACE(push, 4)) + return FALSE; + + BEGIN_NV04(push, NV01_SUBC(MISC, OBJECT), 1); + PUSH_DATA (push, pNv->NvContextBeta4->handle); + BEGIN_NV04(push, NV04_BETA4(BETA_FACTOR), 1); /*RGBA factor*/ + PUSH_DATA (push, 0xffff0000); return TRUE; } @@ -299,27 +308,27 @@ static Bool NVAccelInitImagePattern(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; - if (!pNv->NvImagePattern) { - if (nouveau_grobj_alloc(chan, NvImagePattern, - NV04_PATTERN_CLASS, - &pNv->NvImagePattern)) - return FALSE; - } + if (nouveau_object_new(pNv->channel, NvImagePattern, NV04_PATTERN_CLASS, + NULL, 0, &pNv->NvImagePattern)) + return FALSE; + + if (!PUSH_SPACE(push, 8)) + return FALSE; - BEGIN_NV04(chan, NV01_SUBC(MISC, OBJECT), 1); - OUT_RING (chan, pNv->NvImagePattern->handle); - BEGIN_NV04(chan, NV01_PATT(DMA_NOTIFY), 1); - OUT_RING (chan, chan->nullobj->handle); - BEGIN_NV04(chan, NV01_PATT(MONOCHROME_FORMAT), 3); + BEGIN_NV04(push, NV01_SUBC(MISC, OBJECT), 1); + PUSH_DATA (push, pNv->NvImagePattern->handle); + BEGIN_NV04(push, NV01_PATT(DMA_NOTIFY), 1); + PUSH_DATA (push, pNv->NvNull->handle); + BEGIN_NV04(push, NV01_PATT(MONOCHROME_FORMAT), 3); #if X_BYTE_ORDER == X_BIG_ENDIAN - OUT_RING (chan, NV01_PATTERN_MONOCHROME_FORMAT_LE); + PUSH_DATA (push, NV01_PATTERN_MONOCHROME_FORMAT_LE); #else - OUT_RING (chan, NV01_PATTERN_MONOCHROME_FORMAT_CGA6); + PUSH_DATA (push, NV01_PATTERN_MONOCHROME_FORMAT_CGA6); #endif - OUT_RING (chan, NV01_PATTERN_MONOCHROME_SHAPE_8X8); - OUT_RING (chan, NV04_PATTERN_PATTERN_SELECT_MONO); + PUSH_DATA (push, NV01_PATTERN_MONOCHROME_SHAPE_8X8); + PUSH_DATA (push, NV04_PATTERN_PATTERN_SELECT_MONO); return TRUE; } @@ -328,18 +337,19 @@ static Bool NVAccelInitRasterOp(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; - if (!pNv->NvRop) { - if (nouveau_grobj_alloc(chan, NvRop, NV03_ROP_CLASS, - &pNv->NvRop)) - return FALSE; - } + if (nouveau_object_new(pNv->channel, NvRop, NV03_ROP_CLASS, + NULL, 0, &pNv->NvRop)) + return FALSE; - BEGIN_NV04(chan, NV01_SUBC(MISC, OBJECT), 1); - OUT_RING (chan, pNv->NvRop->handle); - BEGIN_NV04(chan, NV01_ROP(DMA_NOTIFY), 1); - OUT_RING (chan, chan->nullobj->handle); + if (!PUSH_SPACE(push, 4)) + return FALSE; + + BEGIN_NV04(push, NV01_SUBC(MISC, OBJECT), 1); + PUSH_DATA (push, pNv->NvRop->handle); + BEGIN_NV04(push, NV01_ROP(DMA_NOTIFY), 1); + PUSH_DATA (push, pNv->NvNull->handle); pNv->currentRop = ~0; return TRUE; @@ -349,34 +359,35 @@ static Bool NVAccelInitRectangle(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; - if (!pNv->NvRectangle) { - if (nouveau_grobj_alloc(chan, NvRectangle, NV04_GDI_CLASS, - &pNv->NvRectangle)) - return FALSE; - } + if (nouveau_object_new(pNv->channel, NvRectangle, NV04_GDI_CLASS, + NULL, 0, &pNv->NvRectangle)) + return FALSE; + + if (!PUSH_SPACE(push, 16)) + return FALSE; - BEGIN_NV04(chan, NV01_SUBC(RECT, OBJECT), 1); - OUT_RING (chan, pNv->NvRectangle->handle); - BEGIN_NV04(chan, NV04_RECT(DMA_NOTIFY), 1); - OUT_RING (chan, pNv->notify0->handle); - BEGIN_NV04(chan, NV04_RECT(DMA_FONTS), 1); - OUT_RING (chan, chan->nullobj->handle); - BEGIN_NV04(chan, NV04_RECT(SURFACE), 1); - OUT_RING (chan, pNv->NvContextSurfaces->handle); - BEGIN_NV04(chan, NV04_RECT(ROP), 1); - OUT_RING (chan, pNv->NvRop->handle); - BEGIN_NV04(chan, NV04_RECT(PATTERN), 1); - OUT_RING (chan, pNv->NvImagePattern->handle); - BEGIN_NV04(chan, NV04_RECT(OPERATION), 1); - OUT_RING (chan, NV04_GDI_OPERATION_ROP_AND); - BEGIN_NV04(chan, NV04_RECT(MONOCHROME_FORMAT), 1); + BEGIN_NV04(push, NV01_SUBC(RECT, OBJECT), 1); + PUSH_DATA (push, pNv->NvRectangle->handle); + BEGIN_NV04(push, NV04_RECT(DMA_NOTIFY), 1); + PUSH_DATA (push, pNv->notify0->handle); + BEGIN_NV04(push, NV04_RECT(DMA_FONTS), 1); + PUSH_DATA (push, pNv->NvNull->handle); + BEGIN_NV04(push, NV04_RECT(SURFACE), 1); + PUSH_DATA (push, pNv->NvContextSurfaces->handle); + BEGIN_NV04(push, NV04_RECT(ROP), 1); + PUSH_DATA (push, pNv->NvRop->handle); + BEGIN_NV04(push, NV04_RECT(PATTERN), 1); + PUSH_DATA (push, pNv->NvImagePattern->handle); + BEGIN_NV04(push, NV04_RECT(OPERATION), 1); + PUSH_DATA (push, NV04_GDI_OPERATION_ROP_AND); + BEGIN_NV04(push, NV04_RECT(MONOCHROME_FORMAT), 1); /* XXX why putting 1 like renouveau dump, swap the text */ #if 1 || X_BYTE_ORDER == X_BIG_ENDIAN - OUT_RING (chan, NV04_GDI_MONOCHROME_FORMAT_LE); + PUSH_DATA (push, NV04_GDI_MONOCHROME_FORMAT_LE); #else - OUT_RING (chan, NV04_GDI_MONOCHROME_FORMAT_CGA6); + PUSH_DATA (push, NV04_GDI_MONOCHROME_FORMAT_CGA6); #endif return TRUE; @@ -386,36 +397,37 @@ static Bool NVAccelInitImageBlit(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; uint32_t class; class = (pNv->dev->chipset >= 0x11) ? NV15_BLIT_CLASS : NV04_BLIT_CLASS; - if (!pNv->NvImageBlit) { - if (nouveau_grobj_alloc(chan, NvImageBlit, class, - &pNv->NvImageBlit)) - return FALSE; - } + if (nouveau_object_new(pNv->channel, NvImageBlit, class, + NULL, 0, &pNv->NvImageBlit)) + return FALSE; + + if (!PUSH_SPACE(push, 16)) + return FALSE; - BEGIN_NV04(chan, NV01_SUBC(BLIT, OBJECT), 1); - OUT_RING (chan, pNv->NvImageBlit->handle); - BEGIN_NV04(chan, NV01_BLIT(DMA_NOTIFY), 1); - OUT_RING (chan, pNv->notify0->handle); - BEGIN_NV04(chan, NV01_BLIT(COLOR_KEY), 1); - OUT_RING (chan, chan->nullobj->handle); - BEGIN_NV04(chan, NV04_BLIT(SURFACES), 1); - OUT_RING (chan, pNv->NvContextSurfaces->handle); - BEGIN_NV04(chan, NV01_BLIT(CLIP), 3); - OUT_RING (chan, chan->nullobj->handle); - OUT_RING (chan, pNv->NvImagePattern->handle); - OUT_RING (chan, pNv->NvRop->handle); - BEGIN_NV04(chan, NV01_BLIT(OPERATION), 1); - OUT_RING (chan, NV01_BLIT_OPERATION_ROP_AND); - if (pNv->NvImageBlit->grclass == NV15_BLIT_CLASS) { - BEGIN_NV04(chan, NV15_BLIT(FLIP_SET_READ), 3); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - OUT_RING (chan, 2); + BEGIN_NV04(push, NV01_SUBC(BLIT, OBJECT), 1); + PUSH_DATA (push, pNv->NvImageBlit->handle); + BEGIN_NV04(push, NV01_BLIT(DMA_NOTIFY), 1); + PUSH_DATA (push, pNv->notify0->handle); + BEGIN_NV04(push, NV01_BLIT(COLOR_KEY), 1); + PUSH_DATA (push, pNv->NvNull->handle); + BEGIN_NV04(push, NV04_BLIT(SURFACES), 1); + PUSH_DATA (push, pNv->NvContextSurfaces->handle); + BEGIN_NV04(push, NV01_BLIT(CLIP), 3); + PUSH_DATA (push, pNv->NvNull->handle); + PUSH_DATA (push, pNv->NvImagePattern->handle); + PUSH_DATA (push, pNv->NvRop->handle); + BEGIN_NV04(push, NV01_BLIT(OPERATION), 1); + PUSH_DATA (push, NV01_BLIT_OPERATION_ROP_AND); + if (pNv->NvImageBlit->oclass == NV15_BLIT_CLASS) { + BEGIN_NV04(push, NV15_BLIT(FLIP_SET_READ), 3); + PUSH_DATA (push, 0); + PUSH_DATA (push, 1); + PUSH_DATA (push, 2); } return TRUE; @@ -425,7 +437,8 @@ static Bool NVAccelInitScaledImage(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; + struct nv04_fifo *fifo = pNv->channel->data; uint32_t class; switch (pNv->Architecture) { @@ -443,28 +456,29 @@ NVAccelInitScaledImage(ScrnInfoPtr pScrn) break; } - if (!pNv->NvScaledImage) { - if (nouveau_grobj_alloc(chan, NvScaledImage, class, - &pNv->NvScaledImage)) - return FALSE; - } + if (nouveau_object_new(pNv->channel, NvScaledImage, class, + NULL, 0, &pNv->NvScaledImage)) + return FALSE; - BEGIN_NV04(chan, NV01_SUBC(MISC, OBJECT), 1); - OUT_RING (chan, pNv->NvScaledImage->handle); - BEGIN_NV04(chan, NV03_SIFM(DMA_NOTIFY), 7); - OUT_RING (chan, pNv->notify0->handle); - OUT_RING (chan, pNv->chan->vram->handle); - OUT_RING (chan, chan->nullobj->handle); - OUT_RING (chan, chan->nullobj->handle); - OUT_RING (chan, pNv->NvContextBeta1->handle); - OUT_RING (chan, pNv->NvContextBeta4->handle); - OUT_RING (chan, pNv->NvContextSurfaces->handle); + if (!PUSH_SPACE(push, 16)) + return FALSE; + + BEGIN_NV04(push, NV01_SUBC(MISC, OBJECT), 1); + PUSH_DATA (push, pNv->NvScaledImage->handle); + BEGIN_NV04(push, NV03_SIFM(DMA_NOTIFY), 7); + PUSH_DATA (push, pNv->notify0->handle); + PUSH_DATA (push, fifo->vram); + PUSH_DATA (push, pNv->NvNull->handle); + PUSH_DATA (push, pNv->NvNull->handle); + PUSH_DATA (push, pNv->NvContextBeta1->handle); + PUSH_DATA (push, pNv->NvContextBeta4->handle); + PUSH_DATA (push, pNv->NvContextSurfaces->handle); if (pNv->Architecture>=NV_ARCH_10) { - BEGIN_NV04(chan, NV05_SIFM(COLOR_CONVERSION), 1); - OUT_RING (chan, NV05_SIFM_COLOR_CONVERSION_DITHER); + BEGIN_NV04(push, NV05_SIFM(COLOR_CONVERSION), 1); + PUSH_DATA (push, NV05_SIFM_COLOR_CONVERSION_DITHER); } - BEGIN_NV04(chan, NV03_SIFM(OPERATION), 1); - OUT_RING (chan, NV03_SIFM_OPERATION_SRCCOPY); + BEGIN_NV04(push, NV03_SIFM(OPERATION), 1); + PUSH_DATA (push, NV03_SIFM_OPERATION_SRCCOPY); return TRUE; } @@ -473,50 +487,39 @@ static Bool NVAccelInitClipRectangle(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; - if (!pNv->NvClipRectangle) { - if (nouveau_grobj_alloc(pNv->chan, NvClipRectangle, - NV01_CLIP_CLASS, - &pNv->NvClipRectangle)) - return FALSE; - } + if (nouveau_object_new(pNv->channel, NvClipRectangle, NV01_CLIP_CLASS, + NULL, 0, &pNv->NvClipRectangle)) + return FALSE; - BEGIN_NV04(chan, NV01_SUBC(MISC, OBJECT), 1); - OUT_RING (chan, pNv->NvClipRectangle->handle); - BEGIN_NV04(chan, NV01_CLIP(DMA_NOTIFY), 1); - OUT_RING (chan, chan->nullobj->handle); + if (!PUSH_SPACE(push, 4)) + return FALSE; + BEGIN_NV04(push, NV01_SUBC(MISC, OBJECT), 1); + PUSH_DATA (push, pNv->NvClipRectangle->handle); + BEGIN_NV04(push, NV01_CLIP(DMA_NOTIFY), 1); + PUSH_DATA (push, pNv->NvNull->handle); return TRUE; } -/* FLAGS_NONE, NvDmaFB, NvDmaAGP, NvDmaNotifier0 */ static Bool NVAccelInitMemFormat(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; - uint32_t class; - - if (pNv->Architecture < NV_ARCH_50) - class = NV03_M2MF_CLASS; - else - class = NV50_M2MF_CLASS; + struct nouveau_pushbuf *push = pNv->pushbuf; - if (!pNv->NvMemFormat) { - if (nouveau_grobj_alloc(chan, NvMemFormat, class, - &pNv->NvMemFormat)) - return FALSE; - } + if (nouveau_object_new(pNv->channel, NvMemFormat, NV03_M2MF_CLASS, + NULL, 0, &pNv->NvMemFormat)) + return FALSE; - BEGIN_NV04(chan, NV01_SUBC(M2MF, OBJECT), 1); - OUT_RING (chan, pNv->NvMemFormat->handle); - BEGIN_NV04(chan, NV03_M2MF(DMA_NOTIFY), 1); - OUT_RING (chan, pNv->notify0->handle); - BEGIN_NV04(chan, NV03_M2MF(DMA_BUFFER_IN), 2); - OUT_RING (chan, chan->vram->handle); - OUT_RING (chan, chan->vram->handle); + if (!PUSH_SPACE(push, 4)) + return FALSE; + BEGIN_NV04(push, NV01_SUBC(M2MF, OBJECT), 1); + PUSH_DATA (push, pNv->NvMemFormat->handle); + BEGIN_NV04(push, NV03_M2MF(DMA_NOTIFY), 1); + PUSH_DATA (push, pNv->notify0->handle); return TRUE; } @@ -524,7 +527,7 @@ static Bool NVAccelInitImageFromCpu(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; uint32_t class; switch (pNv->Architecture) { @@ -540,67 +543,33 @@ NVAccelInitImageFromCpu(ScrnInfoPtr pScrn) break; } - if (!pNv->NvImageFromCpu) { - if (nouveau_grobj_alloc(chan, NvImageFromCpu, class, - &pNv->NvImageFromCpu)) - return FALSE; - } - - BEGIN_NV04(chan, NV01_SUBC(IFC, OBJECT), 1); - OUT_RING (chan, pNv->NvImageFromCpu->handle); - BEGIN_NV04(chan, NV01_IFC(DMA_NOTIFY), 1); - OUT_RING (chan, pNv->notify0->handle); - BEGIN_NV04(chan, NV01_IFC(CLIP), 1); - OUT_RING (chan, chan->nullobj->handle); - BEGIN_NV04(chan, NV01_IFC(PATTERN), 1); - OUT_RING (chan, chan->nullobj->handle); - BEGIN_NV04(chan, NV01_IFC(ROP), 1); - OUT_RING (chan, chan->nullobj->handle); - if (pNv->Architecture >= NV_ARCH_10) { - BEGIN_NV04(chan, NV01_IFC(BETA), 1); - OUT_RING (chan, chan->nullobj->handle); - BEGIN_NV04(chan, NV04_IFC(BETA4), 1); - OUT_RING (chan, chan->nullobj->handle); - } - BEGIN_NV04(chan, NV04_IFC(SURFACE), 1); - OUT_RING (chan, pNv->NvContextSurfaces->handle); - BEGIN_NV04(chan, NV01_IFC(OPERATION), 1); - OUT_RING (chan, NV01_IFC_OPERATION_SRCCOPY); - - return TRUE; -} + if (nouveau_object_new(pNv->channel, NvImageFromCpu, class, + NULL, 0, &pNv->NvImageFromCpu)) + return FALSE; -static Bool -NVAccelInit2D_NV50(ScrnInfoPtr pScrn) -{ - NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; + if (!PUSH_SPACE(push, 16)) + return FALSE; - if (!pNv->Nv2D) { - if (nouveau_grobj_alloc(chan, Nv2D, NV50_2D_CLASS, &pNv->Nv2D)) - return FALSE; + BEGIN_NV04(push, NV01_SUBC(IFC, OBJECT), 1); + PUSH_DATA (push, pNv->NvImageFromCpu->handle); + BEGIN_NV04(push, NV01_IFC(DMA_NOTIFY), 1); + PUSH_DATA (push, pNv->notify0->handle); + BEGIN_NV04(push, NV01_IFC(CLIP), 1); + PUSH_DATA (push, pNv->NvNull->handle); + BEGIN_NV04(push, NV01_IFC(PATTERN), 1); + PUSH_DATA (push, pNv->NvNull->handle); + BEGIN_NV04(push, NV01_IFC(ROP), 1); + PUSH_DATA (push, pNv->NvNull->handle); + if (pNv->Architecture >= NV_ARCH_10) { + BEGIN_NV04(push, NV01_IFC(BETA), 1); + PUSH_DATA (push, pNv->NvNull->handle); + BEGIN_NV04(push, NV04_IFC(BETA4), 1); + PUSH_DATA (push, pNv->NvNull->handle); } - - BEGIN_NV04(chan, NV01_SUBC(2D, OBJECT), 1); - OUT_RING (chan, pNv->Nv2D->handle); - BEGIN_NV04(chan, NV50_2D(DMA_NOTIFY), 3); - OUT_RING (chan, pNv->notify0->handle); - OUT_RING (chan, pNv->chan->vram->handle); - OUT_RING (chan, pNv->chan->vram->handle); - - /* Magics from nv, no clue what they do, but at least some - * of them are needed to avoid crashes. - */ - BEGIN_NV04(chan, SUBC_2D(0x0260), 1); - OUT_RING (chan, 1); - BEGIN_NV04(chan, NV50_2D(CLIP_ENABLE), 1); - OUT_RING (chan, 1); - BEGIN_NV04(chan, NV50_2D(COLOR_KEY_ENABLE), 1); - OUT_RING (chan, 0); - BEGIN_NV04(chan, SUBC_2D(0x058c), 1); - OUT_RING (chan, 0x111); - - pNv->currentRop = 0xfffffffa; + BEGIN_NV04(push, NV04_IFC(SURFACE), 1); + PUSH_DATA (push, pNv->NvContextSurfaces->handle); + BEGIN_NV04(push, NV01_IFC(OPERATION), 1); + PUSH_DATA (push, NV01_IFC_OPERATION_SRCCOPY); return TRUE; } @@ -624,8 +593,10 @@ NVAccelCommonInit(ScrnInfoPtr pScrn) return TRUE; /* General engine objects */ - if (pNv->Architecture < NV_ARCH_C0) + if (pNv->Architecture < NV_ARCH_C0) { INIT_CONTEXT_OBJECT(DmaNotifier0); + INIT_CONTEXT_OBJECT(Null); + } /* 2D engine */ if (pNv->Architecture < NV_ARCH_50) { @@ -646,8 +617,11 @@ NVAccelCommonInit(ScrnInfoPtr pScrn) INIT_CONTEXT_OBJECT(2D_NVC0); } - if (pNv->Architecture < NV_ARCH_C0) + if (pNv->Architecture < NV_ARCH_50) INIT_CONTEXT_OBJECT(MemFormat); + else + if (pNv->Architecture < NV_ARCH_C0) + INIT_CONTEXT_OBJECT(M2MF_NV50); else INIT_CONTEXT_OBJECT(M2MF_NVC0); @@ -683,23 +657,23 @@ void NVAccelFree(ScrnInfoPtr pScrn) if (pNv->NoAccel) return; - nouveau_notifier_free(&pNv->notify0); - nouveau_notifier_free(&pNv->vblank_sem); - - nouveau_grobj_free(&pNv->NvContextSurfaces); - nouveau_grobj_free(&pNv->NvContextBeta1); - nouveau_grobj_free(&pNv->NvContextBeta4); - nouveau_grobj_free(&pNv->NvImagePattern); - nouveau_grobj_free(&pNv->NvRop); - nouveau_grobj_free(&pNv->NvRectangle); - nouveau_grobj_free(&pNv->NvImageBlit); - nouveau_grobj_free(&pNv->NvScaledImage); - nouveau_grobj_free(&pNv->NvClipRectangle); - nouveau_grobj_free(&pNv->NvImageFromCpu); - nouveau_grobj_free(&pNv->Nv2D); - nouveau_grobj_free(&pNv->NvMemFormat); - nouveau_grobj_free(&pNv->NvSW); - nouveau_grobj_free(&pNv->Nv3D); + nouveau_object_del(&pNv->notify0); + nouveau_object_del(&pNv->vblank_sem); + + nouveau_object_del(&pNv->NvContextSurfaces); + nouveau_object_del(&pNv->NvContextBeta1); + nouveau_object_del(&pNv->NvContextBeta4); + nouveau_object_del(&pNv->NvImagePattern); + nouveau_object_del(&pNv->NvRop); + nouveau_object_del(&pNv->NvRectangle); + nouveau_object_del(&pNv->NvImageBlit); + nouveau_object_del(&pNv->NvScaledImage); + nouveau_object_del(&pNv->NvClipRectangle); + nouveau_object_del(&pNv->NvImageFromCpu); + nouveau_object_del(&pNv->Nv2D); + nouveau_object_del(&pNv->NvMemFormat); + nouveau_object_del(&pNv->NvSW); + nouveau_object_del(&pNv->Nv3D); nouveau_bo_ref(NULL, &pNv->tesla_scratch); nouveau_bo_ref(NULL, &pNv->shader_mem); diff --git a/src/nv_dma.c b/src/nv_dma.c index 49ed40a..3b75ca9 100644 --- a/src/nv_dma.c +++ b/src/nv_dma.c @@ -24,46 +24,55 @@ #include #include "nv_include.h" -static void -NVLockedUp(ScrnInfoPtr pScrn) -{ - NVPtr pNv = NVPTR(pScrn); - - /* avoid re-entering FatalError on shutdown */ - if (pNv->LockedUp) - return; - pNv->LockedUp = TRUE; - - FatalError("Detected GPU lockup\n"); -} - -static void -NVChannelHangNotify(struct nouveau_channel *chan) -{ - ScrnInfoPtr pScrn = chan->user_private; - - NVLockedUp(pScrn); -} - Bool NVInitDma(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); - int ret; + struct nv04_fifo nv04_data = { .vram = NvDmaFB, + .gart = NvDmaTT }; + struct nvc0_fifo nvc0_data = { }; + struct nouveau_object *device = &pNv->dev->object; + struct nouveau_fifo *fifo; + int size, ret; + void *data; + + if (pNv->Architecture < NV_ARCH_C0) { + data = &nv04_data; + size = sizeof(nv04_data); + } else { + data = &nvc0_data; + size = sizeof(nvc0_data); + } - ret = nouveau_channel_alloc(pNv->dev, NvDmaFB, NvDmaTT, 24*1024, - &pNv->chan); + ret = nouveau_object_new(device, 0, NOUVEAU_FIFO_CHANNEL_CLASS, + data, size, &pNv->channel); if (ret) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Error creating GPU channel: %d\n", ret); return FALSE; } - pNv->chan->user_private = pScrn; - pNv->chan->hang_notify = NVChannelHangNotify; + + fifo = pNv->channel->data; xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Opened GPU channel %d\n", pNv->chan->id); + "Opened GPU channel %d\n", fifo->channel); + + ret = nouveau_pushbuf_new(pNv->client, pNv->channel, 4, 32 * 1024, + true, &pNv->pushbuf); + if (ret) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Error allocating DMA push buffer: %d\n",ret); + NVTakedownDma(pScrn); + return FALSE; + } + ret = nouveau_bufctx_new(pNv->client, 1, &pNv->bufctx); + if (ret) { + NVTakedownDma(pScrn); + return FALSE; + } + + pNv->pushbuf->user_priv = pNv->bufctx; return TRUE; } @@ -71,12 +80,16 @@ void NVTakedownDma(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); + if (pNv->channel) { + struct nouveau_fifo *fifo = pNv->channel->data; + int chid = fifo->channel; - if (!pNv->chan) - return; + nouveau_bufctx_del(&pNv->bufctx); + nouveau_pushbuf_del(&pNv->pushbuf); + nouveau_object_del(&pNv->channel); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Closed GPU channel %d\n", pNv->chan->id); - nouveau_channel_free(&pNv->chan); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Closed GPU channel %d\n", chid); + } } diff --git a/src/nv_dma.h b/src/nv_dma.h index d21ff39..a386104 100644 --- a/src/nv_dma.h +++ b/src/nv_dma.h @@ -20,8 +20,8 @@ enum DMAObjects { NvContextBeta4 = 0x8000001C, Nv2D = 0x80000020, NvSW = 0x80000021, - NvDmaFB = 0xD8000001, - NvDmaTT = 0xD8000002, + NvDmaFB = 0xbeef0201, + NvDmaTT = 0xbeef0202, NvDmaNotifier0 = 0xD8000003, NvVBlankSem = 0xD8000004, }; diff --git a/src/nv_driver.c b/src/nv_driver.c index 56865e2..9f6d75f 100644 --- a/src/nv_driver.c +++ b/src/nv_driver.c @@ -24,8 +24,6 @@ #include "nv_include.h" -#include "nouveau_pushbuf.h" - #include "xorg-server.h" #include "xf86int10.h" #include "xf86drm.h" @@ -224,7 +222,7 @@ NVPciProbe(DriverPtr drv, int entity_num, struct pci_device *pci_dev, } busid = DRICreatePCIBusID(pci_dev); - ret = nouveau_device_open(&dev, busid); + ret = nouveau_device_open(busid, &dev); if (ret) { xf86DrvMsg(-1, X_ERROR, "[drm] failed to open device\n"); free(busid); @@ -236,14 +234,14 @@ NVPciProbe(DriverPtr drv, int entity_num, struct pci_device *pci_dev, * But, we're currently using the kernel patchlevel to also version * the DRI interface. */ - version = drmGetVersion(nouveau_device(dev)->fd); + version = drmGetVersion(dev->fd); xf86DrvMsg(-1, X_INFO, "[drm] nouveau interface version: %d.%d.%d\n", version->version_major, version->version_minor, version->version_patchlevel); drmFree(version); chipset = dev->chipset; - nouveau_device_close(&dev); + nouveau_device_del(&dev); ret = drmCheckModesettingSupported(busid); free(busid); @@ -337,7 +335,7 @@ NVEnterVT(int scrnIndex, int flags) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVEnterVT is called.\n"); - ret = drmSetMaster(nouveau_device(pNv->dev)->fd); + ret = drmSetMaster(pNv->dev->fd); if (ret) ErrorF("Unable to get master: %s\n", strerror(errno)); @@ -365,7 +363,7 @@ NVLeaveVT(int scrnIndex, int flags) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVLeaveVT is called.\n"); - ret = drmDropMaster(nouveau_device(pNv->dev)->fd); + ret = drmDropMaster(pNv->dev->fd); if (ret) ErrorF("Error dropping master: %d\n", ret); } @@ -377,7 +375,7 @@ NVFlushCallback(CallbackListPtr *list, pointer user_data, pointer call_data) NVPtr pNv = NVPTR(pScrn); if (pScrn->vtSema && !pNv->NoAccel) - FIRE_RING (pNv->chan); + nouveau_pushbuf_kick(pNv->pushbuf, pNv->pushbuf->channel); } static void @@ -397,7 +395,7 @@ NVBlockHandler ( pScreen->BlockHandler = NVBlockHandler; if (pScrn->vtSema && !pNv->NoAccel) - FIRE_RING (pNv->chan); + nouveau_pushbuf_kick(pNv->pushbuf, pNv->pushbuf->channel); if (pNv->VideoTimerCallback) (*pNv->VideoTimerCallback)(pScrn, currentTime.milliseconds); @@ -526,7 +524,7 @@ NVCloseDRM(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); - nouveau_device_close(&pNv->dev); + nouveau_device_del(&pNv->dev); drmFree(pNv->drm_device_name); } @@ -585,13 +583,17 @@ NVPreInitDRM(ScrnInfoPtr pScrn) } /* Initialise libdrm_nouveau */ - ret = nouveau_device_open_existing(&pNv->dev, 1, DRIMasterFD(pScrn), 0); + ret = nouveau_device_wrap(DRIMasterFD(pScrn), 1, &pNv->dev); if (ret) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[drm] error creating device\n"); return FALSE; } + ret = nouveau_client_new(pNv->dev, &pNv->client); + if (ret) + return FALSE; + pNv->drm_device_name = drmGetDeviceNameFromFd(DRIMasterFD(pScrn)); return TRUE; @@ -709,7 +711,7 @@ NVPreInit(ScrnInfoPtr pScrn, int flags) * The first thing we should figure out is the depth, bpp, etc. */ - if (dev->vm_vram_size <= 16 * 1024 * 1024) + if (dev->vram_size <= 16 * 1024 * 1024) defaultDepth = 16; if (!xf86SetDepthBpp(pScrn, defaultDepth, 0, 0, Support32bppFb)) { NVPreInitFail("\n"); @@ -830,8 +832,7 @@ NVPreInit(ScrnInfoPtr pScrn, int flags) reason = ": no kernel support"; from = X_DEFAULT; - ret = nouveau_device_get_param(pNv->dev, - NOUVEAU_GETPARAM_HAS_PAGEFLIP, &v); + ret = nouveau_getparam(pNv->dev, NOUVEAU_GETPARAM_HAS_PAGEFLIP, &v); if (ret == 0 && v == 1) { pNv->has_pageflip = TRUE; if (xf86GetOptValBool(pNv->Options, OPTION_PAGE_FLIP, &pNv->has_pageflip)) @@ -886,8 +887,7 @@ NVPreInit(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, from, "Swap limit set to %d [Max allowed %d]%s\n", pNv->swap_limit, pNv->max_swap_limit, reason); - ret = drmmode_pre_init(pScrn, nouveau_device(pNv->dev)->fd, - pScrn->bitsPerPixel >> 3); + ret = drmmode_pre_init(pScrn, pNv->dev->fd, pScrn->bitsPerPixel >> 3); if (ret == FALSE) NVPreInitFail("Kernel modesetting failed to initialize\n"); @@ -959,15 +959,15 @@ NVMapMem(ScrnInfoPtr pScrn) return TRUE; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "GART: %dMiB available\n", - (unsigned int)(dev->vm_gart_size >> 20)); - if (dev->vm_gart_size > (16 * 1024 * 1024)) + (unsigned int)(dev->gart_size >> 20)); + if (dev->gart_size > (16 * 1024 * 1024)) size = 16 * 1024 * 1024; else /* always leave 512kb for other things like the fifos */ - size = dev->vm_gart_size - 512*1024; + size = dev->gart_size - 512*1024; if (nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, - 0, size, &pNv->GART)) { + 0, size, NULL, &pNv->GART)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to allocate GART memory\n"); } @@ -1139,9 +1139,8 @@ NVScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (pNv->NoAccel) { pNv->ShadowPtr = NULL; displayWidth = pScrn->displayWidth; - nouveau_bo_map(pNv->scanout, NOUVEAU_BO_RDWR); + nouveau_bo_map(pNv->scanout, NOUVEAU_BO_RDWR, pNv->client); FBStart = pNv->scanout->map; - nouveau_bo_unmap(pNv->scanout); } else { pNv->ShadowPtr = NULL; displayWidth = pScrn->displayWidth; diff --git a/src/nv_include.h b/src/nv_include.h index 407b7c9..0d104a3 100644 --- a/src/nv_include.h +++ b/src/nv_include.h @@ -63,18 +63,11 @@ #define NV_DMA_DEBUG 0 +#include "nouveau_local.h" + #include "nv_type.h" #include "nv_proto.h" #include "nv_dma.h" #include "sarea.h" -#include "nouveau_drmif.h" -#include "nouveau_device.h" -#include "nouveau_channel.h" -#include "nouveau_bo.h" -#include "nouveau_grobj.h" -#include "nouveau_notifier.h" -#include "nouveau_local.h" -#include "nouveau_pushbuf.h" - #endif /* __NV_INCLUDE_H__ */ diff --git a/src/nv_proto.h b/src/nv_proto.h index 8bf2fc1..88cd870 100644 --- a/src/nv_proto.h +++ b/src/nv_proto.h @@ -142,6 +142,8 @@ int NV40SetTexturePortAttribute(ScrnInfoPtr, Atom, INT32, pointer); /* in nv50_accel.c */ void NV50SyncToVBlank(PixmapPtr ppix, BoxPtr box); +Bool NVAccelInitM2MF_NV50(ScrnInfoPtr pScrn); +Bool NVAccelInit2D_NV50(ScrnInfoPtr pScrn); Bool NVAccelInitNV50TCL(ScrnInfoPtr pScrn); /* in nvc0_accel.c */ diff --git a/src/nv_shadow.c b/src/nv_shadow.c index 58a569f..67d9ea5 100644 --- a/src/nv_shadow.c +++ b/src/nv_shadow.c @@ -39,7 +39,7 @@ NVRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) FBPitch = pScrn->displayWidth * cpp; max_height = pNv->scanout->size/FBPitch; - nouveau_bo_map(pNv->scanout, NOUVEAU_BO_WR); + nouveau_bo_map(pNv->scanout, NOUVEAU_BO_WR, pNv->client); while(num--) { x1 = MAX(pbox->x1, 0); y1 = MAX(pbox->y1, 0); @@ -61,5 +61,4 @@ NVRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) pbox++; } - nouveau_bo_unmap(pNv->scanout); } diff --git a/src/nv_type.h b/src/nv_type.h index c8f27ac..1ba3e4e 100644 --- a/src/nv_type.h +++ b/src/nv_type.h @@ -11,7 +11,6 @@ #include "dri.h" #include #include -#include "nouveau_device.h" #include "xf86Crtc.h" #else #error "This driver requires a DRI-enabled X server" @@ -82,36 +81,35 @@ typedef struct _NVRec { char *drm_device_name; /* GPU context */ - struct nouveau_channel *chan; - struct nouveau_notifier *notify0; - struct nouveau_notifier *vblank_sem; - struct nouveau_grobj *NvContextSurfaces; - struct nouveau_grobj *NvContextBeta1; - struct nouveau_grobj *NvContextBeta4; - struct nouveau_grobj *NvImagePattern; - struct nouveau_grobj *NvRop; - struct nouveau_grobj *NvRectangle; - struct nouveau_grobj *NvImageBlit; - struct nouveau_grobj *NvScaledImage; - struct nouveau_grobj *NvClipRectangle; - struct nouveau_grobj *NvMemFormat; - struct nouveau_grobj *NvImageFromCpu; - struct nouveau_grobj *Nv2D; - struct nouveau_grobj *Nv3D; - struct nouveau_grobj *NvSW; + struct nouveau_client *client; + struct nouveau_object *channel; + struct nouveau_pushbuf *pushbuf; + struct nouveau_bufctx *bufctx; + struct nouveau_object *notify0; + struct nouveau_object *vblank_sem; + struct nouveau_object *NvNull; + struct nouveau_object *NvContextSurfaces; + struct nouveau_object *NvContextBeta1; + struct nouveau_object *NvContextBeta4; + struct nouveau_object *NvImagePattern; + struct nouveau_object *NvRop; + struct nouveau_object *NvRectangle; + struct nouveau_object *NvImageBlit; + struct nouveau_object *NvScaledImage; + struct nouveau_object *NvClipRectangle; + struct nouveau_object *NvMemFormat; + struct nouveau_object *NvImageFromCpu; + struct nouveau_object *Nv2D; + struct nouveau_object *Nv3D; + struct nouveau_object *NvSW; struct nouveau_bo *tesla_scratch; struct nouveau_bo *shader_mem; struct nouveau_bo *xv_filtertable_mem; /* Acceleration context */ PixmapPtr pspix, pmpix, pdpix; - PicturePtr pspict, pmpict, pdpict; + PicturePtr pspict, pmpict; Pixel fg_colour; - Pixel planemask; - int alu; - unsigned point_x, point_y; - unsigned width_in, width_out; - unsigned height_in, height_out; } NVRec; #define NVPTR(p) ((NVPtr)((p)->driverPrivate)) diff --git a/src/nvc0_accel.c b/src/nvc0_accel.c index 3f4d25f..6a3e711 100644 --- a/src/nvc0_accel.c +++ b/src/nvc0_accel.c @@ -23,21 +23,20 @@ #include "nv_include.h" #include "nvc0_accel.h" -#define NOUVEAU_BO(a, b, m) (NOUVEAU_BO_##a | NOUVEAU_BO_##b | NOUVEAU_BO_##m) - Bool NVAccelInitM2MF_NVC0(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; int ret; - ret = nouveau_grobj_alloc(chan, 0x9039, 0x9039, &pNv->NvMemFormat); + ret = nouveau_object_new(pNv->channel, 0x00009039, 0x9039, + NULL, 0, &pNv->NvMemFormat); if (ret) return FALSE; - BEGIN_NVC0(chan, NV01_SUBC(M2MF, OBJECT), 1); - OUT_RING (chan, pNv->NvMemFormat->handle); + BEGIN_NVC0(push, NV01_SUBC(M2MF, OBJECT), 1); + PUSH_DATA (push, pNv->NvMemFormat->handle); return TRUE; } @@ -45,41 +44,44 @@ Bool NVAccelInit2D_NVC0(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; int ret; - ret = nouveau_grobj_alloc(chan, 0x902d, 0x902d, &pNv->Nv2D); + ret = nouveau_object_new(pNv->channel, 0x0000902d, 0x902d, + NULL, 0, &pNv->Nv2D); if (ret) return FALSE; - BEGIN_NVC0(chan, NV01_SUBC(2D, OBJECT), 1); - OUT_RING (chan, pNv->Nv2D->handle); - - BEGIN_NVC0(chan, NV50_2D(CLIP_ENABLE), 1); - OUT_RING (chan, 1); - BEGIN_NVC0(chan, NV50_2D(COLOR_KEY_ENABLE), 1); - OUT_RING (chan, 0); - BEGIN_NVC0(chan, SUBC_2D(0x0884), 1); - OUT_RING (chan, 0x3f); - BEGIN_NVC0(chan, SUBC_2D(0x0888), 1); - OUT_RING (chan, 1); - BEGIN_NVC0(chan, NV50_2D(ROP), 1); - OUT_RING (chan, 0x55); - BEGIN_NVC0(chan, NV50_2D(OPERATION), 1); - OUT_RING (chan, NV50_2D_OPERATION_SRCCOPY); - - BEGIN_NVC0(chan, NV50_2D(BLIT_DU_DX_FRACT), 4); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - BEGIN_NVC0(chan, NV50_2D(DRAW_SHAPE), 2); - OUT_RING (chan, 4); - OUT_RING (chan, NV50_SURFACE_FORMAT_B5G6R5_UNORM); - BEGIN_NVC0(chan, NV50_2D(PATTERN_COLOR_FORMAT), 2); - OUT_RING (chan, 2); - OUT_RING (chan, 1); - FIRE_RING (chan); + if (!PUSH_SPACE(push, 64)) + return FALSE; + + BEGIN_NVC0(push, NV01_SUBC(2D, OBJECT), 1); + PUSH_DATA (push, pNv->Nv2D->handle); + + BEGIN_NVC0(push, NV50_2D(CLIP_ENABLE), 1); + PUSH_DATA (push, 1); + BEGIN_NVC0(push, NV50_2D(COLOR_KEY_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, SUBC_2D(0x0884), 1); + PUSH_DATA (push, 0x3f); + BEGIN_NVC0(push, SUBC_2D(0x0888), 1); + PUSH_DATA (push, 1); + BEGIN_NVC0(push, NV50_2D(ROP), 1); + PUSH_DATA (push, 0x55); + BEGIN_NVC0(push, NV50_2D(OPERATION), 1); + PUSH_DATA (push, NV50_2D_OPERATION_SRCCOPY); + + BEGIN_NVC0(push, NV50_2D(BLIT_DU_DX_FRACT), 4); + PUSH_DATA (push, 0); + PUSH_DATA (push, 1); + PUSH_DATA (push, 0); + PUSH_DATA (push, 1); + BEGIN_NVC0(push, NV50_2D(DRAW_SHAPE), 2); + PUSH_DATA (push, 4); + PUSH_DATA (push, NV50_SURFACE_FORMAT_B5G6R5_UNORM); + BEGIN_NVC0(push, NV50_2D(PATTERN_COLOR_FORMAT), 2); + PUSH_DATA (push, 2); + PUSH_DATA (push, 1); pNv->currentRop = 0xfffffffa; return TRUE; @@ -89,635 +91,611 @@ Bool NVAccelInit3D_NVC0(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; struct nouveau_bo *bo; int ret, i; - if (!pNv->Nv3D) { - ret = nouveau_grobj_alloc(chan, 0x9097, 0x9097, &pNv->Nv3D); - if (ret) - return FALSE; - - ret = nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM, - (128 << 10), 0x20000, - &pNv->tesla_scratch); - if (ret) { - nouveau_grobj_free(&pNv->Nv3D); - return FALSE; - } + ret = nouveau_object_new(pNv->channel, 0x00009097, 0x9097, + NULL, 0, &pNv->Nv3D); + if (ret) + return FALSE; + + ret = nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM, + (128 << 10), 0x20000, NULL, + &pNv->tesla_scratch); + if (ret) { + nouveau_object_del(&pNv->Nv3D); + return FALSE; } bo = pNv->tesla_scratch; - if (MARK_RING(chan, 512, 32)) + if (nouveau_pushbuf_space(push, 512, 0, 0) || + nouveau_pushbuf_refn (push, &(struct nouveau_pushbuf_refn) { + pNv->tesla_scratch, NOUVEAU_BO_VRAM | + NOUVEAU_BO_WR }, 1)) return FALSE; - BEGIN_NVC0(chan, NVC0_M2MF(QUERY_ADDRESS_HIGH), 3); - OUT_RELOCh(chan, bo, NTFY_OFFSET, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); - OUT_RELOCl(chan, bo, NTFY_OFFSET, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); - OUT_RING (chan, 0); - - BEGIN_NVC0(chan, NV01_SUBC(3D, OBJECT), 1); - OUT_RING (chan, pNv->Nv3D->handle); - BEGIN_NVC0(chan, SUBC_3D(NVC0_GRAPH_NOTIFY_ADDRESS_HIGH), 3); - OUT_RELOCh(chan, bo, NTFY_OFFSET, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); - OUT_RELOCl(chan, bo, NTFY_OFFSET, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); - OUT_RING (chan, 0); - - BEGIN_NVC0(chan, NVC0_3D(CSAA_ENABLE), 1); - OUT_RING (chan, 0); - BEGIN_NVC0(chan, NVC0_3D(MULTISAMPLE_ENABLE), 1); - OUT_RING (chan, 0); - BEGIN_NVC0(chan, NVC0_3D(MULTISAMPLE_MODE), 1); - OUT_RING (chan, NVC0_3D_MULTISAMPLE_MODE_MS1); - - BEGIN_NVC0(chan, NVC0_3D(COND_MODE), 1); - OUT_RING (chan, NVC0_3D_COND_MODE_ALWAYS); - BEGIN_NVC0(chan, NVC0_3D(RT_CONTROL), 1); - OUT_RING (chan, 1); - BEGIN_NVC0(chan, NVC0_3D(ZETA_ENABLE), 1); - OUT_RING (chan, 0); - BEGIN_NVC0(chan, NVC0_3D(CLIP_RECTS_EN), 2); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - BEGIN_NVC0(chan, NVC0_3D(CLIPID_ENABLE), 1); - OUT_RING (chan, 0); - BEGIN_NVC0(chan, NVC0_3D(VERTEX_TWO_SIDE_ENABLE), 1); - OUT_RING (chan, 0); - BEGIN_NVC0(chan, SUBC_3D(0x0fac), 1); - OUT_RING (chan, 0); - BEGIN_NVC0(chan, NVC0_3D(COLOR_MASK(0)), 8); - OUT_RING (chan, 0x1111); + BEGIN_NVC0(push, NVC0_M2MF(QUERY_ADDRESS_HIGH), 3); + PUSH_DATA (push, (bo->offset + NTFY_OFFSET) >> 32); + PUSH_DATA (push, (bo->offset + NTFY_OFFSET)); + PUSH_DATA (push, 0); + + BEGIN_NVC0(push, NV01_SUBC(3D, OBJECT), 1); + PUSH_DATA (push, pNv->Nv3D->handle); + BEGIN_NVC0(push, SUBC_3D(NVC0_GRAPH_NOTIFY_ADDRESS_HIGH), 3); + PUSH_DATA (push, (bo->offset + NTFY_OFFSET) >> 32); + PUSH_DATA (push, (bo->offset + NTFY_OFFSET)); + PUSH_DATA (push, 0); + + BEGIN_NVC0(push, NVC0_3D(CSAA_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, NVC0_3D(MULTISAMPLE_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, NVC0_3D(MULTISAMPLE_MODE), 1); + PUSH_DATA (push, NVC0_3D_MULTISAMPLE_MODE_MS1); + + BEGIN_NVC0(push, NVC0_3D(COND_MODE), 1); + PUSH_DATA (push, NVC0_3D_COND_MODE_ALWAYS); + BEGIN_NVC0(push, NVC0_3D(RT_CONTROL), 1); + PUSH_DATA (push, 1); + BEGIN_NVC0(push, NVC0_3D(ZETA_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, NVC0_3D(CLIP_RECTS_EN), 2); + PUSH_DATA (push, 0); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, NVC0_3D(CLIPID_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, NVC0_3D(VERTEX_TWO_SIDE_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, SUBC_3D(0x0fac), 1); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, NVC0_3D(COLOR_MASK(0)), 8); + PUSH_DATA (push, 0x1111); for (i = 1; i < 8; ++i) - OUT_RING(chan, 0); - FIRE_RING (chan); - - BEGIN_NVC0(chan, NVC0_3D(SCREEN_SCISSOR_HORIZ), 2); - OUT_RING (chan, (8192 << 16) | 0); - OUT_RING (chan, (8192 << 16) | 0); - BEGIN_NVC0(chan, NVC0_3D(SCREEN_Y_CONTROL), 1); - OUT_RING (chan, 0); - BEGIN_NVC0(chan, NVC0_3D(WINDOW_OFFSET_X), 2); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - BEGIN_NVC0(chan, SUBC_3D(0x1590), 1); - OUT_RING (chan, 0); - - BEGIN_NVC0(chan, NVC0_3D(LINKED_TSC), 1); - OUT_RING (chan, 1); - - BEGIN_NVC0(chan, NVC0_3D(VIEWPORT_TRANSFORM_EN), 1); - OUT_RING (chan, 0); - BEGIN_NVC0(chan, NVC0_3D(VIEW_VOLUME_CLIP_CTRL), 1); - OUT_RING (chan, 0); - BEGIN_NVC0(chan, NVC0_3D(DEPTH_RANGE_NEAR(0)), 2); - OUT_RINGf (chan, 0.0f); - OUT_RINGf (chan, 1.0f); - - BEGIN_NVC0(chan, NVC0_3D(TEX_LIMITS(4)), 1); - OUT_RING (chan, 0x54); - - BEGIN_NVC0(chan, NVC0_3D(BLEND_ENABLE(0)), 8); - OUT_RING (chan, 1); + PUSH_DATA (push, 0); + + BEGIN_NVC0(push, NVC0_3D(SCREEN_SCISSOR_HORIZ), 2); + PUSH_DATA (push, (8192 << 16) | 0); + PUSH_DATA (push, (8192 << 16) | 0); + BEGIN_NVC0(push, NVC0_3D(SCREEN_Y_CONTROL), 1); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, NVC0_3D(WINDOW_OFFSET_X), 2); + PUSH_DATA (push, 0); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, SUBC_3D(0x1590), 1); + PUSH_DATA (push, 0); + + BEGIN_NVC0(push, NVC0_3D(LINKED_TSC), 1); + PUSH_DATA (push, 1); + + BEGIN_NVC0(push, NVC0_3D(VIEWPORT_TRANSFORM_EN), 1); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, NVC0_3D(VIEW_VOLUME_CLIP_CTRL), 1); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, NVC0_3D(DEPTH_RANGE_NEAR(0)), 2); + PUSH_DATAf(push, 0.0f); + PUSH_DATAf(push, 1.0f); + + BEGIN_NVC0(push, NVC0_3D(TIC_ADDRESS_HIGH), 3); + PUSH_DATA (push, (bo->offset + TIC_OFFSET) >> 32); + PUSH_DATA (push, (bo->offset + TIC_OFFSET)); + PUSH_DATA (push, 15); + BEGIN_NVC0(push, NVC0_3D(TSC_ADDRESS_HIGH), 3); + PUSH_DATA (push, (bo->offset + TSC_OFFSET) >> 32); + PUSH_DATA (push, (bo->offset + TSC_OFFSET)); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, NVC0_3D(TEX_LIMITS(4)), 1); + PUSH_DATA (push, 0x54); + + BEGIN_NVC0(push, NVC0_3D(BLEND_ENABLE(0)), 8); + PUSH_DATA (push, 1); for (i = 1; i < 8; ++i) - OUT_RING(chan, 0); - BEGIN_NVC0(chan, NVC0_3D(BLEND_INDEPENDENT), 1); - OUT_RING (chan, 0); - - BEGIN_NVC0(chan, SUBC_3D(0x17bc), 3); - OUT_RELOCh(chan, bo, MISC_OFFSET, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); - OUT_RELOCl(chan, bo, MISC_OFFSET, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); - OUT_RING (chan, 1); - FIRE_RING (chan); - - BEGIN_NVC0(chan, NVC0_3D(CODE_ADDRESS_HIGH), 2); - OUT_RELOCh(chan, bo, CODE_OFFSET, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCl(chan, bo, CODE_OFFSET, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - - BEGIN_NVC0(chan, NVC0_M2MF(OFFSET_OUT_HIGH), 2); - if (OUT_RELOCh(chan, bo, PVP_PASS, NOUVEAU_BO(VRAM, VRAM, WR)) || - OUT_RELOCl(chan, bo, PVP_PASS, NOUVEAU_BO(VRAM, VRAM, WR))) { - MARK_UNDO(chan); - return FALSE; - } - BEGIN_NVC0(chan, NVC0_M2MF(LINE_LENGTH_IN), 2); - OUT_RING (chan, 7 * 8 + 20 * 4); - OUT_RING (chan, 1); - BEGIN_NVC0(chan, NVC0_M2MF(EXEC), 1); - OUT_RING (chan, 0x100111); - BEGIN_NIC0(chan, NVC0_M2MF(DATA), 7 * 2 + 20); - OUT_RING (chan, 0x00020461); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, 0xff000); - OUT_RING (chan, 0x00000000); /* VP_ATTR_EN[0x000] */ - OUT_RING (chan, 0x0001033f); /* VP_ATTR_EN[0x080] */ - OUT_RING (chan, 0x00000000); /* VP_ATTR_EN[0x100] */ - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); /* VP_ATTR_EN[0x200] */ - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); /* VP_ATTR_EN[0x300] */ - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x0033f000); /* VP_EXPORT_EN[0x040] */ - OUT_RING (chan, 0x00000000); /* VP_EXPORT_EN[0x0c0] */ - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); /* VP_EXPORT_EN[0x2c0] */ - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0xfff01c66); - OUT_RING (chan, 0x06000080); /* vfetch { $r0,1,2,3 } b128 a[0x80] */ - OUT_RING (chan, 0xfff11c26); - OUT_RING (chan, 0x06000090); /* vfetch { $r4,5 } b64 a[0x90] */ - OUT_RING (chan, 0xfff19c26); - OUT_RING (chan, 0x060000a0); /* vfetch { $r6,7 } b64 a[0xa0] */ - OUT_RING (chan, 0x03f01c66); - OUT_RING (chan, 0x0a7e0070); /* export v[0x70] { $r0 $r1 $r2 $r3 } */ - OUT_RING (chan, 0x13f01c26); - OUT_RING (chan, 0x0a7e0080); /* export v[0x80] { $r4 $r5 } */ - OUT_RING (chan, 0x1bf01c26); - OUT_RING (chan, 0x0a7e0090); /* export v[0x90] { $r6 $r7 } */ - OUT_RING (chan, 0x00001de7); - OUT_RING (chan, 0x80000000); /* exit */ - - BEGIN_NVC0(chan, NVC0_3D(SP_SELECT(1)), 2); - OUT_RING (chan, 0x11); - OUT_RING (chan, PVP_PASS); - BEGIN_NVC0(chan, NVC0_3D(SP_GPR_ALLOC(1)), 1); - OUT_RING (chan, 8); - BEGIN_NVC0(chan, SUBC_3D(0x163c), 1); - OUT_RING (chan, 0); - BEGIN_NVC0(chan, SUBC_3D(0x2600), 1); - OUT_RING (chan, 1); - FIRE_RING (chan); - - BEGIN_NVC0(chan, NVC0_M2MF(OFFSET_OUT_HIGH), 2); - if (OUT_RELOCh(chan, bo, PFP_S, NOUVEAU_BO(VRAM, VRAM, WR)) || - OUT_RELOCl(chan, bo, PFP_S, NOUVEAU_BO(VRAM, VRAM, WR))) { - MARK_UNDO(chan); - return FALSE; - } - BEGIN_NVC0(chan, NVC0_M2MF(LINE_LENGTH_IN), 2); - OUT_RING (chan, 6 * 8 + 20 * 4); - OUT_RING (chan, 1); - BEGIN_NVC0(chan, NVC0_M2MF(EXEC), 1); - OUT_RING (chan, 0x100111); - BEGIN_NIC0(chan, NVC0_M2MF(DATA), 6 * 2 + 20); - OUT_RING (chan, 0x00021462); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x80000000); - OUT_RING (chan, 0x0000000a); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x0000000f); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0xfff01c00); - OUT_RING (chan, 0xc07e007c); /* linterp f32 $r0 v[$r63+0x7c] */ - OUT_RING (chan, 0x10001c00); - OUT_RING (chan, 0xc8000000); /* rcp f32 $r0 $r0 */ - OUT_RING (chan, 0x03f05c40); - OUT_RING (chan, 0xc07e0084); /* pinterp f32 $r1 $r0 v[$r63+0x84] */ - OUT_RING (chan, 0x03f01c40); - OUT_RING (chan, 0xc07e0080); /* pinterp f32 $r0 $r0 v[$r63+0x80] */ - OUT_RING (chan, 0xfc001e86); - OUT_RING (chan, 0x8013c000); /* tex { $r0,1,2,3 } $t0 { $r0,1 } */ - OUT_RING (chan, 0x00001de7); - OUT_RING (chan, 0x80000000); /* exit */ - - BEGIN_NVC0(chan, NVC0_M2MF(OFFSET_OUT_HIGH), 2); - if (OUT_RELOCh(chan, bo, PFP_C, NOUVEAU_BO(VRAM, VRAM, WR)) || - OUT_RELOCl(chan, bo, PFP_C, NOUVEAU_BO(VRAM, VRAM, WR))) { - MARK_UNDO(chan); - return FALSE; - } - BEGIN_NVC0(chan, NVC0_M2MF(LINE_LENGTH_IN), 2); - OUT_RING (chan, 13 * 8 + 20 * 4); - OUT_RING (chan, 1); - BEGIN_NVC0(chan, NVC0_M2MF(EXEC), 1); - OUT_RING (chan, 0x100111); - BEGIN_NIC0(chan, NVC0_M2MF(DATA), 13 * 2 + 20); - OUT_RING (chan, 0x00021462); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x80000000); - OUT_RING (chan, 0x00000a0a); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x0000000f); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0xfff01c00); - OUT_RING (chan, 0xc07e007c); /* linterp f32 $r0 v[$r63+0x7c] */ - OUT_RING (chan, 0x10001c00); - OUT_RING (chan, 0xc8000000); /* rcp f32 $r0 $r0 */ - OUT_RING (chan, 0x03f0dc40); - OUT_RING (chan, 0xc07e0094); /* pinterp f32 $r3 $r0 v[$r63+0x94] */ - OUT_RING (chan, 0x03f09c40); - OUT_RING (chan, 0xc07e0090); /* pinterp f32 $r2 $r0 v[$r63+0x90] */ - OUT_RING (chan, 0xfc211e86); - OUT_RING (chan, 0x80120001); /* tex { _,_,_,$r4 } $t1 { $r2,3 } */ - OUT_RING (chan, 0x03f05c40); - OUT_RING (chan, 0xc07e0084); /* pinterp f32 $r1 $r0 v[$r63+0x84] */ - OUT_RING (chan, 0x03f01c40); - OUT_RING (chan, 0xc07e0080); /* pinterp f32 $r0 $r0 v[$r63+0x80] */ - OUT_RING (chan, 0xfc001e86); - OUT_RING (chan, 0x8013c000); /* tex { $r0,1,2,3 } $t0 { $r0,1 } */ - OUT_RING (chan, 0x1030dc40); - OUT_RING (chan, 0x58000000); /* mul ftz rn f32 $r3 $r3 $r4 */ - OUT_RING (chan, 0x10209c40); - OUT_RING (chan, 0x58000000); /* mul ftz rn f32 $r2 $r2 $r4 */ - OUT_RING (chan, 0x10105c40); - OUT_RING (chan, 0x58000000); /* mul ftz rn f32 $r1 $r1 $r4 */ - OUT_RING (chan, 0x10001c40); - OUT_RING (chan, 0x58000000); /* mul ftz rn f32 $r0 $r0 $r4 */ - OUT_RING (chan, 0x00001de7); - OUT_RING (chan, 0x80000000); /* exit */ - - BEGIN_NVC0(chan, NVC0_M2MF(OFFSET_OUT_HIGH), 2); - if (OUT_RELOCh(chan, bo, PFP_CCA, NOUVEAU_BO(VRAM, VRAM, WR)) || - OUT_RELOCl(chan, bo, PFP_CCA, NOUVEAU_BO(VRAM, VRAM, WR))) { - MARK_UNDO(chan); - return FALSE; - } - BEGIN_NVC0(chan, NVC0_M2MF(LINE_LENGTH_IN), 2); - OUT_RING (chan, 13 * 8 + 20 * 4); - OUT_RING (chan, 1); - BEGIN_NVC0(chan, NVC0_M2MF(EXEC), 1); - OUT_RING (chan, 0x100111); - BEGIN_NIC0(chan, NVC0_M2MF(DATA), 13 * 2 + 20); - OUT_RING (chan, 0x00021462); /* 0x0000c000 = USES_KIL, MULTI_COLORS */ - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x80000000); /* FRAG_COORD_UMASK = 0x8 */ - OUT_RING (chan, 0x00000a0a); /* FP_INTERP[0x080], 0022 0022 */ - OUT_RING (chan, 0x00000000); /* FP_INTERP[0x0c0], 0 = OFF */ - OUT_RING (chan, 0x00000000); /* FP_INTERP[0x100], 1 = FLAT */ - OUT_RING (chan, 0x00000000); /* FP_INTERP[0x140], 2 = PERSPECTIVE */ - OUT_RING (chan, 0x00000000); /* FP_INTERP[0x180], 3 = LINEAR */ - OUT_RING (chan, 0x00000000); /* FP_INTERP[0x1c0] */ - OUT_RING (chan, 0x00000000); /* FP_INTERP[0x200] */ - OUT_RING (chan, 0x00000000); /* FP_INTERP[0x240] */ - OUT_RING (chan, 0x00000000); /* FP_INTERP[0x280] */ - OUT_RING (chan, 0x00000000); /* FP_INTERP[0x2c0] */ - OUT_RING (chan, 0x00000000); /* FP_INTERP[0x300] */ - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x0000000f); /* FP_RESULT_MASK (0x8000 Face ?) */ - OUT_RING (chan, 0x00000000); /* 0x2 = FragDepth, 0x1 = SampleMask */ - OUT_RING (chan, 0xfff01c00); - OUT_RING (chan, 0xc07e007c); /* linterp f32 $r0 v[$r63+0x7c] */ - OUT_RING (chan, 0x10001c00); - OUT_RING (chan, 0xc8000000); /* rcp f32 $r0 $r0 */ - OUT_RING (chan, 0x03f0dc40); - OUT_RING (chan, 0xc07e0094); /* pinterp f32 $r3 $r0 v[$r63+0x94] */ - OUT_RING (chan, 0x03f09c40); - OUT_RING (chan, 0xc07e0090); /* pinterp f32 $r2 $r0 v[$r63+0x90] */ - OUT_RING (chan, 0xfc211e86); - OUT_RING (chan, 0x8013c001); /* tex { $r4,5,6,7 } $t1 { $r2,3 } */ - OUT_RING (chan, 0x03f05c40); - OUT_RING (chan, 0xc07e0084); /* pinterp f32 $r1 $r0 v[$r63+0x84] */ - OUT_RING (chan, 0x03f01c40); - OUT_RING (chan, 0xc07e0080); /* pinterp f32 $r0 $r0 v[$r63+0x80] */ - OUT_RING (chan, 0xfc001e86); - OUT_RING (chan, 0x8013c000); /* tex { $r0,1,2,3 } $t0 { $r0,1 } */ - OUT_RING (chan, 0x1c30dc40); - OUT_RING (chan, 0x58000000); /* mul ftz rn f32 $r3 $r3 $r7 */ - OUT_RING (chan, 0x18209c40); - OUT_RING (chan, 0x58000000); /* mul ftz rn f32 $r2 $r2 $r6 */ - OUT_RING (chan, 0x14105c40); - OUT_RING (chan, 0x58000000); /* mul ftz rn f32 $r1 $r1 $r5 */ - OUT_RING (chan, 0x10001c40); - OUT_RING (chan, 0x58000000); /* mul ftz rn f32 $r0 $r0 $r4 */ - OUT_RING (chan, 0x00001de7); - OUT_RING (chan, 0x80000000); /* exit */ - - BEGIN_NVC0(chan, NVC0_M2MF(OFFSET_OUT_HIGH), 2); - if (OUT_RELOCh(chan, bo, PFP_CCASA, NOUVEAU_BO(VRAM, VRAM, WR)) || - OUT_RELOCl(chan, bo, PFP_CCASA, NOUVEAU_BO(VRAM, VRAM, WR))) { - MARK_UNDO(chan); - return FALSE; - } - BEGIN_NVC0(chan, NVC0_M2MF(LINE_LENGTH_IN), 2); - OUT_RING (chan, 13 * 8 + 20 * 4); - OUT_RING (chan, 1); - BEGIN_NVC0(chan, NVC0_M2MF(EXEC), 1); - OUT_RING (chan, 0x100111); - BEGIN_NIC0(chan, NVC0_M2MF(DATA), 13 * 2 + 20); - OUT_RING (chan, 0x00021462); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x80000000); - OUT_RING (chan, 0x00000a0a); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x0000000f); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0xfff01c00); - OUT_RING (chan, 0xc07e007c); /* linterp f32 $r0 v[$r63+0x7c] */ - OUT_RING (chan, 0x10001c00); - OUT_RING (chan, 0xc8000000); /* rcp f32 $r0 $r0 */ - OUT_RING (chan, 0x03f0dc40); - OUT_RING (chan, 0xc07e0084); /* pinterp f32 $r3 $r0 v[$r63+0x84] */ - OUT_RING (chan, 0x03f09c40); - OUT_RING (chan, 0xc07e0080); /* pinterp f32 $r2 $r0 v[$r63+0x80] */ - OUT_RING (chan, 0xfc211e86); - OUT_RING (chan, 0x80120000); /* tex { _,_,_,$r4 } $t0 { $r2,3 } */ - OUT_RING (chan, 0x03f05c40); - OUT_RING (chan, 0xc07e0094); /* pinterp f32 $r1 $r0 v[$r63+0x94] */ - OUT_RING (chan, 0x03f01c40); - OUT_RING (chan, 0xc07e0090); /* pinterp f32 $r0 $r0 v[$r63+0x90] */ - OUT_RING (chan, 0xfc001e86); - OUT_RING (chan, 0x8013c001); /* tex { $r0,1,2,3 } $t1 { $r0,1 } */ - OUT_RING (chan, 0x1030dc40); - OUT_RING (chan, 0x58000000); /* mul ftz rn f32 $r3 $r3 $r4 */ - OUT_RING (chan, 0x10209c40); - OUT_RING (chan, 0x58000000); /* mul ftz rn f32 $r2 $r2 $r4 */ - OUT_RING (chan, 0x10105c40); - OUT_RING (chan, 0x58000000); /* mul ftz rn f32 $r1 $r1 $r4 */ - OUT_RING (chan, 0x10001c40); - OUT_RING (chan, 0x58000000); /* mul ftz rn f32 $r0 $r0 $r4 */ - OUT_RING (chan, 0x00001de7); - OUT_RING (chan, 0x80000000); /* exit */ - - BEGIN_NVC0(chan, NVC0_M2MF(OFFSET_OUT_HIGH), 2); - if (OUT_RELOCh(chan, bo, PFP_S_A8, NOUVEAU_BO(VRAM, VRAM, WR)) || - OUT_RELOCl(chan, bo, PFP_S_A8, NOUVEAU_BO(VRAM, VRAM, WR))) { - MARK_UNDO(chan); - return FALSE; - } - BEGIN_NVC0(chan, NVC0_M2MF(LINE_LENGTH_IN), 2); - OUT_RING (chan, 9 * 8 + 20 * 4); - OUT_RING (chan, 1); - BEGIN_NVC0(chan, NVC0_M2MF(EXEC), 1); - OUT_RING (chan, 0x100111); - BEGIN_NIC0(chan, NVC0_M2MF(DATA), 9 * 2 + 20); - OUT_RING (chan, 0x00021462); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x80000000); - OUT_RING (chan, 0x0000000a); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x0000000f); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0xfff01c00); - OUT_RING (chan, 0xc07e007c); /* linterp f32 $r0 v[$r63+0x7c] */ - OUT_RING (chan, 0x10001c00); - OUT_RING (chan, 0xc8000000); /* rcp f32 $r0 $r0 */ - OUT_RING (chan, 0x03f05c40); - OUT_RING (chan, 0xc07e0084); /* pinterp f32 $r1 $r0 v[$r63+0x84] */ - OUT_RING (chan, 0x03f01c40); - OUT_RING (chan, 0xc07e0080); /* pinterp f32 $r0 $r0 v[$r63+0x80] */ - OUT_RING (chan, 0xfc001e86); - OUT_RING (chan, 0x80120000); /* tex { _ _ _ $r0 } $t0 { $r0 $r1 } */ - OUT_RING (chan, 0x0000dde4); - OUT_RING (chan, 0x28000000); /* mov b32 $r3 $r0 */ - OUT_RING (chan, 0x00009de4); - OUT_RING (chan, 0x28000000); /* mov b32 $r2 $r0 */ - OUT_RING (chan, 0x00005de4); - OUT_RING (chan, 0x28000000); /* mov b32 $r1 $r0 */ - OUT_RING (chan, 0x00001de7); - OUT_RING (chan, 0x80000000); /* exit */ - - BEGIN_NVC0(chan, NVC0_M2MF(OFFSET_OUT_HIGH), 2); - if (OUT_RELOCh(chan, bo, PFP_C_A8, NOUVEAU_BO(VRAM, VRAM, WR)) || - OUT_RELOCl(chan, bo, PFP_C_A8, NOUVEAU_BO(VRAM, VRAM, WR))) { - MARK_UNDO(chan); - return FALSE; - } - BEGIN_NVC0(chan, NVC0_M2MF(LINE_LENGTH_IN), 2); - OUT_RING (chan, 13 * 8 + 20 * 4); - OUT_RING (chan, 1); - BEGIN_NVC0(chan, NVC0_M2MF(EXEC), 1); - OUT_RING (chan, 0x100111); - BEGIN_NIC0(chan, NVC0_M2MF(DATA), 13 * 2 + 20); - OUT_RING (chan, 0x00021462); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x80000000); - OUT_RING (chan, 0x00000a0a); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x0000000f); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0xfff01c00); - OUT_RING (chan, 0xc07e007c); /* linterp f32 $r0 v[$r63+0x7c] */ - OUT_RING (chan, 0x10001c00); - OUT_RING (chan, 0xc8000000); /* rcp f32 $r0 $r0 */ - OUT_RING (chan, 0x03f0dc40); - OUT_RING (chan, 0xc07e0094); /* pinterp f32 $r3 $r0 v[$r63+0x94] */ - OUT_RING (chan, 0x03f09c40); - OUT_RING (chan, 0xc07e0090); /* pinterp f32 $r2 $r0 v[$r63+0x90] */ - OUT_RING (chan, 0xfc205e86); - OUT_RING (chan, 0x80120001); /* tex { _ _ _ $r1 } $t1 { $r2 $r3 } */ - OUT_RING (chan, 0x03f0dc40); - OUT_RING (chan, 0xc07e0084); /* pinterp f32 $r3 $r0 v[$r63+0x84] */ - OUT_RING (chan, 0x03f09c40); - OUT_RING (chan, 0xc07e0080); /* pinterp f32 $r2 $r0 v[$r63+0x80] */ - OUT_RING (chan, 0xfc201e86); - OUT_RING (chan, 0x80120000); /* tex { _ _ _ $r0 } $t0 { $r2 $r3 } */ - OUT_RING (chan, 0x0400dc40); - OUT_RING (chan, 0x58000000); /* mul ftz rn f32 $r3 $r0 $r1 */ - OUT_RING (chan, 0x0c009de4); - OUT_RING (chan, 0x28000000); /* mov b32 $r2 $r3 */ - OUT_RING (chan, 0x0c005de4); - OUT_RING (chan, 0x28000000); /* mov b32 $r1 $r3 */ - OUT_RING (chan, 0x0c001de4); - OUT_RING (chan, 0x28000000); /* mov b32 $r0 $r3 */ - OUT_RING (chan, 0x00001de7); - OUT_RING (chan, 0x80000000); /* exit */ - FIRE_RING (chan); - - BEGIN_NVC0(chan, NVC0_M2MF(OFFSET_OUT_HIGH), 2); - if (OUT_RELOCh(chan, bo, PFP_NV12, NOUVEAU_BO(VRAM, VRAM, WR)) || - OUT_RELOCl(chan, bo, PFP_NV12, NOUVEAU_BO(VRAM, VRAM, WR))) { - MARK_UNDO(chan); - return FALSE; - } - BEGIN_NVC0(chan, NVC0_M2MF(LINE_LENGTH_IN), 2); - OUT_RING (chan, 19 * 8 + 20 * 4); - OUT_RING (chan, 1); - BEGIN_NVC0(chan, NVC0_M2MF(EXEC), 1); - OUT_RING (chan, 0x100111); - BEGIN_NIC0(chan, NVC0_M2MF(DATA), 19 * 2 + 20); - OUT_RING (chan, 0x00021462); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x80000000); - OUT_RING (chan, 0x00000a0a); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x0000000f); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0xfff09c00); - OUT_RING (chan, 0xc07e007c); - OUT_RING (chan, 0x10209c00); - OUT_RING (chan, 0xc8000000); - OUT_RING (chan, 0x0bf01c40); - OUT_RING (chan, 0xc07e0080); - OUT_RING (chan, 0x0bf05c40); - OUT_RING (chan, 0xc07e0084); - OUT_RING (chan, 0xfc001e86); - OUT_RING (chan, 0x80120000); - OUT_RING (chan, 0x00015c40); - OUT_RING (chan, 0x58004000); - OUT_RING (chan, 0x1050dc20); - OUT_RING (chan, 0x50004000); - OUT_RING (chan, 0x20511c20); - OUT_RING (chan, 0x50004000); - OUT_RING (chan, 0x30515c20); - OUT_RING (chan, 0x50004000); - OUT_RING (chan, 0x0bf01c40); - OUT_RING (chan, 0xc07e0090); - OUT_RING (chan, 0x0bf05c40); - OUT_RING (chan, 0xc07e0094); - OUT_RING (chan, 0xfc001e86); - OUT_RING (chan, 0x80130001); - OUT_RING (chan, 0x4000dc40); - OUT_RING (chan, 0x30064000); - OUT_RING (chan, 0x50011c40); - OUT_RING (chan, 0x30084000); - OUT_RING (chan, 0x60015c40); - OUT_RING (chan, 0x300a4000); - OUT_RING (chan, 0x70101c40); - OUT_RING (chan, 0x30064000); - OUT_RING (chan, 0x90109c40); - OUT_RING (chan, 0x300a4000); - OUT_RING (chan, 0x80105c40); - OUT_RING (chan, 0x30084000); - OUT_RING (chan, 0x00001de7); - OUT_RING (chan, 0x80000000); - - BEGIN_NVC0(chan, SUBC_3D(0x021c), 1); /* CODE_FLUSH ? */ - OUT_RING (chan, 0x1111); - FIRE_RING (chan); - - BEGIN_NVC0(chan, NVC0_3D(SP_SELECT(5)), 2); - OUT_RING (chan, 0x51); - OUT_RING (chan, PFP_S); - BEGIN_NVC0(chan, NVC0_3D(SP_GPR_ALLOC(5)), 1); - OUT_RING (chan, 8); - - BEGIN_NVC0(chan, NVC0_3D(CB_SIZE), 3); - OUT_RING (chan, 256); - if (OUT_RELOCh(chan, bo, CB_OFFSET, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR) || - OUT_RELOCl(chan, bo, CB_OFFSET, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR)) { - MARK_UNDO(chan); - return FALSE; - } - BEGIN_NVC0(chan, NVC0_3D(CB_BIND(4)), 1); - OUT_RING (chan, 0x01); - - BEGIN_NVC0(chan, NVC0_3D(EARLY_FRAGMENT_TESTS), 1); - OUT_RING (chan, 0); - BEGIN_NVC0(chan, SUBC_3D(0x0360), 2); - OUT_RING (chan, 0x20164010); - OUT_RING (chan, 0x20); - BEGIN_NVC0(chan, SUBC_3D(0x196c), 1); - OUT_RING (chan, 0); - BEGIN_NVC0(chan, SUBC_3D(0x1664), 1); - OUT_RING (chan, 0); - BEGIN_NVC0(chan, NVC0_3D(FRAG_COLOR_CLAMP_EN), 1); - OUT_RING (chan, 0x11111111); - - BEGIN_NVC0(chan, NVC0_3D(DEPTH_TEST_ENABLE), 1); - OUT_RING (chan, 0); - - BEGIN_NVC0(chan, NVC0_3D(RASTERIZE_ENABLE), 1); - OUT_RING (chan, 1); - BEGIN_NVC0(chan, NVC0_3D(SP_SELECT(4)), 1); - OUT_RING (chan, 0x40); - BEGIN_NVC0(chan, NVC0_3D(LAYER), 1); - OUT_RING (chan, 0); - BEGIN_NVC0(chan, NVC0_3D(SP_SELECT(3)), 1); - OUT_RING (chan, 0x30); - BEGIN_NVC0(chan, NVC0_3D(SP_SELECT(2)), 1); - OUT_RING (chan, 0x20); - BEGIN_NVC0(chan, NVC0_3D(SP_SELECT(0)), 1); - OUT_RING (chan, 0x00); - - BEGIN_NVC0(chan, SUBC_3D(0x1604), 1); - OUT_RING (chan, 4); - BEGIN_NVC0(chan, NVC0_3D(POINT_SPRITE_ENABLE), 1); - OUT_RING (chan, 0); - BEGIN_NVC0(chan, NVC0_3D(SCISSOR_ENABLE(0)), 1); - OUT_RING (chan, 1); - - BEGIN_NVC0(chan, NVC0_3D(VIEWPORT_HORIZ(0)), 2); - OUT_RING (chan, (8192 << 16) | 0); - OUT_RING (chan, (8192 << 16) | 0); - BEGIN_NVC0(chan, NVC0_3D(SCISSOR_HORIZ(0)), 2); - OUT_RING (chan, (8192 << 16) | 0); - OUT_RING (chan, (8192 << 16) | 0); - FIRE_RING (chan); - + PUSH_DATA (push, 0); + BEGIN_NVC0(push, NVC0_3D(BLEND_INDEPENDENT), 1); + PUSH_DATA (push, 0); + + BEGIN_NVC0(push, SUBC_3D(0x17bc), 3); + PUSH_DATA (push, (bo->offset + MISC_OFFSET) >> 32); + PUSH_DATA (push, (bo->offset + MISC_OFFSET)); + PUSH_DATA (push, 1); + + BEGIN_NVC0(push, NVC0_3D(CODE_ADDRESS_HIGH), 2); + PUSH_DATA (push, (bo->offset + CODE_OFFSET) >> 32); + PUSH_DATA (push, (bo->offset + CODE_OFFSET)); + + BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2); + PUSH_DATA (push, (bo->offset + PVP_PASS) >> 32); + PUSH_DATA (push, (bo->offset + PVP_PASS)); + BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2); + PUSH_DATA (push, 7 * 8 + 20 * 4); + PUSH_DATA (push, 1); + BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1); + PUSH_DATA (push, 0x100111); + BEGIN_NIC0(push, NVC0_M2MF(DATA), 7 * 2 + 20); + PUSH_DATA (push, 0x00020461); + PUSH_DATA (push, 0); + PUSH_DATA (push, 0); + PUSH_DATA (push, 0); + PUSH_DATA (push, 0xff000); + PUSH_DATA (push, 0x00000000); /* VP_ATTR_EN[0x000] */ + PUSH_DATA (push, 0x0001033f); /* VP_ATTR_EN[0x080] */ + PUSH_DATA (push, 0x00000000); /* VP_ATTR_EN[0x100] */ + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); /* VP_ATTR_EN[0x200] */ + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); /* VP_ATTR_EN[0x300] */ + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x0033f000); /* VP_EXPORT_EN[0x040] */ + PUSH_DATA (push, 0x00000000); /* VP_EXPORT_EN[0x0c0] */ + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); /* VP_EXPORT_EN[0x2c0] */ + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0xfff01c66); + PUSH_DATA (push, 0x06000080); /* vfetch { $r0,1,2,3 } b128 a[0x80] */ + PUSH_DATA (push, 0xfff11c26); + PUSH_DATA (push, 0x06000090); /* vfetch { $r4,5 } b64 a[0x90] */ + PUSH_DATA (push, 0xfff19c26); + PUSH_DATA (push, 0x060000a0); /* vfetch { $r6,7 } b64 a[0xa0] */ + PUSH_DATA (push, 0x03f01c66); + PUSH_DATA (push, 0x0a7e0070); /* export v[0x70] { $r0 $r1 $r2 $r3 } */ + PUSH_DATA (push, 0x13f01c26); + PUSH_DATA (push, 0x0a7e0080); /* export v[0x80] { $r4 $r5 } */ + PUSH_DATA (push, 0x1bf01c26); + PUSH_DATA (push, 0x0a7e0090); /* export v[0x90] { $r6 $r7 } */ + PUSH_DATA (push, 0x00001de7); + PUSH_DATA (push, 0x80000000); /* exit */ + + BEGIN_NVC0(push, NVC0_3D(SP_SELECT(1)), 2); + PUSH_DATA (push, 0x11); + PUSH_DATA (push, PVP_PASS); + BEGIN_NVC0(push, NVC0_3D(SP_GPR_ALLOC(1)), 1); + PUSH_DATA (push, 8); + BEGIN_NVC0(push, SUBC_3D(0x163c), 1); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, SUBC_3D(0x2600), 1); + PUSH_DATA (push, 1); + + BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2); + PUSH_DATA (push, (bo->offset + PFP_S) >> 32); + PUSH_DATA (push, (bo->offset + PFP_S)); + BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2); + PUSH_DATA (push, 6 * 8 + 20 * 4); + PUSH_DATA (push, 1); + BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1); + PUSH_DATA (push, 0x100111); + BEGIN_NIC0(push, NVC0_M2MF(DATA), 6 * 2 + 20); + PUSH_DATA (push, 0x00021462); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x80000000); + PUSH_DATA (push, 0x0000000a); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x0000000f); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0xfff01c00); + PUSH_DATA (push, 0xc07e007c); /* linterp f32 $r0 v[$r63+0x7c] */ + PUSH_DATA (push, 0x10001c00); + PUSH_DATA (push, 0xc8000000); /* rcp f32 $r0 $r0 */ + PUSH_DATA (push, 0x03f05c40); + PUSH_DATA (push, 0xc07e0084); /* pinterp f32 $r1 $r0 v[$r63+0x84] */ + PUSH_DATA (push, 0x03f01c40); + PUSH_DATA (push, 0xc07e0080); /* pinterp f32 $r0 $r0 v[$r63+0x80] */ + PUSH_DATA (push, 0xfc001e86); + PUSH_DATA (push, 0x8013c000); /* tex { $r0,1,2,3 } $t0 { $r0,1 } */ + PUSH_DATA (push, 0x00001de7); + PUSH_DATA (push, 0x80000000); /* exit */ + + BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2); + PUSH_DATA (push, (bo->offset + PFP_C) >> 32); + PUSH_DATA (push, (bo->offset + PFP_C)); + BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2); + PUSH_DATA (push, 13 * 8 + 20 * 4); + PUSH_DATA (push, 1); + BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1); + PUSH_DATA (push, 0x100111); + BEGIN_NIC0(push, NVC0_M2MF(DATA), 13 * 2 + 20); + PUSH_DATA (push, 0x00021462); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x80000000); + PUSH_DATA (push, 0x00000a0a); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x0000000f); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0xfff01c00); + PUSH_DATA (push, 0xc07e007c); /* linterp f32 $r0 v[$r63+0x7c] */ + PUSH_DATA (push, 0x10001c00); + PUSH_DATA (push, 0xc8000000); /* rcp f32 $r0 $r0 */ + PUSH_DATA (push, 0x03f0dc40); + PUSH_DATA (push, 0xc07e0094); /* pinterp f32 $r3 $r0 v[$r63+0x94] */ + PUSH_DATA (push, 0x03f09c40); + PUSH_DATA (push, 0xc07e0090); /* pinterp f32 $r2 $r0 v[$r63+0x90] */ + PUSH_DATA (push, 0xfc211e86); + PUSH_DATA (push, 0x80120001); /* tex { _,_,_,$r4 } $t1 { $r2,3 } */ + PUSH_DATA (push, 0x03f05c40); + PUSH_DATA (push, 0xc07e0084); /* pinterp f32 $r1 $r0 v[$r63+0x84] */ + PUSH_DATA (push, 0x03f01c40); + PUSH_DATA (push, 0xc07e0080); /* pinterp f32 $r0 $r0 v[$r63+0x80] */ + PUSH_DATA (push, 0xfc001e86); + PUSH_DATA (push, 0x8013c000); /* tex { $r0,1,2,3 } $t0 { $r0,1 } */ + PUSH_DATA (push, 0x1030dc40); + PUSH_DATA (push, 0x58000000); /* mul ftz rn f32 $r3 $r3 $r4 */ + PUSH_DATA (push, 0x10209c40); + PUSH_DATA (push, 0x58000000); /* mul ftz rn f32 $r2 $r2 $r4 */ + PUSH_DATA (push, 0x10105c40); + PUSH_DATA (push, 0x58000000); /* mul ftz rn f32 $r1 $r1 $r4 */ + PUSH_DATA (push, 0x10001c40); + PUSH_DATA (push, 0x58000000); /* mul ftz rn f32 $r0 $r0 $r4 */ + PUSH_DATA (push, 0x00001de7); + PUSH_DATA (push, 0x80000000); /* exit */ + + BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2); + PUSH_DATA (push, (bo->offset + PFP_CCA) >> 32); + PUSH_DATA (push, (bo->offset + PFP_CCA)); + BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2); + PUSH_DATA (push, 13 * 8 + 20 * 4); + PUSH_DATA (push, 1); + BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1); + PUSH_DATA (push, 0x100111); + BEGIN_NIC0(push, NVC0_M2MF(DATA), 13 * 2 + 20); + PUSH_DATA (push, 0x00021462); /* 0x0000c000 = USES_KIL, MULTI_COLORS */ + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x80000000); /* FRAG_COORD_UMASK = 0x8 */ + PUSH_DATA (push, 0x00000a0a); /* FP_INTERP[0x080], 0022 0022 */ + PUSH_DATA (push, 0x00000000); /* FP_INTERP[0x0c0], 0 = OFF */ + PUSH_DATA (push, 0x00000000); /* FP_INTERP[0x100], 1 = FLAT */ + PUSH_DATA (push, 0x00000000); /* FP_INTERP[0x140], 2 = PERSPECTIVE */ + PUSH_DATA (push, 0x00000000); /* FP_INTERP[0x180], 3 = LINEAR */ + PUSH_DATA (push, 0x00000000); /* FP_INTERP[0x1c0] */ + PUSH_DATA (push, 0x00000000); /* FP_INTERP[0x200] */ + PUSH_DATA (push, 0x00000000); /* FP_INTERP[0x240] */ + PUSH_DATA (push, 0x00000000); /* FP_INTERP[0x280] */ + PUSH_DATA (push, 0x00000000); /* FP_INTERP[0x2c0] */ + PUSH_DATA (push, 0x00000000); /* FP_INTERP[0x300] */ + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x0000000f); /* FP_RESULT_MASK (0x8000 Face ?) */ + PUSH_DATA (push, 0x00000000); /* 0x2 = FragDepth, 0x1 = SampleMask */ + PUSH_DATA (push, 0xfff01c00); + PUSH_DATA (push, 0xc07e007c); /* linterp f32 $r0 v[$r63+0x7c] */ + PUSH_DATA (push, 0x10001c00); + PUSH_DATA (push, 0xc8000000); /* rcp f32 $r0 $r0 */ + PUSH_DATA (push, 0x03f0dc40); + PUSH_DATA (push, 0xc07e0094); /* pinterp f32 $r3 $r0 v[$r63+0x94] */ + PUSH_DATA (push, 0x03f09c40); + PUSH_DATA (push, 0xc07e0090); /* pinterp f32 $r2 $r0 v[$r63+0x90] */ + PUSH_DATA (push, 0xfc211e86); + PUSH_DATA (push, 0x8013c001); /* tex { $r4,5,6,7 } $t1 { $r2,3 } */ + PUSH_DATA (push, 0x03f05c40); + PUSH_DATA (push, 0xc07e0084); /* pinterp f32 $r1 $r0 v[$r63+0x84] */ + PUSH_DATA (push, 0x03f01c40); + PUSH_DATA (push, 0xc07e0080); /* pinterp f32 $r0 $r0 v[$r63+0x80] */ + PUSH_DATA (push, 0xfc001e86); + PUSH_DATA (push, 0x8013c000); /* tex { $r0,1,2,3 } $t0 { $r0,1 } */ + PUSH_DATA (push, 0x1c30dc40); + PUSH_DATA (push, 0x58000000); /* mul ftz rn f32 $r3 $r3 $r7 */ + PUSH_DATA (push, 0x18209c40); + PUSH_DATA (push, 0x58000000); /* mul ftz rn f32 $r2 $r2 $r6 */ + PUSH_DATA (push, 0x14105c40); + PUSH_DATA (push, 0x58000000); /* mul ftz rn f32 $r1 $r1 $r5 */ + PUSH_DATA (push, 0x10001c40); + PUSH_DATA (push, 0x58000000); /* mul ftz rn f32 $r0 $r0 $r4 */ + PUSH_DATA (push, 0x00001de7); + PUSH_DATA (push, 0x80000000); /* exit */ + + BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2); + PUSH_DATA (push, (bo->offset + PFP_CCASA) >> 32); + PUSH_DATA (push, (bo->offset + PFP_CCASA)); + BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2); + PUSH_DATA (push, 13 * 8 + 20 * 4); + PUSH_DATA (push, 1); + BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1); + PUSH_DATA (push, 0x100111); + BEGIN_NIC0(push, NVC0_M2MF(DATA), 13 * 2 + 20); + PUSH_DATA (push, 0x00021462); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x80000000); + PUSH_DATA (push, 0x00000a0a); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x0000000f); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0xfff01c00); + PUSH_DATA (push, 0xc07e007c); /* linterp f32 $r0 v[$r63+0x7c] */ + PUSH_DATA (push, 0x10001c00); + PUSH_DATA (push, 0xc8000000); /* rcp f32 $r0 $r0 */ + PUSH_DATA (push, 0x03f0dc40); + PUSH_DATA (push, 0xc07e0084); /* pinterp f32 $r3 $r0 v[$r63+0x84] */ + PUSH_DATA (push, 0x03f09c40); + PUSH_DATA (push, 0xc07e0080); /* pinterp f32 $r2 $r0 v[$r63+0x80] */ + PUSH_DATA (push, 0xfc211e86); + PUSH_DATA (push, 0x80120000); /* tex { _,_,_,$r4 } $t0 { $r2,3 } */ + PUSH_DATA (push, 0x03f05c40); + PUSH_DATA (push, 0xc07e0094); /* pinterp f32 $r1 $r0 v[$r63+0x94] */ + PUSH_DATA (push, 0x03f01c40); + PUSH_DATA (push, 0xc07e0090); /* pinterp f32 $r0 $r0 v[$r63+0x90] */ + PUSH_DATA (push, 0xfc001e86); + PUSH_DATA (push, 0x8013c001); /* tex { $r0,1,2,3 } $t1 { $r0,1 } */ + PUSH_DATA (push, 0x1030dc40); + PUSH_DATA (push, 0x58000000); /* mul ftz rn f32 $r3 $r3 $r4 */ + PUSH_DATA (push, 0x10209c40); + PUSH_DATA (push, 0x58000000); /* mul ftz rn f32 $r2 $r2 $r4 */ + PUSH_DATA (push, 0x10105c40); + PUSH_DATA (push, 0x58000000); /* mul ftz rn f32 $r1 $r1 $r4 */ + PUSH_DATA (push, 0x10001c40); + PUSH_DATA (push, 0x58000000); /* mul ftz rn f32 $r0 $r0 $r4 */ + PUSH_DATA (push, 0x00001de7); + PUSH_DATA (push, 0x80000000); /* exit */ + + BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2); + PUSH_DATA (push, (bo->offset + PFP_S_A8) >> 32); + PUSH_DATA (push, (bo->offset + PFP_S_A8)); + BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2); + PUSH_DATA (push, 9 * 8 + 20 * 4); + PUSH_DATA (push, 1); + BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1); + PUSH_DATA (push, 0x100111); + BEGIN_NIC0(push, NVC0_M2MF(DATA), 9 * 2 + 20); + PUSH_DATA (push, 0x00021462); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x80000000); + PUSH_DATA (push, 0x0000000a); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x0000000f); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0xfff01c00); + PUSH_DATA (push, 0xc07e007c); /* linterp f32 $r0 v[$r63+0x7c] */ + PUSH_DATA (push, 0x10001c00); + PUSH_DATA (push, 0xc8000000); /* rcp f32 $r0 $r0 */ + PUSH_DATA (push, 0x03f05c40); + PUSH_DATA (push, 0xc07e0084); /* pinterp f32 $r1 $r0 v[$r63+0x84] */ + PUSH_DATA (push, 0x03f01c40); + PUSH_DATA (push, 0xc07e0080); /* pinterp f32 $r0 $r0 v[$r63+0x80] */ + PUSH_DATA (push, 0xfc001e86); + PUSH_DATA (push, 0x80120000); /* tex { _ _ _ $r0 } $t0 { $r0 $r1 } */ + PUSH_DATA (push, 0x0000dde4); + PUSH_DATA (push, 0x28000000); /* mov b32 $r3 $r0 */ + PUSH_DATA (push, 0x00009de4); + PUSH_DATA (push, 0x28000000); /* mov b32 $r2 $r0 */ + PUSH_DATA (push, 0x00005de4); + PUSH_DATA (push, 0x28000000); /* mov b32 $r1 $r0 */ + PUSH_DATA (push, 0x00001de7); + PUSH_DATA (push, 0x80000000); /* exit */ + + BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2); + PUSH_DATA (push, (bo->offset + PFP_C_A8) >> 32); + PUSH_DATA (push, (bo->offset + PFP_C_A8)); + BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2); + PUSH_DATA (push, 13 * 8 + 20 * 4); + PUSH_DATA (push, 1); + BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1); + PUSH_DATA (push, 0x100111); + BEGIN_NIC0(push, NVC0_M2MF(DATA), 13 * 2 + 20); + PUSH_DATA (push, 0x00021462); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x80000000); + PUSH_DATA (push, 0x00000a0a); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x0000000f); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0xfff01c00); + PUSH_DATA (push, 0xc07e007c); /* linterp f32 $r0 v[$r63+0x7c] */ + PUSH_DATA (push, 0x10001c00); + PUSH_DATA (push, 0xc8000000); /* rcp f32 $r0 $r0 */ + PUSH_DATA (push, 0x03f0dc40); + PUSH_DATA (push, 0xc07e0094); /* pinterp f32 $r3 $r0 v[$r63+0x94] */ + PUSH_DATA (push, 0x03f09c40); + PUSH_DATA (push, 0xc07e0090); /* pinterp f32 $r2 $r0 v[$r63+0x90] */ + PUSH_DATA (push, 0xfc205e86); + PUSH_DATA (push, 0x80120001); /* tex { _ _ _ $r1 } $t1 { $r2 $r3 } */ + PUSH_DATA (push, 0x03f0dc40); + PUSH_DATA (push, 0xc07e0084); /* pinterp f32 $r3 $r0 v[$r63+0x84] */ + PUSH_DATA (push, 0x03f09c40); + PUSH_DATA (push, 0xc07e0080); /* pinterp f32 $r2 $r0 v[$r63+0x80] */ + PUSH_DATA (push, 0xfc201e86); + PUSH_DATA (push, 0x80120000); /* tex { _ _ _ $r0 } $t0 { $r2 $r3 } */ + PUSH_DATA (push, 0x0400dc40); + PUSH_DATA (push, 0x58000000); /* mul ftz rn f32 $r3 $r0 $r1 */ + PUSH_DATA (push, 0x0c009de4); + PUSH_DATA (push, 0x28000000); /* mov b32 $r2 $r3 */ + PUSH_DATA (push, 0x0c005de4); + PUSH_DATA (push, 0x28000000); /* mov b32 $r1 $r3 */ + PUSH_DATA (push, 0x0c001de4); + PUSH_DATA (push, 0x28000000); /* mov b32 $r0 $r3 */ + PUSH_DATA (push, 0x00001de7); + PUSH_DATA (push, 0x80000000); /* exit */ + + BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2); + PUSH_DATA (push, (bo->offset + PFP_NV12) >> 32); + PUSH_DATA (push, (bo->offset + PFP_NV12)); + BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2); + PUSH_DATA (push, 19 * 8 + 20 * 4); + PUSH_DATA (push, 1); + BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1); + PUSH_DATA (push, 0x100111); + BEGIN_NIC0(push, NVC0_M2MF(DATA), 19 * 2 + 20); + PUSH_DATA (push, 0x00021462); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x80000000); + PUSH_DATA (push, 0x00000a0a); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x0000000f); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0xfff09c00); + PUSH_DATA (push, 0xc07e007c); + PUSH_DATA (push, 0x10209c00); + PUSH_DATA (push, 0xc8000000); + PUSH_DATA (push, 0x0bf01c40); + PUSH_DATA (push, 0xc07e0080); + PUSH_DATA (push, 0x0bf05c40); + PUSH_DATA (push, 0xc07e0084); + PUSH_DATA (push, 0xfc001e86); + PUSH_DATA (push, 0x80120000); + PUSH_DATA (push, 0x00015c40); + PUSH_DATA (push, 0x58004000); + PUSH_DATA (push, 0x1050dc20); + PUSH_DATA (push, 0x50004000); + PUSH_DATA (push, 0x20511c20); + PUSH_DATA (push, 0x50004000); + PUSH_DATA (push, 0x30515c20); + PUSH_DATA (push, 0x50004000); + PUSH_DATA (push, 0x0bf01c40); + PUSH_DATA (push, 0xc07e0090); + PUSH_DATA (push, 0x0bf05c40); + PUSH_DATA (push, 0xc07e0094); + PUSH_DATA (push, 0xfc001e86); + PUSH_DATA (push, 0x80130001); + PUSH_DATA (push, 0x4000dc40); + PUSH_DATA (push, 0x30064000); + PUSH_DATA (push, 0x50011c40); + PUSH_DATA (push, 0x30084000); + PUSH_DATA (push, 0x60015c40); + PUSH_DATA (push, 0x300a4000); + PUSH_DATA (push, 0x70101c40); + PUSH_DATA (push, 0x30064000); + PUSH_DATA (push, 0x90109c40); + PUSH_DATA (push, 0x300a4000); + PUSH_DATA (push, 0x80105c40); + PUSH_DATA (push, 0x30084000); + PUSH_DATA (push, 0x00001de7); + PUSH_DATA (push, 0x80000000); + + BEGIN_NVC0(push, SUBC_3D(0x021c), 1); /* CODE_FLUSH ? */ + PUSH_DATA (push, 0x1111); + + BEGIN_NVC0(push, NVC0_3D(SP_SELECT(5)), 2); + PUSH_DATA (push, 0x51); + PUSH_DATA (push, PFP_S); + BEGIN_NVC0(push, NVC0_3D(SP_GPR_ALLOC(5)), 1); + PUSH_DATA (push, 8); + + BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3); + PUSH_DATA (push, 256); + PUSH_DATA (push, (bo->offset + CB_OFFSET) >> 32); + PUSH_DATA (push, (bo->offset + CB_OFFSET)); + BEGIN_NVC0(push, NVC0_3D(CB_BIND(4)), 1); + PUSH_DATA (push, 0x01); + + BEGIN_NVC0(push, NVC0_3D(EARLY_FRAGMENT_TESTS), 1); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, SUBC_3D(0x0360), 2); + PUSH_DATA (push, 0x20164010); + PUSH_DATA (push, 0x20); + BEGIN_NVC0(push, SUBC_3D(0x196c), 1); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, SUBC_3D(0x1664), 1); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, NVC0_3D(FRAG_COLOR_CLAMP_EN), 1); + PUSH_DATA (push, 0x11111111); + + BEGIN_NVC0(push, NVC0_3D(DEPTH_TEST_ENABLE), 1); + PUSH_DATA (push, 0); + + BEGIN_NVC0(push, NVC0_3D(RASTERIZE_ENABLE), 1); + PUSH_DATA (push, 1); + BEGIN_NVC0(push, NVC0_3D(SP_SELECT(4)), 1); + PUSH_DATA (push, 0x40); + BEGIN_NVC0(push, NVC0_3D(LAYER), 1); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, NVC0_3D(SP_SELECT(3)), 1); + PUSH_DATA (push, 0x30); + BEGIN_NVC0(push, NVC0_3D(SP_SELECT(2)), 1); + PUSH_DATA (push, 0x20); + BEGIN_NVC0(push, NVC0_3D(SP_SELECT(0)), 1); + PUSH_DATA (push, 0x00); + + BEGIN_NVC0(push, SUBC_3D(0x1604), 1); + PUSH_DATA (push, 4); + BEGIN_NVC0(push, NVC0_3D(POINT_SPRITE_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, NVC0_3D(SCISSOR_ENABLE(0)), 1); + PUSH_DATA (push, 1); + + BEGIN_NVC0(push, NVC0_3D(VIEWPORT_HORIZ(0)), 2); + PUSH_DATA (push, (8192 << 16) | 0); + PUSH_DATA (push, (8192 << 16) | 0); + BEGIN_NVC0(push, NVC0_3D(SCISSOR_HORIZ(0)), 2); + PUSH_DATA (push, (8192 << 16) | 0); + PUSH_DATA (push, (8192 << 16) | 0); return TRUE; } diff --git a/src/nvc0_accel.h b/src/nvc0_accel.h index 316a9da..7e1fd00 100644 --- a/src/nvc0_accel.h +++ b/src/nvc0_accel.h @@ -9,6 +9,16 @@ #include "hwdefs/nv50_texture.h" #include "hwdefs/nv_3ddefs.xml.h" +/* subchannel assignments */ +#define SUBC_M2MF(mthd) 0, (mthd) +#define NVC0_M2MF(mthd) SUBC_M2MF(NVC0_M2MF_##mthd) +#define SUBC_NVSW(mthd) 1, (mthd) +#define SUBC_2D(mthd) 2, (mthd) +#define NV50_2D(mthd) SUBC_2D(NV50_2D_##mthd) +#define NVC0_2D(mthd) SUBC_2D(NVC0_2D_##mthd) +#define SUBC_3D(mthd) 7, (mthd) +#define NVC0_3D(mthd) SUBC_3D(NVC0_3D_##mthd) + /* scratch buffer offsets */ #define CODE_OFFSET 0x00000 /* Code */ #define TIC_OFFSET 0x02000 /* Texture Image Control */ @@ -40,21 +50,21 @@ static __inline__ void VTX1s(NVPtr pNv, float sx, float sy, unsigned dx, unsigned dy) { - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; - BEGIN_NVC0(chan, NVC0_3D(VTX_ATTR_DEFINE), 3); - OUT_RING (chan, VTX_ATTR(1, 2, FLOAT, 4)); - OUT_RINGf (chan, sx); - OUT_RINGf (chan, sy); + BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3); + PUSH_DATA (push, VTX_ATTR(1, 2, FLOAT, 4)); + PUSH_DATAf(push, sx); + PUSH_DATAf(push, sy); #if 1 - BEGIN_NVC0(chan, NVC0_3D(VTX_ATTR_DEFINE), 2); - OUT_RING (chan, VTX_ATTR(0, 2, USCALED, 2)); - OUT_RING (chan, (dy << 16) | dx); + BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 2); + PUSH_DATA (push, VTX_ATTR(0, 2, USCALED, 2)); + PUSH_DATA (push, (dy << 16) | dx); #else - BEGIN_NVC0(chan, NVC0_3D(VTX_ATTR_DEFINE), 3); - OUT_RING (chan, VTX_ATTR(0, 2, FLOAT, 4)); - OUT_RINGf (chan, (float)dx); - OUT_RINGf (chan, (float)dy); + BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3); + PUSH_DATA (push, VTX_ATTR(0, 2, FLOAT, 4)); + PUSH_DATAf(push, (float)dx); + PUSH_DATAf(push, (float)dy); #endif } @@ -62,25 +72,25 @@ static __inline__ void VTX2s(NVPtr pNv, float s1x, float s1y, float s2x, float s2y, unsigned dx, unsigned dy) { - struct nouveau_channel *chan = pNv->chan; + struct nouveau_pushbuf *push = pNv->pushbuf; - BEGIN_NVC0(chan, NVC0_3D(VTX_ATTR_DEFINE), 3); - OUT_RING (chan, VTX_ATTR(1, 2, FLOAT, 4)); - OUT_RINGf (chan, s1x); - OUT_RINGf (chan, s1y); - BEGIN_NVC0(chan, NVC0_3D(VTX_ATTR_DEFINE), 3); - OUT_RING (chan, VTX_ATTR(2, 2, FLOAT, 4)); - OUT_RINGf (chan, s2x); - OUT_RINGf (chan, s2y); + BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3); + PUSH_DATA (push, VTX_ATTR(1, 2, FLOAT, 4)); + PUSH_DATAf(push, s1x); + PUSH_DATAf(push, s1y); + BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3); + PUSH_DATA (push, VTX_ATTR(2, 2, FLOAT, 4)); + PUSH_DATAf(push, s2x); + PUSH_DATAf(push, s2y); #if 1 - BEGIN_NVC0(chan, NVC0_3D(VTX_ATTR_DEFINE), 2); - OUT_RING (chan, VTX_ATTR(0, 2, USCALED, 2)); - OUT_RING (chan, (dy << 16) | dx); + BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 2); + PUSH_DATA (push, VTX_ATTR(0, 2, USCALED, 2)); + PUSH_DATA (push, (dy << 16) | dx); #else - BEGIN_NVC0(chan, NVC0_3D(VTX_ATTR_DEFINE), 3); - OUT_RING (chan, VTX_ATTR(0, 2, FLOAT, 4)); - OUT_RINGf (chan, (float)dx); - OUT_RINGf (chan, (float)dy); + BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3); + PUSH_DATA (push, VTX_ATTR(0, 2, FLOAT, 4)); + PUSH_DATAf(push, (float)dx); + PUSH_DATAf(push, (float)dy); #endif } diff --git a/src/nvc0_exa.c b/src/nvc0_exa.c index d7f4f58..a8713da 100644 --- a/src/nvc0_exa.c +++ b/src/nvc0_exa.c @@ -39,10 +39,10 @@ struct nvc0_exa_state { static struct nvc0_exa_state exa_state; -#define NVC0EXA_LOCALS(p) \ - ScrnInfoPtr pScrn = xf86Screens[(p)->drawable.pScreen->myNum]; \ - NVPtr pNv = NVPTR(pScrn); \ - struct nouveau_channel *chan = pNv->chan; (void)chan; \ +#define NVC0EXA_LOCALS(p) \ + ScrnInfoPtr pScrn = xf86Screens[(p)->drawable.pScreen->myNum]; \ + NVPtr pNv = NVPTR(pScrn); \ + struct nouveau_pushbuf *push = pNv->pushbuf; (void)push; \ struct nvc0_exa_state *state = &exa_state; (void)state #define BF(f) NV50_BLEND_FACTOR_##f @@ -96,53 +96,49 @@ static void NVC0EXASetClip(PixmapPtr ppix, int x, int y, int w, int h) { NVC0EXA_LOCALS(ppix); - BEGIN_NVC0(chan, NV50_2D(CLIP_X), 4); - OUT_RING (chan, x); - OUT_RING (chan, y); - OUT_RING (chan, w); - OUT_RING (chan, h); + BEGIN_NVC0(push, NV50_2D(CLIP_X), 4); + PUSH_DATA (push, x); + PUSH_DATA (push, y); + PUSH_DATA (push, w); + PUSH_DATA (push, h); } -static Bool -NVC0EXAAcquireSurface2D(PixmapPtr ppix, int is_src) +static void +NVC0EXAAcquireSurface2D(PixmapPtr ppix, int is_src, uint32_t fmt) { NVC0EXA_LOCALS(ppix); struct nouveau_bo *bo = nouveau_pixmap_bo(ppix); int mthd = is_src ? NV50_2D_SRC_FORMAT : NV50_2D_DST_FORMAT; - uint32_t fmt, bo_flags; - - if (!NVC0EXA2DSurfaceFormat(ppix, &fmt)) - return FALSE; + uint32_t bo_flags; bo_flags = NOUVEAU_BO_VRAM; bo_flags |= is_src ? NOUVEAU_BO_RD : NOUVEAU_BO_WR; if (!nv50_style_tiled_pixmap(ppix)) { - BEGIN_NVC0(chan, SUBC_2D(mthd), 2); - OUT_RING (chan, fmt); - OUT_RING (chan, 1); - BEGIN_NVC0(chan, SUBC_2D(mthd + 0x14), 1); - OUT_RING (chan, (uint32_t)exaGetPixmapPitch(ppix)); + BEGIN_NVC0(push, SUBC_2D(mthd), 2); + PUSH_DATA (push, fmt); + PUSH_DATA (push, 1); + BEGIN_NVC0(push, SUBC_2D(mthd + 0x14), 1); + PUSH_DATA (push, (uint32_t)exaGetPixmapPitch(ppix)); } else { - BEGIN_NVC0(chan, SUBC_2D(mthd), 5); - OUT_RING (chan, fmt); - OUT_RING (chan, 0); - OUT_RING (chan, bo->tile_mode); - OUT_RING (chan, 1); - OUT_RING (chan, 0); + BEGIN_NVC0(push, SUBC_2D(mthd), 5); + PUSH_DATA (push, fmt); + PUSH_DATA (push, 0); + PUSH_DATA (push, bo->config.nvc0.tile_mode); + PUSH_DATA (push, 1); + PUSH_DATA (push, 0); } - BEGIN_NVC0(chan, SUBC_2D(mthd + 0x18), 4); - OUT_RING (chan, ppix->drawable.width); - OUT_RING (chan, ppix->drawable.height); - if (OUT_RELOCh(chan, bo, 0, bo_flags) || - OUT_RELOCl(chan, bo, 0, bo_flags)) - return FALSE; + BEGIN_NVC0(push, SUBC_2D(mthd + 0x18), 4); + PUSH_DATA (push, ppix->drawable.width); + PUSH_DATA (push, ppix->drawable.height); + PUSH_DATA (push, bo->offset >> 32); + PUSH_DATA (push, bo->offset); if (is_src == 0) NVC0EXASetClip(ppix, 0, 0, ppix->drawable.width, ppix->drawable.height); - return TRUE; + PUSH_REFN (push, bo, bo_flags); } static void @@ -150,11 +146,11 @@ NVC0EXASetPattern(PixmapPtr pdpix, int col0, int col1, int pat0, int pat1) { NVC0EXA_LOCALS(pdpix); - BEGIN_NVC0(chan, NV50_2D(PATTERN_COLOR(0)), 4); - OUT_RING (chan, col0); - OUT_RING (chan, col1); - OUT_RING (chan, pat0); - OUT_RING (chan, pat1); + BEGIN_NVC0(push, NV50_2D(PATTERN_COLOR(0)), 4); + PUSH_DATA (push, col0); + PUSH_DATA (push, col1); + PUSH_DATA (push, pat0); + PUSH_DATA (push, pat1); } static void @@ -168,26 +164,26 @@ NVC0EXASetROP(PixmapPtr pdpix, int alu, Pixel planemask) else rop = NVROP[alu].copy; - BEGIN_NVC0(chan, NV50_2D(OPERATION), 1); + BEGIN_NVC0(push, NV50_2D(OPERATION), 1); if (alu == GXcopy && EXA_PM_IS_SOLID(&pdpix->drawable, planemask)) { - OUT_RING (chan, NV50_2D_OPERATION_SRCCOPY); + PUSH_DATA (push, NV50_2D_OPERATION_SRCCOPY); return; } else { - OUT_RING (chan, NV50_2D_OPERATION_ROP); + PUSH_DATA (push, NV50_2D_OPERATION_ROP); } - BEGIN_NVC0(chan, NV50_2D(PATTERN_COLOR_FORMAT), 2); + BEGIN_NVC0(push, NV50_2D(PATTERN_COLOR_FORMAT), 2); switch (pdpix->drawable.bitsPerPixel) { - case 8: OUT_RING (chan, 3); break; - case 15: OUT_RING (chan, 1); break; - case 16: OUT_RING (chan, 0); break; + case 8: PUSH_DATA (push, 3); break; + case 15: PUSH_DATA (push, 1); break; + case 16: PUSH_DATA (push, 0); break; case 24: case 32: default: - OUT_RING (chan, 2); + PUSH_DATA (push, 2); break; } - OUT_RING (chan, 1); + PUSH_DATA (push, 1); /* There are 16 ALUs. * 0-15: copy @@ -203,22 +199,12 @@ NVC0EXASetROP(PixmapPtr pdpix, int alu, Pixel planemask) } if (pNv->currentRop != alu) { - BEGIN_NVC0(chan, NV50_2D(ROP), 1); - OUT_RING (chan, rop); + BEGIN_NVC0(push, NV50_2D(ROP), 1); + PUSH_DATA (push, rop); pNv->currentRop = alu; } } -static void -NVC0EXAStateSolidResubmit(struct nouveau_channel *chan) -{ - ScrnInfoPtr pScrn = chan->user_private; - NVPtr pNv = NVPTR(pScrn); - - NVC0EXAPrepareSolid(pNv->pdpix, pNv->alu, pNv->planemask, - pNv->fg_colour); -} - Bool NVC0EXAPrepareSolid(PixmapPtr pdpix, int alu, Pixel planemask, Pixel fg) { @@ -228,26 +214,24 @@ NVC0EXAPrepareSolid(PixmapPtr pdpix, int alu, Pixel planemask, Pixel fg) if (!NVC0EXA2DSurfaceFormat(pdpix, &fmt)) NOUVEAU_FALLBACK("rect format\n"); - if (MARK_RING(chan, 64, 4)) - NOUVEAU_FALLBACK("ring space\n"); - - if (!NVC0EXAAcquireSurface2D(pdpix, 0)) { - MARK_UNDO(chan); - NOUVEAU_FALLBACK("dest pixmap\n"); - } + if (!PUSH_SPACE(push, 64)) + NOUVEAU_FALLBACK("space\n"); + PUSH_RESET(push); + NVC0EXAAcquireSurface2D(pdpix, 0, fmt); NVC0EXASetROP(pdpix, alu, planemask); - BEGIN_NVC0(chan, NV50_2D(DRAW_SHAPE), 3); - OUT_RING (chan, NV50_2D_DRAW_SHAPE_RECTANGLES); - OUT_RING (chan, fmt); - OUT_RING (chan, fg); + BEGIN_NVC0(push, NV50_2D(DRAW_SHAPE), 3); + PUSH_DATA (push, NV50_2D_DRAW_SHAPE_RECTANGLES); + PUSH_DATA (push, fmt); + PUSH_DATA (push, fg); + + nouveau_pushbuf_bufctx(push, pNv->bufctx); + if (nouveau_pushbuf_validate(push)) { + nouveau_pushbuf_bufctx(push, NULL); + NOUVEAU_FALLBACK("validate\n"); + } - pNv->pdpix = pdpix; - pNv->alu = alu; - pNv->planemask = planemask; - pNv->fg_colour = fg; - chan->flush_notify = NVC0EXAStateSolidResubmit; return TRUE; } @@ -256,33 +240,24 @@ NVC0EXASolid(PixmapPtr pdpix, int x1, int y1, int x2, int y2) { NVC0EXA_LOCALS(pdpix); - WAIT_RING (chan, 5); - BEGIN_NVC0(chan, NV50_2D(DRAW_POINT32_X(0)), 4); - OUT_RING (chan, x1); - OUT_RING (chan, y1); - OUT_RING (chan, x2); - OUT_RING (chan, y2); + if (!PUSH_SPACE(push, 8)) + return; + + BEGIN_NVC0(push, NV50_2D(DRAW_POINT32_X(0)), 4); + PUSH_DATA (push, x1); + PUSH_DATA (push, y1); + PUSH_DATA (push, x2); + PUSH_DATA (push, y2); if ((x2 - x1) * (y2 - y1) >= 512) - FIRE_RING (chan); + PUSH_KICK(push); } void NVC0EXADoneSolid(PixmapPtr pdpix) { NVC0EXA_LOCALS(pdpix); - - chan->flush_notify = NULL; -} - -static void -NVC0EXAStateCopyResubmit(struct nouveau_channel *chan) -{ - ScrnInfoPtr pScrn = chan->user_private; - NVPtr pNv = NVPTR(pScrn); - - NVC0EXAPrepareCopy(pNv->pspix, pNv->pdpix, 0, 0, pNv->alu, - pNv->planemask); + nouveau_pushbuf_bufctx(push, NULL); } Bool @@ -290,27 +265,27 @@ NVC0EXAPrepareCopy(PixmapPtr pspix, PixmapPtr pdpix, int dx, int dy, int alu, Pixel planemask) { NVC0EXA_LOCALS(pdpix); + uint32_t src, dst; - if (MARK_RING(chan, 64, 4)) - NOUVEAU_FALLBACK("ring space\n"); - - if (!NVC0EXAAcquireSurface2D(pspix, 1)) { - MARK_UNDO(chan); - NOUVEAU_FALLBACK("src pixmap\n"); - } + if (!NVC0EXA2DSurfaceFormat(pspix, &src)) + NOUVEAU_FALLBACK("src format\n"); + if (!NVC0EXA2DSurfaceFormat(pdpix, &dst)) + NOUVEAU_FALLBACK("dst format\n"); - if (!NVC0EXAAcquireSurface2D(pdpix, 0)) { - MARK_UNDO(chan); - NOUVEAU_FALLBACK("dest pixmap\n"); - } + if (!PUSH_SPACE(push, 64)) + NOUVEAU_FALLBACK("space\n"); + PUSH_RESET(push); + NVC0EXAAcquireSurface2D(pspix, 1, src); + NVC0EXAAcquireSurface2D(pdpix, 0, dst); NVC0EXASetROP(pdpix, alu, planemask); - pNv->pspix = pspix; - pNv->pdpix = pdpix; - pNv->alu = alu; - pNv->planemask = planemask; - chan->flush_notify = NVC0EXAStateCopyResubmit; + nouveau_pushbuf_bufctx(push, pNv->bufctx); + if (nouveau_pushbuf_validate(push)) { + nouveau_pushbuf_bufctx(push, NULL); + NOUVEAU_FALLBACK("validate\n"); + } + return TRUE; } @@ -321,48 +296,36 @@ NVC0EXACopy(PixmapPtr pdpix, int srcX , int srcY, { NVC0EXA_LOCALS(pdpix); - WAIT_RING (chan, 17); - BEGIN_NVC0(chan, SUBC_2D(NV50_GRAPH_SERIALIZE), 1); - OUT_RING (chan, 0); - BEGIN_NVC0(chan, SUBC_2D(0x088c), 1); - OUT_RING (chan, 0); - BEGIN_NVC0(chan, NV50_2D(BLIT_DST_X), 12); - OUT_RING (chan, dstX); - OUT_RING (chan, dstY); - OUT_RING (chan, width); - OUT_RING (chan, height); - OUT_RING (chan, 0); /* DU,V_DX,Y_FRACT,INT */ - OUT_RING (chan, 1); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - OUT_RING (chan, 0); /* BLIT_SRC_X,Y_FRACT,INT */ - OUT_RING (chan, srcX); - OUT_RING (chan, 0); - OUT_RING (chan, srcY); + if (!PUSH_SPACE(push, 32)) + return; + + BEGIN_NVC0(push, SUBC_2D(NV50_GRAPH_SERIALIZE), 1); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, SUBC_2D(0x088c), 1); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, NV50_2D(BLIT_DST_X), 12); + PUSH_DATA (push, dstX); + PUSH_DATA (push, dstY); + PUSH_DATA (push, width); + PUSH_DATA (push, height); + PUSH_DATA (push, 0); /* DU,V_DX,Y_FRACT,INT */ + PUSH_DATA (push, 1); + PUSH_DATA (push, 0); + PUSH_DATA (push, 1); + PUSH_DATA (push, 0); /* BLIT_SRC_X,Y_FRACT,INT */ + PUSH_DATA (push, srcX); + PUSH_DATA (push, 0); + PUSH_DATA (push, srcY); if (width * height >= 512) - FIRE_RING (chan); + PUSH_KICK(push); } void NVC0EXADoneCopy(PixmapPtr pdpix) { NVC0EXA_LOCALS(pdpix); - - chan->flush_notify = NULL; -} - -static void -NVC0EXAStateSIFCResubmit(struct nouveau_channel *chan) -{ - ScrnInfoPtr pScrn = chan->user_private; - NVPtr pNv = NVPTR(pScrn); - - if (MARK_RING(pNv->chan, 32, 2)) - return; - - if (!NVC0EXAAcquireSurface2D(pNv->pdpix, 0)) - MARK_UNDO(pNv->chan); + nouveau_pushbuf_bufctx(push, NULL); } Bool @@ -373,42 +336,38 @@ NVC0EXAUploadSIFC(const char *src, int src_pitch, ScreenPtr pScreen = pdpix->drawable.pScreen; int line_dwords = (w * cpp + 3) / 4; uint32_t sifc_fmt; + Bool ret = FALSE; if (!NVC0EXA2DSurfaceFormat(pdpix, &sifc_fmt)) NOUVEAU_FALLBACK("hostdata format\n"); - if (MARK_RING(chan, 64, 2)) - return FALSE; + if (!PUSH_SPACE(push, 64)) + NOUVEAU_FALLBACK("pushbuf\n"); + PUSH_RESET(push); - if (!NVC0EXAAcquireSurface2D(pdpix, 0)) { - MARK_UNDO(chan); - NOUVEAU_FALLBACK("dest pixmap\n"); - } - - /* If the pitch isn't aligned to a dword you can - * get corruption at the end of a line. - */ + NVC0EXAAcquireSurface2D(pdpix, 0, sifc_fmt); NVC0EXASetClip(pdpix, x, y, w, h); - BEGIN_NVC0(chan, NV50_2D(OPERATION), 1); - OUT_RING (chan, NV50_2D_OPERATION_SRCCOPY); - BEGIN_NVC0(chan, NV50_2D(SIFC_BITMAP_ENABLE), 2); - OUT_RING (chan, 0); - OUT_RING (chan, sifc_fmt); - BEGIN_NVC0(chan, NV50_2D(SIFC_WIDTH), 10); - OUT_RING (chan, (line_dwords * 4) / cpp); - OUT_RING (chan, h); - OUT_RING (chan, 0); /* SIFC_DX,Y_DU,V_FRACT,INT */ - OUT_RING (chan, 1); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - OUT_RING (chan, 0); /* SIFC_DST_X,Y_FRACT,INT */ - OUT_RING (chan, x); - OUT_RING (chan, 0); - OUT_RING (chan, y); - - pNv->pdpix = pdpix; - chan->flush_notify = NVC0EXAStateSIFCResubmit; + BEGIN_NVC0(push, NV50_2D(OPERATION), 1); + PUSH_DATA (push, NV50_2D_OPERATION_SRCCOPY); + BEGIN_NVC0(push, NV50_2D(SIFC_BITMAP_ENABLE), 2); + PUSH_DATA (push, 0); + PUSH_DATA (push, sifc_fmt); + BEGIN_NVC0(push, NV50_2D(SIFC_WIDTH), 10); + PUSH_DATA (push, (line_dwords * 4) / cpp); + PUSH_DATA (push, h); + PUSH_DATA (push, 0); /* SIFC_DX,Y_DU,V_FRACT,INT */ + PUSH_DATA (push, 1); + PUSH_DATA (push, 0); + PUSH_DATA (push, 1); + PUSH_DATA (push, 0); /* SIFC_DST_X,Y_FRACT,INT */ + PUSH_DATA (push, x); + PUSH_DATA (push, 0); + PUSH_DATA (push, y); + + nouveau_pushbuf_bufctx(push, pNv->bufctx); + if (nouveau_pushbuf_validate(push)) + goto out; while (h--) { const char *ptr = src; @@ -417,9 +376,10 @@ NVC0EXAUploadSIFC(const char *src, int src_pitch, while (count) { int size = count > 1792 ? 1792 : count; - WAIT_RING (chan, size + 1); - BEGIN_NIC0(chan, NV50_2D(SIFC_DATA), size); - OUT_RINGp (chan, ptr, size); + if (!PUSH_SPACE(push, size + 1)) + goto out; + BEGIN_NIC0(push, NV50_2D(SIFC_DATA), size); + PUSH_DATAp(push, ptr, size); ptr += size * 4; count -= size; @@ -428,11 +388,12 @@ NVC0EXAUploadSIFC(const char *src, int src_pitch, src += src_pitch; } - chan->flush_notify = NULL; - + ret = TRUE; +out: + nouveau_pushbuf_bufctx(push, NULL); if (pdpix == pScreen->GetScreenPixmap(pScreen)) - FIRE_RING(chan); - return TRUE; + PUSH_KICK(push); + return ret; } static Bool @@ -495,17 +456,15 @@ NVC0EXARenderTarget(PixmapPtr ppix, PicturePtr ppict) NOUVEAU_FALLBACK("invalid picture format\n"); } - BEGIN_NVC0(chan, NVC0_3D(RT_ADDRESS_HIGH(0)), 8); - if (OUT_RELOCh(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR) || - OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR)) - return FALSE; - OUT_RING (chan, ppix->drawable.width); - OUT_RING (chan, ppix->drawable.height); - OUT_RING (chan, format); - OUT_RING (chan, bo->tile_mode); - OUT_RING (chan, 0x00000001); - OUT_RING (chan, 0x00000000); - + BEGIN_NVC0(push, NVC0_3D(RT_ADDRESS_HIGH(0)), 8); + PUSH_DATA (push, bo->offset >> 32); + PUSH_DATA (push, bo->offset); + PUSH_DATA (push, ppix->drawable.width); + PUSH_DATA (push, ppix->drawable.height); + PUSH_DATA (push, format); + PUSH_DATA (push, bo->config.nvc0.tile_mode); + PUSH_DATA (push, 0x00000001); + PUSH_DATA (push, 0x00000000); return TRUE; } @@ -581,174 +540,156 @@ NVC0EXATexture(PixmapPtr ppix, PicturePtr ppict, unsigned unit) { NVC0EXA_LOCALS(ppix); struct nouveau_bo *bo = nouveau_pixmap_bo(ppix); - const unsigned tcb_flags = NOUVEAU_BO_RDWR | NOUVEAU_BO_VRAM; + uint64_t tic = pNv->tesla_scratch->offset + TIC_OFFSET + (unit * 32); + uint64_t tsc = pNv->tesla_scratch->offset + TSC_OFFSET + (unit * 32); uint32_t mode; /* XXX: maybe add support for linear textures at some point */ if (!nv50_style_tiled_pixmap(ppix)) NOUVEAU_FALLBACK("pixmap is scanout buffer\n"); - BEGIN_NVC0(chan, NVC0_3D(TIC_ADDRESS_HIGH), 3); - if (OUT_RELOCh(chan, pNv->tesla_scratch, TIC_OFFSET, tcb_flags) || - OUT_RELOCl(chan, pNv->tesla_scratch, TIC_OFFSET, tcb_flags)) - return FALSE; - OUT_RING (chan, 15); - - BEGIN_NVC0(chan, NVC0_M2MF(OFFSET_OUT_HIGH), 2); - if (OUT_RELOCh(chan, pNv->tesla_scratch, - TIC_OFFSET + unit * 32, tcb_flags) || - OUT_RELOCl(chan, pNv->tesla_scratch, - TIC_OFFSET + unit * 32, tcb_flags)) - return FALSE; - BEGIN_NVC0(chan, NVC0_M2MF(LINE_LENGTH_IN), 2); - OUT_RING (chan, 8 * 4); - OUT_RING (chan, 1); - BEGIN_NVC0(chan, NVC0_M2MF(EXEC), 1); - OUT_RING (chan, 0x100111); - BEGIN_NIC0(chan, NVC0_M2MF(DATA), 8); + BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2); + PUSH_DATA (push, tic >> 32); + PUSH_DATA (push, tic); + BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2); + PUSH_DATA (push, 8 * 4); + PUSH_DATA (push, 1); + BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1); + PUSH_DATA (push, 0x100111); + BEGIN_NIC0(push, NVC0_M2MF(DATA), 8); switch (ppict->format) { case PICT_a8r8g8b8: - OUT_RING(chan, _(B_C0, G_C1, R_C2, A_C3, 8_8_8_8)); + PUSH_DATA (push, _(B_C0, G_C1, R_C2, A_C3, 8_8_8_8)); break; case PICT_a8b8g8r8: - OUT_RING(chan, _(R_C0, G_C1, B_C2, A_C3, 8_8_8_8)); + PUSH_DATA (push, _(R_C0, G_C1, B_C2, A_C3, 8_8_8_8)); break; case PICT_x8r8g8b8: - OUT_RING(chan, _(B_C0, G_C1, R_C2, A_ONE, 8_8_8_8)); + PUSH_DATA (push, _(B_C0, G_C1, R_C2, A_ONE, 8_8_8_8)); break; case PICT_x8b8g8r8: - OUT_RING(chan, _(R_C0, G_C1, B_C2, A_ONE, 8_8_8_8)); + PUSH_DATA (push, _(R_C0, G_C1, B_C2, A_ONE, 8_8_8_8)); break; case PICT_r5g6b5: - OUT_RING(chan, _(B_C0, G_C1, R_C2, A_ONE, 5_6_5)); + PUSH_DATA (push, _(B_C0, G_C1, R_C2, A_ONE, 5_6_5)); break; case PICT_a8: - OUT_RING(chan, _(A_C0, B_ZERO, G_ZERO, R_ZERO, 8)); + PUSH_DATA (push, _(A_C0, B_ZERO, G_ZERO, R_ZERO, 8)); break; case PICT_x1r5g5b5: - OUT_RING(chan, _(B_C0, G_C1, R_C2, A_ONE, 1_5_5_5)); + PUSH_DATA (push, _(B_C0, G_C1, R_C2, A_ONE, 1_5_5_5)); break; case PICT_x1b5g5r5: - OUT_RING(chan, _(R_C0, G_C1, B_C2, A_ONE, 1_5_5_5)); + PUSH_DATA (push, _(R_C0, G_C1, B_C2, A_ONE, 1_5_5_5)); break; case PICT_a1r5g5b5: - OUT_RING(chan, _(B_C0, G_C1, R_C2, A_C3, 1_5_5_5)); + PUSH_DATA (push, _(B_C0, G_C1, R_C2, A_C3, 1_5_5_5)); break; case PICT_a1b5g5r5: - OUT_RING(chan, _(R_C0, G_C1, B_C2, A_C3, 1_5_5_5)); + PUSH_DATA (push, _(R_C0, G_C1, B_C2, A_C3, 1_5_5_5)); break; case PICT_b5g6r5: - OUT_RING(chan, _(R_C0, G_C1, B_C2, A_ONE, 5_6_5)); + PUSH_DATA (push, _(R_C0, G_C1, B_C2, A_ONE, 5_6_5)); break; case PICT_b8g8r8x8: - OUT_RING(chan, _(A_ONE, R_C1, G_C2, B_C3, 8_8_8_8)); + PUSH_DATA (push, _(A_ONE, R_C1, G_C2, B_C3, 8_8_8_8)); break; case PICT_b8g8r8a8: - OUT_RING(chan, _(A_C0, R_C1, G_C2, B_C3, 8_8_8_8)); + PUSH_DATA (push, _(A_C0, R_C1, G_C2, B_C3, 8_8_8_8)); break; case PICT_a2b10g10r10: - OUT_RING(chan, _(R_C0, G_C1, B_C2, A_C3, 2_10_10_10)); + PUSH_DATA (push, _(R_C0, G_C1, B_C2, A_C3, 2_10_10_10)); break; case PICT_x2b10g10r10: - OUT_RING(chan, _(R_C0, G_C1, B_C2, A_ONE, 2_10_10_10)); + PUSH_DATA (push, _(R_C0, G_C1, B_C2, A_ONE, 2_10_10_10)); break; case PICT_x2r10g10b10: - OUT_RING(chan, _(B_C0, G_C1, R_C2, A_ONE, 2_10_10_10)); + PUSH_DATA (push, _(B_C0, G_C1, R_C2, A_ONE, 2_10_10_10)); break; case PICT_a2r10g10b10: - OUT_RING(chan, _(B_C0, G_C1, R_C2, A_C3, 2_10_10_10)); + PUSH_DATA (push, _(B_C0, G_C1, R_C2, A_C3, 2_10_10_10)); break; case PICT_x4r4g4b4: - OUT_RING(chan, _(B_C0, G_C1, R_C2, A_ONE, 4_4_4_4)); + PUSH_DATA (push, _(B_C0, G_C1, R_C2, A_ONE, 4_4_4_4)); break; case PICT_x4b4g4r4: - OUT_RING(chan, _(R_C0, G_C1, B_C2, A_ONE, 4_4_4_4)); + PUSH_DATA (push, _(R_C0, G_C1, B_C2, A_ONE, 4_4_4_4)); break; case PICT_a4r4g4b4: - OUT_RING(chan, _(B_C0, G_C1, R_C2, A_C3, 4_4_4_4)); + PUSH_DATA (push, _(B_C0, G_C1, R_C2, A_C3, 4_4_4_4)); break; case PICT_a4b4g4r4: - OUT_RING(chan, _(R_C0, G_C1, B_C2, A_C3, 4_4_4_4)); + PUSH_DATA (push, _(R_C0, G_C1, B_C2, A_C3, 4_4_4_4)); break; default: NOUVEAU_FALLBACK("invalid picture format, this SHOULD NOT HAPPEN. Expect trouble.\n"); } #undef _ - mode = 0xd0005000 | (bo->tile_mode << (22 - 4)); - if (OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD) || - OUT_RELOCd(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | - NOUVEAU_BO_HIGH | NOUVEAU_BO_OR, mode, mode)) - return FALSE; - OUT_RING (chan, 0x00300000); - OUT_RING (chan, (1 << 31) | ppix->drawable.width); - OUT_RING (chan, (1 << 16) | ppix->drawable.height); - OUT_RING (chan, 0x03000000); - OUT_RING (chan, 0x00000000); - - BEGIN_NVC0(chan, NVC0_3D(TSC_ADDRESS_HIGH), 3); - if (OUT_RELOCh(chan, pNv->tesla_scratch, TSC_OFFSET, tcb_flags) || - OUT_RELOCl(chan, pNv->tesla_scratch, TSC_OFFSET, tcb_flags)) - return FALSE; - OUT_RING (chan, 0); - - BEGIN_NVC0(chan, NVC0_M2MF(OFFSET_OUT_HIGH), 2); - if (OUT_RELOCh(chan, pNv->tesla_scratch, - TSC_OFFSET + unit * 32, tcb_flags) || - OUT_RELOCl(chan, pNv->tesla_scratch, - TSC_OFFSET + unit * 32, tcb_flags)) - return FALSE; - BEGIN_NVC0(chan, NVC0_M2MF(LINE_LENGTH_IN), 2); - OUT_RING (chan, 8 * 4); - OUT_RING (chan, 1); - BEGIN_NVC0(chan, NVC0_M2MF(EXEC), 1); - OUT_RING (chan, 0x100111); - BEGIN_NIC0(chan, NVC0_M2MF(DATA), 8); + mode = 0xd0005000 | (bo->config.nvc0.tile_mode << (22 - 4)); + PUSH_DATA (push, bo->offset); + PUSH_DATA (push, (bo->offset >> 32) | mode | + (bo->config.nvc0.tile_mode << 18)); + PUSH_DATA (push, 0x00300000); + PUSH_DATA (push, (1 << 31) | ppix->drawable.width); + PUSH_DATA (push, (1 << 16) | ppix->drawable.height); + PUSH_DATA (push, 0x03000000); + PUSH_DATA (push, 0x00000000); + + BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2); + PUSH_DATA (push, tsc >> 32); + PUSH_DATA (push, tsc); + BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2); + PUSH_DATA (push, 8 * 4); + PUSH_DATA (push, 1); + BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1); + PUSH_DATA (push, 0x100111); + BEGIN_NIC0(push, NVC0_M2MF(DATA), 8); if (ppict->repeat) { switch (ppict->repeatType) { case RepeatPad: - OUT_RING (chan, 0x00024000 | + PUSH_DATA (push, 0x00024000 | NV50TSC_1_0_WRAPS_CLAMP | NV50TSC_1_0_WRAPT_CLAMP | NV50TSC_1_0_WRAPR_CLAMP); break; case RepeatReflect: - OUT_RING (chan, 0x00024000 | + PUSH_DATA (push, 0x00024000 | NV50TSC_1_0_WRAPS_MIRROR_REPEAT | NV50TSC_1_0_WRAPT_MIRROR_REPEAT | NV50TSC_1_0_WRAPR_MIRROR_REPEAT); break; case RepeatNormal: default: - OUT_RING (chan, 0x00024000 | + PUSH_DATA (push, 0x00024000 | NV50TSC_1_0_WRAPS_REPEAT | NV50TSC_1_0_WRAPT_REPEAT | NV50TSC_1_0_WRAPR_REPEAT); break; } } else { - OUT_RING (chan, 0x00024000 | + PUSH_DATA (push, 0x00024000 | NV50TSC_1_0_WRAPS_CLAMP_TO_BORDER | NV50TSC_1_0_WRAPT_CLAMP_TO_BORDER | NV50TSC_1_0_WRAPR_CLAMP_TO_BORDER); } if (ppict->filter == PictFilterBilinear) { - OUT_RING (chan, + PUSH_DATA (push, NV50TSC_1_1_MAGF_LINEAR | NV50TSC_1_1_MINF_LINEAR | NV50TSC_1_1_MIPF_NONE); } else { - OUT_RING (chan, + PUSH_DATA (push, NV50TSC_1_1_MAGF_NEAREST | NV50TSC_1_1_MINF_NEAREST | NV50TSC_1_1_MIPF_NONE); } - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RINGf (chan, 0.0f); - OUT_RINGf (chan, 0.0f); - OUT_RINGf (chan, 0.0f); - OUT_RINGf (chan, 0.0f); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATAf(push, 0.0f); + PUSH_DATAf(push, 0.0f); + PUSH_DATAf(push, 0.0f); + PUSH_DATAf(push, 0.0f); state->unit[unit].width = ppix->drawable.width; state->unit[unit].height = ppix->drawable.height; @@ -791,19 +732,19 @@ NVC0EXABlend(PixmapPtr ppix, PicturePtr ppict, int op, int component_alpha) } if (sblend == BF(ONE) && dblend == BF(ZERO)) { - BEGIN_NVC0(chan, NVC0_3D(BLEND_ENABLE(0)), 1); - OUT_RING (chan, 0); + BEGIN_NVC0(push, NVC0_3D(BLEND_ENABLE(0)), 1); + PUSH_DATA (push, 0); } else { - BEGIN_NVC0(chan, NVC0_3D(BLEND_ENABLE(0)), 1); - OUT_RING (chan, 1); - BEGIN_NVC0(chan, NVC0_3D(BLEND_EQUATION_RGB), 5); - OUT_RING (chan, NVC0_3D_BLEND_EQUATION_RGB_FUNC_ADD); - OUT_RING (chan, sblend); - OUT_RING (chan, dblend); - OUT_RING (chan, NVC0_3D_BLEND_EQUATION_ALPHA_FUNC_ADD); - OUT_RING (chan, sblend); - BEGIN_NVC0(chan, NVC0_3D(BLEND_FUNC_DST_ALPHA), 1); - OUT_RING (chan, dblend); + BEGIN_NVC0(push, NVC0_3D(BLEND_ENABLE(0)), 1); + PUSH_DATA (push, 1); + BEGIN_NVC0(push, NVC0_3D(BLEND_EQUATION_RGB), 5); + PUSH_DATA (push, NVC0_3D_BLEND_EQUATION_RGB_FUNC_ADD); + PUSH_DATA (push, sblend); + PUSH_DATA (push, dblend); + PUSH_DATA (push, NVC0_3D_BLEND_EQUATION_ALPHA_FUNC_ADD); + PUSH_DATA (push, sblend); + BEGIN_NVC0(push, NVC0_3D(BLEND_FUNC_DST_ALPHA), 1); + PUSH_DATA (push, dblend); } } @@ -834,110 +775,88 @@ NVC0EXACheckComposite(int op, return TRUE; } -static void -NVC0EXAStateCompositeResubmit(struct nouveau_channel *chan) -{ - ScrnInfoPtr pScrn = chan->user_private; - NVPtr pNv = NVPTR(pScrn); - - NVC0EXAPrepareComposite(pNv->alu, pNv->pspict, pNv->pmpict, pNv->pdpict, - pNv->pspix, pNv->pmpix, pNv->pdpix); -} - Bool NVC0EXAPrepareComposite(int op, PicturePtr pspict, PicturePtr pmpict, PicturePtr pdpict, PixmapPtr pspix, PixmapPtr pmpix, PixmapPtr pdpix) { + struct nouveau_bo *src = nouveau_pixmap_bo(pspix); + struct nouveau_bo *dst = nouveau_pixmap_bo(pdpix); + struct nouveau_bo *mask = pmpix ? nouveau_pixmap_bo(pmpix) : NULL; NVC0EXA_LOCALS(pspix); - const unsigned shd_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD; - - if (MARK_RING (chan, 128, 4 + 2 + 2 * 10)) - NOUVEAU_FALLBACK("ring space\n"); - // fonts: !pmpict, op == 12 (Add, ONE/ONE) - /* - if (pmpict || op != 12) - NOUVEAU_FALLBACK("comp-alpha"); - */ + if (!PUSH_SPACE(push, 256)) + NOUVEAU_FALLBACK("space\n"); - BEGIN_NVC0(chan, SUBC_2D(NV50_GRAPH_SERIALIZE), 1); - OUT_RING (chan, 0); + BEGIN_NVC0(push, SUBC_2D(NV50_GRAPH_SERIALIZE), 1); + PUSH_DATA (push, 0); - if (!NVC0EXARenderTarget(pdpix, pdpict)) { - MARK_UNDO(chan); + if (!NVC0EXARenderTarget(pdpix, pdpict)) NOUVEAU_FALLBACK("render target invalid\n"); - } NVC0EXABlend(pdpix, pdpict, op, pmpict && pmpict->componentAlpha && PICT_FORMAT_RGB(pmpict->format)); - BEGIN_NVC0(chan, NVC0_3D(CODE_ADDRESS_HIGH), 2); - if (OUT_RELOCh(chan, pNv->tesla_scratch, CODE_OFFSET, shd_flags) || - OUT_RELOCl(chan, pNv->tesla_scratch, CODE_OFFSET, shd_flags)) { - MARK_UNDO(chan); - return FALSE; - } - - if (!NVC0EXATexture(pspix, pspict, 0)) { - MARK_UNDO(chan); + if (!NVC0EXATexture(pspix, pspict, 0)) NOUVEAU_FALLBACK("src picture invalid\n"); - } - BEGIN_NVC0(chan, NVC0_3D(BIND_TIC(4)), 1); - OUT_RING (chan, (0 << 9) | (0 << 1) | NVC0_3D_BIND_TIC_ACTIVE); + BEGIN_NVC0(push, NVC0_3D(BIND_TIC(4)), 1); + PUSH_DATA (push, (0 << 9) | (0 << 1) | NVC0_3D_BIND_TIC_ACTIVE); if (pmpict) { - if (!NVC0EXATexture(pmpix, pmpict, 1)) { - MARK_UNDO(chan); + if (!NVC0EXATexture(pmpix, pmpict, 1)) NOUVEAU_FALLBACK("mask picture invalid\n"); - } state->have_mask = TRUE; - BEGIN_NVC0(chan, NVC0_3D(BIND_TIC(4)), 1); - OUT_RING (chan, (1 << 9) | (1 << 1) | NVC0_3D_BIND_TIC_ACTIVE); + BEGIN_NVC0(push, NVC0_3D(BIND_TIC(4)), 1); + PUSH_DATA (push, (1 << 9) | (1 << 1) | NVC0_3D_BIND_TIC_ACTIVE); - BEGIN_NVC0(chan, NVC0_3D(SP_START_ID(5)), 1); + BEGIN_NVC0(push, NVC0_3D(SP_START_ID(5)), 1); if (pdpict->format == PICT_a8) { - OUT_RING (chan, PFP_C_A8); + PUSH_DATA (push, PFP_C_A8); } else { if (pmpict->componentAlpha && PICT_FORMAT_RGB(pmpict->format)) { if (NVC0EXABlendOp[op].src_alpha) - OUT_RING (chan, PFP_CCASA); + PUSH_DATA (push, PFP_CCASA); else - OUT_RING (chan, PFP_CCA); + PUSH_DATA (push, PFP_CCA); } else { - OUT_RING (chan, PFP_C); + PUSH_DATA (push, PFP_C); } } } else { state->have_mask = FALSE; - BEGIN_NVC0(chan, NVC0_3D(BIND_TIC(4)), 1); - OUT_RING (chan, (1 << 1) | 0); + BEGIN_NVC0(push, NVC0_3D(BIND_TIC(4)), 1); + PUSH_DATA (push, (1 << 1) | 0); - BEGIN_NVC0(chan, NVC0_3D(SP_START_ID(5)), 1); + BEGIN_NVC0(push, NVC0_3D(SP_START_ID(5)), 1); if (pdpict->format == PICT_a8) - OUT_RING (chan, PFP_S_A8); + PUSH_DATA (push, PFP_S_A8); else - OUT_RING (chan, PFP_S); + PUSH_DATA (push, PFP_S); + } + + BEGIN_NVC0(push, NVC0_3D(TSC_FLUSH), 1); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, NVC0_3D(TIC_FLUSH), 1); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, NVC0_3D(TEX_CACHE_CTL), 1); + PUSH_DATA (push, 0); + + PUSH_RESET(push); + PUSH_REFN (push, pNv->tesla_scratch, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); + PUSH_REFN (push, src, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + PUSH_REFN (push, dst, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + if (pmpict) + PUSH_REFN (push, mask, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + + nouveau_pushbuf_bufctx(push, pNv->bufctx); + if (nouveau_pushbuf_validate(push)) { + nouveau_pushbuf_bufctx(push, NULL); + NOUVEAU_FALLBACK("validate\n"); } - BEGIN_NVC0(chan, NVC0_3D(TSC_FLUSH), 1); - OUT_RING (chan, 0); - BEGIN_NVC0(chan, NVC0_3D(TIC_FLUSH), 1); - OUT_RING (chan, 0); - BEGIN_NVC0(chan, NVC0_3D(TEX_CACHE_CTL), 1); - OUT_RING (chan, 0); - - pNv->alu = op; - pNv->pspict = pspict; - pNv->pmpict = pmpict; - pNv->pdpict = pdpict; - pNv->pspix = pspix; - pNv->pmpix = pmpix; - pNv->pdpix = pdpix; - chan->flush_notify = NVC0EXAStateCompositeResubmit; return TRUE; } @@ -971,12 +890,14 @@ NVC0EXAComposite(PixmapPtr pdpix, NVC0EXA_LOCALS(pdpix); float sX0, sX1, sX2, sY0, sY1, sY2; - WAIT_RING (chan, 64); - BEGIN_NVC0(chan, NVC0_3D(SCISSOR_HORIZ(0)), 2); - OUT_RING (chan, ((dx + w) << 16) | dx); - OUT_RING (chan, ((dy + h) << 16) | dy); - BEGIN_NVC0(chan, NVC0_3D(VERTEX_BEGIN_GL), 1); - OUT_RING (chan, NVC0_3D_VERTEX_BEGIN_GL_PRIMITIVE_TRIANGLES); + if (!PUSH_SPACE(push, 64)) + return; + + BEGIN_NVC0(push, NVC0_3D(SCISSOR_HORIZ(0)), 2); + PUSH_DATA (push, ((dx + w) << 16) | dx); + PUSH_DATA (push, ((dy + h) << 16) | dy); + BEGIN_NVC0(push, NVC0_3D(VERTEX_BEGIN_GL), 1); + PUSH_DATA (push, NVC0_3D_VERTEX_BEGIN_GL_PRIMITIVE_TRIANGLES); NVC0EXATransform(state->unit[0].transform, sx, sy + (h * 2), state->unit[0].width, state->unit[0].height, @@ -1010,16 +931,15 @@ NVC0EXAComposite(PixmapPtr pdpix, VTX1s(pNv, sX2, sY2, dx + (w * 2), dy); } - BEGIN_NVC0(chan, NVC0_3D(VERTEX_END_GL), 1); - OUT_RING (chan, 0); + BEGIN_NVC0(push, NVC0_3D(VERTEX_END_GL), 1); + PUSH_DATA (push, 0); } void NVC0EXADoneComposite(PixmapPtr pdpix) { NVC0EXA_LOCALS(pdpix); - - chan->flush_notify = NULL; + nouveau_pushbuf_bufctx(push, NULL); } Bool @@ -1029,35 +949,41 @@ NVC0EXARectM2MF(NVPtr pNv, int w, int h, int cpp, struct nouveau_bo *dst, uint32_t dst_off, int dst_dom, int dst_pitch, int dst_h, int dst_x, int dst_y) { - struct nouveau_grobj *m2mf = pNv->NvMemFormat; - struct nouveau_channel *chan = m2mf->channel; + struct nouveau_pushbuf_refn refs[] = { + { src, src_dom | NOUVEAU_BO_RD }, + { dst, dst_dom | NOUVEAU_BO_WR }, + }; + struct nouveau_pushbuf *push = pNv->pushbuf; unsigned exec = 0; - if (src->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK) { - BEGIN_NVC0(chan, NVC0_M2MF(TILING_MODE_IN), 5); - OUT_RING (chan, src->tile_mode); - OUT_RING (chan, src_pitch); - OUT_RING (chan, src_h); - OUT_RING (chan, 1); - OUT_RING (chan, 0); + if (!PUSH_SPACE(push, 64)) + return FALSE; + + if (src->config.nvc0.memtype) { + BEGIN_NVC0(push, NVC0_M2MF(TILING_MODE_IN), 5); + PUSH_DATA (push, src->config.nvc0.tile_mode); + PUSH_DATA (push, src_pitch); + PUSH_DATA (push, src_h); + PUSH_DATA (push, 1); + PUSH_DATA (push, 0); } else { - BEGIN_NVC0(chan, NVC0_M2MF(PITCH_IN), 1); - OUT_RING (chan, src_pitch); + BEGIN_NVC0(push, NVC0_M2MF(PITCH_IN), 1); + PUSH_DATA (push, src_pitch); src_off += src_y * src_pitch + src_x * cpp; exec |= NVC0_M2MF_EXEC_LINEAR_IN; } - if (dst->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK) { - BEGIN_NVC0(chan, NVC0_M2MF(TILING_MODE_OUT), 5); - OUT_RING (chan, dst->tile_mode); - OUT_RING (chan, dst_pitch); - OUT_RING (chan, dst_h); - OUT_RING (chan, 1); - OUT_RING (chan, 0); + if (dst->config.nvc0.memtype) { + BEGIN_NVC0(push, NVC0_M2MF(TILING_MODE_OUT), 5); + PUSH_DATA (push, dst->config.nvc0.tile_mode); + PUSH_DATA (push, dst_pitch); + PUSH_DATA (push, dst_h); + PUSH_DATA (push, 1); + PUSH_DATA (push, 0); } else { - BEGIN_NVC0(chan, NVC0_M2MF(PITCH_OUT), 1); - OUT_RING (chan, dst_pitch); + BEGIN_NVC0(push, NVC0_M2MF(PITCH_OUT), 1); + PUSH_DATA (push, dst_pitch); dst_off += dst_y * dst_pitch + dst_x * cpp; exec |= NVC0_M2MF_EXEC_LINEAR_OUT; @@ -1068,44 +994,38 @@ NVC0EXARectM2MF(NVPtr pNv, int w, int h, int cpp, if (line_count > 2047) line_count = 2047; - if (MARK_RING (chan, 32, 4)) - return FALSE; - - BEGIN_NVC0(chan, NVC0_M2MF(OFFSET_OUT_HIGH), 2); - if (OUT_RELOCh(chan, dst, dst_off, dst_dom | NOUVEAU_BO_WR) || - OUT_RELOCl(chan, dst, dst_off, dst_dom | NOUVEAU_BO_WR)) { - MARK_UNDO(chan); + if (nouveau_pushbuf_space(push, 32, 0, 0) || + nouveau_pushbuf_refn (push, refs, 2)) return FALSE; - } - - BEGIN_NVC0(chan, NVC0_M2MF(OFFSET_IN_HIGH), 2); - if (OUT_RELOCh(chan, src, src_off, src_dom | NOUVEAU_BO_RD) || - OUT_RELOCl(chan, src, src_off, src_dom | NOUVEAU_BO_RD)) { - MARK_UNDO(chan); - return FALSE; - } - if (src->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK) { - BEGIN_NVC0(chan, NVC0_M2MF(TILING_POSITION_IN_X), 2); - OUT_RING (chan, src_x * cpp); - OUT_RING (chan, src_y); + BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2); + PUSH_DATA (push, (dst->offset + dst_off) >> 32); + PUSH_DATA (push, (dst->offset + dst_off)); + BEGIN_NVC0(push, NVC0_M2MF(OFFSET_IN_HIGH), 2); + PUSH_DATA (push, (src->offset + src_off) >> 32); + PUSH_DATA (push, (src->offset + src_off)); + + if (src->config.nvc0.memtype) { + BEGIN_NVC0(push, NVC0_M2MF(TILING_POSITION_IN_X), 2); + PUSH_DATA (push, src_x * cpp); + PUSH_DATA (push, src_y); } else { src_off += line_count * src_pitch; } - if (dst->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK) { - BEGIN_NVC0(chan, NVC0_M2MF(TILING_POSITION_OUT_X), 2); - OUT_RING (chan, dst_x * cpp); - OUT_RING (chan, dst_y); + if (dst->config.nvc0.memtype) { + BEGIN_NVC0(push, NVC0_M2MF(TILING_POSITION_OUT_X), 2); + PUSH_DATA (push, dst_x * cpp); + PUSH_DATA (push, dst_y); } else { dst_off += line_count * dst_pitch; } - BEGIN_NVC0(chan, NVC0_M2MF(LINE_LENGTH_IN), 2); - OUT_RING (chan, w * cpp); - OUT_RING (chan, line_count); - BEGIN_NVC0(chan, NVC0_M2MF(EXEC), 1); - OUT_RING (chan, NVC0_M2MF_EXEC_QUERY_SHORT | exec); + BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2); + PUSH_DATA (push, w * cpp); + PUSH_DATA (push, line_count); + BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1); + PUSH_DATA (push, NVC0_M2MF_EXEC_QUERY_SHORT | exec); src_y += line_count; dst_y += line_count; diff --git a/src/nvc0_xv.c b/src/nvc0_xv.c index 42d0ff7..96ae223 100644 --- a/src/nvc0_xv.c +++ b/src/nvc0_xv.c @@ -55,237 +55,179 @@ nvc0_xv_check_image_put(PixmapPtr ppix) return TRUE; } -static Bool -nvc0_xv_state_emit(PixmapPtr ppix, int id, struct nouveau_bo *src, - int packed_y, int uv, int src_w, int src_h) +int +nvc0_xv_image_put(ScrnInfoPtr pScrn, + struct nouveau_bo *src, int packed_y, int uv, + int id, int src_pitch, BoxPtr dstBox, + int x1, int y1, int x2, int y2, + uint16_t width, uint16_t height, + uint16_t src_w, uint16_t src_h, + uint16_t drw_w, uint16_t drw_h, + RegionPtr clipBoxes, PixmapPtr ppix, + NVPortPrivPtr pPriv) { - ScrnInfoPtr pScrn = xf86Screens[ppix->drawable.pScreen->myNum]; NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; - struct nouveau_bo *bo = nouveau_pixmap_bo(ppix); - const unsigned shd_flags = NOUVEAU_BO_RD | NOUVEAU_BO_VRAM; - const unsigned tcb_flags = NOUVEAU_BO_RDWR | NOUVEAU_BO_VRAM; - uint32_t mode = 0xd0005000 | (src->tile_mode << 18); - - if (MARK_RING(chan, 256, 18)) - return FALSE; - - BEGIN_NVC0(chan, NVC0_3D(RT_ADDRESS_HIGH(0)), 8); - if (OUT_RELOCh(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR) || - OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR)) { - MARK_UNDO(chan); - return FALSE; - } - OUT_RING (chan, ppix->drawable.width); - OUT_RING (chan, ppix->drawable.height); - switch (ppix->drawable.bitsPerPixel) { - case 32: OUT_RING (chan, NV50_SURFACE_FORMAT_BGRA8_UNORM); break; - case 24: OUT_RING (chan, NV50_SURFACE_FORMAT_BGRX8_UNORM); break; - case 16: OUT_RING (chan, NV50_SURFACE_FORMAT_B5G6R5_UNORM); break; - case 15: OUT_RING (chan, NV50_SURFACE_FORMAT_BGR5_X1_UNORM); break; - } - OUT_RING (chan, bo->tile_mode); - OUT_RING (chan, 1); - OUT_RING (chan, 0); + struct nouveau_bo *dst = nouveau_pixmap_bo(ppix); + struct nouveau_pushbuf_refn refs[] = { + { pNv->tesla_scratch, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR }, + { src, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD }, + { dst, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR }, + }; + struct nouveau_pushbuf *push = pNv->pushbuf; + uint32_t mode = 0xd0005000 | (src->config.nvc0.tile_mode << 18); + float X1, X2, Y1, Y2; + BoxPtr pbox; + int nbox; - BEGIN_NVC0(chan, NVC0_3D(BLEND_ENABLE(0)), 1); - OUT_RING (chan, 0); + if (!nvc0_xv_check_image_put(ppix)) + return BadMatch; - BEGIN_NVC0(chan, NVC0_3D(TIC_ADDRESS_HIGH), 3); - if (OUT_RELOCh(chan, pNv->tesla_scratch, TIC_OFFSET, tcb_flags) || - OUT_RELOCl(chan, pNv->tesla_scratch, TIC_OFFSET, tcb_flags)) { - MARK_UNDO(chan); - return FALSE; - } - OUT_RING (chan, 15); + if (!PUSH_SPACE(push, 256)) + return BadImplementation; - BEGIN_NVC0(chan, NVC0_M2MF(OFFSET_OUT_HIGH), 2); - if (OUT_RELOCh(chan, pNv->tesla_scratch, TIC_OFFSET, tcb_flags) || - OUT_RELOCl(chan, pNv->tesla_scratch, TIC_OFFSET, tcb_flags)) { - MARK_UNDO(chan); - return FALSE; + BEGIN_NVC0(push, NVC0_3D(RT_ADDRESS_HIGH(0)), 8); + PUSH_DATA (push, dst->offset >> 32); + PUSH_DATA (push, dst->offset); + PUSH_DATA (push, ppix->drawable.width); + PUSH_DATA (push, ppix->drawable.height); + switch (ppix->drawable.bitsPerPixel) { + case 32: PUSH_DATA (push, NV50_SURFACE_FORMAT_BGRA8_UNORM); break; + case 24: PUSH_DATA (push, NV50_SURFACE_FORMAT_BGRX8_UNORM); break; + case 16: PUSH_DATA (push, NV50_SURFACE_FORMAT_B5G6R5_UNORM); break; + case 15: PUSH_DATA (push, NV50_SURFACE_FORMAT_BGR5_X1_UNORM); break; } - BEGIN_NVC0(chan, NVC0_M2MF(LINE_LENGTH_IN), 2); - OUT_RING (chan, 16 * 4); - OUT_RING (chan, 1); - BEGIN_NVC0(chan, NVC0_M2MF(EXEC), 1); - OUT_RING (chan, 0x00100111); - BEGIN_NIC0(chan, NVC0_M2MF(DATA), 16); + PUSH_DATA (push, dst->config.nvc0.tile_mode); + PUSH_DATA (push, 1); + PUSH_DATA (push, 0); + + BEGIN_NVC0(push, NVC0_3D(BLEND_ENABLE(0)), 1); + PUSH_DATA (push, 0); + + BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2); + PUSH_DATA (push, (pNv->tesla_scratch->offset + TIC_OFFSET) >> 32); + PUSH_DATA (push, (pNv->tesla_scratch->offset + TIC_OFFSET)); + BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2); + PUSH_DATA (push, 16 * 4); + PUSH_DATA (push, 1); + BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1); + PUSH_DATA (push, 0x00100111); + BEGIN_NIC0(push, NVC0_M2MF(DATA), 16); if (id == FOURCC_YV12 || id == FOURCC_I420) { - OUT_RING (chan, NV50TIC_0_0_MAPA_C0 | NV50TIC_0_0_TYPEA_UNORM | + PUSH_DATA (push, NV50TIC_0_0_MAPA_C0 | NV50TIC_0_0_TYPEA_UNORM | NV50TIC_0_0_MAPB_ZERO | NV50TIC_0_0_TYPEB_UNORM | NV50TIC_0_0_MAPG_ZERO | NV50TIC_0_0_TYPEG_UNORM | NV50TIC_0_0_MAPR_ZERO | NV50TIC_0_0_TYPER_UNORM | NV50TIC_0_0_FMT_8); - if (OUT_RELOCl(chan, src, packed_y, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD) || - OUT_RELOC (chan, src, packed_y, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | - NOUVEAU_BO_HIGH | NOUVEAU_BO_OR, mode, mode)) { - MARK_UNDO(chan); - return FALSE; - } - OUT_RING (chan, 0x00300000); - OUT_RING (chan, src_w); - OUT_RING (chan, (1 << NV50TIC_0_5_DEPTH_SHIFT) | src_h); - OUT_RING (chan, 0x03000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, NV50TIC_0_0_MAPA_C1 | NV50TIC_0_0_TYPEA_UNORM | + PUSH_DATA (push, ((src->offset + packed_y))); + PUSH_DATA (push, ((src->offset + packed_y) >> 32) | mode); + PUSH_DATA (push, 0x00300000); + PUSH_DATA (push, width); + PUSH_DATA (push, (1 << NV50TIC_0_5_DEPTH_SHIFT) | height); + PUSH_DATA (push, 0x03000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, NV50TIC_0_0_MAPA_C1 | NV50TIC_0_0_TYPEA_UNORM | NV50TIC_0_0_MAPB_C0 | NV50TIC_0_0_TYPEB_UNORM | NV50TIC_0_0_MAPG_ZERO | NV50TIC_0_0_TYPEG_UNORM | NV50TIC_0_0_MAPR_ZERO | NV50TIC_0_0_TYPER_UNORM | NV50TIC_0_0_FMT_8_8); - if (OUT_RELOCl(chan, src, uv, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD) || - OUT_RELOC (chan, src, uv, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | - NOUVEAU_BO_HIGH | NOUVEAU_BO_OR, mode, mode)) { - MARK_UNDO(chan); - return FALSE; - } - OUT_RING (chan, 0x00300000); - OUT_RING (chan, src_w >> 1); - OUT_RING (chan, (1 << NV50TIC_0_5_DEPTH_SHIFT) | (src_h >> 1)); - OUT_RING (chan, 0x03000000); - OUT_RING (chan, 0x00000000); + PUSH_DATA (push, ((src->offset + uv))); + PUSH_DATA (push, ((src->offset + uv) >> 32) | mode); + PUSH_DATA (push, 0x00300000); + PUSH_DATA (push, width >> 1); + PUSH_DATA (push, (1 << NV50TIC_0_5_DEPTH_SHIFT) | (height >> 1)); + PUSH_DATA (push, 0x03000000); + PUSH_DATA (push, 0x00000000); } else { if (id == FOURCC_UYVY) { - OUT_RING (chan, NV50TIC_0_0_MAPA_C1 | NV50TIC_0_0_TYPEA_UNORM | + PUSH_DATA (push, NV50TIC_0_0_MAPA_C1 | NV50TIC_0_0_TYPEA_UNORM | NV50TIC_0_0_MAPB_ZERO | NV50TIC_0_0_TYPEB_UNORM | NV50TIC_0_0_MAPG_ZERO | NV50TIC_0_0_TYPEG_UNORM | NV50TIC_0_0_MAPR_ZERO | NV50TIC_0_0_TYPER_UNORM | NV50TIC_0_0_FMT_8_8); } else { - OUT_RING (chan, NV50TIC_0_0_MAPA_C0 | NV50TIC_0_0_TYPEA_UNORM | + PUSH_DATA (push, NV50TIC_0_0_MAPA_C0 | NV50TIC_0_0_TYPEA_UNORM | NV50TIC_0_0_MAPB_ZERO | NV50TIC_0_0_TYPEB_UNORM | NV50TIC_0_0_MAPG_ZERO | NV50TIC_0_0_TYPEG_UNORM | NV50TIC_0_0_MAPR_ZERO | NV50TIC_0_0_TYPER_UNORM | NV50TIC_0_0_FMT_8_8); } - if (OUT_RELOCl(chan, src, packed_y, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD) || - OUT_RELOC (chan, src, packed_y, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | - NOUVEAU_BO_HIGH | NOUVEAU_BO_OR, mode, mode)) { - MARK_UNDO(chan); - return FALSE; - } - OUT_RING (chan, 0x00300000); - OUT_RING (chan, src_w); - OUT_RING (chan, (1 << NV50TIC_0_5_DEPTH_SHIFT) | src_h); - OUT_RING (chan, 0x03000000); - OUT_RING (chan, 0x00000000); + PUSH_DATA (push, ((src->offset + packed_y))); + PUSH_DATA (push, ((src->offset + packed_y) >> 32) | mode); + PUSH_DATA (push, 0x00300000); + PUSH_DATA (push, width); + PUSH_DATA (push, (1 << NV50TIC_0_5_DEPTH_SHIFT) | height); + PUSH_DATA (push, 0x03000000); + PUSH_DATA (push, 0x00000000); if (id == FOURCC_UYVY) { - OUT_RING (chan, NV50TIC_0_0_MAPA_C2 | NV50TIC_0_0_TYPEA_UNORM | + PUSH_DATA (push, NV50TIC_0_0_MAPA_C2 | NV50TIC_0_0_TYPEA_UNORM | NV50TIC_0_0_MAPB_C0 | NV50TIC_0_0_TYPEB_UNORM | NV50TIC_0_0_MAPG_ZERO | NV50TIC_0_0_TYPEG_UNORM | NV50TIC_0_0_MAPR_ZERO | NV50TIC_0_0_TYPER_UNORM | NV50TIC_0_0_FMT_8_8_8_8); } else { - OUT_RING (chan, NV50TIC_0_0_MAPA_C3 | NV50TIC_0_0_TYPEA_UNORM | + PUSH_DATA (push, NV50TIC_0_0_MAPA_C3 | NV50TIC_0_0_TYPEA_UNORM | NV50TIC_0_0_MAPB_C1 | NV50TIC_0_0_TYPEB_UNORM | NV50TIC_0_0_MAPG_ZERO | NV50TIC_0_0_TYPEG_UNORM | NV50TIC_0_0_MAPR_ZERO | NV50TIC_0_0_TYPER_UNORM | NV50TIC_0_0_FMT_8_8_8_8); } - if (OUT_RELOCl(chan, src, packed_y, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD) || - OUT_RELOC (chan, src, packed_y, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | - NOUVEAU_BO_HIGH | NOUVEAU_BO_OR, mode, mode)) { - MARK_UNDO(chan); - return FALSE; - } - OUT_RING (chan, 0x00300000); - OUT_RING (chan, (src_w >> 1)); - OUT_RING (chan, (1 << NV50TIC_0_5_DEPTH_SHIFT) | src_h); - OUT_RING (chan, 0x03000000); - OUT_RING (chan, 0x00000000); + PUSH_DATA (push, ((src->offset + packed_y))); + PUSH_DATA (push, ((src->offset + packed_y) >> 32) | mode); + PUSH_DATA (push, 0x00300000); + PUSH_DATA (push, (width >> 1)); + PUSH_DATA (push, (1 << NV50TIC_0_5_DEPTH_SHIFT) | height); + PUSH_DATA (push, 0x03000000); + PUSH_DATA (push, 0x00000000); } - BEGIN_NVC0(chan, NVC0_3D(TSC_ADDRESS_HIGH), 3); - if (OUT_RELOCh(chan, pNv->tesla_scratch, TSC_OFFSET, tcb_flags) || - OUT_RELOCl(chan, pNv->tesla_scratch, TSC_OFFSET, tcb_flags)) { - MARK_UNDO(chan); - return FALSE; - } - OUT_RING (chan, 0x00000000); - - BEGIN_NVC0(chan, NVC0_M2MF(OFFSET_OUT_HIGH), 2); - if (OUT_RELOCh(chan, pNv->tesla_scratch, TSC_OFFSET, tcb_flags) || - OUT_RELOCl(chan, pNv->tesla_scratch, TSC_OFFSET, tcb_flags)) { - MARK_UNDO(chan); - return FALSE; - } - BEGIN_NVC0(chan, NVC0_M2MF(LINE_LENGTH_IN), 2); - OUT_RING (chan, 16 * 4); - OUT_RING (chan, 1); - BEGIN_NVC0(chan, NVC0_M2MF(EXEC), 1); - OUT_RING (chan, 0x00100111); - BEGIN_NIC0(chan, NVC0_M2MF(DATA), 16); - OUT_RING (chan, NV50TSC_1_0_WRAPS_CLAMP_TO_EDGE | + BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2); + PUSH_DATA (push, (pNv->tesla_scratch->offset + TSC_OFFSET) >> 32); + PUSH_DATA (push, (pNv->tesla_scratch->offset + TSC_OFFSET)); + BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2); + PUSH_DATA (push, 16 * 4); + PUSH_DATA (push, 1); + BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1); + PUSH_DATA (push, 0x00100111); + BEGIN_NIC0(push, NVC0_M2MF(DATA), 16); + PUSH_DATA (push, NV50TSC_1_0_WRAPS_CLAMP_TO_EDGE | NV50TSC_1_0_WRAPT_CLAMP_TO_EDGE | NV50TSC_1_0_WRAPR_CLAMP_TO_EDGE); - OUT_RING (chan, NV50TSC_1_1_MAGF_LINEAR | + PUSH_DATA (push, NV50TSC_1_1_MAGF_LINEAR | NV50TSC_1_1_MINF_LINEAR | NV50TSC_1_1_MIPF_NONE); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, NV50TSC_1_0_WRAPS_CLAMP_TO_EDGE | + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, NV50TSC_1_0_WRAPS_CLAMP_TO_EDGE | NV50TSC_1_0_WRAPT_CLAMP_TO_EDGE | NV50TSC_1_0_WRAPR_CLAMP_TO_EDGE); - OUT_RING (chan, NV50TSC_1_1_MAGF_LINEAR | + PUSH_DATA (push, NV50TSC_1_1_MAGF_LINEAR | NV50TSC_1_1_MINF_LINEAR | NV50TSC_1_1_MIPF_NONE); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - - BEGIN_NVC0(chan, NVC0_3D(CODE_ADDRESS_HIGH), 2); - if (OUT_RELOCh(chan, pNv->tesla_scratch, CODE_OFFSET, shd_flags) || - OUT_RELOCl(chan, pNv->tesla_scratch, CODE_OFFSET, shd_flags)) { - MARK_UNDO(chan); - return FALSE; - - } - BEGIN_NVC0(chan, NVC0_3D(SP_START_ID(5)), 1); - OUT_RING (chan, PFP_NV12); - - BEGIN_NVC0(chan, NVC0_3D(TSC_FLUSH), 1); - OUT_RING (chan, 0); - BEGIN_NVC0(chan, NVC0_3D(TIC_FLUSH), 1); - OUT_RING (chan, 0); - BEGIN_NVC0(chan, NVC0_3D(TEX_CACHE_CTL), 1); - OUT_RING (chan, 0); - - BEGIN_NVC0(chan, NVC0_3D(BIND_TIC(4)), 1); - OUT_RING (chan, 1); - BEGIN_NVC0(chan, NVC0_3D(BIND_TIC(4)), 1); - OUT_RING (chan, 0x203); - - return TRUE; -} - -int -nvc0_xv_image_put(ScrnInfoPtr pScrn, - struct nouveau_bo *src, int packed_y, int uv, - int id, int src_pitch, BoxPtr dstBox, - int x1, int y1, int x2, int y2, - uint16_t width, uint16_t height, - uint16_t src_w, uint16_t src_h, - uint16_t drw_w, uint16_t drw_h, - RegionPtr clipBoxes, PixmapPtr ppix, - NVPortPrivPtr pPriv) -{ - NVPtr pNv = NVPTR(pScrn); - struct nouveau_channel *chan = pNv->chan; - float X1, X2, Y1, Y2; - BoxPtr pbox; - int nbox; - - if (!nvc0_xv_check_image_put(ppix)) - return BadMatch; - if (!nvc0_xv_state_emit(ppix, id, src, packed_y, uv, width, height)) - return BadAlloc; + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + PUSH_DATA (push, 0x00000000); + + BEGIN_NVC0(push, NVC0_3D(SP_START_ID(5)), 1); + PUSH_DATA (push, PFP_NV12); + + BEGIN_NVC0(push, NVC0_3D(TSC_FLUSH), 1); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, NVC0_3D(TIC_FLUSH), 1); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, NVC0_3D(TEX_CACHE_CTL), 1); + PUSH_DATA (push, 0); + + BEGIN_NVC0(push, NVC0_3D(BIND_TIC(4)), 1); + PUSH_DATA (push, 1); + BEGIN_NVC0(push, NVC0_3D(BIND_TIC(4)), 1); + PUSH_DATA (push, 0x203); if (0 && pPriv->SyncToVBlank) { NV50SyncToVBlank(ppix, dstBox); @@ -314,57 +256,54 @@ nvc0_xv_image_put(ScrnInfoPtr pScrn, ty1 = ty1 / height; ty2 = ty2 / height; - if (AVAIL_RING(chan) < 64) { - if (!nvc0_xv_state_emit(ppix, id, src, packed_y, uv, - width, height)) - return BadAlloc; - } + if (nouveau_pushbuf_space(push, 64, 0, 0) || + nouveau_pushbuf_refn (push, refs, 3)) + return BadImplementation; - BEGIN_NVC0(chan, NVC0_3D(SCISSOR_HORIZ(0)), 2); - OUT_RING (chan, sx2 << NVC0_3D_SCISSOR_HORIZ_MAX__SHIFT | sx1); - OUT_RING (chan, sy2 << NVC0_3D_SCISSOR_VERT_MAX__SHIFT | sy1 ); + BEGIN_NVC0(push, NVC0_3D(SCISSOR_HORIZ(0)), 2); + PUSH_DATA (push, sx2 << NVC0_3D_SCISSOR_HORIZ_MAX__SHIFT | sx1); + PUSH_DATA (push, sy2 << NVC0_3D_SCISSOR_VERT_MAX__SHIFT | sy1 ); - BEGIN_NVC0(chan, NVC0_3D(VERTEX_BEGIN_GL), 1); - OUT_RING (chan, NVC0_3D_VERTEX_BEGIN_GL_PRIMITIVE_TRIANGLES); + BEGIN_NVC0(push, NVC0_3D(VERTEX_BEGIN_GL), 1); + PUSH_DATA (push, NVC0_3D_VERTEX_BEGIN_GL_PRIMITIVE_TRIANGLES); VTX2s(pNv, tx1, ty1, tx1, ty1, sx1, sy1); VTX2s(pNv, tx2+(tx2-tx1), ty1, tx2+(tx2-tx1), ty1, sx2+(sx2-sx1), sy1); VTX2s(pNv, tx1, ty2+(ty2-ty1), tx1, ty2+(ty2-ty1), sx1, sy2+(sy2-sy1)); - BEGIN_NVC0(chan, NVC0_3D(VERTEX_END_GL), 1); - OUT_RING (chan, 0); + BEGIN_NVC0(push, NVC0_3D(VERTEX_END_GL), 1); + PUSH_DATA (push, 0); pbox++; } - FIRE_RING (chan); + PUSH_KICK(push); return Success; } void nvc0_xv_csc_update(NVPtr pNv, float yco, float *off, float *uco, float *vco) { - struct nouveau_channel *chan = pNv->chan; - struct nouveau_bo *bo = pNv->tesla_scratch; + struct nouveau_pushbuf *push = pNv->pushbuf; - if (MARK_RING(chan, 64, 2)) + if (nouveau_pushbuf_space(push, 64, 0, 0) || + nouveau_pushbuf_refn (push, &(struct nouveau_pushbuf_refn) { + pNv->tesla_scratch, NOUVEAU_BO_WR | + NOUVEAU_BO_VRAM }, 1)) return; - BEGIN_NVC0(chan, NVC0_3D(CB_SIZE), 3); - OUT_RING (chan, 256); - if (OUT_RELOCh(chan, bo, CB_OFFSET, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR) || - OUT_RELOCl(chan, bo, CB_OFFSET, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR)) { - MARK_UNDO(chan); - return; - } - BEGIN_NVC0(chan, NVC0_3D(CB_POS), 11); - OUT_RING (chan, 0); - OUT_RINGf (chan, yco); - OUT_RINGf (chan, off[0]); - OUT_RINGf (chan, off[1]); - OUT_RINGf (chan, off[2]); - OUT_RINGf (chan, uco[0]); - OUT_RINGf (chan, uco[1]); - OUT_RINGf (chan, uco[2]); - OUT_RINGf (chan, vco[0]); - OUT_RINGf (chan, vco[1]); - OUT_RINGf (chan, vco[2]); + BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3); + PUSH_DATA (push, 256); + PUSH_DATA (push, (pNv->tesla_scratch->offset + CB_OFFSET) >> 32); + PUSH_DATA (push, (pNv->tesla_scratch->offset + CB_OFFSET)); + BEGIN_NVC0(push, NVC0_3D(CB_POS), 11); + PUSH_DATA (push, 0); + PUSH_DATAf(push, yco); + PUSH_DATAf(push, off[0]); + PUSH_DATAf(push, off[1]); + PUSH_DATAf(push, off[2]); + PUSH_DATAf(push, uco[0]); + PUSH_DATAf(push, uco[1]); + PUSH_DATAf(push, uco[2]); + PUSH_DATAf(push, vco[0]); + PUSH_DATAf(push, vco[1]); + PUSH_DATAf(push, vco[2]); } -- cgit v1.2.1