From 3eccc1dc3dc3547a8d4d4dff02708a19a918a376 Mon Sep 17 00:00:00 2001 From: "Sergey Semyonov (Serge)" Date: Sun, 17 Nov 2013 06:47:10 +0000 Subject: [PATCH] i915: Mesa-9.2 ready git-svn-id: svn://kolibrios.org@4246 a494cfbc-eb01-0410-851d-a64ba20cac60 --- drivers/video/drm/drm_gem.c | 3 +- drivers/video/drm/i915/i915_dma.c | 16 ++- drivers/video/drm/i915/i915_gem.c | 79 +++++++++++-- drivers/video/drm/i915/i915_gem_context.c | 10 +- drivers/video/drm/i915/i915_gem_execbuffer.c | 111 ++++++++++++++++++- drivers/video/drm/i915/i915_gem_tiling.c | 20 +--- drivers/video/drm/i915/main.c | 108 +++++++++++++----- drivers/video/drm/i915/utils.c | 5 +- 8 files changed, 274 insertions(+), 78 deletions(-) diff --git a/drivers/video/drm/drm_gem.c b/drivers/video/drm/drm_gem.c index 82a93b8371..78264fcf1f 100644 --- a/drivers/video/drm/drm_gem.c +++ b/drivers/video/drm/drm_gem.c @@ -484,8 +484,6 @@ drm_gem_close_ioctl(struct drm_device *dev, void *data, * Note that the name does not hold a reference; when the object * is freed, the name goes away. */ - -#if 0 int drm_gem_flink_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) @@ -572,6 +570,7 @@ drm_gem_open_ioctl(struct drm_device *dev, void *data, return 0; } +#if 0 /** * Called at device open time, sets up the structure for handling refcounting * of mm objects. diff --git a/drivers/video/drm/i915/i915_dma.c b/drivers/video/drm/i915/i915_dma.c index a32abe14ed..b5f7e323a5 100644 --- a/drivers/video/drm/i915/i915_dma.c +++ b/drivers/video/drm/i915/i915_dma.c @@ -377,6 +377,7 @@ static int i915_emit_cmds(struct drm_device * dev, int *buffer, int dwords) return 0; } +#endif int i915_emit_box(struct drm_device *dev, @@ -419,6 +420,7 @@ i915_emit_box(struct drm_device *dev, return 0; } +#if 0 /* XXX: Emitting the counter should really be moved to part of the IRQ * emit. For now, do it in both places: */ @@ -913,7 +915,7 @@ static int i915_flip_bufs(struct drm_device *dev, void *data, } #endif -static int i915_getparam(struct drm_device *dev, void *data, +int i915_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv) { drm_i915_private_t *dev_priv = dev->dev_private; @@ -960,6 +962,9 @@ static int i915_getparam(struct drm_device *dev, void *data, case I915_PARAM_HAS_BLT: value = intel_ring_initialized(&dev_priv->ring[BCS]); break; + case I915_PARAM_HAS_VEBOX: + value = intel_ring_initialized(&dev_priv->ring[VECS]); + break; case I915_PARAM_HAS_RELAXED_FENCING: value = 1; break; @@ -978,6 +983,9 @@ static int i915_getparam(struct drm_device *dev, void *data, case I915_PARAM_HAS_LLC: value = HAS_LLC(dev); break; + case I915_PARAM_HAS_WT: + value = HAS_WT(dev); + break; case I915_PARAM_HAS_ALIASING_PPGTT: value = dev_priv->mm.aliasing_ppgtt ? 1 : 0; break; @@ -1000,7 +1008,7 @@ static int i915_getparam(struct drm_device *dev, void *data, value = 1; break; case I915_PARAM_HAS_EXEC_HANDLE_LUT: - value = 1; + value = 0; //1; break; default: DRM_DEBUG("Unknown parameter %d\n", param->param); @@ -1692,7 +1700,3 @@ int i915_driver_device_is_agp(struct drm_device * dev) #endif -int gem_getparam(struct drm_device *dev, void *data) -{ - return i915_getparam(dev, data, NULL); -}; diff --git a/drivers/video/drm/i915/i915_gem.c b/drivers/video/drm/i915/i915_gem.c index d63b91ec36..090db4d74e 100644 --- a/drivers/video/drm/i915/i915_gem.c +++ b/drivers/video/drm/i915/i915_gem.c @@ -1321,8 +1321,6 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data, if (obj == NULL) return -ENOENT; - //dbgprintf("%s offset %lld size %lld\n", -// __FUNCTION__, args->offset, args->size); /* prime objects have no backing filp to GEM mmap * pages from. */ @@ -2330,17 +2328,74 @@ i915_gem_object_flush_active(struct drm_i915_gem_object *obj) * function completes. A similar but shorter * race condition exists in the busy * ioctl */ +int +i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + struct drm_i915_gem_wait *args = data; + struct drm_i915_gem_object *obj; + struct intel_ring_buffer *ring = NULL; + struct timespec timeout_stack, *timeout = NULL; + unsigned reset_counter; + u32 seqno = 0; + int ret = 0; + if (args->timeout_ns >= 0) { + timeout_stack = ns_to_timespec(args->timeout_ns); + timeout = &timeout_stack; + } + ret = i915_mutex_lock_interruptible(dev); + if (ret) + return ret; + if(args->bo_handle == -2) + { + obj = get_fb_obj(); + drm_gem_object_reference(&obj->base); + } + else + obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->bo_handle)); + if (&obj->base == NULL) { + mutex_unlock(&dev->struct_mutex); + return -ENOENT; + } + /* Need to make sure the object gets inactive eventually. */ + ret = i915_gem_object_flush_active(obj); + if (ret) + goto out; + if (obj->active) { + seqno = obj->last_read_seqno; + ring = obj->ring; + } + if (seqno == 0) + goto out; + /* Do this after OLR check to make sure we make forward progress polling + * on this IOCTL with a 0 timeout (like busy ioctl) + */ + if (!args->timeout_ns) { + ret = -ETIME; + goto out; + } + drm_gem_object_unreference(&obj->base); + reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter); + mutex_unlock(&dev->struct_mutex); + ret = __wait_seqno(ring, seqno, reset_counter, true, timeout); + if (timeout) + args->timeout_ns = timespec_to_ns(timeout); + return ret; - +out: + drm_gem_object_unreference(&obj->base); + mutex_unlock(&dev->struct_mutex); + return ret; +} /** * i915_gem_object_sync - sync an object to a ring. @@ -3613,6 +3668,9 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj, if (WARN_ON(obj->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT)) return -EBUSY; +// if( obj == get_fb_obj()) +// return 0; + WARN_ON(map_and_fenceable && !i915_is_ggtt(vm)); vma = i915_gem_obj_to_vma(obj, vm); @@ -3720,8 +3778,6 @@ unlock: return ret; } -#if 0 - int i915_gem_unpin_ioctl(struct drm_device *dev, void *data, struct drm_file *file) @@ -3734,6 +3790,12 @@ i915_gem_unpin_ioctl(struct drm_device *dev, void *data, if (ret) return ret; + if(args->handle == -2) + { + obj = get_fb_obj(); + drm_gem_object_reference(&obj->base); + } + else obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); if (&obj->base == NULL) { ret = -ENOENT; @@ -3759,8 +3821,6 @@ unlock: return ret; } -#endif - int i915_gem_busy_ioctl(struct drm_device *dev, void *data, struct drm_file *file) @@ -3894,10 +3954,7 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, obj = i915_gem_object_alloc(dev); if (obj == NULL) - { - FAIL(); return NULL; - }; if (drm_gem_object_init(dev, &obj->base, size) != 0) { i915_gem_object_free(obj); @@ -4215,8 +4272,6 @@ i915_gem_init_hw(struct drm_device *dev) return 0; } -#define LFB_SIZE 0xC00000 - int i915_gem_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; diff --git a/drivers/video/drm/i915/i915_gem_context.c b/drivers/video/drm/i915/i915_gem_context.c index 20afdae810..97533b3130 100644 --- a/drivers/video/drm/i915/i915_gem_context.c +++ b/drivers/video/drm/i915/i915_gem_context.c @@ -289,6 +289,8 @@ void i915_gem_context_fini(struct drm_device *dev) * to default context. So we need to unreference the base object once * to offset the do_switch part, so that i915_gem_context_unreference() * can then free the base object correctly. */ + drm_gem_object_unreference(&dctx->obj->base); + i915_gem_context_unreference(dctx); } static int context_idr_cleanup(int id, void *p, void *data) @@ -307,7 +309,7 @@ void i915_gem_context_close(struct drm_device *dev, struct drm_file *file) struct drm_i915_file_private *file_priv = file->driver_priv; mutex_lock(&dev->struct_mutex); -// idr_for_each(&file_priv->context_idr, context_idr_cleanup, NULL); + idr_for_each(&file_priv->context_idr, context_idr_cleanup, NULL); idr_destroy(&file_priv->context_idr); mutex_unlock(&dev->struct_mutex); } @@ -493,7 +495,6 @@ int i915_switch_context(struct intel_ring_buffer *ring, return do_switch(to); } -#if 0 int i915_gem_context_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file) { @@ -545,11 +546,10 @@ int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data, return -ENOENT; } - + idr_remove(&ctx->file_priv->context_idr, ctx->id); + i915_gem_context_unreference(ctx); mutex_unlock(&dev->struct_mutex); DRM_DEBUG_DRIVER("HW context %d destroyed\n", args->ctx_id); return 0; } - -#endif diff --git a/drivers/video/drm/i915/i915_gem_execbuffer.c b/drivers/video/drm/i915/i915_gem_execbuffer.c index 6589ef20a3..efbd1213ce 100644 --- a/drivers/video/drm/i915/i915_gem_execbuffer.c +++ b/drivers/video/drm/i915/i915_gem_execbuffer.c @@ -138,6 +138,10 @@ eb_lookup_objects(struct eb_objects *eb, list_add_tail(&obj->exec_list, &eb->objects); obj->exec_entry = &exec[i]; + + if(exec[i].handle == -2) + continue; + if (eb->and < 0) { eb->lut[i] = obj; } else { @@ -155,6 +159,10 @@ eb_lookup_objects(struct eb_objects *eb, static struct drm_i915_gem_object * eb_get_object(struct eb_objects *eb, unsigned long handle) { + + if(handle == -2) + return get_fb_obj(); + if (eb->and < 0) { if (handle >= -eb->and) return NULL; @@ -569,6 +577,8 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, obj->tiling_mode != I915_TILING_NONE; need_mappable = need_fence || need_reloc_mappable(obj); + WARN_ON((need_mappable || need_fence) && + !i915_is_ggtt(vm)); if ((entry->alignment && obj_offset & (entry->alignment - 1)) || @@ -1099,7 +1109,18 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, args->batch_start_offset; exec_len = args->batch_len; if (cliprects) { + for (i = 0; i < args->num_cliprects; i++) { + ret = i915_emit_box(dev, &cliprects[i], + args->DR1, args->DR4); + if (ret) + goto err; + ret = ring->dispatch_execbuffer(ring, + exec_start, exec_len, + flags); + if (ret) + goto err; + } } else { ret = ring->dispatch_execbuffer(ring, exec_start, exec_len, @@ -1123,7 +1144,94 @@ pre_mutex_err: return ret; } +#if 0 +/* + * Legacy execbuffer just creates an exec2 list from the original exec object + * list array and passes it to the real function. + */ +int +i915_gem_execbuffer(struct drm_device *dev, void *data, + struct drm_file *file) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_gem_execbuffer *args = data; + struct drm_i915_gem_execbuffer2 exec2; + struct drm_i915_gem_exec_object *exec_list = NULL; + struct drm_i915_gem_exec_object2 *exec2_list = NULL; + int ret, i; + if (args->buffer_count < 1) { + DRM_DEBUG("execbuf with %d buffers\n", args->buffer_count); + return -EINVAL; + } + + /* Copy in the exec list from userland */ + exec_list = drm_malloc_ab(sizeof(*exec_list), args->buffer_count); + exec2_list = drm_malloc_ab(sizeof(*exec2_list), args->buffer_count); + if (exec_list == NULL || exec2_list == NULL) { + DRM_DEBUG("Failed to allocate exec list for %d buffers\n", + args->buffer_count); + drm_free_large(exec_list); + drm_free_large(exec2_list); + return -ENOMEM; + } + ret = copy_from_user(exec_list, + to_user_ptr(args->buffers_ptr), + sizeof(*exec_list) * args->buffer_count); + if (ret != 0) { + DRM_DEBUG("copy %d exec entries failed %d\n", + args->buffer_count, ret); + drm_free_large(exec_list); + drm_free_large(exec2_list); + return -EFAULT; + } + + for (i = 0; i < args->buffer_count; i++) { + exec2_list[i].handle = exec_list[i].handle; + exec2_list[i].relocation_count = exec_list[i].relocation_count; + exec2_list[i].relocs_ptr = exec_list[i].relocs_ptr; + exec2_list[i].alignment = exec_list[i].alignment; + exec2_list[i].offset = exec_list[i].offset; + if (INTEL_INFO(dev)->gen < 4) + exec2_list[i].flags = EXEC_OBJECT_NEEDS_FENCE; + else + exec2_list[i].flags = 0; + } + + exec2.buffers_ptr = args->buffers_ptr; + exec2.buffer_count = args->buffer_count; + exec2.batch_start_offset = args->batch_start_offset; + exec2.batch_len = args->batch_len; + exec2.DR1 = args->DR1; + exec2.DR4 = args->DR4; + exec2.num_cliprects = args->num_cliprects; + exec2.cliprects_ptr = args->cliprects_ptr; + exec2.flags = I915_EXEC_RENDER; + i915_execbuffer2_set_context_id(exec2, 0); + + ret = i915_gem_do_execbuffer(dev, data, file, &exec2, exec2_list, + &dev_priv->gtt.base); + if (!ret) { + /* Copy the new buffer offsets back to the user's exec list. */ + for (i = 0; i < args->buffer_count; i++) + exec_list[i].offset = exec2_list[i].offset; + /* ... and back out to userspace */ + ret = copy_to_user(to_user_ptr(args->buffers_ptr), + exec_list, + sizeof(*exec_list) * args->buffer_count); + if (ret) { + ret = -EFAULT; + DRM_DEBUG("failed to copy %d exec entries " + "back to user (%d)\n", + args->buffer_count, ret); + } + } + + drm_free_large(exec_list); + drm_free_large(exec2_list); + return ret; +} +#endif int i915_gem_execbuffer2(struct drm_device *dev, void *data, @@ -1175,8 +1283,5 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data, } kfree(exec2_list); - -// LEAVE(); - return ret; } diff --git a/drivers/video/drm/i915/i915_gem_tiling.c b/drivers/video/drm/i915/i915_gem_tiling.c index 5dc37db54f..3d624eba7e 100644 --- a/drivers/video/drm/i915/i915_gem_tiling.c +++ b/drivers/video/drm/i915/i915_gem_tiling.c @@ -80,24 +80,6 @@ * to match what the GPU expects. */ -#define I915_TILING_NONE 0 -#define I915_TILING_X 1 -#define I915_TILING_Y 2 - -#define I915_BIT_6_SWIZZLE_NONE 0 -#define I915_BIT_6_SWIZZLE_9 1 -#define I915_BIT_6_SWIZZLE_9_10 2 -#define I915_BIT_6_SWIZZLE_9_11 3 -#define I915_BIT_6_SWIZZLE_9_10_11 4 -/* Not seen by userland */ -#define I915_BIT_6_SWIZZLE_UNKNOWN 5 -/* Seen by userland. */ -#define I915_BIT_6_SWIZZLE_9_17 6 -#define I915_BIT_6_SWIZZLE_9_10_17 7 - - - - /** * Detects bit 6 swizzling of address lookup between IGD access and CPU * access through main memory. @@ -218,7 +200,6 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev) dev_priv->mm.bit_6_swizzle_y = swizzle_y; } -#if 0 /* Check pitch constriants for all chips & tiling formats */ static bool i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) @@ -470,6 +451,7 @@ i915_gem_get_tiling(struct drm_device *dev, void *data, return 0; } +#if 0 /** * Swap every 64 bytes of this page around, to account for it having a new * bit 17 of its physical address and therefore being interpreted differently diff --git a/drivers/video/drm/i915/main.c b/drivers/video/drm/i915/main.c index fbb0b481b4..22609f1aac 100644 --- a/drivers/video/drm/i915/main.c +++ b/drivers/video/drm/i915/main.c @@ -45,7 +45,8 @@ int blit_tex(u32 hbitmap, int dst_x, int dst_y, int src_x, int src_y, u32 w, u32 h); void get_pci_info(struct pci_device *dev); -int gem_getparam(struct drm_device *dev, void *data); +int i915_getparam(struct drm_device *dev, void *data, + struct drm_file *file_priv); int i915_mask_update(struct drm_device *dev, void *data, struct drm_file *file); @@ -221,22 +222,31 @@ u32_t __attribute__((externally_visible)) drvEntry(int action, char *cmdline) #define SRV_GET_PCI_INFO 20 -#define SRV_GET_PARAM 21 +#define SRV_I915_GET_PARAM 21 #define SRV_I915_GEM_CREATE 22 #define SRV_DRM_GEM_CLOSE 23 -#define SRV_I915_GEM_PIN 24 -#define SRV_I915_GEM_SET_CACHEING 25 -#define SRV_I915_GEM_GET_APERTURE 26 -#define SRV_I915_GEM_PWRITE 27 -#define SRV_I915_GEM_BUSY 28 -#define SRV_I915_GEM_SET_DOMAIN 29 -#define SRV_I915_GEM_MMAP 30 -#define SRV_I915_GEM_MMAP_GTT 31 -#define SRV_I915_GEM_THROTTLE 32 -#define SRV_FBINFO 33 -#define SRV_I915_GEM_EXECBUFFER2 34 -#define SRV_MASK_UPDATE 35 +#define SRV_DRM_GEM_FLINK 24 +#define SRV_DRM_GEM_OPEN 25 +#define SRV_I915_GEM_PIN 26 +#define SRV_I915_GEM_UNPIN 27 +#define SRV_I915_GEM_SET_CACHING 28 +#define SRV_I915_GEM_PWRITE 29 +#define SRV_I915_GEM_BUSY 30 +#define SRV_I915_GEM_SET_DOMAIN 31 +#define SRV_I915_GEM_MMAP 32 +#define SRV_I915_GEM_SET_TILING 33 +#define SRV_I915_GEM_GET_TILING 34 +#define SRV_I915_GEM_GET_APERTURE 35 +#define SRV_I915_GEM_MMAP_GTT 36 +#define SRV_I915_GEM_THROTTLE 37 +#define SRV_I915_GEM_EXECBUFFER2 38 +#define SRV_I915_GEM_WAIT 39 +#define SRV_I915_GEM_CONTEXT_CREATE 40 +#define SRV_I915_GEM_CONTEXT_DESTROY 41 +#define SRV_I915_REG_READ 42 +#define SRV_FBINFO 43 +#define SRV_MASK_UPDATE 44 #define check_input(size) \ @@ -316,8 +326,8 @@ int _stdcall display_handler(ioctl_t *io) retval = 0; break; - case SRV_GET_PARAM: - retval = gem_getparam(main_device, inp); + case SRV_I915_GET_PARAM: + retval = i915_getparam(main_device, inp, file); break; case SRV_I915_GEM_CREATE: @@ -328,16 +338,24 @@ int _stdcall display_handler(ioctl_t *io) retval = drm_gem_close_ioctl(main_device, inp, file); break; + case SRV_DRM_GEM_FLINK: + retval = drm_gem_flink_ioctl(main_device, inp, file); + break; + + case SRV_DRM_GEM_OPEN: + retval = drm_gem_open_ioctl(main_device, inp, file); + break; + case SRV_I915_GEM_PIN: retval = i915_gem_pin_ioctl(main_device, inp, file); break; - case SRV_I915_GEM_SET_CACHEING: - retval = i915_gem_set_caching_ioctl(main_device, inp, file); + case SRV_I915_GEM_UNPIN: + retval = i915_gem_unpin_ioctl(main_device, inp, file); break; - case SRV_I915_GEM_GET_APERTURE: - retval = i915_gem_get_aperture_ioctl(main_device, inp, file); + case SRV_I915_GEM_SET_CACHING: + retval = i915_gem_set_caching_ioctl(main_device, inp, file); break; case SRV_I915_GEM_PWRITE: @@ -352,31 +370,60 @@ int _stdcall display_handler(ioctl_t *io) retval = i915_gem_set_domain_ioctl(main_device, inp, file); break; - case SRV_I915_GEM_THROTTLE: - retval = i915_gem_throttle_ioctl(main_device, inp, file); - break; - case SRV_I915_GEM_MMAP: retval = i915_gem_mmap_ioctl(main_device, inp, file); break; + case SRV_I915_GEM_SET_TILING: + retval = i915_gem_set_tiling(main_device, inp, file); + break; + + case SRV_I915_GEM_GET_TILING: + retval = i915_gem_get_tiling(main_device, inp, file); + break; + + case SRV_I915_GEM_GET_APERTURE: +// printf("SRV_I915_GEM_GET_APERTURE "); + retval = i915_gem_get_aperture_ioctl(main_device, inp, file); +// printf(" retval=%d\n", retval); + break; + case SRV_I915_GEM_MMAP_GTT: retval = i915_gem_mmap_gtt_ioctl(main_device, inp, file); break; + case SRV_I915_GEM_THROTTLE: + retval = i915_gem_throttle_ioctl(main_device, inp, file); + break; + + case SRV_I915_GEM_EXECBUFFER2: +// printf("SRV_I915_GEM_EXECBUFFER2\n"); + retval = i915_gem_execbuffer2(main_device, inp, file); + break; + + case SRV_I915_GEM_WAIT: + retval = i915_gem_wait_ioctl(main_device, inp, file); + break; + + case SRV_I915_GEM_CONTEXT_CREATE: + retval = i915_gem_context_create_ioctl(main_device, inp, file); + break; + + case SRV_I915_GEM_CONTEXT_DESTROY: + retval = i915_gem_context_destroy_ioctl(main_device, inp, file); + break; + + case SRV_I915_REG_READ: + retval = i915_reg_read_ioctl(main_device, inp, file); + break; case SRV_FBINFO: retval = i915_fbinfo(inp); break; - case SRV_I915_GEM_EXECBUFFER2: - retval = i915_gem_execbuffer2(main_device, inp, file); - break; - case SRV_MASK_UPDATE: retval = i915_mask_update(main_device, inp, file); break; - }; return retval; @@ -521,3 +568,6 @@ void get_pci_info(struct pci_device *dev) dev->device_id = pdev->device; dev->revision = pdev->revision; }; + + + diff --git a/drivers/video/drm/i915/utils.c b/drivers/video/drm/i915/utils.c index 85f50dcfc0..26454f0cc8 100644 --- a/drivers/video/drm/i915/utils.c +++ b/drivers/video/drm/i915/utils.c @@ -41,8 +41,6 @@ struct page *shmem_read_mapping_page_gfp(struct file *filep, { struct page *page; -// dbgprintf("%s, file %p index %d\n", __FUNCTION__, filep, index); - if(unlikely(index >= filep->count)) return ERR_PTR(-EINVAL); @@ -56,6 +54,9 @@ struct page *shmem_read_mapping_page_gfp(struct file *filep, return ERR_PTR(-ENOMEM); filep->pages[index] = page; +// printf("file %p index %d page %x\n", filep, index, page); +// delay(1); + }; return page;