Merge branch 'master' of git+ssh://git.freedesktop.org/git/mesa/drm into modesetting-101

main
Alan Hourihane 2007-12-13 10:41:23 +00:00
commit f62a300547
4 changed files with 76 additions and 16 deletions

View File

@ -925,7 +925,7 @@ int drm_bo_mem_space(struct drm_buffer_object *bo,
ret = drm_bo_mem_force_space(dev, mem, mem_type, no_wait); ret = drm_bo_mem_force_space(dev, mem, mem_type, no_wait);
if (ret == 0) { if (ret == 0 && mem->mm_node) {
mem->flags = cur_flags; mem->flags = cur_flags;
return 0; return 0;
} }

View File

@ -753,6 +753,7 @@ struct drm_fence_arg {
/* Don't place this buffer on the unfenced list.*/ /* Don't place this buffer on the unfenced list.*/
#define DRM_BO_HINT_DONT_FENCE 0x00000004 #define DRM_BO_HINT_DONT_FENCE 0x00000004
#define DRM_BO_HINT_WAIT_LAZY 0x00000008 #define DRM_BO_HINT_WAIT_LAZY 0x00000008
#define DRM_BO_HINT_PRESUMED_OFFSET 0x00000010
#define DRM_BO_INIT_MAGIC 0xfe769812 #define DRM_BO_INIT_MAGIC 0xfe769812
#define DRM_BO_INIT_MAJOR 1 #define DRM_BO_INIT_MAJOR 1
@ -769,6 +770,7 @@ struct drm_bo_info_req {
unsigned int desired_tile_stride; unsigned int desired_tile_stride;
unsigned int tile_info; unsigned int tile_info;
unsigned int pad64; unsigned int pad64;
uint64_t presumed_offset;
}; };
struct drm_bo_create_req { struct drm_bo_create_req {

View File

@ -681,7 +681,14 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
return 0; return 0;
} }
#if DRM_DEBUG_CODE
#define DRM_DEBUG_RELOCATION (drm_debug != 0)
#else
#define DRM_DEBUG_RELOCATION 0
#endif
#ifdef I915_HAVE_BUFFER #ifdef I915_HAVE_BUFFER
struct i915_relocatee_info { struct i915_relocatee_info {
struct drm_buffer_object *buf; struct drm_buffer_object *buf;
unsigned long offset; unsigned long offset;
@ -691,15 +698,20 @@ struct i915_relocatee_info {
int is_iomem; 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) unsigned num_buffers)
{ {
while (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, 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, struct i915_relocatee_info *relocatee,
uint32_t *reloc) uint32_t *reloc)
{ {
@ -713,11 +725,25 @@ int i915_apply_reloc(struct drm_file *file_priv, int num_buffers,
return -EINVAL; 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]; new_cmd_offset = reloc[0];
if (!relocatee->data_page || if (!relocatee->data_page ||
!drm_bo_same_page(relocatee->offset, new_cmd_offset)) { !drm_bo_same_page(relocatee->offset, new_cmd_offset)) {
drm_bo_kunmap(&relocatee->kmap); drm_bo_kunmap(&relocatee->kmap);
relocatee->offset = new_cmd_offset; 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, ret = drm_bo_kmap(relocatee->buf, new_cmd_offset >> PAGE_SHIFT,
1, &relocatee->kmap); 1, &relocatee->kmap);
if (ret) { if (ret) {
@ -730,12 +756,19 @@ int i915_apply_reloc(struct drm_file *file_priv, int num_buffers,
relocatee->page_offset = (relocatee->offset & PAGE_MASK); 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; index = (reloc[0] - relocatee->page_offset) >> 2;
/* add in validate */ /* add in validate */
val = val + reloc[1]; 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; relocatee->data_page[index] = val;
return 0; return 0;
} }
@ -744,7 +777,7 @@ int i915_process_relocs(struct drm_file *file_priv,
uint32_t buf_handle, uint32_t buf_handle,
uint32_t *reloc_buf_handle, uint32_t *reloc_buf_handle,
struct i915_relocatee_info *relocatee, struct i915_relocatee_info *relocatee,
struct drm_buffer_object **buffers, struct drm_i915_validate_buffer *buffers,
uint32_t num_buffers) uint32_t num_buffers)
{ {
struct drm_device *dev = file_priv->head->dev; struct drm_device *dev = file_priv->head->dev;
@ -830,12 +863,27 @@ out:
static int i915_exec_reloc(struct drm_file *file_priv, drm_handle_t buf_handle, static int i915_exec_reloc(struct drm_file *file_priv, drm_handle_t buf_handle,
drm_handle_t buf_reloc_handle, drm_handle_t buf_reloc_handle,
struct drm_buffer_object **buffers, struct drm_i915_validate_buffer *buffers,
uint32_t buf_count) uint32_t buf_count)
{ {
struct drm_device *dev = file_priv->head->dev; struct drm_device *dev = file_priv->head->dev;
struct i915_relocatee_info relocatee; struct i915_relocatee_info relocatee;
int ret = 0; 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)); memset(&relocatee, 0, sizeof(relocatee));
@ -869,7 +917,7 @@ out_err:
*/ */
int i915_validate_buffer_list(struct drm_file *file_priv, int i915_validate_buffer_list(struct drm_file *file_priv,
unsigned int fence_class, uint64_t data, unsigned int fence_class, uint64_t data,
struct drm_buffer_object **buffers, struct drm_i915_validate_buffer *buffers,
uint32_t *num_buffers) uint32_t *num_buffers)
{ {
struct drm_i915_op_arg arg; struct drm_i915_op_arg arg;
@ -889,7 +937,8 @@ int i915_validate_buffer_list(struct drm_file *file_priv,
goto out_err; 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))) { if (copy_from_user(&arg, (void __user *)(unsigned long)data, sizeof(arg))) {
ret = -EFAULT; ret = -EFAULT;
@ -899,7 +948,7 @@ int i915_validate_buffer_list(struct drm_file *file_priv,
if (arg.handled) { if (arg.handled) {
data = arg.next; data = arg.next;
mutex_lock(&dev->struct_mutex); 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); mutex_unlock(&dev->struct_mutex);
buf_count++; buf_count++;
continue; continue;
@ -930,13 +979,21 @@ int i915_validate_buffer_list(struct drm_file *file_priv,
req->bo_req.hint, req->bo_req.hint,
0, 0,
&rep.bo_info, &rep.bo_info,
&buffers[buf_count]); &buffers[buf_count].buffer);
if (rep.ret) { if (rep.ret) {
DRM_ERROR("error on handle validate %d\n", rep.ret); DRM_ERROR("error on handle validate %d\n", rep.ret);
goto out_err; 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; next = arg.next;
arg.handled = 1; arg.handled = 1;
@ -970,7 +1027,7 @@ static int i915_execbuffer(struct drm_device *dev, void *data,
struct drm_fence_arg *fence_arg = &exec_buf->fence_arg; struct drm_fence_arg *fence_arg = &exec_buf->fence_arg;
int num_buffers; int num_buffers;
int ret; int ret;
struct drm_buffer_object **buffers; struct drm_i915_validate_buffer *buffers;
struct drm_fence_object *fence; struct drm_fence_object *fence;
if (!dev_priv->allow_batchbuffer) { if (!dev_priv->allow_batchbuffer) {
@ -1005,7 +1062,7 @@ static int i915_execbuffer(struct drm_device *dev, void *data,
num_buffers = exec_buf->num_buffers; 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) { if (!buffers) {
drm_bo_read_unlock(&dev->bm.bm_lock); drm_bo_read_unlock(&dev->bm.bm_lock);
mutex_unlock(&dev_priv->cmdbuf_mutex); mutex_unlock(&dev_priv->cmdbuf_mutex);
@ -1023,7 +1080,7 @@ static int i915_execbuffer(struct drm_device *dev, void *data,
drm_agp_chipset_flush(dev); drm_agp_chipset_flush(dev);
/* submit buffer */ /* 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", DRM_DEBUG("i915 exec batchbuffer, start %x used %d cliprects %d\n",
batch->start, batch->used, batch->num_cliprects); batch->start, batch->used, batch->num_cliprects);

View File

@ -57,10 +57,11 @@
* 1.9: Usable page flipping and triple buffering * 1.9: Usable page flipping and triple buffering
* 1.10: Plane/pipe disentangling * 1.10: Plane/pipe disentangling
* 1.11: TTM superioctl * 1.11: TTM superioctl
* 1.12: TTM relocation optimization
*/ */
#define DRIVER_MAJOR 1 #define DRIVER_MAJOR 1
#if defined(I915_HAVE_FENCE) && defined(I915_HAVE_BUFFER) #if defined(I915_HAVE_FENCE) && defined(I915_HAVE_BUFFER)
#define DRIVER_MINOR 11 #define DRIVER_MINOR 12
#else #else
#define DRIVER_MINOR 6 #define DRIVER_MINOR 6
#endif #endif