diff options
Diffstat (limited to 'libdrm')
| -rw-r--r-- | libdrm/Makefile.am | 4 | ||||
| -rw-r--r-- | libdrm/dri_bufmgr.c | 4 | ||||
| -rw-r--r-- | libdrm/dri_bufmgr.h | 8 | ||||
| -rw-r--r-- | libdrm/intel/Makefile.am | 1 | ||||
| -rw-r--r-- | libdrm/intel/intel_bufmgr.h | 35 | ||||
| -rw-r--r-- | libdrm/intel/intel_bufmgr_fake.c | 64 | ||||
| -rw-r--r-- | libdrm/intel/intel_bufmgr_gem.c | 142 | ||||
| -rw-r--r-- | libdrm/libdrm_lists.h | 87 | ||||
| -rw-r--r-- | libdrm/xf86drm.c | 43 | ||||
| -rw-r--r-- | libdrm/xf86drm.h | 2 | 
10 files changed, 313 insertions, 77 deletions
| diff --git a/libdrm/Makefile.am b/libdrm/Makefile.am index 624f6ffb..c6d66732 100644 --- a/libdrm/Makefile.am +++ b/libdrm/Makefile.am @@ -26,10 +26,10 @@ libdrm_la_LDFLAGS = -version-number 2:3:0 -no-undefined  AM_CFLAGS = -I$(top_srcdir)/shared-core  libdrm_la_SOURCES = xf86drm.c xf86drmHash.c xf86drmRandom.c xf86drmSL.c \ -	xf86drmMode.c dri_bufmgr.c +	xf86drmMode.c dri_bufmgr.c libdrm_lists.h  libdrm_la_LIBADD = intel/libdrm_intel.la  libdrmincludedir = ${includedir} -libdrminclude_HEADERS = xf86drm.h xf86mm.h xf86drmMode.h dri_bufmgr.h +libdrminclude_HEADERS = xf86drm.h xf86drmMode.h dri_bufmgr.h  EXTRA_DIST = ChangeLog TODO diff --git a/libdrm/dri_bufmgr.c b/libdrm/dri_bufmgr.c index 7657df61..a6eda3bd 100644 --- a/libdrm/dri_bufmgr.c +++ b/libdrm/dri_bufmgr.c @@ -135,7 +135,7 @@ dri_bufmgr_set_debug(dri_bufmgr *bufmgr, int enable_debug)  }  int -dri_bufmgr_check_aperture_space(dri_bo *bo) +dri_bufmgr_check_aperture_space(dri_bo **bo_array, int count)  { -    return bo->bufmgr->check_aperture_space(bo); +	return bo_array[0]->bufmgr->check_aperture_space(bo_array, count);  } diff --git a/libdrm/dri_bufmgr.h b/libdrm/dri_bufmgr.h index a5ae6c0f..2005bdc6 100644 --- a/libdrm/dri_bufmgr.h +++ b/libdrm/dri_bufmgr.h @@ -58,6 +58,10 @@ struct _dri_bo {     void *virtual;     /** Buffer manager context associated with this buffer object */     dri_bufmgr *bufmgr; +   /** +    * MM-specific handle for accessing object +    */ +   int handle;  };  /** @@ -146,7 +150,7 @@ struct _dri_bufmgr {     void (*post_submit)(dri_bo *batch_buf); -   int (*check_aperture_space)(dri_bo *bo); +   int (*check_aperture_space)(dri_bo **bo_array, int count);     int debug; /**< Enables verbose debugging printouts */  }; @@ -169,6 +173,6 @@ void dri_bufmgr_destroy(dri_bufmgr *bufmgr);  void *dri_process_relocs(dri_bo *batch_buf);  void dri_post_process_relocs(dri_bo *batch_buf);  void dri_post_submit(dri_bo *batch_buf); -int dri_bufmgr_check_aperture_space(dri_bo *bo); +int dri_bufmgr_check_aperture_space(dri_bo **bo_array, int count);  #endif diff --git a/libdrm/intel/Makefile.am b/libdrm/intel/Makefile.am index 111204b1..31a8512a 100644 --- a/libdrm/intel/Makefile.am +++ b/libdrm/intel/Makefile.am @@ -24,6 +24,7 @@  AM_CFLAGS = \  	$(WARN_CFLAGS) \ +	-I$(top_srcdir)/libdrm \  	-I$(top_srcdir)/shared-core  noinst_LTLIBRARIES = libdrm_intel.la 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_fake.c b/libdrm/intel/intel_bufmgr_fake.c index e7ed893f..15da398f 100644 --- a/libdrm/intel/intel_bufmgr_fake.c +++ b/libdrm/intel/intel_bufmgr_fake.c @@ -42,6 +42,9 @@  #include "drm.h"  #include "i915_drm.h"  #include "mm.h" +#include "libdrm_lists.h" + +#define ALIGN(value, alignment)  ((value + alignment - 1) & ~(alignment - 1))  #define DBG(...) do {					\     if (bufmgr_fake->bufmgr.debug)			\ @@ -147,9 +150,6 @@ typedef struct _bufmgr_fake {     int debug;     int performed_rendering; - -   /* keep track of the current total size of objects we have relocs for */ -   unsigned long current_total_size;  } dri_bufmgr_fake;  typedef struct _dri_bo_fake { @@ -159,8 +159,8 @@ typedef struct _dri_bo_fake {     const char *name;     unsigned dirty:1; -   unsigned size_accounted:1; /*this buffers size has been accounted against the aperture */ -   unsigned card_dirty:1; /* has the card written to this buffer - we make need to copy it back */ +   /** has the card written to this buffer - we make need to copy it back */ +   unsigned card_dirty:1;     unsigned int refcount;     /* Flags may consist of any of the DRM_BO flags, plus      * DRM_BO_NO_BACKING_STORE and BM_NO_FENCE_SUBDATA, which are the first two @@ -179,6 +179,12 @@ typedef struct _dri_bo_fake {     /** relocation list */     struct fake_buffer_reloc *relocs;     int nr_relocs; +   /** +    * Total size of the target_bos of this buffer. +    * +    * Used for estimation in check_aperture. +    */ +   unsigned int child_size;     struct block *block;     void *backing_store; @@ -189,8 +195,6 @@ typedef struct _dri_bo_fake {  static int clear_fenced(dri_bufmgr_fake *bufmgr_fake,  			unsigned int fence_cookie); -static int dri_fake_check_aperture_space(dri_bo *bo); -  #define MAXFENCE 0x7fffffff  static int FENCE_LTE( unsigned a, unsigned b ) @@ -855,9 +859,6 @@ dri_fake_bo_validate(dri_bo *bo)        return 0;     } -   /* reset size accounted */ -   bo_fake->size_accounted = 0; -     /* Allocate the card memory */     if (!bo_fake->block && !evict_and_alloc_block(bo)) {        bufmgr_fake->fail = 1; @@ -941,8 +942,6 @@ dri_fake_emit_reloc(dri_bo *reloc_buf,     assert(reloc_buf);     assert(target_buf); -   assert(target_fake->is_static || target_fake->size_accounted); -     if (reloc_fake->relocs == NULL) {        reloc_fake->relocs = malloc(sizeof(struct fake_buffer_reloc) *  				  MAX_RELOCS); @@ -954,6 +953,9 @@ dri_fake_emit_reloc(dri_bo *reloc_buf,     dri_bo_reference(target_buf); +   if (!target_fake->is_static) +      reloc_fake->child_size += ALIGN(target_buf->size, target_fake->alignment); +     r->target_buf = target_buf;     r->offset = offset;     r->last_target_offset = target_buf->offset; @@ -1079,7 +1081,6 @@ dri_fake_process_relocs(dri_bo *batch_buf)     assert(ret == 0); -   bufmgr_fake->current_total_size = 0;     return NULL;  } @@ -1117,26 +1118,39 @@ dri_fake_post_submit(dri_bo *batch_buf)     dri_bo_fake_post_submit(batch_buf);  } +/** + * Return an error if the list of BOs will exceed the aperture size. + * + * This is a rough guess and likely to fail, as during the validate sequence we + * may place a buffer in an inopportune spot early on and then fail to fit + * a set smaller than the aperture. + */  static int -dri_fake_check_aperture_space(dri_bo *bo) +dri_fake_check_aperture_space(dri_bo **bo_array, int count)  { -   dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr; -   dri_bo_fake *bo_fake = (dri_bo_fake *)bo; -   unsigned int sz; +   dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bo_array[0]->bufmgr; +   unsigned int sz = 0; +   int i; -   sz = (bo->size + bo_fake->alignment - 1) & ~(bo_fake->alignment - 1); +   for (i = 0; i < count; i++) { +      dri_bo_fake *bo_fake = (dri_bo_fake *)bo_array[i]; -   if (bo_fake->size_accounted || bo_fake->is_static) -      return 0; +      if (bo_fake == NULL) +	 continue; + +      if (!bo_fake->is_static) +	 sz += ALIGN(bo_array[i]->size, bo_fake->alignment); +      sz += bo_fake->child_size; +   } -   if (bufmgr_fake->current_total_size + sz > bufmgr_fake->size) { -     DBG("check_space: %s bo %d %d overflowed bufmgr size %d\n", bo_fake->name, bo_fake->id, sz, bufmgr_fake->size); +   if (sz > bufmgr_fake->size) { +      DBG("check_space: overflowed bufmgr size, %dkb vs %dkb\n", +	  sz / 1024, bufmgr_fake->size / 1024);        return -1;     } -   bufmgr_fake->current_total_size += sz; -   bo_fake->size_accounted = 1; -   DBG("drm_check_space: buf %d, %s %d %d\n", bo_fake->id, bo_fake->name, bo->size, bufmgr_fake->current_total_size); +   DBG("drm_check_space: sz %dkb vs bufgr %dkb\n", sz / 1024 , +       bufmgr_fake->size / 1024);     return 0;  } diff --git a/libdrm/intel/intel_bufmgr_gem.c b/libdrm/intel/intel_bufmgr_gem.c index cdc2a7ac..af20efb2 100644 --- a/libdrm/intel/intel_bufmgr_gem.c +++ b/libdrm/intel/intel_bufmgr_gem.c @@ -103,6 +103,11 @@ struct _dri_bo_gem {      const char *name;      /** +     * Kenel-assigned global name for this object +     */ +    unsigned int global_name; +     +    /**       * Index of the buffer within the validation list while preparing a       * batchbuffer execution.       */ @@ -311,6 +316,7 @@ dri_gem_bo_alloc(dri_bufmgr *bufmgr, const char *name,  	ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_CREATE, &create);  	bo_gem->gem_handle = create.handle; +	bo_gem->bo.handle = bo_gem->gem_handle;  	if (ret != 0) {  	    free(bo_gem);  	    return NULL; @@ -768,6 +774,84 @@ 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; + +    if (!bo_gem->global_name) { +	flink.handle = bo_gem->gem_handle; +     +	ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_GEM_FLINK, &flink); +	if (ret != 0) +	    return -errno; +	bo_gem->global_name = flink.name; +    } +     +    *name = bo_gem->global_name; +    return 0; +} +  /**   * Enables unlimited caching of buffer objects for reuse.   * @@ -790,7 +874,7 @@ intel_bufmgr_gem_enable_reuse(dri_bufmgr *bufmgr)   *   */  static int -dri_gem_check_aperture_space(dri_bo *bo) +dri_gem_check_aperture_space(dri_bo **bo_array, int count)  {      return 0;  } @@ -832,6 +916,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 +939,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/libdrm/libdrm_lists.h b/libdrm/libdrm_lists.h new file mode 100644 index 00000000..8e23991f --- /dev/null +++ b/libdrm/libdrm_lists.h @@ -0,0 +1,87 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND. USA. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + */ + +/* + * List macros heavily inspired by the Linux kernel + * list handling. No list looping yet. + */ + +typedef struct _drmMMListHead +{ +    struct _drmMMListHead *prev; +    struct _drmMMListHead *next; +} drmMMListHead; + +#define DRMINITLISTHEAD(__item)		       \ +  do{					       \ +    (__item)->prev = (__item);		       \ +    (__item)->next = (__item);		       \ +  } while (0) + +#define DRMLISTADD(__item, __list)		\ +  do {						\ +    (__item)->prev = (__list);			\ +    (__item)->next = (__list)->next;		\ +    (__list)->next->prev = (__item);		\ +    (__list)->next = (__item);			\ +  } while (0) + +#define DRMLISTADDTAIL(__item, __list)		\ +  do {						\ +    (__item)->next = (__list);			\ +    (__item)->prev = (__list)->prev;		\ +    (__list)->prev->next = (__item);		\ +    (__list)->prev = (__item);			\ +  } while(0) + +#define DRMLISTDEL(__item)			\ +  do {						\ +    (__item)->prev->next = (__item)->next;	\ +    (__item)->next->prev = (__item)->prev;	\ +  } while(0) + +#define DRMLISTDELINIT(__item)			\ +  do {						\ +    (__item)->prev->next = (__item)->next;	\ +    (__item)->next->prev = (__item)->prev;	\ +    (__item)->next = (__item);			\ +    (__item)->prev = (__item);			\ +  } while(0) + +#define DRMLISTENTRY(__type, __item, __field)   \ +    ((__type *)(((char *) (__item)) - offsetof(__type, __field))) + +#define DRMLISTEMPTY(__item) ((__item)->next == (__item)) + +#define DRMLISTFOREACHSAFE(__item, __temp, __list)			\ +	for ((__item) = (__list)->next, (__temp) = (__item)->next;	\ +	     (__item) != (__list);					\ +	     (__item) = (__temp), (__temp) = (__item)->next) + +#define DRMLISTFOREACHSAFEREVERSE(__item, __temp, __list)		\ +	for ((__item) = (__list)->prev, (__temp) = (__item)->prev;	\ +	     (__item) != (__list);					\ +	     (__item) = (__temp), (__temp) = (__item)->prev) diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index 1fd3a697..64765339 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -2356,49 +2356,6 @@ int drmCommandWriteRead(int fd, unsigned long drmCommandIndex, void *data,      return 0;  } - -#define DRM_IOCTL_TIMEOUT_USEC 3000000UL - -static unsigned long -drmTimeDiff(struct timeval *now, struct timeval *then) -{ -    uint64_t val; - -    val = now->tv_sec - then->tv_sec; -    val *= 1000000LL; -    val += now->tv_usec; -    val -= then->tv_usec; - -    return (unsigned long) val; -} - -static int -drmIoctlTimeout(int fd, unsigned long request, void *argp) -{ -    int haveThen = 0; -    struct timeval then, now; -    int ret; - -    do { -	ret = drmIoctl(fd, request, argp); -	if (ret != 0 && errno == EAGAIN) { -	    if (!haveThen) { -		gettimeofday(&then, NULL); -		haveThen = 1; -	    } -	    gettimeofday(&now, NULL); -	} -    } while (ret != 0 && errno == EAGAIN &&  -	     drmTimeDiff(&now, &then) < DRM_IOCTL_TIMEOUT_USEC); -     -    if (ret != 0) -	return ((errno == EAGAIN) ? -EBUSY : -errno); - -    return 0; -} -     -	 -  #define DRM_MAX_FDS 16  static struct {      char *BusID; diff --git a/libdrm/xf86drm.h b/libdrm/xf86drm.h index b29b3e5d..584d2a41 100644 --- a/libdrm/xf86drm.h +++ b/libdrm/xf86drm.h @@ -664,6 +664,4 @@ extern void drmMsg(const char *format, ...);  extern int drmSetMaster(int fd);  extern int drmDropMaster(int fd); -#include "xf86mm.h" -  #endif | 
