From e45213d89bf26c68c9f4c9074eaec9ab3311de7d Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sat, 31 Jan 2009 01:59:57 +1000 Subject: [PATCH] r200/r300: add aperture space checks --- src/mesa/drivers/dri/r200/r200_ioctl.h | 2 + src/mesa/drivers/dri/r200/r200_state.c | 71 +++++++++++- src/mesa/drivers/dri/r200/r200_state.h | 2 +- src/mesa/drivers/dri/r200/r200_tcl.c | 3 +- src/mesa/drivers/dri/r300/r300_cmdbuf.c | 8 +- src/mesa/drivers/dri/r300/r300_render.c | 3 + src/mesa/drivers/dri/r300/r300_state.c | 1 - src/mesa/drivers/dri/r300/r300_swtcl.c | 2 + src/mesa/drivers/dri/r300/r300_tex.h | 2 +- src/mesa/drivers/dri/r300/r300_texstate.c | 53 ++++++++- src/mesa/drivers/dri/radeon/common_misc.c | 49 +++++++-- src/mesa/drivers/dri/radeon/common_misc.h | 33 ++++++ .../drivers/dri/radeon/radeon_bo_legacy.c | 65 ++++++----- .../drivers/dri/radeon/radeon_bo_legacy.h | 1 + .../drivers/dri/radeon/radeon_cs_legacy.c | 104 +++++++++++++++++- 15 files changed, 345 insertions(+), 54 deletions(-) diff --git a/src/mesa/drivers/dri/r200/r200_ioctl.h b/src/mesa/drivers/dri/r200/r200_ioctl.h index 0410fdf3c31..3e39a9124d2 100644 --- a/src/mesa/drivers/dri/r200/r200_ioctl.h +++ b/src/mesa/drivers/dri/r200/r200_ioctl.h @@ -43,6 +43,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "drm.h" #include "radeon_drm.h" +#include "common_cmdbuf.h" + extern void r200EmitState( r200ContextPtr rmesa ); extern void r200EmitVertexAOS( r200ContextPtr rmesa, GLuint vertex_size, diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c index f2e62d1bf78..f3d809d62cb 100644 --- a/src/mesa/drivers/dri/r200/r200_state.c +++ b/src/mesa/drivers/dri/r200/r200_state.c @@ -48,6 +48,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast_setup/swrast_setup.h" #include "radeon_buffer.h" +#include "radeon_cs.h" +#include "radeon_mipmap_tree.h" #include "r200_context.h" #include "r200_ioctl.h" #include "r200_state.h" @@ -2347,9 +2349,66 @@ r200UpdateDrawBuffer(GLcontext *ctx) #endif } +static GLboolean r200ValidateBuffers(GLcontext *ctx) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + struct radeon_cs_space_check bos[8]; + struct radeon_renderbuffer *rrb; + int num_bo = 0; + int i; + int flushed = 0, ret; +again: + num_bo = 0; + + rrb = radeon_get_colorbuffer(&rmesa->radeon); + /* color buffer */ + if (rrb && rrb->bo) { + bos[num_bo].bo = rrb->bo; + bos[num_bo].read_domains = 0; + bos[num_bo].write_domain = RADEON_GEM_DOMAIN_VRAM; + bos[num_bo].new_accounted = 0; + num_bo++; + } + + /* depth buffer */ + rrb = radeon_get_depthbuffer(&rmesa->radeon); + /* color buffer */ + if (rrb && rrb->bo) { + bos[num_bo].bo = rrb->bo; + bos[num_bo].read_domains = 0; + bos[num_bo].write_domain = RADEON_GEM_DOMAIN_VRAM; + bos[num_bo].new_accounted = 0; + num_bo++; + } + + for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) { + radeonTexObj *t; + + if (!ctx->Texture.Unit[i]._ReallyEnabled) + continue; + + t = radeon_tex_obj(ctx->Texture.Unit[i]._Current); + bos[num_bo].bo = t->mt->bo; + bos[num_bo].read_domains = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM; + bos[num_bo].write_domain = 0; + bos[num_bo].new_accounted = 0; + num_bo++; + } + + ret = radeon_cs_space_check(rmesa->radeon.cmdbuf.cs, bos, num_bo); + if (ret == RADEON_CS_SPACE_OP_TO_BIG) + return GL_FALSE; + if (ret == RADEON_CS_SPACE_FLUSH) { + r200Flush(ctx); + if (flushed) + return GL_FALSE; + flushed = 1; + goto again; + } + return GL_TRUE; +} - -void r200ValidateState( GLcontext *ctx ) +GLboolean r200ValidateState( GLcontext *ctx ) { r200ContextPtr rmesa = R200_CONTEXT(ctx); GLuint new_state = rmesa->radeon.NewGLState; @@ -2364,6 +2423,10 @@ void r200ValidateState( GLcontext *ctx ) r200UpdateLocalViewer( ctx ); } + /* we need to do a space check here */ + if (!r200ValidateBuffers(ctx)) + return GL_FALSE; + /* FIXME: don't really need most of these when vertex progs are enabled */ /* Need an event driven matrix update? @@ -2408,6 +2471,7 @@ void r200ValidateState( GLcontext *ctx ) } rmesa->radeon.NewGLState = 0; + return GL_TRUE; } @@ -2452,7 +2516,8 @@ static void r200WrapRunPipeline( GLcontext *ctx ) /* Validate state: */ if (rmesa->radeon.NewGLState) - r200ValidateState( ctx ); + if (!r200ValidateState( ctx )) + FALLBACK(rmesa, RADEON_FALLBACK_TEXTURE, GL_TRUE); has_material = !ctx->VertexProgram._Enabled && ctx->Light.Enabled && check_material( ctx ); diff --git a/src/mesa/drivers/dri/r200/r200_state.h b/src/mesa/drivers/dri/r200/r200_state.h index 741bf88e9c2..1dddbfdbfed 100644 --- a/src/mesa/drivers/dri/r200/r200_state.h +++ b/src/mesa/drivers/dri/r200/r200_state.h @@ -47,7 +47,7 @@ extern void r200UpdateViewportOffset( GLcontext *ctx ); extern void r200UpdateWindow( GLcontext *ctx ); extern void r200UpdateDrawBuffer(GLcontext *ctx); -extern void r200ValidateState( GLcontext *ctx ); +extern GLboolean r200ValidateState( GLcontext *ctx ); extern void r200PrintDirty( r200ContextPtr rmesa, const char *msg ); diff --git a/src/mesa/drivers/dri/r200/r200_tcl.c b/src/mesa/drivers/dri/r200/r200_tcl.c index 5bb25bc53a6..3c19e330f5c 100644 --- a/src/mesa/drivers/dri/r200/r200_tcl.c +++ b/src/mesa/drivers/dri/r200/r200_tcl.c @@ -406,7 +406,8 @@ static GLboolean r200_run_tcl_render( GLcontext *ctx, /* Validate state: */ if (rmesa->radeon.NewGLState) - r200ValidateState( ctx ); + if (!r200ValidateState( ctx )) + return GL_TRUE; /* fallback to sw t&l */ if (!ctx->VertexProgram._Enabled) { /* NOTE: inputs != tnl->render_inputs - these are the untransformed diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c index 04bb76bb301..90989316022 100644 --- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c +++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c @@ -296,12 +296,8 @@ static void emit_cb_offset(GLcontext *ctx, struct radeon_state_atom * atom) BATCH_LOCALS(&r300->radeon); struct radeon_renderbuffer *rrb; uint32_t cbpitch; - GLframebuffer *fb = r300->radeon.dri.drawable->driverPrivate; - rrb = r300->radeon.state.color.rrb; - if (r300->radeon.radeonScreen->driScreen->dri2.enabled) { - rrb = (struct radeon_renderbuffer *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; - } + rrb = radeon_get_colorbuffer(&r300->radeon); if (!rrb || !rrb->bo) { fprintf(stderr, "no rrb\n"); return; @@ -331,7 +327,7 @@ static void emit_zb_offset(GLcontext *ctx, struct radeon_state_atom * atom) struct radeon_renderbuffer *rrb; uint32_t zbpitch; - rrb = r300->radeon.state.depth.rrb; + rrb = radeon_get_depthbuffer(&r300->radeon); if (!rrb) return; diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c index 57249c46ef8..3b00de2b562 100644 --- a/src/mesa/drivers/dri/r300/r300_render.c +++ b/src/mesa/drivers/dri/r300/r300_render.c @@ -501,6 +501,9 @@ static GLboolean r300RunTCLRender(GLcontext * ctx, return GL_TRUE; } + if (!r300ValidateTextures(ctx)) + return GL_TRUE; + r300UpdateShaders(rmesa); vp = (struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx); diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 5fbd5b93ff8..e5939afeeb3 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -2632,7 +2632,6 @@ void r300UpdateShaderStates(r300ContextPtr rmesa) GLcontext *ctx; ctx = rmesa->radeon.glCtx; - r300ValidateTextures(ctx); r300SetEarlyZState(ctx); GLuint fgdepthsrc = R300_FG_DEPTH_SRC_SCAN; diff --git a/src/mesa/drivers/dri/r300/r300_swtcl.c b/src/mesa/drivers/dri/r300/r300_swtcl.c index 6ae5868a52c..ef65fbb127a 100644 --- a/src/mesa/drivers/dri/r300/r300_swtcl.c +++ b/src/mesa/drivers/dri/r300/r300_swtcl.c @@ -579,6 +579,8 @@ static void r300RenderStart(GLcontext *ctx) r300ChooseRenderState(ctx); r300SetVertexFormat(ctx); + r300ValidateTextures(ctx); + r300UpdateShaders(rmesa); r300UpdateShaderStates(rmesa); diff --git a/src/mesa/drivers/dri/r300/r300_tex.h b/src/mesa/drivers/dri/r300/r300_tex.h index 358b927828c..a293ccf02ca 100644 --- a/src/mesa/drivers/dri/r300/r300_tex.h +++ b/src/mesa/drivers/dri/r300/r300_tex.h @@ -41,7 +41,7 @@ extern void r300SetTexOffset(__DRIcontext *pDRICtx, GLint texname, unsigned long long offset, GLint depth, GLuint pitch); -extern void r300ValidateTextures(GLcontext * ctx); +extern GLboolean r300ValidateTextures(GLcontext * ctx); extern void r300InitTextureFuncs(struct dd_function_table *functions); diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c index 68c7ca3d29f..7ffc15fe39d 100644 --- a/src/mesa/drivers/dri/r300/r300_texstate.c +++ b/src/mesa/drivers/dri/r300/r300_texstate.c @@ -49,6 +49,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r300_ioctl.h" #include "radeon_ioctl.h" #include "radeon_mipmap_tree.h" +#include "radeon_cs.h" #include "r300_tex.h" #include "r300_reg.h" #include "radeon_buffer.h" @@ -265,13 +266,43 @@ static GLboolean r300_validate_texture(GLcontext * ctx, struct gl_texture_object /** - * Ensure all enabled and complete textures are uploaded. + * Ensure all enabled and complete textures are uploaded along with any buffers being used. */ -void r300ValidateTextures(GLcontext * ctx) +GLboolean r300ValidateBuffers(GLcontext * ctx) { + r300ContextPtr rmesa = R300_CONTEXT(ctx); + struct radeon_cs_space_check bos[16]; + struct radeon_renderbuffer *rrb; + int num_bo = 0; int i; + int flushed = 0, ret; +again: + num_bo = 0; + + rrb = radeon_get_colorbuffer(&rmesa->radeon); + /* color buffer */ + if (rrb && rrb->bo) { + bos[num_bo].bo = rrb->bo; + bos[num_bo].read_domains = 0; + bos[num_bo].write_domain = RADEON_GEM_DOMAIN_VRAM; + bos[num_bo].new_accounted = 0; + num_bo++; + } + /* depth buffer */ + rrb = radeon_get_depthbuffer(&rmesa->radeon); + /* color buffer */ + if (rrb && rrb->bo) { + bos[num_bo].bo = rrb->bo; + bos[num_bo].read_domains = 0; + bos[num_bo].write_domain = RADEON_GEM_DOMAIN_VRAM; + bos[num_bo].new_accounted = 0; + num_bo++; + } + for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) { + radeonTexObj *t; + if (!ctx->Texture.Unit[i]._ReallyEnabled) continue; @@ -280,7 +311,25 @@ void r300ValidateTextures(GLcontext * ctx) "failed to validate texture for unit %d.\n", i); } + t = radeon_tex_obj(ctx->Texture.Unit[i]._Current); + bos[num_bo].bo = t->mt->bo; + bos[num_bo].read_domains = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM; + bos[num_bo].write_domain = 0; + bos[num_bo].new_accounted = 0; + num_bo++; } + + ret = radeon_cs_space_check(rmesa->radeon.cmdbuf.cs, bos, num_bo); + if (ret == RADEON_CS_SPACE_OP_TO_BIG) + return GL_FALSE; + if (ret == RADEON_CS_SPACE_FLUSH) { + r300Flush(ctx); + if (flushed) + return GL_FALSE; + flushed = 1; + goto again; + } + return GL_TRUE; } void r300SetTexOffset(__DRIcontext * pDRICtx, GLint texname, diff --git a/src/mesa/drivers/dri/radeon/common_misc.c b/src/mesa/drivers/dri/radeon/common_misc.c index 19294487f64..1adcefb19a1 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 d17d1607db1..44e464eb139 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 bd126c026cc..f782d96900c 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 208171e3720..575979cbecc 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 8997187d62b..171818db37c 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) -- 2.30.2