vulkan: Support MemPtr as input in blit

This commit is contained in:
columbarius 2023-09-24 20:37:36 +02:00
parent 7e40aec64e
commit c76addabd6
2 changed files with 44 additions and 2 deletions

View file

@ -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 = &copy,
};
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, &copy);
}
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;
}