i965: share buffer managers across screens
Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Cc: <mesa-stable@lists.freedesktop.org> Closes: https://gitlab.freedesktop.org/mesa/mesa/issues/1373 Reviewed-by: Adam Jackson <ajax@redhat.com> Reviewed-by: Rafael Antognolli <rafael.antognolli@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4086>
This commit is contained in:
@@ -136,6 +136,10 @@ struct bo_cache_bucket {
|
||||
};
|
||||
|
||||
struct brw_bufmgr {
|
||||
uint32_t refcount;
|
||||
|
||||
struct list_head link;
|
||||
|
||||
int fd;
|
||||
|
||||
mtx_t lock;
|
||||
@@ -157,6 +161,12 @@ struct brw_bufmgr {
|
||||
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);
|
||||
|
||||
@@ -1279,8 +1289,19 @@ brw_bo_wait(struct brw_bo *bo, int64_t timeout_ns)
|
||||
}
|
||||
|
||||
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 */
|
||||
@@ -1309,6 +1330,9 @@ brw_bufmgr_destroy(struct brw_bufmgr *bufmgr)
|
||||
}
|
||||
}
|
||||
|
||||
close(bufmgr->fd);
|
||||
bufmgr->fd = -1;
|
||||
|
||||
free(bufmgr);
|
||||
}
|
||||
|
||||
@@ -1651,14 +1675,21 @@ brw_using_softpin(struct brw_bufmgr *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;
|
||||
|
||||
@@ -1675,9 +1706,16 @@ brw_bufmgr_init(struct gen_device_info *devinfo, int fd, bool bo_reuse)
|
||||
* 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;
|
||||
}
|
||||
@@ -1719,6 +1757,7 @@ brw_bufmgr_init(struct gen_device_info *devinfo, int fd, bool bo_reuse)
|
||||
* might actually mean requiring 4.14.
|
||||
*/
|
||||
fprintf(stderr, "i965 requires softpin (Kernel 4.5) on Gen10+.");
|
||||
close(bufmgr->fd);
|
||||
free(bufmgr);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1733,3 +1772,41 @@ brw_bufmgr_init(struct gen_device_info *devinfo, int fd, bool bo_reuse)
|
||||
|
||||
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;
|
||||
}
|
||||
|
@@ -300,9 +300,9 @@ int brw_bo_subdata(struct brw_bo *bo, uint64_t offset,
|
||||
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.
|
||||
@@ -343,8 +343,9 @@ int brw_bo_busy(struct brw_bo *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);
|
||||
@@ -359,6 +360,8 @@ int brw_hw_context_set_priority(struct brw_bufmgr *bufmgr,
|
||||
|
||||
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);
|
||||
|
@@ -1707,7 +1707,7 @@ intelDestroyScreen(__DRIscreen * sPriv)
|
||||
{
|
||||
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);
|
||||
@@ -1910,6 +1910,8 @@ err_out:
|
||||
static bool
|
||||
intel_init_bufmgr(struct intel_screen *screen)
|
||||
{
|
||||
__DRIscreen *dri_screen = screen->driScrnPriv;
|
||||
|
||||
if (getenv("INTEL_NO_HW") != NULL)
|
||||
screen->no_hw = true;
|
||||
|
||||
@@ -1923,12 +1925,13 @@ intel_init_bufmgr(struct intel_screen *screen)
|
||||
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__);
|
||||
@@ -2561,7 +2564,6 @@ __DRIconfig **intelInitScreen2(__DRIscreen *dri_screen)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
screen->fd = dri_screen->fd;
|
||||
if (!intel_init_bufmgr(screen))
|
||||
return NULL;
|
||||
|
||||
|
Reference in New Issue
Block a user