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

📄 savage_state.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
			for (i = start + 1; i + 1 < start + count; i += 2)				BCI_WRITE((i + reorder[i % 3]) |					  ((i + 1 +					    reorder[(i + 1) % 3]) << 16));			if (i < start + count)				BCI_WRITE(i + reorder[i % 3]);		} else if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {			BEGIN_BCI((count + 1 + 1) / 2);			BCI_DRAW_INDICES_S3D(count, prim, start);			for (i = start + 1; i + 1 < start + count; i += 2)				BCI_WRITE(i | ((i + 1) << 16));			if (i < start + count)				BCI_WRITE(i);		} else {			BEGIN_BCI((count + 2 + 1) / 2);			BCI_DRAW_INDICES_S4(count, prim, skip);			for (i = start; i + 1 < start + count; i += 2)				BCI_WRITE(i | ((i + 1) << 16));			if (i < start + count)				BCI_WRITE(i);		}		start += count;		n -= count;		prim |= BCI_CMD_DRAW_CONT;	}	return 0;}static int savage_dispatch_vb_prim(drm_savage_private_t * dev_priv,				   const drm_savage_cmd_header_t * cmd_header,				   const uint32_t __user * vtxbuf,				   unsigned int vb_size, unsigned int vb_stride){	unsigned char reorder = 0;	unsigned int prim = cmd_header->prim.prim;	unsigned int skip = cmd_header->prim.skip;	unsigned int n = cmd_header->prim.count;	unsigned int start = cmd_header->prim.start;	unsigned int vtx_size;	unsigned int i;	DMA_LOCALS;	if (!n)		return 0;	switch (prim) {	case SAVAGE_PRIM_TRILIST_201:		reorder = 1;		prim = SAVAGE_PRIM_TRILIST;	case SAVAGE_PRIM_TRILIST:		if (n % 3 != 0) {			DRM_ERROR("wrong number of vertices %u in TRILIST\n",				  n);			return DRM_ERR(EINVAL);		}		break;	case SAVAGE_PRIM_TRISTRIP:	case SAVAGE_PRIM_TRIFAN:		if (n < 3) {			DRM_ERROR			    ("wrong number of vertices %u in TRIFAN/STRIP\n",			     n);			return DRM_ERR(EINVAL);		}		break;	default:		DRM_ERROR("invalid primitive type %u\n", prim);		return DRM_ERR(EINVAL);	}	if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {		if (skip > SAVAGE_SKIP_ALL_S3D) {			DRM_ERROR("invalid skip flags 0x%04x\n", skip);			return DRM_ERR(EINVAL);		}		vtx_size = 8;	/* full vertex */	} else {		if (skip > SAVAGE_SKIP_ALL_S4) {			DRM_ERROR("invalid skip flags 0x%04x\n", skip);			return DRM_ERR(EINVAL);		}		vtx_size = 10;	/* full vertex */	}	vtx_size -= (skip & 1) + (skip >> 1 & 1) +	    (skip >> 2 & 1) + (skip >> 3 & 1) + (skip >> 4 & 1) +	    (skip >> 5 & 1) + (skip >> 6 & 1) + (skip >> 7 & 1);	if (vtx_size > vb_stride) {		DRM_ERROR("vertex size greater than vb stride (%u > %u)\n",			  vtx_size, vb_stride);		return DRM_ERR(EINVAL);	}	if (start + n > vb_size / (vb_stride * 4)) {		DRM_ERROR("vertex indices (%u-%u) out of range (0-%u)\n",			  start, start + n - 1, vb_size / (vb_stride * 4));		return DRM_ERR(EINVAL);	}	prim <<= 25;	while (n != 0) {		/* Can emit up to 255 vertices (85 triangles) at once. */		unsigned int count = n > 255 ? 255 : n;		if (reorder) {			/* Need to reorder vertices for correct flat			 * shading while preserving the clock sense			 * for correct culling. Only on Savage3D. */			int reorder[3] = { -1, -1, -1 };			reorder[start % 3] = 2;			BEGIN_DMA(count * vtx_size + 1);			DMA_DRAW_PRIMITIVE(count, prim, skip);			for (i = start; i < start + count; ++i) {				unsigned int j = 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);			if (vb_stride == vtx_size) {				DMA_COPY_FROM_USER(&vtxbuf[vb_stride * start],						   vtx_size * count);			} else {				for (i = start; i < start + count; ++i) {					DMA_COPY_FROM_USER(&vtxbuf							   [vb_stride * i],							   vtx_size);				}			}			DMA_COMMIT();		}		start += count;		n -= count;		prim |= BCI_CMD_DRAW_CONT;	}	return 0;}static int savage_dispatch_dma_idx(drm_savage_private_t * dev_priv,				   const drm_savage_cmd_header_t * cmd_header,				   const uint16_t __user * usr_idx,				   const drm_buf_t * dmabuf){	unsigned char reorder = 0;	unsigned int prim = cmd_header->idx.prim;	unsigned int skip = cmd_header->idx.skip;	unsigned int n = cmd_header->idx.count;	unsigned int i;	BCI_LOCALS;	if (!dmabuf) {		DRM_ERROR("called without dma buffers!\n");		return DRM_ERR(EINVAL);	}	if (!n)		return 0;	switch (prim) {	case SAVAGE_PRIM_TRILIST_201:		reorder = 1;		prim = SAVAGE_PRIM_TRILIST;	case SAVAGE_PRIM_TRILIST:		if (n % 3 != 0) {			DRM_ERROR("wrong number of indices %u in TRILIST\n", n);			return DRM_ERR(EINVAL);		}		break;	case SAVAGE_PRIM_TRISTRIP:	case SAVAGE_PRIM_TRIFAN:		if (n < 3) {			DRM_ERROR			    ("wrong number of indices %u in TRIFAN/STRIP\n", n);			return DRM_ERR(EINVAL);		}		break;	default:		DRM_ERROR("invalid primitive type %u\n", prim);		return DRM_ERR(EINVAL);	}	if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {		if (skip != 0) {			DRM_ERROR("invalid skip flags 0x%04x for DMA\n", skip);			return DRM_ERR(EINVAL);		}	} else {		unsigned int size = 10 - (skip & 1) - (skip >> 1 & 1) -		    (skip >> 2 & 1) - (skip >> 3 & 1) - (skip >> 4 & 1) -		    (skip >> 5 & 1) - (skip >> 6 & 1) - (skip >> 7 & 1);		if (skip > SAVAGE_SKIP_ALL_S4 || size != 8) {			DRM_ERROR("invalid skip flags 0x%04x for DMA\n", skip);			return DRM_ERR(EINVAL);		}		if (reorder) {			DRM_ERROR("TRILIST_201 used on Savage4 hardware\n");			return DRM_ERR(EINVAL);		}	}	/* Vertex DMA doesn't work with command DMA at the same time,	 * so we use BCI_... to submit commands here. Flush buffered	 * faked DMA first. */	DMA_FLUSH();	if (dmabuf->bus_address != dev_priv->state.common.vbaddr) {		BEGIN_BCI(2);		BCI_SET_REGISTERS(SAVAGE_VERTBUFADDR, 1);		BCI_WRITE(dmabuf->bus_address | dev_priv->dma_type);		dev_priv->state.common.vbaddr = dmabuf->bus_address;	}	if (S3_SAVAGE3D_SERIES(dev_priv->chipset) && dev_priv->waiting) {		/* Workaround for what looks like a hardware bug. If a		 * WAIT_3D_IDLE was emitted some time before the		 * indexed drawing command then the engine will lock		 * up. There are two known workarounds:		 * WAIT_IDLE_EMPTY or emit at least 63 NOPs. */		BEGIN_BCI(63);		for (i = 0; i < 63; ++i)			BCI_WRITE(BCI_CMD_WAIT);		dev_priv->waiting = 0;	}	prim <<= 25;	while (n != 0) {		/* Can emit up to 255 indices (85 triangles) at once. */		unsigned int count = n > 255 ? 255 : n;		/* Is it ok to allocate 510 bytes on the stack in an ioctl? */		uint16_t idx[255];		/* Copy and check indices */		DRM_COPY_FROM_USER_UNCHECKED(idx, usr_idx, count * 2);		for (i = 0; i < count; ++i) {			if (idx[i] > dmabuf->total / 32) {				DRM_ERROR("idx[%u]=%u out of range (0-%u)\n",					  i, idx[i], dmabuf->total / 32);				return DRM_ERR(EINVAL);			}		}		if (reorder) {			/* Need to reorder indices for correct flat			 * shading while preserving the clock sense			 * for correct culling. Only on Savage3D. */			int reorder[3] = { 2, -1, -1 };			BEGIN_BCI((count + 1 + 1) / 2);			BCI_DRAW_INDICES_S3D(count, prim, idx[2]);			for (i = 1; i + 1 < count; i += 2)				BCI_WRITE(idx[i + reorder[i % 3]] |					  (idx[i + 1 + reorder[(i + 1) % 3]] <<					   16));			if (i < count)				BCI_WRITE(idx[i + reorder[i % 3]]);		} else if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {			BEGIN_BCI((count + 1 + 1) / 2);			BCI_DRAW_INDICES_S3D(count, prim, idx[0]);			for (i = 1; i + 1 < count; i += 2)				BCI_WRITE(idx[i] | (idx[i + 1] << 16));			if (i < count)				BCI_WRITE(idx[i]);		} else {			BEGIN_BCI((count + 2 + 1) / 2);			BCI_DRAW_INDICES_S4(count, prim, skip);			for (i = 0; i + 1 < count; i += 2)				BCI_WRITE(idx[i] | (idx[i + 1] << 16));			if (i < count)				BCI_WRITE(idx[i]);		}		usr_idx += count;		n -= count;		prim |= BCI_CMD_DRAW_CONT;	}	return 0;}static int savage_dispatch_vb_idx(drm_savage_private_t * dev_priv,				  const drm_savage_cmd_header_t * cmd_header,				  const uint16_t __user * usr_idx,				  const uint32_t __user * vtxbuf,				  unsigned int vb_size, unsigned int vb_stride){	unsigned char reorder = 0;	unsigned int prim = cmd_header->idx.prim;	unsigned int skip = cmd_header->idx.skip;	unsigned int n = cmd_header->idx.count;	unsigned int vtx_size;	unsigned int i;	DMA_LOCALS;	if (!n)		return 0;	switch (prim) {	case SAVAGE_PRIM_TRILIST_201:		reorder = 1;		prim = SAVAGE_PRIM_TRILIST;	case SAVAGE_PRIM_TRILIST:		if (n % 3 != 0) {			DRM_ERROR("wrong number of indices %u in TRILIST\n", n);			return DRM_ERR(EINVAL);		}		break;	case SAVAGE_PRIM_TRISTRIP:	case SAVAGE_PRIM_TRIFAN:		if (n < 3) {			DRM_ERROR			    ("wrong number of indices %u in TRIFAN/STRIP\n", n);			return DRM_ERR(EINVAL);		}		break;	default:		DRM_ERROR("invalid primitive type %u\n", prim);		return DRM_ERR(EINVAL);	}	if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {		if (skip > SAVAGE_SKIP_ALL_S3D) {			DRM_ERROR("invalid skip flags 0x%04x\n", skip);			return DRM_ERR(EINVAL);		}		vtx_size = 8;	/* full vertex */	} else {		if (skip > SAVAGE_SKIP_ALL_S4) {			DRM_ERROR("invalid skip flags 0x%04x\n", skip);			return DRM_ERR(EINVAL);		}		vtx_size = 10;	/* full vertex */	}	vtx_size -= (skip & 1) + (skip >> 1 & 1) +	    (skip >> 2 & 1) + (skip >> 3 & 1) + (skip >> 4 & 1) +	    (skip >> 5 & 1) + (skip >> 6 & 1) + (skip >> 7 & 1);	if (vtx_size > vb_stride) {		DRM_ERROR("vertex size greater than vb stride (%u > %u)\n",			  vtx_size, vb_stride);		return DRM_ERR(EINVAL);	}	prim <<= 25;	while (n != 0) {		/* Can emit up to 255 vertices (85 triangles) at once. */		unsigned int count = n > 255 ? 255 : n;		/* Is it ok to allocate 510 bytes on the stack in an ioctl? */		uint16_t idx[255];		/* Copy and check indices */		DRM_COPY_FROM_USER_UNCHECKED(idx, usr_idx, count * 2);		for (i = 0; i < count; ++i) {			if (idx[i] > vb_size / (vb_stride * 4)) {				DRM_ERROR("idx[%u]=%u out of range (0-%u)\n",					  i, idx[i], vb_size / (vb_stride * 4));				return DRM_ERR(EINVAL);			}		}		if (reorder) {			/* Need to reorder vertices for correct flat			 * shading while preserving the clock sense			 * for correct culling. Only on Savage3D. */			int reorder[3] = { 2, -1, -1 };			BEGIN_DMA(count * vtx_size + 1);			DMA_DRAW_PRIMITIVE(count, prim, skip);			for (i = 0; i < count; ++i) {

⌨️ 快捷键说明

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