mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-03-31 07:11:32 -04:00
render: explicit sync for wlr_texture_read_pixels()
This commit is contained in:
parent
413664e0b0
commit
f295d0322a
6 changed files with 110 additions and 55 deletions
|
|
@ -99,53 +99,6 @@ static void render_pass_destroy(struct wlr_vk_render_pass *pass) {
|
|||
free(pass);
|
||||
}
|
||||
|
||||
static VkSemaphore render_pass_wait_sync_file(struct wlr_vk_render_pass *pass,
|
||||
size_t sem_index, int sync_file_fd) {
|
||||
struct wlr_vk_renderer *renderer = pass->renderer;
|
||||
struct wlr_vk_command_buffer *render_cb = pass->command_buffer;
|
||||
VkResult res;
|
||||
|
||||
VkSemaphore *wait_semaphores = render_cb->wait_semaphores.data;
|
||||
size_t wait_semaphores_len = render_cb->wait_semaphores.size / sizeof(wait_semaphores[0]);
|
||||
|
||||
VkSemaphore *sem_ptr;
|
||||
if (sem_index >= wait_semaphores_len) {
|
||||
sem_ptr = wl_array_add(&render_cb->wait_semaphores, sizeof(*sem_ptr));
|
||||
if (sem_ptr == NULL) {
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
*sem_ptr = VK_NULL_HANDLE;
|
||||
} else {
|
||||
sem_ptr = &wait_semaphores[sem_index];
|
||||
}
|
||||
|
||||
if (*sem_ptr == VK_NULL_HANDLE) {
|
||||
VkSemaphoreCreateInfo semaphore_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
|
||||
};
|
||||
res = vkCreateSemaphore(renderer->dev->dev, &semaphore_info, NULL, sem_ptr);
|
||||
if (res != VK_SUCCESS) {
|
||||
wlr_vk_error("vkCreateSemaphore", res);
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
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 = *sem_ptr,
|
||||
.fd = sync_file_fd,
|
||||
};
|
||||
res = renderer->dev->api.vkImportSemaphoreFdKHR(renderer->dev->dev, &import_info);
|
||||
if (res != VK_SUCCESS) {
|
||||
wlr_vk_error("vkImportSemaphoreFdKHR", res);
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
return *sem_ptr;
|
||||
}
|
||||
|
||||
static bool render_pass_wait_render_buffer(struct wlr_vk_render_pass *pass,
|
||||
VkSemaphoreSubmitInfoKHR *render_wait, uint32_t *render_wait_len_ptr) {
|
||||
int sync_file_fds[WLR_DMABUF_MAX_PLANES];
|
||||
|
|
@ -162,7 +115,8 @@ static bool render_pass_wait_render_buffer(struct wlr_vk_render_pass *pass,
|
|||
continue;
|
||||
}
|
||||
|
||||
VkSemaphore sem = render_pass_wait_sync_file(pass, *render_wait_len_ptr, sync_file_fds[i]);
|
||||
VkSemaphore sem = vulkan_command_buffer_wait_sync_file(pass->renderer,
|
||||
pass->command_buffer, *render_wait_len_ptr, sync_file_fds[i]);
|
||||
if (sem == VK_NULL_HANDLE) {
|
||||
close(sync_file_fds[i]);
|
||||
continue;
|
||||
|
|
@ -431,7 +385,8 @@ static bool render_pass_submit(struct wlr_render_pass *wlr_pass) {
|
|||
continue;
|
||||
}
|
||||
|
||||
VkSemaphore sem = render_pass_wait_sync_file(pass, render_wait_len, sync_file_fds[i]);
|
||||
VkSemaphore sem = vulkan_command_buffer_wait_sync_file(renderer, render_cb,
|
||||
render_wait_len, sync_file_fds[i]);
|
||||
if (sem == VK_NULL_HANDLE) {
|
||||
close(sync_file_fds[i]);
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -379,7 +379,52 @@ VkCommandBuffer vulkan_record_stage_cb(struct wlr_vk_renderer *renderer) {
|
|||
return renderer->stage.cb->vk;
|
||||
}
|
||||
|
||||
bool vulkan_submit_stage_wait(struct wlr_vk_renderer *renderer) {
|
||||
VkSemaphore vulkan_command_buffer_wait_sync_file(struct wlr_vk_renderer *renderer,
|
||||
struct wlr_vk_command_buffer *render_cb, size_t sem_index, int sync_file_fd) {
|
||||
VkResult res;
|
||||
|
||||
VkSemaphore *wait_semaphores = render_cb->wait_semaphores.data;
|
||||
size_t wait_semaphores_len = render_cb->wait_semaphores.size / sizeof(wait_semaphores[0]);
|
||||
|
||||
VkSemaphore *sem_ptr;
|
||||
if (sem_index >= wait_semaphores_len) {
|
||||
sem_ptr = wl_array_add(&render_cb->wait_semaphores, sizeof(*sem_ptr));
|
||||
if (sem_ptr == NULL) {
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
*sem_ptr = VK_NULL_HANDLE;
|
||||
} else {
|
||||
sem_ptr = &wait_semaphores[sem_index];
|
||||
}
|
||||
|
||||
if (*sem_ptr == VK_NULL_HANDLE) {
|
||||
VkSemaphoreCreateInfo semaphore_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
|
||||
};
|
||||
res = vkCreateSemaphore(renderer->dev->dev, &semaphore_info, NULL, sem_ptr);
|
||||
if (res != VK_SUCCESS) {
|
||||
wlr_vk_error("vkCreateSemaphore", res);
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
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 = *sem_ptr,
|
||||
.fd = sync_file_fd,
|
||||
};
|
||||
res = renderer->dev->api.vkImportSemaphoreFdKHR(renderer->dev->dev, &import_info);
|
||||
if (res != VK_SUCCESS) {
|
||||
wlr_vk_error("vkImportSemaphoreFdKHR", res);
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
return *sem_ptr;
|
||||
}
|
||||
|
||||
bool vulkan_submit_stage_wait(struct wlr_vk_renderer *renderer, int wait_sync_file_fd) {
|
||||
if (renderer->stage.cb == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -389,9 +434,12 @@ bool vulkan_submit_stage_wait(struct wlr_vk_renderer *renderer) {
|
|||
|
||||
uint64_t timeline_point = vulkan_end_command_buffer(cb, renderer);
|
||||
if (timeline_point == 0) {
|
||||
close(wait_sync_file_fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
VkSemaphore wait_semaphore;
|
||||
VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
|
||||
VkTimelineSemaphoreSubmitInfoKHR timeline_submit_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR,
|
||||
.signalSemaphoreValueCount = 1,
|
||||
|
|
@ -405,6 +453,18 @@ bool vulkan_submit_stage_wait(struct wlr_vk_renderer *renderer) {
|
|||
.signalSemaphoreCount = 1,
|
||||
.pSignalSemaphores = &renderer->timeline_semaphore,
|
||||
};
|
||||
|
||||
if (wait_sync_file_fd != -1) {
|
||||
wait_semaphore = vulkan_command_buffer_wait_sync_file(renderer, cb, 0, wait_sync_file_fd);
|
||||
if (wait_semaphore == VK_NULL_HANDLE) {
|
||||
close(wait_sync_file_fd);
|
||||
return false;
|
||||
}
|
||||
submit_info.waitSemaphoreCount = 1;
|
||||
submit_info.pWaitSemaphores = &wait_semaphore;
|
||||
submit_info.pWaitDstStageMask = &wait_stage;
|
||||
}
|
||||
|
||||
VkResult res = vkQueueSubmit(renderer->dev->queue, 1, &submit_info, VK_NULL_HANDLE);
|
||||
if (res != VK_SUCCESS) {
|
||||
wlr_vk_error("vkQueueSubmit", res);
|
||||
|
|
@ -1218,7 +1278,8 @@ bool vulkan_read_pixels(struct wlr_vk_renderer *vk_renderer,
|
|||
VkFormat src_format, VkImage src_image,
|
||||
uint32_t drm_format, uint32_t stride,
|
||||
uint32_t width, uint32_t height, uint32_t src_x, uint32_t src_y,
|
||||
uint32_t dst_x, uint32_t dst_y, void *data) {
|
||||
uint32_t dst_x, uint32_t dst_y, void *data,
|
||||
struct wlr_drm_syncobj_timeline *wait_timeline, uint64_t wait_point) {
|
||||
VkDevice dev = vk_renderer->dev->dev;
|
||||
|
||||
const struct wlr_pixel_format_info *pixel_format_info = drm_get_pixel_format_info(drm_format);
|
||||
|
|
@ -1404,7 +1465,17 @@ bool vulkan_read_pixels(struct wlr_vk_renderer *vk_renderer,
|
|||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_ACCESS_MEMORY_READ_BIT);
|
||||
|
||||
if (!vulkan_submit_stage_wait(vk_renderer)) {
|
||||
int wait_sync_file_fd = -1;
|
||||
if (wait_timeline != NULL) {
|
||||
wait_sync_file_fd = wlr_drm_syncobj_timeline_export_sync_file(wait_timeline, wait_point);
|
||||
if (wait_sync_file_fd < 0) {
|
||||
wlr_log(WLR_ERROR, "Failed to export wait timeline point as sync_file");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!vulkan_submit_stage_wait(vk_renderer, wait_sync_file_fd)) {
|
||||
close(wait_sync_file_fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -238,7 +238,8 @@ static bool vulkan_texture_read_pixels(struct wlr_texture *wlr_texture,
|
|||
void *p = wlr_texture_read_pixel_options_get_data(options);
|
||||
|
||||
return vulkan_read_pixels(texture->renderer, texture->format->vk, texture->image,
|
||||
options->format, options->stride, src.width, src.height, src.x, src.y, 0, 0, p);
|
||||
options->format, options->stride, src.width, src.height, src.x, src.y, 0, 0, p,
|
||||
options->wait_timeline, options->wait_point);
|
||||
}
|
||||
|
||||
static uint32_t vulkan_texture_preferred_read_format(struct wlr_texture *wlr_texture) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue