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

📄 savage_state.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
				unsigned int j = idx[i + reorder[i % 3]];				DMA_COPY_FROM_USER(&vtxbuf[vb_stride * j],						   vtx_size);			}			DMA_COMMIT();		} else {			BEGIN_DMA(count * vtx_size + 1);			DMA_DRAW_PRIMITIVE(count, prim, skip);			for (i = 0; i < count; ++i) {				unsigned int j = idx[i];				DMA_COPY_FROM_USER(&vtxbuf[vb_stride * j],						   vtx_size);			}			DMA_COMMIT();		}		usr_idx += count;		n -= count;		prim |= BCI_CMD_DRAW_CONT;	}	return 0;}static int savage_dispatch_clear(drm_savage_private_t * dev_priv,				 const drm_savage_cmd_header_t * cmd_header,				 const drm_savage_cmd_header_t __user * data,				 unsigned int nbox,				 const drm_clip_rect_t __user * usr_boxes){	unsigned int flags = cmd_header->clear0.flags, mask, value;	unsigned int clear_cmd;	unsigned int i, nbufs;	DMA_LOCALS;	if (nbox == 0)		return 0;	DRM_GET_USER_UNCHECKED(mask, &data->clear1.mask);	DRM_GET_USER_UNCHECKED(value, &data->clear1.value);	clear_cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP |	    BCI_CMD_SEND_COLOR | BCI_CMD_DEST_PBD_NEW;	BCI_CMD_SET_ROP(clear_cmd, 0xCC);	nbufs = ((flags & SAVAGE_FRONT) ? 1 : 0) +	    ((flags & SAVAGE_BACK) ? 1 : 0) + ((flags & SAVAGE_DEPTH) ? 1 : 0);	if (nbufs == 0)		return 0;	if (mask != 0xffffffff) {		/* set mask */		BEGIN_DMA(2);		DMA_SET_REGISTERS(SAVAGE_BITPLANEWTMASK, 1);		DMA_WRITE(mask);		DMA_COMMIT();	}	for (i = 0; i < nbox; ++i) {		drm_clip_rect_t box;		unsigned int x, y, w, h;		unsigned int buf;		DRM_COPY_FROM_USER_UNCHECKED(&box, &usr_boxes[i], sizeof(box));		x = box.x1, y = box.y1;		w = box.x2 - box.x1;		h = box.y2 - box.y1;		BEGIN_DMA(nbufs * 6);		for (buf = SAVAGE_FRONT; buf <= SAVAGE_DEPTH; buf <<= 1) {			if (!(flags & buf))				continue;			DMA_WRITE(clear_cmd);			switch (buf) {			case SAVAGE_FRONT:				DMA_WRITE(dev_priv->front_offset);				DMA_WRITE(dev_priv->front_bd);				break;			case SAVAGE_BACK:				DMA_WRITE(dev_priv->back_offset);				DMA_WRITE(dev_priv->back_bd);				break;			case SAVAGE_DEPTH:				DMA_WRITE(dev_priv->depth_offset);				DMA_WRITE(dev_priv->depth_bd);				break;			}			DMA_WRITE(value);			DMA_WRITE(BCI_X_Y(x, y));			DMA_WRITE(BCI_W_H(w, h));		}		DMA_COMMIT();	}	if (mask != 0xffffffff) {		/* reset mask */		BEGIN_DMA(2);		DMA_SET_REGISTERS(SAVAGE_BITPLANEWTMASK, 1);		DMA_WRITE(0xffffffff);		DMA_COMMIT();	}	return 0;}static int savage_dispatch_swap(drm_savage_private_t * dev_priv,				unsigned int nbox,				const drm_clip_rect_t __user * usr_boxes){	unsigned int swap_cmd;	unsigned int i;	DMA_LOCALS;	if (nbox == 0)		return 0;	swap_cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP |	    BCI_CMD_SRC_PBD_COLOR_NEW | BCI_CMD_DEST_GBD;	BCI_CMD_SET_ROP(swap_cmd, 0xCC);	for (i = 0; i < nbox; ++i) {		drm_clip_rect_t box;		DRM_COPY_FROM_USER_UNCHECKED(&box, &usr_boxes[i], sizeof(box));		BEGIN_DMA(6);		DMA_WRITE(swap_cmd);		DMA_WRITE(dev_priv->back_offset);		DMA_WRITE(dev_priv->back_bd);		DMA_WRITE(BCI_X_Y(box.x1, box.y1));		DMA_WRITE(BCI_X_Y(box.x1, box.y1));		DMA_WRITE(BCI_W_H(box.x2 - box.x1, box.y2 - box.y1));		DMA_COMMIT();	}	return 0;}static int savage_dispatch_draw(drm_savage_private_t * dev_priv,				const drm_savage_cmd_header_t __user * start,				const drm_savage_cmd_header_t __user * end,				const drm_buf_t * dmabuf,				const unsigned int __user * usr_vtxbuf,				unsigned int vb_size, unsigned int vb_stride,				unsigned int nbox,				const drm_clip_rect_t __user * usr_boxes){	unsigned int i, j;	int ret;	for (i = 0; i < nbox; ++i) {		drm_clip_rect_t box;		const drm_savage_cmd_header_t __user *usr_cmdbuf;		DRM_COPY_FROM_USER_UNCHECKED(&box, &usr_boxes[i], sizeof(box));		dev_priv->emit_clip_rect(dev_priv, &box);		usr_cmdbuf = start;		while (usr_cmdbuf < end) {			drm_savage_cmd_header_t cmd_header;			DRM_COPY_FROM_USER_UNCHECKED(&cmd_header, usr_cmdbuf,						     sizeof(cmd_header));			usr_cmdbuf++;			switch (cmd_header.cmd.cmd) {			case SAVAGE_CMD_DMA_PRIM:				ret =				    savage_dispatch_dma_prim(dev_priv,							     &cmd_header,							     dmabuf);				break;			case SAVAGE_CMD_VB_PRIM:				ret =				    savage_dispatch_vb_prim(dev_priv,							    &cmd_header,							    (const uint32_t							     __user *)							    usr_vtxbuf, vb_size,							    vb_stride);				break;			case SAVAGE_CMD_DMA_IDX:				j = (cmd_header.idx.count + 3) / 4;				/* j was check in savage_bci_cmdbuf */				ret =				    savage_dispatch_dma_idx(dev_priv,							    &cmd_header,							    (const uint16_t							     __user *)							    usr_cmdbuf, dmabuf);				usr_cmdbuf += j;				break;			case SAVAGE_CMD_VB_IDX:				j = (cmd_header.idx.count + 3) / 4;				/* j was check in savage_bci_cmdbuf */				ret =				    savage_dispatch_vb_idx(dev_priv,							   &cmd_header,							   (const uint16_t							    __user *)usr_cmdbuf,							   (const uint32_t							    __user *)usr_vtxbuf,							   vb_size, vb_stride);				usr_cmdbuf += j;				break;			default:				/* What's the best return code? EFAULT? */				DRM_ERROR("IMPLEMENTATION ERROR: "					  "non-drawing-command %d\n",					  cmd_header.cmd.cmd);				return DRM_ERR(EINVAL);			}			if (ret != 0)				return ret;		}	}	return 0;}int savage_bci_cmdbuf(DRM_IOCTL_ARGS){	DRM_DEVICE;	drm_savage_private_t *dev_priv = dev->dev_private;	drm_device_dma_t *dma = dev->dma;	drm_buf_t *dmabuf;	drm_savage_cmdbuf_t cmdbuf;	drm_savage_cmd_header_t __user *usr_cmdbuf;	drm_savage_cmd_header_t __user *first_draw_cmd;	unsigned int __user *usr_vtxbuf;	drm_clip_rect_t __user *usr_boxes;	unsigned int i, j;	int ret = 0;	DRM_DEBUG("\n");	LOCK_TEST_WITH_RETURN(dev, filp);	DRM_COPY_FROM_USER_IOCTL(cmdbuf, (drm_savage_cmdbuf_t __user *) data,				 sizeof(cmdbuf));	if (dma && dma->buflist) {		if (cmdbuf.dma_idx > dma->buf_count) {			DRM_ERROR			    ("vertex buffer index %u out of range (0-%u)\n",			     cmdbuf.dma_idx, dma->buf_count - 1);			return DRM_ERR(EINVAL);		}		dmabuf = dma->buflist[cmdbuf.dma_idx];	} else {		dmabuf = NULL;	}	usr_cmdbuf = (drm_savage_cmd_header_t __user *) cmdbuf.cmd_addr;	usr_vtxbuf = (unsigned int __user *)cmdbuf.vb_addr;	usr_boxes = (drm_clip_rect_t __user *) cmdbuf.box_addr;	if ((cmdbuf.size && DRM_VERIFYAREA_READ(usr_cmdbuf, cmdbuf.size * 8)) ||	    (cmdbuf.vb_size && DRM_VERIFYAREA_READ(usr_vtxbuf, cmdbuf.vb_size))	    || (cmdbuf.nbox		&& DRM_VERIFYAREA_READ(usr_boxes,				       cmdbuf.nbox * sizeof(drm_clip_rect_t))))		return DRM_ERR(EFAULT);	/* Make sure writes to DMA buffers are finished before sending	 * DMA commands to the graphics hardware. */	DRM_MEMORYBARRIER();	/* Coming from user space. Don't know if the Xserver has	 * emitted wait commands. Assuming the worst. */	dev_priv->waiting = 1;	i = 0;	first_draw_cmd = NULL;	while (i < cmdbuf.size) {		drm_savage_cmd_header_t cmd_header;		DRM_COPY_FROM_USER_UNCHECKED(&cmd_header, usr_cmdbuf,					     sizeof(cmd_header));		usr_cmdbuf++;		i++;		/* Group drawing commands with same state to minimize		 * iterations over clip rects. */		j = 0;		switch (cmd_header.cmd.cmd) {		case SAVAGE_CMD_DMA_IDX:		case SAVAGE_CMD_VB_IDX:			j = (cmd_header.idx.count + 3) / 4;			if (i + j > cmdbuf.size) {				DRM_ERROR("indexed drawing command extends "					  "beyond end of command buffer\n");				DMA_FLUSH();				return DRM_ERR(EINVAL);			}			/* fall through */		case SAVAGE_CMD_DMA_PRIM:		case SAVAGE_CMD_VB_PRIM:			if (!first_draw_cmd)				first_draw_cmd = usr_cmdbuf - 1;			usr_cmdbuf += j;			i += j;			break;		default:			if (first_draw_cmd) {				ret =				    savage_dispatch_draw(dev_priv,							 first_draw_cmd,							 usr_cmdbuf - 1, dmabuf,							 usr_vtxbuf,							 cmdbuf.vb_size,							 cmdbuf.vb_stride,							 cmdbuf.nbox,							 usr_boxes);				if (ret != 0)					return ret;				first_draw_cmd = NULL;			}		}		if (first_draw_cmd)			continue;		switch (cmd_header.cmd.cmd) {		case SAVAGE_CMD_STATE:			j = (cmd_header.state.count + 1) / 2;			if (i + j > cmdbuf.size) {				DRM_ERROR("command SAVAGE_CMD_STATE extends "					  "beyond end of command buffer\n");				DMA_FLUSH();				return DRM_ERR(EINVAL);			}			ret = savage_dispatch_state(dev_priv, &cmd_header,						    (uint32_t __user *)						    usr_cmdbuf);			usr_cmdbuf += j;			i += j;			break;		case SAVAGE_CMD_CLEAR:			if (i + 1 > cmdbuf.size) {				DRM_ERROR("command SAVAGE_CMD_CLEAR extends "					  "beyond end of command buffer\n");				DMA_FLUSH();				return DRM_ERR(EINVAL);			}			ret = savage_dispatch_clear(dev_priv, &cmd_header,						    usr_cmdbuf,						    cmdbuf.nbox, usr_boxes);			usr_cmdbuf++;			i++;			break;		case SAVAGE_CMD_SWAP:			ret = savage_dispatch_swap(dev_priv,						   cmdbuf.nbox, usr_boxes);			break;		default:			DRM_ERROR("invalid command 0x%x\n", cmd_header.cmd.cmd);			DMA_FLUSH();			return DRM_ERR(EINVAL);		}		if (ret != 0) {			DMA_FLUSH();			return ret;		}	}	if (first_draw_cmd) {		ret =		    savage_dispatch_draw(dev_priv, first_draw_cmd, usr_cmdbuf,					 dmabuf, usr_vtxbuf, cmdbuf.vb_size,					 cmdbuf.vb_stride, cmdbuf.nbox,					 usr_boxes);		if (ret != 0) {			DMA_FLUSH();			return ret;		}	}	DMA_FLUSH();	if (dmabuf && cmdbuf.discard) {		drm_savage_buf_priv_t *buf_priv = dmabuf->dev_private;		uint16_t event;		event = savage_bci_emit_event(dev_priv, SAVAGE_WAIT_3D);		SET_AGE(&buf_priv->age, event, dev_priv->event_wrap);		savage_freelist_put(dev, dmabuf);	}	return 0;}

⌨️ 快捷键说明

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