From 4af4c97e44cac762fd01cc2eb0d712dc49ddb3e7 Mon Sep 17 00:00:00 2001
From: Cameron Cawley <[EMAIL REDACTED]>
Date: Fri, 16 Jan 2026 23:15:50 +0000
Subject: [PATCH] Support 16-bit packed texture formats with the Metal renderer
---
src/render/metal/SDL_render_metal.m | 46 ++++++++++++++++++++++++++++-
1 file changed, 45 insertions(+), 1 deletion(-)
diff --git a/src/render/metal/SDL_render_metal.m b/src/render/metal/SDL_render_metal.m
index 36a4b5cc336dd..5c1a3dc2f79dc 100644
--- a/src/render/metal/SDL_render_metal.m
+++ b/src/render/metal/SDL_render_metal.m
@@ -682,7 +682,7 @@ static bool METAL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SD
{
@autoreleasepool {
SDL3METAL_RenderData *data = (__bridge SDL3METAL_RenderData *)renderer->internal;
- MTLPixelFormat pixfmt;
+ MTLPixelFormat pixfmt = MTLPixelFormatInvalid;
MTLTextureDescriptor *mtltexdesc;
id<MTLTexture> mtltexture = nil, mtltextureUv = nil;
SDL3METAL_TextureData *texturedata;
@@ -715,6 +715,26 @@ static bool METAL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SD
case SDL_PIXELFORMAT_ABGR2101010:
pixfmt = MTLPixelFormatRGB10A2Unorm;
break;
+ case SDL_PIXELFORMAT_RGB565:
+ if (@available(macOS 11.0, *)) {
+ pixfmt = MTLPixelFormatB5G6R5Unorm;
+ }
+ break;
+ case SDL_PIXELFORMAT_RGBA5551:
+ if (@available(macOS 11.0, *)) {
+ pixfmt = MTLPixelFormatA1BGR5Unorm;
+ }
+ break;
+ case SDL_PIXELFORMAT_ARGB1555:
+ if (@available(macOS 11.0, *)) {
+ pixfmt = MTLPixelFormatBGR5A1Unorm;
+ }
+ break;
+ case SDL_PIXELFORMAT_RGBA4444:
+ if (@available(macOS 11.0, *)) {
+ pixfmt = MTLPixelFormatABGR4Unorm;
+ }
+ break;
case SDL_PIXELFORMAT_INDEX8:
case SDL_PIXELFORMAT_IYUV:
case SDL_PIXELFORMAT_YV12:
@@ -732,6 +752,10 @@ static bool METAL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SD
pixfmt = MTLPixelFormatRGBA32Float;
break;
default:
+ break;
+ }
+
+ if (pixfmt == MTLPixelFormatInvalid) {
return SDL_SetError("Texture format %s not supported by Metal", SDL_GetPixelFormatName(texture->format));
}
@@ -1949,6 +1973,18 @@ static bool METAL_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd
case MTLPixelFormatRGBA16Float:
format = SDL_PIXELFORMAT_RGBA64_FLOAT;
break;
+ case MTLPixelFormatB5G6R5Unorm:
+ format = SDL_PIXELFORMAT_RGB565;
+ break;
+ case MTLPixelFormatA1BGR5Unorm:
+ format = SDL_PIXELFORMAT_RGBA5551;
+ break;
+ case MTLPixelFormatBGR5A1Unorm:
+ format = SDL_PIXELFORMAT_ARGB1555;
+ break;
+ case MTLPixelFormatABGR4Unorm:
+ format = SDL_PIXELFORMAT_RGBA4444;
+ break;
default:
SDL_SetError("Unknown framebuffer pixel format");
return NULL;
@@ -2365,6 +2401,14 @@ in case we want to use it later (recreating the renderer)
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_ABGR2101010);
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_RGBA64_FLOAT);
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_RGBA128_FLOAT);
+ if (@available(macOS 11.0, iOS 13.0, tvOS 13.0, *)) {
+ if ([mtldevice supportsFamily:MTLGPUFamilyApple1]) {
+ SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_RGB565);
+ SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_RGBA5551);
+ SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_ARGB1555);
+ SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_RGBA4444);
+ }
+ }
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_INDEX8);
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_YV12);
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_IYUV);