mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2026-01-05 02:10:20 +01:00
I915 accelerated blit copy functional.
Fixed - to System memory copies are implemented by flipping in a cache-coherent TTM, blitting to it, and then flipping it out.
This commit is contained in:
parent
57df398072
commit
53aee3122a
6 changed files with 78 additions and 18 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue