diff options
Diffstat (limited to 'shared-core')
-rw-r--r-- | shared-core/drm.h | 51 | ||||
-rw-r--r-- | shared-core/i915_dma.c | 91 | ||||
-rw-r--r-- | shared-core/i915_drv.h | 9 | ||||
-rw-r--r-- | shared-core/i915_irq.c | 2 | ||||
-rw-r--r-- | shared-core/mga_dma.c | 2 | ||||
-rw-r--r-- | shared-core/nv20_graph.c | 13 | ||||
-rw-r--r-- | shared-core/via_drv.c | 2 | ||||
-rw-r--r-- | shared-core/via_drv.h | 2 |
8 files changed, 126 insertions, 46 deletions
diff --git a/shared-core/drm.h b/shared-core/drm.h index ec07b895..6b4125f2 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -662,6 +662,10 @@ struct drm_fence_arg { #define DRM_BO_FLAG_EXE (1ULL << 2) /* + * All of the bits related to access mode + */ +#define DRM_BO_MASK_ACCESS (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_EXE) +/* * Status flags. Can be read to determine the actual state of a buffer. * Can also be set in the buffer mask before validation. */ @@ -741,18 +745,50 @@ struct drm_fence_arg { #define DRM_BO_FLAG_MEM_PRIV4 (1ULL << 31) /* We can add more of these now with a 64-bit flag type */ -/* Memory flag mask */ +/* + * This is a mask covering all of the memory type flags; easier to just + * use a single constant than a bunch of | values. It covers + * DRM_BO_FLAG_MEM_LOCAL through DRM_BO_FLAG_MEM_PRIV4 + */ #define DRM_BO_MASK_MEM 0x00000000FF000000ULL -#define DRM_BO_MASK_MEMTYPE 0x00000000FF0800A0ULL - +/* + * This adds all of the CPU-mapping options in with the memory + * type to label all bits which change how the page gets mapped + */ +#define DRM_BO_MASK_MEMTYPE (DRM_BO_MASK_MEM | \ + DRM_BO_FLAG_CACHED_MAPPED | \ + DRM_BO_FLAG_CACHED | \ + DRM_BO_FLAG_MAPPABLE) + /* Driver-private flags */ #define DRM_BO_MASK_DRIVER 0xFFFF000000000000ULL -/* Don't block on validate and map */ +/* + * Don't block on validate and map. Instead, return EBUSY. + */ #define DRM_BO_HINT_DONT_BLOCK 0x00000002 -/* Don't place this buffer on the unfenced list.*/ +/* + * Don't place this buffer on the unfenced list. This means + * that the buffer will not end up having a fence associated + * with it as a result of this operation + */ #define DRM_BO_HINT_DONT_FENCE 0x00000004 +/* + * Sleep while waiting for the operation to complete. + * Without this flag, the kernel will, instead, spin + * until this operation has completed. I'm not sure + * why you would ever want this, so please always + * provide DRM_BO_HINT_WAIT_LAZY to any operation + * which may block + */ #define DRM_BO_HINT_WAIT_LAZY 0x00000008 +/* + * The client has compute relocations refering to this buffer using the + * offset in the presumed_offset field. If that offset ends up matching + * where this buffer lands, the kernel is free to skip executing those + * relocations + */ +#define DRM_BO_HINT_PRESUMED_OFFSET 0x00000010 #define DRM_BO_INIT_MAGIC 0xfe769812 #define DRM_BO_INIT_MAJOR 1 @@ -769,10 +805,11 @@ struct drm_bo_info_req { unsigned int desired_tile_stride; unsigned int tile_info; unsigned int pad64; + uint64_t presumed_offset; }; struct drm_bo_create_req { - uint64_t mask; + uint64_t flags; uint64_t size; uint64_t buffer_start; unsigned int hint; @@ -788,7 +825,7 @@ struct drm_bo_create_req { struct drm_bo_info_rep { uint64_t flags; - uint64_t mask; + uint64_t proposed_flags; uint64_t size; uint64_t offset; uint64_t arg_handle; diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 42114beb..df395ba7 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -702,7 +702,14 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, return 0; } +#if DRM_DEBUG_CODE +#define DRM_DEBUG_RELOCATION (drm_debug != 0) +#else +#define DRM_DEBUG_RELOCATION 0 +#endif + #ifdef I915_HAVE_BUFFER + struct i915_relocatee_info { struct drm_buffer_object *buf; unsigned long offset; @@ -712,15 +719,20 @@ struct i915_relocatee_info { int is_iomem; }; -static void i915_dereference_buffers_locked(struct drm_buffer_object **buffers, +struct drm_i915_validate_buffer { + struct drm_buffer_object *buffer; + int presumed_offset_correct; +}; + +static void i915_dereference_buffers_locked(struct drm_i915_validate_buffer *buffers, unsigned num_buffers) { while (num_buffers--) - drm_bo_usage_deref_locked(&buffers[num_buffers]); + drm_bo_usage_deref_locked(&buffers[num_buffers].buffer); } int i915_apply_reloc(struct drm_file *file_priv, int num_buffers, - struct drm_buffer_object **buffers, + struct drm_i915_validate_buffer *buffers, struct i915_relocatee_info *relocatee, uint32_t *reloc) { @@ -734,11 +746,25 @@ int i915_apply_reloc(struct drm_file *file_priv, int num_buffers, return -EINVAL; } + /* + * Short-circuit relocations that were correctly + * guessed by the client + */ + if (buffers[reloc[2]].presumed_offset_correct && !DRM_DEBUG_RELOCATION) + return 0; + new_cmd_offset = reloc[0]; if (!relocatee->data_page || !drm_bo_same_page(relocatee->offset, new_cmd_offset)) { drm_bo_kunmap(&relocatee->kmap); relocatee->offset = new_cmd_offset; + mutex_lock (&relocatee->buf->mutex); + ret = drm_bo_wait (relocatee->buf, 0, 0, FALSE); + mutex_unlock (&relocatee->buf->mutex); + if (ret) { + DRM_ERROR("Could not wait for buffer to apply relocs\n %08lx", new_cmd_offset); + return ret; + } ret = drm_bo_kmap(relocatee->buf, new_cmd_offset >> PAGE_SHIFT, 1, &relocatee->kmap); if (ret) { @@ -751,12 +777,19 @@ int i915_apply_reloc(struct drm_file *file_priv, int num_buffers, relocatee->page_offset = (relocatee->offset & PAGE_MASK); } - val = buffers[reloc[2]]->offset; + val = buffers[reloc[2]].buffer->offset; index = (reloc[0] - relocatee->page_offset) >> 2; /* add in validate */ val = val + reloc[1]; + if (DRM_DEBUG_RELOCATION) { + if (buffers[reloc[2]].presumed_offset_correct && + relocatee->data_page[index] != val) { + DRM_DEBUG ("Relocation mismatch source %d target %d buffer %d user %08x kernel %08x\n", + reloc[0], reloc[1], reloc[2], relocatee->data_page[index], val); + } + } relocatee->data_page[index] = val; return 0; } @@ -765,7 +798,7 @@ int i915_process_relocs(struct drm_file *file_priv, uint32_t buf_handle, uint32_t *reloc_buf_handle, struct i915_relocatee_info *relocatee, - struct drm_buffer_object **buffers, + struct drm_i915_validate_buffer *buffers, uint32_t num_buffers) { struct drm_device *dev = file_priv->head->dev; @@ -851,12 +884,27 @@ out: static int i915_exec_reloc(struct drm_file *file_priv, drm_handle_t buf_handle, drm_handle_t buf_reloc_handle, - struct drm_buffer_object **buffers, + struct drm_i915_validate_buffer *buffers, uint32_t buf_count) { struct drm_device *dev = file_priv->head->dev; struct i915_relocatee_info relocatee; int ret = 0; + int b; + + /* + * Short circuit relocations when all previous + * buffers offsets were correctly guessed by + * the client + */ + if (!DRM_DEBUG_RELOCATION) { + for (b = 0; b < buf_count; b++) + if (!buffers[b].presumed_offset_correct) + break; + + if (b == buf_count) + return 0; + } memset(&relocatee, 0, sizeof(relocatee)); @@ -890,7 +938,7 @@ out_err: */ int i915_validate_buffer_list(struct drm_file *file_priv, unsigned int fence_class, uint64_t data, - struct drm_buffer_object **buffers, + struct drm_i915_validate_buffer *buffers, uint32_t *num_buffers) { struct drm_i915_op_arg arg; @@ -910,7 +958,8 @@ int i915_validate_buffer_list(struct drm_file *file_priv, goto out_err; } - buffers[buf_count] = NULL; + buffers[buf_count].buffer = NULL; + buffers[buf_count].presumed_offset_correct = 0; if (copy_from_user(&arg, (void __user *)(unsigned long)data, sizeof(arg))) { ret = -EFAULT; @@ -920,7 +969,7 @@ int i915_validate_buffer_list(struct drm_file *file_priv, if (arg.handled) { data = arg.next; mutex_lock(&dev->struct_mutex); - buffers[buf_count] = drm_lookup_buffer_object(file_priv, req->arg_handle, 1); + buffers[buf_count].buffer = drm_lookup_buffer_object(file_priv, req->arg_handle, 1); mutex_unlock(&dev->struct_mutex); buf_count++; continue; @@ -945,19 +994,25 @@ int i915_validate_buffer_list(struct drm_file *file_priv, } rep.ret = drm_bo_handle_validate(file_priv, req->bo_req.handle, - req->bo_req.fence_class, - req->bo_req.flags, - req->bo_req.mask, + req->bo_req.flags, req->bo_req.mask, req->bo_req.hint, - 0, + req->bo_req.fence_class, 0, &rep.bo_info, - &buffers[buf_count]); + &buffers[buf_count].buffer); if (rep.ret) { DRM_ERROR("error on handle validate %d\n", rep.ret); goto out_err; } - + /* + * If the user provided a presumed offset hint, check whether + * the buffer is in the same place, if so, relocations relative to + * this buffer need not be performed + */ + if ((req->bo_req.hint & DRM_BO_HINT_PRESUMED_OFFSET) && + buffers[buf_count].buffer->offset == req->bo_req.presumed_offset) { + buffers[buf_count].presumed_offset_correct = 1; + } next = arg.next; arg.handled = 1; @@ -991,7 +1046,7 @@ static int i915_execbuffer(struct drm_device *dev, void *data, struct drm_fence_arg *fence_arg = &exec_buf->fence_arg; int num_buffers; int ret; - struct drm_buffer_object **buffers; + struct drm_i915_validate_buffer *buffers; struct drm_fence_object *fence; if (!dev_priv->allow_batchbuffer) { @@ -1026,7 +1081,7 @@ static int i915_execbuffer(struct drm_device *dev, void *data, num_buffers = exec_buf->num_buffers; - buffers = drm_calloc(num_buffers, sizeof(struct drm_buffer_object *), DRM_MEM_DRIVER); + buffers = drm_calloc(num_buffers, sizeof(struct drm_i915_validate_buffer), DRM_MEM_DRIVER); if (!buffers) { drm_bo_read_unlock(&dev->bm.bm_lock); mutex_unlock(&dev_priv->cmdbuf_mutex); @@ -1044,7 +1099,7 @@ static int i915_execbuffer(struct drm_device *dev, void *data, drm_agp_chipset_flush(dev); /* submit buffer */ - batch->start = buffers[num_buffers-1]->offset; + batch->start = buffers[num_buffers-1].buffer->offset; DRM_DEBUG("i915 exec batchbuffer, start %x used %d cliprects %d\n", batch->start, batch->used, batch->num_cliprects); diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index cb336659..2bdd4b79 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -57,10 +57,11 @@ * 1.9: Usable page flipping and triple buffering * 1.10: Plane/pipe disentangling * 1.11: TTM superioctl + * 1.12: TTM relocation optimization */ #define DRIVER_MAJOR 1 #if defined(I915_HAVE_FENCE) && defined(I915_HAVE_BUFFER) -#define DRIVER_MINOR 11 +#define DRIVER_MINOR 12 #else #define DRIVER_MINOR 6 #endif @@ -302,12 +303,12 @@ extern int i915_fence_has_irq(struct drm_device *dev, uint32_t class, uint32_t f #ifdef I915_HAVE_BUFFER /* i915_buffer.c */ extern struct drm_ttm_backend *i915_create_ttm_backend_entry(struct drm_device *dev); -extern int i915_fence_types(struct drm_buffer_object *bo, uint32_t *fclass, - uint32_t *type); +extern int i915_fence_type(struct drm_buffer_object *bo, uint32_t *fclass, + uint32_t *type); extern int i915_invalidate_caches(struct drm_device *dev, uint64_t buffer_flags); extern int i915_init_mem_type(struct drm_device *dev, uint32_t type, struct drm_mem_type_manager *man); -extern uint32_t i915_evict_mask(struct drm_buffer_object *bo); +extern uint64_t i915_evict_flags(struct drm_buffer_object *bo); extern int i915_move(struct drm_buffer_object *bo, int evict, int no_wait, struct drm_bo_mem_reg *new_mem); void i915_flush_ttm(struct drm_ttm *ttm); diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index ee7c40b5..7e3d3f3b 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -719,7 +719,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data, DRM_SPINLOCK_IRQSAVE(&dev_priv->swaps_lock, irqflags); - list_add_tail((struct list_head *)vbl_swap, &dev_priv->vbl_swaps.head); + list_add_tail(&vbl_swap->head, &dev_priv->vbl_swaps.head); dev_priv->swaps_pending++; DRM_SPINUNLOCK_IRQRESTORE(&dev_priv->swaps_lock, irqflags); diff --git a/shared-core/mga_dma.c b/shared-core/mga_dma.c index 67236b2d..00154b23 100644 --- a/shared-core/mga_dma.c +++ b/shared-core/mga_dma.c @@ -997,7 +997,7 @@ static int mga_do_cleanup_dma(struct drm_device *dev, int full_cleanup) } } - return 0; + return err; } int mga_dma_init(struct drm_device *dev, void *data, diff --git a/shared-core/nv20_graph.c b/shared-core/nv20_graph.c index 81501ed7..a21fde71 100644 --- a/shared-core/nv20_graph.c +++ b/shared-core/nv20_graph.c @@ -432,19 +432,6 @@ static void nv30_31_graph_context_init(struct drm_device *dev, INSTANCE_WR(ctx, 0x385c/4, 0x3f800000); INSTANCE_WR(ctx, 0x3864/4, 0xbf800000); INSTANCE_WR(ctx, 0x386c/4, 0xbf800000); - - /* nv30gl stuff */ - for (i=0; i<8; i++) { - INSTANCE_WR(ctx, (0x4dfc/4)+i, 0x001c527d); - } - INSTANCE_WR(ctx, 0x4e3c/4, 0x001c527c); -/* these ones make dma fifo hang - INSTANCE_WR(ctx, 0x567c/4, 0x000a0000); - INSTANCE_WR(ctx, 0x0878/4, 0x01000000); - INSTANCE_WR(ctx, 0x02f4/4, 0x0001ffff); - - INSTANCE_WR(ctx, 0x0028/4, INSTANCE_RD(ctx, 0x0028/4) | 1); -*/ } static void nv34_graph_context_init(struct drm_device *dev, diff --git a/shared-core/via_drv.c b/shared-core/via_drv.c index 9f099555..6528a7c1 100644 --- a/shared-core/via_drv.c +++ b/shared-core/via_drv.c @@ -74,7 +74,7 @@ static struct drm_bo_driver via_bo_driver = { .fence_type = via_fence_types, .invalidate_caches = via_invalidate_caches, .init_mem_type = via_init_mem_type, - .evict_mask = via_evict_mask, + .evict_flags = via_evict_flags, .move = NULL, }; #endif diff --git a/shared-core/via_drv.h b/shared-core/via_drv.h index d6da8bd9..39aedb1d 100644 --- a/shared-core/via_drv.h +++ b/shared-core/via_drv.h @@ -211,7 +211,7 @@ extern int via_fence_types(struct drm_buffer_object *bo, uint32_t *fclass, extern int via_invalidate_caches(struct drm_device *dev, uint64_t buffer_flags); extern int via_init_mem_type(struct drm_device *dev, uint32_t type, struct drm_mem_type_manager *man); -extern uint32_t via_evict_mask(struct drm_buffer_object *bo); +extern uint64_t via_evict_flags(struct drm_buffer_object *bo); extern int via_move(struct drm_buffer_object *bo, int evict, int no_wait, struct drm_bo_mem_reg *new_mem); #endif |