diff options
author | Dave Airlie <airlied@redhat.com> | 2009-01-29 16:47:37 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2009-01-29 16:47:37 +1000 |
commit | 5ba92a5b0543b4ff2c7db6101029ba36cb9843fa (patch) | |
tree | 5d03423813f9044a6e05b66c7a141fd1a315447c /src/mesa/drivers/dri/radeon | |
parent | 682ebc79d55ae6aede3369e344dbcb320be1f39f (diff) |
radeon/r200/r300: bring back old style DMA buffer on top of BOs.
this gets back a lot of the lots speed in gears on r500 at least
I also fixed the legacy bufmgr to deal when the dma space fills up
Diffstat (limited to 'src/mesa/drivers/dri/radeon')
-rw-r--r-- | src/mesa/drivers/dri/radeon/common_context.h | 33 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/common_misc.c | 85 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/common_misc.h | 4 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_bo_legacy.c | 34 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_context.c | 6 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_context.h | 1 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_ioctl.c | 14 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_ioctl.h | 16 |
8 files changed, 145 insertions, 48 deletions
diff --git a/src/mesa/drivers/dri/radeon/common_context.h b/src/mesa/drivers/dri/radeon/common_context.h index 09a53b00ea..471e7cdfb1 100644 --- a/src/mesa/drivers/dri/radeon/common_context.h +++ b/src/mesa/drivers/dri/radeon/common_context.h @@ -225,16 +225,26 @@ struct radeon_aos { }; struct radeon_dma { - /* Active dma region. Allocations for vertices and retained - * regions come from here. Also used for emitting random vertices, - * these may be flushed by calling flush_current(); - */ - struct radeon_dma_region current; - - void (*flush)( GLcontext *ctx ); - - char *buf0_address; /* start of buf[0], for index calcs */ - GLuint nr_released_bufs; /* flush after so many buffers released */ + /* Active dma region. Allocations for vertices and retained + * regions come from here. Also used for emitting random vertices, + * these may be flushed by calling flush_current(); + */ + struct radeon_bo *current; /** Buffer that DMA memory is allocated from */ + int current_used; /** Number of bytes allocated and forgotten about */ + int current_vertexptr; /** End of active vertex region */ + + /** + * If current_vertexptr != current_used then flush must be non-zero. + * flush must be called before non-active vertex allocations can be + * performed. + */ + void (*flush) (GLcontext *); + + /* Number of "in-flight" DMA buffers, i.e. the number of buffers + * for which a DISCARD command is currently queued in the command buffer +. + */ + GLuint nr_released_bufs; }; struct radeon_ioctl { @@ -266,6 +276,8 @@ static INLINE GLuint radeonPackColor(GLuint cpp, #define MAX_CMD_BUF_SZ (16*1024) +#define MAX_DMA_BUF_SZ (64*1024) + struct radeon_store { GLuint statenr; GLuint primnr; @@ -354,6 +366,7 @@ struct radeon_context { int texture_depth; float initialMaxAnisotropy; + struct radeon_dma dma; /* Rasterization and vertex state: */ GLuint TclFallback; diff --git a/src/mesa/drivers/dri/radeon/common_misc.c b/src/mesa/drivers/dri/radeon/common_misc.c index 99ca936dae..3ed58815d3 100644 --- a/src/mesa/drivers/dri/radeon/common_misc.c +++ b/src/mesa/drivers/dri/radeon/common_misc.c @@ -1316,22 +1316,19 @@ void rcommon_emit_vector(GLcontext * ctx, struct radeon_aos *aos, uint32_t *out; uint32_t bo_size; - memset(aos, 0, sizeof(struct radeon_aos)); if (stride == 0) { - bo_size = size * 4; + radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * 4, 32); count = 1; aos->stride = 0; } else { - bo_size = size * count * 4; + radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * count * 4, 32); aos->stride = size; } - aos->bo = radeon_bo_open(rmesa->radeonScreen->bom, - 0, bo_size, 32, RADEON_GEM_DOMAIN_GTT, 0); - aos->offset = 0; + aos->components = size; aos->count = count; - radeon_bo_map(aos->bo, 1); +// radeon_bo_map(aos->bo, 1); out = (uint32_t*)((char*)aos->bo->ptr + aos->offset); switch (size) { case 1: radeonEmitVec4(out, data, stride, count); break; @@ -1342,7 +1339,7 @@ void rcommon_emit_vector(GLcontext * ctx, struct radeon_aos *aos, assert(0); break; } - radeon_bo_unmap(aos->bo); +// radeon_bo_unmap(aos->bo); } @@ -2321,3 +2318,75 @@ void radeonSpanRenderFinish(GLcontext * ctx) unmap_buffer(ctx->DrawBuffer->_StencilBuffer->Wrapped); } +void radeonRefillCurrentDmaRegion(radeonContextPtr rmesa, int size) +{ + size = MAX2(size, MAX_DMA_BUF_SZ * 16); + + if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA)) + fprintf(stderr, "%s\n", __FUNCTION__); + + if (rmesa->dma.flush) { + radeon_bo_unmap(rmesa->dma.current); + rmesa->dma.flush(rmesa->glCtx); + } + + + + if (rmesa->dma.nr_released_bufs > 4) { + rcommonFlushCmdBuf(rmesa, __FUNCTION__); + rmesa->dma.nr_released_bufs = 0; + } + + if (rmesa->dma.current) { + radeon_bo_unref(rmesa->dma.current); + rmesa->dma.current = 0; + } + + rmesa->dma.current = radeon_bo_open(rmesa->radeonScreen->bom, + 0, size, 4, RADEON_GEM_DOMAIN_GTT, + 0); + + rmesa->dma.current_used = 0; + rmesa->dma.current_vertexptr = 0; + radeon_bo_map(rmesa->dma.current, 1); +} + +/* 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 radeonAllocDmaRegion(radeonContextPtr rmesa, + struct radeon_bo **pbo, int *poffset, + int bytes, int alignment) +{ + if (RADEON_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s %d\n", __FUNCTION__, bytes); + + if (rmesa->dma.flush) + rmesa->dma.flush(rmesa->glCtx); + + assert(rmesa->dma.current_used == rmesa->dma.current_vertexptr); + + alignment--; + rmesa->dma.current_used = (rmesa->dma.current_used + alignment) & ~alignment; + + if (!rmesa->dma.current || rmesa->dma.current_used + bytes > rmesa->dma.current->size) + radeonRefillCurrentDmaRegion(rmesa, (bytes + 15) & ~15); + + *poffset = rmesa->dma.current_used; + *pbo = rmesa->dma.current; + radeon_bo_ref(*pbo); + + /* Always align to at least 16 bytes */ + rmesa->dma.current_used = (rmesa->dma.current_used + bytes + 15) & ~15; + rmesa->dma.current_vertexptr = rmesa->dma.current_used; + + assert(rmesa->dma.current_used <= rmesa->dma.current->size); +} + +void radeonReleaseDmaRegion(radeonContextPtr rmesa) +{ + rmesa->dma.nr_released_bufs++; + radeon_bo_unref(rmesa->dma.current); + rmesa->dma.current = NULL; +} + diff --git a/src/mesa/drivers/dri/radeon/common_misc.h b/src/mesa/drivers/dri/radeon/common_misc.h index aeff52a66e..d17d1607db 100644 --- a/src/mesa/drivers/dri/radeon/common_misc.h +++ b/src/mesa/drivers/dri/radeon/common_misc.h @@ -118,4 +118,8 @@ GLubyte *radeon_ptr16(const struct radeon_renderbuffer * rrb, GLint x, GLint y); GLubyte *radeon_ptr32(const struct radeon_renderbuffer * rrb, GLint x, GLint y); +void radeonRefillCurrentDmaRegion(radeonContextPtr rmesa, int size); +void radeonAllocDmaRegion(radeonContextPtr rmesa, + struct radeon_bo **pbo, int *poffset, + int bytes, int alignment); #endif diff --git a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c index 353f00100a..bd126c026c 100644 --- a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c +++ b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c @@ -77,6 +77,7 @@ struct bo_manager_legacy { uint32_t fb_location; uint32_t texture_offset; unsigned dma_alloc_size; + uint32_t dma_buf_count; unsigned cpendings; driTextureObject texture_swapped; driTexHeap *texture_heap; @@ -221,7 +222,7 @@ static int legacy_wait_pending(struct radeon_bo *bo) return 0; } -static void legacy_track_pending(struct bo_manager_legacy *boml) +static void legacy_track_pending(struct bo_manager_legacy *boml, int debug) { struct bo_legacy *bo_legacy; struct bo_legacy *next; @@ -229,6 +230,9 @@ static void legacy_track_pending(struct bo_manager_legacy *boml) legacy_get_current_age(boml); bo_legacy = boml->pending_bos.pnext; while (bo_legacy) { + if (debug) + fprintf(stderr,"pending %p %d %d %d\n", bo_legacy, bo_legacy->base.size, + boml->current_age, bo_legacy->pending); next = bo_legacy->pnext; if (legacy_is_pending(&(bo_legacy->base))) { } @@ -236,6 +240,19 @@ static void legacy_track_pending(struct bo_manager_legacy *boml) } } +static int legacy_wait_any_pending(struct bo_manager_legacy *boml) +{ + struct bo_legacy *bo_legacy; + struct bo_legacy *next; + + legacy_get_current_age(boml); + bo_legacy = boml->pending_bos.pnext; + if (!bo_legacy) + return -1; + legacy_wait_pending(&bo_legacy->base); + return 0; +} + static struct bo_legacy *bo_allocate(struct bo_manager_legacy *boml, uint32_t size, uint32_t alignment, @@ -292,13 +309,13 @@ static int bo_dma_alloc(struct radeon_bo *bo) if (r) { /* ptr is set to NULL if dma allocation failed */ bo_legacy->ptr = NULL; - exit(0); return r; } bo_legacy->ptr = boml->screen->gartTextures.map + base_offset; bo_legacy->offset = boml->screen->gart_texture_offset + base_offset; bo->size = size; boml->dma_alloc_size += size; + boml->dma_buf_count++; return 0; } @@ -328,6 +345,7 @@ static int bo_dma_free(struct radeon_bo *bo) return r; } boml->dma_alloc_size -= bo_legacy->base.size; + boml->dma_buf_count--; return 0; } @@ -388,15 +406,20 @@ static struct radeon_bo *bo_open(struct radeon_bo_manager *bom, return NULL; } if (bo_legacy->base.domains & RADEON_GEM_DOMAIN_GTT) { - legacy_track_pending(boml); + retry: + legacy_track_pending(boml, 0); /* dma buffers */ + r = bo_dma_alloc(&(bo_legacy->base)); if (r) { - fprintf(stderr, "Ran out of GART memory (for %d)!\n", size); + if (legacy_wait_any_pending(boml) == -1) { + fprintf(stderr, "Ran out of GART memory (for %d)!\n", size); fprintf(stderr, "Please consider adjusting GARTSize option.\n"); bo_free(bo_legacy); exit(-1); - return NULL; + } + goto retry; + return NULL; } } else { bo_legacy->ptr = malloc(bo_legacy->base.size); @@ -460,7 +483,6 @@ static int bo_map(struct radeon_bo *bo, int write) volatile int *buf = (int*)boml->screen->driScreen->pFB; p = *buf; } - return 0; } diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c index b87275c56b..a6a3b1178c 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_context.c @@ -318,7 +318,7 @@ radeonCreateContext( const __GLcontextModes *glVisual, screen->sarea_priv_offset); - rmesa->dma.buf0_address = rmesa->radeon.radeonScreen->buffers->list[0].address; + //rmesa->dma.buf0_address = rmesa->radeon.radeonScreen->buffers->list[0].address; (void) memset( rmesa->radeon.texture_heaps, 0, sizeof( rmesa->radeon.texture_heaps ) ); make_empty_list( & rmesa->radeon.swapped ); @@ -522,8 +522,8 @@ void radeonDestroyContext( __DRIcontextPrivate *driContextPriv ) radeonDestroySwtcl( rmesa->radeon.glCtx ); radeonReleaseArrays( rmesa->radeon.glCtx, ~0 ); - if (rmesa->dma.current.buf) { - radeonReleaseDmaRegion( rmesa, &rmesa->dma.current, __FUNCTION__ ); + if (rmesa->radeon.dma.current) { + radeonReleaseDmaRegion( rmesa, &rmesa->radeon.dma.current, __FUNCTION__ ); radeonFlushCmdBuf( rmesa, __FUNCTION__ ); } diff --git a/src/mesa/drivers/dri/radeon/radeon_context.h b/src/mesa/drivers/dri/radeon/radeon_context.h index dedc362604..ba5c57f121 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.h +++ b/src/mesa/drivers/dri/radeon/radeon_context.h @@ -425,7 +425,6 @@ struct r100_context { /* Vertex buffers */ struct radeon_ioctl ioctl; - struct radeon_dma dma; struct radeon_store store; /* A full state emit as of the first state emit in the main store, in case * the context is lost. diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.c b/src/mesa/drivers/dri/radeon/radeon_ioctl.c index cd0f90d748..5ab19b2a8c 100644 --- a/src/mesa/drivers/dri/radeon/radeon_ioctl.c +++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.c @@ -117,12 +117,12 @@ static void radeonBackUpAndEmitLostStateLocked( r100ContextPtr rmesa ) rmesa->radeon.lost_context = GL_FALSE; - nr_released_bufs = rmesa->dma.nr_released_bufs; + nr_released_bufs = rmesa->radeon.dma.nr_released_bufs; saved_store = rmesa->store; - rmesa->dma.nr_released_bufs = 0; + rmesa->radeon.dma.nr_released_bufs = 0; rmesa->store = rmesa->backup_store; radeonFlushCmdBufLocked( rmesa, __FUNCTION__ ); - rmesa->dma.nr_released_bufs = nr_released_bufs; + rmesa->radeon.dma.nr_released_bufs = nr_released_bufs; rmesa->store = saved_store; } @@ -308,8 +308,8 @@ void radeonFlushElts( GLcontext *ctx ) if (RADEON_DEBUG & DEBUG_IOCTL) fprintf(stderr, "%s\n", __FUNCTION__); - assert( rmesa->dma.flush == radeonFlushElts ); - rmesa->dma.flush = NULL; + assert( rmesa->radeon.dma.flush == radeonFlushElts ); + rmesa->radeon.dma.flush = NULL; /* Cope with odd number of elts: */ @@ -381,9 +381,9 @@ GLushort *radeonAllocEltsOpenEnded( r100ContextPtr rmesa, __FUNCTION__, cmd[1].i, vertex_format, primitive); - assert(!rmesa->dma.flush); + assert(!rmesa->radeon.dma.flush); rmesa->radeon.glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; - rmesa->dma.flush = radeonFlushElts; + rmesa->radeon.dma.flush = radeonFlushElts; rmesa->store.elts_start = ((char *)cmd) - rmesa->store.cmd_buf; diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.h b/src/mesa/drivers/dri/radeon/radeon_ioctl.h index d11feb5804..b4bc9b1144 100644 --- a/src/mesa/drivers/dri/radeon/radeon_ioctl.h +++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.h @@ -76,16 +76,6 @@ extern void radeonEmitBlit( r100ContextPtr rmesa, extern void radeonEmitWait( r100ContextPtr rmesa, GLuint flags ); extern void radeonFlushCmdBuf( r100ContextPtr rmesa, const char * ); -extern void radeonRefillCurrentDmaRegion( r100ContextPtr rmesa ); - -extern void radeonAllocDmaRegion( r100ContextPtr rmesa, - struct radeon_dma_region *region, - int bytes, - int alignment ); - -extern void radeonReleaseDmaRegion( r100ContextPtr rmesa, - struct radeon_dma_region *region, - const char *caller ); extern void radeonFlush( GLcontext *ctx ); extern void radeonFinish( GLcontext *ctx ); @@ -101,8 +91,8 @@ extern void radeonSetUpAtomList( r100ContextPtr rmesa ); */ #define RADEON_NEWPRIM( rmesa ) \ do { \ - if ( rmesa->dma.flush ) \ - rmesa->dma.flush( rmesa->radeon.glCtx ); \ + if ( rmesa->radeon.dma.flush ) \ + rmesa->radeon.dma.flush( rmesa->radeon.glCtx ); \ } while (0) /* Can accomodate several state changes and primitive changes without @@ -142,7 +132,7 @@ static INLINE int RADEON_DB_STATECHANGE( */ #define RADEON_FIREVERTICES( rmesa ) \ do { \ - if ( rmesa->store.cmd_used || rmesa->dma.flush ) { \ + if ( rmesa->store.cmd_used || rmesa->radeon.dma.flush ) { \ radeonFlush( rmesa->radeon.glCtx ); \ } \ } while (0) |