Kick VBOs out of GART if nothing else helps.
authorAapo Tahkola <aet@rasterburn.org>
Thu, 9 Mar 2006 06:21:17 +0000 (06:21 +0000)
committerAapo Tahkola <aet@rasterburn.org>
Thu, 9 Mar 2006 06:21:17 +0000 (06:21 +0000)
src/mesa/drivers/dri/r300/r300_context.h
src/mesa/drivers/dri/r300/r300_ioctl.c
src/mesa/drivers/dri/r300/radeon_mm.c
src/mesa/drivers/dri/r300/radeon_mm.h
src/mesa/drivers/dri/r300/radeon_vtxfmt_a.c

index 278319b..53b689e 100644 (file)
@@ -933,6 +933,7 @@ extern void radeon_init_vtxfmt_a(r300ContextPtr rmesa);
 
 #ifdef HW_VBOS
 extern void r300_init_vbo_funcs(struct dd_function_table *functions);
+extern void r300_evict_vbos(GLcontext *ctx, int amount);
 #endif
 
 #define RADEON_D_CAPTURE 0
index 078ff35..73725fc 100644 (file)
@@ -632,12 +632,19 @@ void r300RefillCurrentDmaRegion(r300ContextPtr rmesa)
                radeonWaitForIdleLocked(&rmesa->radeon);
                
                dmabuf->id = radeon_mm_alloc(rmesa, 4, RADEON_BUFFER_SIZE*16);
-               
+
+#ifdef HW_VBOS
+               if (dmabuf->id == 0) {
+                       /* Just kick all */
+                       r300_evict_vbos(rmesa->radeon.glCtx, /*RADEON_BUFFER_SIZE*16*/1<<30);
+                       dmabuf->id = radeon_mm_alloc(rmesa, 4, RADEON_BUFFER_SIZE*16);
+               }
+#endif
                UNLOCK_HARDWARE(&rmesa->radeon);
                
                if (dmabuf->id == 0) {
-                       WARN_ONCE("Whops! Dont know how to evict VBOs yet.\n");
-                       exit(1);
+                       fprintf(stderr, "Error: Could not get dma buffer... exiting\n");
+                       exit(-1);
                }
        }
                        
index 08f2b2f..394c59b 100644 (file)
@@ -97,7 +97,7 @@ int radeon_mm_alloc(r300ContextPtr rmesa, int alignment, int size)
                        
        again:
        
