mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-02 09:01:50 -05:00
vulkan: split spa_vulkan_use_buffers into separate allocation and import functions
This commit add helpers to create and to import a DmaBuf via the external_dmabuf_info struct. The import path is based on the image creation of wlroots and the create path is inspired by the wlroots vulkan allocator MR.
This commit is contained in:
parent
2068972bb3
commit
35b080ec61
3 changed files with 301 additions and 106 deletions
|
|
@ -31,12 +31,6 @@
|
||||||
#define VULKAN_INSTANCE_FUNCTION(name) \
|
#define VULKAN_INSTANCE_FUNCTION(name) \
|
||||||
PFN_##name name = (PFN_##name)vkGetInstanceProcAddr(s->base.instance, #name)
|
PFN_##name name = (PFN_##name)vkGetInstanceProcAddr(s->base.instance, #name)
|
||||||
|
|
||||||
static uint32_t findMemoryType(struct vulkan_compute_state *s,
|
|
||||||
uint32_t memoryTypeBits, VkMemoryPropertyFlags properties)
|
|
||||||
{
|
|
||||||
return vulkan_memoryType_find(&s->base, memoryTypeBits, properties);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int createFence(struct vulkan_compute_state *s) {
|
static int createFence(struct vulkan_compute_state *s) {
|
||||||
VkFenceCreateInfo createInfo = {
|
VkFenceCreateInfo createInfo = {
|
||||||
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
|
||||||
|
|
@ -334,115 +328,60 @@ static void clear_streams(struct vulkan_compute_state *s)
|
||||||
int spa_vulkan_use_buffers(struct vulkan_compute_state *s, struct vulkan_stream *p, uint32_t flags,
|
int spa_vulkan_use_buffers(struct vulkan_compute_state *s, struct vulkan_stream *p, uint32_t flags,
|
||||||
struct spa_video_info_dsp *dsp_info, uint32_t n_buffers, struct spa_buffer **buffers)
|
struct spa_video_info_dsp *dsp_info, uint32_t n_buffers, struct spa_buffer **buffers)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
|
||||||
VULKAN_INSTANCE_FUNCTION(vkGetMemoryFdKHR);
|
|
||||||
|
|
||||||
VkFormat format = vulkan_id_to_vkformat(dsp_info->format);
|
VkFormat format = vulkan_id_to_vkformat(dsp_info->format);
|
||||||
if (format == VK_FORMAT_UNDEFINED)
|
if (format == VK_FORMAT_UNDEFINED)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
vulkan_wait_idle(&s->base);
|
||||||
clear_buffers(s, p);
|
clear_buffers(s, p);
|
||||||
|
|
||||||
for (i = 0; i < n_buffers; i++) {
|
bool alloc = flags & SPA_NODE_BUFFERS_FLAG_ALLOC;
|
||||||
VkExternalMemoryImageCreateInfo extInfo;
|
int ret;
|
||||||
VkImageCreateInfo imageCreateInfo = {
|
p->n_buffers = 0;
|
||||||
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
for (uint32_t i = 0; i < n_buffers; i++) {
|
||||||
.imageType = VK_IMAGE_TYPE_2D,
|
if (alloc) {
|
||||||
.format = format,
|
if (SPA_FLAG_IS_SET(buffers[i]->datas[0].type, 1<<SPA_DATA_DmaBuf)) {
|
||||||
.extent.width = s->constants.width,
|
struct external_dmabuf_info dmabuf_info = {
|
||||||
.extent.height = s->constants.height,
|
.format = format,
|
||||||
.extent.depth = 1,
|
.modifier = dsp_info->modifier,
|
||||||
.mipLevels = 1,
|
.size.width = s->constants.width,
|
||||||
.arrayLayers = 1,
|
.size.height = s->constants.height,
|
||||||
.samples = VK_SAMPLE_COUNT_1_BIT,
|
.usage = p->direction == SPA_DIRECTION_OUTPUT
|
||||||
.tiling = VK_IMAGE_TILING_LINEAR,
|
? VK_IMAGE_USAGE_STORAGE_BIT
|
||||||
.usage = p->direction == SPA_DIRECTION_OUTPUT ?
|
: VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||||
VK_IMAGE_USAGE_STORAGE_BIT:
|
.spa_buf = buffers[i],
|
||||||
VK_IMAGE_USAGE_SAMPLED_BIT,
|
};
|
||||||
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
ret = vulkan_create_dmabuf(&s->base, &dmabuf_info, &p->buffers[i]);
|
||||||
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
} else {
|
||||||
};
|
spa_log_error(s->log, "Unsupported buffer type mask %d", buffers[i]->datas[0].type);
|
||||||
|
return -1;
|
||||||
if (!(flags & SPA_NODE_BUFFERS_FLAG_ALLOC)) {
|
}
|
||||||
extInfo = (VkExternalMemoryImageCreateInfo) {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
|
|
||||||
.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
|
|
||||||
};
|
|
||||||
imageCreateInfo.pNext = &extInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
VK_CHECK_RESULT(vkCreateImage(s->base.device,
|
|
||||||
&imageCreateInfo, NULL, &p->buffers[i].image));
|
|
||||||
|
|
||||||
VkMemoryRequirements memoryRequirements;
|
|
||||||
vkGetImageMemoryRequirements(s->base.device,
|
|
||||||
p->buffers[i].image, &memoryRequirements);
|
|
||||||
|
|
||||||
VkMemoryAllocateInfo allocateInfo = {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
|
|
||||||
.allocationSize = memoryRequirements.size,
|
|
||||||
.memoryTypeIndex = findMemoryType(s,
|
|
||||||
memoryRequirements.memoryTypeBits,
|
|
||||||
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
|
|
||||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT),
|
|
||||||
};
|
|
||||||
|
|
||||||
if (flags & SPA_NODE_BUFFERS_FLAG_ALLOC) {
|
|
||||||
VK_CHECK_RESULT(vkAllocateMemory(s->base.device,
|
|
||||||
&allocateInfo, NULL, &p->buffers[i].memory));
|
|
||||||
|
|
||||||
const VkMemoryGetFdInfoKHR getFdInfo = {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
|
|
||||||
.memory = p->buffers[i].memory,
|
|
||||||
.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT
|
|
||||||
};
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
VK_CHECK_RESULT(vkGetMemoryFdKHR(s->base.device, &getFdInfo, &fd));
|
|
||||||
|
|
||||||
spa_log_info(s->log, "export DMABUF %zd", memoryRequirements.size);
|
|
||||||
|
|
||||||
// buffers[i]->datas[0].type = SPA_DATA_DmaBuf;
|
|
||||||
buffers[i]->datas[0].type = SPA_DATA_MemFd;
|
|
||||||
buffers[i]->datas[0].fd = fd;
|
|
||||||
buffers[i]->datas[0].flags = SPA_DATA_FLAG_READABLE;
|
|
||||||
buffers[i]->datas[0].mapoffset = 0;
|
|
||||||
buffers[i]->datas[0].maxsize = memoryRequirements.size;
|
|
||||||
p->buffers[i].fd = fd;
|
|
||||||
} else {
|
} else {
|
||||||
VkImportMemoryFdInfoKHR importInfo = {
|
switch (buffers[i]->datas[0].type) {
|
||||||
.sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
|
case SPA_DATA_DmaBuf:;
|
||||||
.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
|
struct external_dmabuf_info dmabuf_info = {
|
||||||
.fd = fcntl(buffers[i]->datas[0].fd, F_DUPFD_CLOEXEC, 0),
|
.format = format,
|
||||||
};
|
.modifier = dsp_info->modifier,
|
||||||
allocateInfo.pNext = &importInfo;
|
.size.width = s->constants.width,
|
||||||
p->buffers[i].fd = -1;
|
.size.height = s->constants.height,
|
||||||
spa_log_info(s->log, "import DMABUF");
|
.usage = p->direction == SPA_DIRECTION_OUTPUT
|
||||||
|
? VK_IMAGE_USAGE_STORAGE_BIT
|
||||||
VK_CHECK_RESULT(vkAllocateMemory(s->base.device,
|
: VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||||
&allocateInfo, NULL, &p->buffers[i].memory));
|
.spa_buf = buffers[i],
|
||||||
|
};
|
||||||
|
ret = vulkan_import_dmabuf(&s->base, &dmabuf_info, &p->buffers[i]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
spa_log_error(s->log, "Unsupported buffer type %d", buffers[i]->datas[0].type);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
VK_CHECK_RESULT(vkBindImageMemory(s->base.device,
|
if (ret != 0) {
|
||||||
p->buffers[i].image, p->buffers[i].memory, 0));
|
spa_log_error(s->log, "Failed to use buffer %d", i);
|
||||||
|
return ret;
|
||||||
VkImageViewCreateInfo viewInfo = {
|
}
|
||||||
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
p->n_buffers++;
|
||||||
.image = p->buffers[i].image,
|
|
||||||
.viewType = VK_IMAGE_VIEW_TYPE_2D,
|
|
||||||
.format = 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->base.device,
|
|
||||||
&viewInfo, NULL, &p->buffers[i].view));
|
|
||||||
}
|
}
|
||||||
p->n_buffers = n_buffers;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,9 @@
|
||||||
|
|
||||||
//#define ENABLE_VALIDATION
|
//#define ENABLE_VALIDATION
|
||||||
|
|
||||||
|
#define VULKAN_INSTANCE_FUNCTION(name) \
|
||||||
|
PFN_##name name = (PFN_##name)vkGetInstanceProcAddr(s->instance, #name)
|
||||||
|
|
||||||
static int vkresult_to_errno(VkResult result)
|
static int vkresult_to_errno(VkResult result)
|
||||||
{
|
{
|
||||||
switch (result) {
|
switch (result) {
|
||||||
|
|
@ -401,6 +404,246 @@ void vulkan_buffer_clear(struct vulkan_base *s, struct vulkan_buffer *buffer)
|
||||||
vkDestroyImageView(s->device, buffer->view, NULL);
|
vkDestroyImageView(s->device, buffer->view, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VkImageAspectFlagBits mem_plane_aspect(uint32_t i)
|
||||||
|
{
|
||||||
|
switch (i) {
|
||||||
|
case 0: return VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT;
|
||||||
|
case 1: return VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT;
|
||||||
|
case 2: return VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT;
|
||||||
|
case 3: return VK_IMAGE_ASPECT_MEMORY_PLANE_3_BIT_EXT;
|
||||||
|
default: abort(); // unreachable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int allocate_dmabuf(struct vulkan_base *s, VkFormat format, uint32_t modifierCount, uint64_t *modifiers, VkImageUsageFlags usage, struct spa_rectangle *size, struct vulkan_buffer *vk_buf)
|
||||||
|
{
|
||||||
|
VkImageDrmFormatModifierListCreateInfoEXT imageDrmFormatModifierListCreateInfo = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT,
|
||||||
|
.drmFormatModifierCount = modifierCount,
|
||||||
|
.pDrmFormatModifiers = modifiers,
|
||||||
|
};
|
||||||
|
|
||||||
|
VkExternalMemoryImageCreateInfo extMemoryImageCreateInfo = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
|
||||||
|
.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
|
||||||
|
};
|
||||||
|
extMemoryImageCreateInfo.pNext = &imageDrmFormatModifierListCreateInfo;
|
||||||
|
|
||||||
|
VkImageCreateInfo imageCreateInfo = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
||||||
|
.imageType = VK_IMAGE_TYPE_2D,
|
||||||
|
.format = format,
|
||||||
|
.extent.width = size->width,
|
||||||
|
.extent.height = size->height,
|
||||||
|
.extent.depth = 1,
|
||||||
|
.mipLevels = 1,
|
||||||
|
.arrayLayers = 1,
|
||||||
|
.samples = VK_SAMPLE_COUNT_1_BIT,
|
||||||
|
.tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT,
|
||||||
|
.usage = usage,
|
||||||
|
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
||||||
|
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||||
|
};
|
||||||
|
imageCreateInfo.pNext = &extMemoryImageCreateInfo;
|
||||||
|
|
||||||
|
VK_CHECK_RESULT(vkCreateImage(s->device,
|
||||||
|
&imageCreateInfo, NULL, &vk_buf->image));
|
||||||
|
|
||||||
|
VkMemoryRequirements memoryRequirements = {0};
|
||||||
|
vkGetImageMemoryRequirements(s->device,
|
||||||
|
vk_buf->image, &memoryRequirements);
|
||||||
|
|
||||||
|
VkExportMemoryAllocateInfo exportAllocateInfo = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO,
|
||||||
|
.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
|
||||||
|
};
|
||||||
|
VkMemoryAllocateInfo allocateInfo = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
|
||||||
|
.allocationSize = memoryRequirements.size,
|
||||||
|
.memoryTypeIndex = vulkan_memoryType_find(s,
|
||||||
|
memoryRequirements.memoryTypeBits,
|
||||||
|
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT),
|
||||||
|
};
|
||||||
|
allocateInfo.pNext = &exportAllocateInfo;
|
||||||
|
|
||||||
|
VK_CHECK_RESULT(vkAllocateMemory(s->device,
|
||||||
|
&allocateInfo, NULL, &vk_buf->memory));
|
||||||
|
|
||||||
|
VK_CHECK_RESULT(vkBindImageMemory(s->device,
|
||||||
|
vk_buf->image, vk_buf->memory, 0));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int vulkan_create_dmabuf(struct vulkan_base *s, struct external_dmabuf_info *info, struct vulkan_buffer *vk_buf)
|
||||||
|
{
|
||||||
|
VULKAN_INSTANCE_FUNCTION(vkGetMemoryFdKHR);
|
||||||
|
|
||||||
|
if (info->spa_buf->n_datas != 1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
VK_CHECK_RESULT(allocate_dmabuf(s, info->format, 1, &info->modifier, info->usage, &info->size, vk_buf));
|
||||||
|
|
||||||
|
const VkMemoryGetFdInfoKHR getFdInfo = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
|
||||||
|
.memory = vk_buf->memory,
|
||||||
|
.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT
|
||||||
|
};
|
||||||
|
int fd = -1;
|
||||||
|
VK_CHECK_RESULT(vkGetMemoryFdKHR(s->device, &getFdInfo, &fd));
|
||||||
|
|
||||||
|
const struct vulkan_modifier_info *modInfo = vulkan_modifierInfo_find(s, info->format, info->modifier);
|
||||||
|
|
||||||
|
if (info->spa_buf->n_datas != modInfo->props.drmFormatModifierPlaneCount)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
VkMemoryRequirements memoryRequirements = {0};
|
||||||
|
vkGetImageMemoryRequirements(s->device,
|
||||||
|
vk_buf->image, &memoryRequirements);
|
||||||
|
|
||||||
|
spa_log_info(s->log, "export DMABUF %zd", memoryRequirements.size);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < info->spa_buf->n_datas; i++) {
|
||||||
|
VkImageSubresource subresource = {
|
||||||
|
.aspectMask = mem_plane_aspect(i),
|
||||||
|
};
|
||||||
|
VkSubresourceLayout subresLayout = {0};
|
||||||
|
vkGetImageSubresourceLayout(s->device, vk_buf->image, &subresource, &subresLayout);
|
||||||
|
|
||||||
|
info->spa_buf->datas[i].type = SPA_DATA_DmaBuf;
|
||||||
|
info->spa_buf->datas[i].fd = fd;
|
||||||
|
info->spa_buf->datas[i].flags = SPA_DATA_FLAG_READABLE;
|
||||||
|
info->spa_buf->datas[i].mapoffset = 0;
|
||||||
|
info->spa_buf->datas[i].chunk->offset = subresLayout.offset;
|
||||||
|
info->spa_buf->datas[i].chunk->stride = subresLayout.rowPitch;
|
||||||
|
info->spa_buf->datas[i].chunk->size = subresLayout.size;
|
||||||
|
info->spa_buf->datas[i].maxsize = memoryRequirements.size;
|
||||||
|
}
|
||||||
|
vk_buf->fd = fd;
|
||||||
|
|
||||||
|
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_import_dmabuf(struct vulkan_base *s, struct external_dmabuf_info *info, struct vulkan_buffer *vk_buf)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (info->spa_buf->n_datas == 0 || info->spa_buf->n_datas > DMABUF_MAX_PLANES)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
struct vulkan_modifier_info *modProps = vulkan_modifierInfo_find(s, info->format, info->modifier);
|
||||||
|
if (!modProps)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
uint32_t planeCount = info->spa_buf->n_datas;
|
||||||
|
|
||||||
|
if (planeCount != modProps->props.drmFormatModifierPlaneCount)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (info->size.width > modProps->max_extent.width || info->size.height > modProps->max_extent.height)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
VkSubresourceLayout planeLayouts[DMABUF_MAX_PLANES] = {0};
|
||||||
|
for (uint32_t i = 0; i < planeCount; i++) {
|
||||||
|
planeLayouts[i].offset = info->spa_buf->datas[i].chunk->offset;
|
||||||
|
planeLayouts[i].rowPitch = info->spa_buf->datas[i].chunk->stride;
|
||||||
|
planeLayouts[i].size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkImageDrmFormatModifierExplicitCreateInfoEXT modInfo = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT,
|
||||||
|
.drmFormatModifierPlaneCount = planeCount,
|
||||||
|
.drmFormatModifier = info->modifier,
|
||||||
|
.pPlaneLayouts = planeLayouts,
|
||||||
|
};
|
||||||
|
|
||||||
|
VkExternalMemoryImageCreateInfo extInfo = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
|
||||||
|
.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
|
||||||
|
.pNext = &modInfo,
|
||||||
|
};
|
||||||
|
|
||||||
|
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_DRM_FORMAT_MODIFIER_EXT,
|
||||||
|
.usage = info->usage,
|
||||||
|
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
||||||
|
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||||
|
.pNext = &extInfo,
|
||||||
|
};
|
||||||
|
|
||||||
|
VK_CHECK_RESULT(vkCreateImage(s->device,
|
||||||
|
&imageCreateInfo, NULL, &vk_buf->image));
|
||||||
|
|
||||||
|
VkMemoryRequirements memoryRequirements;
|
||||||
|
vkGetImageMemoryRequirements(s->device,
|
||||||
|
vk_buf->image, &memoryRequirements);
|
||||||
|
|
||||||
|
vk_buf->fd = fcntl(info->spa_buf->datas[0].fd, F_DUPFD_CLOEXEC, 0);
|
||||||
|
VkImportMemoryFdInfoKHR importInfo = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
|
||||||
|
.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
|
||||||
|
.fd = fcntl(info->spa_buf->datas[0].fd, F_DUPFD_CLOEXEC, 0),
|
||||||
|
};
|
||||||
|
|
||||||
|
VkMemoryAllocateInfo allocateInfo = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
|
||||||
|
.allocationSize = memoryRequirements.size,
|
||||||
|
.memoryTypeIndex = vulkan_memoryType_find(s,
|
||||||
|
memoryRequirements.memoryTypeBits,
|
||||||
|
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT),
|
||||||
|
};
|
||||||
|
allocateInfo.pNext = &importInfo;
|
||||||
|
|
||||||
|
spa_log_info(s->log, "import DMABUF");
|
||||||
|
|
||||||
|
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,
|
int vulkan_stream_init(struct vulkan_stream *stream, enum spa_direction direction,
|
||||||
struct spa_dict *props)
|
struct spa_dict *props)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
/* SPDX-FileCopyrightText: Copyright © 2019 Wim Taymans */
|
/* SPDX-FileCopyrightText: Copyright © 2019 Wim Taymans */
|
||||||
/* SPDX-License-Identifier: MIT */
|
/* SPDX-License-Identifier: MIT */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include <vulkan/vulkan.h>
|
#include <vulkan/vulkan.h>
|
||||||
|
|
||||||
#include <spa/buffer/buffer.h>
|
#include <spa/buffer/buffer.h>
|
||||||
|
|
@ -34,6 +36,17 @@
|
||||||
return _res; \
|
return _res; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct external_dmabuf_info {
|
||||||
|
VkFormat format;
|
||||||
|
uint64_t modifier;
|
||||||
|
struct spa_rectangle size;
|
||||||
|
VkImageUsageFlags usage;
|
||||||
|
struct spa_buffer *spa_buf;
|
||||||
|
};
|
||||||
|
|
||||||
|
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_commandPool_create(struct vulkan_base *s, VkCommandPool *commandPool);
|
int vulkan_commandPool_create(struct vulkan_base *s, VkCommandPool *commandPool);
|
||||||
int vulkan_commandBuffer_create(struct vulkan_base *s, VkCommandPool commandPool, VkCommandBuffer *commandBuffer);
|
int vulkan_commandBuffer_create(struct vulkan_base *s, VkCommandPool commandPool, VkCommandBuffer *commandBuffer);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue