r200/r300: add aperture space checks
authorDave Airlie <airlied@redhat.com>
Fri, 30 Jan 2009 15:59:57 +0000 (01:59 +1000)
committerDave Airlie <airlied@redhat.com>
Fri, 30 Jan 2009 15:59:57 +0000 (01:59 +1000)
15 files changed:
src/mesa/drivers/dri/r200/r200_ioctl.h
src/mesa/drivers/dri/r200/r200_state.c
src/mesa/drivers/dri/r200/r200_state.h
src/mesa/drivers/dri/r200/r200_tcl.c
src/mesa/drivers/dri/r300/r300_cmdbuf.c
src/mesa/drivers/dri/r300/r300_render.c
src/mesa/drivers/dri/r300/r300_state.c
src/mesa/drivers/dri/r300/r300_swtcl.c
src/mesa/drivers/dri/r300/r300_tex.h
src/mesa/drivers/dri/r300/r300_texstate.c
src/mesa/drivers/dri/radeon/common_misc.c
src/mesa/drivers/dri/radeon/common_misc.h
src/mesa/drivers/dri/radeon/radeon_bo_legacy.c
src/mesa/drivers/dri/radeon/radeon_bo_legacy.h
src/mesa/drivers/dri/radeon/radeon_cs_legacy.c

index 0410fdf3c31df4926a9ed4c7c3e99d257619752a..3e39a9124d2500675f3a963c5af2201ffb023a49 100644 (file)
@@ -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,
index f2e62d1bf784b239aa4fcc42bfeb10eef5a4f5ab..f3d809d62cbb7e517367e914c07877e7a43b3625 100644 (file)
@@ -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 );
 
index 741bf88e9c2fae00f271c342db499dc2e6016d39..1dddbfdbfedf2c1418624bac0232ab726e7fbc43 100644 (file)
@@ -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 );
index 5bb25bc53a637f91babbfc474e2510a1cf824e9f..3c19e330f5cac06d37af8729c0165ae16f17a30c 100644 (file)
@@ -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
index 04bb76bb301f2c99638fc41477b3ccf574a970b9..90989316022dbd425f4481049185debba1806aca 100644 (file)
@@ -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;
 
index 57249c46ef8af1173ee2a08af4523c65efffbe6d..3b00de2b5624d8d05e34913af4eaf516d8955ab8 100644 (file)
@@ -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);
index 5fbd5b93ff889de09884c2afbdc7258b2f2fb9a4..e5939afeeb3f076af67113650ae0a967496f2a75 100644 (file)
@@ -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;
index 6ae5868a52c4af62e1f300897d60ab512ed06795..ef65fbb127a683c86926ae068e0041d4fff0366b 100644 (file)
@@ -579,6 +579,8 @@ static void r300RenderStart(GLcontext *ctx)
        r300ChooseRenderState(ctx);
        r300SetVertexFormat(ctx);
 
+       r300ValidateTextures(ctx);
+
        r300UpdateShaders(rmesa);
        r300UpdateShaderStates(rmesa);
 
index 358b927828c80da31d217908066fd22fc5bcdd02..a293ccf02cacb0a05bfc48c829e6d39dd4210677 100644 (file)
@@ -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);
 
index 68c7ca3d29f88b3a617e52568484b3b742242f71..7ffc15fe39dbfc28954b2d5a3878b44279122b3a 100644 (file)
@@ -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,
index 19294487f64339cae60ceaf2d8dc808bb285c920..1adcefb19a1a3ebbcecfda7e777482380fd1b28a 100644 (file)
@@ -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);
 }
 
index d17d1607db1a01c65b26216470db99970a4f9926..44e464eb139c10534a40ded3bda786f8eee75f23 100644 (file)
@@ -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
index bd126c026cca5a48c91eba427de62be6327ffa25..f782d96900c3c2d1c37c7ce934cd5725297fe94a 100644 (file)
@@ -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;
+}
+
index 208171e372096c7c0c4404a717633524625929bc..575979cbeccebac9c76242e00aeb1de76c03996f 100644 (file)
@@ -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
index 8997187d62b2290cca35c12aac47dda0618eaca6..171818db37cfd0d31e9691982c730cc4684926f3 100644 (file)
@@ -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)