From c76addabd6e36d4c66d68c07bbf4ac177191c98f Mon Sep 17 00:00:00 2001 From: columbarius Date: Sun, 24 Sep 2023 20:37:36 +0200 Subject: [PATCH] vulkan: Support MemPtr as input in blit --- spa/plugins/vulkan/vulkan-blit-utils.c | 45 ++++++++++++++++++++++++-- spa/plugins/vulkan/vulkan-blit-utils.h | 1 + 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/spa/plugins/vulkan/vulkan-blit-utils.c b/spa/plugins/vulkan/vulkan-blit-utils.c index a2ea96b53..fd738ca11 100644 --- a/spa/plugins/vulkan/vulkan-blit-utils.c +++ b/spa/plugins/vulkan/vulkan-blit-utils.c @@ -53,6 +53,31 @@ static int updateBuffers(struct vulkan_blit_state *s) return 0; } +static int runImportSHMBuffers(struct vulkan_blit_state *s) { + struct vulkan_stream *p = &s->streams[SPA_DIRECTION_INPUT]; + + if (p->spa_buffers[p->current_buffer_id]->datas[0].type == SPA_DATA_MemPtr) { + struct vulkan_buffer *vk_buf = &p->buffers[p->current_buffer_id]; + struct spa_buffer *spa_buf = p->spa_buffers[p->current_buffer_id]; + VkBufferImageCopy copy; + struct vulkan_write_pixels_info writeInfo = { + .data = spa_buf->datas[0].data, + .offset = 0, + .stride = p->bpp * p->dim.width, + .bytes_per_pixel = p->bpp, + .size.width = p->dim.width, + .size.height = p->dim.height, + .copies = ©, + }; + CHECK(vulkan_write_pixels(&s->base, &writeInfo, &s->staging_buffer)); + + vkCmdCopyBufferToImage(s->commandBuffer, s->staging_buffer.buffer, vk_buf->image, + VK_IMAGE_LAYOUT_GENERAL, 1, ©); + } + + return 0; +} + static int runExportSHMBuffers(struct vulkan_blit_state *s) { struct vulkan_stream *p = &s->streams[SPA_DIRECTION_OUTPUT]; @@ -89,6 +114,8 @@ static int runCommandBuffer(struct vulkan_blit_state *s) }; VK_CHECK_RESULT(vkBeginCommandBuffer(s->commandBuffer, &beginInfo)); + CHECK(runImportSHMBuffers(s)); + uint32_t i; struct vulkan_stream *stream_input = &s->streams[SPA_DIRECTION_INPUT]; struct vulkan_stream *stream_output = &s->streams[SPA_DIRECTION_OUTPUT]; @@ -271,6 +298,10 @@ static void clear_buffers(struct vulkan_blit_state *s, struct vulkan_stream *p) p->spa_buffers[i] = NULL; } p->n_buffers = 0; + if (p->direction == SPA_DIRECTION_INPUT) { + vulkan_staging_buffer_destroy(&s->base, &s->staging_buffer); + s->staging_buffer.buffer = VK_NULL_HANDLE; + } } static void clear_streams(struct vulkan_blit_state *s) @@ -366,8 +397,11 @@ int spa_vulkan_blit_use_buffers(struct vulkan_blit_state *s, struct vulkan_strea ret = vulkan_import_dmabuf(&s->base, &externalBufferInfo, &p->buffers[i]); break; case SPA_DATA_MemPtr:; - if (p->direction == SPA_DIRECTION_OUTPUT) + if (p->direction == SPA_DIRECTION_OUTPUT) { externalBufferInfo.usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + } else { + externalBufferInfo.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; + } ret = vulkan_import_memptr(&s->base, &externalBufferInfo, &p->buffers[i]); break; default: @@ -382,6 +416,13 @@ int spa_vulkan_blit_use_buffers(struct vulkan_blit_state *s, struct vulkan_strea p->spa_buffers[i] = buffers[i]; p->n_buffers++; } + if (p->direction == SPA_DIRECTION_INPUT && buffers[0]->datas[0].type == SPA_DATA_MemPtr) { + ret = vulkan_staging_buffer_create(&s->base, buffers[0]->datas[0].maxsize, &s->staging_buffer); + if (ret < 0) { + spa_log_error(s->log, "Failed to create staging buffer"); + return ret; + } + } return 0; } @@ -529,7 +570,7 @@ int spa_vulkan_blit_get_buffer_caps(struct vulkan_blit_state *s, enum spa_direct { switch (direction) { case SPA_DIRECTION_INPUT: - return VULKAN_BUFFER_TYPE_CAP_DMABUF; + return VULKAN_BUFFER_TYPE_CAP_DMABUF | VULKAN_BUFFER_TYPE_CAP_SHM; case SPA_DIRECTION_OUTPUT: return VULKAN_BUFFER_TYPE_CAP_DMABUF | VULKAN_BUFFER_TYPE_CAP_SHM; } diff --git a/spa/plugins/vulkan/vulkan-blit-utils.h b/spa/plugins/vulkan/vulkan-blit-utils.h index 249a40d26..9fa089c80 100644 --- a/spa/plugins/vulkan/vulkan-blit-utils.h +++ b/spa/plugins/vulkan/vulkan-blit-utils.h @@ -40,6 +40,7 @@ struct vulkan_blit_state { VkCommandPool commandPool; VkCommandBuffer commandBuffer; + struct vulkan_staging_buffer staging_buffer; VkFence fence; VkSemaphore pipelineSemaphore;