From 4959912bf7cc7fb386260da107bc0f136bdb56ad Mon Sep 17 00:00:00 2001 From: Jeff Hartmann Date: Sun, 6 Feb 2000 21:42:21 +0000 Subject: [PATCH] Iload stuff + bugfixes --- linux/mga_clear.c | 40 ++++++++++++-- linux/mga_dma.c | 119 ++++++++++++++++++++++++++++++++--------- linux/mga_dma.h | 1 - linux/mga_drm_public.h | 7 +-- 4 files changed, 132 insertions(+), 35 deletions(-) diff --git a/linux/mga_clear.c b/linux/mga_clear.c index eee18ba2..2a83218b 100644 --- a/linux/mga_clear.c +++ b/linux/mga_clear.c @@ -132,7 +132,7 @@ static int mgaClearBuffers(drm_device_t *dev, d.send_count = 1; d.send_indices = &buf->idx; d.send_sizes = &buf->used; - d.flags = _DRM_DMA_GENERAL; + d.flags = _DRM_DMA_WHILE_LOCKED; d.request_count = 0; d.request_size = 0; d.request_indices = NULL; @@ -202,7 +202,7 @@ int mgaSwapBuffers(drm_device_t *dev, int flags) d.send_count = 1; d.send_indices = &buf->idx; d.send_sizes = &buf->used; - d.flags = _DRM_DMA_GENERAL; + d.flags = _DRM_DMA_WHILE_LOCKED; d.request_count = 0; d.request_size = 0; d.request_indices = NULL; @@ -215,20 +215,50 @@ int mgaSwapBuffers(drm_device_t *dev, int flags) } -static int mgaIload( drm_device_t *dev, drm_mga_iload_t *args ) +static int mgaIload(drm_device_t *dev, drm_mga_iload_t *args) { + drm_device_dma_t *dma = dev->dma; + drm_buf_t *buf = dma->buflist[ args->idx ]; + drm_mga_buf_priv_t *buf_priv = (drm_mga_buf_priv_t *)buf->dev_private; + drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_dma_t d; + + buf_priv->dma_type = MGA_DMA_ILOAD; + buf_priv->boxes[0].y1 = args->texture.y1; + buf_priv->boxes[0].y2 = args->texture.y2; + buf_priv->boxes[0].x1 = args->texture.x1; + buf_priv->boxes[0].x2 = args->texture.x2; + buf_priv->ContextState[MGA_CTXREG_DSTORG] = args->destOrg; + buf_priv->ContextState[MGA_CTXREG_MACCESS] = args->mAccess; + buf_priv->nbox = 1; + sarea_priv->dirty |= MGASAREA_NEW_CONTEXT; + + d.context = DRM_KERNEL_CONTEXT; + d.send_count = 1; + d.send_indices = &buf->idx; + d.send_sizes = &buf->used; + d.flags = _DRM_DMA_WHILE_LOCKED; + d.request_count = 0; + d.request_size = 0; + d.request_indices = NULL; + d.request_sizes = NULL; + d.granted_count = 0; + + drm_dma_enqueue(dev, &d); + mga_dma_schedule(dev, 1); + return 0; } /* Necessary? Not necessary?? */ -static int check_lock( void ) +static int check_lock(void) { return 1; } - int mga_clear_bufs(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { diff --git a/linux/mga_dma.c b/linux/mga_dma.c index a828f838..09eece1d 100644 --- a/linux/mga_dma.c +++ b/linux/mga_dma.c @@ -218,48 +218,106 @@ int mga_dma_init(struct inode *inode, struct file *filp, return -EINVAL; } - #define MGA_ILOAD_CMD (DC_opcod_iload | DC_atype_rpl | \ DC_linear_linear | DC_bltmod_bfcol | \ (0xC << DC_bop_SHIFT) | DC_sgnzero_enable | \ DC_shftzero_enable | DC_clipdis_enable) -/* This needs a lot of work (see mgatex.c) - */ -static void mga_dma_dispatch_iload(drm_device_t *dev, drm_buf_t *buf) +static void __mga_iload_small(drm_device_t *dev, + drm_buf_t *buf, + int use_agp) { drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_buf_priv_t *buf_priv = buf->dev_private; - unsigned long address = (unsigned long)buf->bus_address; + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + unsigned long address = (unsigned long)buf->bus_address; int length = buf->used; - int use_agp = PDEA_pagpxfer_enable; int y1 = buf_priv->boxes[0].y1; int x1 = buf_priv->boxes[0].x1; int y2 = buf_priv->boxes[0].y2; int x2 = buf_priv->boxes[0].x2; + int dstorg = buf_priv->ContextState[MGA_CTXREG_DSTORG]; + int maccess = buf_priv->ContextState[MGA_CTXREG_MACCESS]; PRIMLOCALS; PRIMRESET(dev_priv); PRIMGETPTR(dev_priv); - - PRIMOUTREG( MGAREG_YDSTLEN, (y1 << 16) | (y2 - y1)); - PRIMOUTREG( MGAREG_FXBNDRY, (x2 << 16) | x1); - PRIMOUTREG( MGAREG_AR0, (x2 - x1) * (y2 - y1 - 1)); - PRIMOUTREG( MGAREG_AR3, 0 ); - PRIMOUTREG( MGAREG_DMAPAD, 0); - PRIMOUTREG( MGAREG_DMAPAD, 0); - PRIMOUTREG( MGAREG_DMAPAD, 0); - PRIMOUTREG( MGAREG_DWGCTL+MGAREG_MGA_EXEC, MGA_ILOAD_CMD); - PRIMOUTREG( MGAREG_DMAPAD, 0); - PRIMOUTREG( MGAREG_DMAPAD, 0); - PRIMOUTREG( MGAREG_SECADDRESS, address | TT_BLIT); - PRIMOUTREG( MGAREG_SECEND, (address + length) | use_agp); - PRIMOUTREG( MGAREG_DMAPAD, 0); - PRIMOUTREG( MGAREG_DMAPAD, 0); - PRIMOUTREG( MGAREG_DWGSYNC, 0); - PRIMOUTREG( MGAREG_SOFTRAP, 0); + + PRIMOUTREG(MGAREG_DSTORG, dstorg | use_agp); + PRIMOUTREG(MGAREG_MACCESS, maccess); + PRIMOUTREG(MGAREG_PITCH, (1 << 15)); + PRIMOUTREG(MGAREG_YDST, y1 * (x2 - x1)); + PRIMOUTREG(MGAREG_LEN, 1); + PRIMOUTREG(MGAREG_FXBNDRY, ((x2 - x1) * (y2 - y1) - 1) << 16); + PRIMOUTREG(MGAREG_AR0, (x2 - x1) * (y2 - y1) - 1); + PRIMOUTREG(MGAREG_AR3, 0); + PRIMOUTREG(MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_DWGCTL+MGAREG_MGA_EXEC, MGA_ILOAD_CMD); + PRIMOUTREG(MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_SECADDRESS, address | TT_BLIT); + PRIMOUTREG(MGAREG_SECEND, (address + length) | use_agp); + PRIMOUTREG(MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_DWGSYNC, 0); + PRIMOUTREG(MGAREG_SOFTRAP, 0); PRIMADVANCE(dev_priv); +#if 0 + /* For now we need to set this in the ioctl */ + sarea_priv->dirty |= MGASAREA_NEW_CONTEXT; +#endif + MGA_WRITE(MGAREG_DWGSYNC, MGA_SYNC_TAG); + while(MGA_READ(MGAREG_DWGSYNC) != MGA_SYNC_TAG) ; + MGA_WRITE(MGAREG_PRIMADDRESS, dev_priv->prim_phys_head | TT_GENERAL); + MGA_WRITE(MGAREG_PRIMEND, (phys_head + num_dwords * 4) | use_agp); +} + +static void __mga_iload_xy(drm_device_t *dev, + drm_buf_t *buf, + int use_agp) +{ + drm_mga_private_t *dev_priv = dev->dev_private; + drm_mga_buf_priv_t *buf_priv = buf->dev_private; + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + unsigned long address = (unsigned long)buf->bus_address; + int length = buf->used; + int y1 = buf_priv->boxes[0].y1; + int x1 = buf_priv->boxes[0].x1; + int y2 = buf_priv->boxes[0].y2; + int x2 = buf_priv->boxes[0].x2; + int dstorg = buf_priv->ContextState[MGA_CTXREG_DSTORG]; + int maccess = buf_priv->ContextState[MGA_CTXREG_MACCESS]; + PRIMLOCALS; + + PRIMRESET(dev_priv); + PRIMGETPTR(dev_priv); + PRIMOUTREG(MGAREG_DSTORG, dstorg | use_agp); + PRIMOUTREG(MGAREG_MACCESS, maccess); + PRIMOUTREG(MGAREG_PITCH, (x2 - x1)); + PRIMOUTREG(MGAREG_YDSTLEN, (y1 << 16) | (y2 - y1)); + + PRIMOUTREG(MGAREG_FXBNDRY, (x2 << 16) | x1); + PRIMOUTREG(MGAREG_AR0, (x2 - x1) * (y2 - y1 - 1)); + PRIMOUTREG(MGAREG_AR3, 0 ); + PRIMOUTREG(MGAREG_DWGCTL+MGAREG_MGA_EXEC, MGA_ILOAD_CMD); + + PRIMOUTREG(MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_SECADDRESS, address | TT_BLIT); + PRIMOUTREG(MGAREG_SECEND, (address + length) | use_agp); + + PRIMOUTREG(MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_DWGSYNC, 0); + PRIMOUTREG(MGAREG_SOFTRAP, 0); + PRIMADVANCE(dev_priv); +#if 0 + /* For now we need to set this in the ioctl */ + sarea_priv->dirty |= MGASAREA_NEW_CONTEXT; +#endif MGA_WRITE(MGAREG_DWGSYNC, MGA_SYNC_TAG); while(MGA_READ(MGAREG_DWGSYNC) != MGA_SYNC_TAG) ; @@ -267,6 +325,20 @@ static void mga_dma_dispatch_iload(drm_device_t *dev, drm_buf_t *buf) MGA_WRITE(MGAREG_PRIMEND, (phys_head + num_dwords * 4) | use_agp); } +static void mga_dma_dispatch_iload(drm_device_t *dev, drm_buf_t *buf) +{ + drm_mga_buf_priv_t *buf_priv = buf->dev_private; + + int use_agp = PDEA_pagpxfer_enable; + int x1 = buf_priv->boxes[0].x1; + int x2 = buf_priv->boxes[0].x2; + + if((x2 - x1) < 32) { + __mga_iload_small(dev, buf, use_agp); + } else { + __mga_iload_xy(dev, buf, use_agp); + } +} static void mga_dma_dispatch_vertex(drm_device_t *dev, drm_buf_t *buf) { @@ -345,7 +417,6 @@ static void mga_dma_dispatch_general(drm_device_t *dev, drm_buf_t *buf) MGA_WRITE(MGAREG_PRIMEND, (phys_head + num_dwords * 4) | use_agp); } - /* Frees dispatch lock */ static inline void mga_dma_quiescent(drm_device_t *dev) { diff --git a/linux/mga_dma.h b/linux/mga_dma.h index 2bd37a30..9dc557db 100644 --- a/linux/mga_dma.h +++ b/linux/mga_dma.h @@ -17,7 +17,6 @@ typedef struct { unsigned int nbox; xf86drmClipRectRec boxes[MGA_NR_SAREA_CLIPRECTS]; - } drm_mga_buf_priv_t; diff --git a/linux/mga_drm_public.h b/linux/mga_drm_public.h index 21968c39..47a62494 100644 --- a/linux/mga_drm_public.h +++ b/linux/mga_drm_public.h @@ -101,9 +101,6 @@ typedef struct drm_mga_init { int mAccess; } drm_mga_init_t; - - - typedef struct _xf86drmClipRectRec { unsigned short x1; unsigned short y1; @@ -128,8 +125,8 @@ typedef struct { typedef struct { unsigned int destOrg; unsigned int mAccess; - unsigned int pitch; - unsigned int x,y,width,height; + xf86drmClipRectRec texture; + int idx; } drm_mga_iload_t; /* Each context has a state: