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 |