radeon/r200/r300: fix up the whole buffer space checking.
authorDave Airlie <airlied@redhat.com>
Thu, 2 Apr 2009 08:58:49 +0000 (18:58 +1000)
committerDave Airlie <airlied@redhat.com>
Thu, 2 Apr 2009 08:58:49 +0000 (18:58 +1000)
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
src/mesa/drivers/dri/r300/r300_emit.c
src/mesa/drivers/dri/r300/r300_texstate.c
src/mesa/drivers/dri/radeon/radeon_common.c
src/mesa/drivers/dri/radeon/radeon_common.h
src/mesa/drivers/dri/radeon/radeon_common_context.c
src/mesa/drivers/dri/radeon/radeon_common_context.h
src/mesa/drivers/dri/radeon/radeon_dma.c
src/mesa/drivers/dri/radeon/radeon_state.c
src/mesa/drivers/dri/radeon/radeon_state.h

index ca4dee8a5bcd0839c98fe880eba00c7c327e6832..f040713980f7c736ffeb04fdfb5eaa5478dec1f5 100644 (file)
@@ -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 )
index 3ce0ba68c99cd2b64bb99d4cef555bf0be543fef..bcf8803875989714d0a0df8a4e9f91c80fcdf3fb 100644 (file)
@@ -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);
index baaca5f1e59605306a733b63f0b824d48444a109..5a87b5da43d821ebd86674070affe8432c829a26 100644 (file)
@@ -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,
index 3ce868d2cf33ad10a1e00b25e1bbb9cfd52a21ed..4f7bfebf04fa4fbdf3c57744ab0a066e38f10d72 100644 (file)
@@ -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;
 }
 
index f3e2290cab8d62d351e7474a9c8daf7eebd12bcb..c2fbb0950d5fd6a06e9955e5fe868ddbb7e86ec2 100644 (file)
@@ -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
index ef67c86f0b8af27d421246914ef2aeb3cf53a0a1..ba74c97f2cb0f7d754d083dfe55c3e946eab3a72 100644 (file)
@@ -219,7 +219,6 @@ void radeonDestroyContext(__DRIcontextPrivate *driContextPriv )
        if (radeon) {
 
                if (radeon->dma.current) {
-                       radeonReleaseDmaRegion( radeon );
                        rcommonFlushCmdBuf( radeon, __FUNCTION__ );
                }
 
index c6e6be74840212a724c60b041ff481d0587a885b..d32e5af5441785bb1f8104a604e12f0a51ec5c66 100644 (file)
 #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;
 };
 
 /**
index 47f789e9cd08b398d0538ea92cd40402fdeac985..5ffee86e5a33266a90589a41b1609eb01be9ec1f 100644 (file)
@@ -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);
 }
 
index 19ff2688e6ed055eb4971878bedc059624be96e2..dcca326c667a38e9edbce41f960a5631bd1b6226 100644 (file)
@@ -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 ));
 
index f05fa827d726788309c59756dba380f64d80f6b8..a7c8eef32a54697fb2ba1e35ab3833960b369d00 100644 (file)
@@ -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 );