diff options
| author | Dave Airlie <airlied@redhat.com> | 2011-02-07 12:16:14 +1000 | 
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2011-02-07 12:16:14 +1000 | 
| commit | ff72145badb834e8051719ea66e024784d000cb4 (patch) | |
| tree | 39dc5fc512e3e0836713de9defb91ea8b4033aa2 /drivers/gpu/drm/i915/i915_gem.c | |
| parent | 1f692a14cbfbeb11f9a9c16f25c8ecb8ab50d3d5 (diff) | |
| download | olio-linux-3.10-ff72145badb834e8051719ea66e024784d000cb4.tar.xz olio-linux-3.10-ff72145badb834e8051719ea66e024784d000cb4.zip  | |
drm: dumb scanout create/mmap for intel/radeon (v3)
This is just an idea that might or might not be a good idea,
it basically adds two ioctls to create a dumb and map a dumb buffer
suitable for scanout. The handle can be passed to the KMS ioctls to create
a framebuffer.
It looks to me like it would be useful in the following cases:
a) in development drivers - we can always provide a shadowfb fallback.
b) libkms users - we can clean up libkms a lot and avoid linking
to libdrm_*.
c) plymouth via libkms is a lot easier.
Userspace bits would be just calls + mmaps. We could probably
mark these handles somehow as not being suitable for acceleartion
so as top stop people who are dumber than dumb.
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem.c')
| -rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 103 | 
1 files changed, 73 insertions, 30 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index cf4f74c7c6f..bc7f06b8fbc 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -193,22 +193,20 @@ i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,  	return 0;  } -/** - * Creates a new mm object and returns a handle to it. - */ -int -i915_gem_create_ioctl(struct drm_device *dev, void *data, -		      struct drm_file *file) +static int +i915_gem_create(struct drm_file *file, +		struct drm_device *dev, +		uint64_t size, +		uint32_t *handle_p)  { -	struct drm_i915_gem_create *args = data;  	struct drm_i915_gem_object *obj;  	int ret;  	u32 handle; -	args->size = roundup(args->size, PAGE_SIZE); +	size = roundup(size, PAGE_SIZE);  	/* Allocate the new object */ -	obj = i915_gem_alloc_object(dev, args->size); +	obj = i915_gem_alloc_object(dev, size);  	if (obj == NULL)  		return -ENOMEM; @@ -224,10 +222,41 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data,  	drm_gem_object_unreference(&obj->base);  	trace_i915_gem_object_create(obj); -	args->handle = handle; +	*handle_p = handle;  	return 0;  } +int +i915_gem_dumb_create(struct drm_file *file, +		     struct drm_device *dev, +		     struct drm_mode_create_dumb *args) +{ +	/* have to work out size/pitch and return them */ +	args->pitch = ALIGN(args->width & ((args->bpp + 1) / 8), 64); +	args->size = args->pitch * args->height; +	return i915_gem_create(file, dev, +			       args->size, &args->handle); +} + +int i915_gem_dumb_destroy(struct drm_file *file, +			  struct drm_device *dev, +			  uint32_t handle) +{ +	return drm_gem_handle_delete(file, handle); +} + +/** + * Creates a new mm object and returns a handle to it. + */ +int +i915_gem_create_ioctl(struct drm_device *dev, void *data, +		      struct drm_file *file) +{ +	struct drm_i915_gem_create *args = data; +	return i915_gem_create(file, dev, +			       args->size, &args->handle); +} +  static int i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_object *obj)  {  	drm_i915_private_t *dev_priv = obj->base.dev->dev_private; @@ -1425,27 +1454,13 @@ i915_gem_get_unfenced_gtt_alignment(struct drm_i915_gem_object *obj)  	return tile_height * obj->stride * 2;  } -/** - * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing - * @dev: DRM device - * @data: GTT mapping ioctl data - * @file: GEM object info - * - * Simply returns the fake offset to userspace so it can mmap it. - * The mmap call will end up in drm_gem_mmap(), which will set things - * up so we can get faults in the handler above. - * - * The fault handler will take care of binding the object into the GTT - * (since it may have been evicted to make room for something), allocating - * a fence register, and mapping the appropriate aperture address into - * userspace. - */  int -i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, -			struct drm_file *file) +i915_gem_mmap_gtt(struct drm_file *file, +		  struct drm_device *dev, +		  uint32_t handle, +		  uint64_t *offset)  {  	struct drm_i915_private *dev_priv = dev->dev_private; -	struct drm_i915_gem_mmap_gtt *args = data;  	struct drm_i915_gem_object *obj;  	int ret; @@ -1456,7 +1471,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,  	if (ret)  		return ret; -	obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); +	obj = to_intel_bo(drm_gem_object_lookup(dev, file, handle));  	if (obj == NULL) {  		ret = -ENOENT;  		goto unlock; @@ -1479,7 +1494,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,  			goto out;  	} -	args->offset = (u64)obj->base.map_list.hash.key << PAGE_SHIFT; +	*offset = (u64)obj->base.map_list.hash.key << PAGE_SHIFT;  out:  	drm_gem_object_unreference(&obj->base); @@ -1488,6 +1503,34 @@ unlock:  	return ret;  } +/** + * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing + * @dev: DRM device + * @data: GTT mapping ioctl data + * @file: GEM object info + * + * Simply returns the fake offset to userspace so it can mmap it. + * The mmap call will end up in drm_gem_mmap(), which will set things + * up so we can get faults in the handler above. + * + * The fault handler will take care of binding the object into the GTT + * (since it may have been evicted to make room for something), allocating + * a fence register, and mapping the appropriate aperture address into + * userspace. + */ +int +i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, +			struct drm_file *file) +{ +	struct drm_i915_gem_mmap_gtt *args = data; + +	if (!(dev->driver->driver_features & DRIVER_GEM)) +		return -ENODEV; + +	return i915_gem_mmap_gtt(file, dev, args->handle, &args->offset); +} + +  static int  i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj,  			      gfp_t gfpmask)  |