summaryrefslogtreecommitdiff
path: root/linux-core
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2008-05-05 11:27:06 -0700
committerKeith Packard <keithp@keithp.com>2008-05-05 11:27:06 -0700
commit4511e6cd80b4c47a142db48727753da8d0898857 (patch)
tree9f1ba4b2ac2fcb193b182b0b4e0748bc1e0e7519 /linux-core
parentb6f173c4300e90be9bdd3b24003b800afd8819c5 (diff)
Correct execbuffer offset. Add memory barrier and chipset flush.
Diffstat (limited to 'linux-core')
-rw-r--r--linux-core/i915_gem.c47
1 files changed, 32 insertions, 15 deletions
diff --git a/linux-core/i915_gem.c b/linux-core/i915_gem.c
index 95f6a267..7e4e8d5f 100644
--- a/linux-core/i915_gem.c
+++ b/linux-core/i915_gem.c
@@ -192,6 +192,7 @@ i915_gem_reloc_and_validate_object(struct drm_gem_object *obj,
if (obj_priv->gtt_space == NULL)
return -ENOMEM;
}
+ entry->buffer_offset = obj_priv->gtt_offset;
relocs = (struct drm_i915_gem_relocation_entry __user *) (uintptr_t) entry->relocs_ptr;
/* Apply the relocations, using the GTT aperture to avoid cache
@@ -306,21 +307,32 @@ i915_gem_sync_and_evict(struct drm_device *dev)
static int
i915_dispatch_gem_execbuffer (struct drm_device * dev,
- struct drm_i915_gem_execbuffer * exec)
+ struct drm_i915_gem_execbuffer * exec,
+ uint64_t exec_offset)
{
drm_i915_private_t *dev_priv = dev->dev_private;
struct drm_clip_rect __user *boxes = (struct drm_clip_rect __user *) (uintptr_t) exec->cliprects_ptr;
int nbox = exec->num_cliprects;
int i = 0, count;
+ uint32_t exec_start, exec_len;
RING_LOCALS;
- if ((exec->batch_start_offset | exec->batch_len) & 0x7) {
+ exec_start = (uint32_t) exec_offset + exec->batch_start_offset;
+ exec_len = (uint32_t) exec->batch_len;
+
+ if ((exec_start | exec_len) & 0x7) {
DRM_ERROR("alignment\n");
return -EINVAL;
}
i915_kernel_lost_context(dev);
+ DRM_INFO ("execbuffer at %x+%d len %d\n",
+ (uint32_t) exec_offset, exec->batch_start_offset, exec_len);
+
+ if (!exec_start)
+ return -EINVAL;
+
count = nbox ? nbox : 1;
for (i = 0; i < count; i++) {
@@ -335,18 +347,18 @@ i915_dispatch_gem_execbuffer (struct drm_device * dev,
BEGIN_LP_RING(2);
if (IS_I965G(dev)) {
OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965);
- OUT_RING(exec->batch_start_offset);
+ OUT_RING(exec_start);
} else {
OUT_RING(MI_BATCH_BUFFER_START | (2 << 6));
- OUT_RING(exec->batch_start_offset | MI_BATCH_NON_SECURE);
+ OUT_RING(exec_start | MI_BATCH_NON_SECURE);
}
ADVANCE_LP_RING();
} else {
BEGIN_LP_RING(4);
OUT_RING(MI_BATCH_BUFFER);
- OUT_RING(exec->batch_start_offset | MI_BATCH_NON_SECURE);
- OUT_RING(exec->batch_start_offset + exec->batch_len - 4);
+ OUT_RING(exec_start | MI_BATCH_NON_SECURE);
+ OUT_RING(exec_start + exec_len - 4);
OUT_RING(0);
ADVANCE_LP_RING();
}
@@ -364,6 +376,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
struct drm_i915_gem_validate_entry *validate_list;
struct drm_gem_object **object_list;
int ret, i;
+ uint64_t exec_offset;
LOCK_TEST_WITH_RETURN(dev, file_priv);
@@ -410,12 +423,22 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
goto err;
}
- i915_gem_reloc_and_validate_object(object_list[i], file_priv,
- &validate_list[i]);
+ ret = i915_gem_reloc_and_validate_object(object_list[i], file_priv,
+ &validate_list[i]);
+ if (ret) {
+ DRM_ERROR ("reloc and validate failed %d\n", ret);
+ goto err;
+ }
}
+ exec_offset = validate_list[args->buffer_count - 1].buffer_offset;
+
+ /* make sure all previous memory operations have passed */
+ DRM_MEMORYBARRIER();
+ drm_agp_chipset_flush(dev);
+
/* Exec the batchbuffer */
- ret = i915_dispatch_gem_execbuffer (dev, args);
+ ret = i915_dispatch_gem_execbuffer (dev, args, exec_offset);
if (ret)
{
DRM_ERROR ("dispatch failed %d\n", ret);
@@ -423,12 +446,6 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
}
/* Copy the new buffer offsets back to the user's validate list. */
- for (i = 0; i < args->buffer_count; i++) {
- struct drm_i915_gem_object *obj_priv =
- object_list[i]->driver_private;
-
- validate_list[i].buffer_offset = obj_priv->gtt_offset;
- }
ret = copy_to_user((struct drm_i915_relocation_entry __user*)(uintptr_t)
args->buffers_ptr,
validate_list,