From 73d6c20225827e7082720983dba8d2874071c663 Mon Sep 17 00:00:00 2001 From: columbarius Date: Thu, 10 Aug 2023 04:03:44 +0200 Subject: [PATCH] vulkan: spa_vulkan_use_buffers support datatype MemPtr --- spa/plugins/vulkan/vulkan-compute-utils.c | 20 +++++-- spa/plugins/vulkan/vulkan-utils.c | 65 ++++++++++++++++++++++- spa/plugins/vulkan/vulkan-utils.h | 7 +-- 3 files changed, 83 insertions(+), 9 deletions(-) diff --git a/spa/plugins/vulkan/vulkan-compute-utils.c b/spa/plugins/vulkan/vulkan-compute-utils.c index 54c7d867a..dfd8f08d4 100644 --- a/spa/plugins/vulkan/vulkan-compute-utils.c +++ b/spa/plugins/vulkan/vulkan-compute-utils.c @@ -469,7 +469,7 @@ int spa_vulkan_use_buffers(struct vulkan_compute_state *s, struct vulkan_stream for (uint32_t i = 0; i < n_buffers; i++) { if (alloc) { if (SPA_FLAG_IS_SET(buffers[i]->datas[0].type, 1<modifier, .size.width = s->constants.width, @@ -479,7 +479,7 @@ int spa_vulkan_use_buffers(struct vulkan_compute_state *s, struct vulkan_stream : VK_IMAGE_USAGE_SAMPLED_BIT, .spa_buf = buffers[i], }; - ret = vulkan_create_dmabuf(&s->base, &dmabuf_info, &p->buffers[i]); + ret = vulkan_create_dmabuf(&s->base, &dmabufInfo, &p->buffers[i]); } else { spa_log_error(s->log, "Unsupported buffer type mask %d", buffers[i]->datas[0].type); return -1; @@ -487,7 +487,7 @@ int spa_vulkan_use_buffers(struct vulkan_compute_state *s, struct vulkan_stream } else { switch (buffers[i]->datas[0].type) { case SPA_DATA_DmaBuf:; - struct external_dmabuf_info dmabuf_info = { + struct external_buffer_info dmabufInfo = { .format = format, .modifier = dsp_info->modifier, .size.width = s->constants.width, @@ -497,7 +497,19 @@ int spa_vulkan_use_buffers(struct vulkan_compute_state *s, struct vulkan_stream : VK_IMAGE_USAGE_SAMPLED_BIT, .spa_buf = buffers[i], }; - ret = vulkan_import_dmabuf(&s->base, &dmabuf_info, &p->buffers[i]); + ret = vulkan_import_dmabuf(&s->base, &dmabufInfo, &p->buffers[i]); + break; + case SPA_DATA_MemPtr:; + struct external_buffer_info memptrInfo = { + .format = format, + .size.width = s->constants.width, + .size.height = s->constants.height, + .usage = p->direction == SPA_DIRECTION_OUTPUT + ? VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT + : VK_IMAGE_USAGE_SAMPLED_BIT, + .spa_buf = buffers[i], + }; + ret = vulkan_import_memptr(&s->base, &memptrInfo, &p->buffers[i]); break; default: spa_log_error(s->log, "Unsupported buffer type %d", buffers[i]->datas[0].type); diff --git a/spa/plugins/vulkan/vulkan-utils.c b/spa/plugins/vulkan/vulkan-utils.c index cea99e596..62e42eb84 100644 --- a/spa/plugins/vulkan/vulkan-utils.c +++ b/spa/plugins/vulkan/vulkan-utils.c @@ -559,7 +559,7 @@ int vulkan_fixate_modifier(struct vulkan_base *s, struct dmabuf_fixation_info *i return 0; } -int vulkan_create_dmabuf(struct vulkan_base *s, struct external_dmabuf_info *info, struct vulkan_buffer *vk_buf) +int vulkan_create_dmabuf(struct vulkan_base *s, struct external_buffer_info *info, struct vulkan_buffer *vk_buf) { VULKAN_INSTANCE_FUNCTION(vkGetMemoryFdKHR); @@ -624,7 +624,7 @@ int vulkan_create_dmabuf(struct vulkan_base *s, struct external_dmabuf_info *inf return 0; } -int vulkan_import_dmabuf(struct vulkan_base *s, struct external_dmabuf_info *info, struct vulkan_buffer *vk_buf) +int vulkan_import_dmabuf(struct vulkan_base *s, struct external_buffer_info *info, struct vulkan_buffer *vk_buf) { if (info->spa_buf->n_datas == 0 || info->spa_buf->n_datas > DMABUF_MAX_PLANES) @@ -728,6 +728,67 @@ int vulkan_import_dmabuf(struct vulkan_base *s, struct external_dmabuf_info *inf return 0; } +int vulkan_import_memptr(struct vulkan_base *s, struct external_buffer_info *info, struct vulkan_buffer *vk_buf) +{ + VkImageCreateInfo imageCreateInfo = { + .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + .imageType = VK_IMAGE_TYPE_2D, + .format = info->format, + .extent.width = info->size.width, + .extent.height = info->size.height, + .extent.depth = 1, + .mipLevels = 1, + .arrayLayers = 1, + .samples = VK_SAMPLE_COUNT_1_BIT, + .tiling = VK_IMAGE_TILING_LINEAR, + .usage = info->usage, + .sharingMode = VK_SHARING_MODE_EXCLUSIVE, + .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, + }; + + VK_CHECK_RESULT(vkCreateImage(s->device, + &imageCreateInfo, NULL, &vk_buf->image)); + + VkMemoryRequirements memoryRequirements; + vkGetImageMemoryRequirements(s->device, + vk_buf->image, &memoryRequirements); + + VkMemoryAllocateInfo allocateInfo = { + .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, + .allocationSize = memoryRequirements.size, + .memoryTypeIndex = vulkan_memoryType_find(s, + memoryRequirements.memoryTypeBits, + VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT), + }; + + vk_buf->fd = -1; + spa_log_info(s->log, "import MemPtr"); + + VK_CHECK_RESULT(vkAllocateMemory(s->device, + &allocateInfo, NULL, &vk_buf->memory)); + VK_CHECK_RESULT(vkBindImageMemory(s->device, + vk_buf->image, vk_buf->memory, 0)); + + VkImageViewCreateInfo viewInfo = { + .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + .image = vk_buf->image, + .viewType = VK_IMAGE_VIEW_TYPE_2D, + .format = info->format, + .components.r = VK_COMPONENT_SWIZZLE_R, + .components.g = VK_COMPONENT_SWIZZLE_G, + .components.b = VK_COMPONENT_SWIZZLE_B, + .components.a = VK_COMPONENT_SWIZZLE_A, + .subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .subresourceRange.levelCount = 1, + .subresourceRange.layerCount = 1, + }; + + VK_CHECK_RESULT(vkCreateImageView(s->device, + &viewInfo, NULL, &vk_buf->view)); + return 0; +} + int vulkan_stream_init(struct vulkan_stream *stream, enum spa_direction direction, struct spa_dict *props) { diff --git a/spa/plugins/vulkan/vulkan-utils.h b/spa/plugins/vulkan/vulkan-utils.h index 879cc6ff0..7dac6bcbb 100644 --- a/spa/plugins/vulkan/vulkan-utils.h +++ b/spa/plugins/vulkan/vulkan-utils.h @@ -54,7 +54,7 @@ struct dmabuf_fixation_info { VkImageUsageFlags usage; }; -struct external_dmabuf_info { +struct external_buffer_info { VkFormat format; uint64_t modifier; struct spa_rectangle size; @@ -66,8 +66,9 @@ int vulkan_sync_foreign_dmabuf(struct vulkan_base *s, struct vulkan_buffer *vk_b bool vulkan_sync_export_dmabuf(struct vulkan_base *s, struct vulkan_buffer *vk_buf, int sync_file_fd); int vulkan_fixate_modifier(struct vulkan_base *s, struct dmabuf_fixation_info *info, uint64_t *modifier); -int vulkan_create_dmabuf(struct vulkan_base *s, struct external_dmabuf_info *info, struct vulkan_buffer *vk_buf); -int vulkan_import_dmabuf(struct vulkan_base *s, struct external_dmabuf_info *info, struct vulkan_buffer *vk_buf); +int vulkan_create_dmabuf(struct vulkan_base *s, struct external_buffer_info *info, struct vulkan_buffer *vk_buf); +int vulkan_import_dmabuf(struct vulkan_base *s, struct external_buffer_info *info, struct vulkan_buffer *vk_buf); +int vulkan_import_memptr(struct vulkan_base *s, struct external_buffer_info *info, struct vulkan_buffer *vk_buf); int vulkan_commandPool_create(struct vulkan_base *s, VkCommandPool *commandPool); int vulkan_commandBuffer_create(struct vulkan_base *s, VkCommandPool commandPool, VkCommandBuffer *commandBuffer);