summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/radeon
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2009-01-31 01:59:57 +1000
committerDave Airlie <airlied@redhat.com>2009-01-31 01:59:57 +1000
commite45213d89bf26c68c9f4c9074eaec9ab3311de7d (patch)
treef4ca6a1fdec732dc2d5faba6d700ea54b14ff995 /src/mesa/drivers/dri/radeon
parent08bb7eedfbba839676ab63fb20dd22e4f27722cb (diff)
r200/r300: add aperture space checks
Diffstat (limited to 'src/mesa/drivers/dri/radeon')
-rw-r--r--src/mesa/drivers/dri/radeon/common_misc.c49
-rw-r--r--src/mesa/drivers/dri/radeon/common_misc.h33
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_bo_legacy.c65
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_bo_legacy.h1
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_cs_legacy.c104
5 files changed, 213 insertions, 39 deletions
diff --git a/src/mesa/drivers/dri/radeon/common_misc.c b/src/mesa/drivers/dri/radeon/common_misc.c
index 19294487f6..1adcefb19a 100644
--- a/src/mesa/drivers/dri/radeon/common_misc.c
+++ b/src/mesa/drivers/dri/radeon/common_misc.c
@@ -685,6 +685,14 @@ void rcommonInitCmdBuf(radeonContextPtr rmesa, int max_state_size)
assert(rmesa->cmdbuf.cs != NULL);
rmesa->cmdbuf.size = size;
+ if (!rmesa->radeonScreen->kernel_mm) {
+ radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_VRAM, rmesa->radeonScreen->texSize[0]);
+ radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_GTT, rmesa->radeonScreen->gartTextures.size);
+ } else {
+ radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_VRAM, rmesa->radeonScreen->texSize[0]);
+ radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_GTT, rmesa->radeonScreen->gartTextures.size);
+ }
+
}
/**
* Destroy the command buffer
@@ -907,7 +915,7 @@ void radeonCleanupContext(radeonContextPtr radeon)
}
}
-void
+static void
radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon,
GLframebuffer *draw)
{
@@ -1314,7 +1322,6 @@ void rcommon_emit_vector(GLcontext * ctx, struct radeon_aos *aos,
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
uint32_t *out;
- uint32_t bo_size;
if (stride == 0) {
radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * 4, 32);
@@ -1328,7 +1335,6 @@ void rcommon_emit_vector(GLcontext * ctx, struct radeon_aos *aos,
aos->components = size;
aos->count = count;
-// 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;
@@ -1339,7 +1345,6 @@ void rcommon_emit_vector(GLcontext * ctx, struct radeon_aos *aos,
assert(0);
break;
}
-// radeon_bo_unmap(aos->bo);
}
@@ -2320,6 +2325,9 @@ void radeonSpanRenderFinish(GLcontext * ctx)
void radeonRefillCurrentDmaRegion(radeonContextPtr rmesa, int size)
{
+ struct radeon_cs_space_check bos[1];
+ int flushed, ret;
+
size = MAX2(size, MAX_DMA_BUF_SZ * 16);
if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA))
@@ -2330,8 +2338,6 @@ void radeonRefillCurrentDmaRegion(radeonContextPtr rmesa, int size)
rmesa->dma.flush(rmesa->glCtx);
}
-
-
if (rmesa->dma.nr_released_bufs > 4) {
rcommonFlushCmdBuf(rmesa, __FUNCTION__);
rmesa->dma.nr_released_bufs = 0;
@@ -2341,13 +2347,42 @@ void radeonRefillCurrentDmaRegion(radeonContextPtr rmesa, int size)
radeon_bo_unref(rmesa->dma.current);
rmesa->dma.current = 0;
}
-
+
+again_alloc:
rmesa->dma.current = radeon_bo_open(rmesa->radeonScreen->bom,
0, size, 4, RADEON_GEM_DOMAIN_GTT,
0);
+ if (!rmesa->dma.current) {
+ rcommonFlushCmdBuf(rmesa, __FUNCTION__);
+ rmesa->dma.nr_released_bufs = 0;
+ goto again_alloc;
+ }
+
rmesa->dma.current_used = 0;
rmesa->dma.current_vertexptr = 0;
+
+ bos[0].bo = rmesa->dma.current;
+ bos[0].read_domains = RADEON_GEM_DOMAIN_GTT;
+ bos[0].write_domain =0 ;
+ bos[0].new_accounted = 0;
+
+again:
+ ret = radeon_cs_space_check(rmesa->cmdbuf.cs, bos, 1);
+ if (ret == RADEON_CS_SPACE_OP_TO_BIG) {
+ fprintf(stderr,"Got OPEARTION TO BIG ILLEGAL - this cannot happen");
+ assert(0);
+ } else if (ret == RADEON_CS_SPACE_FLUSH) {
+ rcommonFlushCmdBuf(rmesa, __FUNCTION__);
+ if (flushed) {
+ fprintf(stderr,"flushed but still no space\n");
+ assert(0);
+ }
+ flushed = 1;
+ goto again;
+ }
+
+
radeon_bo_map(rmesa->dma.current, 1);
}
diff --git a/src/mesa/drivers/dri/radeon/common_misc.h b/src/mesa/drivers/dri/radeon/common_misc.h
index d17d1607db..44e464eb13 100644
--- a/src/mesa/drivers/dri/radeon/common_misc.h
+++ b/src/mesa/drivers/dri/radeon/common_misc.h
@@ -2,6 +2,7 @@
#define COMMON_MISC_H
#include "common_context.h"
+#include "radeon_buffer.h"
void radeonRecalcScissorRects(radeonContextPtr radeon);
void radeonSetCliprects(radeonContextPtr radeon);
void radeonUpdateScissor( GLcontext *ctx );
@@ -122,4 +123,36 @@ void radeonRefillCurrentDmaRegion(radeonContextPtr rmesa, int size);
void radeonAllocDmaRegion(radeonContextPtr rmesa,
struct radeon_bo **pbo, int *poffset,
int bytes, int alignment);
+void radeonReleaseDmaRegion(radeonContextPtr rmesa);
+
+void rcommon_flush_last_swtcl_prim(GLcontext *ctx);
+
+void *rcommonAllocDmaLowVerts(radeonContextPtr rmesa, int nverts, int vsize);
+
+
+static inline struct radeon_renderbuffer *radeon_get_depthbuffer(radeonContextPtr rmesa)
+{
+ struct radeon_renderbuffer *rrb;
+ rrb = rmesa->state.depth.rrb;
+ if (!rrb)
+ return NULL;
+
+ return rrb;
+}
+
+static inline struct radeon_renderbuffer *radeon_get_colorbuffer(radeonContextPtr rmesa)
+{
+ struct radeon_renderbuffer *rrb;
+ GLframebuffer *fb = rmesa->dri.drawable->driverPrivate;
+
+ rrb = rmesa->state.color.rrb;
+ if (rmesa->radeonScreen->driScreen->dri2.enabled) {
+ rrb = (struct radeon_renderbuffer *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
+ }
+ if (!rrb)
+ return NULL;
+ return rrb;
+}
+
+
#endif
diff --git a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c
index bd126c026c..f782d96900 100644
--- a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c
+++ b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c
@@ -413,10 +413,8 @@ static struct radeon_bo *bo_open(struct radeon_bo_manager *bom,
r = bo_dma_alloc(&(bo_legacy->base));
if (r) {
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;
@@ -639,6 +637,24 @@ void radeon_bo_manager_legacy_dtor(struct radeon_bo_manager *bom)
free(boml);
}
+static struct bo_legacy *radeon_legacy_bo_alloc_static(struct bo_manager_legacy *bom,
+ int size, uint32_t offset)
+{
+ struct bo_legacy *bo;
+
+ bo = bo_allocate(bom, size, 0, RADEON_GEM_DOMAIN_VRAM, 0);
+ if (bo == NULL)
+ return NULL;
+ bo->static_bo = 1;
+ bo->offset = offset + bom->fb_location;
+ bo->base.handle = bo->offset;
+ bo->ptr = bom->screen->driScreen->pFB + offset;
+ if (bo->base.handle > bom->nhandle) {
+ bom->nhandle = bo->base.handle + 1;
+ }
+ return bo;
+}
+
struct radeon_bo_manager *radeon_bo_manager_legacy_ctor(struct radeon_screen *scrn)
{
struct bo_manager_legacy *bom;
@@ -682,41 +698,30 @@ struct radeon_bo_manager *radeon_bo_manager_legacy_ctor(struct radeon_screen *sc
/* biggest framebuffer size */
size = 4096*4096*4;
+
/* allocate front */
- bo = bo_allocate(bom, size, 0, RADEON_GEM_DOMAIN_VRAM, 0);
- if (bo == NULL) {
+ bo = radeon_legacy_bo_alloc_static(bom, size, bom->screen->frontOffset);
+ if (!bo) {
radeon_bo_manager_legacy_dtor((struct radeon_bo_manager*)bom);
return NULL;
}
if (scrn->sarea->tiling_enabled) {
bo->base.flags = RADEON_BO_FLAGS_MACRO_TILE;
}
- bo->static_bo = 1;
- bo->offset = bom->screen->frontOffset + bom->fb_location;
- bo->base.handle = bo->offset;
- bo->ptr = scrn->driScreen->pFB + bom->screen->frontOffset;
- if (bo->base.handle > bom->nhandle) {
- bom->nhandle = bo->base.handle + 1;
- }
+
/* allocate back */
- bo = bo_allocate(bom, size, 0, RADEON_GEM_DOMAIN_VRAM, 0);
- if (bo == NULL) {
+ bo = radeon_legacy_bo_alloc_static(bom, size, bom->screen->backOffset);
+ if (!bo) {
radeon_bo_manager_legacy_dtor((struct radeon_bo_manager*)bom);
return NULL;
}
if (scrn->sarea->tiling_enabled) {
bo->base.flags = RADEON_BO_FLAGS_MACRO_TILE;
}
- bo->static_bo = 1;
- bo->offset = bom->screen->backOffset + bom->fb_location;
- bo->base.handle = bo->offset;
- bo->ptr = scrn->driScreen->pFB + bom->screen->backOffset;
- if (bo->base.handle > bom->nhandle) {
- bom->nhandle = bo->base.handle + 1;
- }
+
/* allocate depth */
- bo = bo_allocate(bom, size, 0, RADEON_GEM_DOMAIN_VRAM, 0);
- if (bo == NULL) {
+ bo = radeon_legacy_bo_alloc_static(bom, size, bom->screen->depthOffset);
+ if (!bo) {
radeon_bo_manager_legacy_dtor((struct radeon_bo_manager*)bom);
return NULL;
}
@@ -725,13 +730,6 @@ struct radeon_bo_manager *radeon_bo_manager_legacy_ctor(struct radeon_screen *sc
bo->base.flags |= RADEON_BO_FLAGS_MACRO_TILE;
bo->base.flags |= RADEON_BO_FLAGS_MICRO_TILE;
}
- bo->static_bo = 1;
- bo->offset = bom->screen->depthOffset + bom->fb_location;
- bo->base.handle = bo->offset;
- bo->ptr = scrn->driScreen->pFB + bom->screen->depthOffset;
- if (bo->base.handle > bom->nhandle) {
- bom->nhandle = bo->base.handle + 1;
- }
return (struct radeon_bo_manager*)bom;
}
@@ -750,3 +748,10 @@ unsigned radeon_bo_legacy_relocs_size(struct radeon_bo *bo)
}
return bo->size;
}
+
+int radeon_legacy_bo_is_static(struct radeon_bo *bo)
+{
+ struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
+ return bo_legacy->static_bo;
+}
+
diff --git a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.h b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.h
index 208171e372..575979cbec 100644
--- a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.h
+++ b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.h
@@ -44,4 +44,5 @@ void radeon_bo_manager_legacy_dtor(struct radeon_bo_manager *bom);
void radeon_bo_legacy_texture_age(struct radeon_bo_manager *bom);
unsigned radeon_bo_legacy_relocs_size(struct radeon_bo *bo);
+int radeon_legacy_bo_is_static(struct radeon_bo *bo);
#endif
diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c
index 8997187d62..171818db37 100644
--- a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c
+++ b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c
@@ -315,7 +315,7 @@ static int cs_emit(struct radeon_cs *cs)
cmd.boxes = (drm_clip_rect_t *) csm->ctx->pClipRects;
}
- dump_cmdbuf(cs);
+ // dump_cmdbuf(cs);
r = drmCommandWrite(cs->csm->fd, DRM_RADEON_CMDBUF, &cmd, sizeof(cmd));
if (r) {
@@ -330,6 +330,10 @@ static int cs_emit(struct radeon_cs *cs)
}
}
cs_set_age(cs);
+
+ cs->csm->read_used = 0;
+ cs->csm->vram_write_used = 0;
+ cs->csm->gart_write_used = 0;
return 0;
}
@@ -374,6 +378,101 @@ static void cs_print(struct radeon_cs *cs, FILE *file)
{
}
+static int cs_check_space(struct radeon_cs *cs, struct radeon_cs_space_check *bos, int num_bo)
+{
+ struct radeon_cs_manager *csm = cs->csm;
+ int this_op_read = 0, this_op_gart_write = 0, this_op_vram_write = 0;
+ uint32_t read_domains, write_domain;
+ int i;
+ struct radeon_bo *bo;
+
+ /* check the totals for this operation */
+
+ if (num_bo == 0)
+ return 0;
+
+ /* prepare */
+ for (i = 0; i < num_bo; i++) {
+ bo = bos[i].bo;
+
+ bos[i].new_accounted = 0;
+ read_domains = bos[i].read_domains;
+ write_domain = bos[i].write_domain;
+
+ /* pinned bos don't count */
+ if (radeon_legacy_bo_is_static(bo))
+ continue;
+
+ /* already accounted this bo */
+ if (write_domain && (write_domain == bo->space_accounted))
+ continue;
+
+ if (read_domains && ((read_domains << 16) == bo->space_accounted))
+ continue;
+
+ if (bo->space_accounted == 0) {
+ if (write_domain == RADEON_GEM_DOMAIN_VRAM)
+ this_op_vram_write += bo->size;
+ else if (write_domain == RADEON_GEM_DOMAIN_GTT)
+ this_op_gart_write += bo->size;
+ else
+ this_op_read += bo->size;
+ bos[i].new_accounted = (read_domains << 16) | write_domain;
+ } else {
+ uint16_t old_read, old_write;
+
+ old_read = bo->space_accounted >> 16;
+ old_write = bo->space_accounted & 0xffff;
+
+ if (write_domain && (old_read & write_domain)) {
+ bos[i].new_accounted = write_domain;
+ /* moving from read to a write domain */
+ if (write_domain == RADEON_GEM_DOMAIN_VRAM) {
+ this_op_read -= bo->size;
+ this_op_vram_write += bo->size;
+ } else if (write_domain == RADEON_GEM_DOMAIN_VRAM) {
+ this_op_read -= bo->size;
+ this_op_gart_write += bo->size;
+ }
+ } else if (read_domains & old_write) {
+ bos[i].new_accounted = bo->space_accounted & 0xffff;
+ } else {
+ /* rewrite the domains */
+ if (write_domain != old_write)
+ fprintf(stderr,"WRITE DOMAIN RELOC FAILURE 0x%x %d %d\n", bo->handle, write_domain, old_write);
+ if (read_domains != old_read)
+ fprintf(stderr,"READ DOMAIN RELOC FAILURE 0x%x %d %d\n", bo->handle, read_domains, old_read);
+ return RADEON_CS_SPACE_FLUSH;
+ }
+ }
+ }
+
+ if (this_op_read < 0)
+ this_op_read = 0;
+
+ /* check sizes - operation first */
+ if ((this_op_read + this_op_gart_write > csm->gart_limit) ||
+ (this_op_vram_write > csm->vram_limit)) {
+ return RADEON_CS_SPACE_OP_TO_BIG;
+ }
+
+ if (((csm->vram_write_used + this_op_vram_write) > csm->vram_limit) ||
+ ((csm->read_used + csm->gart_write_used + this_op_gart_write + this_op_read) > csm->gart_limit)) {
+ return RADEON_CS_SPACE_FLUSH;
+ }
+
+ csm->gart_write_used += this_op_gart_write;
+ csm->vram_write_used += this_op_vram_write;
+ csm->read_used += this_op_read;
+ /* commit */
+ for (i = 0; i < num_bo; i++) {
+ bo = bos[i].bo;
+ bo->space_accounted = bos[i].new_accounted;
+ }
+
+ return RADEON_CS_SPACE_OK;
+}
+
static struct radeon_cs_funcs radeon_cs_legacy_funcs = {
cs_create,
cs_write_dword,
@@ -384,7 +483,8 @@ static struct radeon_cs_funcs radeon_cs_legacy_funcs = {
cs_destroy,
cs_erase,
cs_need_flush,
- cs_print
+ cs_print,
+ cs_check_space
};
struct radeon_cs_manager *radeon_cs_manager_legacy_ctor(struct radeon_context *ctx)