I915 accelerated blit copy functional.
authorThomas Hellstrom <thomas-at-tungstengraphics-dot-com>
Fri, 9 Feb 2007 15:36:53 +0000 (16:36 +0100)
committerThomas Hellstrom <thomas-at-tungstengraphics-dot-com>
Fri, 9 Feb 2007 15:36:53 +0000 (16:36 +0100)
Fixed - to System memory copies are implemented by
flipping in a cache-coherent TTM,
blitting to it, and then flipping it out.

linux-core/drm_bo_move.c
linux-core/drm_mm.c
linux-core/drm_ttm.c
linux-core/i915_buffer.c
linux-core/i915_drv.c
shared-core/i915_drv.h

index e134020..d712a70 100644 (file)
@@ -333,8 +333,10 @@ int drm_bo_move_accel_cleanup(drm_buffer_object_t *bo,
 
        if (evict) {
                ret = drm_bo_wait(bo, 0, 1, 0);
-               if (ret)
+               if (ret) {
+                 DRM_ERROR("Wait failure\n");
                        return ret;
+               }
                if (old_mem->mm_node) {
                        mutex_lock(&dev->struct_mutex);
                        drm_mm_put_block(old_mem->mm_node);
index 5889ee4..634a178 100644 (file)
@@ -217,6 +217,7 @@ void drm_mm_put_block(drm_mm_node_t * cur)
                drm_ctl_free(cur, sizeof(*cur), DRM_MEM_MM);
        }
 }
+EXPORT_SYMBOL(drm_mm_put_block);
 
 drm_mm_node_t *drm_mm_search_free(const drm_mm_t * mm,
                                  unsigned long size,
index fa55a8b..8cd961d 100644 (file)
@@ -344,3 +344,4 @@ int drm_bind_ttm(drm_ttm_t * ttm, int cached, unsigned long aper_offset)
 
        return 0;
 }
+EXPORT_SYMBOL(drm_bind_ttm);
index 41f05b7..70ba9a6 100644 (file)
@@ -132,37 +132,28 @@ static void i915_emit_copy_blit(drm_device_t *dev,
        if (!dev_priv)
                return;
        
-       if (direction) {
-               stride = -stride;
-               src_offset += (pages - 1) << PAGE_SHIFT;
-               dst_offset += (pages - 1) << PAGE_SHIFT;
-       }
-
+       i915_kernel_lost_context(dev);
        while(pages > 0) {
                cur_pages = pages;
                if (cur_pages > 2048)
                        cur_pages = 2048;
                pages -= cur_pages;
 
-               BEGIN_LP_RING(8);
-               OUT_RING(XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
+               BEGIN_LP_RING(6);
+               OUT_RING(SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
                         XY_SRC_COPY_BLT_WRITE_RGB);
                OUT_RING((stride & 0xffff) | ( 0xcc << 16) | (1 << 24) | 
-                        (1 << 25));
-               OUT_RING(0);
-               OUT_RING((cur_pages << 16) | (PAGE_SIZE >> 2));
+                        (1 << 25) | (direction ? (1 << 30) : 0));
+               OUT_RING((cur_pages << 16) | PAGE_SIZE);
                OUT_RING(dst_offset);
-               OUT_RING(0);
                OUT_RING(stride & 0xffff);
                OUT_RING(src_offset);
                ADVANCE_LP_RING();
-               dst_offset += (cur_pages << PAGE_SHIFT)*(direction ? -1 : 1);
-               src_offset += (cur_pages << PAGE_SHIFT)*(direction ? -1 : 1);
        }
        return;
 }
 
-static int drm_bo_move_blit(drm_buffer_object_t *bo,
+static int i915_move_blit(drm_buffer_object_t *bo,
                            int evict,
                            int no_wait,
                            drm_bo_mem_reg_t *new_mem)
@@ -191,5 +182,66 @@ static int drm_bo_move_blit(drm_buffer_object_t *bo,
                                         new_mem);
 }
 
+/*
+ * Flip destination ttm into cached-coherent AGP, 
+ * then blit and subsequently move out again.
+ */
+
+
+static int i915_move_flip(drm_buffer_object_t *bo,
+                         int evict,
+                         int no_wait,
+                         drm_bo_mem_reg_t *new_mem)
+{
+       drm_device_t *dev = bo->dev;
+       drm_bo_mem_reg_t tmp_mem;
+       int ret;
+
+       tmp_mem = *new_mem;
+       tmp_mem.mm_node = NULL;
+       tmp_mem.mask = DRM_BO_FLAG_MEM_TT |
+               DRM_BO_FLAG_CACHED  |
+               DRM_BO_FLAG_FORCE_CACHING;
+       
+       ret = drm_bo_mem_space(dev, &tmp_mem, no_wait);
+       if (ret) 
+               return ret;
        
+       ret = drm_bind_ttm(bo->ttm, 1, tmp_mem.mm_node->start);
+       if (ret) 
+               goto out_cleanup;
 
+       ret = i915_move_blit(bo, 1, no_wait, &tmp_mem);
+       if (ret) 
+               goto out_cleanup;
+       
+       ret = drm_bo_move_ttm(bo, evict, no_wait, new_mem);
+out_cleanup:
+       if (tmp_mem.mm_node) {
+               mutex_lock(&dev->struct_mutex);
+               drm_mm_put_block(tmp_mem.mm_node);
+               tmp_mem.mm_node = NULL;
+               mutex_unlock(&dev->struct_mutex);
+       }
+       return ret;
+}
+
+       
+int i915_move(drm_buffer_object_t *bo,
+             int evict,
+             int no_wait,
+             drm_bo_mem_reg_t *new_mem)
+{
+       drm_bo_mem_reg_t *old_mem = &bo->mem;
+
+       if (old_mem->mem_type == DRM_BO_MEM_LOCAL) 
+               return drm_bo_move_memcpy(bo, evict, no_wait, new_mem);
+       if (new_mem->mem_type == DRM_BO_MEM_LOCAL) {
+               if (i915_move_flip(bo, evict, no_wait, new_mem)) 
+                       return drm_bo_move_memcpy(bo, evict, no_wait, new_mem);
+       } else {
+               if (i915_move_blit(bo, evict, no_wait, new_mem)) 
+                       return drm_bo_move_memcpy(bo, evict, no_wait, new_mem);
+       }
+       return 0;
+}
index 19b63b7..848ffa7 100644 (file)
@@ -64,7 +64,7 @@ static drm_bo_driver_t i915_bo_driver = {
        .invalidate_caches = i915_invalidate_caches,
        .init_mem_type = i915_init_mem_type,
        .evict_flags = i915_evict_flags,
-       .move = NULL,
+       .move = i915_move,
 };
 #endif
 
index 55c8cf5..ffc9d43 100644 (file)
@@ -192,6 +192,9 @@ extern int i915_invalidate_caches(drm_device_t *dev, uint32_t buffer_flags);
 extern int i915_init_mem_type(drm_device_t *dev, uint32_t type, 
                               drm_mem_type_manager_t *man);
 extern uint32_t i915_evict_flags(drm_device_t *dev, uint32_t type);
+extern int i915_move(drm_buffer_object_t *bo, int evict,
+               int no_wait, drm_bo_mem_reg_t *new_mem);
+
 #endif
 
 #define I915_READ(reg)          DRM_READ32(dev_priv->mmio_map, (reg))
@@ -329,6 +332,7 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller);
 
 #define GFX_OP_DRAWRECT_INFO_I965  ((0x7900<<16)|0x2)
 
+#define SRC_COPY_BLT_CMD                ((2<<29)|(0x43<<22)|4)
 #define XY_SRC_COPY_BLT_CMD            ((2<<29)|(0x53<<22)|6)
 #define XY_SRC_COPY_BLT_WRITE_ALPHA    (1<<21)
 #define XY_SRC_COPY_BLT_WRITE_RGB      (1<<20)