📄 r300_ioctl.c
字号:
e32(R300_PFS_NODE_OUTPUT_COLOR); R300_STATECHANGE(r300, fpi[0]); R300_STATECHANGE(r300, fpi[1]); R300_STATECHANGE(r300, fpi[2]); R300_STATECHANGE(r300, fpi[3]); reg_start(R300_PFS_INSTR0_0, 0); e32(FP_INSTRC(MAD, FP_ARGC(SRC0C_XYZ), FP_ARGC(ONE), FP_ARGC(ZERO))); reg_start(R300_PFS_INSTR1_0, 0); e32(FP_SELC(0,NO,XYZ,FP_TMP(0),0,0)); reg_start(R300_PFS_INSTR2_0, 0); e32(FP_INSTRA(MAD, FP_ARGA(SRC0A), FP_ARGA(ONE), FP_ARGA(ZERO))); reg_start(R300_PFS_INSTR3_0, 0); e32(FP_SELA(0,NO,W,FP_TMP(0),0,0)); R300_STATECHANGE(r300, pvs); reg_start(R300_VAP_PVS_CNTL_1, 2); e32((0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT) | (0 << R300_PVS_CNTL_1_POS_END_SHIFT) | (1 << R300_PVS_CNTL_1_PROGRAM_END_SHIFT)); e32(0); e32(1 << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT); R300_STATECHANGE(r300, vpi); vsf_start_fragment(0x0, 8); e32(VP_OUT(ADD,OUT,0,XYZW)); e32(VP_IN(IN,0)); e32(VP_ZERO()); e32(0); e32(VP_OUT(ADD,OUT,1,XYZW)); e32(VP_IN(IN,1)); e32(VP_ZERO()); e32(0); /*reg_start(0x4500,0); e32(2560-1);*/}#endif/** * Buffer clear */static void r300Clear(GLcontext * ctx, GLbitfield mask, GLboolean all, GLint cx, GLint cy, GLint cw, GLint ch){ 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, "%s: all=%d cx=%d cy=%d cw=%d ch=%d\n", __FUNCTION__, all, cx, cy, cw, ch); { 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, all, cx, cy, cw, ch); } swapped = r300->radeon.doPageFlip && (r300->radeon.sarea->pfCurrentPage == 1);#ifdef CB_DPATH /* Make sure it fits there. */ r300EnsureCmdBufSpace(r300, 419*3, __FUNCTION__); if(flags || bits) r300EmitClearState(ctx);#endif 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);#ifndef CB_DPATH /* Recalculate the hardware state. This could be done more efficiently, * but do keep it like this for now. */ r300ResetHwState(r300); /* r300ClearBuffer has trampled all over the hardware state.. */ r300->hw.all_dirty=GL_TRUE;#endif}void r300Flush(GLcontext * ctx){ r300ContextPtr r300 = R300_CONTEXT(ctx); if (RADEON_DEBUG & DEBUG_IOCTL) fprintf(stderr, "%s\n", __FUNCTION__); if (r300->cmdbuf.count_used > r300->cmdbuf.count_reemit) r300FlushCmdBuf(r300, __FUNCTION__);}#ifdef USER_BUFFERS#include "radeon_mm.h"void r300RefillCurrentDmaRegion(r300ContextPtr rmesa){ struct r300_dma_buffer *dmabuf; 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__); dmabuf = CALLOC_STRUCT(r300_dma_buffer); dmabuf->buf = (void *)1; /* hack */ dmabuf->refcount = 1; dmabuf->id = radeon_mm_alloc(rmesa, 4, RADEON_BUFFER_SIZE*16); if (dmabuf->id == 0) { LOCK_HARDWARE(&rmesa->radeon); /* no need to validate */ r300FlushCmdBufLocked(rmesa, __FUNCTION__); radeonWaitForIdleLocked(&rmesa->radeon); dmabuf->id = radeon_mm_alloc(rmesa, 4, RADEON_BUFFER_SIZE*16);#ifdef HW_VBOS if (dmabuf->id == 0) { /* Just kick all */ r300_evict_vbos(rmesa->radeon.glCtx, /*RADEON_BUFFER_SIZE*16*/1<<30); dmabuf->id = radeon_mm_alloc(rmesa, 4, RADEON_BUFFER_SIZE*16); }#endif UNLOCK_HARDWARE(&rmesa->radeon); if (dmabuf->id == 0) { fprintf(stderr, "Error: Could not get dma buffer... exiting\n"); exit(-1); } } rmesa->dma.current.buf = dmabuf; rmesa->dma.current.address = radeon_mm_ptr(rmesa, dmabuf->id); rmesa->dma.current.end = RADEON_BUFFER_SIZE*16; 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) { radeon_mm_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); 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);}#elsevoid 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"); 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);}#endif/* Called via glXGetMemoryOffsetMESA() */GLuint r300GetMemoryOffsetMESA(__DRInativeDisplay * dpy, int scrn, const GLvoid * pointer){ GET_CURRENT_CONTEXT(ctx); r300ContextPtr rmesa; GLuint card_offset; if (!ctx || !(rmesa = R300_CONTEXT(ctx))) { fprintf(stderr, "%s: no context\n", __FUNCTION__); return ~0; } if (!r300IsGartMemory(rmesa, pointer, 0)) return ~0; if (rmesa->radeon.dri.drmMinor < 6) return ~0; card_offset = r300GartOffsetFromVirtual(rmesa, pointer); return card_offset - rmesa->radeon.radeonScreen->gart_base;}GLboolean 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 + -