diff options
author | Dave Airlie <airlied@redhat.com> | 2011-02-06 21:16:14 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2011-02-06 21:16:14 -0500 |
commit | ff72145badb834e8051719ea66e024784d000cb4 (patch) | |
tree | 39dc5fc512e3e0836713de9defb91ea8b4033aa2 /drivers/gpu/drm/i915/i915_gem.c | |
parent | 1f692a14cbfbeb11f9a9c16f25c8ecb8ab50d3d5 (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.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 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 | /** | 196 | static int |
197 | * Creates a new mm object and returns a handle to it. | 197 | i915_gem_create(struct drm_file *file, |
198 | */ | 198 | struct drm_device *dev, |
199 | int | 199 | uint64_t size, |
200 | i915_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 | ||
229 | int | ||
230 | i915_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 | |||
241 | int 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 | */ | ||
251 | int | ||
252 | i915_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 | |||
231 | static int i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_object *obj) | 260 | static 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 | */ | ||
1443 | int | 1457 | int |
1444 | i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, | 1458 | i915_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 | ||
1484 | out: | 1499 | out: |
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 | */ | ||
1521 | int | ||
1522 | i915_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 | |||
1491 | static int | 1534 | static int |
1492 | i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj, | 1535 | i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj, |
1493 | gfp_t gfpmask) | 1536 | gfp_t gfpmask) |