wsi/metal: move VkFormat -> MTLPixelFormat conversion to wsi_common_metal_layer.m

Reviewed-by: Lucas Fryzek <lfryzek@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33779>
This commit is contained in:
Aleksi Sapon 2025-09-26 14:16:14 -04:00 committed by Marge Bot
parent d32e6f2842
commit f022754647
3 changed files with 55 additions and 53 deletions

View file

@ -375,36 +375,23 @@ wsi_metal_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
const VkAllocationCallbacks* pAllocator,
struct wsi_swapchain **swapchain_out)
{
VkResult result;
VkIcdSurfaceMetal *metal_surface = (VkIcdSurfaceMetal *)icd_surface;
assert(metal_surface->pLayer);
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR);
MTLPixelFormat metal_format;
switch (pCreateInfo->imageFormat)
{
case VK_FORMAT_B8G8R8A8_SRGB:
metal_format = MTLPixelFormatBGRA8Unorm_sRGB;
break;
case VK_FORMAT_B8G8R8A8_UNORM:
metal_format = MTLPixelFormatBGRA8Unorm;
break;
case VK_FORMAT_R16G16B16A16_SFLOAT:
metal_format = MTLPixelFormatRGBA16Float;
break;
case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
metal_format = MTLPixelFormatRGB10A2Unorm;
break;
case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
metal_format = MTLPixelFormatBGR10A2Unorm;
break;
default:
return VK_ERROR_FORMAT_NOT_SUPPORTED;
}
const int num_images = pCreateInfo->minImageCount;
const bool opaque_composition =
pCreateInfo->compositeAlpha & VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
const bool immediate_mode =
pCreateInfo->presentMode == VK_PRESENT_MODE_IMMEDIATE_KHR;
int num_images = pCreateInfo->minImageCount;
VkResult result = wsi_metal_layer_configure(metal_surface->pLayer,
pCreateInfo->imageExtent.width, pCreateInfo->imageExtent.height,
num_images, pCreateInfo->imageFormat,
opaque_composition, immediate_mode);
if (result != VK_SUCCESS)
return result;
struct wsi_metal_swapchain *chain;
size_t size = sizeof(*chain) + num_images * sizeof(chain->images[0]);
@ -433,12 +420,6 @@ wsi_metal_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
chain->vk_format = pCreateInfo->imageFormat;
chain->surface = metal_surface;
wsi_metal_layer_configure(metal_surface->pLayer,
pCreateInfo->imageExtent.width, pCreateInfo->imageExtent.height,
num_images, metal_format,
pCreateInfo->compositeAlpha & VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
pCreateInfo->presentMode == VK_PRESENT_MODE_IMMEDIATE_KHR);
chain->current_image_index = 0;
for (uint32_t i = 0; i < chain->base.image_count; i++) {
result = wsi_create_image(&chain->base, &chain->base.image_info,

View file

@ -7,35 +7,23 @@
#ifndef WSI_COMMON_METAL_LAYER_H
#define WSI_COMMON_METAL_LAYER_H
#include <vulkan/vulkan_core.h>
#include <vulkan/vulkan_metal.h>
#include <stdint.h>
#include <stdbool.h>
#ifdef __OBJC__
@class CAMetalLayer;
typedef unsigned long NSUInteger;
typedef enum MTLPixelFormat : NSUInteger MTLPixelFormat;
#else
typedef void CAMetalLayer;
typedef enum MTLPixelFormat : unsigned long
{
MTLPixelFormatBGRA8Unorm = 80,
MTLPixelFormatBGRA8Unorm_sRGB = 81,
MTLPixelFormatRGB10A2Unorm = 90,
MTLPixelFormatBGR10A2Unorm = 94,
MTLPixelFormatRGBA16Float = 115,
} MTLPixelFormat;
#endif
typedef void CAMetalDrawableBridged;
void
wsi_metal_layer_size(const CAMetalLayer *metal_layer,
uint32_t *width, uint32_t *height);
void
VkResult
wsi_metal_layer_configure(const CAMetalLayer *metal_layer,
uint32_t width, uint32_t height, uint32_t image_count,
MTLPixelFormat format, bool enable_opaque, bool enable_immediate);
VkFormat format,
bool enable_opaque, bool enable_immediate);
CAMetalDrawableBridged *
wsi_metal_layer_acquire_drawable(const CAMetalLayer *metal_layer);

View file

@ -22,15 +22,46 @@ wsi_metal_layer_size(const CAMetalLayer *metal_layer,
}
}
void
static VkResult
get_mtl_pixel_format(VkFormat format, MTLPixelFormat *metal_format)
{
switch (format) {
case VK_FORMAT_B8G8R8A8_SRGB:
*metal_format = MTLPixelFormatBGRA8Unorm_sRGB;
break;
case VK_FORMAT_B8G8R8A8_UNORM:
*metal_format = MTLPixelFormatBGRA8Unorm;
break;
case VK_FORMAT_R16G16B16A16_SFLOAT:
*metal_format = MTLPixelFormatRGBA16Float;
break;
case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
*metal_format = MTLPixelFormatRGB10A2Unorm;
break;
case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
*metal_format = MTLPixelFormatBGR10A2Unorm;
break;
default:
return VK_ERROR_FORMAT_NOT_SUPPORTED;
}
return VK_SUCCESS;
}
VkResult
wsi_metal_layer_configure(const CAMetalLayer *metal_layer,
uint32_t width, uint32_t height, uint32_t image_count,
MTLPixelFormat format, bool enable_opaque, bool enable_immediate)
VkFormat format,
bool enable_opaque, bool enable_immediate)
{
@autoreleasepool {
if (metal_layer.device == nil) {
MTLPixelFormat metal_format;
VkResult result = get_mtl_pixel_format(format, &metal_format);
if (result != VK_SUCCESS)
return result;
if (metal_layer.device == nil)
metal_layer.device = metal_layer.preferredDevice;
}
/* So acquire timeout works */
metal_layer.allowsNextDrawableTimeout = YES;
@ -39,10 +70,12 @@ wsi_metal_layer_configure(const CAMetalLayer *metal_layer,
metal_layer.maximumDrawableCount = image_count;
metal_layer.drawableSize = (CGSize){.width = width, .height = height};
metal_layer.pixelFormat = format;
metal_layer.opaque = enable_opaque;
metal_layer.displaySyncEnabled = !enable_immediate;
metal_layer.pixelFormat = metal_format;
}
return VK_SUCCESS;
}
CAMetalDrawableBridged *