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

📄 r128_state.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
	drm_r128_buf_priv_t *buf_priv = buf->dev_private;	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;	int format = sarea_priv->vc_format;	int offset = buf->bus_address;	int size = buf->used;	int prim = buf_priv->prim;	int i = 0;	RING_LOCALS;	DRM_DEBUG("buf=%d nbox=%d\n", buf->idx, sarea_priv->nbox);	if (0)		r128_print_dirty("dispatch_vertex", sarea_priv->dirty);	if (buf->used) {		buf_priv->dispatched = 1;		if (sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS) {			r128_emit_state(dev_priv);		}		do {			/* Emit the next set of up to three cliprects */			if (i < sarea_priv->nbox) {				r128_emit_clip_rects(dev_priv,						     &sarea_priv->boxes[i],						     sarea_priv->nbox - i);			}			/* Emit the vertex buffer rendering commands */			BEGIN_RING(5);			OUT_RING(CCE_PACKET3(R128_3D_RNDR_GEN_INDX_PRIM, 3));			OUT_RING(offset);			OUT_RING(size);			OUT_RING(format);			OUT_RING(prim | R128_CCE_VC_CNTL_PRIM_WALK_LIST |				 (size << R128_CCE_VC_CNTL_NUM_SHIFT));			ADVANCE_RING();			i += 3;		} while (i < sarea_priv->nbox);	}	if (buf_priv->discard) {		buf_priv->age = dev_priv->sarea_priv->last_dispatch;		/* Emit the vertex buffer age */		BEGIN_RING(2);		OUT_RING(CCE_PACKET0(R128_LAST_DISPATCH_REG, 0));		OUT_RING(buf_priv->age);		ADVANCE_RING();		buf->pending = 1;		buf->used = 0;		/* FIXME: Check dispatched field */		buf_priv->dispatched = 0;	}	dev_priv->sarea_priv->last_dispatch++;	sarea_priv->dirty &= ~R128_UPLOAD_CLIPRECTS;	sarea_priv->nbox = 0;}static void r128_cce_dispatch_indirect(drm_device_t * dev,				       drm_buf_t * buf, int start, int end){	drm_r128_private_t *dev_priv = dev->dev_private;	drm_r128_buf_priv_t *buf_priv = buf->dev_private;	RING_LOCALS;	DRM_DEBUG("indirect: buf=%d s=0x%x e=0x%x\n", buf->idx, start, end);	if (start != end) {		int offset = buf->bus_address + start;		int dwords = (end - start + 3) / sizeof(u32);		/* Indirect buffer data must be an even number of		 * dwords, so if we've been given an odd number we must		 * pad the data with a Type-2 CCE packet.		 */		if (dwords & 1) {			u32 *data = (u32 *)			    ((char *)dev->agp_buffer_map->handle			     + buf->offset + start);			data[dwords++] = cpu_to_le32(R128_CCE_PACKET2);		}		buf_priv->dispatched = 1;		/* Fire off the indirect buffer */		BEGIN_RING(3);		OUT_RING(CCE_PACKET0(R128_PM4_IW_INDOFF, 1));		OUT_RING(offset);		OUT_RING(dwords);		ADVANCE_RING();	}	if (buf_priv->discard) {		buf_priv->age = dev_priv->sarea_priv->last_dispatch;		/* Emit the indirect buffer age */		BEGIN_RING(2);		OUT_RING(CCE_PACKET0(R128_LAST_DISPATCH_REG, 0));		OUT_RING(buf_priv->age);		ADVANCE_RING();		buf->pending = 1;		buf->used = 0;		/* FIXME: Check dispatched field */		buf_priv->dispatched = 0;	}	dev_priv->sarea_priv->last_dispatch++;}static void r128_cce_dispatch_indices(drm_device_t * dev,				      drm_buf_t * buf,				      int start, int end, int count){	drm_r128_private_t *dev_priv = dev->dev_private;	drm_r128_buf_priv_t *buf_priv = buf->dev_private;	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;	int format = sarea_priv->vc_format;	int offset = dev->agp_buffer_map->offset - dev_priv->cce_buffers_offset;	int prim = buf_priv->prim;	u32 *data;	int dwords;	int i = 0;	RING_LOCALS;	DRM_DEBUG("indices: s=%d e=%d c=%d\n", start, end, count);	if (0)		r128_print_dirty("dispatch_indices", sarea_priv->dirty);	if (start != end) {		buf_priv->dispatched = 1;		if (sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS) {			r128_emit_state(dev_priv);		}		dwords = (end - start + 3) / sizeof(u32);		data = (u32 *) ((char *)dev->agp_buffer_map->handle				+ buf->offset + start);		data[0] = cpu_to_le32(CCE_PACKET3(R128_3D_RNDR_GEN_INDX_PRIM,						  dwords - 2));		data[1] = cpu_to_le32(offset);		data[2] = cpu_to_le32(R128_MAX_VB_VERTS);		data[3] = cpu_to_le32(format);		data[4] = cpu_to_le32((prim | R128_CCE_VC_CNTL_PRIM_WALK_IND |				       (count << 16)));		if (count & 0x1) {#ifdef __LITTLE_ENDIAN			data[dwords - 1] &= 0x0000ffff;#else			data[dwords - 1] &= 0xffff0000;#endif		}		do {			/* Emit the next set of up to three cliprects */			if (i < sarea_priv->nbox) {				r128_emit_clip_rects(dev_priv,						     &sarea_priv->boxes[i],						     sarea_priv->nbox - i);			}			r128_cce_dispatch_indirect(dev, buf, start, end);			i += 3;		} while (i < sarea_priv->nbox);	}	if (buf_priv->discard) {		buf_priv->age = dev_priv->sarea_priv->last_dispatch;		/* Emit the vertex buffer age */		BEGIN_RING(2);		OUT_RING(CCE_PACKET0(R128_LAST_DISPATCH_REG, 0));		OUT_RING(buf_priv->age);		ADVANCE_RING();		buf->pending = 1;		/* FIXME: Check dispatched field */		buf_priv->dispatched = 0;	}	dev_priv->sarea_priv->last_dispatch++;	sarea_priv->dirty &= ~R128_UPLOAD_CLIPRECTS;	sarea_priv->nbox = 0;}static int r128_cce_dispatch_blit(DRMFILE filp,				  drm_device_t * dev, drm_r128_blit_t * blit){	drm_r128_private_t *dev_priv = dev->dev_private;	drm_device_dma_t *dma = dev->dma;	drm_buf_t *buf;	drm_r128_buf_priv_t *buf_priv;	u32 *data;	int dword_shift, dwords;	RING_LOCALS;	DRM_DEBUG("\n");	/* The compiler won't optimize away a division by a variable,	 * even if the only legal values are powers of two.  Thus, we'll	 * use a shift instead.	 */	switch (blit->format) {	case R128_DATATYPE_ARGB8888:		dword_shift = 0;		break;	case R128_DATATYPE_ARGB1555:	case R128_DATATYPE_RGB565:	case R128_DATATYPE_ARGB4444:	case R128_DATATYPE_YVYU422:	case R128_DATATYPE_VYUY422:		dword_shift = 1;		break;	case R128_DATATYPE_CI8:	case R128_DATATYPE_RGB8:		dword_shift = 2;		break;	default:		DRM_ERROR("invalid blit format %d\n", blit->format);		return DRM_ERR(EINVAL);	}	/* Flush the pixel cache, and mark the contents as Read Invalid.	 * This ensures no pixel data gets mixed up with the texture	 * data from the host data blit, otherwise part of the texture	 * image may be corrupted.	 */	BEGIN_RING(2);	OUT_RING(CCE_PACKET0(R128_PC_GUI_CTLSTAT, 0));	OUT_RING(R128_PC_RI_GUI | R128_PC_FLUSH_GUI);	ADVANCE_RING();	/* Dispatch the indirect buffer.	 */	buf = dma->buflist[blit->idx];	buf_priv = buf->dev_private;	if (buf->filp != filp) {		DRM_ERROR("process %d using buffer owned by %p\n",			  DRM_CURRENTPID, buf->filp);		return DRM_ERR(EINVAL);	}	if (buf->pending) {		DRM_ERROR("sending pending buffer %d\n", blit->idx);		return DRM_ERR(EINVAL);	}	buf_priv->discard = 1;	dwords = (blit->width * blit->height) >> dword_shift;	data = (u32 *) ((char *)dev->agp_buffer_map->handle + buf->offset);	data[0] = cpu_to_le32(CCE_PACKET3(R128_CNTL_HOSTDATA_BLT, dwords + 6));	data[1] = cpu_to_le32((R128_GMC_DST_PITCH_OFFSET_CNTL |			       R128_GMC_BRUSH_NONE |			       (blit->format << 8) |			       R128_GMC_SRC_DATATYPE_COLOR |			       R128_ROP3_S |			       R128_DP_SRC_SOURCE_HOST_DATA |			       R128_GMC_CLR_CMP_CNTL_DIS |			       R128_GMC_AUX_CLIP_DIS | R128_GMC_WR_MSK_DIS));	data[2] = cpu_to_le32((blit->pitch << 21) | (blit->offset >> 5));	data[3] = cpu_to_le32(0xffffffff);	data[4] = cpu_to_le32(0xffffffff);	data[5] = cpu_to_le32((blit->y << 16) | blit->x);	data[6] = cpu_to_le32((blit->height << 16) | blit->width);	data[7] = cpu_to_le32(dwords);	buf->used = (dwords + 8) * sizeof(u32);	r128_cce_dispatch_indirect(dev, buf, 0, buf->used);	/* Flush the pixel cache after the blit completes.  This ensures	 * the texture data is written out to memory before rendering	 * continues.	 */	BEGIN_RING(2);	OUT_RING(CCE_PACKET0(R128_PC_GUI_CTLSTAT, 0));	OUT_RING(R128_PC_FLUSH_GUI);	ADVANCE_RING();	return 0;}/* ================================================================ * Tiled depth buffer management * * FIXME: These should all set the destination write mask for when we * have hardware stencil support. */static int r128_cce_dispatch_write_span(drm_device_t * dev,					drm_r128_depth_t * depth){	drm_r128_private_t *dev_priv = dev->dev_private;	int count, x, y;	u32 *buffer;	u8 *mask;	int i, buffer_size, mask_size;	RING_LOCALS;	DRM_DEBUG("\n");	count = depth->n;	if (count > 4096 || count <= 0)		return DRM_ERR(EMSGSIZE);	if (DRM_COPY_FROM_USER(&x, depth->x, sizeof(x))) {		return DRM_ERR(EFAULT);	}	if (DRM_COPY_FROM_USER(&y, depth->y, sizeof(y))) {		return DRM_ERR(EFAULT);	}	buffer_size = depth->n * sizeof(u32);	buffer = drm_alloc(buffer_size, DRM_MEM_BUFS);	if (buffer == NULL)		return DRM_ERR(ENOMEM);	if (DRM_COPY_FROM_USER(buffer, depth->buffer, buffer_size)) {		drm_free(buffer, buffer_size, DRM_MEM_BUFS);		return DRM_ERR(EFAULT);	}	mask_size = depth->n * sizeof(u8);	if (depth->mask) {		mask = drm_alloc(mask_size, DRM_MEM_BUFS);		if (mask == NULL) {			drm_free(buffer, buffer_size, DRM_MEM_BUFS);			return DRM_ERR(ENOMEM);		}		if (DRM_COPY_FROM_USER(mask, depth->mask, mask_size)) {			drm_free(buffer, buffer_size, DRM_MEM_BUFS);			drm_free(mask, mask_size, DRM_MEM_BUFS);			return DRM_ERR(EFAULT);		}		for (i = 0; i < count; i++, x++) {			if (mask[i]) {				BEGIN_RING(6);				OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4));				OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL |					 R128_GMC_BRUSH_SOLID_COLOR |					 (dev_priv->depth_fmt << 8) |					 R128_GMC_SRC_DATATYPE_COLOR |					 R128_ROP3_P |					 R128_GMC_CLR_CMP_CNTL_DIS |					 R128_GMC_WR_MSK_DIS);				OUT_RING(dev_priv->depth_pitch_offset_c);				OUT_RING(buffer[i]);				OUT_RING((x << 16) | y);				OUT_RING((1 << 16) | 1);				ADVANCE_RING();			}		}		drm_free(mask, mask_size, DRM_MEM_BUFS);	} else {		for (i = 0; i < count; i++, x++) {			BEGIN_RING(6);			OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4));			OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL |				 R128_GMC_BRUSH_SOLID_COLOR |				 (dev_priv->depth_fmt << 8) |				 R128_GMC_SRC_DATATYPE_COLOR |				 R128_ROP3_P |				 R128_GMC_CLR_CMP_CNTL_DIS |				 R128_GMC_WR_MSK_DIS);			OUT_RING(dev_priv->depth_pitch_offset_c);			OUT_RING(buffer[i]);			OUT_RING((x << 16) | y);			OUT_RING((1 << 16) | 1);			ADVANCE_RING();		}	}	drm_free(buffer, buffer_size, DRM_MEM_BUFS);	return 0;}static int r128_cce_dispatch_write_pixels(drm_device_t * dev,					  drm_r128_depth_t * depth){	drm_r128_private_t *dev_priv = dev->dev_private;	int count, *x, *y;	u32 *buffer;	u8 *mask;	int i, xbuf_size, ybuf_size, buffer_size, mask_size;	RING_LOCALS;	DRM_DEBUG("\n");	count = depth->n;	if (count > 4096 || count <= 0)		return DRM_ERR(EMSGSIZE);	xbuf_size = count * sizeof(*x);	ybuf_size = count * sizeof(*y);	x = drm_alloc(xbuf_size, DRM_MEM_BUFS);	if (x == NULL) {		return DRM_ERR(ENOMEM);	}	y = drm_alloc(ybuf_size, DRM_MEM_BUFS);	if (y == NULL) {		drm_free(x, xbuf_size, DRM_MEM_BUFS);		return DRM_ERR(ENOMEM);	}	if (DRM_COPY_FROM_USER(x, depth->x, xbuf_size)) {		drm_free(x, xbuf_size, DRM_MEM_BUFS);		drm_free(y, ybuf_size, DRM_MEM_BUFS);		return DRM_ERR(EFAULT);	}	if (DRM_COPY_FROM_USER(y, depth->y, xbuf_size)) {		drm_free(x, xbuf_size, DRM_MEM_BUFS);		drm_free(y, ybuf_size, DRM_MEM_BUFS);		return DRM_ERR(EFAULT);	}	buffer_size = depth->n * sizeof(u32);	buffer = drm_alloc(buffer_size, DRM_MEM_BUFS);	if (buffer == NULL) {		drm_free(x, xbuf_size, DRM_MEM_BUFS);		drm_free(y, ybuf_size, DRM_MEM_BUFS);		return DRM_ERR(ENOMEM);	}	if (DRM_COPY_FROM_USER(buffer, depth->buffer, buffer_size)) {		drm_free(x, xbuf_size, DRM_MEM_BUFS);		drm_free(y, ybuf_size, DRM_MEM_BUFS);		drm_free(buffer, buffer_size, DRM_MEM_BUFS);		return DRM_ERR(EFAULT);	}	if (depth->mask) {		mask_size = depth->n * sizeof(u8);		mask = drm_alloc(mask_size, DRM_MEM_BUFS);		if (mask == NULL) {			drm_free(x, xbuf_size, DRM_MEM_BUFS);			drm_free(y, ybuf_size, DRM_MEM_BUFS);			drm_free(buffer, buffer_size, DRM_MEM_BUFS);			return DRM_ERR(ENOMEM);		}		if (DRM_COPY_FROM_USER(mask, depth->mask, mask_size)) {			drm_free(x, xbuf_size, DRM_MEM_BUFS);			drm_free(y, ybuf_size, DRM_MEM_BUFS);			drm_free(buffer, buffer_size, DRM_MEM_BUFS);			drm_free(mask, mask_size, DRM_MEM_BUFS);			return DRM_ERR(EFAULT);		}		for (i = 0; i < count; i++) {			if (mask[i]) {				BEGIN_RING(6);				OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4));				OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL |					 R128_GMC_BRUSH_SOLID_COLOR |					 (dev_priv->depth_fmt << 8) |					 R128_GMC_SRC_DATATYPE_COLOR |					 R128_ROP3_P |					 R128_GMC_CLR_CMP_CNTL_DIS |					 R128_GMC_WR_MSK_DIS);				OUT_RING(dev_priv->depth_pitch_offset_c);				OUT_RING(buffer[i]);				OUT_RING((x[i] << 16) | y[i]);				OUT_RING((1 << 16) | 1);				ADVANCE_RING();			}		}		drm_free(mask, mask_size, DRM_MEM_BUFS);	} else {		for (i = 0; i < count; i++) {			BEGIN_RING(6);			OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4));			OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL |				 R128_GMC_BRUSH_SOLID_COLOR |				 (dev_priv->depth_fmt << 8) |				 R128_GMC_SRC_DATATYPE_COLOR |				 R128_ROP3_P |				 R128_GMC_CLR_CMP_CNTL_DIS |				 R128_GMC_WR_MSK_DIS);			OUT_RING(dev_priv->depth_pitch_offset_c);			OUT_RING(buffer[i]);			OUT_RING((x[i] << 16) | y[i]);			OUT_RING((1 << 16) | 1);			ADVANCE_RING();		}	}	drm_free(x, xbuf_size, DRM_MEM_BUFS);	drm_free(y, ybuf_size, DRM_MEM_BUFS);	drm_free(buffer, buffer_size, DRM_MEM_BUFS);	return 0;}static int r128_cce_dispatch_read_span(drm_device_t * dev,				       drm_r128_depth_t * depth){	drm_r128_private_t *dev_priv = dev->dev_private;	int count, x, y;	RING_LOCALS;	DRM_DEBUG("\n");	count = depth->n;	if (count > 4096 || count <= 0)		return DRM_ERR(EMSGSIZE);	if (DRM_COPY_FROM_USER(&x, depth->x, sizeof(x))) {		return DRM_ERR(EFAULT);	}	if (DRM_COPY_FROM_USER(&y, depth->y, sizeof(y))) {		return DRM_ERR(EFAULT);	}	BEGIN_RING(7);	OUT_RING(CCE_PACKET3(R128_CNTL_BITBLT_MULTI, 5));	OUT_RING(R128_GMC_SRC_PITCH_OFFSET_CNTL |		 R128_GMC_DST_PITCH_OFFSET_CNTL |		 R128_GMC_BRUSH_NONE |		 (dev_priv->depth_fmt << 8) |		 R128_GMC_SRC_DATATYPE_COLOR |		 R128_ROP3_S |		 R128_DP_SRC_SOURCE_MEMORY |		 R128_GMC_CLR_CMP_CNTL_DIS | R128_GMC_WR_MSK_DIS);	OUT_RING(dev_priv->depth_pitch_offset_c);	OUT_RING(dev_priv->span_pitch_offset_c);	OUT_RING((x << 16) | y);	OUT_RING((0 << 16) | 0);

⌨️ 快捷键说明

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