aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_gem.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2011-02-06 21:16:14 -0500
committerDave Airlie <airlied@redhat.com>2011-02-06 21:16:14 -0500
commitff72145badb834e8051719ea66e024784d000cb4 (patch)
tree39dc5fc512e3e0836713de9defb91ea8b4033aa2 /drivers/gpu/drm/i915/i915_gem.c
parent1f692a14cbfbeb11f9a9c16f25c8ecb8ab50d3d5 (diff)
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.c103
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 cf4f74c7c6fb..bc7f06b8fbca 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,
193 return 0; 193 return 0;
194} 194}
195 195
196/** 196static int
197 * Creates a new mm object and returns a handle to it. 197i915_gem_create(struct drm_file *file,
198 */ 198 struct drm_device *dev,
199int 199 uint64_t size,
200i915_gem_create_ioctl(struct drm_device *dev, void *data, 200 uint32_t *handle_p)
201 struct drm_file *file)
202{ 201{
203 struct drm_i915_gem_create *args = data;
204 struct drm_i915_gem_object *obj; 202 struct drm_i915_gem_object *obj;
205 int ret; 203 int ret;
206 u32 handle; 204 u32 handle;
207 205
208 args->size = roundup(args->size, PAGE_SIZE); 206 size = roundup(size, PAGE_SIZE);
209 207
210 /* Allocate the new object */ 208 /* Allocate the new object */
211 obj = i915_gem_alloc_object(dev, args->size); 209 obj = i915_gem_alloc_object(dev, size);
212 if (obj == NULL) 210 if (obj == NULL)
213 return -ENOMEM; 211 return -ENOMEM;
214 212
@@ -224,10 +222,41 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data,
224 drm_gem_object_unreference(&obj->base); 222 drm_gem_object_unreference(&obj->base);
225 trace_i915_gem_object_create(obj); 223 trace_i915_gem_object_create(obj);
226 224
227 args->handle = handle; 225 *handle_p = handle;
228 return 0; 226 return 0;
229} 227}
230 228
229int
230i915_gem_dumb_create(struct drm_file *file,
231 struct drm_device *dev,
232 struct drm_mode_create_dumb *args)
233{
234 /* have to work out size/pitch and return them */
235 args->pitch = ALIGN(args->width & ((args->bpp + 1) / 8), 64);
236 args->size = args->pitch * args->height;
237 return i915_gem_create(file, dev,
238 args->size, &args->handle);
239}
240
241int i915_gem_dumb_destroy(struct drm_file *file,
242 struct drm_device *dev,
243 uint32_t handle)
244{
245 return drm_gem_handle_delete(file, handle);
246}
247
248/**
249 * Creates a new mm object and returns a handle to it.
250 */
251int
252i915_gem_create_ioctl(struct drm_device *dev, void *data,
253 struct drm_file *file)
254{
255 struct drm_i915_gem_create *args = data;
256 return i915_gem_create(file, dev,
257 args->size, &args->handle);
258}
259
231static int i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_object *obj) 260static int i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_object *obj)
232{ 261{
233 drm_i915_private_t *dev_priv = obj->base.dev->dev_private; 262 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)
1425 return tile_height * obj->stride * 2; 1454 return tile_height * obj->stride * 2;
1426} 1455}
1427 1456
1428/**
1429 * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing
1430 * @dev: DRM device
1431 * @data: GTT mapping ioctl data
1432 * @file: GEM object info
1433 *
1434 * Simply returns the fake offset to userspace so it can mmap it.
1435 * The mmap call will end up in drm_gem_mmap(), which will set things
1436 * up so we can get faults in the handler above.
1437 *
1438 * The fault handler will take care of binding the object into the GTT
1439 * (since it may have been evicted to make room for something), allocating
1440 * a fence register, and mapping the appropriate aperture address into
1441 * userspace.
1442 */
1443int 1457int
1444i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, 1458i915_gem_mmap_gtt(struct drm_file *file,
1445 struct drm_file *file) 1459 struct drm_device *dev,
1460 uint32_t handle,
1461 uint64_t *offset)
1446{ 1462{
1447 struct drm_i915_private *dev_priv = dev->dev_private; 1463 struct drm_i915_private *dev_priv = dev->dev_private;
1448 struct drm_i915_gem_mmap_gtt *args = data;
1449 struct drm_i915_gem_object *obj; 1464 struct drm_i915_gem_object *obj;
1450 int ret; 1465 int ret;
1451 1466
@@ -1456,7 +1471,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
1456 if (ret) 1471 if (ret)
1457 return ret; 1472 return ret;
1458 1473
1459 obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); 1474 obj = to_intel_bo(drm_gem_object_lookup(dev, file, handle));
1460 if (obj == NULL) { 1475 if (obj == NULL) {
1461 ret = -ENOENT; 1476 ret = -ENOENT;
1462 goto unlock; 1477 goto unlock;
@@ -1479,7 +1494,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
1479 goto out; 1494 goto out;
1480 } 1495 }
1481 1496
1482 args->offset = (u64)obj->base.map_list.hash.key << PAGE_SHIFT; 1497 *offset = (u64)obj->base.map_list.hash.key << PAGE_SHIFT;
1483 1498
1484out: 1499out:
1485 drm_gem_object_unreference(&obj->base); 1500 drm_gem_object_unreference(&obj->base);
@@ -1488,6 +1503,34 @@ unlock:
1488 return ret; 1503 return ret;
1489} 1504}
1490 1505
1506/**
1507 * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing
1508 * @dev: DRM device
1509 * @data: GTT mapping ioctl data
1510 * @file: GEM object info
1511 *
1512 * Simply returns the fake offset to userspace so it can mmap it.
1513 * The mmap call will end up in drm_gem_mmap(), which will set things
1514 * up so we can get faults in the handler above.
1515 *
1516 * The fault handler will take care of binding the object into the GTT
1517 * (since it may have been evicted to make room for something), allocating
1518 * a fence register, and mapping the appropriate aperture address into
1519 * userspace.
1520 */
1521int
1522i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
1523 struct drm_file *file)
1524{
1525 struct drm_i915_gem_mmap_gtt *args = data;
1526
1527 if (!(dev->driver->driver_features & DRIVER_GEM))
1528 return -ENODEV;
1529
1530 return i915_gem_mmap_gtt(file, dev, args->handle, &args->offset);
1531}
1532
1533
1491static int 1534static int
1492i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj, 1535i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj,
1493 gfp_t gfpmask) 1536 gfp_t gfpmask)