Mesa (radeon-rewrite): radeon/r200/r300: fix up the whole buffer space checking.

Dave Airlie airlied at kemper.freedesktop.org
Thu Apr 2 09:05:26 UTC 2009


Module: Mesa
Branch: radeon-rewrite
Commit: 05304d41f2d9ab7a66a8b976580c156b7b93a9d3
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=05304d41f2d9ab7a66a8b976580c156b7b93a9d3

Author: Dave Airlie <airlied at redhat.com>
Date:   Thu Apr  2 18:58:49 2009 +1000

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/r200/r200_state.c             |   48 +++++------------
 src/mesa/drivers/dri/r300/r300_emit.c              |    2 +-
 src/mesa/drivers/dri/r300/r300_texstate.c          |   46 ++++------------
 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 +-
 10 files changed, 149 insertions(+), 92 deletions(-)

diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c
index ca4dee8..f040713 100644
--- a/src/mesa/drivers/dri/r200/r200_state.c
+++ b/src/mesa/drivers/dri/r200/r200_state.c
@@ -2273,33 +2273,24 @@ static void update_texturematrix( GLcontext *ctx )
 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;
+
+   radeon_validate_reset_bos(&rmesa->radeon);
    
    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++;
+     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) {
-      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++;
+     radeon_validate_bo(&rmesa->radeon, rrb->bo,
+			0, RADEON_GEM_DOMAIN_VRAM);
    }
 
    for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) {
@@ -2307,26 +2298,17 @@ again:
       
       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++;
+      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);
    }
-   
-   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) {
-      radeonFlush(ctx);
-      if (flushed)
-	 return GL_FALSE;
-      flushed = 1;
-      goto again;
-   }
-   return GL_TRUE;
+
+   return radeon_revalidate_bos(ctx);
 }
 
 GLboolean r200ValidateState( GLcontext *ctx )
diff --git a/src/mesa/drivers/dri/r300/r300_emit.c b/src/mesa/drivers/dri/r300/r300_emit.c
index 3ce0ba6..bcf8803 100644
--- a/src/mesa/drivers/dri/r300/r300_emit.c
+++ b/src/mesa/drivers/dri/r300/r300_emit.c
@@ -352,7 +352,7 @@ void r300EmitCacheFlush(r300ContextPtr rmesa)
 {
 	BATCH_LOCALS(&rmesa->radeon);
 
-	BEGIN_BATCH(4);
+	BEGIN_BATCH_NO_AUTOSTATE(4);
 	OUT_BATCH_REGVAL(R300_RB3D_DSTCACHE_CTLSTAT,
 		R300_RB3D_DSTCACHE_CTLSTAT_DC_FREE_FREE_3D_TAGS |
 		R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D);
diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c
index baaca5f..5a87b5d 100644
--- a/src/mesa/drivers/dri/r300/r300_texstate.c
+++ b/src/mesa/drivers/dri/r300/r300_texstate.c
@@ -268,40 +268,29 @@ static GLboolean r300_validate_texture(GLcontext * ctx, struct gl_texture_object
 	return GL_TRUE;
 }
 
-
 /**
  * Ensure all enabled and complete textures are uploaded along with any buffers being used.
  */
 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;
+
+	radeon_validate_reset_bos(&rmesa->radeon);
 
 	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++;
+		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) {
-		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++;
+		radeon_validate_bo(&rmesa->radeon, rrb->bo,
+				   0, RADEON_GEM_DOMAIN_VRAM);
 	}
 	
 	for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) {
@@ -317,26 +306,15 @@ again:
 		}
 		t = radeon_tex_obj(ctx->Texture.Unit[i]._Current);
 		if (t->image_override && t->bo)
-			bos[num_bo].bo = t->bo;
+			radeon_validate_bo(&rmesa->radeon, t->bo,
+					   RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
+
 		else if (t->mt->bo)
-			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++;
+			radeon_validate_bo(&rmesa->radeon, t->mt->bo,
+					   RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
 	}
 
-	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) {
-		radeonFlush(ctx);
-		if (flushed)
-			return GL_FALSE;
-		flushed = 1;
-		goto again;
-	}
-	return GL_TRUE;
+	return radeon_revalidate_bos(ctx);
 }
 
 void r300SetTexOffset(__DRIcontext * pDRICtx, GLint texname,
diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c
index 3ce868d..4f7bfeb 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 f3e2290..c2fbb09 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 ef67c86..ba74c97 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 c6e6be7..d32e5af 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 47f789e..5ffee86 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 19ff268..dcca326 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 f05fa82..a7c8eef 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 );




More information about the mesa-commit mailing list