summaryrefslogtreecommitdiff
path: root/linux-core/drm_gem.c
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2008-05-11 00:10:16 -0700
committerKeith Packard <keithp@keithp.com>2008-05-11 00:10:16 -0700
commitff39db099b9ca6c8feee68101a2269345b7bd798 (patch)
treef991f1bdb260d90c60823f1427f93f4c423c64c4 /linux-core/drm_gem.c
parent1b0bf301431e76712de1ee43681bc818383b2e56 (diff)
[GEM] Make pread/pwrite manage memory domains. No luck with movnti though.
pread and pwrite must update the memory domains to ensure consistency with the GPU. At some point, it should be possible to avoid clflush through this path, but that isn't working for me.
Diffstat (limited to 'linux-core/drm_gem.c')
-rw-r--r--linux-core/drm_gem.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/linux-core/drm_gem.c b/linux-core/drm_gem.c
index 6c462921..14cf7e47 100644
--- a/linux-core/drm_gem.c
+++ b/linux-core/drm_gem.c
@@ -266,6 +266,7 @@ drm_gem_pread_ioctl(struct drm_device *dev, void *data,
struct drm_gem_object *obj;
ssize_t read;
loff_t offset;
+ int ret;
if (!(dev->driver->driver_features & DRIVER_GEM))
return -ENODEV;
@@ -274,6 +275,15 @@ drm_gem_pread_ioctl(struct drm_device *dev, void *data,
if (obj == NULL)
return -EINVAL;
+ if (dev->driver->gem_set_domain) {
+ ret = dev->driver->gem_set_domain (obj,
+ DRM_GEM_DOMAIN_CPU,
+ 0);
+ if (ret) {
+ drm_gem_object_unreference(obj);
+ return ret;
+ }
+ }
offset = args->offset;
read = vfs_read(obj->filp, (char __user *)(uintptr_t)args->data_ptr,
@@ -343,6 +353,7 @@ drm_gem_pwrite_ioctl(struct drm_device *dev, void *data,
struct drm_gem_object *obj;
ssize_t written;
loff_t offset;
+ int ret;
if (!(dev->driver->driver_features & DRIVER_GEM))
return -ENODEV;
@@ -351,11 +362,21 @@ drm_gem_pwrite_ioctl(struct drm_device *dev, void *data,
if (obj == NULL)
return -EINVAL;
+ if (dev->driver->gem_set_domain) {
+ ret = dev->driver->gem_set_domain (obj,
+ DRM_GEM_DOMAIN_CPU,
+ 0);
+ if (ret) {
+ drm_gem_object_unreference(obj);
+ return ret;
+ }
+ }
offset = args->offset;
written = vfs_write(obj->filp,
(char __user *)(uintptr_t) args->data_ptr,
args->size, &offset);
+
if (written != args->size) {
drm_gem_object_unreference(obj);
if (written < 0)
@@ -364,6 +385,11 @@ drm_gem_pwrite_ioctl(struct drm_device *dev, void *data,
return -EINVAL;
}
+ if (dev->driver->gem_flush_pwrite)
+ dev->driver->gem_flush_pwrite(obj,
+ args->offset,
+ args->size);
+
drm_gem_object_unreference(obj);
return 0;