- VkExternalImageFormatProperties ext_img_fmt_props;
-
- int i;
- VkPhysicalDeviceImageFormatInfo2 img_fmt_info;
- VkImageFormatProperties2 img_fmt_props;
- VkImageUsageFlagBits all_flags[] = {
- VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
- VK_IMAGE_USAGE_TRANSFER_DST_BIT,
- VK_IMAGE_USAGE_SAMPLED_BIT,
- VK_IMAGE_USAGE_STORAGE_BIT,
- VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
- VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
- VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
- /* Shouldn't be used together with COLOR, DEPTH_STENCIL
- * attachment bits:
- * VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,
- * Provided by VK_EXT_fragment_density_map
- * VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT,
- * Provided by VK_NV_shading_rate_image
- * VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV,
- * Provided by VK_KHR_fragment_shading_rate
- * VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR,
- */
- };
- VkImageUsageFlagBits flags = 0;
-
- VkExternalMemoryFeatureFlagBits export_feature_flags =
- VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT;
- VkExternalMemoryHandleTypeFlagBits handle_type =
- VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
-
- memset(&ext_img_fmt_info, 0, sizeof ext_img_fmt_info);
- ext_img_fmt_info.sType =
- VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO;
- ext_img_fmt_info.handleType = handle_type;
-
- memset(&ext_img_fmt_props, 0, sizeof ext_img_fmt_props);
- ext_img_fmt_props.sType =
- VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES;
-
- memset(&img_fmt_props, 0, sizeof img_fmt_props);
- img_fmt_props.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2;
- img_fmt_props.pNext = &ext_img_fmt_props;
-
- memset(&img_fmt_info, 0, sizeof img_fmt_info);
- img_fmt_info.sType =
- VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2;
- img_fmt_info.pNext = &ext_img_fmt_info;
- img_fmt_info.format = props->format;
- img_fmt_info.type = get_image_type(props->h, props->depth);
- img_fmt_info.tiling = props->tiling;
-
- for (i = 0; i < ARRAY_SIZE(all_flags); i++) {
- img_fmt_info.usage = all_flags[i];
- if (vkGetPhysicalDeviceImageFormatProperties2(ctx->pdev,
- &img_fmt_info,
- &img_fmt_props) == VK_SUCCESS) {
- flags |= all_flags[i];
- }
- }
-
- /* usage can't be null */
- if (flags) {
- img_fmt_info.usage = flags;
- }
- else {
- fprintf(stderr, "Unsupported Vulkan format properties: usage.\n");
- return false;
- }
-
- if (vkGetPhysicalDeviceImageFormatProperties2
- (ctx->pdev, &img_fmt_info, &img_fmt_props) != VK_SUCCESS) {
- fprintf(stderr,
- "Unsupported Vulkan format properties.\n");
- return false;
- }
- props->usage = flags;
-
- if (props->need_export &&
- !(ext_img_fmt_props.externalMemoryProperties.externalMemoryFeatures
- & export_feature_flags)) {
- fprintf(stderr, "Unsupported Vulkan external memory features.\n");
- return false;
- }
-
- return true;
+ VkExternalImageFormatProperties ext_img_fmt_props;
+
+ int i;
+ VkPhysicalDeviceImageFormatInfo2 img_fmt_info;
+ VkImageFormatProperties2 img_fmt_props;
+ VkImageUsageFlagBits all_flags[] = {
+ VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
+ VK_IMAGE_USAGE_TRANSFER_DST_BIT,
+ VK_IMAGE_USAGE_SAMPLED_BIT,
+ VK_IMAGE_USAGE_STORAGE_BIT,
+ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
+ VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
+ VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
+ /* Shouldn't be used together with COLOR, DEPTH_STENCIL
+ * attachment bits:
+ * VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,
+ * Provided by VK_EXT_fragment_density_map
+ * VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT,
+ * Provided by VK_NV_shading_rate_image
+ * VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV,
+ * Provided by VK_KHR_fragment_shading_rate
+ * VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR,
+ */
+ };
+ VkImageUsageFlagBits flags = 0;
+
+ VkExternalMemoryFeatureFlagBits export_feature_flags =
+ VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT;
+ VkExternalMemoryHandleTypeFlagBits handle_type =
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
+
+ memset(&ext_img_fmt_info, 0, sizeof ext_img_fmt_info);
+ ext_img_fmt_info.sType =
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO;
+ ext_img_fmt_info.handleType = handle_type;
+
+ memset(&ext_img_fmt_props, 0, sizeof ext_img_fmt_props);
+ ext_img_fmt_props.sType =
+ VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES;
+
+ memset(&img_fmt_props, 0, sizeof img_fmt_props);
+ img_fmt_props.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2;
+ img_fmt_props.pNext = &ext_img_fmt_props;
+
+ memset(&img_fmt_info, 0, sizeof img_fmt_info);
+ img_fmt_info.sType =
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2;
+ img_fmt_info.pNext = &ext_img_fmt_info;
+ img_fmt_info.format = props->format;
+ img_fmt_info.type = get_image_type(props->h, props->depth);
+ img_fmt_info.tiling = props->tiling;
+
+ for (i = 0; i < ARRAY_SIZE(all_flags); i++) {
+ img_fmt_info.usage = all_flags[i];
+ if (vkGetPhysicalDeviceImageFormatProperties2(ctx->pdev,
+ &img_fmt_info,
+ &img_fmt_props) == VK_SUCCESS) {
+ flags |= all_flags[i];
+ }
+ }
+
+ /* usage can't be null */
+ if (flags) {
+ img_fmt_info.usage = flags;
+ }
+ else {
+ fprintf(stderr, "Unsupported Vulkan format properties: usage.\n");
+ return false;
+ }
+
+ if (vkGetPhysicalDeviceImageFormatProperties2
+ (ctx->pdev, &img_fmt_info, &img_fmt_props) != VK_SUCCESS) {
+ fprintf(stderr,
+ "Unsupported Vulkan format properties.\n");
+ return false;
+ }
+ props->usage = flags;
+
+ if (props->need_export &&
+ !(ext_img_fmt_props.externalMemoryProperties.externalMemoryFeatures
+ & export_feature_flags)) {
+ fprintf(stderr, "Unsupported Vulkan external memory features.\n");
+ return false;
+ }
+
+ return true;
+}
+
+/* static swapchain / surf related functions */
+
+static bool
+sc_validate_surface(struct vk_ctx *ctx,
+ VkSurfaceKHR surf)
+{
+ VkBool32 supported;
+ if (!surf) {
+ fprintf(stderr, "No surface!\n");
+ return false;
+ }
+
+ if(vkGetPhysicalDeviceSurfaceSupportKHR(ctx->pdev, ctx->qfam_idx, surf, &supported) != VK_SUCCESS) {
+ fprintf(stderr, "Failed to validate surface.\n");
+ return false;
+ }
+
+ if (!supported) {
+ fprintf(stderr, "Invalid surface! Check if the surface with queue family index: %d supports presentation.\n", (int)ctx->qfam_idx);
+ return false;
+ }
+
+ return true;
+}
+
+static bool
+sc_select_format(struct vk_ctx *ctx,
+ VkSurfaceKHR surf,
+ VkSwapchainCreateInfoKHR *s_info)
+{
+ VkSurfaceFormatKHR *formats;
+ uint32_t num_formats;
+
+ if (vkGetPhysicalDeviceSurfaceFormatsKHR(ctx->pdev, surf, &num_formats, 0) != VK_SUCCESS) {
+ fprintf(stderr, "Failed to get the number of surface formats.\n");
+ return false;
+ }
+
+ if (!num_formats) {
+ fprintf(stderr, "No surface formats found.\n");
+ return false;
+ }
+
+ formats = malloc(num_formats * sizeof *formats);
+
+ if (vkGetPhysicalDeviceSurfaceFormatsKHR(ctx->pdev, surf, &num_formats, formats) != VK_SUCCESS) {
+ fprintf(stderr, "Failed to get the supported surface formats.\n");
+ return false;
+ }
+
+ if ((num_formats == 1) && (formats[0].format == VK_FORMAT_UNDEFINED)) {
+ s_info->imageFormat = VK_FORMAT_B8G8R8A8_UNORM;
+ s_info->imageColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
+ } else {
+ s_info->imageFormat = formats[0].format;
+ s_info->imageColorSpace = formats[0].colorSpace;
+ }
+ free(formats);
+
+ return true;