From 05304d41f2d9ab7a66a8b976580c156b7b93a9d3 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 2 Apr 2009 18:58:49 +1000 Subject: radeon/r200/r300: fix up the whole buffer space checking. This fixes up the buffer validation scheme, so that we keep a list of buffers to validate so cmdbuf flushes during a pipeline get all the buffers revalidated on the next emit. This also fixes radeonFlush to not flush unless we have something useful to send to the GPU, like a DMA buffer or something not state --- src/mesa/drivers/dri/radeon/radeon_common.c | 56 ++++++++++++++++++++++ src/mesa/drivers/dri/radeon/radeon_common.h | 3 ++ .../drivers/dri/radeon/radeon_common_context.c | 1 - .../drivers/dri/radeon/radeon_common_context.h | 8 ++++ src/mesa/drivers/dri/radeon/radeon_dma.c | 25 ++-------- src/mesa/drivers/dri/radeon/radeon_state.c | 50 ++++++++++++++++++- src/mesa/drivers/dri/radeon/radeon_state.h | 2 +- 7 files changed, 121 insertions(+), 24 deletions(-) (limited to 'src/mesa/drivers/dri/radeon') diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c index 3ce868d2cf..4f7bfebf04 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common.c +++ b/src/mesa/drivers/dri/radeon/radeon_common.c @@ -906,6 +906,49 @@ static INLINE void radeonEmitAtoms(radeonContextPtr radeon, GLboolean dirty) COMMIT_BATCH(); } +GLboolean radeon_revalidate_bos(GLcontext *ctx) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + int flushed = 0; + int ret; +again: + ret = radeon_cs_space_check(radeon->cmdbuf.cs, radeon->state.bos, radeon->state.validated_bo_count); + if (ret == RADEON_CS_SPACE_OP_TO_BIG) + return GL_FALSE; + if (ret == RADEON_CS_SPACE_FLUSH) { + radeonFlush(ctx); + if (flushed) + return GL_FALSE; + flushed = 1; + goto again; + } + return GL_TRUE; +} + +void radeon_validate_reset_bos(radeonContextPtr radeon) +{ + int i; + + for (i = 0; i < radeon->state.validated_bo_count; i++) { + radeon->state.bos[i].bo = NULL; + radeon->state.bos[i].read_domains = 0; + radeon->state.bos[i].write_domain = 0; + radeon->state.bos[i].new_accounted = 0; + } + radeon->state.validated_bo_count = 0; +} + +void radeon_validate_bo(radeonContextPtr radeon, struct radeon_bo *bo, uint32_t read_domains, uint32_t write_domain) +{ + radeon->state.bos[radeon->state.validated_bo_count].bo = bo; + radeon->state.bos[radeon->state.validated_bo_count].read_domains = read_domains; + radeon->state.bos[radeon->state.validated_bo_count].write_domain = write_domain; + radeon->state.bos[radeon->state.validated_bo_count].new_accounted = 0; + radeon->state.validated_bo_count++; + + assert(radeon->state.validated_bo_count < RADEON_MAX_BOS); +} + void radeonEmitState(radeonContextPtr radeon) { if (RADEON_DEBUG & (DEBUG_STATE|DEBUG_PRIMS)) @@ -947,6 +990,14 @@ void radeonFlush(GLcontext *ctx) if (RADEON_DEBUG & DEBUG_IOCTL) fprintf(stderr, "%s %d\n", __FUNCTION__, radeon->cmdbuf.cs->cdw); + /* okay if we have no cmds in the buffer && + we have no DMA flush && + we have no DMA buffer allocated. + then no point flushing anything at all. + */ + if (!radeon->dma.flush && !radeon->cmdbuf.cs->cdw && !radeon->dma.current) + return; + if (radeon->dma.flush) radeon->dma.flush( ctx ); @@ -1015,6 +1066,11 @@ int rcommonFlushCmdBufLocked(radeonContextPtr rmesa, const char *caller) } radeon_cs_erase(rmesa->cmdbuf.cs); rmesa->cmdbuf.flushing = 0; + + if (radeon_revalidate_bos(rmesa->glCtx) == GL_FALSE) { + fprintf(stderr,"failed to revalidate buffers\n"); + } + return ret; } diff --git a/src/mesa/drivers/dri/radeon/radeon_common.h b/src/mesa/drivers/dri/radeon/radeon_common.h index f3e2290cab..c2fbb0950d 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common.h +++ b/src/mesa/drivers/dri/radeon/radeon_common.h @@ -47,6 +47,9 @@ void radeon_get_cliprects(radeonContextPtr radeon, struct drm_clip_rect **cliprects, unsigned int *num_cliprects, int *x_off, int *y_off); +GLboolean radeon_revalidate_bos(GLcontext *ctx); +void radeon_validate_bo(radeonContextPtr radeon, struct radeon_bo *bo, uint32_t read_domains, uint32_t write_domain); +void radeon_validate_reset_bos(radeonContextPtr radeon); void radeon_fbo_init(struct radeon_context *radeon); void diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.c b/src/mesa/drivers/dri/radeon/radeon_common_context.c index ef67c86f0b..ba74c97f2c 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.c @@ -219,7 +219,6 @@ void radeonDestroyContext(__DRIcontextPrivate *driContextPriv ) if (radeon) { if (radeon->dma.current) { - radeonReleaseDmaRegion( radeon ); rcommonFlushCmdBuf( radeon, __FUNCTION__ ); } diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.h b/src/mesa/drivers/dri/radeon/radeon_common_context.h index c6e6be7484..d32e5af544 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common_context.h +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.h @@ -13,6 +13,10 @@ #include "dri_util.h" #include "tnl/t_vertex.h" +struct radeon_context; + +#include "radeon_bocs_wrapper.h" + /* This union is used to avoid warnings/miscompilation with float to uint32_t casts due to strict-aliasing */ typedef union { GLfloat f; uint32_t ui32; } float_ui32_type; @@ -384,11 +388,15 @@ typedef void (*radeon_line_func) (radeonContextPtr, typedef void (*radeon_point_func) (radeonContextPtr, radeonVertex *); +#define RADEON_MAX_BOS 24 struct radeon_state { struct radeon_colorbuffer_state color; struct radeon_depthbuffer_state depth; struct radeon_scissor_state scissor; struct radeon_stencilbuffer_state stencil; + + struct radeon_cs_space_check bos[RADEON_MAX_BOS]; + int validated_bo_count; }; /** diff --git a/src/mesa/drivers/dri/radeon/radeon_dma.c b/src/mesa/drivers/dri/radeon/radeon_dma.c index 47f789e9cd..5ffee86e5a 100644 --- a/src/mesa/drivers/dri/radeon/radeon_dma.c +++ b/src/mesa/drivers/dri/radeon/radeon_dma.c @@ -163,8 +163,6 @@ void rcommon_emit_vector(GLcontext * ctx, struct radeon_aos *aos, void radeonRefillCurrentDmaRegion(radeonContextPtr rmesa, int size) { - struct radeon_cs_space_check bos[1]; - int flushed = 0, ret; size = MAX2(size, MAX_DMA_BUF_SZ * 16); @@ -200,24 +198,11 @@ 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; - - 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_alloc; - } + radeon_validate_bo(rmesa, rmesa->dma.current, RADEON_GEM_DOMAIN_GTT, 0); + + if (radeon_revalidate_bos(rmesa->glCtx) == GL_FALSE) + fprintf(stderr,"failure to revalidate BOs - badness\n"); + radeon_bo_map(rmesa->dma.current, 1); } diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c index 19ff2688e6..dcca326c66 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state.c +++ b/src/mesa/drivers/dri/radeon/radeon_state.c @@ -47,6 +47,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast_setup/swrast_setup.h" #include "radeon_context.h" +#include "radeon_mipmap_tree.h" #include "radeon_ioctl.h" #include "radeon_state.h" #include "radeon_tcl.h" @@ -2043,8 +2044,48 @@ static void update_texturematrix( GLcontext *ctx ) } } +static GLboolean r100ValidateBuffers(GLcontext *ctx) +{ + r100ContextPtr rmesa = R100_CONTEXT(ctx); + struct radeon_renderbuffer *rrb; + int i; + + radeon_validate_reset_bos(&rmesa->radeon); + + rrb = radeon_get_colorbuffer(&rmesa->radeon); + /* color buffer */ + if (rrb && rrb->bo) { + radeon_validate_bo(&rmesa->radeon, rrb->bo, + 0, RADEON_GEM_DOMAIN_VRAM); + } + + /* depth buffer */ + rrb = radeon_get_depthbuffer(&rmesa->radeon); + /* color buffer */ + if (rrb && rrb->bo) { + radeon_validate_bo(&rmesa->radeon, rrb->bo, + 0, RADEON_GEM_DOMAIN_VRAM); + } -void radeonValidateState( GLcontext *ctx ) + 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); + if (t->image_override && t->bo) + radeon_validate_bo(&rmesa->radeon, t->bo, + RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); + else if (t->mt->bo) + radeon_validate_bo(&rmesa->radeon, t->mt->bo, + RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); + } + + return radeon_revalidate_bos(ctx); +} + +GLboolean radeonValidateState( GLcontext *ctx ) { r100ContextPtr rmesa = R100_CONTEXT(ctx); GLuint new_state = rmesa->radeon.NewGLState; @@ -2061,6 +2102,10 @@ void radeonValidateState( GLcontext *ctx ) new_state |= rmesa->radeon.NewGLState; /* may add TEXTURE_MATRIX */ } + /* we need to do a space check here */ + if (!r100ValidateBuffers(ctx)) + return GL_FALSE; + /* Need an event driven matrix update? */ if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION)) @@ -2136,7 +2181,8 @@ static void radeonWrapRunPipeline( GLcontext *ctx ) /* Validate state: */ if (rmesa->radeon.NewGLState) - radeonValidateState( ctx ); + if (!radeonValidateState( ctx )) + FALLBACK(rmesa, RADEON_FALLBACK_TEXTURE, GL_TRUE); has_material = (ctx->Light.Enabled && check_material( ctx )); diff --git a/src/mesa/drivers/dri/radeon/radeon_state.h b/src/mesa/drivers/dri/radeon/radeon_state.h index f05fa827d7..a7c8eef32a 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state.h +++ b/src/mesa/drivers/dri/radeon/radeon_state.h @@ -50,7 +50,7 @@ extern void radeonUpdateDrawBuffer( GLcontext *ctx ); extern void radeonUploadTexMatrix( r100ContextPtr rmesa, int unit, GLboolean swapcols ); -extern void radeonValidateState( GLcontext *ctx ); +extern GLboolean radeonValidateState( GLcontext *ctx ); extern void radeonFallback( GLcontext *ctx, GLuint bit, GLboolean mode ); -- cgit v1.2.3