-       done_age = rmesa->radeon.radeonScreen->scratch[2];
+       done_age = rmesa->radeon.radeonScreen->scratch[RADEON_MM_SCRATCH];
        
        for (i = rmesa->rmm->u_last + 1; i > 0; i --) {
                if (rmesa->rmm->u_list[i].ptr == NULL) {
@@ -119,7 +119,7 @@ int radeon_mm_alloc(r300ContextPtr rmesa, int alignment, int size)
                                exit(1);
                        } else {
 #ifdef MM_DEBUG
-                               fprintf(stderr, "really freed %d at age %x\n", i, rmesa->radeon.radeonScreen->scratch[2]);
+                               fprintf(stderr, "really freed %d at age %x\n", i, rmesa->radeon.radeonScreen->scratch[RADEON_MM_SCRATCH]);
 #endif
                                if (i == rmesa->rmm->u_last)
                                        rmesa->rmm->u_last --;
@@ -196,7 +196,7 @@ int radeon_mm_alloc(r300ContextPtr rmesa, int alignment, int size)
        //fprintf(stderr, "alloc %p at id %d\n", rmesa->rmm->u_list[i].ptr, i);
        
 #ifdef MM_DEBUG
-       fprintf(stderr, "allocated %d at age %x\n", i, rmesa->radeon.radeonScreen->scratch[2]);
+       fprintf(stderr, "allocated %d at age %x\n", i, rmesa->radeon.radeonScreen->scratch[RADEON_MM_SCRATCH]);
 #endif
        
        return i;
@@ -261,7 +261,7 @@ void radeon_mm_use(r300ContextPtr rmesa, int id)
 {
        unsigned long long ull;
 #ifdef MM_DEBUG
-       fprintf(stderr, "%s: %d at age %x\n", __FUNCTION__, id, rmesa->radeon.radeonScreen->scratch[2]);
+       fprintf(stderr, "%s: %d at age %x\n", __FUNCTION__, id, rmesa->radeon.radeonScreen->scratch[RADEON_MM_SCRATCH]);
 #endif 
        drm_r300_cmd_header_t *cmd;
        
@@ -303,7 +303,7 @@ void radeon_mm_use(r300ContextPtr rmesa, int id)
                
        cmd = r300AllocCmdBuf(rmesa, 2 + sizeof(ull) / 4, __FUNCTION__);
        cmd[0].scratch.cmd_type = R300_CMD_SCRATCH;
-       cmd[0].scratch.reg = 2;
+       cmd[0].scratch.reg = RADEON_MM_SCRATCH;
        cmd[0].scratch.n_bufs = 1;
        cmd[0].scratch.flags = 0;
        cmd ++;
@@ -345,7 +345,7 @@ int radeon_mm_on_card(r300ContextPtr rmesa, int id)
 void *radeon_mm_map(r300ContextPtr rmesa, int id, int access)
 {
 #ifdef MM_DEBUG
-       fprintf(stderr, "%s: %d at age %x\n", __FUNCTION__, id, rmesa->radeon.radeonScreen->scratch[2]);
+       fprintf(stderr, "%s: %d at age %x\n", __FUNCTION__, id, rmesa->radeon.radeonScreen->scratch[RADEON_MM_SCRATCH]);
 #endif 
        void *ptr;
        int tries = 0;
@@ -385,12 +385,12 @@ void *radeon_mm_map(r300ContextPtr rmesa, int id, int access)
                return NULL;
        }
        
-       while(rmesa->rmm->u_list[id].age > rmesa->radeon.radeonScreen->scratch[2] && tries++ < 1000)
+       while(rmesa->rmm->u_list[id].age > rmesa->radeon.radeonScreen->scratch[RADEON_MM_SCRATCH] && tries++ < 1000)
                usleep(10);
        
        if (tries >= 1000) {
                fprintf(stderr, "Idling failed (%x vs %x)\n",
-                               rmesa->rmm->u_list[id].age, rmesa->radeon.radeonScreen->scratch[2]);
+                               rmesa->rmm->u_list[id].age, rmesa->radeon.radeonScreen->scratch[RADEON_MM_SCRATCH]);
                return NULL;
        }
        
@@ -406,7 +406,7 @@ void *radeon_mm_map(r300ContextPtr rmesa, int id, int access)
 void radeon_mm_unmap(r300ContextPtr rmesa, int id)
 {
 #ifdef MM_DEBUG
-       fprintf(stderr, "%s: %d at age %x\n", __FUNCTION__, id, rmesa->radeon.radeonScreen->scratch[2]);
+       fprintf(stderr, "%s: %d at age %x\n", __FUNCTION__, id, rmesa->radeon.radeonScreen->scratch[RADEON_MM_SCRATCH]);
 #endif 
        
        if(rmesa->rmm->u_list[id].mapped == 0)
@@ -423,7 +423,7 @@ void radeon_mm_unmap(r300ContextPtr rmesa, int id)
 void radeon_mm_free(r300ContextPtr rmesa, int id)
 {
 #ifdef MM_DEBUG
-       fprintf(stderr, "%s: %d at age %x\n", __FUNCTION__, id, rmesa->radeon.radeonScreen->scratch[2]);
+       fprintf(stderr, "%s: %d at age %x\n", __FUNCTION__, id, rmesa->radeon.radeonScreen->scratch[RADEON_MM_SCRATCH]);
 #endif 
        
        if(id == 0)
index 56a9bc0..9df5224 100644 (file)
@@ -7,7 +7,9 @@
 #define RADEON_MM_R 1
 #define RADEON_MM_W 2
 #define RADEON_MM_RW (RADEON_MM_R | RADEON_MM_W)
-    
+
+#define RADEON_MM_SCRATCH 2
+
 struct radeon_memory_manager {
        struct {
                void *ptr;
index 2269a87..bff64ac 100644 (file)
@@ -776,6 +776,38 @@ void r300DeleteBuffer(GLcontext *ctx, struct gl_buffer_object *obj)
        _mesa_delete_buffer_object(ctx, obj);
 }
 
+void r300_evict_vbos(GLcontext *ctx, int amount)
+{
+       r300ContextPtr rmesa = R300_CONTEXT(ctx);
+       const struct _mesa_HashTable *hash = ctx->Shared->BufferObjects;
+       GLuint k = _mesa_HashFirstEntry(hash);
+       struct gl_buffer_object *obj;
+       struct r300_buffer_object *r300_obj;
+       GLvoid *data;
+       
+       while (amount > 0 && k) {
+               obj = (struct gl_buffer_object *) _mesa_HashLookup(hash, k);
+               r300_obj = (struct r300_buffer_object *) obj;
+               
+               if (obj->OnCard && obj->Size) {
+                       obj->Data = _mesa_malloc(obj->Size);
+                       
+                       data = radeon_mm_map(rmesa, r300_obj->id, RADEON_MM_R);
+                       _mesa_memcpy(obj->Data, data, obj->Size);
+                       radeon_mm_unmap(rmesa, r300_obj->id);
+                       
+                       radeon_mm_free(rmesa, r300_obj->id);
+                       r300_obj->id = 0;
+                       obj->OnCard = GL_FALSE;
+                       
+                       amount -= obj->Size;
+               }
+               
+               k = _mesa_HashNextEntry(hash, k);
+       }
+       
+}
+
 void r300_init_vbo_funcs(struct dd_function_table *functions)
 {
        functions->NewBufferObject = r300NewBufferObject;