mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 22:38:05 +02:00
virgl: do not share virgl_screen between different drm_files
Now, only one instance of virgl_screen exists for a device
(/dev/dri/cardX), and it is shared by different frontends (eg GLX,
GBM, etc.). There is a problem with this, as follows:
/* Init GLX */
...
glXCreateContext(...);
...
/* GBM */
gbm_fd = open("/dev/dri/card0", O_RDWR);
dev = gbm_create_device(gbm_fd);
bo = gbm_bo_create(dev, ...);
plane_handle = gbm_bo_get_handle_for_plane(bo, ...);
drmPrimeHandleToFD(gbm_fd, handle.u32, flags, &plane_fd);
The above drmPrimeHandleToFD() call will fail with ENOENT.
The reason is that GBM and GLX share the same virgl_screen (file
descriptor), and it is not gbm_fd that is used to create gbm_bo,
but other fd (opened during GLX initialization). Since the scope
of prime handle is limited to drm_file, the above plane_handle is
invalid under gbm_fd.
By canceling the sharing of virgl_screen between different drm_files,
GBM can use the correct fd to create resources, thereby avoiding the
problem of invalid prime handle.
Signed-off-by: Feng Jiang <jiangfeng@kylinos.cn>
Reviewed-by: Gert Wollny <gert.wollny@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16738>
This commit is contained in:
parent
883acc4150
commit
2926a1aa76
1 changed files with 38 additions and 1 deletions
|
|
@ -1298,6 +1298,43 @@ virgl_drm_screen_destroy(struct pipe_screen *pscreen)
|
|||
}
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
hash_fd(const void *key)
|
||||
{
|
||||
int fd = pointer_to_intptr(key);
|
||||
|
||||
return _mesa_hash_int(&fd);
|
||||
}
|
||||
|
||||
static bool
|
||||
equal_fd(const void *key1, const void *key2)
|
||||
{
|
||||
int ret;
|
||||
int fd1 = pointer_to_intptr(key1);
|
||||
int fd2 = pointer_to_intptr(key2);
|
||||
|
||||
/* Since the scope of prime handle is limited to drm_file,
|
||||
* virgl_screen is only shared at the drm_file level,
|
||||
* not at the device (/dev/dri/cardX) level.
|
||||
*/
|
||||
ret = os_same_file_description(fd1, fd2);
|
||||
if (ret == 0) {
|
||||
return true;
|
||||
} else if (ret < 0) {
|
||||
static bool logged;
|
||||
|
||||
if (!logged) {
|
||||
_debug_printf("virgl: os_same_file_description couldn't "
|
||||
"determine if two DRM fds reference the same "
|
||||
"file description.\n"
|
||||
"If they do, bad things may happen!\n");
|
||||
logged = true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
struct pipe_screen *
|
||||
virgl_drm_screen_create(int fd, const struct pipe_screen_config *config)
|
||||
{
|
||||
|
|
@ -1305,7 +1342,7 @@ virgl_drm_screen_create(int fd, const struct pipe_screen_config *config)
|
|||
|
||||
mtx_lock(&virgl_screen_mutex);
|
||||
if (!fd_tab) {
|
||||
fd_tab = util_hash_table_create_fd_keys();
|
||||
fd_tab = _mesa_hash_table_create(NULL, hash_fd, equal_fd);
|
||||
if (!fd_tab)
|
||||
goto unlock;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue