diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-07-10 05:27:08 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-07-26 06:56:25 -0400 |
commit | e6994aeedcee4f71998d89d2c10c5baa419ebeac (patch) | |
tree | 8b298417e51e2fc2dd2e191b26d504f648ffd91b /drivers/gpu/drm/i915/i915_gem.c | |
parent | 42d6ab4839799b2f246748ce663d6b023f02bb73 (diff) |
drm/i915: Export ability of changing cache levels to userspace
By selecting the cache level (essentially whether or not the CPU snoops
any updates to the bo, and on more recent machines whether it resides
inside the CPU's last-level-cache) a userspace driver is able to then
manage all of its memory within buffer objects, if it so desires. This
enables the userspace driver to accelerate uploads and more importantly
downloads from the GPU and to able to mix CPU and GPU rendering/activity
efficiently.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
[danvet: Added code comment about where we plan to stuff platform
specific cacheing control bits in the ioctl struct.]
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 19bdc245a87a..c540321b42ba 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -3015,6 +3015,68 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, | |||
3015 | return 0; | 3015 | return 0; |
3016 | } | 3016 | } |
3017 | 3017 | ||
3018 | int i915_gem_get_cacheing_ioctl(struct drm_device *dev, void *data, | ||
3019 | struct drm_file *file) | ||
3020 | { | ||
3021 | struct drm_i915_gem_cacheing *args = data; | ||
3022 | struct drm_i915_gem_object *obj; | ||
3023 | int ret; | ||
3024 | |||
3025 | ret = i915_mutex_lock_interruptible(dev); | ||
3026 | if (ret) | ||
3027 | return ret; | ||
3028 | |||
3029 | obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); | ||
3030 | if (&obj->base == NULL) { | ||
3031 | ret = -ENOENT; | ||
3032 | goto unlock; | ||
3033 | } | ||
3034 | |||
3035 | args->cacheing = obj->cache_level != I915_CACHE_NONE; | ||
3036 | |||
3037 | drm_gem_object_unreference(&obj->base); | ||
3038 | unlock: | ||
3039 | mutex_unlock(&dev->struct_mutex); | ||
3040 | return ret; | ||
3041 | } | ||
3042 | |||
3043 | int i915_gem_set_cacheing_ioctl(struct drm_device *dev, void *data, | ||
3044 | struct drm_file *file) | ||
3045 | { | ||
3046 | struct drm_i915_gem_cacheing *args = data; | ||
3047 | struct drm_i915_gem_object *obj; | ||
3048 | enum i915_cache_level level; | ||
3049 | int ret; | ||
3050 | |||
3051 | ret = i915_mutex_lock_interruptible(dev); | ||
3052 | if (ret) | ||
3053 | return ret; | ||
3054 | |||
3055 | switch (args->cacheing) { | ||
3056 | case I915_CACHEING_NONE: | ||
3057 | level = I915_CACHE_NONE; | ||
3058 | break; | ||
3059 | case I915_CACHEING_CACHED: | ||
3060 | level = I915_CACHE_LLC; | ||
3061 | break; | ||
3062 | default: | ||
3063 | return -EINVAL; | ||
3064 | } | ||
3065 | |||
3066 | obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); | ||
3067 | if (&obj->base == NULL) { | ||
3068 | ret = -ENOENT; | ||
3069 | goto unlock; | ||
3070 | } | ||
3071 | |||
3072 | ret = i915_gem_object_set_cache_level(obj, level); | ||
3073 | |||
3074 | drm_gem_object_unreference(&obj->base); | ||
3075 | unlock: | ||
3076 | mutex_unlock(&dev->struct_mutex); | ||
3077 | return ret; | ||
3078 | } | ||
3079 | |||
3018 | /* | 3080 | /* |
3019 | * Prepare buffer for display plane (scanout, cursors, etc). | 3081 | * Prepare buffer for display plane (scanout, cursors, etc). |
3020 | * Can be called from an uninterruptible phase (modesetting) and allows | 3082 | * Can be called from an uninterruptible phase (modesetting) and allows |