⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mga_state.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 2 页
字号:
	PRIMOUTREG(MGAREG_DWGCTL, MGA_COPY_CMD);	PRIMOUTREG(MGAREG_AR0, 63);	PRIMOUTREG(MGAREG_AR3, 0);	PRIMOUTREG(MGAREG_FXBNDRY, (63 << 16));	PRIMOUTREG(MGAREG_YDSTLEN + MGAREG_MGA_EXEC, y2);	PRIMOUTREG(MGAREG_DMAPAD, 0);	PRIMOUTREG(MGAREG_SRCORG, 0);	PRIMOUTREG(MGAREG_PITCH, dev_priv->stride / dev_priv->cpp);	PRIMOUTREG(MGAREG_DWGSYNC, 0x7000);	PRIMADVANCE(dev_priv);}static void mga_dma_dispatch_vertex(drm_device_t * dev, drm_buf_t * buf){	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 use_agp = PDEA_pagpxfer_enable;	int i = 0;	PRIMLOCALS;	if (buf->used) {		/* WARNING: if you change any of the state functions verify		 * these numbers (Overestimating this doesn't hurt).		 */		buf_priv->dispatched = 1;		PRIM_OVERFLOW(dev, dev_priv,			      (MAX_STATE_SIZE + (5 * MGA_NR_SAREA_CLIPRECTS)));		mgaEmitState(dev_priv);#if 0		length = dev_priv->vertexsize * 3 * 4;#endif		do {			if (i < sarea_priv->nbox) {				mgaEmitClipRect(dev_priv,						&sarea_priv->boxes[i]);			}			PRIMGETPTR(dev_priv);			PRIMOUTREG(MGAREG_DMAPAD, 0);			PRIMOUTREG(MGAREG_DMAPAD, 0);			PRIMOUTREG(MGAREG_SECADDRESS,				   ((u32) address) | TT_VERTEX);			PRIMOUTREG(MGAREG_SECEND,				   (((u32) (address + length)) | use_agp));			PRIMADVANCE(dev_priv);		} while (++i < sarea_priv->nbox);	}	if (buf_priv->discard) {		if (buf_priv->dispatched == 1)			AGEBUF(dev_priv, buf_priv);		buf_priv->dispatched = 0;		mga_freelist_put(dev, buf);	}}static void mga_dma_dispatch_indices(drm_device_t * dev,				     drm_buf_t * buf,				     unsigned int start, unsigned int end){	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 int address = (unsigned int) buf->bus_address;	int use_agp = PDEA_pagpxfer_enable;	int i = 0;	PRIMLOCALS;	if (start != end) {		/* WARNING: if you change any of the state functions verify		 * these numbers (Overestimating this doesn't hurt).		 */		buf_priv->dispatched = 1;		PRIM_OVERFLOW(dev, dev_priv,			      (MAX_STATE_SIZE + (5 * MGA_NR_SAREA_CLIPRECTS)));		mgaEmitState(dev_priv);		do {			if (i < sarea_priv->nbox) {				mgaEmitClipRect(dev_priv,						&sarea_priv->boxes[i]);			}			PRIMGETPTR(dev_priv);			PRIMOUTREG(MGAREG_DMAPAD, 0);			PRIMOUTREG(MGAREG_DMAPAD, 0);			PRIMOUTREG(MGAREG_SETUPADDRESS,				   ((address + start) |				    SETADD_mode_vertlist));			PRIMOUTREG(MGAREG_SETUPEND,				   ((address + end) | use_agp));/*  				   ((address + start + 12) | use_agp)); */			PRIMADVANCE(dev_priv);		} while (++i < sarea_priv->nbox);	}	if (buf_priv->discard) {		if (buf_priv->dispatched == 1)			AGEBUF(dev_priv, buf_priv);		buf_priv->dispatched = 0;		mga_freelist_put(dev, buf);	}}static void mga_dma_dispatch_clear(drm_device_t * dev, int flags,				   unsigned int clear_color,				   unsigned int clear_zval,				   unsigned int clear_colormask,				   unsigned int clear_depthmask){	drm_mga_private_t *dev_priv = dev->dev_private;	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;	unsigned int *regs = sarea_priv->ContextState;	int nbox = sarea_priv->nbox;	drm_clip_rect_t *pbox = sarea_priv->boxes;	unsigned int cmd;	int i;	PRIMLOCALS;	if (dev_priv->sgram)		cmd = MGA_CLEAR_CMD | DC_atype_blk;	else		cmd = MGA_CLEAR_CMD | DC_atype_rstr;	PRIM_OVERFLOW(dev, dev_priv, 35 * MGA_NR_SAREA_CLIPRECTS);	for (i = 0; i < nbox; i++) {		unsigned int height = pbox[i].y2 - pbox[i].y1;		if (flags & MGA_FRONT) {			PRIMOUTREG(MGAREG_DMAPAD, 0);			PRIMOUTREG(MGAREG_PLNWT, clear_colormask);			PRIMOUTREG(MGAREG_YDSTLEN,				   (pbox[i].y1 << 16) | height);			PRIMOUTREG(MGAREG_FXBNDRY,				   (pbox[i].x2 << 16) | pbox[i].x1);			PRIMOUTREG(MGAREG_DMAPAD, 0);			PRIMOUTREG(MGAREG_FCOL, clear_color);			PRIMOUTREG(MGAREG_DSTORG, dev_priv->frontOffset);			PRIMOUTREG(MGAREG_DWGCTL + MGAREG_MGA_EXEC, cmd);		}		if (flags & MGA_BACK) {			PRIMOUTREG(MGAREG_DMAPAD, 0);			PRIMOUTREG(MGAREG_PLNWT, clear_colormask);			PRIMOUTREG(MGAREG_YDSTLEN,				   (pbox[i].y1 << 16) | height);			PRIMOUTREG(MGAREG_FXBNDRY,				   (pbox[i].x2 << 16) | pbox[i].x1);			PRIMOUTREG(MGAREG_DMAPAD, 0);			PRIMOUTREG(MGAREG_FCOL, clear_color);			PRIMOUTREG(MGAREG_DSTORG, dev_priv->backOffset);			PRIMOUTREG(MGAREG_DWGCTL + MGAREG_MGA_EXEC, cmd);		}		if (flags & MGA_DEPTH) {			PRIMOUTREG(MGAREG_DMAPAD, 0);			PRIMOUTREG(MGAREG_PLNWT, clear_depthmask);			PRIMOUTREG(MGAREG_YDSTLEN,				   (pbox[i].y1 << 16) | height);			PRIMOUTREG(MGAREG_FXBNDRY,				   (pbox[i].x2 << 16) | pbox[i].x1);			PRIMOUTREG(MGAREG_DMAPAD, 0);			PRIMOUTREG(MGAREG_FCOL, clear_zval);			PRIMOUTREG(MGAREG_DSTORG, dev_priv->depthOffset);			PRIMOUTREG(MGAREG_DWGCTL + MGAREG_MGA_EXEC, cmd);		}	}	/* Force reset of DWGCTL */	PRIMOUTREG(MGAREG_DMAPAD, 0);	PRIMOUTREG(MGAREG_DMAPAD, 0);	PRIMOUTREG(MGAREG_DMAPAD, 0);	PRIMOUTREG(MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL]);	PRIMADVANCE(dev_priv);}static void mga_dma_dispatch_swap(drm_device_t * dev){	drm_mga_private_t *dev_priv = dev->dev_private;	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;	unsigned int *regs = sarea_priv->ContextState;	int nbox = sarea_priv->nbox;	drm_clip_rect_t *pbox = sarea_priv->boxes;	int i;	int pixel_stride = dev_priv->stride / dev_priv->cpp;	PRIMLOCALS;	PRIM_OVERFLOW(dev, dev_priv, (MGA_NR_SAREA_CLIPRECTS * 5) + 20);	PRIMOUTREG(MGAREG_DMAPAD, 0);	PRIMOUTREG(MGAREG_DMAPAD, 0);	PRIMOUTREG(MGAREG_DWGSYNC, 0x7100);	PRIMOUTREG(MGAREG_DWGSYNC, 0x7000);	PRIMOUTREG(MGAREG_DSTORG, dev_priv->frontOffset);	PRIMOUTREG(MGAREG_MACCESS, dev_priv->mAccess);	PRIMOUTREG(MGAREG_SRCORG, dev_priv->backOffset);	PRIMOUTREG(MGAREG_AR5, pixel_stride);	PRIMOUTREG(MGAREG_DMAPAD, 0);	PRIMOUTREG(MGAREG_DMAPAD, 0);	PRIMOUTREG(MGAREG_DMAPAD, 0);	PRIMOUTREG(MGAREG_DWGCTL, MGA_COPY_CMD);	for (i = 0; i < nbox; i++) {		unsigned int h = pbox[i].y2 - pbox[i].y1;		unsigned int start = pbox[i].y1 * pixel_stride;		PRIMOUTREG(MGAREG_AR0, start + pbox[i].x2 - 1);		PRIMOUTREG(MGAREG_AR3, start + pbox[i].x1);		PRIMOUTREG(MGAREG_FXBNDRY,			   pbox[i].x1 | ((pbox[i].x2 - 1) << 16));		PRIMOUTREG(MGAREG_YDSTLEN + MGAREG_MGA_EXEC,			   (pbox[i].y1 << 16) | h);	}	/* Force reset of DWGCTL */	PRIMOUTREG(MGAREG_DMAPAD, 0);	PRIMOUTREG(MGAREG_DMAPAD, 0);	PRIMOUTREG(MGAREG_SRCORG, 0);	PRIMOUTREG(MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL]);	PRIMADVANCE(dev_priv);}int mga_clear_bufs(struct inode *inode, struct file *filp,		   unsigned int cmd, unsigned long arg){	drm_file_t *priv = filp->private_data;	drm_device_t *dev = priv->dev;	drm_mga_private_t *dev_priv =	    (drm_mga_private_t *) dev->dev_private;	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;	drm_mga_clear_t clear;	if (copy_from_user(&clear, (drm_mga_clear_t *) arg, sizeof(clear)))		return -EFAULT;	if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {		DRM_ERROR("mga_clear_bufs called without lock held\n");		return -EINVAL;	}	if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS)		sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS;	/* Make sure we restore the 3D state next time.	 */	dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CTX;	mga_dma_dispatch_clear(dev, clear.flags,			       clear.clear_color,			       clear.clear_depth,			       clear.clear_color_mask,			       clear.clear_depth_mask);	PRIMUPDATE(dev_priv);	mga_flush_write_combine();	mga_dma_schedule(dev, 1);	return 0;}int mga_swap_bufs(struct inode *inode, struct file *filp,		  unsigned int cmd, unsigned long arg){	drm_file_t *priv = filp->private_data;	drm_device_t *dev = priv->dev;	drm_mga_private_t *dev_priv =	    (drm_mga_private_t *) dev->dev_private;	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;	if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {		DRM_ERROR("mga_swap_bufs called without lock held\n");		return -EINVAL;	}	if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS)		sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS;	/* Make sure we restore the 3D state next time.	 */	dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CTX;	mga_dma_dispatch_swap(dev);	PRIMUPDATE(dev_priv);	set_bit(MGA_BUF_SWAP_PENDING,		&dev_priv->current_prim->buffer_status);	mga_flush_write_combine();	mga_dma_schedule(dev, 1);	return 0;}int mga_iload(struct inode *inode, struct file *filp,	      unsigned int cmd, unsigned long arg){	drm_file_t *priv = filp->private_data;	drm_device_t *dev = priv->dev;	drm_device_dma_t *dma = dev->dma;	drm_mga_private_t *dev_priv =	    (drm_mga_private_t *) dev->dev_private;	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;	drm_buf_t *buf;	drm_mga_buf_priv_t *buf_priv;	drm_mga_iload_t iload;	unsigned long bus_address;	if (copy_from_user(&iload, (drm_mga_iload_t *) arg, sizeof(iload)))		return -EFAULT;	if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {		DRM_ERROR("mga_iload called without lock held\n");		return -EINVAL;	}	if(iload.idx < 0 || iload.idx > dma->buf_count) return -EINVAL;	buf = dma->buflist[iload.idx];	buf_priv = buf->dev_private;	bus_address = buf->bus_address;	if (mgaVerifyIload(dev_priv,			   bus_address, iload.destOrg, iload.length)) {		mga_freelist_put(dev, buf);		return -EINVAL;	}	sarea_priv->dirty |= MGA_UPLOAD_CTX;	mga_dma_dispatch_tex_blit(dev, bus_address, iload.length,				  iload.destOrg);	AGEBUF(dev_priv, buf_priv);	buf_priv->discard = 1;	mga_freelist_put(dev, buf);	mga_flush_write_combine();	mga_dma_schedule(dev, 1);	return 0;}int mga_vertex(struct inode *inode, struct file *filp,	       unsigned int cmd, unsigned long arg){	drm_file_t *priv = filp->private_data;	drm_device_t *dev = priv->dev;	drm_mga_private_t *dev_priv =	    (drm_mga_private_t *) dev->dev_private;	drm_device_dma_t *dma = dev->dma;	drm_buf_t *buf;	drm_mga_buf_priv_t *buf_priv;	drm_mga_vertex_t vertex;	if (copy_from_user(&vertex, (drm_mga_vertex_t *) arg, sizeof(vertex)))		return -EFAULT;	if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {		DRM_ERROR("mga_vertex called without lock held\n");		return -EINVAL;	}	if(vertex.idx < 0 || vertex.idx > dma->buf_count) return -EINVAL;	buf = dma->buflist[vertex.idx];	buf_priv = buf->dev_private;	buf->used = vertex.used;	buf_priv->discard = vertex.discard;	if (!mgaVerifyState(dev_priv)) {		if (vertex.discard) {			if (buf_priv->dispatched == 1)				AGEBUF(dev_priv, buf_priv);			buf_priv->dispatched = 0;			mga_freelist_put(dev, buf);		}		return -EINVAL;	}	mga_dma_dispatch_vertex(dev, buf);	PRIMUPDATE(dev_priv);	mga_flush_write_combine();	mga_dma_schedule(dev, 1);	return 0;}int mga_indices(struct inode *inode, struct file *filp,		unsigned int cmd, unsigned long arg){	drm_file_t *priv = filp->private_data;	drm_device_t *dev = priv->dev;	drm_mga_private_t *dev_priv =	    (drm_mga_private_t *) dev->dev_private;	drm_device_dma_t *dma = dev->dma;	drm_buf_t *buf;	drm_mga_buf_priv_t *buf_priv;	drm_mga_indices_t indices;	if (copy_from_user(&indices,			   (drm_mga_indices_t *)arg, sizeof(indices)))		return -EFAULT;	if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {		DRM_ERROR("mga_indices called without lock held\n");		return -EINVAL;	}	if(indices.idx < 0 || indices.idx > dma->buf_count) return -EINVAL;	buf = dma->buflist[indices.idx];	buf_priv = buf->dev_private;	buf_priv->discard = indices.discard;	if (!mgaVerifyState(dev_priv)) {		if (indices.discard) {			if (buf_priv->dispatched == 1)				AGEBUF(dev_priv, buf_priv);			buf_priv->dispatched = 0;			mga_freelist_put(dev, buf);		}		return -EINVAL;	}	mga_dma_dispatch_indices(dev, buf, indices.start, indices.end);	PRIMUPDATE(dev_priv);	mga_flush_write_combine();	mga_dma_schedule(dev, 1);	return 0;}static int mga_dma_get_buffers(drm_device_t * dev, drm_dma_t * d){	int i;	drm_buf_t *buf;	for (i = d->granted_count; i < d->request_count; i++) {		buf = mga_freelist_get(dev);		if (!buf)			break;		buf->pid = current->pid;		if (copy_to_user(&d->request_indices[i],				 &buf->idx, sizeof(buf->idx)))			return -EFAULT;		if (copy_to_user(&d->request_sizes[i],				 &buf->total, sizeof(buf->total)))			return -EFAULT;		++d->granted_count;	}	return 0;}int mga_dma(struct inode *inode, struct file *filp, unsigned int cmd,	    unsigned long arg){	drm_file_t *priv = filp->private_data;	drm_device_t *dev = priv->dev;	drm_device_dma_t *dma = dev->dma;	int retcode = 0;	drm_dma_t d;	if (copy_from_user(&d, (drm_dma_t *) arg, sizeof(d)))		return -EFAULT;	if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {		DRM_ERROR("mga_dma called without lock held\n");		return -EINVAL;	}	/* Please don't send us buffers.	 */	if (d.send_count != 0) {		DRM_ERROR		    ("Process %d trying to send %d buffers via drmDMA\n",		     current->pid, d.send_count);		return -EINVAL;	}	/* We'll send you buffers.	 */	if (d.request_count < 0 || d.request_count > dma->buf_count) {		DRM_ERROR		    ("Process %d trying to get %d buffers (of %d max)\n",		     current->pid, d.request_count, dma->buf_count);		return -EINVAL;	}	d.granted_count = 0;	if (d.request_count) {		retcode = mga_dma_get_buffers(dev, &d);	}	if (copy_to_user((drm_dma_t *) arg, &d, sizeof(d)))		return -EFAULT;	return retcode;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -