📄 r300_ioctl.c
字号:
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 + -