summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/radeon
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri/radeon')
-rw-r--r--src/mesa/drivers/dri/radeon/common_context.h33
-rw-r--r--src/mesa/drivers/dri/radeon/common_misc.c85
-rw-r--r--src/mesa/drivers/dri/radeon/common_misc.h4
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_bo_legacy.c34
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_context.c6
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_context.h1
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_ioctl.c14
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_ioctl.h16
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)