vulkan: Avoid blocking waits on the gpu on blit

This allows the blit-filter to run in synchronous or asynchronous mode.
In asynchronous mode the blocking wait on the gpu is replaced by
registering a fd from vulkan with the event loop.
This commit is contained in:
columbarius 2024-03-17 20:29:19 +01:00
parent 2821b05d0b
commit d2d50a7d88
4 changed files with 128 additions and 16 deletions

View file

@ -103,7 +103,7 @@ static int runExportSHMBuffers(struct vulkan_blit_state *s) {
* ret = 0: queueSubmit was succsessful, but manual synchronization is required
* ret = 1: queueSubmit was succsessful and buffers can be released without synchronization
*/
static int runCommandBuffer(struct vulkan_blit_state *s)
static int runCommandBuffer(struct vulkan_blit_state *s, int *fd)
{
VULKAN_INSTANCE_FUNCTION(vkQueueSubmit2KHR);
VULKAN_INSTANCE_FUNCTION(vkGetSemaphoreFdKHR);
@ -284,7 +284,11 @@ static int runCommandBuffer(struct vulkan_blit_state *s)
ret = 0;
}
}
close(sync_file_fd);
if (fd) {
*fd = sync_file_fd;
} else {
close(sync_file_fd);
}
return ret;
}
@ -568,13 +572,43 @@ int spa_vulkan_blit_process(struct vulkan_blit_state *s)
return -1;
}
CHECK(updateBuffers(s));
CHECK(runCommandBuffer(s));
CHECK(runCommandBuffer(s, NULL));
CHECK(vulkan_wait_idle(&s->base));
CHECK(runExportSHMBuffers(s));
return 0;
}
int spa_vulkan_blit_queue(struct vulkan_blit_state *s, int *fd)
{
if (!s->initialized) {
spa_log_warn(s->log, "Renderer not initialized");
return -1;
}
if (!s->prepared) {
spa_log_warn(s->log, "Renderer not prepared");
return -1;
}
CHECK(updateBuffers(s));
CHECK(runCommandBuffer(s, fd));
return 0;
}
int spa_vulkan_blit_finish(struct vulkan_blit_state *s)
{
if (!s->initialized) {
spa_log_warn(s->log, "Renderer not initialized");
return -1;
}
if (!s->prepared) {
spa_log_warn(s->log, "Renderer not prepared");
return -1;
}
CHECK(runExportSHMBuffers(s));
return 0;
}
int spa_vulkan_blit_get_buffer_caps(struct vulkan_blit_state *s, enum spa_direction direction)
{
switch (direction) {