diff options
| -rw-r--r-- | libdrm/intel/intel_bufmgr.h | 35 | ||||
| -rw-r--r-- | libdrm/intel/intel_bufmgr_gem.c | 131 | ||||
| -rw-r--r-- | linux-core/i915_gem.c | 43 | 
3 files changed, 189 insertions, 20 deletions
| diff --git a/libdrm/intel/intel_bufmgr.h b/libdrm/intel/intel_bufmgr.h index 1cf0d518..4d335210 100644 --- a/libdrm/intel/intel_bufmgr.h +++ b/libdrm/intel/intel_bufmgr.h @@ -61,6 +61,33 @@ struct intel_bufmgr {      int (*emit_reloc)(dri_bo *reloc_buf,  		      uint32_t read_domains, uint32_t write_domain,  		      uint32_t delta, uint32_t offset, dri_bo *target); +    /** +     * Pin a buffer to the aperture and fix the offset until unpinned +     * +     * \param buf Buffer to pin +     * \param alignment Required alignment for aperture, in bytes +     */ +    int (*pin) (dri_bo *buf, uint32_t alignment); +    /** +     * Unpin a buffer from the aperture, allowing it to be removed +     * +     * \param buf Buffer to unpin +     */ +    int (*unpin) (dri_bo *buf); +    /** +     * Ask that the buffer be placed in tiling mode +     * +     * \param buf Buffer to set tiling mode for +     * \param tiling_mode desired, and returned tiling mode +     */ +    int (*set_tiling) (dri_bo *bo, uint32_t *tiling_mode); +    /** +     * Create a visible name for a buffer which can be used by other apps +     * +     * \param buf Buffer to create a name for +     * \param name Returned name +     */ +    int (*flink) (dri_bo *buf, uint32_t *name);  };  /* intel_bufmgr_gem.c */ @@ -91,5 +118,13 @@ int intel_bo_emit_reloc(dri_bo *reloc_buf,  			uint32_t read_domains, uint32_t write_domain,  			uint32_t delta, uint32_t offset, dri_bo *target_buf); +int intel_bo_pin(dri_bo *buf, uint32_t alignment); + +int intel_bo_unpin(dri_bo *buf); + +int intel_bo_set_tiling(dri_bo *buf, uint32_t *tiling_mode); + +int intel_bo_flink(dri_bo *buf, uint32_t *name); +  #endif /* INTEL_BUFMGR_GEM_H */ diff --git a/libdrm/intel/intel_bufmgr_gem.c b/libdrm/intel/intel_bufmgr_gem.c index cdc2a7ac..22f8695d 100644 --- a/libdrm/intel/intel_bufmgr_gem.c +++ b/libdrm/intel/intel_bufmgr_gem.c @@ -768,6 +768,81 @@ dri_gem_post_submit(dri_bo *batch_buf)      bufmgr_gem->exec_count = 0;  } +static int +dri_gem_pin(dri_bo *bo, uint32_t alignment) +{ +    dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bo->bufmgr; +    dri_bo_gem *bo_gem = (dri_bo_gem *)bo; +    struct drm_i915_gem_pin pin; +    int ret; + +    pin.handle = bo_gem->gem_handle; +    pin.alignment = alignment; + +    ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_PIN, &pin); +    if (ret != 0) +	return -errno; + +    bo->offset = pin.offset; +    return 0; +} + +static int +dri_gem_unpin(dri_bo *bo) +{ +    dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bo->bufmgr; +    dri_bo_gem *bo_gem = (dri_bo_gem *)bo; +    struct drm_i915_gem_unpin unpin; +    int ret; + +    unpin.handle = bo_gem->gem_handle; + +    ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_UNPIN, &unpin); +    if (ret != 0) +	return -errno; + +    return 0; +} + +static int +dri_gem_set_tiling(dri_bo *bo, uint32_t *tiling_mode) +{ +    dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bo->bufmgr; +    dri_bo_gem *bo_gem = (dri_bo_gem *)bo; +    struct drm_i915_gem_set_tiling set_tiling; +    int ret; + +    set_tiling.handle = bo_gem->gem_handle; +    set_tiling.tiling_mode = *tiling_mode; + +    ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_SET_TILING, &set_tiling); +    if (ret != 0) { +	*tiling_mode = I915_TILING_NONE; +	return -errno; +    } + +    *tiling_mode = set_tiling.tiling_mode; +    return 0; +} + +static int +dri_gem_flink(dri_bo *bo, uint32_t *name) +{ +    dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bo->bufmgr; +    dri_bo_gem *bo_gem = (dri_bo_gem *)bo; +    struct drm_gem_flink flink; +    int ret; + +    flink.handle = bo_gem->gem_handle; + +    ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_GEM_FLINK, &flink); +    if (ret != 0) +	return -errno; + +    *name = flink.name; +    return 0; +} +  /**   * Enables unlimited caching of buffer objects for reuse.   * @@ -832,6 +907,10 @@ intel_bufmgr_gem_init(int fd, int batch_size)      bufmgr_gem->bufmgr.debug = 0;      bufmgr_gem->bufmgr.check_aperture_space = dri_gem_check_aperture_space;      bufmgr_gem->intel_bufmgr.emit_reloc = dri_gem_emit_reloc; +    bufmgr_gem->intel_bufmgr.pin = dri_gem_pin; +    bufmgr_gem->intel_bufmgr.unpin = dri_gem_unpin; +    bufmgr_gem->intel_bufmgr.set_tiling = dri_gem_set_tiling; +    bufmgr_gem->intel_bufmgr.flink = dri_gem_flink;      /* Initialize the linked lists for BO reuse cache. */      for (i = 0; i < INTEL_GEM_BO_BUCKETS; i++)  	bufmgr_gem->cache_bucket[i].tail = &bufmgr_gem->cache_bucket[i].head; @@ -851,3 +930,55 @@ intel_bo_emit_reloc(dri_bo *reloc_buf,      return intel_bufmgr->emit_reloc(reloc_buf, read_domains, write_domain,  				    delta, offset, target_buf);  } + +int +intel_bo_pin(dri_bo *bo, uint32_t alignment) +{ +    struct intel_bufmgr *intel_bufmgr; + +    intel_bufmgr = (struct intel_bufmgr *)(bo->bufmgr + 1); + +    if (intel_bufmgr->pin) +	return intel_bufmgr->pin(bo, alignment); + +    return 0; +} + +int +intel_bo_unpin(dri_bo *bo) +{ +    struct intel_bufmgr *intel_bufmgr; + +    intel_bufmgr = (struct intel_bufmgr *)(bo->bufmgr + 1); + +    if (intel_bufmgr->unpin) +	return intel_bufmgr->unpin(bo); + +    return 0; +} + +int intel_bo_set_tiling(dri_bo *bo, uint32_t *tiling_mode) +{ +    struct intel_bufmgr *intel_bufmgr; + +    intel_bufmgr = (struct intel_bufmgr *)(bo->bufmgr + 1); + +    if (intel_bufmgr->set_tiling) +	return intel_bufmgr->set_tiling (bo, tiling_mode); + +    *tiling_mode = I915_TILING_NONE; +    return 0; +} + +int intel_bo_flink(dri_bo *bo, uint32_t *name) +{ +    struct intel_bufmgr *intel_bufmgr; + +    intel_bufmgr = (struct intel_bufmgr *)(bo->bufmgr + 1); + +    if (intel_bufmgr->flink) +	return intel_bufmgr->flink (bo, name); + +    return -ENODEV; +} + diff --git a/linux-core/i915_gem.c b/linux-core/i915_gem.c index 9d935be2..64ffa356 100644 --- a/linux-core/i915_gem.c +++ b/linux-core/i915_gem.c @@ -388,6 +388,10 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,  		return -EBADF;  	mutex_lock(&dev->struct_mutex); +#if WATCH_BUF +	DRM_INFO("set_domain_ioctl %p(%d), %08x %08x\n", +		 obj, obj->size, args->read_domains, args->write_domain); +#endif  	ret = i915_gem_set_domain(obj, file_priv,  				  args->read_domains, args->write_domain);  	drm_gem_object_unreference(obj); @@ -418,8 +422,8 @@ i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data,  	}  #if WATCH_BUF -	DRM_INFO("%s: sw_finish %d (%p)\n", -		 __func__, args->handle, obj); +	DRM_INFO("%s: sw_finish %d (%p %d)\n", +		 __func__, args->handle, obj, obj->size);  #endif  	obj_priv = obj->driver_private; @@ -664,6 +668,12 @@ i915_gem_retire_request(struct drm_device *dev,  			 __func__, request->seqno, obj);  #endif +		/* If this request flushes the write domain, +		 * clear the write domain from the object now +		 */ +		if (request->flush_domains & obj->write_domain) +		    obj->write_domain = 0; +  		if (obj->write_domain != 0) {  			list_move_tail(&obj_priv->list,  				       &dev_priv->mm.flushing_list); @@ -763,7 +773,7 @@ i915_wait_request(struct drm_device *dev, uint32_t seqno)  	if (dev_priv->mm.wedged)  		ret = -EIO; -	if (ret) +	if (ret && ret != -ERESTARTSYS)  		DRM_ERROR("%s returns %d (awaiting %d at %d)\n",  			  __func__, ret, seqno, i915_get_gem_seqno(dev)); @@ -860,18 +870,18 @@ i915_gem_object_wait_rendering(struct drm_gem_object *obj)  	struct drm_device *dev = obj->dev;  	struct drm_i915_gem_object *obj_priv = obj->driver_private;  	int ret; +	uint32_t write_domain;  	/* If there are writes queued to the buffer, flush and  	 * create a new seqno to wait for.  	 */ -	if (obj->write_domain & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT)) { -		uint32_t write_domain = obj->write_domain; +	write_domain = obj->write_domain & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT); +	if (write_domain) {  #if WATCH_BUF  		DRM_INFO("%s: flushing object %p from write domain %08x\n",  			  __func__, obj, write_domain);  #endif  		i915_gem_flush(dev, 0, write_domain); -		obj->write_domain = 0;  		i915_gem_object_move_to_active(obj);  		obj_priv->last_rendering_seqno = i915_add_request(dev, @@ -881,6 +891,7 @@ i915_gem_object_wait_rendering(struct drm_gem_object *obj)  		DRM_INFO("%s: flush moves to exec list %p\n", __func__, obj);  #endif  	} +  	/* If there is rendering queued on the buffer being evicted, wait for  	 * it.  	 */ @@ -1079,20 +1090,12 @@ i915_gem_object_get_page_list(struct drm_gem_object *obj)  	inode = obj->filp->f_path.dentry->d_inode;  	mapping = inode->i_mapping;  	for (i = 0; i < page_count; i++) { -		page = find_get_page(mapping, i); -		if (page == NULL || !PageUptodate(page)) { -			if (page) { -				page_cache_release(page); -				page = NULL; -			} -			ret = shmem_getpage(inode, i, &page, SGP_DIRTY, NULL); - -			if (ret) { -				DRM_ERROR("shmem_getpage failed: %d\n", ret); -				i915_gem_object_free_page_list(obj); -				return ret; -			} -			unlock_page(page); +		page = read_mapping_page(mapping, i, NULL); +		if (IS_ERR(page)) { +			ret = PTR_ERR(page); +			DRM_ERROR("read_mapping_page failed: %d\n", ret); +			i915_gem_object_free_page_list(obj); +			return ret;  		}  		obj_priv->page_list[i] = page;  	} | 
