render/pixman: Add dmabuf support

Adds linux-dmabuf support to the pixman renderer.  The main reason is so
clients can use GPU-accelerated rendering even if the compositor is
using the pixman renderer for whatever reason.  This also allows the
pixman renderer to import dmabufs (only RGB/ARGB formats, not YUV for
now).

Since after this change all renderers store a DRM FD, I move the drm_fd
from the individual implementations to the shared wlr_renderer base.
This means that renderer_autocreate() can set pixman's drm_fd for it and
the pixman renderer doesn't have to know about DRM at all.

Originally based on
961edfe44e
This commit is contained in:
David Turner 2024-06-10 17:10:20 +01:00
parent 27bbb91abf
commit e4ccc8e822
10 changed files with 36 additions and 42 deletions

View file

@ -1153,6 +1153,11 @@ static void vulkan_destroy(struct wlr_renderer *wlr_renderer) {
struct wlr_vk_instance *ini = dev->instance;
vulkan_device_destroy(dev);
vulkan_instance_destroy(ini);
if (wlr_renderer->drm_fd > 0) {
close(wlr_renderer->drm_fd);
}
free(renderer);
}
@ -1402,11 +1407,6 @@ destroy_image:
return false;
}
static int vulkan_get_drm_fd(struct wlr_renderer *wlr_renderer) {
struct wlr_vk_renderer *renderer = vulkan_get_renderer(wlr_renderer);
return renderer->dev->drm_fd;
}
static struct wlr_render_pass *vulkan_begin_buffer_pass(struct wlr_renderer *wlr_renderer,
struct wlr_buffer *buffer, const struct wlr_buffer_pass_options *options) {
struct wlr_vk_renderer *renderer = vulkan_get_renderer(wlr_renderer);
@ -1431,7 +1431,6 @@ static const struct wlr_renderer_impl renderer_impl = {
.get_texture_formats = vulkan_get_texture_formats,
.get_render_formats = vulkan_get_render_formats,
.destroy = vulkan_destroy,
.get_drm_fd = vulkan_get_drm_fd,
.texture_from_buffer = vulkan_texture_from_buffer,
.begin_buffer_pass = vulkan_begin_buffer_pass,
};
@ -2442,7 +2441,8 @@ struct wlr_renderer *vulkan_renderer_create_for_device(struct wlr_vk_device *dev
wl_list_init(&renderer->pipeline_layouts);
uint64_t cap_syncobj_timeline;
if (dev->drm_fd >= 0 && drmGetCap(dev->drm_fd, DRM_CAP_SYNCOBJ_TIMELINE, &cap_syncobj_timeline) == 0) {
if (renderer->wlr_renderer.drm_fd >= 0 &&
drmGetCap(renderer->wlr_renderer.drm_fd, DRM_CAP_SYNCOBJ_TIMELINE, &cap_syncobj_timeline) == 0) {
renderer->wlr_renderer.features.timeline = dev->sync_file_import_export && cap_syncobj_timeline != 0;
}
@ -2513,9 +2513,11 @@ struct wlr_renderer *wlr_vk_renderer_create_with_drm_fd(int drm_fd) {
// Do not use the drm_fd that was passed in: we should prefer the render
// node even if a primary node was provided
dev->drm_fd = vulkan_open_phdev_drm_fd(phdev);
int render_drm_fd = vulkan_open_phdev_drm_fd(phdev);
return vulkan_renderer_create_for_device(dev);
struct wlr_renderer *wlr_renderer = vulkan_renderer_create_for_device(dev);
wlr_renderer->drm_fd = render_drm_fd;
return wlr_renderer;
}
VkInstance wlr_vk_renderer_get_instance(struct wlr_renderer *renderer) {