aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2008-05-22 11:34:56 -0700
committerEric Anholt <eric@anholt.net>2008-05-22 22:00:21 -0700
commit44ed693ca6f8d19acb39174c6efada070652a027 (patch)
tree03faad9335216dfcf9b270a3cc6b00e4217183a7
parent71b09a5f75c6063a592f7be07465761519839bcd (diff)
[gem] Use CPU domain for new or pageable objects
Newly allocated objects need to be in the CPU domain as they've just been cleared by the CPU. Also, unmapping objects from the GTT needs to put them into the CPU domain, both to flush rendering as well as to ensure that any paging action gets flushed before we remap to the GTT.
-rw-r--r--linux-core/drm_gem.c8
-rw-r--r--linux-core/i915_gem.c16
2 files changed, 20 insertions, 4 deletions
diff --git a/linux-core/drm_gem.c b/linux-core/drm_gem.c
index a8253bc5..fb175d7d 100644
--- a/linux-core/drm_gem.c
+++ b/linux-core/drm_gem.c
@@ -100,6 +100,14 @@ drm_gem_object_alloc(struct drm_device *dev, size_t size)
kref_init(&obj->handlecount);
obj->size = size;
+ /*
+ * We've just allocated pages from the kernel,
+ * so they've just been written by the CPU with
+ * zeros. They'll need to be clflushed before we
+ * use them with the GPU.
+ */
+ obj->write_domain = DRM_GEM_DOMAIN_CPU;
+ obj->read_domains = DRM_GEM_DOMAIN_CPU;
if (dev->driver->gem_init_object != NULL &&
dev->driver->gem_init_object(obj) != 0) {
fput(obj->filp);
diff --git a/linux-core/i915_gem.c b/linux-core/i915_gem.c
index 3214707f..60a8fa58 100644
--- a/linux-core/i915_gem.c
+++ b/linux-core/i915_gem.c
@@ -35,6 +35,11 @@
#define WATCH_LRU 0
#define WATCH_RELOC 0
+static void
+i915_gem_object_set_domain(struct drm_gem_object *obj,
+ uint32_t read_domains,
+ uint32_t write_domain);
+
int
i915_gem_init_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
@@ -456,11 +461,14 @@ i915_gem_object_unbind(struct drm_gem_object *obj)
if (obj_priv->gtt_space == NULL)
return;
- /* Ignore the return value of wait_rendering. If we're here but
- * a wait_rendering hasn't completed, we're in the freeing process,
- * and we want the buffer to go away even if the command queue is hung.
+ /* Move the object to the CPU domain to ensure that
+ * any possible CPU writes while it's not in the GTT
+ * are flushed when we go to remap it. This will
+ * also ensure that all pending GPU writes are finished
+ * before we unbind.
*/
- (void)i915_gem_object_wait_rendering(obj);
+ i915_gem_object_set_domain (obj, DRM_GEM_DOMAIN_CPU,
+ DRM_GEM_DOMAIN_CPU);
if (obj_priv->agp_mem != NULL) {
drm_unbind_agp(obj_priv->agp_mem);