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

📄 r300_ioctl.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 2 页
字号:
	    vap_cntl |= (5 << R300_PVS_NUM_FPUS_SHIFT);	else if ((r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV410) ||		 (r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_R420))	    vap_cntl |= (6 << R300_PVS_NUM_FPUS_SHIFT);	else if ((r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_R520) ||		 (r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_R580))	    vap_cntl |= (8 << R300_PVS_NUM_FPUS_SHIFT);	else	    vap_cntl |= (4 << R300_PVS_NUM_FPUS_SHIFT);	R300_STATECHANGE(rmesa, vap_cntl);	reg_start(R300_VAP_CNTL, 0);	e32(vap_cntl);	if (has_tcl) {		R300_STATECHANGE(r300, pvs);		reg_start(R300_VAP_PVS_CODE_CNTL_0, 2);		e32((0 << R300_PVS_FIRST_INST_SHIFT) |		    (0 << R300_PVS_XYZW_VALID_INST_SHIFT) |		    (1 << R300_PVS_LAST_INST_SHIFT));		e32((0 << R300_PVS_CONST_BASE_OFFSET_SHIFT) |		    (0 << R300_PVS_MAX_CONST_ADDR_SHIFT));		e32(1 << R300_PVS_LAST_VTX_SRC_INST_SHIFT);		R300_STATECHANGE(r300, vpi);		vsf_start_fragment(0x0, 8);		e32(PVS_OP_DST_OPERAND(VE_ADD, GL_FALSE, GL_FALSE, 0, 0xf, PVS_DST_REG_OUT));		e32(PVS_SRC_OPERAND(0, PVS_SRC_SELECT_X, PVS_SRC_SELECT_Y, PVS_SRC_SELECT_Z, PVS_SRC_SELECT_W, PVS_SRC_REG_INPUT, VSF_FLAG_NONE));		e32(PVS_SRC_OPERAND(0, PVS_SRC_SELECT_FORCE_0, PVS_SRC_SELECT_FORCE_0, PVS_SRC_SELECT_FORCE_0, PVS_SRC_SELECT_FORCE_0, PVS_SRC_REG_INPUT, VSF_FLAG_NONE));		e32(0x0);		e32(PVS_OP_DST_OPERAND(VE_ADD, GL_FALSE, GL_FALSE, 1, 0xf, PVS_DST_REG_OUT));		e32(PVS_SRC_OPERAND(1, PVS_SRC_SELECT_X, PVS_SRC_SELECT_Y, PVS_SRC_SELECT_Z, PVS_SRC_SELECT_W, PVS_SRC_REG_INPUT, VSF_FLAG_NONE));		e32(PVS_SRC_OPERAND(1, PVS_SRC_SELECT_FORCE_0, PVS_SRC_SELECT_FORCE_0, PVS_SRC_SELECT_FORCE_0, PVS_SRC_SELECT_FORCE_0, PVS_SRC_REG_INPUT, VSF_FLAG_NONE));		e32(0x0);	}}/** * Buffer clear */static void r300Clear(GLcontext * ctx, GLbitfield mask){	r300ContextPtr r300 = R300_CONTEXT(ctx);	__DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;	int flags = 0;	int bits = 0;	int swapped;	if (RADEON_DEBUG & DEBUG_IOCTL)		fprintf(stderr, "r300Clear\n");	{		LOCK_HARDWARE(&r300->radeon);		UNLOCK_HARDWARE(&r300->radeon);		if (dPriv->numClipRects == 0)			return;	}	if (mask & BUFFER_BIT_FRONT_LEFT) {		flags |= BUFFER_BIT_FRONT_LEFT;		mask &= ~BUFFER_BIT_FRONT_LEFT;	}	if (mask & BUFFER_BIT_BACK_LEFT) {		flags |= BUFFER_BIT_BACK_LEFT;		mask &= ~BUFFER_BIT_BACK_LEFT;	}	if (mask & BUFFER_BIT_DEPTH) {		bits |= CLEARBUFFER_DEPTH;		mask &= ~BUFFER_BIT_DEPTH;	}	if ((mask & BUFFER_BIT_STENCIL) && r300->state.stencil.hw_stencil) {		bits |= CLEARBUFFER_STENCIL;		mask &= ~BUFFER_BIT_STENCIL;	}	if (mask) {		if (RADEON_DEBUG & DEBUG_FALLBACKS)			fprintf(stderr, "%s: swrast clear, mask: %x\n",				__FUNCTION__, mask);		_swrast_Clear(ctx, mask);	}	swapped = r300->radeon.sarea->pfCurrentPage == 1;	/* Make sure it fits there. */	r300EnsureCmdBufSpace(r300, 421 * 3, __FUNCTION__);	if (flags || bits)		r300EmitClearState(ctx);	if (flags & BUFFER_BIT_FRONT_LEFT) {		r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, swapped);		bits = 0;	}	if (flags & BUFFER_BIT_BACK_LEFT) {		r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, swapped ^ 1);		bits = 0;	}	if (bits)		r300ClearBuffer(r300, bits, 0);}void r300Flush(GLcontext * ctx){	r300ContextPtr rmesa = R300_CONTEXT(ctx);	if (RADEON_DEBUG & DEBUG_IOCTL)		fprintf(stderr, "%s\n", __FUNCTION__);	if (rmesa->dma.flush)		rmesa->dma.flush( rmesa );	if (rmesa->cmdbuf.count_used > rmesa->cmdbuf.count_reemit)		r300FlushCmdBuf(rmesa, __FUNCTION__);}#ifdef USER_BUFFERS#include "r300_mem.h"void r300RefillCurrentDmaRegion(r300ContextPtr rmesa, int size){	struct r300_dma_buffer *dmabuf;	size = MAX2(size, RADEON_BUFFER_SIZE * 16);	if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA))		fprintf(stderr, "%s\n", __FUNCTION__);	if (rmesa->dma.flush) {		rmesa->dma.flush(rmesa);	}	if (rmesa->dma.current.buf) {#ifdef USER_BUFFERS		r300_mem_use(rmesa, rmesa->dma.current.buf->id);#endif		r300ReleaseDmaRegion(rmesa, &rmesa->dma.current, __FUNCTION__);	}	if (rmesa->dma.nr_released_bufs > 4)		r300FlushCmdBuf(rmesa, __FUNCTION__);	dmabuf = CALLOC_STRUCT(r300_dma_buffer);	dmabuf->buf = (void *)1;	/* hack */	dmabuf->refcount = 1;	dmabuf->id = r300_mem_alloc(rmesa, 4, size);	if (dmabuf->id == 0) {		LOCK_HARDWARE(&rmesa->radeon);	/* no need to validate */		r300FlushCmdBufLocked(rmesa, __FUNCTION__);		radeonWaitForIdleLocked(&rmesa->radeon);		dmabuf->id = r300_mem_alloc(rmesa, 4, size);		UNLOCK_HARDWARE(&rmesa->radeon);		if (dmabuf->id == 0) {			fprintf(stderr,				"Error: Could not get dma buffer... exiting\n");			_mesa_exit(-1);		}	}	rmesa->dma.current.buf = dmabuf;	rmesa->dma.current.address = r300_mem_ptr(rmesa, dmabuf->id);	rmesa->dma.current.end = size;	rmesa->dma.current.start = 0;	rmesa->dma.current.ptr = 0;}void r300ReleaseDmaRegion(r300ContextPtr rmesa,			  struct r300_dma_region *region, const char *caller){	if (RADEON_DEBUG & DEBUG_IOCTL)		fprintf(stderr, "%s from %s\n", __FUNCTION__, caller);	if (!region->buf)		return;	if (rmesa->dma.flush)		rmesa->dma.flush(rmesa);	if (--region->buf->refcount == 0) {		r300_mem_free(rmesa, region->buf->id);		FREE(region->buf);		rmesa->dma.nr_released_bufs++;	}	region->buf = 0;	region->start = 0;}/* Allocates a region from rmesa->dma.current.  If there isn't enough * space in current, grab a new buffer (and discard what was left of current) */void r300AllocDmaRegion(r300ContextPtr rmesa,			struct r300_dma_region *region,			int bytes, int alignment){	if (RADEON_DEBUG & DEBUG_IOCTL)		fprintf(stderr, "%s %d\n", __FUNCTION__, bytes);	if (rmesa->dma.flush)		rmesa->dma.flush(rmesa);	if (region->buf)		r300ReleaseDmaRegion(rmesa, region, __FUNCTION__);	alignment--;	rmesa->dma.current.start = rmesa->dma.current.ptr =	    (rmesa->dma.current.ptr + alignment) & ~alignment;	if (rmesa->dma.current.ptr + bytes > rmesa->dma.current.end)		r300RefillCurrentDmaRegion(rmesa, (bytes + 0x7) & ~0x7);	region->start = rmesa->dma.current.start;	region->ptr = rmesa->dma.current.start;	region->end = rmesa->dma.current.start + bytes;	region->address = rmesa->dma.current.address;	region->buf = rmesa->dma.current.buf;	region->buf->refcount++;	rmesa->dma.current.ptr += bytes;	/* bug - if alignment > 7 */	rmesa->dma.current.start =	    rmesa->dma.current.ptr = (rmesa->dma.current.ptr + 0x7) & ~0x7;	assert(rmesa->dma.current.ptr <= rmesa->dma.current.end);}#elsestatic void r300RefillCurrentDmaRegion(r300ContextPtr rmesa){	struct r300_dma_buffer *dmabuf;	int fd = rmesa->radeon.dri.fd;	int index = 0;	int size = 0;	drmDMAReq dma;	int ret;	if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA))		fprintf(stderr, "%s\n", __FUNCTION__);	if (rmesa->dma.flush) {		rmesa->dma.flush(rmesa);	}	if (rmesa->dma.current.buf)		r300ReleaseDmaRegion(rmesa, &rmesa->dma.current, __FUNCTION__);	if (rmesa->dma.nr_released_bufs > 4)		r300FlushCmdBuf(rmesa, __FUNCTION__);	dma.context = rmesa->radeon.dri.hwContext;	dma.send_count = 0;	dma.send_list = NULL;	dma.send_sizes = NULL;	dma.flags = 0;	dma.request_count = 1;	dma.request_size = RADEON_BUFFER_SIZE;	dma.request_list = &index;	dma.request_sizes = &size;	dma.granted_count = 0;	LOCK_HARDWARE(&rmesa->radeon);	/* no need to validate */	ret = drmDMA(fd, &dma);	if (ret != 0) {		/* Try to release some buffers and wait until we can't get any more */		if (rmesa->dma.nr_released_bufs) {			r300FlushCmdBufLocked(rmesa, __FUNCTION__);		}		if (RADEON_DEBUG & DEBUG_DMA)			fprintf(stderr, "Waiting for buffers\n");		radeonWaitForIdleLocked(&rmesa->radeon);		ret = drmDMA(fd, &dma);		if (ret != 0) {			UNLOCK_HARDWARE(&rmesa->radeon);			fprintf(stderr,				"Error: Could not get dma buffer... exiting\n");			_mesa_exit(-1);		}	}	UNLOCK_HARDWARE(&rmesa->radeon);	if (RADEON_DEBUG & DEBUG_DMA)		fprintf(stderr, "Allocated buffer %d\n", index);	dmabuf = CALLOC_STRUCT(r300_dma_buffer);	dmabuf->buf = &rmesa->radeon.radeonScreen->buffers->list[index];	dmabuf->refcount = 1;	rmesa->dma.current.buf = dmabuf;	rmesa->dma.current.address = dmabuf->buf->address;	rmesa->dma.current.end = dmabuf->buf->total;	rmesa->dma.current.start = 0;	rmesa->dma.current.ptr = 0;}void r300ReleaseDmaRegion(r300ContextPtr rmesa,			  struct r300_dma_region *region, const char *caller){	if (RADEON_DEBUG & DEBUG_IOCTL)		fprintf(stderr, "%s from %s\n", __FUNCTION__, caller);	if (!region->buf)		return;	if (rmesa->dma.flush)		rmesa->dma.flush(rmesa);	if (--region->buf->refcount == 0) {		drm_radeon_cmd_header_t *cmd;		if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA))			fprintf(stderr, "%s -- DISCARD BUF %d\n",				__FUNCTION__, region->buf->buf->idx);		cmd =		    (drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa,								sizeof								(*cmd) / 4,								__FUNCTION__);		cmd->dma.cmd_type = R300_CMD_DMA_DISCARD;		cmd->dma.buf_idx = region->buf->buf->idx;		FREE(region->buf);		rmesa->dma.nr_released_bufs++;	}	region->buf = 0;	region->start = 0;}/* Allocates a region from rmesa->dma.current.  If there isn't enough * space in current, grab a new buffer (and discard what was left of current) */void r300AllocDmaRegion(r300ContextPtr rmesa,			struct r300_dma_region *region,			int bytes, int alignment){	if (RADEON_DEBUG & DEBUG_IOCTL)		fprintf(stderr, "%s %d\n", __FUNCTION__, bytes);	if (rmesa->dma.flush)		rmesa->dma.flush(rmesa);	if (region->buf)		r300ReleaseDmaRegion(rmesa, region, __FUNCTION__);	alignment--;	rmesa->dma.current.start = rmesa->dma.current.ptr =	    (rmesa->dma.current.ptr + alignment) & ~alignment;	if (rmesa->dma.current.ptr + bytes > rmesa->dma.current.end)		r300RefillCurrentDmaRegion(rmesa);	region->start = rmesa->dma.current.start;	region->ptr = rmesa->dma.current.start;	region->end = rmesa->dma.current.start + bytes;	region->address = rmesa->dma.current.address;	region->buf = rmesa->dma.current.buf;	region->buf->refcount++;	rmesa->dma.current.ptr += bytes;	/* bug - if alignment > 7 */	rmesa->dma.current.start =	    rmesa->dma.current.ptr = (rmesa->dma.current.ptr + 0x7) & ~0x7;	assert(rmesa->dma.current.ptr <= rmesa->dma.current.end);}#endifGLboolean r300IsGartMemory(r300ContextPtr rmesa, const GLvoid * pointer,			   GLint size){	int offset =	    (char *)pointer -	    (char *)rmesa->radeon.radeonScreen->gartTextures.map;	int valid = (size >= 0 && offset >= 0		     && offset + size <		     rmesa->radeon.radeonScreen->gartTextures.size);	if (RADEON_DEBUG & DEBUG_IOCTL)		fprintf(stderr, "r300IsGartMemory( %p ) : %d\n", pointer,			valid);	return valid;}GLuint r300GartOffsetFromVirtual(r300ContextPtr rmesa, const GLvoid * pointer){	int offset =	    (char *)pointer -	    (char *)rmesa->radeon.radeonScreen->gartTextures.map;	//fprintf(stderr, "offset=%08x\n", offset);	if (offset < 0	    || offset > rmesa->radeon.radeonScreen->gartTextures.size)		return ~0;	else		return rmesa->radeon.radeonScreen->gart_texture_offset + offset;}void r300InitIoctlFuncs(struct dd_function_table *functions){	functions->Clear = r300Clear;	functions->Finish = radeonFinish;	functions->Flush = r300Flush;}

⌨️ 快捷键说明

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