};
struct brw_bufmgr {
+ uint32_t refcount;
+
+ struct list_head link;
+
int fd;
mtx_t lock;
uint64_t initial_kflags;
};
+static mtx_t global_bufmgr_list_mutex = _MTX_INITIALIZER_NP;
+static struct list_head global_bufmgr_list = {
+ .next = &global_bufmgr_list,
+ .prev = &global_bufmgr_list,
+};
+
static int bo_set_tiling_internal(struct brw_bo *bo, uint32_t tiling_mode,
uint32_t stride);
}
void
-brw_bufmgr_destroy(struct brw_bufmgr *bufmgr)
+brw_bufmgr_unref(struct brw_bufmgr *bufmgr)
{
+ mtx_lock(&global_bufmgr_list_mutex);
+ if (p_atomic_dec_zero(&bufmgr->refcount)) {
+ list_del(&bufmgr->link);
+ } else {
+ bufmgr = NULL;
+ }
+ mtx_unlock(&global_bufmgr_list_mutex);
+
+ if (!bufmgr)
+ return;
+
mtx_destroy(&bufmgr->lock);
/* Free any cached buffer objects we were going to reuse */
}
}
+ close(bufmgr->fd);
+ bufmgr->fd = -1;
+
free(bufmgr);
}
return bufmgr->initial_kflags & EXEC_OBJECT_PINNED;
}
+static struct brw_bufmgr *
+brw_bufmgr_ref(struct brw_bufmgr *bufmgr)
+{
+ p_atomic_inc(&bufmgr->refcount);
+ return bufmgr;
+}
+
/**
* Initializes the GEM buffer manager, which uses the kernel to allocate, map,
* and manage map buffer objections.
*
* \param fd File descriptor of the opened DRM device.
*/
-struct brw_bufmgr *
-brw_bufmgr_init(struct gen_device_info *devinfo, int fd, bool bo_reuse)
+static struct brw_bufmgr *
+brw_bufmgr_create(struct gen_device_info *devinfo, int fd, bool bo_reuse)
{
struct brw_bufmgr *bufmgr;
* Don't do this! Ensure that each library/bufmgr has its own device
* fd so that its namespace does not clash with another.
*/
- bufmgr->fd = fd;
+ bufmgr->fd = dup(fd);
+ if (bufmgr->fd < 0) {
+ free(bufmgr);
+ return NULL;
+ }
+
+ p_atomic_set(&bufmgr->refcount, 1);
if (mtx_init(&bufmgr->lock, mtx_plain) != 0) {
+ close(bufmgr->fd);
free(bufmgr);
return NULL;
}
* might actually mean requiring 4.14.
*/
fprintf(stderr, "i965 requires softpin (Kernel 4.5) on Gen10+.");
+ close(bufmgr->fd);
free(bufmgr);
return NULL;
}
return bufmgr;
}
+
+struct brw_bufmgr *
+brw_bufmgr_get_for_fd(struct gen_device_info *devinfo, int fd, bool bo_reuse)
+{
+ struct stat st;
+
+ if (fstat(fd, &st))
+ return NULL;
+
+ struct brw_bufmgr *bufmgr = NULL;
+
+ mtx_lock(&global_bufmgr_list_mutex);
+ list_for_each_entry(struct brw_bufmgr, iter_bufmgr, &global_bufmgr_list, link) {
+ struct stat iter_st;
+ if (fstat(iter_bufmgr->fd, &iter_st))
+ continue;
+
+ if (st.st_rdev == iter_st.st_rdev) {
+ assert(iter_bufmgr->bo_reuse == bo_reuse);
+ bufmgr = brw_bufmgr_ref(iter_bufmgr);
+ goto unlock;
+ }
+ }
+
+ bufmgr = brw_bufmgr_create(devinfo, fd, bo_reuse);
+ list_addtail(&bufmgr->link, &global_bufmgr_list);
+
+ unlock:
+ mtx_unlock(&global_bufmgr_list_mutex);
+
+ return bufmgr;
+}
+
+int
+brw_bufmgr_get_fd(struct brw_bufmgr *bufmgr)
+{
+ return bufmgr->fd;
+}
void brw_bo_wait_rendering(struct brw_bo *bo);
/**
- * Tears down the buffer manager instance.
+ * Unref a buffer manager instance.
*/
-void brw_bufmgr_destroy(struct brw_bufmgr *bufmgr);
+void brw_bufmgr_unref(struct brw_bufmgr *bufmgr);
/**
* Get the current tiling (and resulting swizzling) mode for the bo.
int brw_bo_madvise(struct brw_bo *bo, int madv);
/* drm_bacon_bufmgr_gem.c */
-struct brw_bufmgr *brw_bufmgr_init(struct gen_device_info *devinfo, int fd,
- bool bo_reuse);
+struct brw_bufmgr *brw_bufmgr_get_for_fd(struct gen_device_info *devinfo, int fd,
+ bool bo_reuse);
+
struct brw_bo *brw_bo_gem_create_from_name(struct brw_bufmgr *bufmgr,
const char *name,
unsigned int handle);
void brw_destroy_hw_context(struct brw_bufmgr *bufmgr, uint32_t ctx_id);
+int brw_bufmgr_get_fd(struct brw_bufmgr *bufmgr);
+
int brw_bo_gem_export_to_prime(struct brw_bo *bo, int *prime_fd);
struct brw_bo *brw_bo_gem_create_from_prime(struct brw_bufmgr *bufmgr,
int prime_fd);
{
struct intel_screen *screen = sPriv->driverPrivate;
- brw_bufmgr_destroy(screen->bufmgr);
+ brw_bufmgr_unref(screen->bufmgr);
driDestroyOptionInfo(&screen->optionCache);
disk_cache_destroy(screen->disk_cache);
static bool
intel_init_bufmgr(struct intel_screen *screen)
{
+ __DRIscreen *dri_screen = screen->driScrnPriv;
+
if (getenv("INTEL_NO_HW") != NULL)
screen->no_hw = true;
break;
}
- screen->bufmgr = brw_bufmgr_init(&screen->devinfo, screen->fd, bo_reuse);
+ screen->bufmgr = brw_bufmgr_get_for_fd(&screen->devinfo, dri_screen->fd, bo_reuse);
if (screen->bufmgr == NULL) {
fprintf(stderr, "[%s:%u] Error initializing buffer manager.\n",
__func__, __LINE__);
return false;
}
+ screen->fd = brw_bufmgr_get_fd(screen->bufmgr);
if (!intel_get_boolean(screen, I915_PARAM_HAS_EXEC_NO_RELOC)) {
fprintf(stderr, "[%s: %u] Kernel 3.9 required.\n", __func__, __LINE__);
return NULL;
}
- screen->fd = dri_screen->fd;
if (!intel_init_bufmgr(screen))
return NULL;