radeon: Fix dma buffer object pool to scale object sizes.

This fixes problems when application is using large vertex arrays for drawing.

Signed-off-by: Pauli Nieminen <suokkos@gmail.com>
This commit is contained in:
Pauli Nieminen
2009-08-19 14:47:25 +03:00
committed by Alex Deucher
parent d551b3ac88
commit 66e019c6c9
2 changed files with 42 additions and 11 deletions
@@ -313,8 +313,9 @@ struct radeon_dma {
struct radeon_dma_bo free;
struct radeon_dma_bo wait;
struct radeon_dma_bo reserved;
int current_used; /** Number of bytes allocated and forgotten about */
int current_vertexptr; /** End of active vertex region */
size_t current_used; /** Number of bytes allocated and forgotten about */
size_t current_vertexptr; /** End of active vertex region */
size_t minimum_size;
/**
* If current_vertexptr != current_used then flush must be non-zero.
+39 -9
View File
@@ -164,14 +164,18 @@ void rcommon_emit_vector(GLcontext * ctx, struct radeon_aos *aos,
void radeon_init_dma(radeonContextPtr rmesa)
{
make_empty_list(&rmesa->dma.free);
make_empty_list(&rmesa->dma.wait);
make_empty_list(&rmesa->dma.reserved);
make_empty_list(&rmesa->dma.free);
make_empty_list(&rmesa->dma.wait);
make_empty_list(&rmesa->dma.reserved);
rmesa->dma.minimum_size = MAX_DMA_BUF_SZ;
}
void radeonRefillCurrentDmaRegion(radeonContextPtr rmesa, int size)
{
size = MAX2(size, MAX_DMA_BUF_SZ);
/* we set minimum sizes to at least requested size
aligned to next 16 bytes. */
if (size > rmesa->dma.minimum_size)
rmesa->dma.minimum_size = (size + 15) & (~15);
if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA))
fprintf(stderr, "%s\n", __FUNCTION__);
@@ -184,14 +188,15 @@ void radeonRefillCurrentDmaRegion(radeonContextPtr rmesa, int size)
if (!is_empty_list(&rmesa->dma.reserved))
radeon_bo_unmap(first_elem(&rmesa->dma.reserved)->bo);
if (is_empty_list(&rmesa->dma.free)) {
if (is_empty_list(&rmesa->dma.free)
|| last_elem(&rmesa->dma.free)->bo->size < size) {
struct radeon_dma_bo *dma_bo = CALLOC(sizeof(struct radeon_dma_bo));
assert(dma_bo);
again_alloc:
dma_bo->bo = radeon_bo_open(rmesa->radeonScreen->bom,
0, size, 4, RADEON_GEM_DOMAIN_GTT,
0);
0, rmesa->dma.minimum_size, 4,
RADEON_GEM_DOMAIN_GTT, 0);
if (!dma_bo->bo) {
rcommonFlushCmdBuf(rmesa, __FUNCTION__);
@@ -241,7 +246,7 @@ void radeonAllocDmaRegion(radeonContextPtr rmesa,
if (is_empty_list(&rmesa->dma.reserved)
|| rmesa->dma.current_used + bytes > first_elem(&rmesa->dma.reserved)->bo->size)
radeonRefillCurrentDmaRegion(rmesa, (bytes + 15) & ~15);
radeonRefillCurrentDmaRegion(rmesa, bytes);
*poffset = rmesa->dma.current_used;
*pbo = first_elem(&rmesa->dma.reserved)->bo;
@@ -267,6 +272,12 @@ void radeonFreeDmaRegions(radeonContextPtr rmesa)
FREE(dma_bo);
}
foreach_s(dma_bo, temp, &rmesa->dma.free) {
remove_from_list(dma_bo);
radeon_bo_unref(dma_bo->bo);
FREE(dma_bo);
}
foreach_s(dma_bo, temp, &rmesa->dma.reserved) {
remove_from_list(dma_bo);
radeon_bo_unmap(dma_bo->bo);
@@ -286,6 +297,11 @@ void radeonReturnDmaRegion(radeonContextPtr rmesa, int return_bytes)
rmesa->dma.current_vertexptr = rmesa->dma.current_used;
}
static int radeon_bo_is_idle(struct radeon_bo* bo)
{
return bo->cref == 1;
}
void radeonReleaseDmaRegions(radeonContextPtr rmesa)
{
struct radeon_dma_bo *dma_bo;
@@ -305,7 +321,14 @@ void radeonReleaseDmaRegions(radeonContextPtr rmesa)
FREE(dma_bo);
continue;
}
if (dma_bo->bo->cref > 1)
/* free objects that are too small to be used because of large request */
if (dma_bo->bo->size < rmesa->dma.minimum_size) {
radeon_bo_unref(dma_bo->bo);
remove_from_list(dma_bo);
FREE(dma_bo);
continue;
}
if (!radeon_bo_is_idle(dma_bo->bo))
continue;
remove_from_list(dma_bo);
dma_bo->expire_counter = expire_at;
@@ -317,6 +340,13 @@ void radeonReleaseDmaRegions(radeonContextPtr rmesa)
radeon_bo_unmap(first_elem(&rmesa->dma.reserved)->bo);
/* move reserved to wait list */
foreach_s(dma_bo, temp, &rmesa->dma.reserved) {
/* free objects that are too small to be used because of large request */
if (dma_bo->bo->size < rmesa->dma.minimum_size) {
radeon_bo_unref(dma_bo->bo);
remove_from_list(dma_bo);
FREE(dma_bo);
continue;
}
remove_from_list(dma_bo);
dma_bo->expire_counter = expire_at;
insert_at_tail(&rmesa->dma.wait, dma_bo);