2023-08-31 00:19:12 +02:00
|
|
|
/* Spa */
|
|
|
|
|
/* SPDX-FileCopyrightText: Copyright © 2019 Wim Taymans */
|
|
|
|
|
/* SPDX-License-Identifier: MIT */
|
|
|
|
|
|
2019-08-19 16:32:22 +02:00
|
|
|
#include <vulkan/vulkan.h>
|
|
|
|
|
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
#include <sys/stat.h>
|
|
|
|
|
#include <sys/mman.h>
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
#include <string.h>
|
2022-07-07 16:23:51 -04:00
|
|
|
#if !defined(__FreeBSD__) && !defined(__MidnightBSD__)
|
2019-08-19 16:32:22 +02:00
|
|
|
#include <alloca.h>
|
2020-03-27 19:20:21 +00:00
|
|
|
#endif
|
2019-08-19 16:32:22 +02:00
|
|
|
#include <errno.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
#include <math.h>
|
|
|
|
|
#include <time.h>
|
|
|
|
|
|
2019-08-19 18:16:32 +02:00
|
|
|
#include <spa/utils/result.h>
|
2022-05-31 18:00:24 +02:00
|
|
|
#include <spa/utils/string.h>
|
2023-02-21 16:29:17 +01:00
|
|
|
#include <spa/param/video/format.h>
|
2019-08-19 18:16:32 +02:00
|
|
|
#include <spa/support/log.h>
|
2019-08-19 16:32:22 +02:00
|
|
|
#include <spa/debug/mem.h>
|
|
|
|
|
|
|
|
|
|
#include "vulkan-utils.h"
|
|
|
|
|
|
2022-06-01 10:54:15 +02:00
|
|
|
//#define ENABLE_VALIDATION
|
|
|
|
|
|
2019-08-19 16:32:22 +02:00
|
|
|
static int vkresult_to_errno(VkResult result)
|
|
|
|
|
{
|
|
|
|
|
switch (result) {
|
|
|
|
|
case VK_SUCCESS:
|
|
|
|
|
case VK_EVENT_SET:
|
|
|
|
|
case VK_EVENT_RESET:
|
|
|
|
|
return 0;
|
|
|
|
|
case VK_NOT_READY:
|
|
|
|
|
case VK_INCOMPLETE:
|
|
|
|
|
case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR:
|
|
|
|
|
return EBUSY;
|
|
|
|
|
case VK_TIMEOUT:
|
|
|
|
|
return ETIMEDOUT;
|
|
|
|
|
case VK_ERROR_OUT_OF_HOST_MEMORY:
|
|
|
|
|
case VK_ERROR_OUT_OF_DEVICE_MEMORY:
|
|
|
|
|
case VK_ERROR_MEMORY_MAP_FAILED:
|
|
|
|
|
case VK_ERROR_OUT_OF_POOL_MEMORY:
|
|
|
|
|
case VK_ERROR_FRAGMENTED_POOL:
|
2019-09-27 10:53:36 +02:00
|
|
|
#ifdef VK_ERROR_FRAGMENTATION_EXT
|
|
|
|
|
case VK_ERROR_FRAGMENTATION_EXT:
|
|
|
|
|
#endif
|
2019-08-19 16:32:22 +02:00
|
|
|
return ENOMEM;
|
|
|
|
|
case VK_ERROR_INITIALIZATION_FAILED:
|
|
|
|
|
return EIO;
|
|
|
|
|
case VK_ERROR_DEVICE_LOST:
|
|
|
|
|
case VK_ERROR_SURFACE_LOST_KHR:
|
2019-09-27 10:53:36 +02:00
|
|
|
#ifdef VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT
|
2019-08-19 16:32:22 +02:00
|
|
|
case VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT:
|
2019-09-27 10:53:36 +02:00
|
|
|
#endif
|
2019-08-19 16:32:22 +02:00
|
|
|
return ENODEV;
|
|
|
|
|
case VK_ERROR_LAYER_NOT_PRESENT:
|
|
|
|
|
case VK_ERROR_EXTENSION_NOT_PRESENT:
|
|
|
|
|
case VK_ERROR_FEATURE_NOT_PRESENT:
|
|
|
|
|
return ENOENT;
|
|
|
|
|
case VK_ERROR_INCOMPATIBLE_DRIVER:
|
|
|
|
|
case VK_ERROR_FORMAT_NOT_SUPPORTED:
|
|
|
|
|
case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR:
|
|
|
|
|
return ENOTSUP;
|
|
|
|
|
case VK_ERROR_TOO_MANY_OBJECTS:
|
|
|
|
|
return ENFILE;
|
|
|
|
|
case VK_SUBOPTIMAL_KHR:
|
|
|
|
|
case VK_ERROR_OUT_OF_DATE_KHR:
|
|
|
|
|
return EIO;
|
|
|
|
|
case VK_ERROR_INVALID_EXTERNAL_HANDLE:
|
|
|
|
|
case VK_ERROR_INVALID_SHADER_NV:
|
2019-09-27 10:53:36 +02:00
|
|
|
#ifdef VK_ERROR_VALIDATION_FAILED_EXT
|
|
|
|
|
case VK_ERROR_VALIDATION_FAILED_EXT:
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT
|
2019-08-19 16:32:22 +02:00
|
|
|
case VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT:
|
2019-09-27 10:53:36 +02:00
|
|
|
#endif
|
|
|
|
|
#ifdef VK_ERROR_INVALID_DEVICE_ADDRESS_EXT
|
2019-08-19 16:32:22 +02:00
|
|
|
case VK_ERROR_INVALID_DEVICE_ADDRESS_EXT:
|
2019-09-27 10:53:36 +02:00
|
|
|
#endif
|
2019-08-19 16:32:22 +02:00
|
|
|
return EINVAL;
|
2019-09-27 10:53:36 +02:00
|
|
|
#ifdef VK_ERROR_NOT_PERMITTED_EXT
|
2019-08-19 16:32:22 +02:00
|
|
|
case VK_ERROR_NOT_PERMITTED_EXT:
|
|
|
|
|
return EPERM;
|
2019-09-27 10:53:36 +02:00
|
|
|
#endif
|
2019-08-19 16:32:22 +02:00
|
|
|
default:
|
|
|
|
|
return EIO;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-21 16:29:17 +01:00
|
|
|
static struct {
|
|
|
|
|
VkFormat format;
|
|
|
|
|
uint32_t id;
|
|
|
|
|
} vk_video_format_convs[] = {
|
|
|
|
|
{ VK_FORMAT_R32G32B32A32_SFLOAT, SPA_VIDEO_FORMAT_RGBA_F32 },
|
|
|
|
|
};
|
|
|
|
|
|
2023-08-27 00:24:04 +02:00
|
|
|
static int createInstance(struct vulkan_base *s)
|
2019-08-19 16:32:22 +02:00
|
|
|
{
|
2021-06-27 17:47:13 +02:00
|
|
|
static const VkApplicationInfo applicationInfo = {
|
2019-08-19 16:32:22 +02:00
|
|
|
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
|
2019-08-19 16:47:02 +02:00
|
|
|
.pApplicationName = "PipeWire",
|
2019-08-19 16:32:22 +02:00
|
|
|
.applicationVersion = 0,
|
2019-08-19 16:47:02 +02:00
|
|
|
.pEngineName = "PipeWire Vulkan Engine",
|
2019-08-19 16:32:22 +02:00
|
|
|
.engineVersion = 0,
|
|
|
|
|
.apiVersion = VK_API_VERSION_1_1
|
|
|
|
|
};
|
2021-06-27 17:47:13 +02:00
|
|
|
static const char * const extensions[] = {
|
2019-08-19 16:32:22 +02:00
|
|
|
VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME
|
|
|
|
|
};
|
2022-05-31 18:00:24 +02:00
|
|
|
static const char * const checkLayers[] = {
|
|
|
|
|
#ifdef ENABLE_VALIDATION
|
2022-05-31 09:53:08 +02:00
|
|
|
"VK_LAYER_KHRONOS_validation",
|
2022-05-31 18:00:24 +02:00
|
|
|
#endif
|
|
|
|
|
NULL
|
2022-05-31 09:53:08 +02:00
|
|
|
};
|
2022-05-31 18:00:24 +02:00
|
|
|
uint32_t i, j, layerCount, n_layers = 0;
|
|
|
|
|
const char *layers[1];
|
2022-05-31 09:53:08 +02:00
|
|
|
vkEnumerateInstanceLayerProperties(&layerCount, NULL);
|
|
|
|
|
|
|
|
|
|
VkLayerProperties availableLayers[layerCount];
|
|
|
|
|
vkEnumerateInstanceLayerProperties(&layerCount, availableLayers);
|
|
|
|
|
|
2022-05-31 18:00:24 +02:00
|
|
|
for (i = 0; i < layerCount; i++) {
|
|
|
|
|
for (j = 0; j < SPA_N_ELEMENTS(checkLayers); j++) {
|
|
|
|
|
if (spa_streq(availableLayers[i].layerName, checkLayers[j]))
|
|
|
|
|
layers[n_layers++] = checkLayers[j];
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-06-27 17:47:13 +02:00
|
|
|
|
|
|
|
|
const VkInstanceCreateInfo createInfo = {
|
2019-08-19 16:32:22 +02:00
|
|
|
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
|
|
|
|
|
.pApplicationInfo = &applicationInfo,
|
|
|
|
|
.enabledExtensionCount = 1,
|
|
|
|
|
.ppEnabledExtensionNames = extensions,
|
2022-05-31 18:00:24 +02:00
|
|
|
.enabledLayerCount = n_layers,
|
2022-05-31 09:53:08 +02:00
|
|
|
.ppEnabledLayerNames = layers,
|
2019-08-19 16:32:22 +02:00
|
|
|
};
|
|
|
|
|
|
2019-08-19 18:16:32 +02:00
|
|
|
VK_CHECK_RESULT(vkCreateInstance(&createInfo, NULL, &s->instance));
|
2019-08-19 16:32:22 +02:00
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-27 00:24:04 +02:00
|
|
|
static int findPhysicalDevice(struct vulkan_base *s)
|
|
|
|
|
{
|
|
|
|
|
uint32_t deviceCount;
|
|
|
|
|
VkPhysicalDevice *devices;
|
|
|
|
|
|
|
|
|
|
vkEnumeratePhysicalDevices(s->instance, &deviceCount, NULL);
|
|
|
|
|
if (deviceCount == 0)
|
|
|
|
|
return -ENODEV;
|
|
|
|
|
|
|
|
|
|
devices = alloca(deviceCount * sizeof(VkPhysicalDevice));
|
|
|
|
|
vkEnumeratePhysicalDevices(s->instance, &deviceCount, devices);
|
|
|
|
|
|
|
|
|
|
s->physicalDevice = devices[0];
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int getComputeQueueFamilyIndex(struct vulkan_base *s, uint32_t queueFlags, uint32_t *queueFamilyIndex)
|
2019-08-19 16:32:22 +02:00
|
|
|
{
|
|
|
|
|
uint32_t i, queueFamilyCount;
|
|
|
|
|
VkQueueFamilyProperties *queueFamilies;
|
|
|
|
|
|
2019-08-19 18:16:32 +02:00
|
|
|
vkGetPhysicalDeviceQueueFamilyProperties(s->physicalDevice, &queueFamilyCount, NULL);
|
2019-08-19 16:32:22 +02:00
|
|
|
|
|
|
|
|
queueFamilies = alloca(queueFamilyCount * sizeof(VkQueueFamilyProperties));
|
2019-08-19 18:16:32 +02:00
|
|
|
vkGetPhysicalDeviceQueueFamilyProperties(s->physicalDevice, &queueFamilyCount, queueFamilies);
|
2019-08-19 16:32:22 +02:00
|
|
|
|
|
|
|
|
for (i = 0; i < queueFamilyCount; i++) {
|
|
|
|
|
VkQueueFamilyProperties props = queueFamilies[i];
|
|
|
|
|
|
2023-08-27 00:24:04 +02:00
|
|
|
if (props.queueCount > 0 && ((props.queueFlags & queueFlags) == queueFlags))
|
2019-08-19 16:32:22 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (i == queueFamilyCount)
|
|
|
|
|
return -ENODEV;
|
|
|
|
|
|
2023-08-27 00:24:04 +02:00
|
|
|
*queueFamilyIndex = i;
|
2019-08-19 16:32:22 +02:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-27 00:24:04 +02:00
|
|
|
static int createDevice(struct vulkan_base *s, struct vulkan_base_info *info)
|
2019-08-19 16:32:22 +02:00
|
|
|
{
|
2021-06-27 17:47:13 +02:00
|
|
|
|
2023-08-27 00:24:04 +02:00
|
|
|
CHECK(getComputeQueueFamilyIndex(s, info->queueFlags, &s->queueFamilyIndex));
|
|
|
|
|
|
2021-06-27 17:47:13 +02:00
|
|
|
const VkDeviceQueueCreateInfo queueCreateInfo = {
|
2019-08-19 16:32:22 +02:00
|
|
|
.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
|
2019-08-19 18:16:32 +02:00
|
|
|
.queueFamilyIndex = s->queueFamilyIndex,
|
2019-08-19 16:32:22 +02:00
|
|
|
.queueCount = 1,
|
|
|
|
|
.pQueuePriorities = (const float[]) { 1.0f }
|
|
|
|
|
};
|
2021-06-27 17:47:13 +02:00
|
|
|
static const char * const extensions[] = {
|
2019-08-19 16:32:22 +02:00
|
|
|
VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME,
|
2023-08-11 22:59:22 +02:00
|
|
|
VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME,
|
|
|
|
|
VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME,
|
|
|
|
|
VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME
|
2019-08-19 16:32:22 +02:00
|
|
|
};
|
2021-06-27 17:47:13 +02:00
|
|
|
const VkDeviceCreateInfo deviceCreateInfo = {
|
2019-08-19 16:32:22 +02:00
|
|
|
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
|
|
|
|
|
.queueCreateInfoCount = 1,
|
|
|
|
|
.pQueueCreateInfos = &queueCreateInfo,
|
2023-08-11 22:59:22 +02:00
|
|
|
.enabledExtensionCount = SPA_N_ELEMENTS(extensions),
|
2019-08-19 16:32:22 +02:00
|
|
|
.ppEnabledExtensionNames = extensions,
|
|
|
|
|
};
|
|
|
|
|
|
2019-08-19 18:16:32 +02:00
|
|
|
VK_CHECK_RESULT(vkCreateDevice(s->physicalDevice, &deviceCreateInfo, NULL, &s->device));
|
2019-08-19 16:32:22 +02:00
|
|
|
|
2019-08-19 18:16:32 +02:00
|
|
|
vkGetDeviceQueue(s->device, s->queueFamilyIndex, 0, &s->queue);
|
2019-08-19 16:32:22 +02:00
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-11 22:59:22 +02:00
|
|
|
static int queryFormatInfo(struct vulkan_base *s, struct vulkan_base_info *info)
|
|
|
|
|
{
|
|
|
|
|
if (s->formatInfos)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
s->formatInfos = calloc(info->formatInfo.formatCount, sizeof(struct vulkan_format_info));
|
|
|
|
|
if (!s->formatInfos)
|
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < info->formatInfo.formatCount; i++) {
|
|
|
|
|
VkFormat format = vulkan_id_to_vkformat(info->formatInfo.formats[i]);
|
|
|
|
|
if (format == VK_FORMAT_UNDEFINED)
|
|
|
|
|
continue;
|
|
|
|
|
struct vulkan_format_info *f_info = &s->formatInfos[s->formatInfoCount++];
|
|
|
|
|
f_info->spa_format = info->formatInfo.formats[i];
|
|
|
|
|
f_info->vk_format = format;
|
|
|
|
|
|
|
|
|
|
VkDrmFormatModifierPropertiesListEXT modPropsList = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT,
|
|
|
|
|
};
|
|
|
|
|
VkFormatProperties2 fmtProps = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2,
|
|
|
|
|
.pNext = &modPropsList,
|
|
|
|
|
};
|
|
|
|
|
vkGetPhysicalDeviceFormatProperties2(s->physicalDevice, format, &fmtProps);
|
|
|
|
|
|
|
|
|
|
if (!modPropsList.drmFormatModifierCount)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
modPropsList.pDrmFormatModifierProperties = calloc(modPropsList.drmFormatModifierCount,
|
|
|
|
|
sizeof(modPropsList.pDrmFormatModifierProperties[0]));
|
|
|
|
|
if (!modPropsList.pDrmFormatModifierProperties)
|
|
|
|
|
continue;
|
|
|
|
|
vkGetPhysicalDeviceFormatProperties2(s->physicalDevice, format, &fmtProps);
|
|
|
|
|
|
|
|
|
|
f_info->infos = calloc(modPropsList.drmFormatModifierCount, sizeof(f_info->infos[0]));
|
|
|
|
|
if (!f_info->infos) {
|
|
|
|
|
free(modPropsList.pDrmFormatModifierProperties);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (uint32_t j = 0; j < modPropsList.drmFormatModifierCount; j++) {
|
|
|
|
|
VkDrmFormatModifierPropertiesEXT props = modPropsList.pDrmFormatModifierProperties[j];
|
|
|
|
|
|
|
|
|
|
if (!(props.drmFormatModifierTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
|
|
|
|
|
continue;
|
|
|
|
|
|
2023-08-04 00:30:38 +02:00
|
|
|
if (props.drmFormatModifierPlaneCount > DMABUF_MAX_PLANES)
|
|
|
|
|
continue;
|
|
|
|
|
|
2023-08-11 22:59:22 +02:00
|
|
|
VkPhysicalDeviceImageDrmFormatModifierInfoEXT modInfo = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
|
|
|
|
|
.drmFormatModifier = props.drmFormatModifier,
|
|
|
|
|
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
|
|
|
|
};
|
|
|
|
|
VkPhysicalDeviceExternalImageFormatInfo extImgFmtInfo = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
|
|
|
|
|
.pNext = &modInfo,
|
|
|
|
|
.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
|
|
|
|
|
};
|
|
|
|
|
VkPhysicalDeviceImageFormatInfo2 imgFmtInfo = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
|
|
|
|
|
.pNext = &extImgFmtInfo,
|
|
|
|
|
.type = VK_IMAGE_TYPE_2D,
|
|
|
|
|
.format = format,
|
|
|
|
|
.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
|
|
|
|
|
.tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkExternalImageFormatProperties extImgFmtProps = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES,
|
|
|
|
|
};
|
|
|
|
|
VkImageFormatProperties2 imgFmtProps = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
|
|
|
|
|
.pNext = &extImgFmtProps,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VK_CHECK_RESULT_LOOP(vkGetPhysicalDeviceImageFormatProperties2(s->physicalDevice, &imgFmtInfo, &imgFmtProps))
|
|
|
|
|
|
|
|
|
|
VkExternalMemoryFeatureFlags extMemFeatures =
|
|
|
|
|
extImgFmtProps.externalMemoryProperties.externalMemoryFeatures;
|
|
|
|
|
if (!(extMemFeatures & VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkExtent3D max_extent = imgFmtProps.imageFormatProperties.maxExtent;
|
|
|
|
|
f_info->infos[f_info->modifierCount++] = (struct vulkan_modifier_info){
|
|
|
|
|
.props = props,
|
|
|
|
|
.max_extent = { .width = max_extent.width, .height = max_extent.height },
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
free(modPropsList.pDrmFormatModifierProperties);
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void destroyFormatInfo(struct vulkan_base *s)
|
|
|
|
|
{
|
|
|
|
|
for (uint32_t i = 0; i < s->formatInfoCount; i++) {
|
|
|
|
|
free(s->formatInfos[i].infos);
|
|
|
|
|
}
|
|
|
|
|
free(s->formatInfos);
|
|
|
|
|
s->formatInfos = NULL;
|
|
|
|
|
s->formatInfoCount = 0;
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-27 00:24:04 +02:00
|
|
|
int vulkan_commandPool_create(struct vulkan_base *s, VkCommandPool *commandPool)
|
2019-08-19 16:32:22 +02:00
|
|
|
{
|
2021-06-27 17:47:13 +02:00
|
|
|
const VkCommandPoolCreateInfo commandPoolCreateInfo = {
|
2019-08-19 16:32:22 +02:00
|
|
|
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
|
|
|
|
|
.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
|
2019-08-19 18:16:32 +02:00
|
|
|
.queueFamilyIndex = s->queueFamilyIndex,
|
2019-08-19 16:32:22 +02:00
|
|
|
};
|
2019-08-19 18:16:32 +02:00
|
|
|
VK_CHECK_RESULT(vkCreateCommandPool(s->device,
|
2019-08-19 16:32:22 +02:00
|
|
|
&commandPoolCreateInfo, NULL,
|
2023-08-27 00:24:04 +02:00
|
|
|
commandPool));
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2019-08-19 16:32:22 +02:00
|
|
|
|
2023-08-27 00:24:04 +02:00
|
|
|
int vulkan_commandBuffer_create(struct vulkan_base *s, VkCommandPool commandPool, VkCommandBuffer *commandBuffer)
|
|
|
|
|
{
|
2021-06-27 17:47:13 +02:00
|
|
|
const VkCommandBufferAllocateInfo commandBufferAllocateInfo = {
|
2019-08-19 16:32:22 +02:00
|
|
|
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
|
2023-08-27 00:24:04 +02:00
|
|
|
.commandPool = commandPool,
|
2019-08-19 16:32:22 +02:00
|
|
|
.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
|
|
|
|
|
.commandBufferCount = 1,
|
|
|
|
|
};
|
2019-08-19 18:16:32 +02:00
|
|
|
VK_CHECK_RESULT(vkAllocateCommandBuffers(s->device,
|
2019-08-19 16:32:22 +02:00
|
|
|
&commandBufferAllocateInfo,
|
2023-08-27 00:24:04 +02:00
|
|
|
commandBuffer));
|
2019-08-19 16:32:22 +02:00
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-27 00:24:04 +02:00
|
|
|
uint32_t vulkan_memoryType_find(struct vulkan_base *s,
|
|
|
|
|
uint32_t memoryTypeBits, VkMemoryPropertyFlags properties)
|
2019-08-19 16:32:22 +02:00
|
|
|
{
|
|
|
|
|
uint32_t i;
|
2023-08-27 00:24:04 +02:00
|
|
|
VkPhysicalDeviceMemoryProperties memoryProperties;
|
2019-08-19 16:32:22 +02:00
|
|
|
|
2023-08-27 00:24:04 +02:00
|
|
|
vkGetPhysicalDeviceMemoryProperties(s->physicalDevice, &memoryProperties);
|
2022-05-30 18:34:31 +02:00
|
|
|
|
2023-08-27 00:24:04 +02:00
|
|
|
for (i = 0; i < memoryProperties.memoryTypeCount; i++) {
|
|
|
|
|
if ((memoryTypeBits & (1 << i)) &&
|
|
|
|
|
((memoryProperties.memoryTypes[i].propertyFlags & properties) == properties))
|
|
|
|
|
return i;
|
2019-08-19 16:32:22 +02:00
|
|
|
}
|
2023-08-27 00:24:04 +02:00
|
|
|
return -1;
|
2019-08-19 16:32:22 +02:00
|
|
|
}
|
|
|
|
|
|
2023-08-11 22:59:22 +02:00
|
|
|
struct vulkan_format_info *vulkan_formatInfo_find(struct vulkan_base *s, VkFormat format)
|
|
|
|
|
{
|
|
|
|
|
for (uint32_t i = 0; i < s->formatInfoCount; i++) {
|
|
|
|
|
if (s->formatInfos[i].vk_format == format)
|
|
|
|
|
return &s->formatInfos[i];
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct vulkan_modifier_info *vulkan_modifierInfo_find(struct vulkan_base *s, VkFormat format, uint64_t mod)
|
|
|
|
|
{
|
|
|
|
|
struct vulkan_format_info *f_info = vulkan_formatInfo_find(s, format);
|
|
|
|
|
if (!f_info)
|
|
|
|
|
return NULL;
|
|
|
|
|
for (uint32_t i = 0; i < f_info->modifierCount; i++) {
|
|
|
|
|
if (f_info->infos[i].props.drmFormatModifier == mod)
|
|
|
|
|
return &f_info->infos[i];
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-27 00:24:04 +02:00
|
|
|
void vulkan_buffer_clear(struct vulkan_base *s, struct vulkan_buffer *buffer)
|
2019-08-19 16:32:22 +02:00
|
|
|
{
|
2023-08-27 00:24:04 +02:00
|
|
|
if (buffer->fd != -1)
|
|
|
|
|
close(buffer->fd);
|
|
|
|
|
vkFreeMemory(s->device, buffer->memory, NULL);
|
|
|
|
|
vkDestroyImage(s->device, buffer->image, NULL);
|
|
|
|
|
vkDestroyImageView(s->device, buffer->view, NULL);
|
2019-08-19 16:32:22 +02:00
|
|
|
}
|
|
|
|
|
|
2023-08-27 00:24:04 +02:00
|
|
|
int vulkan_stream_init(struct vulkan_stream *stream, enum spa_direction direction,
|
|
|
|
|
struct spa_dict *props)
|
2022-05-30 18:34:31 +02:00
|
|
|
{
|
|
|
|
|
spa_zero(*stream);
|
|
|
|
|
stream->direction = direction;
|
|
|
|
|
stream->current_buffer_id = SPA_ID_INVALID;
|
|
|
|
|
stream->busy_buffer_id = SPA_ID_INVALID;
|
|
|
|
|
stream->ready_buffer_id = SPA_ID_INVALID;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-21 16:29:17 +01:00
|
|
|
uint32_t vulkan_vkformat_to_id(VkFormat format)
|
|
|
|
|
{
|
|
|
|
|
SPA_FOR_EACH_ELEMENT_VAR(vk_video_format_convs, f) {
|
|
|
|
|
if (f->format == format)
|
|
|
|
|
return f->id;
|
|
|
|
|
}
|
|
|
|
|
return SPA_VIDEO_FORMAT_UNKNOWN;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkFormat vulkan_id_to_vkformat(uint32_t id)
|
|
|
|
|
{
|
|
|
|
|
SPA_FOR_EACH_ELEMENT_VAR(vk_video_format_convs, f) {
|
|
|
|
|
if (f->id == id)
|
|
|
|
|
return f->format;
|
|
|
|
|
}
|
|
|
|
|
return VK_FORMAT_UNDEFINED;
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-27 00:24:04 +02:00
|
|
|
int vulkan_vkresult_to_errno(VkResult result)
|
2019-08-19 16:32:22 +02:00
|
|
|
{
|
2023-08-27 00:24:04 +02:00
|
|
|
return vkresult_to_errno(result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int vulkan_base_init(struct vulkan_base *s, struct vulkan_base_info *info)
|
|
|
|
|
{
|
|
|
|
|
if (!s->initialized) {
|
2022-05-31 11:33:51 +02:00
|
|
|
CHECK(createInstance(s));
|
|
|
|
|
CHECK(findPhysicalDevice(s));
|
2023-08-27 00:24:04 +02:00
|
|
|
CHECK(createDevice(s, info));
|
2023-08-11 22:59:22 +02:00
|
|
|
CHECK(queryFormatInfo(s, info));
|
2023-08-27 00:24:04 +02:00
|
|
|
s->initialized = true;
|
2019-08-19 16:32:22 +02:00
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-27 00:24:04 +02:00
|
|
|
void vulkan_base_deinit(struct vulkan_base *s)
|
2019-08-19 16:32:22 +02:00
|
|
|
{
|
2023-08-27 00:24:04 +02:00
|
|
|
if (s->initialized) {
|
2023-08-11 22:59:22 +02:00
|
|
|
destroyFormatInfo(s);
|
2019-08-19 16:32:22 +02:00
|
|
|
vkDestroyDevice(s->device, NULL);
|
|
|
|
|
vkDestroyInstance(s->instance, NULL);
|
2023-08-27 00:24:04 +02:00
|
|
|
s->initialized = false;
|
2022-05-30 18:34:31 +02:00
|
|
|
}
|
2019-08-19 16:32:22 +02:00
|
|
|
}
|