mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-02-13 04:27:56 -05:00
render/vulkan: add support for explicit sync
This commit is contained in:
parent
9351c78d70
commit
3bbfae73ae
5 changed files with 190 additions and 71 deletions
|
|
@ -13,6 +13,7 @@
|
|||
#include <wlr/types/wlr_drm.h>
|
||||
#include <wlr/util/box.h>
|
||||
#include <wlr/util/log.h>
|
||||
#include <wlr/render/drm_syncobj.h>
|
||||
#include <wlr/render/vulkan.h>
|
||||
#include <wlr/backend/interface.h>
|
||||
#include <wlr/types/wlr_linux_dmabuf_v1.h>
|
||||
|
|
@ -921,9 +922,9 @@ static struct wlr_vk_render_buffer *get_render_buffer(
|
|||
return buffer;
|
||||
}
|
||||
|
||||
bool vulkan_sync_foreign_texture(struct wlr_vk_texture *texture) {
|
||||
bool vulkan_sync_foreign_texture(struct wlr_vk_texture *texture,
|
||||
int sync_file_fds[static WLR_DMABUF_MAX_PLANES]) {
|
||||
struct wlr_vk_renderer *renderer = texture->renderer;
|
||||
VkResult res;
|
||||
|
||||
struct wlr_dmabuf_attributes dmabuf = {0};
|
||||
if (!wlr_buffer_get_dmabuf(texture->buffer, &dmabuf)) {
|
||||
|
|
@ -960,52 +961,22 @@ bool vulkan_sync_foreign_texture(struct wlr_vk_texture *texture) {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (texture->foreign_semaphores[i] == VK_NULL_HANDLE) {
|
||||
VkSemaphoreCreateInfo semaphore_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
|
||||
};
|
||||
res = vkCreateSemaphore(renderer->dev->dev, &semaphore_info, NULL,
|
||||
&texture->foreign_semaphores[i]);
|
||||
if (res != VK_SUCCESS) {
|
||||
close(sync_file_fd);
|
||||
wlr_vk_error("vkCreateSemaphore", res);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
VkImportSemaphoreFdInfoKHR import_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR,
|
||||
.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
|
||||
.flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT,
|
||||
.semaphore = texture->foreign_semaphores[i],
|
||||
.fd = sync_file_fd,
|
||||
};
|
||||
res = renderer->dev->api.vkImportSemaphoreFdKHR(renderer->dev->dev, &import_info);
|
||||
if (res != VK_SUCCESS) {
|
||||
close(sync_file_fd);
|
||||
wlr_vk_error("vkImportSemaphoreFdKHR", res);
|
||||
return false;
|
||||
}
|
||||
sync_file_fds[i] = sync_file_fd;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool vulkan_sync_render_buffer(struct wlr_vk_renderer *renderer,
|
||||
struct wlr_vk_render_buffer *render_buffer, struct wlr_vk_command_buffer *cb) {
|
||||
struct wlr_vk_render_buffer *render_buffer, struct wlr_vk_command_buffer *cb,
|
||||
struct wlr_drm_syncobj_timeline *signal_timeline, uint64_t signal_point) {
|
||||
VkResult res;
|
||||
|
||||
if (!renderer->dev->implicit_sync_interop) {
|
||||
if (!renderer->dev->implicit_sync_interop && signal_timeline == NULL) {
|
||||
// We have no choice but to block here sadly
|
||||
return vulkan_wait_command_buffer(cb, renderer);
|
||||
}
|
||||
|
||||
struct wlr_dmabuf_attributes dmabuf = {0};
|
||||
if (!wlr_buffer_get_dmabuf(render_buffer->wlr_buffer, &dmabuf)) {
|
||||
wlr_log(WLR_ERROR, "wlr_buffer_get_dmabuf failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Note: vkGetSemaphoreFdKHR implicitly resets the semaphore
|
||||
const VkSemaphoreGetFdInfoKHR get_fence_fd_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
|
||||
|
|
@ -1020,17 +991,32 @@ bool vulkan_sync_render_buffer(struct wlr_vk_renderer *renderer,
|
|||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < dmabuf.n_planes; i++) {
|
||||
if (!dmabuf_import_sync_file(dmabuf.fd[i], DMA_BUF_SYNC_WRITE,
|
||||
sync_file_fd)) {
|
||||
close(sync_file_fd);
|
||||
return false;
|
||||
bool ok = false;
|
||||
if (signal_timeline != NULL) {
|
||||
if (!wlr_drm_syncobj_timeline_import_sync_file(signal_timeline,
|
||||
signal_point, sync_file_fd)) {
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
struct wlr_dmabuf_attributes dmabuf = {0};
|
||||
if (!wlr_buffer_get_dmabuf(render_buffer->wlr_buffer, &dmabuf)) {
|
||||
wlr_log(WLR_ERROR, "wlr_buffer_get_dmabuf failed");
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (int i = 0; i < dmabuf.n_planes; i++) {
|
||||
if (!dmabuf_import_sync_file(dmabuf.fd[i], DMA_BUF_SYNC_WRITE,
|
||||
sync_file_fd)) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
close(sync_file_fd);
|
||||
ok = true;
|
||||
|
||||
return true;
|
||||
out:
|
||||
close(sync_file_fd);
|
||||
return ok;
|
||||
}
|
||||
|
||||
static const struct wlr_drm_format_set *vulkan_get_texture_formats(
|
||||
|
|
@ -1073,6 +1059,11 @@ static void vulkan_destroy(struct wlr_renderer *wlr_renderer) {
|
|||
if (cb->binary_semaphore != VK_NULL_HANDLE) {
|
||||
vkDestroySemaphore(renderer->dev->dev, cb->binary_semaphore, NULL);
|
||||
}
|
||||
VkSemaphore *sem_ptr;
|
||||
wl_array_for_each(sem_ptr, &cb->wait_semaphores) {
|
||||
vkDestroySemaphore(renderer->dev->dev, *sem_ptr, NULL);
|
||||
}
|
||||
wl_array_release(&cb->wait_semaphores);
|
||||
}
|
||||
|
||||
// stage.cb automatically freed with command pool
|
||||
|
|
@ -2436,6 +2427,11 @@ struct wlr_renderer *vulkan_renderer_create_for_device(struct wlr_vk_device *dev
|
|||
wl_list_init(&renderer->color_transforms);
|
||||
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) {
|
||||
renderer->wlr_renderer.features.timeline = dev->sync_file_import_export && cap_syncobj_timeline != 0;
|
||||
}
|
||||
|
||||
if (!init_static_render_data(renderer)) {
|
||||
goto error;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue