iris: share buffer managers accross screens
St happilly uses pipe_resources created with one screen with other screens. Unfortunately our resources have a single identifier that related to a given screen and its associated DRM file descriptor. To workaround this, let's share the buffer manager between screens for a given DRM device. That way handles are always valid. v2: Don't forget to close the fd that bufmgr now owns Take a copy of the fd to ensure it stays alive even if the dri layer closes it 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:
parent
bd3e505453
commit
7557f16059
|
@ -49,6 +49,7 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "errno.h"
|
#include "errno.h"
|
||||||
#include "common/gen_aux_map.h"
|
#include "common/gen_aux_map.h"
|
||||||
|
@ -126,6 +127,13 @@ struct bo_cache_bucket {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct iris_bufmgr {
|
struct iris_bufmgr {
|
||||||
|
/**
|
||||||
|
* List into the list of bufmgr.
|
||||||
|
*/
|
||||||
|
struct list_head link;
|
||||||
|
|
||||||
|
uint32_t refcount;
|
||||||
|
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
mtx_t lock;
|
mtx_t lock;
|
||||||
|
@ -152,6 +160,12 @@ struct iris_bufmgr {
|
||||||
struct gen_aux_map_context *aux_map_ctx;
|
struct gen_aux_map_context *aux_map_ctx;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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 iris_bo *bo, uint32_t tiling_mode,
|
static int bo_set_tiling_internal(struct iris_bo *bo, uint32_t tiling_mode,
|
||||||
uint32_t stride);
|
uint32_t stride);
|
||||||
|
|
||||||
|
@ -1201,7 +1215,7 @@ iris_bo_wait(struct iris_bo *bo, int64_t timeout_ns)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
iris_bufmgr_destroy(struct iris_bufmgr *bufmgr)
|
iris_bufmgr_destroy(struct iris_bufmgr *bufmgr)
|
||||||
{
|
{
|
||||||
/* Free aux-map buffers */
|
/* Free aux-map buffers */
|
||||||
|
@ -1237,6 +1251,8 @@ iris_bufmgr_destroy(struct iris_bufmgr *bufmgr)
|
||||||
util_vma_heap_finish(&bufmgr->vma_allocator[z]);
|
util_vma_heap_finish(&bufmgr->vma_allocator[z]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
close(bufmgr->fd);
|
||||||
|
|
||||||
free(bufmgr);
|
free(bufmgr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1622,8 +1638,8 @@ static struct gen_mapped_pinned_buffer_alloc aux_map_allocator = {
|
||||||
*
|
*
|
||||||
* \param fd File descriptor of the opened DRM device.
|
* \param fd File descriptor of the opened DRM device.
|
||||||
*/
|
*/
|
||||||
struct iris_bufmgr *
|
static struct iris_bufmgr *
|
||||||
iris_bufmgr_init(struct gen_device_info *devinfo, int fd, bool bo_reuse)
|
iris_bufmgr_create(struct gen_device_info *devinfo, int fd, bool bo_reuse)
|
||||||
{
|
{
|
||||||
uint64_t gtt_size = iris_gtt_size(fd);
|
uint64_t gtt_size = iris_gtt_size(fd);
|
||||||
if (gtt_size <= IRIS_MEMZONE_OTHER_START)
|
if (gtt_size <= IRIS_MEMZONE_OTHER_START)
|
||||||
|
@ -1642,9 +1658,12 @@ iris_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
|
* Don't do this! Ensure that each library/bufmgr has its own device
|
||||||
* fd so that its namespace does not clash with another.
|
* fd so that its namespace does not clash with another.
|
||||||
*/
|
*/
|
||||||
bufmgr->fd = fd;
|
bufmgr->fd = dup(fd);
|
||||||
|
|
||||||
|
p_atomic_set(&bufmgr->refcount, 1);
|
||||||
|
|
||||||
if (mtx_init(&bufmgr->lock, mtx_plain) != 0) {
|
if (mtx_init(&bufmgr->lock, mtx_plain) != 0) {
|
||||||
|
close(bufmgr->fd);
|
||||||
free(bufmgr);
|
free(bufmgr);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1700,6 +1719,67 @@ iris_bufmgr_init(struct gen_device_info *devinfo, int fd, bool bo_reuse)
|
||||||
return bufmgr;
|
return bufmgr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct iris_bufmgr *
|
||||||
|
iris_bufmgr_ref(struct iris_bufmgr *bufmgr)
|
||||||
|
{
|
||||||
|
p_atomic_inc(&bufmgr->refcount);
|
||||||
|
return bufmgr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
iris_bufmgr_unref(struct iris_bufmgr *bufmgr)
|
||||||
|
{
|
||||||
|
mtx_lock(&global_bufmgr_list_mutex);
|
||||||
|
if (p_atomic_dec_zero(&bufmgr->refcount)) {
|
||||||
|
list_del(&bufmgr->link);
|
||||||
|
iris_bufmgr_destroy(bufmgr);
|
||||||
|
}
|
||||||
|
mtx_unlock(&global_bufmgr_list_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an already existing GEM buffer manager or create a new one.
|
||||||
|
*
|
||||||
|
* \param fd File descriptor of the opened DRM device.
|
||||||
|
*/
|
||||||
|
struct iris_bufmgr *
|
||||||
|
iris_bufmgr_get_for_fd(struct gen_device_info *devinfo, int fd, bool bo_reuse)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
if (fstat(fd, &st))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
struct iris_bufmgr *bufmgr = NULL;
|
||||||
|
|
||||||
|
mtx_lock(&global_bufmgr_list_mutex);
|
||||||
|
list_for_each_entry(struct iris_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 = iris_bufmgr_ref(iter_bufmgr);
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bufmgr = iris_bufmgr_create(devinfo, fd, bo_reuse);
|
||||||
|
list_addtail(&bufmgr->link, &global_bufmgr_list);
|
||||||
|
|
||||||
|
unlock:
|
||||||
|
mtx_unlock(&global_bufmgr_list_mutex);
|
||||||
|
|
||||||
|
return bufmgr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
iris_bufmgr_get_fd(struct iris_bufmgr *bufmgr)
|
||||||
|
{
|
||||||
|
return bufmgr->fd;
|
||||||
|
}
|
||||||
|
|
||||||
void*
|
void*
|
||||||
iris_bufmgr_get_aux_map_context(struct iris_bufmgr *bufmgr)
|
iris_bufmgr_get_aux_map_context(struct iris_bufmgr *bufmgr)
|
||||||
{
|
{
|
||||||
|
|
|
@ -285,10 +285,11 @@ static inline int iris_bo_unmap(struct iris_bo *bo) { return 0; }
|
||||||
*/
|
*/
|
||||||
void iris_bo_wait_rendering(struct iris_bo *bo);
|
void iris_bo_wait_rendering(struct iris_bo *bo);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tears down the buffer manager instance.
|
* Unref a buffer manager instance.
|
||||||
*/
|
*/
|
||||||
void iris_bufmgr_destroy(struct iris_bufmgr *bufmgr);
|
void iris_bufmgr_unref(struct iris_bufmgr *bufmgr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current tiling (and resulting swizzling) mode for the bo.
|
* Get the current tiling (and resulting swizzling) mode for the bo.
|
||||||
|
@ -329,8 +330,10 @@ int iris_bo_busy(struct iris_bo *bo);
|
||||||
int iris_bo_madvise(struct iris_bo *bo, int madv);
|
int iris_bo_madvise(struct iris_bo *bo, int madv);
|
||||||
|
|
||||||
/* drm_bacon_bufmgr_gem.c */
|
/* drm_bacon_bufmgr_gem.c */
|
||||||
struct iris_bufmgr *iris_bufmgr_init(struct gen_device_info *devinfo, int fd,
|
struct iris_bufmgr *iris_bufmgr_get_for_fd(struct gen_device_info *devinfo, int fd,
|
||||||
bool bo_reuse);
|
bool bo_reuse);
|
||||||
|
int iris_bufmgr_get_fd(struct iris_bufmgr *bufmgr);
|
||||||
|
|
||||||
struct iris_bo *iris_bo_gem_create_from_name(struct iris_bufmgr *bufmgr,
|
struct iris_bo *iris_bo_gem_create_from_name(struct iris_bufmgr *bufmgr,
|
||||||
const char *name,
|
const char *name,
|
||||||
unsigned handle);
|
unsigned handle);
|
||||||
|
|
|
@ -527,9 +527,8 @@ iris_destroy_screen(struct pipe_screen *pscreen)
|
||||||
struct iris_screen *screen = (struct iris_screen *) pscreen;
|
struct iris_screen *screen = (struct iris_screen *) pscreen;
|
||||||
iris_bo_unreference(screen->workaround_bo);
|
iris_bo_unreference(screen->workaround_bo);
|
||||||
u_transfer_helper_destroy(pscreen->transfer_helper);
|
u_transfer_helper_destroy(pscreen->transfer_helper);
|
||||||
iris_bufmgr_destroy(screen->bufmgr);
|
iris_bufmgr_unref(screen->bufmgr);
|
||||||
disk_cache_destroy(screen->disk_cache);
|
disk_cache_destroy(screen->disk_cache);
|
||||||
close(screen->fd);
|
|
||||||
ralloc_free(screen);
|
ralloc_free(screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -635,8 +634,6 @@ iris_screen_create(int fd, const struct pipe_screen_config *config)
|
||||||
if (!screen)
|
if (!screen)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
screen->fd = fd;
|
|
||||||
|
|
||||||
if (!gen_get_device_info_from_fd(fd, &screen->devinfo))
|
if (!gen_get_device_info_from_fd(fd, &screen->devinfo))
|
||||||
return NULL;
|
return NULL;
|
||||||
screen->pci_id = screen->devinfo.chipset_id;
|
screen->pci_id = screen->devinfo.chipset_id;
|
||||||
|
@ -645,11 +642,6 @@ iris_screen_create(int fd, const struct pipe_screen_config *config)
|
||||||
if (screen->devinfo.gen < 8 || screen->devinfo.is_cherryview)
|
if (screen->devinfo.gen < 8 || screen->devinfo.is_cherryview)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
screen->aperture_bytes = get_aperture_size(fd);
|
|
||||||
|
|
||||||
if (getenv("INTEL_NO_HW") != NULL)
|
|
||||||
screen->no_hw = true;
|
|
||||||
|
|
||||||
bool bo_reuse = false;
|
bool bo_reuse = false;
|
||||||
int bo_reuse_mode = driQueryOptioni(config->options, "bo_reuse");
|
int bo_reuse_mode = driQueryOptioni(config->options, "bo_reuse");
|
||||||
switch (bo_reuse_mode) {
|
switch (bo_reuse_mode) {
|
||||||
|
@ -660,10 +652,17 @@ iris_screen_create(int fd, const struct pipe_screen_config *config)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
screen->bufmgr = iris_bufmgr_init(&screen->devinfo, fd, bo_reuse);
|
screen->bufmgr = iris_bufmgr_get_for_fd(&screen->devinfo, fd, bo_reuse);
|
||||||
if (!screen->bufmgr)
|
if (!screen->bufmgr)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
screen->fd = iris_bufmgr_get_fd(screen->bufmgr);
|
||||||
|
|
||||||
|
screen->aperture_bytes = get_aperture_size(fd);
|
||||||
|
|
||||||
|
if (getenv("INTEL_NO_HW") != NULL)
|
||||||
|
screen->no_hw = true;
|
||||||
|
|
||||||
screen->workaround_bo =
|
screen->workaround_bo =
|
||||||
iris_bo_alloc(screen->bufmgr, "workaround", 4096, IRIS_MEMZONE_OTHER);
|
iris_bo_alloc(screen->bufmgr, "workaround", 4096, IRIS_MEMZONE_OTHER);
|
||||||
if (!screen->workaround_bo)
|
if (!screen->workaround_bo)
|
||||||
|
|
|
@ -49,7 +49,7 @@ struct iris_screen {
|
||||||
/** Global slab allocator for iris_transfer_map objects */
|
/** Global slab allocator for iris_transfer_map objects */
|
||||||
struct slab_parent_pool transfer_pool;
|
struct slab_parent_pool transfer_pool;
|
||||||
|
|
||||||
/** drm device file descriptor */
|
/** drm device file descriptor, on shared with bufmgr, do not close. */
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
/** PCI ID for our GPU device */
|
/** PCI ID for our GPU device */
|
||||||
|
|
Loading…
Reference in New Issue