radeon/r600: use new libdrm_radeon api
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_bo_legacy.c
index ae5f0c4cfe75189b4402bcb1f57b5af3730908bf..cf12664bacdaf48dff604e3502145ebf550e6971 100644 (file)
 #include "radeon_bocs_wrapper.h"
 #include "radeon_macros.h"
 
+#ifdef HAVE_LIBDRM_RADEON
+#include "radeon_bo_int.h"
+#else
+#include "radeon_bo_int_drm.h"
+#endif
+
 /* no seriously texmem.c is this screwed up */
 struct bo_legacy_texture_object {
     driTextureObject    base;
@@ -57,7 +63,7 @@ struct bo_legacy_texture_object {
 };
 
 struct bo_legacy {
-    struct radeon_bo    base;
+    struct radeon_bo_int    base;
     int                 map_count;
     uint32_t            pending;
     int                 is_pending;
@@ -69,9 +75,6 @@ struct bo_legacy {
     void                *ptr;
     struct bo_legacy    *next, *prev;
     struct bo_legacy    *pnext, *pprev;
-#ifdef RADEON_DEBUG_BO
-    char                szBufUsage[16];
-#endif /* RADEON_DEBUG_BO */
 };
 
 struct bo_manager_legacy {
@@ -190,10 +193,10 @@ static void legacy_get_current_age(struct bo_manager_legacy *boml)
     }
 }
 
-static int legacy_is_pending(struct radeon_bo *bo)
+static int legacy_is_pending(struct radeon_bo_int *boi)
 {
-    struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom;
-    struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
+    struct bo_manager_legacy *boml = (struct bo_manager_legacy *)boi->bom;
+    struct bo_legacy *bo_legacy = (struct bo_legacy*)boi;
 
     if (bo_legacy->is_pending <= 0) {
         bo_legacy->is_pending = 0;
@@ -207,13 +210,13 @@ static int legacy_is_pending(struct radeon_bo *bo)
         if (bo_legacy->pnext) {
             bo_legacy->pnext->pprev = bo_legacy->pprev;
         }
-       assert(bo_legacy->is_pending <= bo->cref);
+       assert(bo_legacy->is_pending <= boi->cref);
         while (bo_legacy->is_pending--) {
-           bo = radeon_bo_unref(bo);
-           if (!bo)
+           boi = (struct radeon_bo_int *)radeon_bo_unref((struct radeon_bo *)boi);
+           if (!boi)
              break;
         }
-       if (bo)
+       if (boi)
          bo_legacy->is_pending = 0;
         boml->cpendings--;
         return 0;
@@ -221,7 +224,7 @@ static int legacy_is_pending(struct radeon_bo *bo)
     return 1;
 }
 
-static int legacy_wait_pending(struct radeon_bo *bo)
+static int legacy_wait_pending(struct radeon_bo_int *bo)
 {
     struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom;
     struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
@@ -238,8 +241,9 @@ static int legacy_wait_pending(struct radeon_bo *bo)
     return 0;
 }
 
-static void legacy_track_pending(struct bo_manager_legacy *boml, int debug)
+void legacy_track_pending(struct radeon_bo_manager *bom, int debug)
 {
+    struct bo_manager_legacy *boml = (struct bo_manager_legacy*) bom;
     struct bo_legacy *bo_legacy;
     struct bo_legacy *next;
 
@@ -247,8 +251,8 @@ static void legacy_track_pending(struct bo_manager_legacy *boml, int debug)
     bo_legacy = boml->pending_bos.pnext;
     while (bo_legacy) {
         if (debug)
-         fprintf(stderr,"pending %p %d %d %d\n", bo_legacy, bo_legacy->base.size,
-                 boml->current_age, bo_legacy->pending);
+            fprintf(stderr,"pending %p %d %d %d\n", bo_legacy, bo_legacy->base.size,
+                    boml->current_age, bo_legacy->pending);
         next = bo_legacy->pnext;
         if (legacy_is_pending(&(bo_legacy->base))) {
         }
@@ -289,12 +293,7 @@ static struct bo_legacy *bo_allocate(struct bo_manager_legacy *boml,
                                      uint32_t size,
                                      uint32_t alignment,
                                      uint32_t domains,
-#ifdef RADEON_DEBUG_BO
-                                     uint32_t flags,
-                                     char * szBufUsage)
-#else
                                      uint32_t flags)
-#endif /* RADEON_DEBUG_BO */
 {
     struct bo_legacy *bo_legacy;
     static int pgsize;
@@ -327,14 +326,10 @@ static struct bo_legacy *bo_allocate(struct bo_manager_legacy *boml,
         bo_legacy->next->prev = bo_legacy;
     }
 
-#ifdef RADEON_DEBUG_BO
-    sprintf(bo_legacy->szBufUsage, "%s", szBufUsage); 
-#endif /* RADEON_DEBUG_BO */
-
     return bo_legacy;
 }
 
-static int bo_dma_alloc(struct radeon_bo *bo)
+static int bo_dma_alloc(struct radeon_bo_int *bo)
 {
     struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom;
     struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
@@ -344,7 +339,7 @@ static int bo_dma_alloc(struct radeon_bo *bo)
     int r;
 
     /* align size on 4Kb */
-    size = (((4 * 1024) - 1) + bo->size) & ~((4 * 1024) - 1);
+    size = (((4 * 1024) - 1) + bo_legacy->base.size) & ~((4 * 1024) - 1);
     alloc.region = RADEON_MEM_REGION_GART;
     alloc.alignment = bo_legacy->base.alignment;
     alloc.size = size;
@@ -366,7 +361,7 @@ static int bo_dma_alloc(struct radeon_bo *bo)
     return 0;
 }
 
-static int bo_dma_free(struct radeon_bo *bo)
+static int bo_dma_free(struct radeon_bo_int *bo)
 {
     struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom;
     struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
@@ -429,12 +424,7 @@ static struct radeon_bo *bo_open(struct radeon_bo_manager *bom,
                                  uint32_t size,
                                  uint32_t alignment,
                                  uint32_t domains,
-#ifdef RADEON_DEBUG_BO
-                                 uint32_t flags,
-                                 char *   szBufUsage)
-#else
                                  uint32_t flags)
-#endif /* RADEON_DEBUG_BO */
 {
     struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bom;
     struct bo_legacy *bo_legacy;
@@ -444,18 +434,14 @@ static struct radeon_bo *bo_open(struct radeon_bo_manager *bom,
         bo_legacy = boml->bos.next;
         while (bo_legacy) {
             if (bo_legacy->base.handle == handle) {
-                radeon_bo_ref(&(bo_legacy->base));
+                radeon_bo_ref((struct radeon_bo *)&(bo_legacy->base));
                 return (struct radeon_bo*)bo_legacy;
             }
             bo_legacy = bo_legacy->next;
         }
         return NULL;
     }
-#ifdef RADEON_DEBUG_BO
-    bo_legacy = bo_allocate(boml, size, alignment, domains, flags, szBufUsage);
-#else
     bo_legacy = bo_allocate(boml, size, alignment, domains, flags);
-#endif /* RADEON_DEBUG_BO */
     bo_legacy->static_bo = 0;
     r = legacy_new_handle(boml, &bo_legacy->base.handle);
     if (r) {
@@ -465,7 +451,7 @@ static struct radeon_bo *bo_open(struct radeon_bo_manager *bom,
     if (bo_legacy->base.domains & RADEON_GEM_DOMAIN_GTT) 
     {
 retry:
-        legacy_track_pending(boml, 0);
+        legacy_track_pending(&boml->base, 0);
         /* dma buffers */
 
         r = bo_dma_alloc(&(bo_legacy->base));
@@ -488,20 +474,20 @@ retry:
             return NULL;
         }
     }
-    radeon_bo_ref(&(bo_legacy->base));
+    radeon_bo_ref((struct radeon_bo *)&(bo_legacy->base));
 
     return (struct radeon_bo*)bo_legacy;
 }
 
-static void bo_ref(struct radeon_bo *bo)
+static void bo_ref(struct radeon_bo_int *bo)
 {
 }
 
-static struct radeon_bo *bo_unref(struct radeon_bo *bo)
+static struct radeon_bo *bo_unref(struct radeon_bo_int *boi)
 {
-    struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
+    struct bo_legacy *bo_legacy = (struct bo_legacy*)boi;
 
-    if (bo->cref <= 0) {
+    if (boi->cref <= 0) {
         bo_legacy->prev->next = bo_legacy->next;
         if (bo_legacy->next) {
             bo_legacy->next->prev = bo_legacy->prev;
@@ -511,10 +497,10 @@ static struct radeon_bo *bo_unref(struct radeon_bo *bo)
         }
         return NULL;
     }
-    return bo;
+    return (struct radeon_bo *)boi;
 }
 
-static int bo_map(struct radeon_bo *bo, int write)
+static int bo_map(struct radeon_bo_int *bo, int write)
 {
     struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom;
     struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
@@ -548,7 +534,7 @@ static int bo_map(struct radeon_bo *bo, int write)
     return 0;
 }
 
-static int bo_unmap(struct radeon_bo *bo)
+static int bo_unmap(struct radeon_bo_int *bo)
 {
     struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
 
@@ -562,15 +548,39 @@ static int bo_unmap(struct radeon_bo *bo)
     return 0;
 }
 
+static int bo_is_busy(struct radeon_bo_int *bo, uint32_t *domain)
+{
+    *domain = 0;
+    if (bo->domains & RADEON_GEM_DOMAIN_GTT)
+        *domain = RADEON_GEM_DOMAIN_GTT;
+    else
+        *domain = RADEON_GEM_DOMAIN_CPU;
+    if (legacy_is_pending(bo))
+        return -EBUSY;
+    else
+        return 0;
+}
+
+static int bo_is_static(struct radeon_bo_int *bo)
+{
+    struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
+    return bo_legacy->static_bo;
+}
+
 static struct radeon_bo_funcs bo_legacy_funcs = {
     bo_open,
     bo_ref,
     bo_unref,
     bo_map,
-    bo_unmap
+    bo_unmap,
+    NULL,
+    bo_is_static,
+    NULL,
+    NULL,
+    bo_is_busy
 };
 
-static int bo_vram_validate(struct radeon_bo *bo,
+static int bo_vram_validate(struct radeon_bo_int *bo,
                             uint32_t *soffset,
                             uint32_t *eoffset)
 {
@@ -590,7 +600,7 @@ static int bo_vram_validate(struct radeon_bo *bo,
         if (r) {
                pending_retry = 0;
                while(boml->cpendings && pending_retry++ < 10000) {
-                       legacy_track_pending(boml, 0);
+                       legacy_track_pending(&boml->base, 0);
                        retry_count++;
                        if (retry_count > 2) {
                                free(bo_legacy->tobj);
@@ -613,12 +623,34 @@ static int bo_vram_validate(struct radeon_bo *bo,
 
     if (bo_legacy->dirty || bo_legacy->tobj->base.dirty_images[0]) {
            if (IS_R600_CLASS(boml->screen)) {
-                   char *src = bo_legacy->ptr;
-                   char *dst = (char *) boml->screen->driScreen->pFB +
-                           (bo_legacy->offset - boml->fb_location);
+                   drm_radeon_texture_t tex;
+                   drm_radeon_tex_image_t tmp;
+                   int ret;
 
-                   /* FIXME: alignment, pitch, etc. */
-                   r600_sw_blit(src, 0, dst, 0, 0, 0, 1, 1, bo->size);
+                   tex.offset = bo_legacy->offset;
+                   tex.image = &tmp;
+                   assert(!(tex.offset & 1023));
+
+                   tmp.x = 0;
+                   tmp.y = 0;
+                   tmp.width = bo->size;
+                   tmp.height = 1;
+                   tmp.data = bo_legacy->ptr;
+                   tex.format = RADEON_TXFORMAT_ARGB8888;
+                   tex.width = tmp.width;
+                   tex.height = tmp.height;
+                   tex.pitch = bo->size;
+                   do {
+                           ret = drmCommandWriteRead(bo->bom->fd,
+                                                     DRM_RADEON_TEXTURE,
+                                                     &tex,
+                                                     sizeof(drm_radeon_texture_t));
+                           if (ret) {
+                                   if (RADEON_DEBUG & RADEON_IOCTL)
+                                           fprintf(stderr, "DRM_RADEON_TEXTURE:  again!\n");
+                                   usleep(1);
+                           }
+                   } while (ret == -EAGAIN);
            } else {
                    /* Copy to VRAM using a blit.
                     * All memory is 4K aligned. We're using 1024 pixels wide blits.
@@ -651,7 +683,7 @@ static int bo_vram_validate(struct radeon_bo *bo,
                                                      &tex,
                                                      sizeof(drm_radeon_texture_t));
                            if (ret) {
-                                   if (RADEON_DEBUG & DEBUG_IOCTL)
+                                   if (RADEON_DEBUG & RADEON_IOCTL)
                                            fprintf(stderr, "DRM_RADEON_TEXTURE:  again!\n");
                                    usleep(1);
                            }
@@ -674,33 +706,32 @@ int radeon_bo_legacy_validate(struct radeon_bo *bo,
                               uint32_t *soffset,
                               uint32_t *eoffset)
 {
-    struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom;
+    struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
+    struct bo_manager_legacy *boml = (struct bo_manager_legacy *)boi->bom;
     struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
     int r;
     int retries = 0;
 
     if (bo_legacy->map_count) {
-#ifdef RADEON_DEBUG_BO
-        fprintf(stderr, "bo(%p, %d, %s) is mapped (%d) can't valide it.\n",
-                bo, bo->size, bo_legacy->szBufUsage, bo_legacy->map_count);
-#else
         fprintf(stderr, "bo(%p, %d) is mapped (%d) can't valide it.\n",
-                bo, bo->size, bo_legacy->map_count);
-#endif /* RADEON_DEBUG_BO */
-
+                bo, boi->size, bo_legacy->map_count);
+        return -EINVAL;
+    }
+    if(boi->size == 0) {
+        fprintf(stderr, "bo(%p) has size 0.\n", bo);
         return -EINVAL;
     }
     if (bo_legacy->static_bo || bo_legacy->validated) {
         *soffset = bo_legacy->offset;
-        *eoffset = bo_legacy->offset + bo->size;
+        *eoffset = bo_legacy->offset + boi->size;
 
         return 0;
     }
-    if (!(bo->domains & RADEON_GEM_DOMAIN_GTT)) {
+    if (!(boi->domains & RADEON_GEM_DOMAIN_GTT)) {
 
-        r = bo_vram_validate(bo, soffset, eoffset);
+        r = bo_vram_validate(boi, soffset, eoffset);
         if (r) {
-           legacy_track_pending(boml, 0);
+           legacy_track_pending(&boml->base, 0);
            legacy_kick_all_buffers(boml);
            retries++;
            if (retries == 2) {
@@ -712,7 +743,7 @@ int radeon_bo_legacy_validate(struct radeon_bo *bo,
         }
     }
     *soffset = bo_legacy->offset;
-    *eoffset = bo_legacy->offset + bo->size;
+    *eoffset = bo_legacy->offset + boi->size;
     bo_legacy->validated = 1;
 
     return 0;
@@ -720,7 +751,8 @@ int radeon_bo_legacy_validate(struct radeon_bo *bo,
 
 void radeon_bo_legacy_pending(struct radeon_bo *bo, uint32_t pending)
 {
-    struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom;
+    struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
+    struct bo_manager_legacy *boml = (struct bo_manager_legacy *)boi->bom;
     struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
 
     bo_legacy->pending = pending;
@@ -759,21 +791,13 @@ void radeon_bo_manager_legacy_dtor(struct radeon_bo_manager *bom)
 }
 
 static struct bo_legacy *radeon_legacy_bo_alloc_static(struct bo_manager_legacy *bom,
-                                                      int size, 
-#ifdef RADEON_DEBUG_BO
-                               uint32_t offset,
-                               char * szBufUsage)
-#else
-                               uint32_t offset)
-#endif /* RADEON_DEBUG_BO */
+                                                      int size,
+                                                      uint32_t offset)
 {
     struct bo_legacy *bo;
 
-#ifdef RADEON_DEBUG_BO
-    bo = bo_allocate(bom, size, 0, RADEON_GEM_DOMAIN_VRAM, 0, szBufUsage);
-#else
     bo = bo_allocate(bom, size, 0, RADEON_GEM_DOMAIN_VRAM, 0);
-#endif /* RADEON_DEBUG_BO */
+
     if (bo == NULL)
        return NULL;
     bo->static_bo = 1;
@@ -783,7 +807,7 @@ static struct bo_legacy *radeon_legacy_bo_alloc_static(struct bo_manager_legacy
     if (bo->base.handle > bom->nhandle) {
         bom->nhandle = bo->base.handle + 1;
     }
-    radeon_bo_ref(&(bo->base));
+    radeon_bo_ref((struct radeon_bo *)&(bo->base));
     return bo;
 }
 
@@ -834,11 +858,8 @@ struct radeon_bo_manager *radeon_bo_manager_legacy_ctor(struct radeon_screen *sc
     size = 4096*4096*4; 
 
     /* allocate front */
-#ifdef RADEON_DEBUG_BO
-    bo = radeon_legacy_bo_alloc_static(bom, size, bom->screen->frontOffset, "FRONT BUF");
-#else
     bo = radeon_legacy_bo_alloc_static(bom, size, bom->screen->frontOffset);
-#endif /* RADEON_DEBUG_BO */
+
     if (!bo) {
         radeon_bo_manager_legacy_dtor((struct radeon_bo_manager*)bom);
         return NULL;
@@ -848,11 +869,8 @@ struct radeon_bo_manager *radeon_bo_manager_legacy_ctor(struct radeon_screen *sc
     }
 
     /* allocate back */
-#ifdef RADEON_DEBUG_BO
-    bo = radeon_legacy_bo_alloc_static(bom, size, bom->screen->backOffset, "BACK BUF");
-#else
     bo = radeon_legacy_bo_alloc_static(bom, size, bom->screen->backOffset);
-#endif /* RADEON_DEBUG_BO */
+
     if (!bo) {
         radeon_bo_manager_legacy_dtor((struct radeon_bo_manager*)bom);
         return NULL;
@@ -862,11 +880,8 @@ struct radeon_bo_manager *radeon_bo_manager_legacy_ctor(struct radeon_screen *sc
     }
 
     /* allocate depth */
-#ifdef RADEON_DEBUG_BO
-    bo = radeon_legacy_bo_alloc_static(bom, size, bom->screen->depthOffset, "Z BUF");
-#else
     bo = radeon_legacy_bo_alloc_static(bom, size, bom->screen->depthOffset);
-#endif /* RADEON_DEBUG_BO */
+
     if (!bo) {
         radeon_bo_manager_legacy_dtor((struct radeon_bo_manager*)bom);
         return NULL;
@@ -887,17 +902,38 @@ void radeon_bo_legacy_texture_age(struct radeon_bo_manager *bom)
 
 unsigned radeon_bo_legacy_relocs_size(struct radeon_bo *bo)
 {
+    struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
     struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
 
-    if (bo_legacy->static_bo || (bo->domains & RADEON_GEM_DOMAIN_GTT)) {
+    if (bo_legacy->static_bo || (boi->domains & RADEON_GEM_DOMAIN_GTT)) {
         return 0;
     }
-    return bo->size;
+    return boi->size;
 }
 
-int radeon_legacy_bo_is_static(struct radeon_bo *bo)
+/*
+ * Fake up a bo for things like texture image_override.
+ * bo->offset already includes fb_location
+ */
+struct radeon_bo *radeon_legacy_bo_alloc_fake(struct radeon_bo_manager *bom,
+                                             int size,
+                                             uint32_t offset)
 {
-    struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
-    return bo_legacy->static_bo;
+    struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bom;
+    struct bo_legacy *bo;
+
+    bo = bo_allocate(boml, size, 0, RADEON_GEM_DOMAIN_VRAM, 0);
+
+    if (bo == NULL)
+       return NULL;
+    bo->static_bo = 1;
+    bo->offset = offset;
+    bo->base.handle = bo->offset;
+    bo->ptr = boml->screen->driScreen->pFB + (offset - boml->fb_location);
+    if (bo->base.handle > boml->nhandle) {
+        boml->nhandle = bo->base.handle + 1;
+    }
+    radeon_bo_ref((struct radeon_bo *)&(bo->base));
+    return (struct radeon_bo *)&(bo->base);
 }