Browse Source

Metal backend: initial commit

Kocsis Attila 10 years ago
parent
commit
5d5df77318
42 changed files with 5254 additions and 11 deletions
  1. 4 0
      examples/common/bgfx_utils.cpp
  2. 51 4
      examples/common/entry/entry_ios.mm
  3. 63 0
      examples/common/font/fs_font_basic.bin.h
  4. 97 0
      examples/common/font/fs_font_distance_field.bin.h
  5. 125 0
      examples/common/font/fs_font_distance_field_subpixel.bin.h
  6. 9 0
      examples/common/font/text_buffer_manager.cpp
  7. 51 0
      examples/common/font/vs_font_basic.bin.h
  8. 51 0
      examples/common/font/vs_font_distance_field.bin.h
  9. 51 0
      examples/common/font/vs_font_distance_field_subpixel.bin.h
  10. 29 0
      examples/common/imgui/fs_imgui_color.bin.h
  11. 52 0
      examples/common/imgui/fs_imgui_cubemap.bin.h
  12. 51 0
      examples/common/imgui/fs_imgui_image.bin.h
  13. 56 0
      examples/common/imgui/fs_imgui_image_swizz.bin.h
  14. 69 0
      examples/common/imgui/fs_imgui_latlong.bin.h
  15. 47 0
      examples/common/imgui/fs_imgui_texture.bin.h
  16. 43 0
      examples/common/imgui/fs_ocornut_imgui.bin.h
  17. 14 0
      examples/common/imgui/imgui.cpp
  18. 5 0
      examples/common/imgui/ocornut_imgui.cpp
  19. 44 0
      examples/common/imgui/vs_imgui_color.bin.h
  20. 44 0
      examples/common/imgui/vs_imgui_cubemap.bin.h
  21. 45 0
      examples/common/imgui/vs_imgui_image.bin.h
  22. 45 0
      examples/common/imgui/vs_imgui_latlong.bin.h
  23. 51 0
      examples/common/imgui/vs_imgui_texture.bin.h
  24. 57 0
      examples/common/imgui/vs_ocornut_imgui.bin.h
  25. 224 0
      examples/common/nanovg/fs_nanovg_fill.bin.h
  26. 5 0
      examples/common/nanovg/nanovg_bgfx.cpp
  27. 58 0
      examples/common/nanovg/vs_nanovg_fill.bin.h
  28. 42 1
      src/bgfx.cpp
  29. 9 1
      src/config.h
  30. 31 0
      src/fs_clear0.bin.h
  31. 37 0
      src/fs_clear1.bin.h
  32. 43 0
      src/fs_clear2.bin.h
  33. 49 0
      src/fs_clear3.bin.h
  34. 55 0
      src/fs_clear4.bin.h
  35. 61 0
      src/fs_clear5.bin.h
  36. 67 0
      src/fs_clear6.bin.h
  37. 73 0
      src/fs_clear7.bin.h
  38. 52 0
      src/fs_debugfont.bin.h
  39. 468 0
      src/renderer_mtl.h
  40. 2735 5
      src/renderer_mtl.mm
  41. 35 0
      src/vs_clear.bin.h
  42. 56 0
      src/vs_debugfont.bin.h

+ 4 - 0
examples/common/bgfx_utils.cpp

@@ -104,6 +104,10 @@ static bgfx::ShaderHandle loadShader(bx::FileReaderI* _reader, const char* _name
 		shaderPath = "shaders/glsl/";
 		break;
 
+	case bgfx::RendererType::Metal:
+		shaderPath = "shaders/metal/";
+		break;
+			
 	case bgfx::RendererType::OpenGLES:
 		shaderPath = "shaders/gles/";
 		break;

+ 51 - 4
examples/common/entry/entry_ios.mm

@@ -11,6 +11,12 @@
 #import <UIKit/UIKit.h>
 #import <QuartzCore/CAEAGLLayer.h>
 
+#if __IPHONE_8_0 && !TARGET_IPHONE_SIMULATOR  // check if sdk/target supports metal
+#   import <Metal/Metal.h>
+#   import <QuartzCore/CAMetalLayer.h>
+//#   define HAS_METAL_SDK
+#endif
+
 #include <bgfxplatform.h>
 
 #include <bx/uint32_t.h>
@@ -140,6 +146,22 @@ namespace entry
 
 using namespace entry;
 
+#ifdef HAS_METAL_SDK
+static	id<MTLDevice>  m_device = NULL;
+#else
+static	void* m_device = NULL;
+#endif
+
+@interface ViewController : UIViewController
+@end
+@implementation ViewController
+- (BOOL)prefersStatusBarHidden
+{
+	return YES;
+}
+@end
+
+
 @interface View : UIView
 {
 	CADisplayLink* m_displayLink;
@@ -151,6 +173,19 @@ using namespace entry;
 
 + (Class)layerClass
 {
+#ifdef HAS_METAL_SDK
+	Class metalClass = NSClassFromString(@"CAMetalLayer");    //is metal runtime sdk available
+	if ( metalClass != nil)
+	{
+		m_device = MTLCreateSystemDefaultDevice(); // is metal supported on this device (is there a better way to do this - without creating device ?)
+		if (m_device)
+		{
+			[m_device retain];
+			return metalClass;
+		}
+	}
+#endif
+	
 	return [CAEAGLLayer class];
 }
 
@@ -162,10 +197,15 @@ using namespace entry;
 	{
 		return nil;
 	}
-
-	CAEAGLLayer* layer = (CAEAGLLayer*)self.layer;
-	bgfx::iosSetEaglLayer(layer);
-
+	
+	bgfx::PlatformData pd;
+	pd.ndt          = NULL;
+	pd.nwh          = self.layer;
+	pd.context		= m_device;
+	pd.backBuffer   = NULL;
+	pd.backBufferDS = NULL;
+	bgfx::setPlatformData(pd);
+	
 	return self;
 }
 
@@ -263,6 +303,13 @@ using namespace entry;
 	m_view = [ [View alloc] initWithFrame: rect];
 
 	[m_window addSubview: m_view];
+
+	UIViewController *viewController = [[ViewController alloc] init];
+	viewController.view = m_view;
+
+	[m_window setRootViewController:viewController];
+	[m_window makeKeyAndVisible];
+	
 	[m_window makeKeyAndVisible];
 
 	//float scaleFactor = [[UIScreen mainScreen] scale]; // should use this, but ui is too small on ipad retina

+ 63 - 0
examples/common/font/fs_font_basic.bin.h

@@ -108,3 +108,66 @@ static const uint8_t fs_font_basic_dx11[600] =
 	0x72, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x12, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, // r ......F.......
 	0x3e, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,                                                 // >.......
 };
+static const uint8_t fs_font_basic_mtl[950] =
+{
+	0x46, 0x53, 0x48, 0x04, 0x01, 0x83, 0xf2, 0xe1, 0x00, 0x00, 0xa7, 0x03, 0x00, 0x00, 0x75, 0x73, // FSH...........us
+	0x69, 0x6e, 0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x6d, 0x65, // ing namespace me
+	0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // tal;.struct xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x7b, // MtlShaderInput {
+	0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, // .  float4 v_colo
+	0x72, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x76, 0x5f, 0x74, // r0;.  float4 v_t
+	0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, // excoord0;.};.str
+	0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, // uct xlatMtlShade
+	0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, // rOutput {.  half
+	0x34, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x0a, // 4 gl_FragColor;.
+	0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, // };.struct xlatMt
+	0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x7b, // lShaderUniform {
+	0x0a, 0x7d, 0x3b, 0x0a, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x78, 0x6c, 0x61, // .};.fragment xla
+	0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, // tMtlShaderOutput
+	0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x4d, 0x61, 0x69, 0x6e, 0x20, 0x28, 0x78, 0x6c, //  xlatMtlMain (xl
+	0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, // atMtlShaderInput
+	0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x20, 0x5b, 0x5b, 0x73, 0x74, 0x61, 0x67, 0x65, 0x5f, //  _mtl_i [[stage_
+	0x69, 0x6e, 0x5d, 0x5d, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x20, 0x78, // in]], constant x
+	0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, // latMtlShaderUnif
+	0x6f, 0x72, 0x6d, 0x26, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x20, 0x5b, 0x5b, 0x62, 0x75, // orm& _mtl_u [[bu
+	0x66, 0x66, 0x65, 0x72, 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x0a, 0x20, 0x20, 0x2c, 0x20, 0x20, 0x20, // ffer(0)]].  ,
+	0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x63, 0x75, 0x62, 0x65, 0x3c, 0x66, 0x6c, 0x6f, 0x61, // texturecube<floa
+	0x74, 0x3e, 0x20, 0x75, 0x5f, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x5b, 0x5b, // t> u_texColor [[
+	0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x2c, 0x20, 0x73, 0x61, // texture(0)]], sa
+	0x6d, 0x70, 0x6c, 0x65, 0x72, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x73, 0x6d, 0x70, 0x5f, 0x75, 0x5f, // mpler _mtlsmp_u_
+	0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x5b, 0x5b, 0x73, 0x61, 0x6d, 0x70, 0x6c, // texColor [[sampl
+	0x65, 0x72, 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x78, 0x6c, 0x61, // er(0)]]).{.  xla
+	0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, // tMtlShaderOutput
+	0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x20, //  _mtl_o;.  half
+	0x72, 0x67, 0x62, 0x61, 0x5f, 0x31, 0x5b, 0x34, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, // rgba_1[4];.  hal
+	0x66, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x3b, 0x0a, 0x20, 0x20, 0x74, // f4 tmpvar_2;.  t
+	0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x28, // mpvar_2 = half4(
+	0x75, 0x5f, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, // u_texColor.sampl
+	0x65, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x73, 0x6d, 0x70, 0x5f, 0x75, 0x5f, 0x74, 0x65, 0x78, 0x43, // e(_mtlsmp_u_texC
+	0x6f, 0x6c, 0x6f, 0x72, 0x2c, 0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x29, 0x28, 0x5f, // olor, (float3)(_
+	0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, // mtl_i.v_texcoord
+	0x30, 0x2e, 0x78, 0x79, 0x7a, 0x29, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x69, 0x6e, 0x74, 0x20, // 0.xyz)));.  int
+	0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x33, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, // tmpvar_3;.  tmpv
+	0x61, 0x72, 0x5f, 0x33, 0x20, 0x3d, 0x20, 0x69, 0x6e, 0x74, 0x28, 0x28, 0x28, 0x5f, 0x6d, 0x74, // ar_3 = int(((_mt
+	0x6c, 0x5f, 0x69, 0x2e, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x2e, // l_i.v_texcoord0.
+	0x77, 0x20, 0x2a, 0x20, 0x34, 0x2e, 0x30, 0x29, 0x20, 0x2b, 0x20, 0x30, 0x2e, 0x35, 0x29, 0x29, // w * 4.0) + 0.5))
+	0x3b, 0x0a, 0x20, 0x20, 0x72, 0x67, 0x62, 0x61, 0x5f, 0x31, 0x5b, 0x30, 0x5d, 0x20, 0x3d, 0x20, // ;.  rgba_1[0] =
+	0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x2e, 0x7a, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x67, // tmpvar_2.z;.  rg
+	0x62, 0x61, 0x5f, 0x31, 0x5b, 0x31, 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, // ba_1[1] = tmpvar
+	0x5f, 0x32, 0x2e, 0x79, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x67, 0x62, 0x61, 0x5f, 0x31, 0x5b, 0x32, // _2.y;.  rgba_1[2
+	0x5d, 0x20, 0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x2e, 0x78, 0x3b, 0x0a, // ] = tmpvar_2.x;.
+	0x20, 0x20, 0x72, 0x67, 0x62, 0x61, 0x5f, 0x31, 0x5b, 0x33, 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x6d, //   rgba_1[3] = tm
+	0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x2e, 0x77, 0x3b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, // pvar_2.w;.  half
+	0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x34, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, // 4 tmpvar_4;.  tm
+	0x70, 0x76, 0x61, 0x72, 0x5f, 0x34, 0x2e, 0x78, 0x79, 0x7a, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, // pvar_4.xyz = hal
+	0x66, 0x33, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, // f3(_mtl_i.v_colo
+	0x72, 0x30, 0x2e, 0x78, 0x79, 0x7a, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, // r0.xyz);.  tmpva
+	0x72, 0x5f, 0x34, 0x2e, 0x77, 0x20, 0x3d, 0x20, 0x28, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x28, // r_4.w = ((half)(
+	0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x2e, // _mtl_i.v_color0.
+	0x77, 0x20, 0x2a, 0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x29, 0x72, 0x67, 0x62, 0x61, 0x5f, // w * (float)rgba_
+	0x31, 0x5b, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x33, 0x5d, 0x29, 0x29, 0x3b, 0x0a, 0x20, // 1[tmpvar_3]));.
+	0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, //  _mtl_o.gl_FragC
+	0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x34, 0x3b, // olor = tmpvar_4;
+	0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, // .  return _mtl_o
+	0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00,                                                             // ;.}...
+};

+ 97 - 0
examples/common/font/fs_font_distance_field.bin.h

@@ -183,3 +183,100 @@ static const uint8_t fs_font_distance_field_dx11[1036] =
 	0x36, 0x00, 0x00, 0x05, 0x72, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x12, 0x10, 0x00, // 6...r ......F...
 	0x01, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,                         // ....>.......
 };
+static const uint8_t fs_font_distance_field_mtl[1492] =
+{
+	0x46, 0x53, 0x48, 0x04, 0x01, 0x83, 0xf2, 0xe1, 0x00, 0x00, 0xc5, 0x05, 0x00, 0x00, 0x75, 0x73, // FSH...........us
+	0x69, 0x6e, 0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x6d, 0x65, // ing namespace me
+	0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // tal;.struct xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x7b, // MtlShaderInput {
+	0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, // .  float4 v_colo
+	0x72, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x76, 0x5f, 0x74, // r0;.  float4 v_t
+	0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, // excoord0;.};.str
+	0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, // uct xlatMtlShade
+	0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, // rOutput {.  half
+	0x34, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x0a, // 4 gl_FragColor;.
+	0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, // };.struct xlatMt
+	0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x7b, // lShaderUniform {
+	0x0a, 0x7d, 0x3b, 0x0a, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x78, 0x6c, 0x61, // .};.fragment xla
+	0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, // tMtlShaderOutput
+	0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x4d, 0x61, 0x69, 0x6e, 0x20, 0x28, 0x78, 0x6c, //  xlatMtlMain (xl
+	0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, // atMtlShaderInput
+	0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x20, 0x5b, 0x5b, 0x73, 0x74, 0x61, 0x67, 0x65, 0x5f, //  _mtl_i [[stage_
+	0x69, 0x6e, 0x5d, 0x5d, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x20, 0x78, // in]], constant x
+	0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, // latMtlShaderUnif
+	0x6f, 0x72, 0x6d, 0x26, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x20, 0x5b, 0x5b, 0x62, 0x75, // orm& _mtl_u [[bu
+	0x66, 0x66, 0x65, 0x72, 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x0a, 0x20, 0x20, 0x2c, 0x20, 0x20, 0x20, // ffer(0)]].  ,
+	0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x63, 0x75, 0x62, 0x65, 0x3c, 0x66, 0x6c, 0x6f, 0x61, // texturecube<floa
+	0x74, 0x3e, 0x20, 0x75, 0x5f, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x5b, 0x5b, // t> u_texColor [[
+	0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x2c, 0x20, 0x73, 0x61, // texture(0)]], sa
+	0x6d, 0x70, 0x6c, 0x65, 0x72, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x73, 0x6d, 0x70, 0x5f, 0x75, 0x5f, // mpler _mtlsmp_u_
+	0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x5b, 0x5b, 0x73, 0x61, 0x6d, 0x70, 0x6c, // texColor [[sampl
+	0x65, 0x72, 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x78, 0x6c, 0x61, // er(0)]]).{.  xla
+	0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, // tMtlShaderOutput
+	0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x20, //  _mtl_o;.  half
+	0x72, 0x67, 0x62, 0x61, 0x5f, 0x31, 0x5b, 0x34, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, // rgba_1[4];.  hal
+	0x66, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x3b, 0x0a, 0x20, 0x20, 0x74, // f4 tmpvar_2;.  t
+	0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x28, // mpvar_2 = half4(
+	0x75, 0x5f, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, // u_texColor.sampl
+	0x65, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x73, 0x6d, 0x70, 0x5f, 0x75, 0x5f, 0x74, 0x65, 0x78, 0x43, // e(_mtlsmp_u_texC
+	0x6f, 0x6c, 0x6f, 0x72, 0x2c, 0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x29, 0x28, 0x5f, // olor, (float3)(_
+	0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, // mtl_i.v_texcoord
+	0x30, 0x2e, 0x78, 0x79, 0x7a, 0x29, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x69, 0x6e, 0x74, 0x20, // 0.xyz)));.  int
+	0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x33, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, // tmpvar_3;.  tmpv
+	0x61, 0x72, 0x5f, 0x33, 0x20, 0x3d, 0x20, 0x69, 0x6e, 0x74, 0x28, 0x28, 0x28, 0x5f, 0x6d, 0x74, // ar_3 = int(((_mt
+	0x6c, 0x5f, 0x69, 0x2e, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x2e, // l_i.v_texcoord0.
+	0x77, 0x20, 0x2a, 0x20, 0x34, 0x2e, 0x30, 0x29, 0x20, 0x2b, 0x20, 0x30, 0x2e, 0x35, 0x29, 0x29, // w * 4.0) + 0.5))
+	0x3b, 0x0a, 0x20, 0x20, 0x72, 0x67, 0x62, 0x61, 0x5f, 0x31, 0x5b, 0x30, 0x5d, 0x20, 0x3d, 0x20, // ;.  rgba_1[0] =
+	0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x2e, 0x7a, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x67, // tmpvar_2.z;.  rg
+	0x62, 0x61, 0x5f, 0x31, 0x5b, 0x31, 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, // ba_1[1] = tmpvar
+	0x5f, 0x32, 0x2e, 0x79, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x67, 0x62, 0x61, 0x5f, 0x31, 0x5b, 0x32, // _2.y;.  rgba_1[2
+	0x5d, 0x20, 0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x2e, 0x78, 0x3b, 0x0a, // ] = tmpvar_2.x;.
+	0x20, 0x20, 0x72, 0x67, 0x62, 0x61, 0x5f, 0x31, 0x5b, 0x33, 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x6d, //   rgba_1[3] = tm
+	0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x2e, 0x77, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, // pvar_2.w;.  floa
+	0x74, 0x33, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x34, 0x3b, 0x0a, 0x20, 0x20, 0x74, // t3 tmpvar_4;.  t
+	0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x34, 0x20, 0x3d, 0x20, 0x64, 0x66, 0x64, 0x78, 0x28, 0x5f, // mpvar_4 = dfdx(_
+	0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, // mtl_i.v_texcoord
+	0x30, 0x2e, 0x78, 0x79, 0x7a, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, // 0.xyz);.  float3
+	0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x35, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, //  tmpvar_5;.  tmp
+	0x76, 0x61, 0x72, 0x5f, 0x35, 0x20, 0x3d, 0x20, 0x64, 0x66, 0x64, 0x79, 0x28, 0x5f, 0x6d, 0x74, // var_5 = dfdy(_mt
+	0x6c, 0x5f, 0x69, 0x2e, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x2e, // l_i.v_texcoord0.
+	0x78, 0x79, 0x7a, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x74, 0x6d, // xyz);.  float tm
+	0x70, 0x76, 0x61, 0x72, 0x5f, 0x36, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, // pvar_6;.  tmpvar
+	0x5f, 0x36, 0x20, 0x3d, 0x20, 0x28, 0x38, 0x2e, 0x30, 0x20, 0x2a, 0x20, 0x28, 0x73, 0x71, 0x72, // _6 = (8.0 * (sqr
+	0x74, 0x28, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x74, 0x20, 0x28, 0x74, 0x6d, 0x70, 0x76, // t(.    dot (tmpv
+	0x61, 0x72, 0x5f, 0x34, 0x2c, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x34, 0x29, 0x0a, // ar_4, tmpvar_4).
+	0x20, 0x20, 0x29, 0x20, 0x2b, 0x20, 0x73, 0x71, 0x72, 0x74, 0x28, 0x0a, 0x20, 0x20, 0x20, 0x20, //   ) + sqrt(.
+	0x64, 0x6f, 0x74, 0x20, 0x28, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x35, 0x2c, 0x20, 0x74, // dot (tmpvar_5, t
+	0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x35, 0x29, 0x0a, 0x20, 0x20, 0x29, 0x29, 0x29, 0x3b, 0x0a, // mpvar_5).  )));.
+	0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x65, 0x64, 0x67, 0x65, 0x30, 0x5f, 0x37, 0x3b, //   float edge0_7;
+	0x0a, 0x20, 0x20, 0x65, 0x64, 0x67, 0x65, 0x30, 0x5f, 0x37, 0x20, 0x3d, 0x20, 0x28, 0x30, 0x2e, // .  edge0_7 = (0.
+	0x35, 0x20, 0x2d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x36, 0x29, 0x3b, 0x0a, 0x20, // 5 - tmpvar_6);.
+	0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x65, 0x64, 0x67, 0x65, 0x31, 0x5f, 0x38, 0x3b, 0x0a, //  float edge1_8;.
+	0x20, 0x20, 0x65, 0x64, 0x67, 0x65, 0x31, 0x5f, 0x38, 0x20, 0x3d, 0x20, 0x28, 0x30, 0x2e, 0x35, //   edge1_8 = (0.5
+	0x20, 0x2b, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x36, 0x29, 0x3b, 0x0a, 0x20, 0x20, //  + tmpvar_6);.
+	0x68, 0x61, 0x6c, 0x66, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x39, 0x3b, 0x0a, 0x20, // half tmpvar_9;.
+	0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x39, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x61, 0x6d, //  tmpvar_9 = clam
+	0x70, 0x20, 0x28, 0x28, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x28, 0x28, 0x66, 0x6c, 0x6f, 0x61, // p (((half)((floa
+	0x74, 0x29, 0x28, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x28, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, // t)((half)((float
+	0x29, 0x72, 0x67, 0x62, 0x61, 0x5f, 0x31, 0x5b, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x33, // )rgba_1[tmpvar_3
+	0x5d, 0x20, 0x2d, 0x20, 0x65, 0x64, 0x67, 0x65, 0x30, 0x5f, 0x37, 0x29, 0x29, 0x20, 0x2f, 0x20, // ] - edge0_7)) /
+	0x28, 0x65, 0x64, 0x67, 0x65, 0x31, 0x5f, 0x38, 0x20, 0x2d, 0x20, 0x65, 0x64, 0x67, 0x65, 0x30, // (edge1_8 - edge0
+	0x5f, 0x37, 0x29, 0x29, 0x29, 0x2c, 0x20, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x30, 0x2e, 0x30, // _7))), (half)0.0
+	0x2c, 0x20, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x31, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x20, 0x20, // , (half)1.0);.
+	0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x30, 0x3b, // half4 tmpvar_10;
+	0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x30, 0x2e, 0x78, 0x79, 0x7a, // .  tmpvar_10.xyz
+	0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x33, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, //  = half3(_mtl_i.
+	0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x2e, 0x78, 0x79, 0x7a, 0x29, 0x3b, 0x0a, 0x20, // v_color0.xyz);.
+	0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x30, 0x2e, 0x77, 0x20, 0x3d, 0x20, 0x28, //  tmpvar_10.w = (
+	0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x76, 0x5f, // (half)(_mtl_i.v_
+	0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x2e, 0x77, 0x20, 0x2a, 0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61, // color0.w * (floa
+	0x74, 0x29, 0x28, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x39, 0x20, 0x2a, 0x20, 0x28, 0x74, // t)(tmpvar_9 * (t
+	0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x39, 0x20, 0x2a, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x28, // mpvar_9 * .    (
+	0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x33, 0x2e, 0x30, 0x20, 0x2d, 0x20, 0x28, 0x28, 0x68, 0x61, // (half)3.0 - ((ha
+	0x6c, 0x66, 0x29, 0x32, 0x2e, 0x30, 0x20, 0x2a, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, // lf)2.0 * tmpvar_
+	0x39, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x29, 0x29, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, // 9)).  ))));.  _m
+	0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, // tl_o.gl_FragColo
+	0x72, 0x20, 0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x30, 0x3b, 0x0a, 0x20, // r = tmpvar_10;.
+	0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, //  return _mtl_o;.
+	0x7d, 0x0a, 0x0a, 0x00,                                                                         // }...
+};

+ 125 - 0
examples/common/font/fs_font_distance_field_subpixel.bin.h

@@ -224,3 +224,128 @@ static const uint8_t fs_font_distance_field_subpixel_dx11[1288] =
 	0x46, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x1f, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, // F...............
 	0x3e, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,                                                 // >.......
 };
+static const uint8_t fs_font_distance_field_subpixel_mtl[1945] =
+{
+	0x46, 0x53, 0x48, 0x04, 0x01, 0x83, 0xf2, 0xe1, 0x00, 0x00, 0x8a, 0x07, 0x00, 0x00, 0x75, 0x73, // FSH...........us
+	0x69, 0x6e, 0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x6d, 0x65, // ing namespace me
+	0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // tal;.struct xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x7b, // MtlShaderInput {
+	0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, // .  float4 v_colo
+	0x72, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x76, 0x5f, 0x74, // r0;.  float4 v_t
+	0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, // excoord0;.};.str
+	0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, // uct xlatMtlShade
+	0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, // rOutput {.  half
+	0x34, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x0a, // 4 gl_FragColor;.
+	0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, // };.struct xlatMt
+	0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x7b, // lShaderUniform {
+	0x0a, 0x7d, 0x3b, 0x0a, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x78, 0x6c, 0x61, // .};.fragment xla
+	0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, // tMtlShaderOutput
+	0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x4d, 0x61, 0x69, 0x6e, 0x20, 0x28, 0x78, 0x6c, //  xlatMtlMain (xl
+	0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, // atMtlShaderInput
+	0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x20, 0x5b, 0x5b, 0x73, 0x74, 0x61, 0x67, 0x65, 0x5f, //  _mtl_i [[stage_
+	0x69, 0x6e, 0x5d, 0x5d, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x20, 0x78, // in]], constant x
+	0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, // latMtlShaderUnif
+	0x6f, 0x72, 0x6d, 0x26, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x20, 0x5b, 0x5b, 0x62, 0x75, // orm& _mtl_u [[bu
+	0x66, 0x66, 0x65, 0x72, 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x0a, 0x20, 0x20, 0x2c, 0x20, 0x20, 0x20, // ffer(0)]].  ,
+	0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x63, 0x75, 0x62, 0x65, 0x3c, 0x66, 0x6c, 0x6f, 0x61, // texturecube<floa
+	0x74, 0x3e, 0x20, 0x75, 0x5f, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x5b, 0x5b, // t> u_texColor [[
+	0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x2c, 0x20, 0x73, 0x61, // texture(0)]], sa
+	0x6d, 0x70, 0x6c, 0x65, 0x72, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x73, 0x6d, 0x70, 0x5f, 0x75, 0x5f, // mpler _mtlsmp_u_
+	0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x5b, 0x5b, 0x73, 0x61, 0x6d, 0x70, 0x6c, // texColor [[sampl
+	0x65, 0x72, 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x78, 0x6c, 0x61, // er(0)]]).{.  xla
+	0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, // tMtlShaderOutput
+	0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x20, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x74, //  _mtl_o;.  int t
+	0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, // mpvar_1;.  tmpva
+	0x72, 0x5f, 0x31, 0x20, 0x3d, 0x20, 0x69, 0x6e, 0x74, 0x28, 0x28, 0x28, 0x5f, 0x6d, 0x74, 0x6c, // r_1 = int(((_mtl
+	0x5f, 0x69, 0x2e, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x2e, 0x77, // _i.v_texcoord0.w
+	0x20, 0x2a, 0x20, 0x34, 0x2e, 0x30, 0x29, 0x20, 0x2b, 0x20, 0x30, 0x2e, 0x35, 0x29, 0x29, 0x3b, //  * 4.0) + 0.5));
+	0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, // .  float3 tmpvar
+	0x5f, 0x32, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x20, 0x3d, // _2;.  tmpvar_2 =
+	0x20, 0x64, 0x66, 0x64, 0x78, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x76, 0x5f, 0x74, //  dfdx(_mtl_i.v_t
+	0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x2e, 0x78, 0x79, 0x7a, 0x29, 0x3b, 0x0a, 0x20, // excoord0.xyz);.
+	0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x33, //  float3 tmpvar_3
+	0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x33, 0x20, 0x3d, 0x20, 0x64, // ;.  tmpvar_3 = d
+	0x66, 0x64, 0x79, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x76, 0x5f, 0x74, 0x65, 0x78, // fdy(_mtl_i.v_tex
+	0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x2e, 0x78, 0x79, 0x7a, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x66, // coord0.xyz);.  f
+	0x6c, 0x6f, 0x61, 0x74, 0x33, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x34, 0x3b, 0x0a, // loat3 tmpvar_4;.
+	0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x34, 0x20, 0x3d, 0x20, 0x28, 0x30, 0x2e, //   tmpvar_4 = (0.
+	0x31, 0x36, 0x36, 0x36, 0x36, 0x37, 0x20, 0x2a, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, // 166667 * tmpvar_
+	0x32, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x20, 0x74, 0x6d, 0x70, // 2);.  float3 tmp
+	0x76, 0x61, 0x72, 0x5f, 0x35, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, // var_5;.  tmpvar_
+	0x35, 0x20, 0x3d, 0x20, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x76, 0x5f, 0x74, 0x65, // 5 = (_mtl_i.v_te
+	0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x2e, 0x78, 0x79, 0x7a, 0x20, 0x2d, 0x20, 0x74, 0x6d, // xcoord0.xyz - tm
+	0x70, 0x76, 0x61, 0x72, 0x5f, 0x34, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, // pvar_4);.  float
+	0x33, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x36, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, // 3 tmpvar_6;.  tm
+	0x70, 0x76, 0x61, 0x72, 0x5f, 0x36, 0x20, 0x3d, 0x20, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, // pvar_6 = (_mtl_i
+	0x2e, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x2e, 0x78, 0x79, 0x7a, // .v_texcoord0.xyz
+	0x20, 0x2b, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x34, 0x29, 0x3b, 0x0a, 0x20, 0x20, //  + tmpvar_4);.
+	0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x37, 0x3b, 0x0a, // half4 tmpvar_7;.
+	0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x37, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, //   tmpvar_7 = hal
+	0x66, 0x34, 0x28, 0x75, 0x5f, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2e, 0x73, 0x61, // f4(u_texColor.sa
+	0x6d, 0x70, 0x6c, 0x65, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x73, 0x6d, 0x70, 0x5f, 0x75, 0x5f, 0x74, // mple(_mtlsmp_u_t
+	0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2c, 0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, // exColor, (float3
+	0x29, 0x28, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x35, 0x29, 0x29, 0x29, 0x3b, 0x0a, 0x20, // )(tmpvar_5)));.
+	0x20, 0x68, 0x61, 0x6c, 0x66, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x38, 0x3b, 0x0a, //  half tmpvar_8;.
+	0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x38, 0x20, 0x3d, 0x20, 0x28, 0x28, 0x68, //   tmpvar_8 = ((h
+	0x61, 0x6c, 0x66, 0x29, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x37, 0x2e, 0x7a, 0x79, 0x78, // alf)tmpvar_7.zyx
+	0x77, 0x5b, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x5d, 0x29, 0x3b, 0x0a, 0x20, 0x20, // w[tmpvar_1]);.
+	0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x39, 0x3b, 0x0a, // half4 tmpvar_9;.
+	0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x39, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, //   tmpvar_9 = hal
+	0x66, 0x34, 0x28, 0x75, 0x5f, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2e, 0x73, 0x61, // f4(u_texColor.sa
+	0x6d, 0x70, 0x6c, 0x65, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x73, 0x6d, 0x70, 0x5f, 0x75, 0x5f, 0x74, // mple(_mtlsmp_u_t
+	0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2c, 0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, // exColor, (float3
+	0x29, 0x28, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x36, 0x29, 0x29, 0x29, 0x3b, 0x0a, 0x20, // )(tmpvar_6)));.
+	0x20, 0x68, 0x61, 0x6c, 0x66, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x30, 0x3b, //  half tmpvar_10;
+	0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x30, 0x20, 0x3d, 0x20, 0x28, // .  tmpvar_10 = (
+	0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x39, 0x2e, 0x7a, // (half)tmpvar_9.z
+	0x79, 0x78, 0x77, 0x5b, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x5d, 0x29, 0x3b, 0x0a, // yxw[tmpvar_1]);.
+	0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x31, //   half tmpvar_11
+	0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x31, 0x20, 0x3d, 0x20, // ;.  tmpvar_11 =
+	0x28, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x30, 0x2e, 0x35, 0x20, 0x2a, 0x20, 0x28, 0x74, 0x6d, // ((half)0.5 * (tm
+	0x70, 0x76, 0x61, 0x72, 0x5f, 0x38, 0x20, 0x2b, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, // pvar_8 + tmpvar_
+	0x31, 0x30, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x74, 0x6d, // 10));.  float tm
+	0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x32, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, // pvar_12;.  tmpva
+	0x72, 0x5f, 0x31, 0x32, 0x20, 0x3d, 0x20, 0x28, 0x38, 0x2e, 0x30, 0x20, 0x2a, 0x20, 0x28, 0x73, // r_12 = (8.0 * (s
+	0x71, 0x72, 0x74, 0x28, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x74, 0x20, 0x28, 0x74, 0x6d, // qrt(.    dot (tm
+	0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x2c, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, // pvar_2, tmpvar_2
+	0x29, 0x0a, 0x20, 0x20, 0x29, 0x20, 0x2b, 0x20, 0x73, 0x71, 0x72, 0x74, 0x28, 0x0a, 0x20, 0x20, // ).  ) + sqrt(.
+	0x20, 0x20, 0x64, 0x6f, 0x74, 0x20, 0x28, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x33, 0x2c, //   dot (tmpvar_3,
+	0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x33, 0x29, 0x0a, 0x20, 0x20, 0x29, 0x29, 0x29, //  tmpvar_3).  )))
+	0x3b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x33, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, // ;.  half3 tmpvar
+	0x5f, 0x31, 0x33, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x33, // _13;.  tmpvar_13
+	0x2e, 0x78, 0x20, 0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x38, 0x3b, 0x0a, 0x20, // .x = tmpvar_8;.
+	0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x33, 0x2e, 0x79, 0x20, 0x3d, 0x20, 0x74, //  tmpvar_13.y = t
+	0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, // mpvar_11;.  tmpv
+	0x61, 0x72, 0x5f, 0x31, 0x33, 0x2e, 0x7a, 0x20, 0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, // ar_13.z = tmpvar
+	0x5f, 0x31, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x65, 0x64, 0x67, // _10;.  float edg
+	0x65, 0x30, 0x5f, 0x31, 0x34, 0x3b, 0x0a, 0x20, 0x20, 0x65, 0x64, 0x67, 0x65, 0x30, 0x5f, 0x31, // e0_14;.  edge0_1
+	0x34, 0x20, 0x3d, 0x20, 0x28, 0x30, 0x2e, 0x35, 0x20, 0x2d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, // 4 = (0.5 - tmpva
+	0x72, 0x5f, 0x31, 0x32, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x65, // r_12);.  float e
+	0x64, 0x67, 0x65, 0x31, 0x5f, 0x31, 0x35, 0x3b, 0x0a, 0x20, 0x20, 0x65, 0x64, 0x67, 0x65, 0x31, // dge1_15;.  edge1
+	0x5f, 0x31, 0x35, 0x20, 0x3d, 0x20, 0x28, 0x30, 0x2e, 0x35, 0x20, 0x2b, 0x20, 0x74, 0x6d, 0x70, // _15 = (0.5 + tmp
+	0x76, 0x61, 0x72, 0x5f, 0x31, 0x32, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x33, // var_12);.  half3
+	0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x36, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, //  tmpvar_16;.  tm
+	0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x36, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x61, 0x6d, 0x70, 0x20, // pvar_16 = clamp
+	0x28, 0x28, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x33, 0x29, 0x28, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, // (((half3)((float
+	0x33, 0x29, 0x28, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x33, 0x29, 0x28, 0x28, 0x66, 0x6c, 0x6f, 0x61, // 3)((half3)((floa
+	0x74, 0x33, 0x29, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x33, 0x20, 0x2d, 0x20, 0x65, // t3)tmpvar_13 - e
+	0x64, 0x67, 0x65, 0x30, 0x5f, 0x31, 0x34, 0x29, 0x29, 0x20, 0x2f, 0x20, 0x28, 0x65, 0x64, 0x67, // dge0_14)) / (edg
+	0x65, 0x31, 0x5f, 0x31, 0x35, 0x20, 0x2d, 0x20, 0x65, 0x64, 0x67, 0x65, 0x30, 0x5f, 0x31, 0x34, // e1_15 - edge0_14
+	0x29, 0x29, 0x29, 0x2c, 0x20, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x30, 0x2e, 0x30, 0x2c, 0x20, // ))), (half)0.0,
+	0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x31, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, // (half)1.0);.  _m
+	0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, // tl_o.gl_FragColo
+	0x72, 0x2e, 0x78, 0x79, 0x7a, 0x20, 0x3d, 0x20, 0x28, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x33, 0x29, // r.xyz = ((half3)
+	0x28, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x29, 0x28, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, // ((float3)(tmpvar
+	0x5f, 0x31, 0x36, 0x20, 0x2a, 0x20, 0x28, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x36, // _16 * (tmpvar_16
+	0x20, 0x2a, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x28, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x33, //  * .    ((half)3
+	0x2e, 0x30, 0x20, 0x2d, 0x20, 0x28, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x32, 0x2e, 0x30, 0x20, // .0 - ((half)2.0
+	0x2a, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x36, 0x29, 0x29, 0x0a, 0x20, 0x20, // * tmpvar_16)).
+	0x29, 0x29, 0x20, 0x2a, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x76, 0x5f, 0x63, 0x6f, // )) * _mtl_i.v_co
+	0x6c, 0x6f, 0x72, 0x30, 0x2e, 0x77, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, // lor0.w));.  _mtl
+	0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2e, // _o.gl_FragColor.
+	0x77, 0x20, 0x3d, 0x20, 0x28, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x28, 0x28, 0x66, 0x6c, 0x6f, // w = ((half)((flo
+	0x61, 0x74, 0x29, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x31, 0x20, 0x2a, 0x20, 0x5f, // at)tmpvar_11 * _
+	0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x2e, 0x77, // mtl_i.v_color0.w
+	0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x6d, 0x74, // ));.  return _mt
+	0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00,                                           // l_o;.}...
+};

+ 9 - 0
examples/common/font/text_buffer_manager.cpp

@@ -584,6 +584,15 @@ TextBufferManager::TextBufferManager(FontManager* _fontManager)
 		fs_font_distance_field_subpixel = bgfx::makeRef(fs_font_distance_field_subpixel_dx11, sizeof(fs_font_distance_field_subpixel_dx11) );
 		break;
 
+	case bgfx::RendererType::Metal:
+		vs_font_basic = bgfx::makeRef(vs_font_basic_mtl, sizeof(vs_font_basic_mtl) );
+		fs_font_basic = bgfx::makeRef(fs_font_basic_mtl, sizeof(fs_font_basic_mtl) );
+		vs_font_distance_field = bgfx::makeRef(vs_font_distance_field_mtl, sizeof(vs_font_distance_field_mtl) );
+		fs_font_distance_field = bgfx::makeRef(fs_font_distance_field_mtl, sizeof(fs_font_distance_field_mtl) );
+		vs_font_distance_field_subpixel = bgfx::makeRef(vs_font_distance_field_subpixel_mtl, sizeof(vs_font_distance_field_subpixel_mtl) );
+		fs_font_distance_field_subpixel = bgfx::makeRef(fs_font_distance_field_subpixel_mtl, sizeof(fs_font_distance_field_subpixel_mtl) );
+		break;
+			
 	default:
 		vs_font_basic = bgfx::makeRef(vs_font_basic_glsl, sizeof(vs_font_basic_glsl) );
 		fs_font_basic = bgfx::makeRef(fs_font_basic_glsl, sizeof(fs_font_basic_glsl) );

+ 51 - 0
examples/common/font/vs_font_basic.bin.h

@@ -92,3 +92,54 @@ static const uint8_t vs_font_basic_dx11[580] =
 	0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x00, 0x03, 0x05, 0x00, 0x01, 0x00, // ......>.........
 	0x10, 0x00, 0x40, 0x00,                                                                         // ..@.
 };
+static const uint8_t vs_font_basic_mtl[764] =
+{
+	0x56, 0x53, 0x48, 0x04, 0x01, 0x83, 0xf2, 0xe1, 0x00, 0x00, 0xed, 0x02, 0x00, 0x00, 0x75, 0x73, // VSH...........us
+	0x69, 0x6e, 0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x6d, 0x65, // ing namespace me
+	0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // tal;.struct xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x7b, // MtlShaderInput {
+	0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x61, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, // .  float4 a_colo
+	0x72, 0x30, 0x20, 0x5b, 0x5b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x30, // r0 [[attribute(0
+	0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x61, 0x5f, // )]];.  float2 a_
+	0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5b, 0x5b, 0x61, 0x74, 0x74, 0x72, 0x69, // position [[attri
+	0x62, 0x75, 0x74, 0x65, 0x28, 0x31, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, // bute(1)]];.  flo
+	0x61, 0x74, 0x34, 0x20, 0x61, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x20, // at4 a_texcoord0
+	0x5b, 0x5b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x32, 0x29, 0x5d, 0x5d, // [[attribute(2)]]
+	0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // ;.};.struct xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, // MtlShaderOutput
+	0x7b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x67, 0x6c, 0x5f, 0x50, 0x6f, // {.  float4 gl_Po
+	0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5b, 0x5b, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, // sition [[positio
+	0x6e, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x76, 0x5f, // n]];.  float4 v_
+	0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, // color0;.  float4
+	0x20, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x3b, 0x0a, 0x7d, 0x3b, //  v_texcoord0;.};
+	0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, // .struct xlatMtlS
+	0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x7b, 0x0a, 0x20, // haderUniform {.
+	0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x78, 0x34, 0x20, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, //  float4x4 u_mode
+	0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x76, 0x65, // lViewProj;.};.ve
+	0x72, 0x74, 0x65, 0x78, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, // rtex xlatMtlShad
+	0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, // erOutput xlatMtl
+	0x4d, 0x61, 0x69, 0x6e, 0x20, 0x28, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, // Main (xlatMtlSha
+	0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x20, // derInput _mtl_i
+	0x5b, 0x5b, 0x73, 0x74, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x6e, 0x5d, 0x5d, 0x2c, 0x20, 0x63, 0x6f, // [[stage_in]], co
+	0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, // nstant xlatMtlSh
+	0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x26, 0x20, 0x5f, 0x6d, 0x74, // aderUniform& _mt
+	0x6c, 0x5f, 0x75, 0x20, 0x5b, 0x5b, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x28, 0x30, 0x29, 0x5d, // l_u [[buffer(0)]
+	0x5d, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, // ]).{.  xlatMtlSh
+	0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, // aderOutput _mtl_
+	0x6f, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, // o;.  float4 tmpv
+	0x61, 0x72, 0x5f, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, // ar_1;.  tmpvar_1
+	0x2e, 0x7a, 0x77, 0x20, 0x3d, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x28, 0x30, 0x2e, 0x30, // .zw = float2(0.0
+	0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, // , 1.0);.  tmpvar
+	0x5f, 0x31, 0x2e, 0x78, 0x79, 0x20, 0x3d, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x61, // _1.xy = _mtl_i.a
+	0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, // _position;.  _mt
+	0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, // l_o.gl_Position
+	0x3d, 0x20, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, // = (_mtl_u.u_mode
+	0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x20, 0x2a, 0x20, 0x74, 0x6d, 0x70, 0x76, // lViewProj * tmpv
+	0x61, 0x72, 0x5f, 0x31, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, // ar_1);.  _mtl_o.
+	0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x20, 0x3d, 0x20, 0x5f, 0x6d, // v_texcoord0 = _m
+	0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x61, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, // tl_i.a_texcoord0
+	0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x76, 0x5f, 0x63, 0x6f, 0x6c, // ;.  _mtl_o.v_col
+	0x6f, 0x72, 0x30, 0x20, 0x3d, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x61, 0x5f, 0x63, // or0 = _mtl_i.a_c
+	0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, // olor0;.  return
+	0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00,                         // _mtl_o;.}...
+};

+ 51 - 0
examples/common/font/vs_font_distance_field.bin.h

@@ -92,3 +92,54 @@ static const uint8_t vs_font_distance_field_dx11[580] =
 	0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x00, 0x03, 0x05, 0x00, 0x01, 0x00, // ......>.........
 	0x10, 0x00, 0x40, 0x00,                                                                         // ..@.
 };
+static const uint8_t vs_font_distance_field_mtl[764] =
+{
+	0x56, 0x53, 0x48, 0x04, 0x01, 0x83, 0xf2, 0xe1, 0x00, 0x00, 0xed, 0x02, 0x00, 0x00, 0x75, 0x73, // VSH...........us
+	0x69, 0x6e, 0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x6d, 0x65, // ing namespace me
+	0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // tal;.struct xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x7b, // MtlShaderInput {
+	0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x61, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, // .  float4 a_colo
+	0x72, 0x30, 0x20, 0x5b, 0x5b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x30, // r0 [[attribute(0
+	0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x61, 0x5f, // )]];.  float2 a_
+	0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5b, 0x5b, 0x61, 0x74, 0x74, 0x72, 0x69, // position [[attri
+	0x62, 0x75, 0x74, 0x65, 0x28, 0x31, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, // bute(1)]];.  flo
+	0x61, 0x74, 0x34, 0x20, 0x61, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x20, // at4 a_texcoord0
+	0x5b, 0x5b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x32, 0x29, 0x5d, 0x5d, // [[attribute(2)]]
+	0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // ;.};.struct xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, // MtlShaderOutput
+	0x7b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x67, 0x6c, 0x5f, 0x50, 0x6f, // {.  float4 gl_Po
+	0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5b, 0x5b, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, // sition [[positio
+	0x6e, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x76, 0x5f, // n]];.  float4 v_
+	0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, // color0;.  float4
+	0x20, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x3b, 0x0a, 0x7d, 0x3b, //  v_texcoord0;.};
+	0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, // .struct xlatMtlS
+	0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x7b, 0x0a, 0x20, // haderUniform {.
+	0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x78, 0x34, 0x20, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, //  float4x4 u_mode
+	0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x76, 0x65, // lViewProj;.};.ve
+	0x72, 0x74, 0x65, 0x78, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, // rtex xlatMtlShad
+	0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, // erOutput xlatMtl
+	0x4d, 0x61, 0x69, 0x6e, 0x20, 0x28, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, // Main (xlatMtlSha
+	0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x20, // derInput _mtl_i
+	0x5b, 0x5b, 0x73, 0x74, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x6e, 0x5d, 0x5d, 0x2c, 0x20, 0x63, 0x6f, // [[stage_in]], co
+	0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, // nstant xlatMtlSh
+	0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x26, 0x20, 0x5f, 0x6d, 0x74, // aderUniform& _mt
+	0x6c, 0x5f, 0x75, 0x20, 0x5b, 0x5b, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x28, 0x30, 0x29, 0x5d, // l_u [[buffer(0)]
+	0x5d, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, // ]).{.  xlatMtlSh
+	0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, // aderOutput _mtl_
+	0x6f, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, // o;.  float4 tmpv
+	0x61, 0x72, 0x5f, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, // ar_1;.  tmpvar_1
+	0x2e, 0x7a, 0x77, 0x20, 0x3d, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x28, 0x30, 0x2e, 0x30, // .zw = float2(0.0
+	0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, // , 1.0);.  tmpvar
+	0x5f, 0x31, 0x2e, 0x78, 0x79, 0x20, 0x3d, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x61, // _1.xy = _mtl_i.a
+	0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, // _position;.  _mt
+	0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, // l_o.gl_Position
+	0x3d, 0x20, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, // = (_mtl_u.u_mode
+	0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x20, 0x2a, 0x20, 0x74, 0x6d, 0x70, 0x76, // lViewProj * tmpv
+	0x61, 0x72, 0x5f, 0x31, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, // ar_1);.  _mtl_o.
+	0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x20, 0x3d, 0x20, 0x5f, 0x6d, // v_texcoord0 = _m
+	0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x61, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, // tl_i.a_texcoord0
+	0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x76, 0x5f, 0x63, 0x6f, 0x6c, // ;.  _mtl_o.v_col
+	0x6f, 0x72, 0x30, 0x20, 0x3d, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x61, 0x5f, 0x63, // or0 = _mtl_i.a_c
+	0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, // olor0;.  return
+	0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00,                         // _mtl_o;.}...
+};

+ 51 - 0
examples/common/font/vs_font_distance_field_subpixel.bin.h

@@ -92,3 +92,54 @@ static const uint8_t vs_font_distance_field_subpixel_dx11[580] =
 	0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x00, 0x03, 0x05, 0x00, 0x01, 0x00, // ......>.........
 	0x10, 0x00, 0x40, 0x00,                                                                         // ..@.
 };
+static const uint8_t vs_font_distance_field_subpixel_mtl[764] =
+{
+	0x56, 0x53, 0x48, 0x04, 0x01, 0x83, 0xf2, 0xe1, 0x00, 0x00, 0xed, 0x02, 0x00, 0x00, 0x75, 0x73, // VSH...........us
+	0x69, 0x6e, 0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x6d, 0x65, // ing namespace me
+	0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // tal;.struct xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x7b, // MtlShaderInput {
+	0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x61, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, // .  float4 a_colo
+	0x72, 0x30, 0x20, 0x5b, 0x5b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x30, // r0 [[attribute(0
+	0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x61, 0x5f, // )]];.  float2 a_
+	0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5b, 0x5b, 0x61, 0x74, 0x74, 0x72, 0x69, // position [[attri
+	0x62, 0x75, 0x74, 0x65, 0x28, 0x31, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, // bute(1)]];.  flo
+	0x61, 0x74, 0x34, 0x20, 0x61, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x20, // at4 a_texcoord0
+	0x5b, 0x5b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x32, 0x29, 0x5d, 0x5d, // [[attribute(2)]]
+	0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // ;.};.struct xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, // MtlShaderOutput
+	0x7b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x67, 0x6c, 0x5f, 0x50, 0x6f, // {.  float4 gl_Po
+	0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5b, 0x5b, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, // sition [[positio
+	0x6e, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x76, 0x5f, // n]];.  float4 v_
+	0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, // color0;.  float4
+	0x20, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x3b, 0x0a, 0x7d, 0x3b, //  v_texcoord0;.};
+	0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, // .struct xlatMtlS
+	0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x7b, 0x0a, 0x20, // haderUniform {.
+	0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x78, 0x34, 0x20, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, //  float4x4 u_mode
+	0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x76, 0x65, // lViewProj;.};.ve
+	0x72, 0x74, 0x65, 0x78, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, // rtex xlatMtlShad
+	0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, // erOutput xlatMtl
+	0x4d, 0x61, 0x69, 0x6e, 0x20, 0x28, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, // Main (xlatMtlSha
+	0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x20, // derInput _mtl_i
+	0x5b, 0x5b, 0x73, 0x74, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x6e, 0x5d, 0x5d, 0x2c, 0x20, 0x63, 0x6f, // [[stage_in]], co
+	0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, // nstant xlatMtlSh
+	0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x26, 0x20, 0x5f, 0x6d, 0x74, // aderUniform& _mt
+	0x6c, 0x5f, 0x75, 0x20, 0x5b, 0x5b, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x28, 0x30, 0x29, 0x5d, // l_u [[buffer(0)]
+	0x5d, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, // ]).{.  xlatMtlSh
+	0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, // aderOutput _mtl_
+	0x6f, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, // o;.  float4 tmpv
+	0x61, 0x72, 0x5f, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, // ar_1;.  tmpvar_1
+	0x2e, 0x7a, 0x77, 0x20, 0x3d, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x28, 0x30, 0x2e, 0x30, // .zw = float2(0.0
+	0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, // , 1.0);.  tmpvar
+	0x5f, 0x31, 0x2e, 0x78, 0x79, 0x20, 0x3d, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x61, // _1.xy = _mtl_i.a
+	0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, // _position;.  _mt
+	0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, // l_o.gl_Position
+	0x3d, 0x20, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, // = (_mtl_u.u_mode
+	0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x20, 0x2a, 0x20, 0x74, 0x6d, 0x70, 0x76, // lViewProj * tmpv
+	0x61, 0x72, 0x5f, 0x31, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, // ar_1);.  _mtl_o.
+	0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x20, 0x3d, 0x20, 0x5f, 0x6d, // v_texcoord0 = _m
+	0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x61, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, // tl_i.a_texcoord0
+	0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x76, 0x5f, 0x63, 0x6f, 0x6c, // ;.  _mtl_o.v_col
+	0x6f, 0x72, 0x30, 0x20, 0x3d, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x61, 0x5f, 0x63, // or0 = _mtl_i.a_c
+	0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, // olor0;.  return
+	0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00,                         // _mtl_o;.}...
+};

+ 29 - 0
examples/common/imgui/fs_imgui_color.bin.h

@@ -39,3 +39,32 @@ static const uint8_t fs_imgui_color_dx11[260] =
 	0x00, 0x00, 0x00, 0x00, 0x46, 0x1e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, // ....F.......>...
 	0x00, 0x00, 0x00, 0x00,                                                                         // ....
 };
+static const uint8_t fs_imgui_color_mtl[410] =
+{
+	0x46, 0x53, 0x48, 0x04, 0xa4, 0x8b, 0xef, 0x49, 0x00, 0x00, 0x8b, 0x01, 0x00, 0x00, 0x75, 0x73, // FSH....I......us
+	0x69, 0x6e, 0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x6d, 0x65, // ing namespace me
+	0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // tal;.struct xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x7b, // MtlShaderInput {
+	0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, // .  float4 v_colo
+	0x72, 0x30, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, // r0;.};.struct xl
+	0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, // atMtlShaderOutpu
+	0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x67, 0x6c, 0x5f, 0x46, // t {.  half4 gl_F
+	0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, // ragColor;.};.str
+	0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, // uct xlatMtlShade
+	0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x7b, 0x0a, 0x7d, 0x3b, 0x0a, 0x66, 0x72, // rUniform {.};.fr
+	0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, // agment xlatMtlSh
+	0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, // aderOutput xlatM
+	0x74, 0x6c, 0x4d, 0x61, 0x69, 0x6e, 0x20, 0x28, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, // tlMain (xlatMtlS
+	0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, // haderInput _mtl_
+	0x69, 0x20, 0x5b, 0x5b, 0x73, 0x74, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x6e, 0x5d, 0x5d, 0x2c, 0x20, // i [[stage_in]],
+	0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, // constant xlatMtl
+	0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x26, 0x20, 0x5f, // ShaderUniform& _
+	0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x20, 0x5b, 0x5b, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x28, 0x30, // mtl_u [[buffer(0
+	0x29, 0x5d, 0x5d, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, // )]]).{.  xlatMtl
+	0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, // ShaderOutput _mt
+	0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, // l_o;.  _mtl_o.gl
+	0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, // _FragColor = hal
+	0x66, 0x34, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, // f4(_mtl_i.v_colo
+	0x72, 0x30, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x6d, // r0);.  return _m
+	0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00,                                     // tl_o;.}...
+};

+ 52 - 0
examples/common/imgui/fs_imgui_cubemap.bin.h

@@ -81,3 +81,55 @@ static const uint8_t fs_imgui_cubemap_dx11[424] =
 	0x01, 0x40, 0x00, 0x00, 0xcd, 0xcc, 0x4c, 0x3f, 0x01, 0x40, 0x00, 0x00, 0xcd, 0xcc, 0x4c, 0x3e, // [email protected][email protected]>
 	0x3e, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00,                                                 // >.......
 };
+static const uint8_t fs_imgui_cubemap_mtl[763] =
+{
+	0x46, 0x53, 0x48, 0x04, 0xe3, 0xc2, 0x5c, 0x65, 0x00, 0x00, 0xec, 0x02, 0x00, 0x00, 0x75, 0x73, // FSH....e......us
+	0x69, 0x6e, 0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x6d, 0x65, // ing namespace me
+	0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // tal;.struct xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x7b, // MtlShaderInput {
+	0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x20, 0x76, 0x5f, 0x6e, 0x6f, 0x72, 0x6d, // .  float3 v_norm
+	0x61, 0x6c, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, // al;.};.struct xl
+	0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, // atMtlShaderOutpu
+	0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x67, 0x6c, 0x5f, 0x46, // t {.  half4 gl_F
+	0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, // ragColor;.};.str
+	0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, // uct xlatMtlShade
+	0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, // rUniform {.  flo
+	0x61, 0x74, 0x34, 0x20, 0x75, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x4c, 0x6f, 0x64, 0x45, 0x6e, // at4 u_imageLodEn
+	0x61, 0x62, 0x6c, 0x65, 0x64, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, // abled;.};.fragme
+	0x6e, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, // nt xlatMtlShader
+	0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x4d, 0x61, // Output xlatMtlMa
+	0x69, 0x6e, 0x20, 0x28, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, // in (xlatMtlShade
+	0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x20, 0x5b, 0x5b, // rInput _mtl_i [[
+	0x73, 0x74, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x6e, 0x5d, 0x5d, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x73, // stage_in]], cons
+	0x74, 0x61, 0x6e, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, // tant xlatMtlShad
+	0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x26, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, // erUniform& _mtl_
+	0x75, 0x20, 0x5b, 0x5b, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x0a, // u [[buffer(0)]].
+	0x20, 0x20, 0x2c, 0x20, 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x63, 0x75, 0x62, //   ,   texturecub
+	0x65, 0x3c, 0x68, 0x61, 0x6c, 0x66, 0x3e, 0x20, 0x73, 0x5f, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, // e<half> s_texCol
+	0x6f, 0x72, 0x20, 0x5b, 0x5b, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x28, 0x30, 0x29, 0x5d, // or [[texture(0)]
+	0x5d, 0x2c, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x73, // ], sampler _mtls
+	0x6d, 0x70, 0x5f, 0x73, 0x5f, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x5b, 0x5b, // mp_s_texColor [[
+	0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x29, 0x0a, 0x7b, 0x0a, // sampler(0)]]).{.
+	0x20, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, //   xlatMtlShaderO
+	0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x20, 0x20, // utput _mtl_o;.
+	0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x3b, 0x0a, // float tmpvar_1;.
+	0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x20, 0x3d, 0x20, 0x28, 0x30, 0x2e, //   tmpvar_1 = (0.
+	0x32, 0x20, 0x2b, 0x20, 0x28, 0x30, 0x2e, 0x38, 0x20, 0x2a, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, // 2 + (0.8 * _mtl_
+	0x75, 0x2e, 0x75, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x4c, 0x6f, 0x64, 0x45, 0x6e, 0x61, 0x62, // u.u_imageLodEnab
+	0x6c, 0x65, 0x64, 0x2e, 0x79, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, // led.y));.  half4
+	0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, //  tmpvar_2;.  tmp
+	0x76, 0x61, 0x72, 0x5f, 0x32, 0x2e, 0x78, 0x79, 0x7a, 0x20, 0x3d, 0x20, 0x73, 0x5f, 0x74, 0x65, // var_2.xyz = s_te
+	0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x28, 0x5f, 0x6d, // xColor.sample(_m
+	0x74, 0x6c, 0x73, 0x6d, 0x70, 0x5f, 0x73, 0x5f, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, // tlsmp_s_texColor
+	0x2c, 0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x29, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, // , (float3)(_mtl_
+	0x69, 0x2e, 0x76, 0x5f, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x29, 0x2c, 0x20, 0x6c, 0x65, 0x76, // i.v_normal), lev
+	0x65, 0x6c, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x75, 0x5f, 0x69, 0x6d, 0x61, 0x67, // el(_mtl_u.u_imag
+	0x65, 0x4c, 0x6f, 0x64, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x2e, 0x78, 0x29, 0x29, 0x2e, // eLodEnabled.x)).
+	0x78, 0x79, 0x7a, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x2e, // xyz;.  tmpvar_2.
+	0x77, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x28, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, // w = half(tmpvar_
+	0x31, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, // 1);.  _mtl_o.gl_
+	0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, // FragColor = tmpv
+	0x61, 0x72, 0x5f, 0x32, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, // ar_2;.  return _
+	0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00,                               // mtl_o;.}...
+};
+

+ 51 - 0
examples/common/imgui/fs_imgui_image.bin.h

@@ -81,3 +81,54 @@ static const uint8_t fs_imgui_image_dx11[428] =
 	0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0xcd, 0xcc, 0x4c, 0x3f, 0x01, 0x40, 0x00, 0x00, // [email protected]?.@..
 	0xcd, 0xcc, 0x4c, 0x3e, 0x3e, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00,                         // ..L>>.......
 };
+static const uint8_t fs_imgui_image_mtl[767] =
+{
+	0x46, 0x53, 0x48, 0x04, 0x6f, 0x1e, 0x3e, 0x3c, 0x00, 0x00, 0xf0, 0x02, 0x00, 0x00, 0x75, 0x73, // FSH.o.><......us
+	0x69, 0x6e, 0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x6d, 0x65, // ing namespace me
+	0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // tal;.struct xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x7b, // MtlShaderInput {
+	0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, // .  float2 v_texc
+	0x6f, 0x6f, 0x72, 0x64, 0x30, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, // oord0;.};.struct
+	0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, //  xlatMtlShaderOu
+	0x74, 0x70, 0x75, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x67, // tput {.  half4 g
+	0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, // l_FragColor;.};.
+	0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, // struct xlatMtlSh
+	0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x7b, 0x0a, 0x20, 0x20, // aderUniform {.
+	0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x75, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x4c, 0x6f, // float4 u_imageLo
+	0x64, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x66, 0x72, 0x61, // dEnabled;.};.fra
+	0x67, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, // gment xlatMtlSha
+	0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, // derOutput xlatMt
+	0x6c, 0x4d, 0x61, 0x69, 0x6e, 0x20, 0x28, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, // lMain (xlatMtlSh
+	0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, // aderInput _mtl_i
+	0x20, 0x5b, 0x5b, 0x73, 0x74, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x6e, 0x5d, 0x5d, 0x2c, 0x20, 0x63, //  [[stage_in]], c
+	0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, // onstant xlatMtlS
+	0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x26, 0x20, 0x5f, 0x6d, // haderUniform& _m
+	0x74, 0x6c, 0x5f, 0x75, 0x20, 0x5b, 0x5b, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x28, 0x30, 0x29, // tl_u [[buffer(0)
+	0x5d, 0x5d, 0x0a, 0x20, 0x20, 0x2c, 0x20, 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, // ]].  ,   texture
+	0x32, 0x64, 0x3c, 0x68, 0x61, 0x6c, 0x66, 0x3e, 0x20, 0x73, 0x5f, 0x74, 0x65, 0x78, 0x43, 0x6f, // 2d<half> s_texCo
+	0x6c, 0x6f, 0x72, 0x20, 0x5b, 0x5b, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x28, 0x30, 0x29, // lor [[texture(0)
+	0x5d, 0x5d, 0x2c, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x20, 0x5f, 0x6d, 0x74, 0x6c, // ]], sampler _mtl
+	0x73, 0x6d, 0x70, 0x5f, 0x73, 0x5f, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x5b, // smp_s_texColor [
+	0x5b, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x29, 0x0a, 0x7b, // [sampler(0)]]).{
+	0x0a, 0x20, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, // .  xlatMtlShader
+	0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x20, // Output _mtl_o;.
+	0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x3b, //  float tmpvar_1;
+	0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x20, 0x3d, 0x20, 0x28, 0x30, // .  tmpvar_1 = (0
+	0x2e, 0x32, 0x20, 0x2b, 0x20, 0x28, 0x30, 0x2e, 0x38, 0x20, 0x2a, 0x20, 0x5f, 0x6d, 0x74, 0x6c, // .2 + (0.8 * _mtl
+	0x5f, 0x75, 0x2e, 0x75, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x4c, 0x6f, 0x64, 0x45, 0x6e, 0x61, // _u.u_imageLodEna
+	0x62, 0x6c, 0x65, 0x64, 0x2e, 0x79, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, // bled.y));.  half
+	0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, // 4 tmpvar_2;.  tm
+	0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x2e, 0x78, 0x79, 0x7a, 0x20, 0x3d, 0x20, 0x73, 0x5f, 0x74, // pvar_2.xyz = s_t
+	0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x28, 0x5f, // exColor.sample(_
+	0x6d, 0x74, 0x6c, 0x73, 0x6d, 0x70, 0x5f, 0x73, 0x5f, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, // mtlsmp_s_texColo
+	0x72, 0x2c, 0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x29, 0x28, 0x5f, 0x6d, 0x74, 0x6c, // r, (float2)(_mtl
+	0x5f, 0x69, 0x2e, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x29, 0x2c, // _i.v_texcoord0),
+	0x20, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x75, 0x5f, //  level(_mtl_u.u_
+	0x69, 0x6d, 0x61, 0x67, 0x65, 0x4c, 0x6f, 0x64, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x2e, // imageLodEnabled.
+	0x78, 0x29, 0x29, 0x2e, 0x78, 0x79, 0x7a, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, // x)).xyz;.  tmpva
+	0x72, 0x5f, 0x32, 0x2e, 0x77, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x28, 0x74, 0x6d, 0x70, // r_2.w = half(tmp
+	0x76, 0x61, 0x72, 0x5f, 0x31, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, // var_1);.  _mtl_o
+	0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, // .gl_FragColor =
+	0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, // tmpvar_2;.  retu
+	0x72, 0x6e, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00,       // rn _mtl_o;.}...
+};

+ 56 - 0
examples/common/imgui/fs_imgui_image_swizz.bin.h

@@ -92,3 +92,59 @@ static const uint8_t fs_imgui_image_swizz_dx11[476] =
 	0x36, 0x00, 0x00, 0x05, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x04, 0x10, 0x00, // 6.... ..........
 	0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x00, 0x00, 0x20, 0x00,                         // ....>..... .
 };
+static const uint8_t fs_imgui_image_swizz_mtl[830] =
+{
+	0x46, 0x53, 0x48, 0x04, 0x6f, 0x1e, 0x3e, 0x3c, 0x00, 0x00, 0x2f, 0x03, 0x00, 0x00, 0x75, 0x73, // FSH.o.><../...us
+	0x69, 0x6e, 0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x6d, 0x65, // ing namespace me
+	0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // tal;.struct xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x7b, // MtlShaderInput {
+	0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, // .  float2 v_texc
+	0x6f, 0x6f, 0x72, 0x64, 0x30, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, // oord0;.};.struct
+	0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, //  xlatMtlShaderOu
+	0x74, 0x70, 0x75, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x67, // tput {.  half4 g
+	0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, // l_FragColor;.};.
+	0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, // struct xlatMtlSh
+	0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x7b, 0x0a, 0x20, 0x20, // aderUniform {.
+	0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x75, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x4c, 0x6f, // float4 u_imageLo
+	0x64, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, // dEnabled;.  floa
+	0x74, 0x34, 0x20, 0x75, 0x5f, 0x73, 0x77, 0x69, 0x7a, 0x7a, 0x6c, 0x65, 0x3b, 0x0a, 0x7d, 0x3b, // t4 u_swizzle;.};
+	0x0a, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, // .fragment xlatMt
+	0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x78, 0x6c, // lShaderOutput xl
+	0x61, 0x74, 0x4d, 0x74, 0x6c, 0x4d, 0x61, 0x69, 0x6e, 0x20, 0x28, 0x78, 0x6c, 0x61, 0x74, 0x4d, // atMtlMain (xlatM
+	0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, // tlShaderInput _m
+	0x74, 0x6c, 0x5f, 0x69, 0x20, 0x5b, 0x5b, 0x73, 0x74, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x6e, 0x5d, // tl_i [[stage_in]
+	0x5d, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // ], constant xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, // MtlShaderUniform
+	0x26, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x20, 0x5b, 0x5b, 0x62, 0x75, 0x66, 0x66, 0x65, // & _mtl_u [[buffe
+	0x72, 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x0a, 0x20, 0x20, 0x2c, 0x20, 0x20, 0x20, 0x74, 0x65, 0x78, // r(0)]].  ,   tex
+	0x74, 0x75, 0x72, 0x65, 0x32, 0x64, 0x3c, 0x68, 0x61, 0x6c, 0x66, 0x3e, 0x20, 0x73, 0x5f, 0x74, // ture2d<half> s_t
+	0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x5b, 0x5b, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, // exColor [[textur
+	0x65, 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x2c, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x20, // e(0)]], sampler
+	0x5f, 0x6d, 0x74, 0x6c, 0x73, 0x6d, 0x70, 0x5f, 0x73, 0x5f, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, // _mtlsmp_s_texCol
+	0x6f, 0x72, 0x20, 0x5b, 0x5b, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x28, 0x30, 0x29, 0x5d, // or [[sampler(0)]
+	0x5d, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, // ]).{.  xlatMtlSh
+	0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, // aderOutput _mtl_
+	0x6f, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, // o;.  float tmpva
+	0x72, 0x5f, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x20, // r_1;.  tmpvar_1
+	0x3d, 0x20, 0x28, 0x30, 0x2e, 0x32, 0x20, 0x2b, 0x20, 0x28, 0x30, 0x2e, 0x38, 0x20, 0x2a, 0x20, // = (0.2 + (0.8 *
+	0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x75, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x4c, 0x6f, // _mtl_u.u_imageLo
+	0x64, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x2e, 0x79, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, // dEnabled.y));.
+	0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x3b, 0x0a, // half4 tmpvar_2;.
+	0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x2e, 0x78, 0x79, 0x7a, 0x20, 0x3d, //   tmpvar_2.xyz =
+	0x20, 0x68, 0x61, 0x6c, 0x66, 0x33, 0x28, 0x28, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x64, 0x6f, //  half3(((half)do
+	0x74, 0x20, 0x28, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x29, 0x73, 0x5f, 0x74, 0x65, 0x78, // t ((float4)s_tex
+	0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x28, 0x5f, 0x6d, 0x74, // Color.sample(_mt
+	0x6c, 0x73, 0x6d, 0x70, 0x5f, 0x73, 0x5f, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2c, // lsmp_s_texColor,
+	0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x29, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, //  (float2)(_mtl_i
+	0x2e, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x29, 0x2c, 0x20, 0x6c, // .v_texcoord0), l
+	0x65, 0x76, 0x65, 0x6c, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x75, 0x5f, 0x69, 0x6d, // evel(_mtl_u.u_im
+	0x61, 0x67, 0x65, 0x4c, 0x6f, 0x64, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x2e, 0x78, 0x29, // ageLodEnabled.x)
+	0x29, 0x2c, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x75, 0x5f, 0x73, 0x77, 0x69, 0x7a, // ), _mtl_u.u_swiz
+	0x7a, 0x6c, 0x65, 0x29, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, // zle)));.  tmpvar
+	0x5f, 0x32, 0x2e, 0x77, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x28, 0x74, 0x6d, 0x70, 0x76, // _2.w = half(tmpv
+	0x61, 0x72, 0x5f, 0x31, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, // ar_1);.  _mtl_o.
+	0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x74, // gl_FragColor = t
+	0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, // mpvar_2;.  retur
+	0x6e, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00,             // n _mtl_o;.}...
+};
+

+ 69 - 0
examples/common/imgui/fs_imgui_latlong.bin.h

@@ -120,3 +120,72 @@ static const uint8_t fs_imgui_latlong_dx11[600] =
 	0x01, 0x40, 0x00, 0x00, 0xcd, 0xcc, 0x4c, 0x3f, 0x01, 0x40, 0x00, 0x00, 0xcd, 0xcc, 0x4c, 0x3e, // [email protected][email protected]>
 	0x3e, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00,                                                 // >.......
 };
+static const uint8_t fs_imgui_latlong_mtl[1042] =
+{
+	0x46, 0x53, 0x48, 0x04, 0x6f, 0x1e, 0x3e, 0x3c, 0x00, 0x00, 0x03, 0x04, 0x00, 0x00, 0x75, 0x73, // FSH.o.><......us
+	0x69, 0x6e, 0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x6d, 0x65, // ing namespace me
+	0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // tal;.struct xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x7b, // MtlShaderInput {
+	0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, // .  float2 v_texc
+	0x6f, 0x6f, 0x72, 0x64, 0x30, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, // oord0;.};.struct
+	0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, //  xlatMtlShaderOu
+	0x74, 0x70, 0x75, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x67, // tput {.  half4 g
+	0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, // l_FragColor;.};.
+	0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, // struct xlatMtlSh
+	0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x7b, 0x0a, 0x20, 0x20, // aderUniform {.
+	0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x75, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x4c, 0x6f, // float4 u_imageLo
+	0x64, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x66, 0x72, 0x61, // dEnabled;.};.fra
+	0x67, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, // gment xlatMtlSha
+	0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, // derOutput xlatMt
+	0x6c, 0x4d, 0x61, 0x69, 0x6e, 0x20, 0x28, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, // lMain (xlatMtlSh
+	0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, // aderInput _mtl_i
+	0x20, 0x5b, 0x5b, 0x73, 0x74, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x6e, 0x5d, 0x5d, 0x2c, 0x20, 0x63, //  [[stage_in]], c
+	0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, // onstant xlatMtlS
+	0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x26, 0x20, 0x5f, 0x6d, // haderUniform& _m
+	0x74, 0x6c, 0x5f, 0x75, 0x20, 0x5b, 0x5b, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x28, 0x30, 0x29, // tl_u [[buffer(0)
+	0x5d, 0x5d, 0x0a, 0x20, 0x20, 0x2c, 0x20, 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, // ]].  ,   texture
+	0x63, 0x75, 0x62, 0x65, 0x3c, 0x68, 0x61, 0x6c, 0x66, 0x3e, 0x20, 0x73, 0x5f, 0x74, 0x65, 0x78, // cube<half> s_tex
+	0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x5b, 0x5b, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x28, // Color [[texture(
+	0x30, 0x29, 0x5d, 0x5d, 0x2c, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x20, 0x5f, 0x6d, // 0)]], sampler _m
+	0x74, 0x6c, 0x73, 0x6d, 0x70, 0x5f, 0x73, 0x5f, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, // tlsmp_s_texColor
+	0x20, 0x5b, 0x5b, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x29, //  [[sampler(0)]])
+	0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, // .{.  xlatMtlShad
+	0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, // erOutput _mtl_o;
+	0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, // .  float3 result
+	0x5f, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x74, 0x6d, 0x70, 0x76, // _1;.  float tmpv
+	0x61, 0x72, 0x5f, 0x32, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, // ar_2;.  tmpvar_2
+	0x20, 0x3d, 0x20, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x76, 0x5f, 0x74, 0x65, 0x78, //  = (_mtl_i.v_tex
+	0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x2e, 0x78, 0x20, 0x2a, 0x20, 0x36, 0x2e, 0x32, 0x38, 0x33, // coord0.x * 6.283
+	0x31, 0x38, 0x35, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x74, 0x6d, // 185);.  float tm
+	0x70, 0x76, 0x61, 0x72, 0x5f, 0x33, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, // pvar_3;.  tmpvar
+	0x5f, 0x33, 0x20, 0x3d, 0x20, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x76, 0x5f, 0x74, // _3 = (_mtl_i.v_t
+	0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x2e, 0x79, 0x20, 0x2a, 0x20, 0x33, 0x2e, 0x31, // excoord0.y * 3.1
+	0x34, 0x31, 0x35, 0x39, 0x33, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, // 41593);.  result
+	0x5f, 0x31, 0x2e, 0x78, 0x20, 0x3d, 0x20, 0x28, 0x2d, 0x28, 0x73, 0x69, 0x6e, 0x28, 0x74, 0x6d, // _1.x = (-(sin(tm
+	0x70, 0x76, 0x61, 0x72, 0x5f, 0x33, 0x29, 0x29, 0x20, 0x2a, 0x20, 0x73, 0x69, 0x6e, 0x28, 0x74, // pvar_3)) * sin(t
+	0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x73, // mpvar_2));.  res
+	0x75, 0x6c, 0x74, 0x5f, 0x31, 0x2e, 0x79, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x73, 0x28, 0x74, 0x6d, // ult_1.y = cos(tm
+	0x70, 0x76, 0x61, 0x72, 0x5f, 0x33, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, // pvar_3);.  resul
+	0x74, 0x5f, 0x31, 0x2e, 0x7a, 0x20, 0x3d, 0x20, 0x28, 0x2d, 0x28, 0x73, 0x69, 0x6e, 0x28, 0x74, // t_1.z = (-(sin(t
+	0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x33, 0x29, 0x29, 0x20, 0x2a, 0x20, 0x63, 0x6f, 0x73, 0x28, // mpvar_3)) * cos(
+	0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, // tmpvar_2));.  fl
+	0x6f, 0x61, 0x74, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x34, 0x3b, 0x0a, 0x20, 0x20, // oat tmpvar_4;.
+	0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x34, 0x20, 0x3d, 0x20, 0x28, 0x30, 0x2e, 0x32, 0x20, // tmpvar_4 = (0.2
+	0x2b, 0x20, 0x28, 0x30, 0x2e, 0x38, 0x20, 0x2a, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, // + (0.8 * _mtl_u.
+	0x75, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x4c, 0x6f, 0x64, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, // u_imageLodEnable
+	0x64, 0x2e, 0x79, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x74, // d.y));.  half4 t
+	0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x35, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, // mpvar_5;.  tmpva
+	0x72, 0x5f, 0x35, 0x2e, 0x78, 0x79, 0x7a, 0x20, 0x3d, 0x20, 0x73, 0x5f, 0x74, 0x65, 0x78, 0x43, // r_5.xyz = s_texC
+	0x6f, 0x6c, 0x6f, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x28, 0x5f, 0x6d, 0x74, 0x6c, // olor.sample(_mtl
+	0x73, 0x6d, 0x70, 0x5f, 0x73, 0x5f, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2c, 0x20, // smp_s_texColor,
+	0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x29, 0x28, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x5f, // (float3)(result_
+	0x31, 0x29, 0x2c, 0x20, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, // 1), level(_mtl_u
+	0x2e, 0x75, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x4c, 0x6f, 0x64, 0x45, 0x6e, 0x61, 0x62, 0x6c, // .u_imageLodEnabl
+	0x65, 0x64, 0x2e, 0x78, 0x29, 0x29, 0x2e, 0x78, 0x79, 0x7a, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, // ed.x)).xyz;.  tm
+	0x70, 0x76, 0x61, 0x72, 0x5f, 0x35, 0x2e, 0x77, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x28, // pvar_5.w = half(
+	0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x34, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, // tmpvar_4);.  _mt
+	0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, // l_o.gl_FragColor
+	0x20, 0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x35, 0x3b, 0x0a, 0x20, 0x20, 0x72, //  = tmpvar_5;.  r
+	0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x7d, 0x0a, // eturn _mtl_o;.}.
+	0x0a, 0x00,                                                                                     // ..
+};

+ 47 - 0
examples/common/imgui/fs_imgui_texture.bin.h

@@ -68,3 +68,50 @@ static const uint8_t fs_imgui_texture_dx11[404] =
 	0x00, 0x00, 0x00, 0x00, 0x46, 0x12, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, // ....F.......>...
 	0x00, 0x00, 0x00, 0x00,                                                                         // ....
 };
+static const uint8_t fs_imgui_texture_mtl[695] =
+{
+	0x46, 0x53, 0x48, 0x04, 0x01, 0x83, 0xf2, 0xe1, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x00, 0x75, 0x73, // FSH...........us
+	0x69, 0x6e, 0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x6d, 0x65, // ing namespace me
+	0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // tal;.struct xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x7b, // MtlShaderInput {
+	0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, // .  float4 v_colo
+	0x72, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x76, 0x5f, 0x74, // r0;.  float2 v_t
+	0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, // excoord0;.};.str
+	0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, // uct xlatMtlShade
+	0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, // rOutput {.  half
+	0x34, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x0a, // 4 gl_FragColor;.
+	0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, // };.struct xlatMt
+	0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x7b, // lShaderUniform {
+	0x0a, 0x7d, 0x3b, 0x0a, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x78, 0x6c, 0x61, // .};.fragment xla
+	0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, // tMtlShaderOutput
+	0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x4d, 0x61, 0x69, 0x6e, 0x20, 0x28, 0x78, 0x6c, //  xlatMtlMain (xl
+	0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, // atMtlShaderInput
+	0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x20, 0x5b, 0x5b, 0x73, 0x74, 0x61, 0x67, 0x65, 0x5f, //  _mtl_i [[stage_
+	0x69, 0x6e, 0x5d, 0x5d, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x20, 0x78, // in]], constant x
+	0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, // latMtlShaderUnif
+	0x6f, 0x72, 0x6d, 0x26, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x20, 0x5b, 0x5b, 0x62, 0x75, // orm& _mtl_u [[bu
+	0x66, 0x66, 0x65, 0x72, 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x0a, 0x20, 0x20, 0x2c, 0x20, 0x20, 0x20, // ffer(0)]].  ,
+	0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x64, 0x3c, 0x68, 0x61, 0x6c, 0x66, 0x3e, 0x20, // texture2d<half>
+	0x73, 0x5f, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x5b, 0x5b, 0x74, 0x65, 0x78, // s_texColor [[tex
+	0x74, 0x75, 0x72, 0x65, 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x2c, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, // ture(0)]], sampl
+	0x65, 0x72, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x73, 0x6d, 0x70, 0x5f, 0x73, 0x5f, 0x74, 0x65, 0x78, // er _mtlsmp_s_tex
+	0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x5b, 0x5b, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x28, // Color [[sampler(
+	0x30, 0x29, 0x5d, 0x5d, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, // 0)]]).{.  xlatMt
+	0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, // lShaderOutput _m
+	0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x74, 0x6d, // tl_o;.  half4 tm
+	0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, // pvar_1;.  tmpvar
+	0x5f, 0x31, 0x2e, 0x78, 0x79, 0x7a, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x33, 0x28, 0x5f, // _1.xyz = half3(_
+	0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x2e, 0x78, // mtl_i.v_color0.x
+	0x79, 0x7a, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x2e, // yz);.  tmpvar_1.
+	0x77, 0x20, 0x3d, 0x20, 0x28, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x28, 0x5f, 0x6d, 0x74, 0x6c, // w = ((half)(_mtl
+	0x5f, 0x69, 0x2e, 0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x2e, 0x77, 0x20, 0x2a, 0x20, // _i.v_color0.w *
+	0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x29, 0x73, 0x5f, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, // (float)s_texColo
+	0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x73, 0x6d, 0x70, // r.sample(_mtlsmp
+	0x5f, 0x73, 0x5f, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2c, 0x20, 0x28, 0x66, 0x6c, // _s_texColor, (fl
+	0x6f, 0x61, 0x74, 0x32, 0x29, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x76, 0x5f, 0x74, // oat2)(_mtl_i.v_t
+	0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x29, 0x29, 0x2e, 0x78, 0x29, 0x29, 0x3b, 0x0a, // excoord0)).x));.
+	0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, //   _mtl_o.gl_Frag
+	0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, // Color = tmpvar_1
+	0x3b, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, // ;.  return _mtl_
+	0x6f, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00,                                                       // o;.}...
+};

+ 43 - 0
examples/common/imgui/fs_ocornut_imgui.bin.h

@@ -61,3 +61,46 @@ static const uint8_t fs_ocornut_imgui_dx11[384] =
 	0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, // . ......F.......
 	0x46, 0x1e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, // F.......>.......
 };
+static const uint8_t fs_ocornut_imgui_mtl[626] =
+{
+	0x46, 0x53, 0x48, 0x04, 0x01, 0x83, 0xf2, 0xe1, 0x00, 0x00, 0x63, 0x02, 0x00, 0x00, 0x75, 0x73, // FSH.......c...us
+	0x69, 0x6e, 0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x6d, 0x65, // ing namespace me
+	0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // tal;.struct xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x7b, // MtlShaderInput {
+	0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, // .  float4 v_colo
+	0x72, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x76, 0x5f, 0x74, // r0;.  float2 v_t
+	0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, // excoord0;.};.str
+	0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, // uct xlatMtlShade
+	0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, // rOutput {.  half
+	0x34, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x0a, // 4 gl_FragColor;.
+	0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, // };.struct xlatMt
+	0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x7b, // lShaderUniform {
+	0x0a, 0x7d, 0x3b, 0x0a, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x78, 0x6c, 0x61, // .};.fragment xla
+	0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, // tMtlShaderOutput
+	0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x4d, 0x61, 0x69, 0x6e, 0x20, 0x28, 0x78, 0x6c, //  xlatMtlMain (xl
+	0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, // atMtlShaderInput
+	0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x20, 0x5b, 0x5b, 0x73, 0x74, 0x61, 0x67, 0x65, 0x5f, //  _mtl_i [[stage_
+	0x69, 0x6e, 0x5d, 0x5d, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x20, 0x78, // in]], constant x
+	0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, // latMtlShaderUnif
+	0x6f, 0x72, 0x6d, 0x26, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x20, 0x5b, 0x5b, 0x62, 0x75, // orm& _mtl_u [[bu
+	0x66, 0x66, 0x65, 0x72, 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x0a, 0x20, 0x20, 0x2c, 0x20, 0x20, 0x20, // ffer(0)]].  ,
+	0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x64, 0x3c, 0x68, 0x61, 0x6c, 0x66, 0x3e, 0x20, // texture2d<half>
+	0x73, 0x5f, 0x74, 0x65, 0x78, 0x20, 0x5b, 0x5b, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x28, // s_tex [[texture(
+	0x30, 0x29, 0x5d, 0x5d, 0x2c, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x20, 0x5f, 0x6d, // 0)]], sampler _m
+	0x74, 0x6c, 0x73, 0x6d, 0x70, 0x5f, 0x73, 0x5f, 0x74, 0x65, 0x78, 0x20, 0x5b, 0x5b, 0x73, 0x61, // tlsmp_s_tex [[sa
+	0x6d, 0x70, 0x6c, 0x65, 0x72, 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, // mpler(0)]]).{.
+	0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, // xlatMtlShaderOut
+	0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x20, 0x20, 0x68, 0x61, // put _mtl_o;.  ha
+	0x6c, 0x66, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x3b, 0x0a, 0x20, 0x20, // lf4 tmpvar_1;.
+	0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x20, 0x3d, 0x20, 0x73, 0x5f, 0x74, 0x65, 0x78, // tmpvar_1 = s_tex
+	0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x73, 0x6d, 0x70, 0x5f, // .sample(_mtlsmp_
+	0x73, 0x5f, 0x74, 0x65, 0x78, 0x2c, 0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x29, 0x28, // s_tex, (float2)(
+	0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, // _mtl_i.v_texcoor
+	0x64, 0x30, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, // d0));.  _mtl_o.g
+	0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x28, 0x28, // l_FragColor = ((
+	0x68, 0x61, 0x6c, 0x66, 0x34, 0x29, 0x28, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x29, 0x74, // half4)((float4)t
+	0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x20, 0x2a, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, // mpvar_1 * _mtl_i
+	0x2e, 0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x72, // .v_color0));.  r
+	0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x7d, 0x0a, // eturn _mtl_o;.}.
+	0x0a, 0x00,                                                                                     // ..
+};

+ 14 - 0
examples/common/imgui/imgui.cpp

@@ -532,6 +532,20 @@ struct Imgui
 			fs_imgui_image       = bgfx::makeRef(fs_imgui_image_dx11, sizeof(fs_imgui_image_dx11) );
 			fs_imgui_image_swizz = bgfx::makeRef(fs_imgui_image_swizz_dx11, sizeof(fs_imgui_image_swizz_dx11) );
 			break;
+				
+		case bgfx::RendererType::Metal:
+			vs_imgui_color       = bgfx::makeRef(vs_imgui_color_mtl, sizeof(vs_imgui_color_mtl) );
+			fs_imgui_color       = bgfx::makeRef(fs_imgui_color_mtl, sizeof(fs_imgui_color_mtl) );
+			vs_imgui_texture     = bgfx::makeRef(vs_imgui_texture_mtl, sizeof(vs_imgui_texture_mtl) );
+			fs_imgui_texture     = bgfx::makeRef(fs_imgui_texture_mtl, sizeof(fs_imgui_texture_mtl) );
+			vs_imgui_cubemap     = bgfx::makeRef(vs_imgui_cubemap_mtl, sizeof(vs_imgui_cubemap_mtl) );
+			fs_imgui_cubemap     = bgfx::makeRef(fs_imgui_cubemap_mtl, sizeof(fs_imgui_cubemap_mtl) );
+			vs_imgui_latlong     = bgfx::makeRef(vs_imgui_latlong_mtl, sizeof(vs_imgui_latlong_mtl) );
+			fs_imgui_latlong     = bgfx::makeRef(fs_imgui_latlong_mtl, sizeof(fs_imgui_latlong_mtl) );
+			vs_imgui_image       = bgfx::makeRef(vs_imgui_image_mtl, sizeof(vs_imgui_image_mtl) );
+			fs_imgui_image       = bgfx::makeRef(fs_imgui_image_mtl, sizeof(fs_imgui_image_mtl) );
+			fs_imgui_image_swizz = bgfx::makeRef(fs_imgui_image_swizz_mtl, sizeof(fs_imgui_image_swizz_mtl) );
+			break;
 
 		default:
 			vs_imgui_color       = bgfx::makeRef(vs_imgui_color_glsl, sizeof(vs_imgui_color_glsl) );

+ 5 - 0
examples/common/imgui/ocornut_imgui.cpp

@@ -159,6 +159,11 @@ struct OcornutImguiContext
 			fsmem = bgfx::makeRef(fs_ocornut_imgui_dx11, sizeof(fs_ocornut_imgui_dx11) );
 			break;
 
+		case bgfx::RendererType::Metal:
+			vsmem = bgfx::makeRef(vs_ocornut_imgui_mtl, sizeof(vs_ocornut_imgui_mtl) );
+			fsmem = bgfx::makeRef(fs_ocornut_imgui_mtl, sizeof(fs_ocornut_imgui_mtl) );
+			break;
+				
 		default:
 			vsmem = bgfx::makeRef(vs_ocornut_imgui_glsl, sizeof(vs_ocornut_imgui_glsl) );
 			fsmem = bgfx::makeRef(fs_ocornut_imgui_glsl, sizeof(fs_ocornut_imgui_glsl) );

+ 44 - 0
examples/common/imgui/vs_imgui_color.bin.h

@@ -77,3 +77,47 @@ static const uint8_t vs_imgui_color_dx11[465] =
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x00, 0x02, 0x05, 0x00, 0x01, 0x00, 0x40, // .....>.........@
 	0x00,                                                                                           // .
 };
+static const uint8_t vs_imgui_color_mtl[653] =
+{
+	0x56, 0x53, 0x48, 0x04, 0xa4, 0x8b, 0xef, 0x49, 0x00, 0x00, 0x7e, 0x02, 0x00, 0x00, 0x75, 0x73, // VSH....I..~...us
+	0x69, 0x6e, 0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x6d, 0x65, // ing namespace me
+	0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // tal;.struct xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x7b, // MtlShaderInput {
+	0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x61, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, // .  float4 a_colo
+	0x72, 0x30, 0x20, 0x5b, 0x5b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x30, // r0 [[attribute(0
+	0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x20, 0x61, 0x5f, // )]];.  float3 a_
+	0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5b, 0x5b, 0x61, 0x74, 0x74, 0x72, 0x69, // position [[attri
+	0x62, 0x75, 0x74, 0x65, 0x28, 0x31, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, // bute(1)]];.};.st
+	0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, // ruct xlatMtlShad
+	0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, // erOutput {.  flo
+	0x61, 0x74, 0x34, 0x20, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, // at4 gl_Position
+	0x5b, 0x5b, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, // [[position]];.
+	0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x3b, // float4 v_color0;
+	0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, // .};.struct xlatM
+	0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, // tlShaderUniform
+	0x7b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x78, 0x34, 0x20, 0x75, 0x5f, 0x76, // {.  float4x4 u_v
+	0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x76, 0x65, 0x72, 0x74, // iewProj;.};.vert
+	0x65, 0x78, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, // ex xlatMtlShader
+	0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x4d, 0x61, // Output xlatMtlMa
+	0x69, 0x6e, 0x20, 0x28, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, // in (xlatMtlShade
+	0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x20, 0x5b, 0x5b, // rInput _mtl_i [[
+	0x73, 0x74, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x6e, 0x5d, 0x5d, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x73, // stage_in]], cons
+	0x74, 0x61, 0x6e, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, // tant xlatMtlShad
+	0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x26, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, // erUniform& _mtl_
+	0x75, 0x20, 0x5b, 0x5b, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x29, // u [[buffer(0)]])
+	0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, // .{.  xlatMtlShad
+	0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, // erOutput _mtl_o;
+	0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, // .  float4 tmpvar
+	0x5f, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x2e, 0x7a, // _1;.  tmpvar_1.z
+	0x77, 0x20, 0x3d, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x28, 0x30, 0x2e, 0x30, 0x2c, 0x20, // w = float2(0.0,
+	0x31, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, // 1.0);.  tmpvar_1
+	0x2e, 0x78, 0x79, 0x20, 0x3d, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x61, 0x5f, 0x70, // .xy = _mtl_i.a_p
+	0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x78, 0x79, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, // osition.xy;.  _m
+	0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, // tl_o.gl_Position
+	0x20, 0x3d, 0x20, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x75, 0x5f, 0x76, 0x69, 0x65, //  = (_mtl_u.u_vie
+	0x77, 0x50, 0x72, 0x6f, 0x6a, 0x20, 0x2a, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, // wProj * tmpvar_1
+	0x29, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x76, 0x5f, 0x63, 0x6f, // );.  _mtl_o.v_co
+	0x6c, 0x6f, 0x72, 0x30, 0x20, 0x3d, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x61, 0x5f, // lor0 = _mtl_i.a_
+	0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, // color0;.  return
+	0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00,                   //  _mtl_o;.}...
+};

+ 44 - 0
examples/common/imgui/vs_imgui_cubemap.bin.h

@@ -80,3 +80,47 @@ static const uint8_t vs_imgui_cubemap_dx11[510] =
 	0x00, 0x05, 0x72, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x12, 0x10, 0x00, 0x00, 0x00, // ..r ......F.....
 	0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, 0x00, 0x01, 0x00, 0x40, 0x00,             // ..>.........@.
 };
+static const uint8_t vs_imgui_cubemap_mtl[651] =
+{
+	0x56, 0x53, 0x48, 0x04, 0xe3, 0xc2, 0x5c, 0x65, 0x00, 0x00, 0x7c, 0x02, 0x00, 0x00, 0x75, 0x73, // VSH....e..|...us
+	0x69, 0x6e, 0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x6d, 0x65, // ing namespace me
+	0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // tal;.struct xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x7b, // MtlShaderInput {
+	0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x61, 0x5f, 0x6e, 0x6f, 0x72, 0x6d, // .  float4 a_norm
+	0x61, 0x6c, 0x20, 0x5b, 0x5b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x30, // al [[attribute(0
+	0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x20, 0x61, 0x5f, // )]];.  float3 a_
+	0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5b, 0x5b, 0x61, 0x74, 0x74, 0x72, 0x69, // position [[attri
+	0x62, 0x75, 0x74, 0x65, 0x28, 0x31, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, // bute(1)]];.};.st
+	0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, // ruct xlatMtlShad
+	0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, // erOutput {.  flo
+	0x61, 0x74, 0x34, 0x20, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, // at4 gl_Position
+	0x5b, 0x5b, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, // [[position]];.
+	0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x20, 0x76, 0x5f, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x3b, // float3 v_normal;
+	0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, // .};.struct xlatM
+	0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, // tlShaderUniform
+	0x7b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x78, 0x34, 0x20, 0x75, 0x5f, 0x6d, // {.  float4x4 u_m
+	0x6f, 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x3b, 0x0a, 0x7d, 0x3b, // odelViewProj;.};
+	0x0a, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, // .vertex xlatMtlS
+	0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // haderOutput xlat
+	0x4d, 0x74, 0x6c, 0x4d, 0x61, 0x69, 0x6e, 0x20, 0x28, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, // MtlMain (xlatMtl
+	0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, // ShaderInput _mtl
+	0x5f, 0x69, 0x20, 0x5b, 0x5b, 0x73, 0x74, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x6e, 0x5d, 0x5d, 0x2c, // _i [[stage_in]],
+	0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, //  constant xlatMt
+	0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x26, 0x20, // lShaderUniform&
+	0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x20, 0x5b, 0x5b, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x28, // _mtl_u [[buffer(
+	0x30, 0x29, 0x5d, 0x5d, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, // 0)]]).{.  xlatMt
+	0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, // lShaderOutput _m
+	0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x74, // tl_o;.  float4 t
+	0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, // mpvar_1;.  tmpva
+	0x72, 0x5f, 0x31, 0x2e, 0x77, 0x20, 0x3d, 0x20, 0x31, 0x2e, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x74, // r_1.w = 1.0;.  t
+	0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x2e, 0x78, 0x79, 0x7a, 0x20, 0x3d, 0x20, 0x5f, 0x6d, // mpvar_1.xyz = _m
+	0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x61, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3b, // tl_i.a_position;
+	0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, // .  _mtl_o.gl_Pos
+	0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, // ition = (_mtl_u.
+	0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x20, // u_modelViewProj
+	0x2a, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x5f, // * tmpvar_1);.  _
+	0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x76, 0x5f, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x20, 0x3d, // mtl_o.v_normal =
+	0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x61, 0x5f, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, //  _mtl_i.a_normal
+	0x2e, 0x78, 0x79, 0x7a, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, // .xyz;.  return _
+	0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00,                               // mtl_o;.}...
+};

+ 45 - 0
examples/common/imgui/vs_imgui_image.bin.h

@@ -77,3 +77,48 @@ static const uint8_t vs_imgui_image_dx11[473] =
 	0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, // .....F.......>..
 	0x01, 0x00, 0x02, 0x01, 0x00, 0x10, 0x00, 0x40, 0x00,                                           // .......@.
 };
+static const uint8_t vs_imgui_image_mtl[665] =
+{
+	0x56, 0x53, 0x48, 0x04, 0x6f, 0x1e, 0x3e, 0x3c, 0x00, 0x00, 0x8a, 0x02, 0x00, 0x00, 0x75, 0x73, // VSH.o.><......us
+	0x69, 0x6e, 0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x6d, 0x65, // ing namespace me
+	0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // tal;.struct xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x7b, // MtlShaderInput {
+	0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x20, 0x61, 0x5f, 0x70, 0x6f, 0x73, 0x69, // .  float3 a_posi
+	0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5b, 0x5b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, // tion [[attribute
+	0x28, 0x30, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, // (0)]];.  float2
+	0x61, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x20, 0x5b, 0x5b, 0x61, 0x74, // a_texcoord0 [[at
+	0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x31, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x7d, 0x3b, // tribute(1)]];.};
+	0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, // .struct xlatMtlS
+	0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, // haderOutput {.
+	0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, // float4 gl_Positi
+	0x6f, 0x6e, 0x20, 0x5b, 0x5b, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5d, 0x5d, 0x3b, // on [[position]];
+	0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, // .  float2 v_texc
+	0x6f, 0x6f, 0x72, 0x64, 0x30, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, // oord0;.};.struct
+	0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, //  xlatMtlShaderUn
+	0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, // iform {.  float4
+	0x78, 0x34, 0x20, 0x75, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x3b, 0x0a, 0x7d, // x4 u_viewProj;.}
+	0x3b, 0x0a, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, // ;.vertex xlatMtl
+	0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x78, 0x6c, 0x61, // ShaderOutput xla
+	0x74, 0x4d, 0x74, 0x6c, 0x4d, 0x61, 0x69, 0x6e, 0x20, 0x28, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, // tMtlMain (xlatMt
+	0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, // lShaderInput _mt
+	0x6c, 0x5f, 0x69, 0x20, 0x5b, 0x5b, 0x73, 0x74, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x6e, 0x5d, 0x5d, // l_i [[stage_in]]
+	0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, // , constant xlatM
+	0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x26, // tlShaderUniform&
+	0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x20, 0x5b, 0x5b, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, //  _mtl_u [[buffer
+	0x28, 0x30, 0x29, 0x5d, 0x5d, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, // (0)]]).{.  xlatM
+	0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x5f, // tlShaderOutput _
+	0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, // mtl_o;.  float4
+	0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, // tmpvar_1;.  tmpv
+	0x61, 0x72, 0x5f, 0x31, 0x2e, 0x7a, 0x77, 0x20, 0x3d, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, // ar_1.zw = float2
+	0x28, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, // (0.0, 1.0);.  tm
+	0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x2e, 0x78, 0x79, 0x20, 0x3d, 0x20, 0x5f, 0x6d, 0x74, 0x6c, // pvar_1.xy = _mtl
+	0x5f, 0x69, 0x2e, 0x61, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x78, 0x79, // _i.a_position.xy
+	0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x50, 0x6f, // ;.  _mtl_o.gl_Po
+	0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, // sition = (_mtl_u
+	0x2e, 0x75, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x20, 0x2a, 0x20, 0x74, 0x6d, // .u_viewProj * tm
+	0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, // pvar_1);.  _mtl_
+	0x6f, 0x2e, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x20, 0x3d, 0x20, // o.v_texcoord0 =
+	0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x61, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, // _mtl_i.a_texcoor
+	0x64, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x6d, 0x74, // d0;.  return _mt
+	0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00,                                           // l_o;.}...
+};

+ 45 - 0
examples/common/imgui/vs_imgui_latlong.bin.h

@@ -82,3 +82,48 @@ static const uint8_t vs_imgui_latlong_dx11[518] =
 	0x00, 0x00, 0x46, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x00, 0x02, // ..F.......>.....
 	0x01, 0x00, 0x10, 0x00, 0x40, 0x00,                                                             // ....@.
 };
+static const uint8_t vs_imgui_latlong_mtl[659] =
+{
+	0x56, 0x53, 0x48, 0x04, 0x6f, 0x1e, 0x3e, 0x3c, 0x00, 0x00, 0x84, 0x02, 0x00, 0x00, 0x75, 0x73, // VSH.o.><......us
+	0x69, 0x6e, 0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x6d, 0x65, // ing namespace me
+	0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // tal;.struct xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x7b, // MtlShaderInput {
+	0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x20, 0x61, 0x5f, 0x70, 0x6f, 0x73, 0x69, // .  float3 a_posi
+	0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5b, 0x5b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, // tion [[attribute
+	0x28, 0x30, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, // (0)]];.  float2
+	0x61, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x20, 0x5b, 0x5b, 0x61, 0x74, // a_texcoord0 [[at
+	0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x31, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x7d, 0x3b, // tribute(1)]];.};
+	0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, // .struct xlatMtlS
+	0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, // haderOutput {.
+	0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, // float4 gl_Positi
+	0x6f, 0x6e, 0x20, 0x5b, 0x5b, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5d, 0x5d, 0x3b, // on [[position]];
+	0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, // .  float2 v_texc
+	0x6f, 0x6f, 0x72, 0x64, 0x30, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, // oord0;.};.struct
+	0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, //  xlatMtlShaderUn
+	0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, // iform {.  float4
+	0x78, 0x34, 0x20, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, // x4 u_modelViewPr
+	0x6f, 0x6a, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x20, 0x78, 0x6c, // oj;.};.vertex xl
+	0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, // atMtlShaderOutpu
+	0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x4d, 0x61, 0x69, 0x6e, 0x20, 0x28, 0x78, // t xlatMtlMain (x
+	0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, // latMtlShaderInpu
+	0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x20, 0x5b, 0x5b, 0x73, 0x74, 0x61, 0x67, 0x65, // t _mtl_i [[stage
+	0x5f, 0x69, 0x6e, 0x5d, 0x5d, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x20, // _in]], constant
+	0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, // xlatMtlShaderUni
+	0x66, 0x6f, 0x72, 0x6d, 0x26, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x20, 0x5b, 0x5b, 0x62, // form& _mtl_u [[b
+	0x75, 0x66, 0x66, 0x65, 0x72, 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, // uffer(0)]]).{.
+	0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, // xlatMtlShaderOut
+	0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, // put _mtl_o;.  fl
+	0x6f, 0x61, 0x74, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x3b, 0x0a, 0x20, // oat4 tmpvar_1;.
+	0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x2e, 0x77, 0x20, 0x3d, 0x20, 0x31, 0x2e, //  tmpvar_1.w = 1.
+	0x30, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x2e, 0x78, 0x79, // 0;.  tmpvar_1.xy
+	0x7a, 0x20, 0x3d, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x61, 0x5f, 0x70, 0x6f, 0x73, // z = _mtl_i.a_pos
+	0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, // ition;.  _mtl_o.
+	0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x28, 0x5f, // gl_Position = (_
+	0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, // mtl_u.u_modelVie
+	0x77, 0x50, 0x72, 0x6f, 0x6a, 0x20, 0x2a, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, // wProj * tmpvar_1
+	0x29, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x76, 0x5f, 0x74, 0x65, // );.  _mtl_o.v_te
+	0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x20, 0x3d, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, // xcoord0 = _mtl_i
+	0x2e, 0x61, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x3b, 0x0a, 0x20, 0x20, // .a_texcoord0;.
+	0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x7d, // return _mtl_o;.}
+	0x0a, 0x0a, 0x00,                                                                               // ...
+};

+ 51 - 0
examples/common/imgui/vs_imgui_texture.bin.h

@@ -91,3 +91,54 @@ static const uint8_t vs_imgui_texture_dx11[575] =
 	0x05, 0x32, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, 0x02, 0x00, 0x00, // .2 ......F......
 	0x00, 0x3e, 0x00, 0x00, 0x01, 0x00, 0x03, 0x05, 0x00, 0x01, 0x00, 0x10, 0x00, 0x40, 0x00,       // .>...........@.
 };
+static const uint8_t vs_imgui_texture_mtl[757] =
+{
+	0x56, 0x53, 0x48, 0x04, 0x01, 0x83, 0xf2, 0xe1, 0x00, 0x00, 0xe6, 0x02, 0x00, 0x00, 0x75, 0x73, // VSH...........us
+	0x69, 0x6e, 0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x6d, 0x65, // ing namespace me
+	0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // tal;.struct xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x7b, // MtlShaderInput {
+	0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x61, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, // .  float4 a_colo
+	0x72, 0x30, 0x20, 0x5b, 0x5b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x30, // r0 [[attribute(0
+	0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x20, 0x61, 0x5f, // )]];.  float3 a_
+	0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5b, 0x5b, 0x61, 0x74, 0x74, 0x72, 0x69, // position [[attri
+	0x62, 0x75, 0x74, 0x65, 0x28, 0x31, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, // bute(1)]];.  flo
+	0x61, 0x74, 0x32, 0x20, 0x61, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x20, // at2 a_texcoord0
+	0x5b, 0x5b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x32, 0x29, 0x5d, 0x5d, // [[attribute(2)]]
+	0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // ;.};.struct xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, // MtlShaderOutput
+	0x7b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x67, 0x6c, 0x5f, 0x50, 0x6f, // {.  float4 gl_Po
+	0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5b, 0x5b, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, // sition [[positio
+	0x6e, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x76, 0x5f, // n]];.  float4 v_
+	0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, // color0;.  float2
+	0x20, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x3b, 0x0a, 0x7d, 0x3b, //  v_texcoord0;.};
+	0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, // .struct xlatMtlS
+	0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x7b, 0x0a, 0x20, // haderUniform {.
+	0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x78, 0x34, 0x20, 0x75, 0x5f, 0x76, 0x69, 0x65, 0x77, //  float4x4 u_view
+	0x50, 0x72, 0x6f, 0x6a, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x20, // Proj;.};.vertex
+	0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, // xlatMtlShaderOut
+	0x70, 0x75, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x4d, 0x61, 0x69, 0x6e, 0x20, // put xlatMtlMain
+	0x28, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, // (xlatMtlShaderIn
+	0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x20, 0x5b, 0x5b, 0x73, 0x74, 0x61, // put _mtl_i [[sta
+	0x67, 0x65, 0x5f, 0x69, 0x6e, 0x5d, 0x5d, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, // ge_in]], constan
+	0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x55, // t xlatMtlShaderU
+	0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x26, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x20, 0x5b, // niform& _mtl_u [
+	0x5b, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x29, 0x0a, 0x7b, 0x0a, // [buffer(0)]]).{.
+	0x20, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, //   xlatMtlShaderO
+	0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x20, 0x20, // utput _mtl_o;.
+	0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x3b, // float4 tmpvar_1;
+	0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x2e, 0x7a, 0x77, 0x20, 0x3d, // .  tmpvar_1.zw =
+	0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x28, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, //  float2(0.0, 1.0
+	0x29, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x2e, 0x78, 0x79, // );.  tmpvar_1.xy
+	0x20, 0x3d, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x61, 0x5f, 0x70, 0x6f, 0x73, 0x69, //  = _mtl_i.a_posi
+	0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x78, 0x79, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, // tion.xy;.  _mtl_
+	0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, // o.gl_Position =
+	0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x75, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x50, 0x72, // (_mtl_u.u_viewPr
+	0x6f, 0x6a, 0x20, 0x2a, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x29, 0x3b, 0x0a, // oj * tmpvar_1);.
+	0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, //   _mtl_o.v_texco
+	0x6f, 0x72, 0x64, 0x30, 0x20, 0x3d, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x61, 0x5f, // ord0 = _mtl_i.a_
+	0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, // texcoord0;.  _mt
+	0x6c, 0x5f, 0x6f, 0x2e, 0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x20, 0x3d, 0x20, 0x5f, // l_o.v_color0 = _
+	0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x61, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x3b, 0x0a, // mtl_i.a_color0;.
+	0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, //   return _mtl_o;
+	0x0a, 0x7d, 0x0a, 0x0a, 0x00,                                                                   // .}...
+};

+ 57 - 0
examples/common/imgui/vs_ocornut_imgui.bin.h

@@ -102,3 +102,60 @@ static const uint8_t vs_ocornut_imgui_dx11[612] =
 	0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x00, 0x03, 0x05, 0x00, 0x01, 0x00, // ......>.........
 	0x10, 0x00, 0x10, 0x00,                                                                         // ....
 };
+static const uint8_t vs_ocornut_imgui_mtl[854] =
+{
+	0x56, 0x53, 0x48, 0x04, 0x01, 0x83, 0xf2, 0xe1, 0x00, 0x00, 0x47, 0x03, 0x00, 0x00, 0x75, 0x73, // VSH.......G...us
+	0x69, 0x6e, 0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x6d, 0x65, // ing namespace me
+	0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // tal;.struct xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x7b, // MtlShaderInput {
+	0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x61, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, // .  float4 a_colo
+	0x72, 0x30, 0x20, 0x5b, 0x5b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x30, // r0 [[attribute(0
+	0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x20, 0x61, 0x5f, // )]];.  float3 a_
+	0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5b, 0x5b, 0x61, 0x74, 0x74, 0x72, 0x69, // position [[attri
+	0x62, 0x75, 0x74, 0x65, 0x28, 0x31, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, // bute(1)]];.  flo
+	0x61, 0x74, 0x32, 0x20, 0x61, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x20, // at2 a_texcoord0
+	0x5b, 0x5b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x32, 0x29, 0x5d, 0x5d, // [[attribute(2)]]
+	0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // ;.};.struct xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, // MtlShaderOutput
+	0x7b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x67, 0x6c, 0x5f, 0x50, 0x6f, // {.  float4 gl_Po
+	0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5b, 0x5b, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, // sition [[positio
+	0x6e, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x76, 0x5f, // n]];.  float4 v_
+	0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, // color0;.  float2
+	0x20, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x3b, 0x0a, 0x7d, 0x3b, //  v_texcoord0;.};
+	0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, // .struct xlatMtlS
+	0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x7b, 0x0a, 0x20, // haderUniform {.
+	0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x75, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x54, 0x65, //  float4 u_viewTe
+	0x78, 0x65, 0x6c, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x20, 0x78, // xel;.};.vertex x
+	0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, // latMtlShaderOutp
+	0x75, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x4d, 0x61, 0x69, 0x6e, 0x20, 0x28, // ut xlatMtlMain (
+	0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, // xlatMtlShaderInp
+	0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x20, 0x5b, 0x5b, 0x73, 0x74, 0x61, 0x67, // ut _mtl_i [[stag
+	0x65, 0x5f, 0x69, 0x6e, 0x5d, 0x5d, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, // e_in]], constant
+	0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, //  xlatMtlShaderUn
+	0x69, 0x66, 0x6f, 0x72, 0x6d, 0x26, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x20, 0x5b, 0x5b, // iform& _mtl_u [[
+	0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x29, 0x0a, 0x7b, 0x0a, 0x20, // buffer(0)]]).{.
+	0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, //  xlatMtlShaderOu
+	0x74, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x20, 0x20, 0x66, // tput _mtl_o;.  f
+	0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x3b, 0x0a, // loat2 tmpvar_1;.
+	0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x20, 0x3d, 0x20, 0x28, 0x28, 0x32, //   tmpvar_1 = ((2
+	0x2e, 0x30, 0x20, 0x2a, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x61, 0x5f, 0x70, 0x6f, // .0 * _mtl_i.a_po
+	0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x78, 0x79, 0x29, 0x20, 0x2a, 0x20, 0x5f, 0x6d, 0x74, // sition.xy) * _mt
+	0x6c, 0x5f, 0x75, 0x2e, 0x75, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x54, 0x65, 0x78, 0x65, 0x6c, 0x2e, // l_u.u_viewTexel.
+	0x78, 0x79, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x74, 0x6d, // xy);.  float4 tm
+	0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, // pvar_2;.  tmpvar
+	0x5f, 0x32, 0x2e, 0x7a, 0x77, 0x20, 0x3d, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x28, 0x30, // _2.zw = float2(0
+	0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, // .0, 1.0);.  tmpv
+	0x61, 0x72, 0x5f, 0x32, 0x2e, 0x78, 0x20, 0x3d, 0x20, 0x28, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, // ar_2.x = (tmpvar
+	0x5f, 0x31, 0x2e, 0x78, 0x20, 0x2d, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x74, // _1.x - 1.0);.  t
+	0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x2e, 0x79, 0x20, 0x3d, 0x20, 0x28, 0x31, 0x2e, 0x30, // mpvar_2.y = (1.0
+	0x20, 0x2d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x2e, 0x79, 0x29, 0x3b, 0x0a, //  - tmpvar_1.y);.
+	0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, //   _mtl_o.gl_Posi
+	0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x3b, // tion = tmpvar_2;
+	0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, // .  _mtl_o.v_texc
+	0x6f, 0x6f, 0x72, 0x64, 0x30, 0x20, 0x3d, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x61, // oord0 = _mtl_i.a
+	0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, // _texcoord0;.  _m
+	0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x20, 0x3d, 0x20, // tl_o.v_color0 =
+	0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x61, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x3b, // _mtl_i.a_color0;
+	0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, // .  return _mtl_o
+	0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00,                                                             // ;.}...
+};

+ 224 - 0
examples/common/nanovg/fs_nanovg_fill.bin.h

@@ -440,3 +440,227 @@ static const uint8_t fs_nanovg_fill_dx11[2286] =
 	0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x01, 0x15, 0x00, 0x00, 0x01, 0x15, 0x00, // ................
 	0x00, 0x01, 0x15, 0x00, 0x00, 0x01, 0x3e, 0x00, 0x00, 0x01, 0x00, 0x00, 0xb0, 0x00,             // ......>.......
 };
+static const uint8_t fs_nanovg_fill_mtl[3526] =
+{
+	0x46, 0x53, 0x48, 0x04, 0xcf, 0xda, 0x1b, 0x94, 0x00, 0x00, 0xb7, 0x0d, 0x00, 0x00, 0x75, 0x73, // FSH...........us
+	0x69, 0x6e, 0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x6d, 0x65, // ing namespace me
+	0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // tal;.struct xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x7b, // MtlShaderInput {
+	0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x76, 0x5f, 0x70, 0x6f, 0x73, 0x69, // .  float2 v_posi
+	0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x76, // tion;.  float2 v
+	0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x73, // _texcoord0;.};.s
+	0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, // truct xlatMtlSha
+	0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x68, 0x61, // derOutput {.  ha
+	0x6c, 0x66, 0x34, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, // lf4 gl_FragColor
+	0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // ;.};.struct xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, // MtlShaderUniform
+	0x20, 0x7b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x78, 0x33, 0x20, 0x75, 0x5f, //  {.  float3x3 u_
+	0x73, 0x63, 0x69, 0x73, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x74, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, // scissorMat;.  fl
+	0x6f, 0x61, 0x74, 0x33, 0x78, 0x33, 0x20, 0x75, 0x5f, 0x70, 0x61, 0x69, 0x6e, 0x74, 0x4d, 0x61, // oat3x3 u_paintMa
+	0x74, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x75, 0x5f, 0x69, 0x6e, // t;.  float4 u_in
+	0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6c, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, // nerCol;.  float4
+	0x20, 0x75, 0x5f, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6c, 0x3b, 0x0a, 0x20, 0x20, 0x66, //  u_outerCol;.  f
+	0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x75, 0x5f, 0x73, 0x63, 0x69, 0x73, 0x73, 0x6f, 0x72, 0x45, // loat4 u_scissorE
+	0x78, 0x74, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, // xtScale;.  float
+	0x34, 0x20, 0x75, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x52, 0x61, 0x64, 0x69, 0x75, 0x73, // 4 u_extentRadius
+	0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x75, 0x5f, 0x70, 0x61, 0x72, // ;.  float4 u_par
+	0x61, 0x6d, 0x73, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, // ams;.};.fragment
+	0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, //  xlatMtlShaderOu
+	0x74, 0x70, 0x75, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x4d, 0x61, 0x69, 0x6e, // tput xlatMtlMain
+	0x20, 0x28, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, //  (xlatMtlShaderI
+	0x6e, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x20, 0x5b, 0x5b, 0x73, 0x74, // nput _mtl_i [[st
+	0x61, 0x67, 0x65, 0x5f, 0x69, 0x6e, 0x5d, 0x5d, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, // age_in]], consta
+	0x6e, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, // nt xlatMtlShader
+	0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x26, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x20, // Uniform& _mtl_u
+	0x5b, 0x5b, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x0a, 0x20, 0x20, // [[buffer(0)]].
+	0x2c, 0x20, 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x64, 0x3c, 0x66, 0x6c, // ,   texture2d<fl
+	0x6f, 0x61, 0x74, 0x3e, 0x20, 0x73, 0x5f, 0x74, 0x65, 0x78, 0x20, 0x5b, 0x5b, 0x74, 0x65, 0x78, // oat> s_tex [[tex
+	0x74, 0x75, 0x72, 0x65, 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x2c, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, // ture(0)]], sampl
+	0x65, 0x72, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x73, 0x6d, 0x70, 0x5f, 0x73, 0x5f, 0x74, 0x65, 0x78, // er _mtlsmp_s_tex
+	0x20, 0x5b, 0x5b, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x29, //  [[sampler(0)]])
+	0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, // .{.  xlatMtlShad
+	0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, // erOutput _mtl_o;
+	0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x5f, // .  half4 result_
+	0x31, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, // 1;.  float tmpva
+	0x72, 0x5f, 0x32, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x73, 0x63, // r_2;.  float2 sc
+	0x5f, 0x33, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x20, 0x74, 0x6d, 0x70, // _3;.  float3 tmp
+	0x76, 0x61, 0x72, 0x5f, 0x34, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, // var_4;.  tmpvar_
+	0x34, 0x2e, 0x7a, 0x20, 0x3d, 0x20, 0x31, 0x2e, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, // 4.z = 1.0;.  tmp
+	0x76, 0x61, 0x72, 0x5f, 0x34, 0x2e, 0x78, 0x79, 0x20, 0x3d, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, // var_4.xy = _mtl_
+	0x69, 0x2e, 0x76, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x0a, 0x20, 0x20, // i.v_position;.
+	0x73, 0x63, 0x5f, 0x33, 0x20, 0x3d, 0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x28, 0x30, // sc_3 = (float2(0
+	0x2e, 0x35, 0x2c, 0x20, 0x30, 0x2e, 0x35, 0x29, 0x20, 0x2d, 0x20, 0x28, 0x28, 0x0a, 0x20, 0x20, // .5, 0.5) - ((.
+	0x20, 0x20, 0x61, 0x62, 0x73, 0x28, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x75, 0x5f, //   abs((_mtl_u.u_
+	0x73, 0x63, 0x69, 0x73, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x74, 0x20, 0x2a, 0x20, 0x74, 0x6d, 0x70, // scissorMat * tmp
+	0x76, 0x61, 0x72, 0x5f, 0x34, 0x29, 0x2e, 0x78, 0x79, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x2d, 0x20, // var_4).xy).   -
+	0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x75, 0x5f, 0x73, 0x63, 0x69, 0x73, 0x73, 0x6f, 0x72, // _mtl_u.u_scissor
+	0x45, 0x78, 0x74, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x78, 0x79, 0x29, 0x20, 0x2a, 0x20, 0x5f, // ExtScale.xy) * _
+	0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x75, 0x5f, 0x73, 0x63, 0x69, 0x73, 0x73, 0x6f, 0x72, 0x45, // mtl_u.u_scissorE
+	0x78, 0x74, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x7a, 0x77, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, // xtScale.zw));.
+	0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x20, 0x3d, 0x20, 0x28, 0x63, 0x6c, 0x61, 0x6d, // tmpvar_2 = (clam
+	0x70, 0x20, 0x28, 0x73, 0x63, 0x5f, 0x33, 0x2e, 0x78, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x2c, 0x20, // p (sc_3.x, 0.0,
+	0x31, 0x2e, 0x30, 0x29, 0x20, 0x2a, 0x20, 0x63, 0x6c, 0x61, 0x6d, 0x70, 0x20, 0x28, 0x73, 0x63, // 1.0) * clamp (sc
+	0x5f, 0x33, 0x2e, 0x79, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x29, // _3.y, 0.0, 1.0))
+	0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, // ;.  float tmpvar
+	0x5f, 0x35, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x35, 0x20, 0x3d, // _5;.  tmpvar_5 =
+	0x20, 0x28, 0x6d, 0x69, 0x6e, 0x20, 0x28, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x28, 0x0a, 0x20, 0x20, //  (min (1.0, (.
+	0x20, 0x20, 0x28, 0x31, 0x2e, 0x30, 0x20, 0x2d, 0x20, 0x61, 0x62, 0x73, 0x28, 0x28, 0x28, 0x5f, //   (1.0 - abs(((_
+	0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, // mtl_i.v_texcoord
+	0x30, 0x2e, 0x78, 0x20, 0x2a, 0x20, 0x32, 0x2e, 0x30, 0x29, 0x20, 0x2d, 0x20, 0x31, 0x2e, 0x30, // 0.x * 2.0) - 1.0
+	0x29, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, // ))).   * _mtl_u.
+	0x75, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x2e, 0x79, 0x29, 0x29, 0x20, 0x2a, 0x20, 0x6d, // u_params.y)) * m
+	0x69, 0x6e, 0x20, 0x28, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, // in (1.0, _mtl_i.
+	0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x2e, 0x79, 0x29, 0x29, 0x3b, // v_texcoord0.y));
+	0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x75, // .  if ((_mtl_u.u
+	0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x2e, 0x77, 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x2e, 0x30, // _params.w == 0.0
+	0x29, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, // )) {.    float4
+	0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x36, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, // color_6;.    flo
+	0x61, 0x74, 0x33, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x37, 0x3b, 0x0a, 0x20, 0x20, // at3 tmpvar_7;.
+	0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x37, 0x2e, 0x7a, 0x20, 0x3d, 0x20, 0x31, //   tmpvar_7.z = 1
+	0x2e, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x37, // .0;.    tmpvar_7
+	0x2e, 0x78, 0x79, 0x20, 0x3d, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x76, 0x5f, 0x70, // .xy = _mtl_i.v_p
+	0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, // osition;.    flo
+	0x61, 0x74, 0x32, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x38, 0x3b, 0x0a, 0x20, 0x20, // at2 tmpvar_8;.
+	0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x38, 0x20, 0x3d, 0x20, 0x28, 0x61, 0x62, //   tmpvar_8 = (ab
+	0x73, 0x28, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x75, 0x5f, 0x70, 0x61, 0x69, 0x6e, // s((_mtl_u.u_pain
+	0x74, 0x4d, 0x61, 0x74, 0x20, 0x2a, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x37, 0x29, // tMat * tmpvar_7)
+	0x2e, 0x78, 0x79, 0x29, 0x20, 0x2d, 0x20, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x75, // .xy) - (_mtl_u.u
+	0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x52, 0x61, 0x64, 0x69, 0x75, 0x73, 0x2e, 0x78, 0x79, // _extentRadius.xy
+	0x20, 0x2d, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x75, 0x5f, 0x65, 0x78, 0x74, 0x65, //  - _mtl_u.u_exte
+	0x6e, 0x74, 0x52, 0x61, 0x64, 0x69, 0x75, 0x73, 0x2e, 0x7a, 0x7a, 0x29, 0x29, 0x3b, 0x0a, 0x20, // ntRadius.zz));.
+	0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, //    float2 tmpvar
+	0x5f, 0x39, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x39, // _9;.    tmpvar_9
+	0x20, 0x3d, 0x20, 0x6d, 0x61, 0x78, 0x20, 0x28, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x38, //  = max (tmpvar_8
+	0x2c, 0x20, 0x30, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, // , 0.0);.    floa
+	0x74, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x30, 0x3b, 0x0a, 0x20, 0x20, // t4 tmpvar_10;.
+	0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x30, 0x20, 0x3d, 0x20, 0x6d, 0x69, //   tmpvar_10 = mi
+	0x78, 0x20, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x75, 0x5f, 0x69, 0x6e, 0x6e, 0x65, // x (_mtl_u.u_inne
+	0x72, 0x43, 0x6f, 0x6c, 0x2c, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x75, 0x5f, 0x6f, // rCol, _mtl_u.u_o
+	0x75, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6c, 0x2c, 0x20, 0x63, 0x6c, 0x61, 0x6d, 0x70, 0x20, 0x28, // uterCol, clamp (
+	0x28, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x28, 0x28, 0x6d, 0x69, 0x6e, 0x20, 0x28, // (.      (((min (
+	0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x61, 0x78, 0x20, 0x28, 0x74, 0x6d, // .        max (tm
+	0x70, 0x76, 0x61, 0x72, 0x5f, 0x38, 0x2e, 0x78, 0x2c, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, // pvar_8.x, tmpvar
+	0x5f, 0x38, 0x2e, 0x79, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2c, 0x20, 0x30, 0x2e, // _8.y).      , 0.
+	0x30, 0x29, 0x20, 0x2b, 0x20, 0x73, 0x71, 0x72, 0x74, 0x28, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, // 0) + sqrt(.
+	0x20, 0x20, 0x20, 0x64, 0x6f, 0x74, 0x20, 0x28, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x39, //    dot (tmpvar_9
+	0x2c, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x39, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, // , tmpvar_9).
+	0x20, 0x20, 0x29, 0x29, 0x20, 0x2d, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x75, 0x5f, //   )) - _mtl_u.u_
+	0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x52, 0x61, 0x64, 0x69, 0x75, 0x73, 0x2e, 0x7a, 0x29, 0x20, // extentRadius.z)
+	0x2b, 0x20, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x75, 0x5f, 0x70, 0x61, 0x72, 0x61, // + (_mtl_u.u_para
+	0x6d, 0x73, 0x2e, 0x78, 0x20, 0x2a, 0x20, 0x30, 0x2e, 0x35, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x20, // ms.x * 0.5)).
+	0x20, 0x20, 0x2f, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x75, 0x5f, 0x70, 0x61, 0x72, //   / _mtl_u.u_par
+	0x61, 0x6d, 0x73, 0x2e, 0x78, 0x29, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, // ams.x), 0.0, 1.0
+	0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x36, 0x2e, // ));.    color_6.
+	0x78, 0x79, 0x7a, 0x20, 0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x30, 0x2e, // xyz = tmpvar_10.
+	0x78, 0x79, 0x7a, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x36, // xyz;.    color_6
+	0x2e, 0x77, 0x20, 0x3d, 0x20, 0x28, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x30, 0x2e, // .w = (tmpvar_10.
+	0x77, 0x20, 0x2a, 0x20, 0x28, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x35, 0x20, 0x2a, 0x20, // w * (tmpvar_5 *
+	0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, // tmpvar_2));.
+	0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x5f, 0x31, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, // result_1 = half4
+	0x28, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x36, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x7d, 0x20, 0x65, // (color_6);.  } e
+	0x6c, 0x73, 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x28, 0x5f, // lse {.    if ((_
+	0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x75, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x2e, 0x77, // mtl_u.u_params.w
+	0x20, 0x3d, 0x3d, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, //  == 1.0)) {.
+	0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x31, 0x31, //   half4 color_11
+	0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x20, 0x74, // ;.      float3 t
+	0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x32, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, // mpvar_12;.
+	0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x32, 0x2e, 0x7a, 0x20, 0x3d, 0x20, 0x31, 0x2e, // tmpvar_12.z = 1.
+	0x30, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, // 0;.      tmpvar_
+	0x31, 0x32, 0x2e, 0x78, 0x79, 0x20, 0x3d, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x76, // 12.xy = _mtl_i.v
+	0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, // _position;.
+	0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, //  float2 tmpvar_1
+	0x33, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, // 3;.      tmpvar_
+	0x31, 0x33, 0x20, 0x3d, 0x20, 0x28, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x75, 0x5f, // 13 = ((_mtl_u.u_
+	0x70, 0x61, 0x69, 0x6e, 0x74, 0x4d, 0x61, 0x74, 0x20, 0x2a, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, // paintMat * tmpva
+	0x72, 0x5f, 0x31, 0x32, 0x29, 0x2e, 0x78, 0x79, 0x20, 0x2f, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, // r_12).xy / _mtl_
+	0x75, 0x2e, 0x75, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x52, 0x61, 0x64, 0x69, 0x75, 0x73, // u.u_extentRadius
+	0x2e, 0x78, 0x79, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, // .xy);.      half
+	0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x34, 0x3b, 0x0a, 0x20, 0x20, 0x20, // 4 tmpvar_14;.
+	0x20, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x34, 0x20, 0x3d, 0x20, 0x73, //    tmpvar_14 = s
+	0x5f, 0x74, 0x65, 0x78, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x28, 0x5f, 0x6d, 0x74, 0x6c, // _tex.sample(_mtl
+	0x73, 0x6d, 0x70, 0x5f, 0x73, 0x5f, 0x74, 0x65, 0x78, 0x2c, 0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61, // smp_s_tex, (floa
+	0x74, 0x32, 0x29, 0x28, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x33, 0x29, 0x29, 0x3b, // t2)(tmpvar_13));
+	0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x31, 0x31, 0x20, // .      color_11
+	0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x34, 0x3b, 0x0a, 0x20, 0x20, 0x20, // = tmpvar_14;.
+	0x20, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, //    half4 tmpvar_
+	0x31, 0x35, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x28, 0x5f, // 15;.      if ((_
+	0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x75, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x2e, 0x7a, // mtl_u.u_params.z
+	0x20, 0x3d, 0x3d, 0x20, 0x30, 0x2e, 0x30, 0x29, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, //  == 0.0)) {.
+	0x20, 0x20, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x35, 0x20, 0x3d, 0x20, //     tmpvar_15 =
+	0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x34, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, // tmpvar_14;.
+	0x20, 0x7d, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, //  } else {.
+	0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, //   half4 tmpvar_1
+	0x36, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, // 6;.        tmpva
+	0x72, 0x5f, 0x31, 0x36, 0x2e, 0x78, 0x79, 0x7a, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x33, // r_16.xyz = half3
+	0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x28, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, // (float3(1.0, 1.0
+	0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, // , 1.0));.
+	0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x36, 0x2e, 0x77, 0x20, 0x3d, 0x20, 0x74, //  tmpvar_16.w = t
+	0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x34, 0x2e, 0x78, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, // mpvar_14.x;.
+	0x20, 0x20, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x35, 0x20, 0x3d, 0x20, //     tmpvar_15 =
+	0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x36, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, // tmpvar_16;.
+	0x20, 0x7d, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, //  };.      color_
+	0x31, 0x31, 0x2e, 0x78, 0x79, 0x7a, 0x20, 0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, // 11.xyz = tmpvar_
+	0x31, 0x35, 0x2e, 0x78, 0x79, 0x7a, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, // 15.xyz;.      co
+	0x6c, 0x6f, 0x72, 0x5f, 0x31, 0x31, 0x2e, 0x77, 0x20, 0x3d, 0x20, 0x28, 0x28, 0x68, 0x61, 0x6c, // lor_11.w = ((hal
+	0x66, 0x29, 0x28, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x29, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, // f)((float)tmpvar
+	0x5f, 0x31, 0x35, 0x2e, 0x77, 0x20, 0x2a, 0x20, 0x28, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, // _15.w * (tmpvar_
+	0x35, 0x20, 0x2a, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x29, 0x29, 0x29, 0x3b, // 5 * tmpvar_2)));
+	0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x5f, 0x31, 0x20, // .      result_1
+	0x3d, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x31, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, // = color_11;.
+	0x7d, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, // } else {.      i
+	0x66, 0x20, 0x28, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x75, 0x5f, 0x70, 0x61, 0x72, // f ((_mtl_u.u_par
+	0x61, 0x6d, 0x73, 0x2e, 0x77, 0x20, 0x3d, 0x3d, 0x20, 0x32, 0x2e, 0x30, 0x29, 0x29, 0x20, 0x7b, // ams.w == 2.0)) {
+	0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x5f, // .        result_
+	0x31, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, // 1 = half4(float4
+	0x28, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, // (1.0, 1.0, 1.0,
+	0x31, 0x2e, 0x30, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x20, 0x65, // 1.0));.      } e
+	0x6c, 0x73, 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, // lse {.        if
+	0x20, 0x28, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x75, 0x5f, 0x70, 0x61, 0x72, 0x61, //  ((_mtl_u.u_para
+	0x6d, 0x73, 0x2e, 0x77, 0x20, 0x3d, 0x3d, 0x20, 0x33, 0x2e, 0x30, 0x29, 0x29, 0x20, 0x7b, 0x0a, // ms.w == 3.0)) {.
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, //           half4
+	0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x31, 0x37, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, // color_17;.
+	0x20, 0x20, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, //     half4 tmpvar
+	0x5f, 0x31, 0x38, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, // _18;.          t
+	0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x38, 0x20, 0x3d, 0x20, 0x73, 0x5f, 0x74, 0x65, 0x78, // mpvar_18 = s_tex
+	0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x73, 0x6d, 0x70, 0x5f, // .sample(_mtlsmp_
+	0x73, 0x5f, 0x74, 0x65, 0x78, 0x2c, 0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x29, 0x28, // s_tex, (float2)(
+	0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, // _mtl_i.v_texcoor
+	0x64, 0x30, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, // d0));.
+	0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x31, 0x37, 0x20, 0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, // color_17 = tmpva
+	0x72, 0x5f, 0x31, 0x38, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, // r_18;.
+	0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x39, 0x3b, // half4 tmpvar_19;
+	0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x28, // .          if ((
+	0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x75, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x2e, // _mtl_u.u_params.
+	0x7a, 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x2e, 0x30, 0x29, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, // z == 0.0)) {.
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, //          tmpvar_
+	0x31, 0x39, 0x20, 0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x38, 0x3b, 0x0a, // 19 = tmpvar_18;.
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x20, 0x65, 0x6c, 0x73, 0x65, //           } else
+	0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, //  {.            h
+	0x61, 0x6c, 0x66, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x30, 0x3b, 0x0a, // alf4 tmpvar_20;.
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, //             tmpv
+	0x61, 0x72, 0x5f, 0x32, 0x30, 0x2e, 0x78, 0x79, 0x7a, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, // ar_20.xyz = half
+	0x33, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x28, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, // 3(float3(1.0, 1.
+	0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, // 0, 1.0));.
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x30, 0x2e, //       tmpvar_20.
+	0x77, 0x20, 0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x38, 0x2e, 0x78, 0x3b, // w = tmpvar_18.x;
+	0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6d, 0x70, // .            tmp
+	0x76, 0x61, 0x72, 0x5f, 0x31, 0x39, 0x20, 0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, // var_19 = tmpvar_
+	0x32, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x3b, // 20;.          };
+	0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, // .          color
+	0x5f, 0x31, 0x37, 0x2e, 0x78, 0x79, 0x7a, 0x20, 0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, // _17.xyz = tmpvar
+	0x5f, 0x31, 0x39, 0x2e, 0x78, 0x79, 0x7a, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, // _19.xyz;.
+	0x20, 0x20, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x31, 0x37, 0x2e, 0x77, 0x20, 0x3d, 0x20, //    color_17.w =
+	0x28, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x28, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x29, 0x74, // ((half)((float)t
+	0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x39, 0x2e, 0x77, 0x20, 0x2a, 0x20, 0x74, 0x6d, 0x70, // mpvar_19.w * tmp
+	0x76, 0x61, 0x72, 0x5f, 0x32, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, // var_2));.
+	0x20, 0x20, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x5f, 0x31, 0x20, 0x3d, 0x20, 0x28, 0x28, //    result_1 = ((
+	0x68, 0x61, 0x6c, 0x66, 0x34, 0x29, 0x28, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x29, 0x63, // half4)((float4)c
+	0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x31, 0x37, 0x20, 0x2a, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, // olor_17 * _mtl_u
+	0x2e, 0x75, 0x5f, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6c, 0x29, 0x29, 0x3b, 0x0a, 0x20, // .u_innerCol));.
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, //        };.
+	0x7d, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x3b, 0x0a, 0x20, 0x20, 0x7d, 0x3b, 0x0a, 0x20, // };.    };.  };.
+	0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, //  _mtl_o.gl_FragC
+	0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x5f, 0x31, 0x3b, // olor = result_1;
+	0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, // .  return _mtl_o
+	0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00,                                                             // ;.}...
+};

+ 5 - 0
examples/common/nanovg/nanovg_bgfx.cpp

@@ -247,6 +247,11 @@ namespace
 			fs_nanovg_fill = bgfx::makeRef(fs_nanovg_fill_dx11, sizeof(fs_nanovg_fill_dx11) );
 			break;
 
+		case bgfx::RendererType::Metal:
+			vs_nanovg_fill = bgfx::makeRef(vs_nanovg_fill_mtl, sizeof(vs_nanovg_fill_mtl) );
+			fs_nanovg_fill = bgfx::makeRef(fs_nanovg_fill_mtl, sizeof(fs_nanovg_fill_mtl) );
+			break;
+				
 		default:
 			vs_nanovg_fill = bgfx::makeRef(vs_nanovg_fill_glsl, sizeof(vs_nanovg_fill_glsl) );
 			fs_nanovg_fill = bgfx::makeRef(fs_nanovg_fill_glsl, sizeof(fs_nanovg_fill_glsl) );

+ 58 - 0
examples/common/nanovg/vs_nanovg_fill.bin.h

@@ -105,3 +105,61 @@ static const uint8_t vs_nanovg_fill_dx11[577] =
 	0x00, 0x01, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x00, 0x02, 0x01, 0x00, 0x10, 0x00, 0x10, // .....>..........
 	0x00,                                                                                           // .
 };
+static const uint8_t vs_nanovg_fill_mtl[865] =
+{
+	0x56, 0x53, 0x48, 0x04, 0xcf, 0xda, 0x1b, 0x94, 0x00, 0x00, 0x52, 0x03, 0x00, 0x00, 0x75, 0x73, // VSH.......R...us
+	0x69, 0x6e, 0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x6d, 0x65, // ing namespace me
+	0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // tal;.struct xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x7b, // MtlShaderInput {
+	0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x61, 0x5f, 0x70, 0x6f, 0x73, 0x69, // .  float2 a_posi
+	0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5b, 0x5b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, // tion [[attribute
+	0x28, 0x30, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, // (0)]];.  float2
+	0x61, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x20, 0x5b, 0x5b, 0x61, 0x74, // a_texcoord0 [[at
+	0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x31, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x7d, 0x3b, // tribute(1)]];.};
+	0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, // .struct xlatMtlS
+	0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, // haderOutput {.
+	0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, // float4 gl_Positi
+	0x6f, 0x6e, 0x20, 0x5b, 0x5b, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5d, 0x5d, 0x3b, // on [[position]];
+	0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x76, 0x5f, 0x70, 0x6f, 0x73, 0x69, // .  float2 v_posi
+	0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x76, // tion;.  float2 v
+	0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x73, // _texcoord0;.};.s
+	0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, // truct xlatMtlSha
+	0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x66, // derUniform {.  f
+	0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x75, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x53, 0x69, 0x7a, 0x65, // loat4 u_viewSize
+	0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x75, 0x5f, 0x68, 0x61, 0x6c, // ;.  float4 u_hal
+	0x66, 0x54, 0x65, 0x78, 0x65, 0x6c, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x76, 0x65, 0x72, 0x74, 0x65, // fTexel;.};.verte
+	0x78, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, // x xlatMtlShaderO
+	0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x4d, 0x61, 0x69, // utput xlatMtlMai
+	0x6e, 0x20, 0x28, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, // n (xlatMtlShader
+	0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x20, 0x5b, 0x5b, 0x73, // Input _mtl_i [[s
+	0x74, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x6e, 0x5d, 0x5d, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, // tage_in]], const
+	0x61, 0x6e, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, // ant xlatMtlShade
+	0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x26, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, // rUniform& _mtl_u
+	0x20, 0x5b, 0x5b, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x29, 0x0a, //  [[buffer(0)]]).
+	0x7b, 0x0a, 0x20, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, // {.  xlatMtlShade
+	0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, // rOutput _mtl_o;.
+	0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x76, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, //   _mtl_o.v_posit
+	0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x61, 0x5f, 0x70, // ion = _mtl_i.a_p
+	0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, // osition;.  _mtl_
+	0x6f, 0x2e, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x20, 0x3d, 0x20, // o.v_texcoord0 =
+	0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x61, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, // (_mtl_i.a_texcoo
+	0x72, 0x64, 0x30, 0x20, 0x2b, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x75, 0x5f, 0x68, // rd0 + _mtl_u.u_h
+	0x61, 0x6c, 0x66, 0x54, 0x65, 0x78, 0x65, 0x6c, 0x2e, 0x78, 0x79, 0x29, 0x3b, 0x0a, 0x20, 0x20, // alfTexel.xy);.
+	0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x3b, // float4 tmpvar_1;
+	0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x2e, 0x7a, 0x77, 0x20, 0x3d, // .  tmpvar_1.zw =
+	0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x28, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, //  float2(0.0, 1.0
+	0x29, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x2e, 0x78, 0x20, // );.  tmpvar_1.x
+	0x3d, 0x20, 0x28, 0x28, 0x28, 0x32, 0x2e, 0x30, 0x20, 0x2a, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, // = (((2.0 * _mtl_
+	0x69, 0x2e, 0x61, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x78, 0x29, 0x20, // i.a_position.x)
+	0x2f, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x75, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x53, // / _mtl_u.u_viewS
+	0x69, 0x7a, 0x65, 0x2e, 0x78, 0x29, 0x20, 0x2d, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x20, // ize.x) - 1.0);.
+	0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x2e, 0x79, 0x20, 0x3d, 0x20, 0x28, 0x31, //  tmpvar_1.y = (1
+	0x2e, 0x30, 0x20, 0x2d, 0x20, 0x28, 0x28, 0x32, 0x2e, 0x30, 0x20, 0x2a, 0x20, 0x5f, 0x6d, 0x74, // .0 - ((2.0 * _mt
+	0x6c, 0x5f, 0x69, 0x2e, 0x61, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x79, // l_i.a_position.y
+	0x29, 0x20, 0x2f, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x75, 0x5f, 0x76, 0x69, 0x65, // ) / _mtl_u.u_vie
+	0x77, 0x53, 0x69, 0x7a, 0x65, 0x2e, 0x79, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, // wSize.y));.  _mt
+	0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, // l_o.gl_Position
+	0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x65, // = tmpvar_1;.  re
+	0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, // turn _mtl_o;.}..
+	0x00,                                                                                           // .
+};

+ 42 - 1
src/bgfx.cpp

@@ -330,6 +330,10 @@ namespace bgfx
 			mem = makeRef(vs_debugfont_dx11, sizeof(vs_debugfont_dx11) );
 			break;
 
+		case RendererType::Metal:
+			mem = makeRef(vs_debugfont_mtl, sizeof(vs_debugfont_mtl) );
+			break;
+				
 		default:
 			mem = makeRef(vs_debugfont_glsl, sizeof(vs_debugfont_glsl) );
 			break;
@@ -348,6 +352,10 @@ namespace bgfx
 			mem = makeRef(fs_debugfont_dx11, sizeof(fs_debugfont_dx11) );
 			break;
 
+		case RendererType::Metal:
+			mem = makeRef(fs_debugfont_mtl, sizeof(fs_debugfont_mtl) );
+			break;
+				
 		default:
 			mem = makeRef(fs_debugfont_glsl, sizeof(fs_debugfont_glsl) );
 			break;
@@ -568,6 +576,27 @@ namespace bgfx
 					fragMem[ii] = makeRef(mem[ii].data, uint32_t(mem[ii].size) );
 				}
 			}
+			else if (RendererType::Metal == g_caps.rendererType)
+			{
+				vsh = createShader(makeRef(vs_clear_mtl, sizeof(vs_clear_mtl) ) );
+				
+				const Mem mem[] =
+				{
+					Mem(fs_clear0_mtl, sizeof(fs_clear0_mtl) ),
+					Mem(fs_clear1_mtl, sizeof(fs_clear1_mtl) ),
+					Mem(fs_clear2_mtl, sizeof(fs_clear2_mtl) ),
+					Mem(fs_clear3_mtl, sizeof(fs_clear3_mtl) ),
+					Mem(fs_clear4_mtl, sizeof(fs_clear4_mtl) ),
+					Mem(fs_clear5_mtl, sizeof(fs_clear5_mtl) ),
+					Mem(fs_clear6_mtl, sizeof(fs_clear6_mtl) ),
+					Mem(fs_clear7_mtl, sizeof(fs_clear7_mtl) ),
+				};
+				
+				for (uint32_t ii = 0, num = g_caps.maxFBAttachments; ii < num; ++ii)
+				{
+					fragMem[ii] = makeRef(mem[ii].data, uint32_t(mem[ii].size) );
+				}
+			}
 			else
 			{
 				BGFX_FATAL(false, Fatal::UnableToInitialize, "Unknown renderer type %d", g_caps.rendererType);
@@ -1496,10 +1525,22 @@ again:
 					_type = RendererType::Null;
 				}
 			}
+			else if (BX_ENABLED(0
+				|| BX_PLATFORM_IOS ) )
+			{
+				if (s_rendererCreator[RendererType::Metal].supported)
+				{
+					_type = RendererType::Metal;
+				}
+				else if (s_rendererCreator[RendererType::OpenGLES].supported)
+				{
+					_type = RendererType::OpenGLES;
+				}
+				
+			}
 			else if (BX_ENABLED(0
 				 ||  BX_PLATFORM_ANDROID
 				 ||  BX_PLATFORM_EMSCRIPTEN
-				 ||  BX_PLATFORM_IOS
 				 ||  BX_PLATFORM_NACL
 				 ||  BX_PLATFORM_RPI
 				 ) )

+ 9 - 1
src/config.h

@@ -41,8 +41,11 @@
 					? 1 : 0)
 #	endif // BGFX_CONFIG_RENDERER_DIRECT3D12
 
+	//TODO: should check if iOS8 or greater
 #	ifndef BGFX_CONFIG_RENDERER_METAL
-#		define BGFX_CONFIG_RENDERER_METAL 0
+#		define BGFX_CONFIG_RENDERER_METAL (0 \
+					|| BX_PLATFORM_IOS \
+					? 1 : 0)
 #	endif // BGFX_CONFIG_RENDERER_METAL
 
 #	ifndef BGFX_CONFIG_RENDERER_OPENGL
@@ -156,6 +159,11 @@
 #	define BGFX_CONFIG_DEBUG_OBJECT_NAME BGFX_CONFIG_DEBUG
 #endif // BGFX_CONFIG_DEBUG_OBJECT_NAME
 
+/// Enable Metal markers.
+#ifndef BGFX_CONFIG_DEBUG_MTL
+#	define BGFX_CONFIG_DEBUG_MTL BGFX_CONFIG_DEBUG
+#endif // BGFX_CONFIG_DEBUG_MTL
+
 #ifndef BGFX_CONFIG_MULTITHREADED
 #	define BGFX_CONFIG_MULTITHREADED ( (!BGFX_CONFIG_RENDERER_NULL)&&(0 \
 						|| BX_PLATFORM_ANDROID \

+ 31 - 0
src/fs_clear0.bin.h

@@ -45,3 +45,34 @@ static const uint8_t fs_clear0_dx11[259] =
 	0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x00, // . .........>....
 	0x00, 0x80, 0x00,                                                                               // ...
 };
+static const uint8_t fs_clear0_mtl[432] =
+{
+	0x46, 0x53, 0x48, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x01, 0x00, 0x00, 0x75, 0x73, // FSH...........us
+	0x69, 0x6e, 0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x6d, 0x65, // ing namespace me
+	0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // tal;.struct xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x7b, // MtlShaderInput {
+	0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, // .};.struct xlatM
+	0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x7b, // tlShaderOutput {
+	0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, // .  half4 gl_Frag
+	0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, // Color;.};.struct
+	0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, //  xlatMtlShaderUn
+	0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, // iform {.  float4
+	0x20, 0x62, 0x67, 0x66, 0x78, 0x5f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, //  bgfx_clear_colo
+	0x72, 0x5b, 0x38, 0x5d, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, // r[8];.};.fragmen
+	0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, // t xlatMtlShaderO
+	0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x4d, 0x61, 0x69, // utput xlatMtlMai
+	0x6e, 0x20, 0x28, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, // n (xlatMtlShader
+	0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x20, 0x5b, 0x5b, 0x73, // Input _mtl_i [[s
+	0x74, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x6e, 0x5d, 0x5d, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, // tage_in]], const
+	0x61, 0x6e, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, // ant xlatMtlShade
+	0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x26, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, // rUniform& _mtl_u
+	0x20, 0x5b, 0x5b, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x29, 0x0a, //  [[buffer(0)]]).
+	0x7b, 0x0a, 0x20, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, // {.  xlatMtlShade
+	0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, // rOutput _mtl_o;.
+	0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, //   _mtl_o.gl_Frag
+	0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x28, 0x5f, 0x6d, // Color = half4(_m
+	0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x62, 0x67, 0x66, 0x78, 0x5f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f, // tl_u.bgfx_clear_
+	0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5b, 0x30, 0x5d, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, // color[0]);.  ret
+	0x75, 0x72, 0x6e, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00, // urn _mtl_o;.}...
+};
+

+ 37 - 0
src/fs_clear1.bin.h

@@ -52,3 +52,40 @@ static const uint8_t fs_clear1_dx11[319] =
 	0x00, 0x00, 0x06, 0xf2, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x00, 0x00, // .... ......F. ..
 	0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x00, 0x00, 0x80, 0x00,       // .......>.......
 };
+static const uint8_t fs_clear1_mtl[543] =
+{
+	0x46, 0x53, 0x48, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x75, 0x73, // FSH...........us
+	0x69, 0x6e, 0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x6d, 0x65, // ing namespace me
+	0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // tal;.struct xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x7b, // MtlShaderInput {
+	0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, // .};.struct xlatM
+	0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x7b, // tlShaderOutput {
+	0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, // .  half4 gl_Frag
+	0x44, 0x61, 0x74, 0x61, 0x5f, 0x30, 0x20, 0x5b, 0x5b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x30, // Data_0 [[color(0
+	0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x67, 0x6c, 0x5f, // )]];.  half4 gl_
+	0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x31, 0x20, 0x5b, 0x5b, 0x63, 0x6f, 0x6c, // FragData_1 [[col
+	0x6f, 0x72, 0x28, 0x31, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, // or(1)]];.};.stru
+	0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, // ct xlatMtlShader
+	0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, // Uniform {.  floa
+	0x74, 0x34, 0x20, 0x62, 0x67, 0x66, 0x78, 0x5f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f, 0x63, 0x6f, // t4 bgfx_clear_co
+	0x6c, 0x6f, 0x72, 0x5b, 0x38, 0x5d, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x66, 0x72, 0x61, 0x67, 0x6d, // lor[8];.};.fragm
+	0x65, 0x6e, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, // ent xlatMtlShade
+	0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x4d, // rOutput xlatMtlM
+	0x61, 0x69, 0x6e, 0x20, 0x28, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, // ain (xlatMtlShad
+	0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x20, 0x5b, // erInput _mtl_i [
+	0x5b, 0x73, 0x74, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x6e, 0x5d, 0x5d, 0x2c, 0x20, 0x63, 0x6f, 0x6e, // [stage_in]], con
+	0x73, 0x74, 0x61, 0x6e, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, // stant xlatMtlSha
+	0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x26, 0x20, 0x5f, 0x6d, 0x74, 0x6c, // derUniform& _mtl
+	0x5f, 0x75, 0x20, 0x5b, 0x5b, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x28, 0x30, 0x29, 0x5d, 0x5d, // _u [[buffer(0)]]
+	0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, // ).{.  xlatMtlSha
+	0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, // derOutput _mtl_o
+	0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, // ;.  _mtl_o.gl_Fr
+	0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x30, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, // agData_0 = half4
+	0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x62, 0x67, 0x66, 0x78, 0x5f, 0x63, 0x6c, 0x65, // (_mtl_u.bgfx_cle
+	0x61, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5b, 0x30, 0x5d, 0x29, 0x3b, 0x0a, 0x20, 0x20, // ar_color[0]);.
+	0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, // _mtl_o.gl_FragDa
+	0x74, 0x61, 0x5f, 0x31, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x28, 0x5f, 0x6d, 0x74, // ta_1 = half4(_mt
+	0x6c, 0x5f, 0x75, 0x2e, 0x62, 0x67, 0x66, 0x78, 0x5f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f, 0x63, // l_u.bgfx_clear_c
+	0x6f, 0x6c, 0x6f, 0x72, 0x5b, 0x31, 0x5d, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, // olor[1]);.  retu
+	0x72, 0x6e, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00,       // rn _mtl_o;.}...
+};

+ 43 - 0
src/fs_clear2.bin.h

@@ -60,3 +60,46 @@ static const uint8_t fs_clear2_dx11[379] =
 	0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, //  ......F. ......
 	0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x00, 0x00, 0x80, 0x00,                               // ...>.......
 };
+static const uint8_t fs_clear2_mtl[639] =
+{
+	0x46, 0x53, 0x48, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x02, 0x00, 0x00, 0x75, 0x73, // FSH.......p...us
+	0x69, 0x6e, 0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x6d, 0x65, // ing namespace me
+	0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // tal;.struct xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x7b, // MtlShaderInput {
+	0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, // .};.struct xlatM
+	0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x7b, // tlShaderOutput {
+	0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, // .  half4 gl_Frag
+	0x44, 0x61, 0x74, 0x61, 0x5f, 0x30, 0x20, 0x5b, 0x5b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x30, // Data_0 [[color(0
+	0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x67, 0x6c, 0x5f, // )]];.  half4 gl_
+	0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x31, 0x20, 0x5b, 0x5b, 0x63, 0x6f, 0x6c, // FragData_1 [[col
+	0x6f, 0x72, 0x28, 0x31, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, // or(1)]];.  half4
+	0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x32, 0x20, 0x5b, //  gl_FragData_2 [
+	0x5b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x32, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, // [color(2)]];.};.
+	0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, // struct xlatMtlSh
+	0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x7b, 0x0a, 0x20, 0x20, // aderUniform {.
+	0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x62, 0x67, 0x66, 0x78, 0x5f, 0x63, 0x6c, 0x65, 0x61, // float4 bgfx_clea
+	0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5b, 0x38, 0x5d, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x66, // r_color[8];.};.f
+	0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, // ragment xlatMtlS
+	0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // haderOutput xlat
+	0x4d, 0x74, 0x6c, 0x4d, 0x61, 0x69, 0x6e, 0x20, 0x28, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, // MtlMain (xlatMtl
+	0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, // ShaderInput _mtl
+	0x5f, 0x69, 0x20, 0x5b, 0x5b, 0x73, 0x74, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x6e, 0x5d, 0x5d, 0x2c, // _i [[stage_in]],
+	0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, //  constant xlatMt
+	0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x26, 0x20, // lShaderUniform&
+	0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x20, 0x5b, 0x5b, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x28, // _mtl_u [[buffer(
+	0x30, 0x29, 0x5d, 0x5d, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, // 0)]]).{.  xlatMt
+	0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, // lShaderOutput _m
+	0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, // tl_o;.  _mtl_o.g
+	0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x30, 0x20, 0x3d, 0x20, 0x68, // l_FragData_0 = h
+	0x61, 0x6c, 0x66, 0x34, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x62, 0x67, 0x66, 0x78, // alf4(_mtl_u.bgfx
+	0x5f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5b, 0x30, 0x5d, 0x29, // _clear_color[0])
+	0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, // ;.  _mtl_o.gl_Fr
+	0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x31, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, // agData_1 = half4
+	0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x62, 0x67, 0x66, 0x78, 0x5f, 0x63, 0x6c, 0x65, // (_mtl_u.bgfx_cle
+	0x61, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5b, 0x31, 0x5d, 0x29, 0x3b, 0x0a, 0x20, 0x20, // ar_color[1]);.
+	0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, // _mtl_o.gl_FragDa
+	0x74, 0x61, 0x5f, 0x32, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x28, 0x5f, 0x6d, 0x74, // ta_2 = half4(_mt
+	0x6c, 0x5f, 0x75, 0x2e, 0x62, 0x67, 0x66, 0x78, 0x5f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f, 0x63, // l_u.bgfx_clear_c
+	0x6f, 0x6c, 0x6f, 0x72, 0x5b, 0x32, 0x5d, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, // olor[2]);.  retu
+	0x72, 0x6e, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00,       // rn _mtl_o;.}...
+};

+ 49 - 0
src/fs_clear3.bin.h

@@ -66,3 +66,52 @@ static const uint8_t fs_clear3_dx11[439] =
 	0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3e, // ...F. .........>
 	0x00, 0x00, 0x01, 0x00, 0x00, 0x80, 0x00,                                                       // .......
 };
+static const uint8_t fs_clear3_mtl[735] =
+{
+	0x46, 0x53, 0x48, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x02, 0x00, 0x00, 0x75, 0x73, // FSH...........us
+	0x69, 0x6e, 0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x6d, 0x65, // ing namespace me
+	0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // tal;.struct xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x7b, // MtlShaderInput {
+	0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, // .};.struct xlatM
+	0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x7b, // tlShaderOutput {
+	0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, // .  half4 gl_Frag
+	0x44, 0x61, 0x74, 0x61, 0x5f, 0x30, 0x20, 0x5b, 0x5b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x30, // Data_0 [[color(0
+	0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x67, 0x6c, 0x5f, // )]];.  half4 gl_
+	0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x31, 0x20, 0x5b, 0x5b, 0x63, 0x6f, 0x6c, // FragData_1 [[col
+	0x6f, 0x72, 0x28, 0x31, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, // or(1)]];.  half4
+	0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x32, 0x20, 0x5b, //  gl_FragData_2 [
+	0x5b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x32, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x68, // [color(2)]];.  h
+	0x61, 0x6c, 0x66, 0x34, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, // alf4 gl_FragData
+	0x5f, 0x33, 0x20, 0x5b, 0x5b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x33, 0x29, 0x5d, 0x5d, 0x3b, // _3 [[color(3)]];
+	0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, // .};.struct xlatM
+	0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, // tlShaderUniform
+	0x7b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x62, 0x67, 0x66, 0x78, 0x5f, // {.  float4 bgfx_
+	0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5b, 0x38, 0x5d, 0x3b, 0x0a, // clear_color[8];.
+	0x7d, 0x3b, 0x0a, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // };.fragment xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, // MtlShaderOutput
+	0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x4d, 0x61, 0x69, 0x6e, 0x20, 0x28, 0x78, 0x6c, 0x61, // xlatMtlMain (xla
+	0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, // tMtlShaderInput
+	0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x20, 0x5b, 0x5b, 0x73, 0x74, 0x61, 0x67, 0x65, 0x5f, 0x69, // _mtl_i [[stage_i
+	0x6e, 0x5d, 0x5d, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x20, 0x78, 0x6c, // n]], constant xl
+	0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, // atMtlShaderUnifo
+	0x72, 0x6d, 0x26, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x20, 0x5b, 0x5b, 0x62, 0x75, 0x66, // rm& _mtl_u [[buf
+	0x66, 0x65, 0x72, 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x78, 0x6c, // fer(0)]]).{.  xl
+	0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, // atMtlShaderOutpu
+	0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, // t _mtl_o;.  _mtl
+	0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x30, // _o.gl_FragData_0
+	0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, //  = half4(_mtl_u.
+	0x62, 0x67, 0x66, 0x78, 0x5f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, // bgfx_clear_color
+	0x5b, 0x30, 0x5d, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, // [0]);.  _mtl_o.g
+	0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x31, 0x20, 0x3d, 0x20, 0x68, // l_FragData_1 = h
+	0x61, 0x6c, 0x66, 0x34, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x62, 0x67, 0x66, 0x78, // alf4(_mtl_u.bgfx
+	0x5f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5b, 0x31, 0x5d, 0x29, // _clear_color[1])
+	0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, // ;.  _mtl_o.gl_Fr
+	0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x32, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, // agData_2 = half4
+	0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x62, 0x67, 0x66, 0x78, 0x5f, 0x63, 0x6c, 0x65, // (_mtl_u.bgfx_cle
+	0x61, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5b, 0x32, 0x5d, 0x29, 0x3b, 0x0a, 0x20, 0x20, // ar_color[2]);.
+	0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, // _mtl_o.gl_FragDa
+	0x74, 0x61, 0x5f, 0x33, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x28, 0x5f, 0x6d, 0x74, // ta_3 = half4(_mt
+	0x6c, 0x5f, 0x75, 0x2e, 0x62, 0x67, 0x66, 0x78, 0x5f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f, 0x63, // l_u.bgfx_clear_c
+	0x6f, 0x6c, 0x6f, 0x72, 0x5b, 0x33, 0x5d, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, // olor[3]);.  retu
+	0x72, 0x6e, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00,       // rn _mtl_o;.}...
+};

+ 55 - 0
src/fs_clear4.bin.h

@@ -73,3 +73,58 @@ static const uint8_t fs_clear4_dx11[499] =
 	0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x00, // . .........>....
 	0x00, 0x80, 0x00,                                                                               // ...
 };
+static const uint8_t fs_clear4_mtl[831] =
+{
+	0x46, 0x53, 0x48, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x00, 0x75, 0x73, // FSH.......0...us
+	0x69, 0x6e, 0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x6d, 0x65, // ing namespace me
+	0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // tal;.struct xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x7b, // MtlShaderInput {
+	0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, // .};.struct xlatM
+	0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x7b, // tlShaderOutput {
+	0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, // .  half4 gl_Frag
+	0x44, 0x61, 0x74, 0x61, 0x5f, 0x30, 0x20, 0x5b, 0x5b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x30, // Data_0 [[color(0
+	0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x67, 0x6c, 0x5f, // )]];.  half4 gl_
+	0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x31, 0x20, 0x5b, 0x5b, 0x63, 0x6f, 0x6c, // FragData_1 [[col
+	0x6f, 0x72, 0x28, 0x31, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, // or(1)]];.  half4
+	0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x32, 0x20, 0x5b, //  gl_FragData_2 [
+	0x5b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x32, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x68, // [color(2)]];.  h
+	0x61, 0x6c, 0x66, 0x34, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, // alf4 gl_FragData
+	0x5f, 0x33, 0x20, 0x5b, 0x5b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x33, 0x29, 0x5d, 0x5d, 0x3b, // _3 [[color(3)]];
+	0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, // .  half4 gl_Frag
+	0x44, 0x61, 0x74, 0x61, 0x5f, 0x34, 0x20, 0x5b, 0x5b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x34, // Data_4 [[color(4
+	0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, // )]];.};.struct x
+	0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, // latMtlShaderUnif
+	0x6f, 0x72, 0x6d, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x62, // orm {.  float4 b
+	0x67, 0x66, 0x78, 0x5f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5b, // gfx_clear_color[
+	0x38, 0x5d, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x20, // 8];.};.fragment
+	0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, // xlatMtlShaderOut
+	0x70, 0x75, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x4d, 0x61, 0x69, 0x6e, 0x20, // put xlatMtlMain
+	0x28, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, // (xlatMtlShaderIn
+	0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x20, 0x5b, 0x5b, 0x73, 0x74, 0x61, // put _mtl_i [[sta
+	0x67, 0x65, 0x5f, 0x69, 0x6e, 0x5d, 0x5d, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, // ge_in]], constan
+	0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x55, // t xlatMtlShaderU
+	0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x26, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x20, 0x5b, // niform& _mtl_u [
+	0x5b, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x29, 0x0a, 0x7b, 0x0a, // [buffer(0)]]).{.
+	0x20, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, //   xlatMtlShaderO
+	0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x20, 0x20, // utput _mtl_o;.
+	0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, // _mtl_o.gl_FragDa
+	0x74, 0x61, 0x5f, 0x30, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x28, 0x5f, 0x6d, 0x74, // ta_0 = half4(_mt
+	0x6c, 0x5f, 0x75, 0x2e, 0x62, 0x67, 0x66, 0x78, 0x5f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f, 0x63, // l_u.bgfx_clear_c
+	0x6f, 0x6c, 0x6f, 0x72, 0x5b, 0x30, 0x5d, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, // olor[0]);.  _mtl
+	0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x31, // _o.gl_FragData_1
+	0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, //  = half4(_mtl_u.
+	0x62, 0x67, 0x66, 0x78, 0x5f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, // bgfx_clear_color
+	0x5b, 0x31, 0x5d, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, // [1]);.  _mtl_o.g
+	0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x32, 0x20, 0x3d, 0x20, 0x68, // l_FragData_2 = h
+	0x61, 0x6c, 0x66, 0x34, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x62, 0x67, 0x66, 0x78, // alf4(_mtl_u.bgfx
+	0x5f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5b, 0x32, 0x5d, 0x29, // _clear_color[2])
+	0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, // ;.  _mtl_o.gl_Fr
+	0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x33, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, // agData_3 = half4
+	0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x62, 0x67, 0x66, 0x78, 0x5f, 0x63, 0x6c, 0x65, // (_mtl_u.bgfx_cle
+	0x61, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5b, 0x33, 0x5d, 0x29, 0x3b, 0x0a, 0x20, 0x20, // ar_color[3]);.
+	0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, // _mtl_o.gl_FragDa
+	0x74, 0x61, 0x5f, 0x34, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x28, 0x5f, 0x6d, 0x74, // ta_4 = half4(_mt
+	0x6c, 0x5f, 0x75, 0x2e, 0x62, 0x67, 0x66, 0x78, 0x5f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f, 0x63, // l_u.bgfx_clear_c
+	0x6f, 0x6c, 0x6f, 0x72, 0x5b, 0x34, 0x5d, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, // olor[4]);.  retu
+	0x72, 0x6e, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00,       // rn _mtl_o;.}...
+};

+ 61 - 0
src/fs_clear5.bin.h

@@ -78,3 +78,64 @@ static const uint8_t fs_clear5_dx11[559] =
 	0x00, 0x00, 0x06, 0xf2, 0x20, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x00, 0x00, // .... ......F. ..
 	0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x00, 0x00, 0x80, 0x00,       // .......>.......
 };
+static const uint8_t fs_clear5_mtl[927] =
+{
+	0x46, 0x53, 0x48, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x03, 0x00, 0x00, 0x75, 0x73, // FSH...........us
+	0x69, 0x6e, 0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x6d, 0x65, // ing namespace me
+	0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // tal;.struct xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x7b, // MtlShaderInput {
+	0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, // .};.struct xlatM
+	0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x7b, // tlShaderOutput {
+	0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, // .  half4 gl_Frag
+	0x44, 0x61, 0x74, 0x61, 0x5f, 0x30, 0x20, 0x5b, 0x5b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x30, // Data_0 [[color(0
+	0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x67, 0x6c, 0x5f, // )]];.  half4 gl_
+	0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x31, 0x20, 0x5b, 0x5b, 0x63, 0x6f, 0x6c, // FragData_1 [[col
+	0x6f, 0x72, 0x28, 0x31, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, // or(1)]];.  half4
+	0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x32, 0x20, 0x5b, //  gl_FragData_2 [
+	0x5b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x32, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x68, // [color(2)]];.  h
+	0x61, 0x6c, 0x66, 0x34, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, // alf4 gl_FragData
+	0x5f, 0x33, 0x20, 0x5b, 0x5b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x33, 0x29, 0x5d, 0x5d, 0x3b, // _3 [[color(3)]];
+	0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, // .  half4 gl_Frag
+	0x44, 0x61, 0x74, 0x61, 0x5f, 0x34, 0x20, 0x5b, 0x5b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x34, // Data_4 [[color(4
+	0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x67, 0x6c, 0x5f, // )]];.  half4 gl_
+	0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x35, 0x20, 0x5b, 0x5b, 0x63, 0x6f, 0x6c, // FragData_5 [[col
+	0x6f, 0x72, 0x28, 0x35, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, // or(5)]];.};.stru
+	0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, // ct xlatMtlShader
+	0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, // Uniform {.  floa
+	0x74, 0x34, 0x20, 0x62, 0x67, 0x66, 0x78, 0x5f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f, 0x63, 0x6f, // t4 bgfx_clear_co
+	0x6c, 0x6f, 0x72, 0x5b, 0x38, 0x5d, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x66, 0x72, 0x61, 0x67, 0x6d, // lor[8];.};.fragm
+	0x65, 0x6e, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, // ent xlatMtlShade
+	0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x4d, // rOutput xlatMtlM
+	0x61, 0x69, 0x6e, 0x20, 0x28, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, // ain (xlatMtlShad
+	0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x20, 0x5b, // erInput _mtl_i [
+	0x5b, 0x73, 0x74, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x6e, 0x5d, 0x5d, 0x2c, 0x20, 0x63, 0x6f, 0x6e, // [stage_in]], con
+	0x73, 0x74, 0x61, 0x6e, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, // stant xlatMtlSha
+	0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x26, 0x20, 0x5f, 0x6d, 0x74, 0x6c, // derUniform& _mtl
+	0x5f, 0x75, 0x20, 0x5b, 0x5b, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x28, 0x30, 0x29, 0x5d, 0x5d, // _u [[buffer(0)]]
+	0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, // ).{.  xlatMtlSha
+	0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, // derOutput _mtl_o
+	0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, // ;.  _mtl_o.gl_Fr
+	0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x30, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, // agData_0 = half4
+	0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x62, 0x67, 0x66, 0x78, 0x5f, 0x63, 0x6c, 0x65, // (_mtl_u.bgfx_cle
+	0x61, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5b, 0x30, 0x5d, 0x29, 0x3b, 0x0a, 0x20, 0x20, // ar_color[0]);.
+	0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, // _mtl_o.gl_FragDa
+	0x74, 0x61, 0x5f, 0x31, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x28, 0x5f, 0x6d, 0x74, // ta_1 = half4(_mt
+	0x6c, 0x5f, 0x75, 0x2e, 0x62, 0x67, 0x66, 0x78, 0x5f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f, 0x63, // l_u.bgfx_clear_c
+	0x6f, 0x6c, 0x6f, 0x72, 0x5b, 0x31, 0x5d, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, // olor[1]);.  _mtl
+	0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x32, // _o.gl_FragData_2
+	0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, //  = half4(_mtl_u.
+	0x62, 0x67, 0x66, 0x78, 0x5f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, // bgfx_clear_color
+	0x5b, 0x32, 0x5d, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, // [2]);.  _mtl_o.g
+	0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x33, 0x20, 0x3d, 0x20, 0x68, // l_FragData_3 = h
+	0x61, 0x6c, 0x66, 0x34, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x62, 0x67, 0x66, 0x78, // alf4(_mtl_u.bgfx
+	0x5f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5b, 0x33, 0x5d, 0x29, // _clear_color[3])
+	0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, // ;.  _mtl_o.gl_Fr
+	0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x34, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, // agData_4 = half4
+	0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x62, 0x67, 0x66, 0x78, 0x5f, 0x63, 0x6c, 0x65, // (_mtl_u.bgfx_cle
+	0x61, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5b, 0x34, 0x5d, 0x29, 0x3b, 0x0a, 0x20, 0x20, // ar_color[4]);.
+	0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, // _mtl_o.gl_FragDa
+	0x74, 0x61, 0x5f, 0x35, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x28, 0x5f, 0x6d, 0x74, // ta_5 = half4(_mt
+	0x6c, 0x5f, 0x75, 0x2e, 0x62, 0x67, 0x66, 0x78, 0x5f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f, 0x63, // l_u.bgfx_clear_c
+	0x6f, 0x6c, 0x6f, 0x72, 0x5b, 0x35, 0x5d, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, // olor[5]);.  retu
+	0x72, 0x6e, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00,       // rn _mtl_o;.}...
+};

+ 67 - 0
src/fs_clear6.bin.h

@@ -85,3 +85,70 @@ static const uint8_t fs_clear6_dx11[619] =
 	0x20, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, //  ......F. ......
 	0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x00, 0x00, 0x80, 0x00,                               // ...>.......
 };
+static const uint8_t fs_clear6_mtl[1023] =
+{
+	0x46, 0x53, 0x48, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x75, 0x73, // FSH...........us
+	0x69, 0x6e, 0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x6d, 0x65, // ing namespace me
+	0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // tal;.struct xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x7b, // MtlShaderInput {
+	0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, // .};.struct xlatM
+	0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x7b, // tlShaderOutput {
+	0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, // .  half4 gl_Frag
+	0x44, 0x61, 0x74, 0x61, 0x5f, 0x30, 0x20, 0x5b, 0x5b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x30, // Data_0 [[color(0
+	0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x67, 0x6c, 0x5f, // )]];.  half4 gl_
+	0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x31, 0x20, 0x5b, 0x5b, 0x63, 0x6f, 0x6c, // FragData_1 [[col
+	0x6f, 0x72, 0x28, 0x31, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, // or(1)]];.  half4
+	0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x32, 0x20, 0x5b, //  gl_FragData_2 [
+	0x5b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x32, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x68, // [color(2)]];.  h
+	0x61, 0x6c, 0x66, 0x34, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, // alf4 gl_FragData
+	0x5f, 0x33, 0x20, 0x5b, 0x5b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x33, 0x29, 0x5d, 0x5d, 0x3b, // _3 [[color(3)]];
+	0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, // .  half4 gl_Frag
+	0x44, 0x61, 0x74, 0x61, 0x5f, 0x34, 0x20, 0x5b, 0x5b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x34, // Data_4 [[color(4
+	0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x67, 0x6c, 0x5f, // )]];.  half4 gl_
+	0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x35, 0x20, 0x5b, 0x5b, 0x63, 0x6f, 0x6c, // FragData_5 [[col
+	0x6f, 0x72, 0x28, 0x35, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, // or(5)]];.  half4
+	0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x36, 0x20, 0x5b, //  gl_FragData_6 [
+	0x5b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x36, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, // [color(6)]];.};.
+	0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, // struct xlatMtlSh
+	0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x7b, 0x0a, 0x20, 0x20, // aderUniform {.
+	0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x62, 0x67, 0x66, 0x78, 0x5f, 0x63, 0x6c, 0x65, 0x61, // float4 bgfx_clea
+	0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5b, 0x38, 0x5d, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x66, // r_color[8];.};.f
+	0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, // ragment xlatMtlS
+	0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // haderOutput xlat
+	0x4d, 0x74, 0x6c, 0x4d, 0x61, 0x69, 0x6e, 0x20, 0x28, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, // MtlMain (xlatMtl
+	0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, // ShaderInput _mtl
+	0x5f, 0x69, 0x20, 0x5b, 0x5b, 0x73, 0x74, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x6e, 0x5d, 0x5d, 0x2c, // _i [[stage_in]],
+	0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, //  constant xlatMt
+	0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x26, 0x20, // lShaderUniform&
+	0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x20, 0x5b, 0x5b, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x28, // _mtl_u [[buffer(
+	0x30, 0x29, 0x5d, 0x5d, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, // 0)]]).{.  xlatMt
+	0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, // lShaderOutput _m
+	0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, // tl_o;.  _mtl_o.g
+	0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x30, 0x20, 0x3d, 0x20, 0x68, // l_FragData_0 = h
+	0x61, 0x6c, 0x66, 0x34, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x62, 0x67, 0x66, 0x78, // alf4(_mtl_u.bgfx
+	0x5f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5b, 0x30, 0x5d, 0x29, // _clear_color[0])
+	0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, // ;.  _mtl_o.gl_Fr
+	0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x31, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, // agData_1 = half4
+	0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x62, 0x67, 0x66, 0x78, 0x5f, 0x63, 0x6c, 0x65, // (_mtl_u.bgfx_cle
+	0x61, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5b, 0x31, 0x5d, 0x29, 0x3b, 0x0a, 0x20, 0x20, // ar_color[1]);.
+	0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, // _mtl_o.gl_FragDa
+	0x74, 0x61, 0x5f, 0x32, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x28, 0x5f, 0x6d, 0x74, // ta_2 = half4(_mt
+	0x6c, 0x5f, 0x75, 0x2e, 0x62, 0x67, 0x66, 0x78, 0x5f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f, 0x63, // l_u.bgfx_clear_c
+	0x6f, 0x6c, 0x6f, 0x72, 0x5b, 0x32, 0x5d, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, // olor[2]);.  _mtl
+	0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x33, // _o.gl_FragData_3
+	0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, //  = half4(_mtl_u.
+	0x62, 0x67, 0x66, 0x78, 0x5f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, // bgfx_clear_color
+	0x5b, 0x33, 0x5d, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, // [3]);.  _mtl_o.g
+	0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x34, 0x20, 0x3d, 0x20, 0x68, // l_FragData_4 = h
+	0x61, 0x6c, 0x66, 0x34, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x62, 0x67, 0x66, 0x78, // alf4(_mtl_u.bgfx
+	0x5f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5b, 0x34, 0x5d, 0x29, // _clear_color[4])
+	0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, // ;.  _mtl_o.gl_Fr
+	0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x35, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, // agData_5 = half4
+	0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x62, 0x67, 0x66, 0x78, 0x5f, 0x63, 0x6c, 0x65, // (_mtl_u.bgfx_cle
+	0x61, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5b, 0x35, 0x5d, 0x29, 0x3b, 0x0a, 0x20, 0x20, // ar_color[5]);.
+	0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, // _mtl_o.gl_FragDa
+	0x74, 0x61, 0x5f, 0x36, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x28, 0x5f, 0x6d, 0x74, // ta_6 = half4(_mt
+	0x6c, 0x5f, 0x75, 0x2e, 0x62, 0x67, 0x66, 0x78, 0x5f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f, 0x63, // l_u.bgfx_clear_c
+	0x6f, 0x6c, 0x6f, 0x72, 0x5b, 0x36, 0x5d, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, // olor[6]);.  retu
+	0x72, 0x6e, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00,       // rn _mtl_o;.}...
+};

+ 73 - 0
src/fs_clear7.bin.h

@@ -91,3 +91,76 @@ static const uint8_t fs_clear7_dx11[679] =
 	0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3e, // ...F. .........>
 	0x00, 0x00, 0x01, 0x00, 0x00, 0x80, 0x00,                                                       // .......
 };
+static const uint8_t fs_clear7_mtl[1119] =
+{
+	0x46, 0x53, 0x48, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x04, 0x00, 0x00, 0x75, 0x73, // FSH.......P...us
+	0x69, 0x6e, 0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x6d, 0x65, // ing namespace me
+	0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // tal;.struct xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x7b, // MtlShaderInput {
+	0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, // .};.struct xlatM
+	0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x7b, // tlShaderOutput {
+	0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, // .  half4 gl_Frag
+	0x44, 0x61, 0x74, 0x61, 0x5f, 0x30, 0x20, 0x5b, 0x5b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x30, // Data_0 [[color(0
+	0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x67, 0x6c, 0x5f, // )]];.  half4 gl_
+	0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x31, 0x20, 0x5b, 0x5b, 0x63, 0x6f, 0x6c, // FragData_1 [[col
+	0x6f, 0x72, 0x28, 0x31, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, // or(1)]];.  half4
+	0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x32, 0x20, 0x5b, //  gl_FragData_2 [
+	0x5b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x32, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x68, // [color(2)]];.  h
+	0x61, 0x6c, 0x66, 0x34, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, // alf4 gl_FragData
+	0x5f, 0x33, 0x20, 0x5b, 0x5b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x33, 0x29, 0x5d, 0x5d, 0x3b, // _3 [[color(3)]];
+	0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, // .  half4 gl_Frag
+	0x44, 0x61, 0x74, 0x61, 0x5f, 0x34, 0x20, 0x5b, 0x5b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x34, // Data_4 [[color(4
+	0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x20, 0x67, 0x6c, 0x5f, // )]];.  half4 gl_
+	0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x35, 0x20, 0x5b, 0x5b, 0x63, 0x6f, 0x6c, // FragData_5 [[col
+	0x6f, 0x72, 0x28, 0x35, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, // or(5)]];.  half4
+	0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x36, 0x20, 0x5b, //  gl_FragData_6 [
+	0x5b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x36, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x68, // [color(6)]];.  h
+	0x61, 0x6c, 0x66, 0x34, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, // alf4 gl_FragData
+	0x5f, 0x37, 0x20, 0x5b, 0x5b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x37, 0x29, 0x5d, 0x5d, 0x3b, // _7 [[color(7)]];
+	0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, // .};.struct xlatM
+	0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, // tlShaderUniform
+	0x7b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x62, 0x67, 0x66, 0x78, 0x5f, // {.  float4 bgfx_
+	0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5b, 0x38, 0x5d, 0x3b, 0x0a, // clear_color[8];.
+	0x7d, 0x3b, 0x0a, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // };.fragment xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, // MtlShaderOutput
+	0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x4d, 0x61, 0x69, 0x6e, 0x20, 0x28, 0x78, 0x6c, 0x61, // xlatMtlMain (xla
+	0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, // tMtlShaderInput
+	0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x20, 0x5b, 0x5b, 0x73, 0x74, 0x61, 0x67, 0x65, 0x5f, 0x69, // _mtl_i [[stage_i
+	0x6e, 0x5d, 0x5d, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x20, 0x78, 0x6c, // n]], constant xl
+	0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, // atMtlShaderUnifo
+	0x72, 0x6d, 0x26, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x20, 0x5b, 0x5b, 0x62, 0x75, 0x66, // rm& _mtl_u [[buf
+	0x66, 0x65, 0x72, 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x78, 0x6c, // fer(0)]]).{.  xl
+	0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, // atMtlShaderOutpu
+	0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, // t _mtl_o;.  _mtl
+	0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x30, // _o.gl_FragData_0
+	0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, //  = half4(_mtl_u.
+	0x62, 0x67, 0x66, 0x78, 0x5f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, // bgfx_clear_color
+	0x5b, 0x30, 0x5d, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, // [0]);.  _mtl_o.g
+	0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x31, 0x20, 0x3d, 0x20, 0x68, // l_FragData_1 = h
+	0x61, 0x6c, 0x66, 0x34, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x62, 0x67, 0x66, 0x78, // alf4(_mtl_u.bgfx
+	0x5f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5b, 0x31, 0x5d, 0x29, // _clear_color[1])
+	0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, // ;.  _mtl_o.gl_Fr
+	0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x32, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, // agData_2 = half4
+	0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x62, 0x67, 0x66, 0x78, 0x5f, 0x63, 0x6c, 0x65, // (_mtl_u.bgfx_cle
+	0x61, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5b, 0x32, 0x5d, 0x29, 0x3b, 0x0a, 0x20, 0x20, // ar_color[2]);.
+	0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, // _mtl_o.gl_FragDa
+	0x74, 0x61, 0x5f, 0x33, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x28, 0x5f, 0x6d, 0x74, // ta_3 = half4(_mt
+	0x6c, 0x5f, 0x75, 0x2e, 0x62, 0x67, 0x66, 0x78, 0x5f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f, 0x63, // l_u.bgfx_clear_c
+	0x6f, 0x6c, 0x6f, 0x72, 0x5b, 0x33, 0x5d, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, // olor[3]);.  _mtl
+	0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x34, // _o.gl_FragData_4
+	0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, //  = half4(_mtl_u.
+	0x62, 0x67, 0x66, 0x78, 0x5f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, // bgfx_clear_color
+	0x5b, 0x34, 0x5d, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, // [4]);.  _mtl_o.g
+	0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x35, 0x20, 0x3d, 0x20, 0x68, // l_FragData_5 = h
+	0x61, 0x6c, 0x66, 0x34, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x62, 0x67, 0x66, 0x78, // alf4(_mtl_u.bgfx
+	0x5f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5b, 0x35, 0x5d, 0x29, // _clear_color[5])
+	0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, // ;.  _mtl_o.gl_Fr
+	0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5f, 0x36, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, // agData_6 = half4
+	0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x2e, 0x62, 0x67, 0x66, 0x78, 0x5f, 0x63, 0x6c, 0x65, // (_mtl_u.bgfx_cle
+	0x61, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5b, 0x36, 0x5d, 0x29, 0x3b, 0x0a, 0x20, 0x20, // ar_color[6]);.
+	0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, // _mtl_o.gl_FragDa
+	0x74, 0x61, 0x5f, 0x37, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6c, 0x66, 0x34, 0x28, 0x5f, 0x6d, 0x74, // ta_7 = half4(_mt
+	0x6c, 0x5f, 0x75, 0x2e, 0x62, 0x67, 0x66, 0x78, 0x5f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f, 0x63, // l_u.bgfx_clear_c
+	0x6f, 0x6c, 0x6f, 0x72, 0x5b, 0x37, 0x5d, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, // olor[7]);.  retu
+	0x72, 0x6e, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00,       // rn _mtl_o;.}...
+};

+ 52 - 0
src/fs_debugfont.bin.h

@@ -86,3 +86,55 @@ static const uint8_t fs_debugfont_dx11[520] =
 	0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, // . ......F.......
 	0x3e, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,                                                 // >.......
 };
+static const uint8_t fs_debugfont_mtl[762] =
+{
+	0x46, 0x53, 0x48, 0x04, 0xb8, 0xbe, 0x22, 0x66, 0x00, 0x00, 0xeb, 0x02, 0x00, 0x00, 0x75, 0x73, // FSH..."f......us
+	0x69, 0x6e, 0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x6d, 0x65, // ing namespace me
+	0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // tal;.struct xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x7b, // MtlShaderInput {
+	0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, // .  float4 v_colo
+	0x72, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x76, 0x5f, 0x63, // r0;.  float4 v_c
+	0x6f, 0x6c, 0x6f, 0x72, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, // olor1;.  float2
+	0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, // v_texcoord0;.};.
+	0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, // struct xlatMtlSh
+	0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x68, // aderOutput {.  h
+	0x61, 0x6c, 0x66, 0x34, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, // alf4 gl_FragColo
+	0x72, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, // r;.};.struct xla
+	0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, // tMtlShaderUnifor
+	0x6d, 0x20, 0x7b, 0x0a, 0x7d, 0x3b, 0x0a, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x20, // m {.};.fragment
+	0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, // xlatMtlShaderOut
+	0x70, 0x75, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x4d, 0x61, 0x69, 0x6e, 0x20, // put xlatMtlMain
+	0x28, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, // (xlatMtlShaderIn
+	0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x20, 0x5b, 0x5b, 0x73, 0x74, 0x61, // put _mtl_i [[sta
+	0x67, 0x65, 0x5f, 0x69, 0x6e, 0x5d, 0x5d, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, // ge_in]], constan
+	0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x55, // t xlatMtlShaderU
+	0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x26, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x20, 0x5b, // niform& _mtl_u [
+	0x5b, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x0a, 0x20, 0x20, 0x2c, // [buffer(0)]].  ,
+	0x20, 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x64, 0x3c, 0x66, 0x6c, 0x6f, //    texture2d<flo
+	0x61, 0x74, 0x3e, 0x20, 0x73, 0x5f, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x5b, // at> s_texColor [
+	0x5b, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x2c, 0x20, 0x73, // [texture(0)]], s
+	0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x73, 0x6d, 0x70, 0x5f, 0x73, // ampler _mtlsmp_s
+	0x5f, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x5b, 0x5b, 0x73, 0x61, 0x6d, 0x70, // _texColor [[samp
+	0x6c, 0x65, 0x72, 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x78, 0x6c, // ler(0)]]).{.  xl
+	0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, // atMtlShaderOutpu
+	0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x20, 0x20, 0x68, 0x61, 0x6c, 0x66, // t _mtl_o;.  half
+	0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, // 4 tmpvar_1;.  tm
+	0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x20, 0x3d, 0x20, 0x28, 0x28, 0x68, 0x61, 0x6c, 0x66, 0x34, // pvar_1 = ((half4
+	0x29, 0x6d, 0x69, 0x78, 0x20, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x76, 0x5f, 0x63, // )mix (_mtl_i.v_c
+	0x6f, 0x6c, 0x6f, 0x72, 0x31, 0x2c, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x76, 0x5f, // olor1, _mtl_i.v_
+	0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x2c, 0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x29, // color0, (float4)
+	0x73, 0x5f, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, // s_texColor.sampl
+	0x65, 0x28, 0x5f, 0x6d, 0x74, 0x6c, 0x73, 0x6d, 0x70, 0x5f, 0x73, 0x5f, 0x74, 0x65, 0x78, 0x43, // e(_mtlsmp_s_texC
+	0x6f, 0x6c, 0x6f, 0x72, 0x2c, 0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x29, 0x28, 0x5f, // olor, (float2)(_
+	0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, // mtl_i.v_texcoord
+	0x30, 0x29, 0x29, 0x2e, 0x78, 0x78, 0x78, 0x78, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x69, 0x66, // 0)).xxxx));.  if
+	0x20, 0x28, 0x28, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x2e, 0x77, 0x20, 0x3c, 0x20, //  ((tmpvar_1.w <
+	0x28, 0x68, 0x61, 0x6c, 0x66, 0x29, 0x30, 0x2e, 0x30, 0x30, 0x33, 0x39, 0x32, 0x31, 0x35, 0x36, // (half)0.00392156
+	0x39, 0x29, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, // 9)) {.    discar
+	0x64, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x29, 0x3b, 0x0a, 0x20, 0x20, // d_fragment();.
+	0x7d, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x46, // };.  _mtl_o.gl_F
+	0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, // ragColor = tmpva
+	0x72, 0x5f, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x6d, // r_1;.  return _m
+	0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00,                                     // tl_o;.}...
+};
+

+ 468 - 0
src/renderer_mtl.h

@@ -0,0 +1,468 @@
+/*
+ * Copyright 2011-2015 Attila Kocsis, Branimir Karadzic. All rights reserved.
+ * License: http://www.opensource.org/licenses/BSD-2-Clause
+ */
+
+#ifndef BGFX_RENDERER_METAL_H_HEADER_GUARD
+#define BGFX_RENDERER_METAL_H_HEADER_GUARD
+
+#include "bgfx_p.h"
+
+#if BGFX_CONFIG_RENDERER_METAL
+
+#import <QuartzCore/CAMetalLayer.h>
+#import <Metal/Metal.h>
+#ifdef BX_PLATFORM_IOS
+#import <UIKit/UIKit.h>
+#endif
+
+namespace bgfx { namespace mtl
+{
+		//c++ wrapper
+		// objects with creation functions starting with 'new' has a refcount 1 after creation, object must be destroyed with release.
+		// commandBuffer, commandEncoders are autoreleased objects. Needs AutoreleasePool!
+	
+#define MTL_CLASS(name)	\
+	class name \
+	{ \
+	public: \
+		name(id <MTL##name> _obj = nil) : m_obj(_obj) {} \
+		operator id <MTL##name>() const { return m_obj; } \
+		id <MTL##name> m_obj;
+#define MTL_CLASS_END };
+		
+		typedef void (*mtlCallback)(void* userData);
+	
+		//TODO: ??MTLBlitCommandEncoder??
+	MTL_CLASS(Buffer)
+		void* contents() { return m_obj.contents; }
+		uint32_t length() { return (uint32_t)m_obj.length; }
+	MTL_CLASS_END
+		
+	MTL_CLASS(CommandBuffer)
+		// Creating Command Encoders
+		id<MTLRenderCommandEncoder> renderCommandEncoderWithDescriptor( MTLRenderPassDescriptor *_renderPassDescriptor){
+			return [m_obj renderCommandEncoderWithDescriptor:_renderPassDescriptor];
+		}
+		id<MTLComputeCommandEncoder> computeCommandEncoder() { return [m_obj computeCommandEncoder]; }
+		
+		// Scheduling and Executing Commands
+		void enqueue() { [m_obj enqueue]; }
+		void commit() { [m_obj commit]; }
+		void addCompletedHandler(mtlCallback _cb, void* _data) { [m_obj addCompletedHandler:^(id <MTLCommandBuffer> cmdb){ _cb(_data); }]; }
+		void presentDrawable(id<MTLDrawable> _drawable) { [m_obj presentDrawable:_drawable]; }
+		void waitUntilCompleted() { [m_obj waitUntilCompleted]; }
+	MTL_CLASS_END
+		
+	MTL_CLASS(CommandQueue)
+		id<MTLCommandBuffer> commandBuffer() { return [m_obj commandBuffer]; }
+		id<MTLCommandBuffer> commandBufferWithUnretainedReferences() { return [m_obj commandBufferWithUnretainedReferences]; }
+	MTL_CLASS_END
+		
+	MTL_CLASS(ComputeCommandEncoder)
+		void setComputePipelineState(id<MTLComputePipelineState> _state) { [m_obj setComputePipelineState:_state]; }
+		
+		void setBuffer(id<MTLBuffer> _buffer, NSUInteger _offset, NSUInteger _index) { [m_obj setBuffer:_buffer offset:_offset atIndex:_index]; }
+		
+		void setTexture(id<MTLTexture> _texture, NSUInteger _index) { [m_obj setTexture:_texture atIndex:_index]; }
+	
+		void setSamplerState(id<MTLSamplerState> _sampler, NSUInteger _index) { [m_obj setSamplerState:_sampler atIndex:_index]; }
+		
+		void endEncoding() {[m_obj endEncoding] ;}
+	MTL_CLASS_END
+		
+	MTL_CLASS(Device)
+		bool supportsFeatureSet(MTLFeatureSet _featureSet) { return [m_obj supportsFeatureSet:_featureSet]; }
+		
+		id<MTLLibrary> newLibraryWithData(const void* _data) {
+			NSError* error;
+			id<MTLLibrary> lib =  [m_obj newLibraryWithData:(dispatch_data_t)_data error:&error];
+			BX_WARN(error==NULL,"newLibraryWithData failed:%s", [error.localizedDescription UTF8String] );
+			return lib;
+		}
+		id<MTLLibrary> newLibraryWithSource(const char* _source) {
+			NSError* error;
+			id<MTLLibrary> lib = [m_obj newLibraryWithSource:@(_source) options:nil error:&error];
+			if (error!=nil) NSLog(@"Shader compilation failed:%@", error.localizedDescription);
+			//TODO: sometimes prints null as paremeter. string is too large
+ 			BX_WARN(error==NULL,"Shader compilation failed:%s", [error.localizedDescription UTF8String]);
+			return lib;
+		}
+	
+		id<MTLCommandQueue> newCommandQueue() { return [m_obj newCommandQueue]; }
+		id<MTLCommandQueue> newCommandQueueWithMaxCommandBufferCount(NSUInteger _maxCommandBufferCount) { return [m_obj newCommandQueueWithMaxCommandBufferCount:_maxCommandBufferCount]; }
+		
+		// Creating Resources
+		id<MTLBuffer> newBufferWithLength(unsigned int _length, MTLResourceOptions _options) { return [m_obj newBufferWithLength:_length options:_options ]; }
+		id<MTLBuffer> newBufferWithBytes(const void *_pointer, NSUInteger _length, MTLResourceOptions _options) { return [m_obj newBufferWithBytes:_pointer length:_length options:_options]; }
+	
+		id<MTLTexture> newTextureWithDescriptor(MTLTextureDescriptor * _descriptor) { return [m_obj newTextureWithDescriptor:_descriptor]; }
+		id<MTLSamplerState> newSamplerStateWithDescriptor(MTLSamplerDescriptor * _descriptor) { return [m_obj newSamplerStateWithDescriptor:_descriptor]; }
+		
+		// Creating Command Objects Needed to Render Graphics
+		id<MTLDepthStencilState> newDepthStencilStateWithDescriptor(MTLDepthStencilDescriptor * _descriptor) { return [m_obj newDepthStencilStateWithDescriptor:_descriptor]; }
+		
+		id <MTLRenderPipelineState> newRenderPipelineStateWithDescriptor(MTLRenderPipelineDescriptor *_descriptor)
+		{
+			NSError *error;
+			id <MTLRenderPipelineState> state = [m_obj newRenderPipelineStateWithDescriptor:_descriptor error:&error];
+			BX_WARN(error==NULL,"newRenderPipelineStateWithDescriptor failed:%s", [error.localizedDescription UTF8String] );
+			return state;
+		}
+	
+		id <MTLRenderPipelineState> newRenderPipelineStateWithDescriptor(MTLRenderPipelineDescriptor *_descriptor, MTLPipelineOption _options, MTLRenderPipelineReflection** _reflection)
+		{
+			NSError *error;
+			id <MTLRenderPipelineState> state = [m_obj newRenderPipelineStateWithDescriptor:_descriptor options:_options reflection:_reflection error:&error];
+
+			BX_WARN(error==NULL,"newRenderPipelineStateWithDescriptor failed:%s", [error.localizedDescription UTF8String] );
+			return state;
+		}
+	
+		// Creating Command Objects Needed to Perform Computational Tasks
+		id <MTLComputePipelineState> newComputePipelineStateWithFunction(id <MTLFunction> _computeFunction)
+		{
+			NSError *error;
+			id <MTLComputePipelineState> state = [m_obj newComputePipelineStateWithFunction:_computeFunction error:&error];
+			BX_WARN(error==NULL,"newComputePipelineStateWithFunction failed:%s", [error.localizedDescription UTF8String] );
+			return state;
+		}
+	MTL_CLASS_END
+		
+	MTL_CLASS(Function)
+		NSArray *vertexAttributes() { return m_obj.vertexAttributes; }
+	MTL_CLASS_END
+		
+	MTL_CLASS(Library)
+		id <MTLFunction> newFunctionWithName(const char* _functionName) { return [m_obj newFunctionWithName:@(_functionName)]; }
+	MTL_CLASS_END
+		
+	MTL_CLASS(RenderCommandEncoder)
+		// Setting Graphics Rendering State
+		void setBlendColor(float _red, float _green, float _blue, float _alpha) { [m_obj setBlendColorRed:_red green:_green blue:_blue alpha:_alpha]; }
+		void setCullMode(MTLCullMode _cullMode) { [m_obj setCullMode:_cullMode]; }
+		void setDepthBias(float _depthBias, float _slopeScale, float _clamp) { [m_obj setDepthBias:_depthBias slopeScale:_slopeScale clamp:_clamp]; }
+		void setDepthStencilState(id<MTLDepthStencilState> _depthStencilState) { [m_obj setDepthStencilState:_depthStencilState];}
+		void setFrontFacingWinding(MTLWinding _frontFacingWinding) { [m_obj setFrontFacingWinding:_frontFacingWinding]; }
+		void setRenderPipelineState(id<MTLRenderPipelineState> _pipelineState) { [m_obj setRenderPipelineState:_pipelineState]; }
+		void setScissorRect(MTLScissorRect _rect) { [m_obj setScissorRect:_rect]; }
+		void setStencilReferenceValue(uint32_t _ref) { [m_obj setStencilReferenceValue:_ref]; }
+		void setTriangleFillMode(MTLTriangleFillMode _fillMode) { [m_obj setTriangleFillMode:_fillMode]; }
+		void setViewport(MTLViewport _viewport) { [m_obj setViewport:_viewport]; }
+		void setVisibilityResultMode(MTLVisibilityResultMode _mode, NSUInteger _offset) { [m_obj setVisibilityResultMode:_mode offset:_offset]; }
+		
+		// Specifying Resources for a Vertex Function
+		void setVertexBuffer(id<MTLBuffer> _buffer, NSUInteger _offset, NSUInteger _index) { [m_obj setVertexBuffer:_buffer offset:_offset atIndex:_index]; }
+		void setVertexSamplerState(id<MTLSamplerState> _sampler, NSUInteger _index) { [m_obj setVertexSamplerState:_sampler atIndex:_index]; }
+		void setVertexTexture(id<MTLTexture> _texture, NSUInteger _index) { [m_obj setVertexTexture:_texture atIndex:_index]; }
+		
+		// Specifying Resources for a Fragment Function
+		void setFragmentBuffer(id<MTLBuffer> _buffer, NSUInteger _offset, NSUInteger _index) { [m_obj setFragmentBuffer:_buffer offset:_offset atIndex:_index]; }
+		void setFragmentSamplerState(id<MTLSamplerState> _sampler, NSUInteger _index) { [m_obj setFragmentSamplerState:_sampler atIndex:_index]; }
+		void setFragmentTexture(id<MTLTexture> _texture, NSUInteger _index) { [m_obj setFragmentTexture:_texture atIndex:_index]; }
+		
+		//Drawing Geometric Primitives
+		//NOTE: not exposing functions without instanceCount, it seems they are just wrappers
+		void drawIndexedPrimitives(MTLPrimitiveType _primitiveType, NSUInteger _indexCount, MTLIndexType _indexType, id<MTLBuffer> _indexBuffer, NSUInteger _indexBufferOffset, NSUInteger _instanceCount)
+		{
+			[m_obj drawIndexedPrimitives:_primitiveType indexCount:_indexCount indexType:_indexType indexBuffer:_indexBuffer indexBufferOffset:_indexBufferOffset instanceCount:_instanceCount];
+		}
+	
+		void drawPrimitives(MTLPrimitiveType _primitiveType, NSUInteger _vertexStart, NSUInteger _vertexCount, NSUInteger _instanceCount) {
+			[m_obj drawPrimitives:_primitiveType vertexStart:_vertexStart vertexCount:_vertexCount instanceCount:_instanceCount];}
+
+		void insertDebugSignpost(const char* _string) { [m_obj insertDebugSignpost:@(_string)]; }
+		void pushDebugGroup(const char* _string) { [m_obj pushDebugGroup:@(_string)]; }
+		void popDebugGroup() { [m_obj popDebugGroup]; }
+		
+		void endEncoding() { [m_obj endEncoding]; }
+	MTL_CLASS_END
+		
+	MTL_CLASS(Texture)
+		// Copying Data into a Texture Image
+		void replaceRegion(MTLRegion _region, NSUInteger _level, NSUInteger _slice, const void *_pixelBytes, NSUInteger _bytesPerRow, NSUInteger _bytesPerImage) { [m_obj replaceRegion:_region mipmapLevel:_level slice:_slice withBytes:_pixelBytes bytesPerRow:_bytesPerRow		bytesPerImage:_bytesPerImage]; }
+	
+		// Copying Data from a Texture Image
+		void getBytes(void *_pixelBytes, NSUInteger _bytesPerRow, NSUInteger _bytesPerImage, MTLRegion _region, NSUInteger _mipmapLevel, NSUInteger _slice) { [m_obj getBytes:_pixelBytes bytesPerRow:_bytesPerRow bytesPerImage:_bytesPerImage fromRegion:_region mipmapLevel:_mipmapLevel slice:_slice]; }
+	
+		// Creating Textures by Reusing Image Data
+		id<MTLTexture> newTextureViewWithPixelFormat(MTLPixelFormat _pixelFormat) { return [m_obj newTextureViewWithPixelFormat:_pixelFormat]; }
+		//properties
+		uint32_t width() { return (uint32_t)m_obj.width; }
+		uint32_t height() { return (uint32_t)m_obj.height; }
+		MTLPixelFormat pixelFormat() const { return m_obj.pixelFormat; }
+	MTL_CLASS_END
+		
+	typedef id<MTLComputePipelineState> ComputePipelineState;
+	typedef id<MTLDepthStencilState> DepthStencilState;
+	typedef id<MTLRenderPipelineState> RenderPipelineState;
+	typedef id<MTLSamplerState> SamplerState;
+	
+		//descriptors
+	//NOTE: [class new] is same as [[class alloc] init]
+	typedef MTLRenderPipelineDescriptor* RenderPipelineDescriptor;
+	RenderPipelineDescriptor newRenderPipelineDescriptor() { return [MTLRenderPipelineDescriptor new]; }
+	void reset(RenderPipelineDescriptor _desc) { [_desc reset]; };
+	
+	typedef MTLRenderPipelineColorAttachmentDescriptor* RenderPipelineColorAttachmentDescriptor;
+	
+	typedef MTLDepthStencilDescriptor* DepthStencilDescriptor;
+	MTLDepthStencilDescriptor* newDepthStencilDescriptor() { return [MTLDepthStencilDescriptor new]; }
+
+	typedef MTLStencilDescriptor* StencilDescriptor;
+	MTLStencilDescriptor* newStencilDescriptor() { return [MTLStencilDescriptor new]; }
+	
+	typedef MTLRenderPassColorAttachmentDescriptor* RenderPassColorAttachmentDescriptor;
+	typedef MTLRenderPassDepthAttachmentDescriptor* RenderPassDepthAttachmentDescriptor;
+	typedef MTLRenderPassStencilAttachmentDescriptor* RenderPassStencilAttachmentDescriptor;
+	
+	typedef MTLRenderPassDescriptor* RenderPassDescriptor;
+	MTLRenderPassDescriptor* newRenderPassDescriptor() { return [MTLRenderPassDescriptor new]; }
+
+	typedef MTLVertexDescriptor* VertexDescriptor;
+	MTLVertexDescriptor* newVertexDescriptor() { return [MTLVertexDescriptor new]; }
+	void reset(VertexDescriptor _desc) { [_desc reset]; };
+
+	typedef MTLSamplerDescriptor* SamplerDescriptor;
+	MTLSamplerDescriptor* newSamplerDescriptor() { return [MTLSamplerDescriptor new]; }
+
+	typedef MTLTextureDescriptor* TextureDescriptor;
+	MTLTextureDescriptor* newTextureDescriptor() { return [MTLTextureDescriptor new]; }
+	
+	typedef MTLRenderPipelineReflection* RenderPipelineReflection;
+
+		//helper functions
+	void release(NSObject* _obj) { [_obj release]; }
+	void retain(NSObject* _obj) { [_obj retain]; }
+	const char* utf8String(NSString* _str) { return [_str UTF8String]; }
+
+	
+#define MTL_RELEASE(_obj)	\
+	[_obj release]; \
+	_obj = nil;
+	
+#ifdef BX_PLATFORM_IOS
+	bool OsVersionEqualOrGreater(const char* _version) { return ([[[UIDevice currentDevice] systemVersion] compare:@(_version) options:NSNumericSearch] != NSOrderedAscending); }
+	//TODO: this could be in bx ?
+#endif
+	// end of c++ wrapper
+	
+	template <typename Ty>
+	class StateCacheT
+	{
+	public:
+		void add(uint64_t _id, Ty _item)
+		{
+			invalidate(_id);
+			m_hashMap.insert(stl::make_pair(_id, _item) );
+		}
+		
+		Ty find(uint64_t _id)
+		{
+			typename HashMap::iterator it = m_hashMap.find(_id);
+			if (it != m_hashMap.end() )
+			{
+				return it->second;
+			}
+			
+			return NULL;
+		}
+		
+		void invalidate(uint64_t _id)
+		{
+			typename HashMap::iterator it = m_hashMap.find(_id);
+			if (it != m_hashMap.end() )
+			{
+				//DX_RELEASE_WARNONLY(it->second, 0);
+				MTL_RELEASE(it->second);
+				m_hashMap.erase(it);
+			}
+		}
+		
+		void invalidate()
+		{
+			for (typename HashMap::iterator it = m_hashMap.begin(), itEnd = m_hashMap.end(); it != itEnd; ++it)
+			{
+				//DX_CHECK_REFCOUNT(it->second, 1);
+				release(it->second);
+			}
+			
+			m_hashMap.clear();
+		}
+		
+		uint32_t getCount() const
+		{
+			return uint32_t(m_hashMap.size() );
+		}
+		
+	private:
+		typedef stl::unordered_map<uint64_t, Ty> HashMap;
+		HashMap m_hashMap;
+	};
+	
+	struct BufferMtl
+	{
+		BufferMtl()
+		: m_buffer(NULL)
+		, m_flags(BGFX_BUFFER_NONE)
+		, m_dynamic(false)
+		{
+		}
+		
+		void create(uint32_t _size, void* _data, uint16_t _flags, uint16_t _stride = 0, bool _vertex = false);
+		void update(uint32_t _offset, uint32_t _size, void* _data, bool _discard = false);
+		
+		void destroy()
+		{
+			if (NULL != m_buffer)
+			{
+				[m_buffer release];
+				m_buffer = NULL;
+				m_dynamic = false;
+			}
+		}
+		
+		Buffer   m_buffer;
+		uint32_t m_size;
+		uint16_t m_flags;
+		bool m_dynamic;
+	};
+	
+	typedef BufferMtl IndexBufferMtl;
+	
+	struct VertexBufferMtl : public BufferMtl
+	{
+		VertexBufferMtl()
+		: BufferMtl()
+		{
+		}
+		
+		void create(uint32_t _size, void* _data, VertexDeclHandle _declHandle, uint16_t _flags);
+		
+		VertexDeclHandle m_decl;
+	};
+	
+	
+	struct ShaderMtl
+	{
+		ShaderMtl()
+		: m_function(NULL)
+		{
+		}
+		
+		void create(const Memory* _mem);
+		void destroy()
+		{
+			MTL_RELEASE(m_function);
+			
+		}
+		
+		Function m_function;
+	};
+	
+	
+	struct ProgramMtl
+	{
+		ProgramMtl()
+		: m_vsh(NULL)
+		, m_fsh(NULL)
+		, m_processedUniforms(false)
+		, m_vshConstantBuffer(NULL)
+		, m_fshConstantBuffer(NULL)
+		, m_numPredefined(0)
+		, m_vshConstantBufferSize(0)
+		, m_vshConstantBufferAlignmentMask(0)
+		, m_fshConstantBufferSize(0)
+		, m_fshConstantBufferAlignmentMask(0)
+		{
+		}
+		
+		void create(const ShaderMtl* _vsh, const ShaderMtl* _fsh);
+		void destroy();
+		
+		RenderPipelineState getRenderPipelineState(uint64_t _state, uint32_t _rgba, FrameBufferHandle _fbHandle, VertexDeclHandle _declHandle,  uint16_t _numInstanceData);
+		
+		StateCacheT<RenderPipelineState>	m_renderPipelineStateCache;
+
+		uint8_t m_used[Attrib::Count+1]; // dense
+		uint32_t m_attributes[Attrib::Count]; // sparse
+		uint32_t m_instanceData[BGFX_CONFIG_MAX_INSTANCE_DATA_COUNT+1];
+		
+		const ShaderMtl* m_vsh;
+		const ShaderMtl* m_fsh;
+		
+		bool m_processedUniforms;
+		uint32_t m_vshConstantBufferSize;
+		uint32_t m_vshConstantBufferAlignmentMask;
+		uint32_t m_fshConstantBufferSize;
+		uint32_t m_fshConstantBufferAlignmentMask;
+		ConstantBuffer* m_fshConstantBuffer;
+		ConstantBuffer* m_vshConstantBuffer;
+		PredefinedUniform m_predefined[PredefinedUniform::Count*2];
+		uint8_t m_numPredefined;
+	};
+	
+	struct TextureMtl
+	{
+		TextureMtl()
+		: m_ptr(NULL)
+		, m_ptrStencil(NULL)
+		, m_sampler(NULL)
+		, m_numMips(0)
+		, m_flags(0)
+		{
+		}
+		
+		void create(const Memory* _mem, uint32_t _flags, uint8_t _skip);
+		void destroy()
+		{
+			MTL_RELEASE(m_ptr);
+			MTL_RELEASE(m_ptrStencil);
+		}
+		void update(uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem);
+		void commit(uint8_t _stage, uint32_t _flags = BGFX_SAMPLER_DEFAULT_FLAGS);
+		
+		Texture m_ptr;
+		Texture m_ptrStencil; // for emulating packed depth/stencil formats - only for iOS8...
+		SamplerState m_sampler;
+		uint32_t m_flags;
+		uint8_t m_requestedFormat;
+		uint8_t m_textureFormat;
+		uint8_t m_numMips;
+	};
+	
+	struct FrameBufferMtl
+	{
+		FrameBufferMtl()
+		: //m_swapChain(NULL) //TODO: swapchain
+		 m_denseIdx(UINT16_MAX)
+		, m_num(0)
+		, m_pixelFormatHash(0)
+		{
+			m_depthHandle.idx = invalidHandle;
+		}
+		
+		void create(uint8_t _num, const TextureHandle* _handles);
+		void create(uint16_t _denseIdx, void* _nwh, uint32_t _width, uint32_t _height, TextureFormat::Enum _depthFormat);
+		void postReset();
+		uint16_t destroy();
+		
+//		SwapChainMtl* m_swapChain;
+		uint32_t m_width;
+		uint32_t m_height;
+		uint16_t m_denseIdx;
+		
+		uint32_t m_pixelFormatHash;
+
+		TextureHandle m_colorHandle[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS-1];
+		TextureHandle m_depthHandle;
+		uint8_t  m_num;	// number of color handles
+	};
+	
+	
+#endif
+	
+} /* namespace metal */ } // namespace bgfx
+
+#endif // BGFX_RENDERER_METAL_H_HEADER_GUARD
+		

+ 2735 - 5
src/renderer_mtl.mm

@@ -1,23 +1,2753 @@
 /*
- * Copyright 2011-2015 Branimir Karadzic. All rights reserved.
+ * Copyright 2011-2015 Attila Kocsis. All rights reserved.
  * License: http://www.opensource.org/licenses/BSD-2-Clause
  */
 
 #include "bgfx_p.h"
+
+
+/*
+Known issues / TODOs:
+- 15-shadowmaps-simple (modified shaderc and example needs modification too, mtxCrop znew = z * 0.5 + 0.5 is not needed ) could be hacked in shader too
+- 19-oit ( hacked shaderc to support MRT output)
+- 21-deferred ( hacked shaderc to support MRT output and fs_deferred_light needed modification for metal (similar to BGFX_SHADER_LANGUAGE_HLSL )
+
+07-callback, saveScreenshot should be implemented with one frame latency (using saveScreenshotBegin and End)
+ 
+16-shadowmaps,  //problem with essl -> metal: SAMPLER2D(u_shadowMap0, 4);  sampler index is lost. Shadowmap is set to slot 4, but
+ metal shader uses sampler/texture slot 0. this could require changes outside of renderer_mtl?
+  Otherwise it works with hacking the slot.
+
+24-nbody - cannot generate compute shaders for metal
+ 
+20-nanonvg - TODO: remove sampler/texture hack
+
+- caps
+ 
+- optimization...
+ 
+create binary shader representation
+ 
+ 13-stencil and 16-shadowmaps are very inefficient. every view stores/loads backbuffer data
+ 
+ BGFX_RESET_FLIP_AFTER_RENDER on low level renderers should be true? (crashes even with BGFX_RESET_FLIP_AFTER_RENDER because there is
+ one rendering frame before reset). Do I have absolutely need to send result to View at flip or can I do it in submit?
+ 
+ */
+
 #if BGFX_CONFIG_RENDERER_METAL
-#	include "../../bgfx-ext/src/renderer_mtl.mm"
-#else
+
+#include "renderer_mtl.h"
+#include "renderer.h"
+#include "bx/bx.h"
+#if BX_PLATFORM_OSX
+#	include <Cocoa/Cocoa.h>
+#endif
+
+#import <Foundation/Foundation.h>
+
+#define UNIFORM_BUFFER_SIZE (1024*1024)
 
 namespace bgfx { namespace mtl
 {
+	static char s_viewName[BGFX_CONFIG_MAX_VIEWS][BGFX_CONFIG_MAX_VIEW_NAME];
+	
+	struct PrimInfo
+	{
+		MTLPrimitiveType m_type;
+		uint32_t m_min;
+		uint32_t m_div;
+		uint32_t m_sub;
+	};
+	
+	static const PrimInfo s_primInfo[] =
+	{
+		{ MTLPrimitiveTypeTriangle,			3, 3, 0 },
+		{ MTLPrimitiveTypeTriangleStrip,	3, 1, 2 },
+		{ MTLPrimitiveTypeLine,				2, 2, 0 },
+		{ MTLPrimitiveTypeLineStrip,		2, 1, 1 },
+		{ MTLPrimitiveTypePoint,			1, 1, 0 },
+	};
+	
+	static const char* s_primName[] =
+	{
+		"TriList",
+		"TriStrip",
+		"Line",
+		"LineStrip",
+		"Point",
+	};
+	BX_STATIC_ASSERT(BX_COUNTOF(s_primInfo) == BX_COUNTOF(s_primName));
+	
+	static const char* s_attribName[] =
+	{
+		"a_position",
+		"a_normal",
+		"a_tangent",
+		"a_bitangent",
+		"a_color0",
+		"a_color1",
+		"a_indices",
+		"a_weight",
+		"a_texcoord0",
+		"a_texcoord1",
+		"a_texcoord2",
+		"a_texcoord3",
+		"a_texcoord4",
+		"a_texcoord5",
+		"a_texcoord6",
+		"a_texcoord7",
+	};
+	BX_STATIC_ASSERT(Attrib::Count == BX_COUNTOF(s_attribName) );
+	
+	static const char* s_instanceDataName[] =
+	{
+		"i_data0",
+		"i_data1",
+		"i_data2",
+		"i_data3",
+		"i_data4",
+	};
+	BX_STATIC_ASSERT(BGFX_CONFIG_MAX_INSTANCE_DATA_COUNT == BX_COUNTOF(s_instanceDataName) );
+	
+	static const MTLVertexFormat s_attribType[][4][2] = //type, count, normalized
+	{
+		// Uint8
+		{
+			{ MTLVertexFormatUChar2, MTLVertexFormatUChar2Normalized },
+			{ MTLVertexFormatUChar2, MTLVertexFormatUChar2Normalized },
+			{ MTLVertexFormatUChar3, MTLVertexFormatUChar3Normalized },
+			{ MTLVertexFormatUChar4, MTLVertexFormatUChar4Normalized }
+		},
+
+		//Uint10
+			//TODO: normalized only
+		{
+			{ MTLVertexFormatInvalid, MTLVertexFormatUInt1010102Normalized },
+			{ MTLVertexFormatInvalid, MTLVertexFormatUInt1010102Normalized },
+			{ MTLVertexFormatInvalid, MTLVertexFormatUInt1010102Normalized },
+			{ MTLVertexFormatInvalid, MTLVertexFormatUInt1010102Normalized }
+		},
+		
+		//Int16
+		{
+			{ MTLVertexFormatShort2, MTLVertexFormatShort2Normalized },
+			{ MTLVertexFormatShort2, MTLVertexFormatShort2Normalized },
+			{ MTLVertexFormatShort3, MTLVertexFormatShort3Normalized },
+			{ MTLVertexFormatShort4, MTLVertexFormatShort4Normalized }
+		},
+		
+		//Half
+		{
+			{ MTLVertexFormatHalf2, MTLVertexFormatHalf2 },
+			{ MTLVertexFormatHalf2, MTLVertexFormatHalf2 },
+			{ MTLVertexFormatHalf3, MTLVertexFormatHalf2 },
+			{ MTLVertexFormatHalf4, MTLVertexFormatHalf2 }
+		},
+
+		//Float
+		{
+			{ MTLVertexFormatFloat, MTLVertexFormatFloat },
+			{ MTLVertexFormatFloat2, MTLVertexFormatFloat2 },
+			{ MTLVertexFormatFloat3, MTLVertexFormatFloat3 },
+			{ MTLVertexFormatFloat4, MTLVertexFormatFloat4 }
+		},
+	};
+	BX_STATIC_ASSERT(AttribType::Count == BX_COUNTOF(s_attribType) );
+	
+	static const MTLCullMode s_cullMode[] =
+	{
+		MTLCullModeNone,
+		MTLCullModeFront,
+		MTLCullModeBack,
+		MTLCullModeNone
+	};
+	
+	static const MTLBlendFactor s_blendFactor[][2] =
+	{
+		{ (MTLBlendFactor)0,						(MTLBlendFactor)0						}, // ignored
+		{ MTLBlendFactorZero,						MTLBlendFactorZero						}, // ZERO
+		{ MTLBlendFactorOne,						MTLBlendFactorOne						},	// ONE
+		{ MTLBlendFactorSourceColor,				MTLBlendFactorSourceAlpha				},	// SRC_COLOR
+		{ MTLBlendFactorOneMinusSourceColor,		MTLBlendFactorOneMinusSourceAlpha		},	// INV_SRC_COLOR
+		{ MTLBlendFactorSourceAlpha,				MTLBlendFactorSourceAlpha				},	// SRC_ALPHA
+		{ MTLBlendFactorOneMinusSourceAlpha,		MTLBlendFactorOneMinusSourceAlpha		},	// INV_SRC_ALPHA
+		{ MTLBlendFactorDestinationAlpha,			MTLBlendFactorDestinationAlpha			},	// DST_ALPHA
+		{ MTLBlendFactorOneMinusDestinationAlpha,   MTLBlendFactorOneMinusDestinationAlpha  },	// INV_DST_ALPHA
+		{ MTLBlendFactorDestinationColor,			MTLBlendFactorDestinationAlpha			},	// DST_COLOR
+		{ MTLBlendFactorOneMinusDestinationColor,   MTLBlendFactorOneMinusDestinationAlpha  },	// INV_DST_COLOR
+		{ MTLBlendFactorSourceAlphaSaturated,		MTLBlendFactorOne						},	// SRC_ALPHA_SAT
+		{ MTLBlendFactorBlendColor,					MTLBlendFactorBlendColor				},	// FACTOR
+		{ MTLBlendFactorOneMinusBlendColor,			MTLBlendFactorOneMinusBlendColor		},	// INV_FACTOR
+	};
+	
+	static const MTLBlendOperation s_blendEquation[] =
+	{
+		MTLBlendOperationAdd,
+		MTLBlendOperationSubtract,
+		MTLBlendOperationReverseSubtract,
+		MTLBlendOperationMin,
+		MTLBlendOperationMax,
+	};
+	
+	static const MTLCompareFunction s_cmpFunc[] =
+	{
+			MTLCompareFunctionAlways, //TODO: depth disable?
+		MTLCompareFunctionLess,
+		MTLCompareFunctionLessEqual,
+		MTLCompareFunctionEqual,
+		MTLCompareFunctionGreaterEqual,
+		MTLCompareFunctionGreater,
+		MTLCompareFunctionNotEqual,
+		MTLCompareFunctionNever,
+		MTLCompareFunctionAlways
+	};
+	
+	static const MTLStencilOperation s_stencilOp[] =
+	{
+		MTLStencilOperationZero,
+		MTLStencilOperationKeep,
+		MTLStencilOperationReplace,
+		MTLStencilOperationIncrementWrap,
+		MTLStencilOperationIncrementClamp,
+		MTLStencilOperationDecrementWrap,
+		MTLStencilOperationDecrementClamp,
+		MTLStencilOperationInvert
+	};
+	
+	static const MTLSamplerAddressMode s_textureAddress[] =
+	{
+		MTLSamplerAddressModeRepeat,
+		MTLSamplerAddressModeMirrorRepeat,
+		MTLSamplerAddressModeClampToEdge,
+	};
+	
+	static const MTLSamplerMinMagFilter s_textureFilterMinMag[] =
+	{
+		MTLSamplerMinMagFilterLinear,
+		MTLSamplerMinMagFilterNearest,
+		MTLSamplerMinMagFilterLinear,
+	};
+
+	static const MTLSamplerMipFilter s_textureFilterMip[] =
+	{
+		MTLSamplerMipFilterLinear,
+		MTLSamplerMipFilterNearest,
+	};
+	
+	struct TextureFormatInfo
+	{
+		MTLPixelFormat m_fmt;
+		MTLPixelFormat m_fmtSrgb;
+	};
+	
+		//TODO: add new ios/osx formats
+	   //TODO: add caps for format support
+	static TextureFormatInfo s_textureFormat[] =
+	{
+		{ MTLPixelFormatInvalid,          MTLPixelFormatInvalid				}, // BC1
+		{ MTLPixelFormatInvalid,          MTLPixelFormatInvalid				}, // BC2
+		{ MTLPixelFormatInvalid,          MTLPixelFormatInvalid				}, // BC3
+		{ MTLPixelFormatInvalid,          MTLPixelFormatInvalid				}, // BC4
+		{ MTLPixelFormatInvalid,          MTLPixelFormatInvalid				}, // BC5
+		{ MTLPixelFormatInvalid,          MTLPixelFormatInvalid				}, // BC6H
+		{ MTLPixelFormatInvalid,          MTLPixelFormatInvalid				}, // BC7
+		{ MTLPixelFormatInvalid,          MTLPixelFormatInvalid				}, // ETC1
+		{ MTLPixelFormatETC2_RGB8,        MTLPixelFormatETC2_RGB8_sRGB		}, // ETC2
+		{ MTLPixelFormatEAC_RGBA8,        MTLPixelFormatEAC_RGBA8_sRGB		}, // ETC2A
+		{ MTLPixelFormatETC2_RGB8A1,      MTLPixelFormatETC2_RGB8A1_sRGB	}, // ETC2A1
+		{ MTLPixelFormatPVRTC_RGB_2BPP,   MTLPixelFormatPVRTC_RGB_2BPP_sRGB	}, // PTC12
+		{ MTLPixelFormatPVRTC_RGB_4BPP,   MTLPixelFormatPVRTC_RGB_4BPP_sRGB	}, // PTC14
+		{ MTLPixelFormatPVRTC_RGBA_2BPP,  MTLPixelFormatPVRTC_RGBA_2BPP_sRGB}, // PTC12A
+		{ MTLPixelFormatPVRTC_RGBA_4BPP,  MTLPixelFormatPVRTC_RGBA_4BPP_sRGB}, // PTC14A
+		{ MTLPixelFormatInvalid,          MTLPixelFormatInvalid				}, // PTC22
+		{ MTLPixelFormatInvalid,          MTLPixelFormatInvalid				}, // PTC24
+		{ MTLPixelFormatInvalid,          MTLPixelFormatInvalid				}, // Unknown
+		{ MTLPixelFormatInvalid,          MTLPixelFormatInvalid				}, // R1
+		{ MTLPixelFormatR8Unorm,          MTLPixelFormatR8Unorm_sRGB		}, // R8
+//ASK: R8 uses unorm R16 uint is this ok? From d3d11
+		{ MTLPixelFormatR16Uint,          MTLPixelFormatInvalid				}, // R16
+		{ MTLPixelFormatR16Float,         MTLPixelFormatInvalid				}, // R16F
+		{ MTLPixelFormatR32Uint,          MTLPixelFormatInvalid				}, // R32
+		{ MTLPixelFormatR32Float,         MTLPixelFormatInvalid				}, // R32F
+		{ MTLPixelFormatRG8Unorm,         MTLPixelFormatRG8Unorm_sRGB		}, // RG8
+		{ MTLPixelFormatRG16Unorm,        MTLPixelFormatInvalid				}, // RG16
+		{ MTLPixelFormatRG16Float,        MTLPixelFormatInvalid				}, // RG16F
+		{ MTLPixelFormatRG32Uint,         MTLPixelFormatInvalid				}, // RG32
+		{ MTLPixelFormatRG32Float,        MTLPixelFormatInvalid				}, // RG32F
+		{ MTLPixelFormatBGRA8Unorm,       MTLPixelFormatBGRA8Unorm_sRGB		}, // BGRA8
+		{ MTLPixelFormatRGBA8Unorm,       MTLPixelFormatRGBA8Unorm_sRGB		}, // RGBA8
+		{ MTLPixelFormatRGBA16Unorm,	  MTLPixelFormatInvalid				}, // RGBA16
+		{ MTLPixelFormatRGBA16Float,	  MTLPixelFormatInvalid				}, // RGBA16F
+		{ MTLPixelFormatRGBA32Uint,		  MTLPixelFormatInvalid				}, // RGBA32
+		{ MTLPixelFormatRGBA32Float,	  MTLPixelFormatInvalid				}, // RGBA32F
+		//only have abgr (not rgba)
+		{ MTLPixelFormatB5G6R5Unorm,	  MTLPixelFormatInvalid				}, // R5G6B5
+		{ MTLPixelFormatABGR4Unorm,		  MTLPixelFormatInvalid				}, // RGBA4
+		{ MTLPixelFormatA1BGR5Unorm,	  MTLPixelFormatInvalid				}, // RGB5A1
+		{ MTLPixelFormatRGB10A2Unorm,			MTLPixelFormatInvalid				}, // RGB10A2
+		{ MTLPixelFormatRG11B10Float,			MTLPixelFormatInvalid				}, // R11G11B10F
+
+		{ MTLPixelFormatInvalid,				MTLPixelFormatInvalid				}, // UnknownDepth
+		{ MTLPixelFormatDepth32Float,			MTLPixelFormatInvalid				}, // D16
+		{ MTLPixelFormatDepth32Float,			MTLPixelFormatInvalid				}, // D24
+		{ MTLPixelFormatInvalid,				MTLPixelFormatInvalid				}, // D24S8
+		{ MTLPixelFormatDepth32Float,			MTLPixelFormatInvalid				}, // D32
+		{ MTLPixelFormatDepth32Float,			MTLPixelFormatInvalid				}, // D16F
+		{ MTLPixelFormatDepth32Float,			MTLPixelFormatInvalid				}, // D24F
+		{ MTLPixelFormatDepth32Float,			MTLPixelFormatInvalid				}, // D32F
+		{ MTLPixelFormatStencil8,				MTLPixelFormatInvalid				}, // D0S8
+	};
+	BX_STATIC_ASSERT(TextureFormat::Count == BX_COUNTOF(s_textureFormat) );
+	
+	
+	#define SHADER_FUNCTION_NAME ("xlatMtlMain")
+	#define SHADER_UNIFORM_NAME ("_mtl_u")
+	
+	struct RendererContextMtl : public RendererContextI
+	{
+		RendererContextMtl()
+			  :	m_numWindows(1),
+				m_metalLayer(NULL),
+				m_drawable(NULL),
+				m_maxAnisotropy(1),
+				m_rtMsaa(false),
+				m_backBufferPixelFormatHash(0)
+		{
+			m_fbh.idx = invalidHandle;
+		}
+			
+		~RendererContextMtl()
+		{
+		}
+			
+		bool init()
+		{
+			if ( NSClassFromString(@"CAMetalLayer") != nil)
+			{
+				//on iOS we need the layer as CAmetalLayer
+#if BX_PLATFORM_IOS
+				CAMetalLayer* metalLayer = (CAMetalLayer*)g_platformData.nwh;
+				if (metalLayer == nil || ![metalLayer isKindOfClass:NSClassFromString(@"CAMetalLayer")])
+				{
+					BX_WARN(NULL != m_device, "Unable to create Metal device. Please set platform data window to a CAMetalLayer");
+					return false;
+				}
+				m_metalLayer = metalLayer;
+#elif BX_PLATFORM_OSX
+				// create and set metalLayer
+				NSWindow* nsWindow = (NSWindow*)g_platformData.nwh;
+				
+				[nsWindow.contentView setWantsLayer:YES];
+				m_metalLayer = [CAMetalLayer layer];
+				[nsWindow.contentView setLayer:m_metalLayer];
+#endif
+
+				m_device = (id<MTLDevice>)g_platformData.context;
+				
+				if (NULL == m_device)
+				{
+					m_device = MTLCreateSystemDefaultDevice();
+				}
+			}
+		
+			if (m_device==NULL || m_metalLayer==nil)
+			{
+				BX_WARN(NULL != m_device, "Unable to create Metal device.");
+				return false;
+			}
+
+			m_metalLayer.device = m_device;
+			
+			m_commandQueue = m_device.newCommandQueue();
+			BGFX_FATAL(NULL != m_commandQueue, Fatal::UnableToInitialize, "Unable to create Metal device.");
+			
+			m_renderPipelineDescriptor = newRenderPipelineDescriptor();
+			m_depthStencilDescriptor = newDepthStencilDescriptor();
+			m_frontFaceStencilDescriptor = newStencilDescriptor();
+			m_backFaceStencilDescriptor = newStencilDescriptor();
+			m_vertexDescriptor = newVertexDescriptor();
+			m_textureDescriptor = newTextureDescriptor();
+			m_samplerDescriptor = newSamplerDescriptor();
+			
+			m_uniformBuffer = m_device.newBufferWithLength(UNIFORM_BUFFER_SIZE, 0);
+			m_uniformBufferVertexOffset = 0;
+			m_uniformBufferFragmentOffset = 0;
+
+			memset(m_uniforms, 0, sizeof(m_uniforms) );
+			
+			g_caps.supported |= (0
+								 | BGFX_CAPS_TEXTURE_COMPARE_LEQUAL
+								 | BGFX_CAPS_TEXTURE_3D
+								 | BGFX_CAPS_INSTANCING
+								 | BGFX_CAPS_VERTEX_ATTRIB_HALF
+								 //| BGFX_CAPS_FRAGMENT_DEPTH //TODO: is this supported?
+								 | BGFX_CAPS_BLEND_INDEPENDENT
+								 | BGFX_CAPS_COMPUTE
+								 | BGFX_CAPS_INDEX32
+								 | BGFX_CAPS_DRAW_INDIRECT
+								 );
+			
+			g_caps.maxTextureSize = 2048; //ASK: real caps width/height: 4096, but max depth(3D) size is only: 2048
+				//TODO: OSX
+#if BX_PLATFORM_IOS
+			g_caps.maxFBAttachments = uint8_t(bx::uint32_min(m_device.supportsFeatureSet(MTLFeatureSet_iOS_GPUFamily2_v1) ? 8 :4, BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS));
+#endif
+			
+			//todo: vendor id, device id, gpu enum
+			//todo: texture format caps
+
+			//add texture formats/caps/etc that are available only on new sdk/devices
+#if BX_PLATFORM_IOS
+		#ifdef __IPHONE_8_0
+			if (OsVersionEqualOrGreater("8.0.0"))
+			{
+				s_textureFormat[TextureFormat::D24S8].m_fmt = MTLPixelFormatDepth32Float;
+			}
+		#endif
+#endif
+
+#if BX_PLATFORM_OSX
+			
+#endif
+			
+			for (uint32_t ii = 0; ii < TextureFormat::Count; ++ii)
+			{
+				uint8_t support = (s_textureFormat[ii].m_fmt != MTLPixelFormatInvalid) ? BGFX_CAPS_FORMAT_TEXTURE_COLOR : BGFX_CAPS_FORMAT_TEXTURE_NONE;
+				
+				support |= (s_textureFormat[ii].m_fmtSrgb != MTLPixelFormatInvalid) ? BGFX_CAPS_FORMAT_TEXTURE_COLOR_SRGB : BGFX_CAPS_FORMAT_TEXTURE_NONE;
+
+					//TODO: additional caps flags
+//				support |= BGFX_CAPS_FORMAT_TEXTURE_VERTEX : BGFX_CAPS_FORMAT_TEXTURE_NONE;
+//				support |= BGFX_CAPS_FORMAT_TEXTURE_IMAGE : BGFX_CAPS_FORMAT_TEXTURE_NONE;
+//				support |= BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER : BGFX_CAPS_FORMAT_TEXTURE_NONE;
+				
+				g_caps.formats[ii] = support;
+			}
+			
+			// Init reserved part of view name.
+			for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii)
+			{
+				bx::snprintf(s_viewName[ii], BGFX_CONFIG_MAX_VIEW_NAME_RESERVED+1, "%3d   ", ii);
+			}
+			
+			return true;
+		}
+			
+	void shutdown()
+	{
+		for (uint32_t ii = 0; ii < BX_COUNTOF(m_shaders); ++ii)
+		{
+			m_shaders[ii].destroy();
+		}
+		
+		for (uint32_t ii = 0; ii < BX_COUNTOF(m_textures); ++ii)
+		{
+			m_textures[ii].destroy();
+		}
+
+		MTL_RELEASE(m_depthStencilDescriptor);
+		MTL_RELEASE(m_frontFaceStencilDescriptor);
+		MTL_RELEASE(m_backFaceStencilDescriptor);
+		MTL_RELEASE(m_renderPipelineDescriptor);
+		MTL_RELEASE(m_vertexDescriptor);
+		MTL_RELEASE(m_textureDescriptor);
+		MTL_RELEASE(m_samplerDescriptor);
+		
+		MTL_RELEASE(m_backBufferDepth);
+#if BX_PLATFORM_IOS
+		MTL_RELEASE(m_backBufferStencil);
+#endif
+
+		MTL_RELEASE(m_uniformBuffer);
+		MTL_RELEASE(m_commandQueue);
+		MTL_RELEASE(m_device);
+	}
+		
+		
+	RendererType::Enum getRendererType() const BX_OVERRIDE
+	{
+		return RendererType::Metal;
+	}
+		
+	const char* getRendererName() const BX_OVERRIDE
+	{
+		return BGFX_RENDERER_METAL_NAME;
+	}
+	
+
+	void createIndexBuffer(IndexBufferHandle _handle, Memory* _mem, uint16_t _flags) BX_OVERRIDE
+	{
+		m_indexBuffers[_handle.idx].create(_mem->size, _mem->data, _flags);
+	}
+	
+	void destroyIndexBuffer(IndexBufferHandle _handle) BX_OVERRIDE
+	{
+		m_indexBuffers[_handle.idx].destroy();
+	}
+	
+	void createVertexDecl(VertexDeclHandle _handle, const VertexDecl& _decl) BX_OVERRIDE
+	{
+		VertexDecl& decl = m_vertexDecls[_handle.idx];
+		memcpy(&decl, &_decl, sizeof(VertexDecl) );
+		dump(decl);
+	}
+	
+	void destroyVertexDecl(VertexDeclHandle /*_handle*/) BX_OVERRIDE
+	{
+	}
+	
+	void createVertexBuffer(VertexBufferHandle _handle, Memory* _mem, VertexDeclHandle _declHandle, uint16_t _flags) BX_OVERRIDE
+	{
+		m_vertexBuffers[_handle.idx].create(_mem->size, _mem->data, _declHandle, _flags);
+	}
+	
+	void destroyVertexBuffer(VertexBufferHandle _handle) BX_OVERRIDE
+	{
+		m_vertexBuffers[_handle.idx].destroy();
+	}
+	
+	void createDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _size, uint16_t _flags) BX_OVERRIDE
+	{
+		m_indexBuffers[_handle.idx].create(_size, NULL, _flags);
+	}
+
+	void updateDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _offset, uint32_t _size, Memory* _mem) BX_OVERRIDE
+	{
+		m_indexBuffers[_handle.idx].update(_offset, bx::uint32_min(_size, _mem->size), _mem->data);
+	}
+
+	void destroyDynamicIndexBuffer(IndexBufferHandle _handle) BX_OVERRIDE
+	{
+		m_indexBuffers[_handle.idx].destroy();
+	}
+
+	void createDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _size, uint16_t _flags) BX_OVERRIDE
+	{
+		VertexDeclHandle decl = BGFX_INVALID_HANDLE;
+		m_vertexBuffers[_handle.idx].create(_size, NULL, decl, _flags);
+	}
+
+	void updateDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _offset, uint32_t _size, Memory* _mem) BX_OVERRIDE
+	{
+		m_vertexBuffers[_handle.idx].update(_offset, bx::uint32_min(_size, _mem->size), _mem->data);
+	}
+
+	void destroyDynamicVertexBuffer(VertexBufferHandle _handle) BX_OVERRIDE
+	{
+		m_vertexBuffers[_handle.idx].destroy();
+	}
+
+	void createShader(ShaderHandle _handle, Memory* _mem) BX_OVERRIDE
+	{
+		m_shaders[_handle.idx].create(_mem);
+	}
+	
+	void destroyShader(ShaderHandle _handle) BX_OVERRIDE
+	{
+		m_shaders[_handle.idx].destroy();
+	}
+	
+	void createProgram(ProgramHandle _handle, ShaderHandle _vsh, ShaderHandle _fsh) BX_OVERRIDE
+	{
+		m_program[_handle.idx].create(&m_shaders[_vsh.idx], &m_shaders[_fsh.idx]);
+	}
+	
+	void destroyProgram(ProgramHandle _handle) BX_OVERRIDE
+	{
+		m_program[_handle.idx].destroy();
+	}
+	
+	void createTexture(TextureHandle _handle, Memory* _mem, uint32_t _flags, uint8_t _skip) BX_OVERRIDE
+	{
+		m_textures[_handle.idx].create(_mem, _flags, _skip);
+	}
+
+	void updateTextureBegin(TextureHandle /*_handle*/, uint8_t /*_side*/, uint8_t /*_mip*/) BX_OVERRIDE
+	{
+	}
+	
+	void updateTexture(TextureHandle _handle, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem) BX_OVERRIDE
+	{
+		m_textures[_handle.idx].update(_side, _mip, _rect, _z, _depth, _pitch, _mem);
+	}
+
+	void updateTextureEnd() BX_OVERRIDE
+	{
+	}
+
+	void resizeTexture(TextureHandle _handle, uint16_t _width, uint16_t _height) BX_OVERRIDE
+	{
+		TextureMtl& texture = m_textures[_handle.idx];
+
+		uint32_t size = sizeof(uint32_t) + sizeof(TextureCreate);
+		const Memory* mem = alloc(size);
+
+		bx::StaticMemoryBlockWriter writer(mem->data, mem->size);
+		uint32_t magic = BGFX_CHUNK_MAGIC_TEX;
+		bx::write(&writer, magic);
+
+		TextureCreate tc;
+		tc.m_flags   = texture.m_flags;
+		tc.m_width   = _width;
+		tc.m_height  = _height;
+		tc.m_sides   = 0;
+		tc.m_depth   = 0;
+		tc.m_numMips = 1;
+		tc.m_format  = texture.m_requestedFormat;
+		tc.m_cubeMap = false;
+		tc.m_mem     = NULL;
+		bx::write(&writer, tc);
+
+		texture.destroy();
+		texture.create(mem, tc.m_flags, 0);
+
+		release(mem);
+	}
+
+	void destroyTexture(TextureHandle _handle) BX_OVERRIDE
+	{
+		m_textures[_handle.idx].destroy();
+	}
+
+	void createFrameBuffer(FrameBufferHandle _handle, uint8_t _num, const TextureHandle* _textureHandles) BX_OVERRIDE
+	{
+		m_frameBuffers[_handle.idx].create(_num, _textureHandles);
+	}
+
+	void createFrameBuffer(FrameBufferHandle _handle, void* _nwh, uint32_t _width, uint32_t _height, TextureFormat::Enum _depthFormat) BX_OVERRIDE
+	{
+		uint16_t denseIdx = m_numWindows++;
+		m_windows[denseIdx] = _handle;
+		m_frameBuffers[_handle.idx].create(denseIdx, _nwh, _width, _height, _depthFormat);
+	}
+
+	void destroyFrameBuffer(FrameBufferHandle _handle) BX_OVERRIDE
+	{
+		uint16_t denseIdx = m_frameBuffers[_handle.idx].destroy();
+		if (UINT16_MAX != denseIdx)
+		{
+			--m_numWindows;
+			if (m_numWindows > 1)
+			{
+				FrameBufferHandle handle = m_windows[m_numWindows];
+				m_windows[denseIdx] = handle;
+				m_frameBuffers[handle.idx].m_denseIdx = denseIdx;
+			}
+		}
+	}
+
+	void createUniform(UniformHandle _handle, UniformType::Enum _type, uint16_t _num, const char* _name) BX_OVERRIDE
+	{
+		if (NULL != m_uniforms[_handle.idx])
+		{
+			BX_FREE(g_allocator, m_uniforms[_handle.idx]);
+		}
+
+		uint32_t size = BX_ALIGN_16(g_uniformTypeSize[_type]*_num);
+		void* data = BX_ALLOC(g_allocator, size);
+		memset(data, 0, size);
+		m_uniforms[_handle.idx] = data;
+		m_uniformReg.add(_handle, _name, data);
+	}
+
+	void destroyUniform(UniformHandle _handle) BX_OVERRIDE
+	{
+		BX_FREE(g_allocator, m_uniforms[_handle.idx]);
+		m_uniforms[_handle.idx] = NULL;
+	}
+
+	void saveScreenShot(const char* _filePath) BX_OVERRIDE
+	{
+		if ( NULL == m_drawable || NULL == m_drawable.texture)
+			return;
+
+		//TODO: we should wait for completion of pending commandBuffers
+		//TODO: implement this with saveScreenshotBegin/End
+
+		Texture backBuffer = m_drawable.texture;
+		uint32_t width = backBuffer.width();
+		uint32_t height = backBuffer.height();
+		uint32_t length = width*height*4;
+		uint8_t* data = (uint8_t*)BX_ALLOC(g_allocator, length);
+
+        MTLRegion region = { 0, 0, 0, width, height, 1};
+
+		backBuffer.getBytes(data, 4*width, 0, region, 0, 0);
+
+		g_callback->screenShot(_filePath
+					   , backBuffer.width()
+					   , backBuffer.height()
+					   , width*4
+					   , data
+					   , length
+					   , false
+					   );
+
+		BX_FREE(g_allocator, data);
+	}
+
+	void updateViewName(uint8_t _id, const char* _name) BX_OVERRIDE
+	{
+		if (BX_ENABLED(BGFX_CONFIG_DEBUG_PIX) )
+		{
+			bx::strlcpy(&s_viewName[_id][BGFX_CONFIG_MAX_VIEW_NAME_RESERVED]
+				, _name
+				, BX_COUNTOF(s_viewName[0])-BGFX_CONFIG_MAX_VIEW_NAME_RESERVED
+				);
+		}
+	}
+
+	void updateUniform(uint16_t _loc, const void* _data, uint32_t _size) BX_OVERRIDE
+	{
+		memcpy(m_uniforms[_loc], _data, _size);
+	}
+
+	void setMarker(const char* _marker, uint32_t /*_size*/) BX_OVERRIDE
+	{
+		if (BX_ENABLED(BGFX_CONFIG_DEBUG_MTL) )
+		{
+			m_renderCommandEncoder.insertDebugSignpost(_marker);
+		}
+	}
+
+	void submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter) BX_OVERRIDE;
+
+	void blitSetup(TextVideoMemBlitter& _blitter) BX_OVERRIDE
+	{
+		RenderCommandEncoder rce = m_renderCommandEncoder;
+
+		uint32_t width  = getBufferWidth();
+		uint32_t height = getBufferHeight();
+
+		//if (m_ovr.isEnabled() )
+		//{
+		//	m_ovr.getSize(width, height);
+		//}
+
+		FrameBufferHandle fbh = BGFX_INVALID_HANDLE;
+		//TODO: change to default framebuffer - we need a new encoder for this!
+		//setFrameBuffer(fbh, false);
+
+		MTLViewport viewport = { 0.0f, 0.0f, (float)width, (float)height, 0.0f, 1.0f};
+		rce.setViewport(viewport);
+		MTLScissorRect rc = { 0,0,width,height };
+		rce.setScissorRect(rc);
+		rce.setCullMode(MTLCullModeNone);
+
+		uint64_t state = BGFX_STATE_RGB_WRITE
+						| BGFX_STATE_ALPHA_WRITE
+						| BGFX_STATE_DEPTH_TEST_ALWAYS;
+
+		setDepthStencilState(state);
+
+		ProgramMtl& program = m_program[_blitter.m_program.idx];
+		RenderPipelineState pipelineState = program.getRenderPipelineState(state, 0, fbh, _blitter.m_vb->decl, 0);
+		rce.setRenderPipelineState(pipelineState);
+
+		uint32_t vertexUniformBufferSize = program.m_vshConstantBufferSize;
+		uint32_t fragmentUniformBufferSize = program.m_fshConstantBufferSize;
+
+		if ( vertexUniformBufferSize )
+		{
+			m_uniformBufferVertexOffset = BX_ALIGN_MASK(m_uniformBufferVertexOffset, program.m_vshConstantBufferAlignmentMask);
+			rce.setVertexBuffer(m_uniformBuffer, m_uniformBufferVertexOffset, 0);
+		}
+
+		m_uniformBufferFragmentOffset = m_uniformBufferVertexOffset + vertexUniformBufferSize;
+		if ( fragmentUniformBufferSize )
+		{
+			m_uniformBufferFragmentOffset = BX_ALIGN_MASK(m_uniformBufferFragmentOffset, program.m_fshConstantBufferAlignmentMask);
+			rce.setFragmentBuffer(m_uniformBuffer, m_uniformBufferFragmentOffset, 0);
+		}
+
+		VertexBufferMtl& vb = m_vertexBuffers[_blitter.m_vb->handle.idx];
+		rce.setVertexBuffer(vb.m_buffer, 0, 1);
+
+		float proj[16];
+		bx::mtxOrtho(proj, 0.0f, (float)width, (float)height, 0.0f, 0.0f, 1000.0f);
+
+		PredefinedUniform& predefined = program.m_predefined[0];
+		uint8_t flags = predefined.m_type;
+		setShaderUniform(flags, predefined.m_loc, proj, 4);
+
+		m_textures[_blitter.m_texture.idx].commit(0);
+	}
+
+	void blitRender(TextVideoMemBlitter& _blitter, uint32_t _numIndices) BX_OVERRIDE
+	{
+		const uint32_t numVertices = _numIndices*4/6;
+		if (0 < numVertices)
+		{
+			m_indexBuffers [_blitter.m_ib->handle.idx].update(0, _numIndices*2, _blitter.m_ib->data);
+			m_vertexBuffers[_blitter.m_vb->handle.idx].update(0, numVertices*_blitter.m_decl.m_stride, _blitter.m_vb->data, true);
+	
+			m_renderCommandEncoder.drawIndexedPrimitives(MTLPrimitiveTypeTriangle, _numIndices, MTLIndexTypeUInt16, m_indexBuffers[_blitter.m_ib->handle.idx].m_buffer, 0, 1);
+		}
+	}
+
+
+	void flip(HMD& /*_hmd*/) BX_OVERRIDE
+	{
+		if ( m_drawable == nil || m_commandBuffer == nil) //there was no draw call, cannot flip
+			return;
+	
+		// Present and commit the command buffer
+		m_commandBuffer.presentDrawable(m_drawable);
+		MTL_RELEASE(m_drawable);
+	
+		m_commandBuffer.commit();
+	
+		//  using heavy syncing now
+		//  TODO: refactor it with double/triple buffering frame data
+		m_commandBuffer.waitUntilCompleted();
+	
+		MTL_RELEASE(m_commandBuffer);
+	
+		//TODO: support multiple windows on OSX
+		/*
+		 if (m_flip)
+		 {
+			for (uint32_t ii = 1, num = m_numWindows; ii < num; ++ii)
+			{
+				m_glctx.swap(m_frameBuffers[m_windows[ii].idx].m_swapChain);
+			}
+	 
+			if (!m_ovr.swap(_hmd) )
+			{
+				m_glctx.swap();
+			}
+		 }
+		 */
+	}
+
+	void updateResolution(const Resolution& _resolution)
+	{
+		if (!!(_resolution.m_flags & BGFX_RESET_MAXANISOTROPY) )
+		{
+			m_maxAnisotropy = 16;
+		}
+		else
+		{
+			m_maxAnisotropy = 1;
+		}
+	
+		//TODO: _resolution has wrong dimensions, usng m_drawable.texture size now
+	
+		if ( NULL == m_drawable.texture )
+			return;
+	
+		uint32_t width = (uint32_t)m_drawable.texture.width;
+		uint32_t height = (uint32_t)m_drawable.texture.height;
+	
+		//TODO: there should be a way to specify if backbuffer needs stencil/depth.
+		//TODO: support msaa
+		if ( NULL == m_backBufferDepth || width!=m_backBufferDepth.width() || height!=m_backBufferDepth.height())
+		{
+			m_textureDescriptor.textureType = MTLTextureType2D;
+#if BX_PLATFORM_IOS
+			m_textureDescriptor.pixelFormat = MTLPixelFormatDepth32Float;
+#else
+			m_textureDescriptor.pixelFormat = MTLPixelFormatDepth32Float_Stencil8;
+#endif
+			m_textureDescriptor.width = width;
+			m_textureDescriptor.height = height;
+			m_textureDescriptor.depth = 1;
+			m_textureDescriptor.mipmapLevelCount = 1;
+			m_textureDescriptor.sampleCount = 1;
+			m_textureDescriptor.arrayLength = 1;
+			//m_textureDescriptor.resourceOptions = 0;
+		
+			if ( NULL != m_backBufferDepth )
+			{
+				release(m_backBufferDepth);
+			}
+			m_backBufferDepth = m_device.newTextureWithDescriptor(m_textureDescriptor);
+		
+#if BX_PLATFORM_IOS
+			m_textureDescriptor.pixelFormat = MTLPixelFormatStencil8;
+			m_textureDescriptor.width = width;
+			m_textureDescriptor.height = height;
+		
+			if ( NULL != m_backBufferStencil )
+			{
+				release(m_backBufferStencil);
+			}
+			m_backBufferStencil = m_device.newTextureWithDescriptor(m_textureDescriptor);
+#else
+			m_backBufferStencil = m_backBufferDepth;
+#endif
+		
+			bx::HashMurmur2A murmur;
+			murmur.begin();
+			murmur.add(1);
+			murmur.add((uint32_t)m_drawable.texture.pixelFormat);
+			murmur.add((uint32_t)m_backBufferDepth.pixelFormat());
+			murmur.add((uint32_t)m_backBufferStencil.pixelFormat());
+			m_backBufferPixelFormatHash = murmur.end();
+		
+			for (uint32_t ii = 0; ii < BX_COUNTOF(m_frameBuffers); ++ii)
+			{
+				m_frameBuffers[ii].postReset();
+			}
+		
+			m_textVideoMem.resize(false, width, height);
+			m_textVideoMem.clear();
+		}
+	}
+
+	void setShaderUniform(uint8_t _flags, uint32_t _loc, const void* _val, uint32_t _numRegs)
+	{
+		if (_flags&BGFX_UNIFORM_FRAGMENTBIT)
+		{
+			memcpy(&((char*)m_uniformBuffer.contents())[m_uniformBufferFragmentOffset + _loc], _val, _numRegs*16);
+		}
+		else
+		{
+			memcpy(&((char*)m_uniformBuffer.contents())[m_uniformBufferVertexOffset + _loc], _val, _numRegs*16);
+		}
+	}
+
+	void setShaderUniform4f(uint8_t _flags, uint32_t _loc, const void* _val, uint32_t _numRegs)
+	{
+		setShaderUniform(_flags, _loc, _val, _numRegs);
+	}
+
+	void setShaderUniform4x4f(uint8_t _flags, uint32_t _loc, const void* _val, uint32_t _numRegs)
+	{
+		setShaderUniform(_flags, _loc, _val, _numRegs);
+	}
+
+	void commit(ConstantBuffer& _constantBuffer)
+	{
+		_constantBuffer.reset();
+		
+		for (;;)
+		{
+			uint32_t opcode = _constantBuffer.read();
+			
+			if (UniformType::End == opcode)
+			{
+				break;
+			}
+			
+			UniformType::Enum type;
+			uint16_t loc;
+			uint16_t num;
+			uint16_t copy;
+			ConstantBuffer::decodeOpcode(opcode, type, loc, num, copy);
+			
+			const char* data;
+			if (copy)
+			{
+				data = _constantBuffer.read(g_uniformTypeSize[type]*num);
+			}
+			else
+			{
+				UniformHandle handle;
+				memcpy(&handle, _constantBuffer.read(sizeof(UniformHandle) ), sizeof(UniformHandle) );
+				data = (const char*)m_uniforms[handle.idx];
+			}
+			
+#define CASE_IMPLEMENT_UNIFORM(_uniform, _dxsuffix, _type) \
+case UniformType::_uniform: \
+case UniformType::_uniform|BGFX_UNIFORM_FRAGMENTBIT: \
+{ \
+setShaderUniform(uint8_t(type), loc, data, num); \
+} \
+break;
+			
+			switch ( (uint32_t)type)
+			{
+				case UniformType::Mat3:
+				case UniformType::Mat3|BGFX_UNIFORM_FRAGMENTBIT: \
+				{
+					float* value = (float*)data;
+					for (uint32_t ii = 0, count = num/3; ii < count; ++ii,  loc += 3*16, value += 9)
+					{
+						Matrix4 mtx;
+						mtx.un.val[ 0] = value[0];
+						mtx.un.val[ 1] = value[1];
+						mtx.un.val[ 2] = value[2];
+						mtx.un.val[ 3] = 0.0f;
+						mtx.un.val[ 4] = value[3];
+						mtx.un.val[ 5] = value[4];
+						mtx.un.val[ 6] = value[5];
+						mtx.un.val[ 7] = 0.0f;
+						mtx.un.val[ 8] = value[6];
+						mtx.un.val[ 9] = value[7];
+						mtx.un.val[10] = value[8];
+						mtx.un.val[11] = 0.0f;
+						setShaderUniform(uint8_t(type), loc, &mtx.un.val[0], 3);
+					}
+				}
+					break;
+					
+					CASE_IMPLEMENT_UNIFORM(Int1,    I, int);
+					CASE_IMPLEMENT_UNIFORM(Vec4,   F, float);
+					CASE_IMPLEMENT_UNIFORM(Mat4, F, float);
+					
+				case UniformType::End:
+					break;
+					
+				default:
+					BX_TRACE("%4d: INVALID 0x%08x, t %d, l %d, n %d, c %d", _constantBuffer.getPos(), opcode, type, loc, num, copy);
+					break;
+			}
+			
+#undef CASE_IMPLEMENT_UNIFORM
+			
+		}
+	}
+
+	void setFrameBuffer(mtl::RenderPassDescriptor renderPassDescriptor, FrameBufferHandle _fbh, bool _msaa = true)
+	{
+		if (!isValid(_fbh) )
+		{
+			renderPassDescriptor.colorAttachments[0].texture = m_drawable.texture;
+			renderPassDescriptor.depthAttachment.texture = m_backBufferDepth;
+			renderPassDescriptor.stencilAttachment.texture = m_backBufferStencil;
+			
+			//todo: set resolve textures
+		}
+		else
+		{
+			FrameBufferMtl& frameBuffer = m_frameBuffers[_fbh.idx];
+			
+			for (uint32_t ii = 0; ii < frameBuffer.m_num; ++ii)
+			{
+				const TextureMtl& texture = m_textures[frameBuffer.m_colorHandle[ii].idx];
+				renderPassDescriptor.colorAttachments[ii].texture = texture.m_ptr;
+			}
+
+			if (isValid(frameBuffer.m_depthHandle))
+			{
+				const TextureMtl& texture = m_textures[frameBuffer.m_depthHandle.idx];
+				renderPassDescriptor.depthAttachment.texture = texture.m_ptr;
+				renderPassDescriptor.stencilAttachment.texture = texture.m_ptrStencil;
+				//TODO: stencilAttachment should be the same if packed/depth stencil format is used
+			}
+			
+			//todo: set resolve textures
+		}
+		
+		m_fbh = _fbh;
+		m_rtMsaa = _msaa;
+	}
+
+	void setDepthStencilState(uint64_t _state, uint64_t _stencil = 0)
+	{
+		_state &= BGFX_STATE_DEPTH_WRITE|BGFX_STATE_DEPTH_TEST_MASK;
+		uint32_t fstencil = unpackStencil(0, _stencil);
+		uint32_t ref = (fstencil&BGFX_STENCIL_FUNC_REF_MASK)>>BGFX_STENCIL_FUNC_REF_SHIFT;
+		_stencil &= packStencil(~BGFX_STENCIL_FUNC_REF_MASK, BGFX_STENCIL_MASK);
+	
+		bx::HashMurmur2A murmur;
+		murmur.begin();
+		murmur.add(_state);
+		murmur.add(_stencil);
+		uint32_t hash = murmur.end();
+		
+		DepthStencilState dss = m_depthStencilStateCache.find(hash);
+		if (NULL == dss)
+		{
+			DepthStencilDescriptor desc = m_depthStencilDescriptor;
+			uint32_t func = (_state&BGFX_STATE_DEPTH_TEST_MASK)>>BGFX_STATE_DEPTH_TEST_SHIFT;
+			desc.depthWriteEnabled = !!(BGFX_STATE_DEPTH_WRITE & _state);
+			desc.depthCompareFunction = s_cmpFunc[func];
+			
+			uint32_t bstencil = unpackStencil(1, _stencil);
+			uint32_t frontAndBack = bstencil != BGFX_STENCIL_NONE && bstencil != fstencil;
+			bstencil = frontAndBack ? bstencil : fstencil;
+			
+			if ( 0 != _stencil)
+			{
+				StencilDescriptor frontFaceDesc = m_frontFaceStencilDescriptor;
+				StencilDescriptor backfaceDesc = m_backFaceStencilDescriptor;
+
+				uint32_t readMask = (fstencil&BGFX_STENCIL_FUNC_RMASK_MASK)>>BGFX_STENCIL_FUNC_RMASK_SHIFT;
+				uint32_t writeMask = 0xff;
+				
+				frontFaceDesc.stencilFailureOperation = s_stencilOp[(fstencil&BGFX_STENCIL_OP_FAIL_S_MASK)>>BGFX_STENCIL_OP_FAIL_S_SHIFT];
+				frontFaceDesc.depthFailureOperation = s_stencilOp[(fstencil&BGFX_STENCIL_OP_FAIL_Z_MASK)>>BGFX_STENCIL_OP_FAIL_Z_SHIFT];
+				frontFaceDesc.depthStencilPassOperation = s_stencilOp[(fstencil&BGFX_STENCIL_OP_PASS_Z_MASK)>>BGFX_STENCIL_OP_PASS_Z_SHIFT];
+				frontFaceDesc.stencilCompareFunction  = s_cmpFunc[(fstencil&BGFX_STENCIL_TEST_MASK)>>BGFX_STENCIL_TEST_SHIFT];
+				frontFaceDesc.readMask  = readMask;
+				frontFaceDesc.writeMask = writeMask;
+				
+				backfaceDesc.stencilFailureOperation = s_stencilOp[(bstencil&BGFX_STENCIL_OP_FAIL_S_MASK)>>BGFX_STENCIL_OP_FAIL_S_SHIFT];
+				backfaceDesc.depthFailureOperation = s_stencilOp[(bstencil&BGFX_STENCIL_OP_FAIL_Z_MASK)>>BGFX_STENCIL_OP_FAIL_Z_SHIFT];
+				backfaceDesc.depthStencilPassOperation = s_stencilOp[(bstencil&BGFX_STENCIL_OP_PASS_Z_MASK)>>BGFX_STENCIL_OP_PASS_Z_SHIFT];
+				backfaceDesc.stencilCompareFunction = s_cmpFunc[(bstencil&BGFX_STENCIL_TEST_MASK)>>BGFX_STENCIL_TEST_SHIFT];
+				backfaceDesc.readMask  = readMask;
+				backfaceDesc.writeMask = writeMask;
+
+				desc.frontFaceStencil = frontFaceDesc;
+				desc.backFaceStencil = backfaceDesc;
+			}
+			else
+			{
+				desc.backFaceStencil = NULL;
+				desc.frontFaceStencil = NULL;
+			}
+
+			dss = m_device.newDepthStencilStateWithDescriptor(desc);
+			
+			m_depthStencilStateCache.add(hash, dss);
+		}
+		
+		m_renderCommandEncoder.setDepthStencilState(dss);
+		m_renderCommandEncoder.setStencilReferenceValue(ref);
+	}
+
+	SamplerState getSamplerState(uint32_t _flags)
+	{
+		_flags &= BGFX_TEXTURE_SAMPLER_BITS_MASK;
+		SamplerState sampler = m_samplerStateCache.find(_flags);
+		if (NULL == sampler)
+		{
+			
+			m_samplerDescriptor.sAddressMode = s_textureAddress[(_flags&BGFX_TEXTURE_U_MASK)>>BGFX_TEXTURE_U_SHIFT];
+			m_samplerDescriptor.tAddressMode = s_textureAddress[(_flags&BGFX_TEXTURE_V_MASK)>>BGFX_TEXTURE_V_SHIFT];
+			m_samplerDescriptor.rAddressMode = s_textureAddress[(_flags&BGFX_TEXTURE_W_MASK)>>BGFX_TEXTURE_W_SHIFT];
+			m_samplerDescriptor.minFilter = s_textureFilterMinMag[(_flags&BGFX_TEXTURE_MIN_MASK)>>BGFX_TEXTURE_MIN_SHIFT];
+			m_samplerDescriptor.magFilter = s_textureFilterMinMag[(_flags&BGFX_TEXTURE_MAG_MASK)>>BGFX_TEXTURE_MAG_SHIFT];
+			m_samplerDescriptor.mipFilter = s_textureFilterMip[(_flags&BGFX_TEXTURE_MIP_MASK)>>BGFX_TEXTURE_MIP_SHIFT];
+			m_samplerDescriptor.lodMinClamp = 0;
+			m_samplerDescriptor.lodMaxClamp = FLT_MAX;
+			m_samplerDescriptor.normalizedCoordinates = TRUE;
+			m_samplerDescriptor.maxAnisotropy =  m_maxAnisotropy;
+
+				//TODO: I haven't found how to specify this. Comparison function can be specified in shader.
+				//  On OSX this can be specified. There is no support for this on iOS right now.
+			//const uint32_t cmpFunc = (_flags&BGFX_TEXTURE_COMPARE_MASK)>>BGFX_TEXTURE_COMPARE_SHIFT;
+			//const uint8_t filter = 0 == cmpFunc ? 0 : D3D11_COMPARISON_FILTERING_BIT;
+			//m_samplerDescriptor.comparisonFunc = 0 == cmpFunc ? D3D11_COMPARISON_NEVER : s_cmpFunc[cmpFunc];
+
+			sampler = m_device.newSamplerStateWithDescriptor(m_samplerDescriptor);
+			m_samplerStateCache.add(_flags, sampler);
+		}
+		
+		return sampler;
+	}
+
+	uint32_t getBufferWidth()
+	{
+		return m_backBufferDepth.width();
+	}
+
+	uint32_t getBufferHeight()
+	{
+		return m_backBufferDepth.height();
+	}
+
+
+
+	Device			m_device;
+	CommandQueue	m_commandQueue;
+	CAMetalLayer*	m_metalLayer;
+	Texture			m_backBufferDepth;
+	Texture			m_backBufferStencil;
+	uint32_t		m_backBufferPixelFormatHash;
+	uint32_t		m_maxAnisotropy;
+
+	Buffer			m_uniformBuffer; //todo: use a pool of this
+	uint32_t		m_uniformBufferVertexOffset;
+	uint32_t		m_uniformBufferFragmentOffset;
+
+	uint16_t			m_numWindows;
+	FrameBufferHandle	m_windows[BGFX_CONFIG_MAX_FRAME_BUFFERS];
+
+	IndexBufferMtl	m_indexBuffers[BGFX_CONFIG_MAX_INDEX_BUFFERS];
+	VertexBufferMtl m_vertexBuffers[BGFX_CONFIG_MAX_VERTEX_BUFFERS];
+	ShaderMtl		m_shaders[BGFX_CONFIG_MAX_SHADERS];
+	ProgramMtl		m_program[BGFX_CONFIG_MAX_PROGRAMS];
+	TextureMtl		m_textures[BGFX_CONFIG_MAX_TEXTURES];
+	FrameBufferMtl	m_frameBuffers[BGFX_CONFIG_MAX_FRAME_BUFFERS];
+	VertexDecl		m_vertexDecls[BGFX_CONFIG_MAX_VERTEX_DECLS];
+	UniformRegistry m_uniformReg;
+	void* m_uniforms[BGFX_CONFIG_MAX_UNIFORMS];
+
+	StateCacheT<DepthStencilState>	m_depthStencilStateCache;
+	StateCacheT<SamplerState>		m_samplerStateCache;
+
+	TextVideoMem	m_textVideoMem;
+
+	FrameBufferHandle m_fbh;
+	bool m_rtMsaa;
+
+
+	// descriptors
+	RenderPipelineDescriptor	m_renderPipelineDescriptor;
+	DepthStencilDescriptor		m_depthStencilDescriptor;
+	StencilDescriptor			m_frontFaceStencilDescriptor;
+	StencilDescriptor			m_backFaceStencilDescriptor;
+	VertexDescriptor			m_vertexDescriptor;
+	TextureDescriptor			m_textureDescriptor;
+	SamplerDescriptor			m_samplerDescriptor;
+
+		// currently active objects data
+	id <CAMetalDrawable> m_drawable;
+	CommandBuffer m_commandBuffer;
+	RenderCommandEncoder m_renderCommandEncoder;
+};
+
+	static RendererContextMtl* s_renderMtl;
+
 	RendererContextI* rendererCreate()
 	{
-		return NULL;
+		s_renderMtl = BX_NEW(g_allocator, RendererContextMtl);
+		if (!s_renderMtl->init())
+		{
+			BX_DELETE(g_allocator, s_renderMtl);
+			s_renderMtl = NULL;
+		}
+		return s_renderMtl;
 	}
 
 	void rendererDestroy()
 	{
+		s_renderMtl->shutdown();
+		BX_DELETE(g_allocator, s_renderMtl);
+		s_renderMtl = NULL;
+	}
+
+	void writeString(bx::WriterI* _writer, const char* _str)
+	{
+		bx::write(_writer, _str, (int32_t)strlen(_str) );
+	}
+
+	void ShaderMtl::create(const Memory* _mem)
+	{
+		bx::MemoryReader reader(_mem->data, _mem->size);
+		
+		uint32_t magic;
+		bx::read(&reader, magic);
+		
+		switch (magic)
+		{
+			case BGFX_CHUNK_MAGIC_CSH:
+			case BGFX_CHUNK_MAGIC_FSH:
+			case BGFX_CHUNK_MAGIC_VSH:
+				break;
+				
+			default:
+				BGFX_FATAL(false, Fatal::InvalidShader, "Unknown shader format %x.", magic);
+				break;
+		}
+		
+		//bool fragment = BGFX_CHUNK_MAGIC_FSH == magic;
+		
+		uint32_t iohash;
+		bx::read(&reader, iohash);
+		
+		uint16_t count;
+		bx::read(&reader, count);
+		
+		BX_TRACE("%s Shader consts %d"
+				 , BGFX_CHUNK_MAGIC_FSH == magic ? "Fragment" : BGFX_CHUNK_MAGIC_VSH == magic ? "Vertex" : "Compute"
+				 , count
+				 );
+		
+		for (uint32_t ii = 0; ii < count; ++ii)
+		{
+			uint8_t nameSize;
+			bx::read(&reader, nameSize);
+			
+			char name[256];
+			bx::read(&reader, &name, nameSize);
+			name[nameSize] = '\0';
+			
+			uint8_t type;
+			bx::read(&reader, type);
+			
+			uint8_t num;
+			bx::read(&reader, num);
+			
+			uint16_t regIndex;
+			bx::read(&reader, regIndex);
+			
+			uint16_t regCount;
+			bx::read(&reader, regCount);
+		}
+		
+		uint32_t shaderSize;
+		bx::read(&reader, shaderSize);
+		
+		const char* code = (const char*)reader.getDataPtr();
+		bx::skip(&reader, shaderSize+1);
+		
+		int32_t codeLen = (int32_t)strlen(code);
+		int32_t tempLen = codeLen + (4<<10);
+		char* temp = (char*)alloca(tempLen);
+		bx::StaticMemoryBlockWriter writer(temp, tempLen);
+		
+		//TODO: remove this hack. some shaders have problem with half<->float conversion
+		writeString(&writer
+					, "#define half float\n"
+					 "#define half2 float2\n"
+					 "#define half3 float3\n"
+					 "#define half4 float4\n"
+					);
+
+		bx::write(&writer, code, codeLen);
+		bx::write(&writer, '\0');
+		code = temp;
+
+			//TODO: use binary format
+		Library lib = s_renderMtl->m_device.newLibraryWithSource(code);
+
+		if (NULL != lib)
+		{
+			m_function = lib.newFunctionWithName(SHADER_FUNCTION_NAME);
+		}
+		
+		BGFX_FATAL(NULL != m_function, bgfx::Fatal::InvalidShader, "Failed to create %s shader."
+				   , BGFX_CHUNK_MAGIC_FSH == magic ? "Fragment" : BGFX_CHUNK_MAGIC_VSH == magic ? "Vertex" : "Compute");
+	}
+
+	void ProgramMtl::create(const ShaderMtl* _vsh, const ShaderMtl* _fsh)
+	{
+		BX_CHECK(NULL != _vsh->m_function.m_obj, "Vertex shader doesn't exist.");
+		m_vsh = _vsh;
+		
+		if (NULL != _fsh)
+		{
+			BX_CHECK(NULL != _fsh->m_function.m_obj, "Fragment shader doesn't exist.");
+			m_fsh = _fsh;
+		}
+
+		// get attributes
+		memset(m_attributes, 0xff, sizeof(m_attributes) );
+		uint32_t used = 0;
+		uint32_t instUsed = 0;
+		if ( NULL != _vsh->m_function.m_obj )
+		{
+			for (MTLVertexAttribute* attrib in _vsh->m_function.m_obj.vertexAttributes)
+			{
+				if ( attrib.active )
+				{
+					const char* name = utf8String(attrib.name);
+					uint32_t loc = (uint32_t)attrib.attributeIndex;
+					BX_TRACE("attr %s: %d", name, loc);
+					
+					for (uint8_t ii = 0; ii < Attrib::Count; ++ii)
+					{
+						if (!strcmp(s_attribName[ii],name))
+						{
+							m_attributes[ii] = loc;
+							m_used[used++] = ii;
+							break;
+						}
+					}
+					
+					for (uint32_t ii = 0; ii < BX_COUNTOF(s_instanceDataName); ++ii)
+					{
+						if (!strcmp(s_instanceDataName[ii],name))
+						{
+							m_instanceData[instUsed++] = loc;
+						}
+					}
+					
+				}
+			}
+		}
+		m_used[used] = Attrib::Count;
+		m_instanceData[instUsed] = 0xffff;
+	}
+
+	void ProgramMtl::destroy()
+	{
+		m_vsh = NULL;
+		m_fsh = NULL;
+		
+		if (NULL != m_vshConstantBuffer)
+		{
+			ConstantBuffer::destroy(m_vshConstantBuffer);
+			m_vshConstantBuffer = NULL;
+		}
+
+		if (NULL != m_fshConstantBuffer)
+		{
+			ConstantBuffer::destroy(m_fshConstantBuffer);
+			m_fshConstantBuffer = NULL;
+		}
+		
+		m_vshConstantBufferSize = 0;
+		m_vshConstantBufferAlignmentMask = 0;
+		m_fshConstantBufferSize = 0;
+		m_fshConstantBufferAlignmentMask = 0;
+
+		m_processedUniforms = false;
+		m_numPredefined = 0;
+	}
+
+	UniformType::Enum convertMtlType(MTLDataType _type)
+	{
+		switch (_type)
+		{
+			case MTLDataTypeUInt:
+			case MTLDataTypeInt:
+				return UniformType::Int1;
+				
+			case MTLDataTypeFloat:
+			case MTLDataTypeFloat2:
+			case MTLDataTypeFloat3:
+			case MTLDataTypeFloat4:
+				return UniformType::Vec4;
+				
+			case MTLDataTypeFloat3x3:
+				return UniformType::Mat3;
+				
+			case MTLDataTypeFloat4x4:
+				return UniformType::Mat4;
+				
+		};
+		
+		BX_CHECK(false, "Unrecognized Mtl Data type 0x%04x.", _type);
+		return UniformType::End;
+	}
+
+	RenderPipelineState ProgramMtl::getRenderPipelineState(uint64_t _state, uint32_t _rgba, FrameBufferHandle _fbHandle, VertexDeclHandle _declHandle,  uint16_t _numInstanceData)
+	{
+		_state &= (BGFX_STATE_BLEND_MASK|BGFX_STATE_BLEND_EQUATION_MASK|BGFX_STATE_ALPHA_WRITE|BGFX_STATE_RGB_WRITE|BGFX_STATE_BLEND_INDEPENDENT|BGFX_STATE_MSAA);
+		
+		bool independentBlendEnable = !!(BGFX_STATE_BLEND_INDEPENDENT & _state);
+		
+		bx::HashMurmur2A murmur;
+		murmur.begin();
+		murmur.add(_state);
+		murmur.add(independentBlendEnable ? _rgba : 0);
+		if (!isValid(_fbHandle) )
+			murmur.add(s_renderMtl->m_backBufferPixelFormatHash);
+		else
+		{
+			FrameBufferMtl& frameBuffer = s_renderMtl->m_frameBuffers[_fbHandle.idx];
+			murmur.add(frameBuffer.m_pixelFormatHash);
+		}
+		murmur.add(_declHandle.idx);
+		murmur.add(_numInstanceData);
+		uint32_t hash = murmur.end();
+		
+		RenderPipelineState rps = m_renderPipelineStateCache.find(hash);
+		if ( NULL == rps )
+		{
+			RenderPipelineDescriptor& 	pipelineDesc = s_renderMtl->m_renderPipelineDescriptor;
+			reset(pipelineDesc);
+			uint32_t frameBufferAttachment = 1;
+		
+			if (!isValid(_fbHandle) )
+			{
+				pipelineDesc.colorAttachments[0].pixelFormat = s_renderMtl->m_drawable.texture.pixelFormat;
+				pipelineDesc.depthAttachmentPixelFormat = s_renderMtl->m_backBufferDepth.m_obj.pixelFormat;
+				pipelineDesc.stencilAttachmentPixelFormat = s_renderMtl->m_backBufferStencil.m_obj.pixelFormat;
+			}
+			else
+			{
+				FrameBufferMtl& frameBuffer = s_renderMtl->m_frameBuffers[_fbHandle.idx];
+				frameBufferAttachment = frameBuffer.m_num;
+				
+				for (uint32_t ii = 0; ii < frameBuffer.m_num; ++ii)
+				{
+					const TextureMtl& texture = s_renderMtl->m_textures[frameBuffer.m_colorHandle[ii].idx];
+					pipelineDesc.colorAttachments[ii].pixelFormat = texture.m_ptr.m_obj.pixelFormat;
+				}
+				
+				if (isValid(frameBuffer.m_depthHandle))
+				{
+					const TextureMtl& texture = s_renderMtl->m_textures[frameBuffer.m_depthHandle.idx];
+					pipelineDesc.depthAttachmentPixelFormat = texture.m_ptr.m_obj.pixelFormat;
+					if ( NULL != texture.m_ptrStencil)
+						pipelineDesc.stencilAttachmentPixelFormat = texture.m_ptrStencil.m_obj.pixelFormat;
+					//todo: stencil attachment should be the same as depth for packed depth/stencil
+				}
+			}
+			
+			// TODO: BGFX_STATE_MSAA using _fbHandle texture msaa values
+			const uint32_t blend    = uint32_t( (_state&BGFX_STATE_BLEND_MASK)>>BGFX_STATE_BLEND_SHIFT);
+			const uint32_t equation = uint32_t( (_state&BGFX_STATE_BLEND_EQUATION_MASK)>>BGFX_STATE_BLEND_EQUATION_SHIFT);
+			
+			const uint32_t srcRGB = (blend    )&0xf;
+			const uint32_t dstRGB = (blend>> 4)&0xf;
+			const uint32_t srcA   = (blend>> 8)&0xf;
+			const uint32_t dstA   = (blend>>12)&0xf;
+			
+			const uint32_t equRGB = (equation   )&0x7;
+			const uint32_t equA   = (equation>>3)&0x7;
+			
+			uint8_t writeMask = (_state&BGFX_STATE_ALPHA_WRITE) ? MTLColorWriteMaskAlpha : 0;
+			writeMask |= (_state&BGFX_STATE_RGB_WRITE) ? MTLColorWriteMaskRed|MTLColorWriteMaskGreen|MTLColorWriteMaskBlue : 0;
+			
+			for (uint32_t ii = 0; ii < (independentBlendEnable ? 1 : frameBufferAttachment); ++ii)
+			{
+				RenderPipelineColorAttachmentDescriptor drt = pipelineDesc.colorAttachments[ii];
+				
+				drt.blendingEnabled = !!(BGFX_STATE_BLEND_MASK & _state);
+				
+				drt.sourceRGBBlendFactor      = s_blendFactor[srcRGB][0];
+				drt.destinationRGBBlendFactor = s_blendFactor[dstRGB][0];
+				drt.rgbBlendOperation        =	s_blendEquation[equRGB];
+				
+				drt.sourceAlphaBlendFactor		= s_blendFactor[srcA][1];
+				drt.destinationAlphaBlendFactor = s_blendFactor[dstA][1];
+				drt.alphaBlendOperation			= s_blendEquation[equA];
+				
+				drt.writeMask = writeMask;
+			}
+			
+			if (independentBlendEnable)
+			{
+				for (uint32_t ii = 1, rgba = _rgba; ii < frameBufferAttachment; ++ii, rgba >>= 11)
+				{
+					RenderPipelineColorAttachmentDescriptor drt = pipelineDesc.colorAttachments[ii];
+					
+					drt.blendingEnabled = 0 != (rgba&0x7ff);
+					
+					const uint32_t src			 = (rgba   )&0xf;
+					const uint32_t dst			 = (rgba>>4)&0xf;
+					const uint32_t equationIndex = (rgba>>8)&0x7;
+					
+					drt.sourceRGBBlendFactor       = s_blendFactor[src][0];
+					drt.destinationRGBBlendFactor  = s_blendFactor[dst][0];
+					drt.rgbBlendOperation		   = s_blendEquation[equationIndex];
+					
+					drt.sourceAlphaBlendFactor		= s_blendFactor[src][1];
+					drt.destinationAlphaBlendFactor = s_blendFactor[dst][1];
+					drt.alphaBlendOperation			= s_blendEquation[equationIndex];
+					
+					drt.writeMask = writeMask;
+				}
+			}
+			
+			pipelineDesc.vertexFunction = m_vsh->m_function;
+			pipelineDesc.fragmentFunction = m_fsh->m_function;
+			
+			if (isValid(_declHandle))
+			{
+				VertexDescriptor vertexDesc = s_renderMtl->m_vertexDescriptor;
+				reset(vertexDesc);
+				
+				VertexDecl &vertexDecl = s_renderMtl->m_vertexDecls[_declHandle.idx];
+				for (uint32_t ii = 0; Attrib::Count != m_used[ii]; ++ii)
+				{
+					Attrib::Enum attr = Attrib::Enum(m_used[ii]);
+					uint32_t loc = m_attributes[attr];
+					
+					uint8_t num;
+					AttribType::Enum type;
+					bool normalized;
+					bool asInt;
+					vertexDecl.decode(attr, num, type, normalized, asInt);
+					BX_CHECK(num<=4, "num must be <=4");
+					
+					if (0xff != vertexDecl.m_attributes[attr])
+					{
+						vertexDesc.attributes[loc].format = s_attribType[type][num-1][normalized?1:0];
+						vertexDesc.attributes[loc].bufferIndex = 1;
+						vertexDesc.attributes[loc].offset = vertexDecl.m_offset[attr];
+						
+						BX_TRACE("attrib:%s format: %d offset:%d", s_attribName[attr], (int)vertexDesc.attributes[loc].format, (int)vertexDesc.attributes[loc].offset);
+					}
+					else
+					{	// missing attribute: using dummy attribute with smallest possible size
+						vertexDesc.attributes[loc].format = MTLVertexFormatUChar2;
+						vertexDesc.attributes[loc].bufferIndex = 1;
+						vertexDesc.attributes[loc].offset = 0;
+					}
+				}
+			
+				vertexDesc.layouts[1].stride = vertexDecl.getStride();
+				vertexDesc.layouts[1].stepFunction = MTLVertexStepFunctionPerVertex;
+				
+				BX_TRACE("stride: %d", (int)vertexDesc.layouts[1].stride);
+		
+				if (_numInstanceData > 0)
+				{
+					for (uint32_t ii = 0; 0xffff != m_instanceData[ii]; ++ii)
+					{
+						uint32_t loc = m_instanceData[ii];
+						vertexDesc.attributes[loc].format = MTLVertexFormatFloat4;
+						vertexDesc.attributes[loc].bufferIndex = 2;
+						vertexDesc.attributes[loc].offset = ii*16;
+					}
+					
+					vertexDesc.layouts[2].stride = _numInstanceData * 16;
+					vertexDesc.layouts[2].stepFunction = MTLVertexStepFunctionPerInstance;
+					vertexDesc.layouts[2].stepRate = 1;
+				}
+				
+				pipelineDesc.vertexDescriptor = vertexDesc;
+			}
+
+			if (m_processedUniforms)
+			{
+				rps = s_renderMtl->m_device.newRenderPipelineStateWithDescriptor(pipelineDesc);
+			}
+			else
+			{
+				m_numPredefined = 0;
+				RenderPipelineReflection reflection = NULL;
+				rps = s_renderMtl->m_device.newRenderPipelineStateWithDescriptor(pipelineDesc, MTLPipelineOptionBufferTypeInfo, &reflection);
+
+				if ( NULL != reflection )
+				{
+					for( int type =0; type<2; ++type)
+					{
+						ConstantBuffer*& constantBuffer = (type==0?m_vshConstantBuffer : m_fshConstantBuffer);
+						uint8_t fragmentBit = (1 == type ? BGFX_UNIFORM_FRAGMENTBIT : 0);
+						
+						for( MTLArgument* arg in (type==0?reflection.vertexArguments:reflection.fragmentArguments))
+						{
+							BX_TRACE("arg: %s type:%d", utf8String(arg.name), arg.type);
+							if (arg.active)
+							{
+								if (arg.type == MTLArgumentTypeBuffer && !strcmp(utf8String(arg.name),SHADER_UNIFORM_NAME) )
+								{
+									BX_CHECK( arg.index == 0, "Uniform buffer must be in the buffer slot 0.");
+									BX_CHECK( MTLDataTypeStruct == arg.bufferDataType, "%s's type must be a struct",SHADER_UNIFORM_NAME );
+									
+									if ( MTLDataTypeStruct == arg.bufferDataType )
+									{
+										if ( type == 0)
+										{
+											m_vshConstantBufferSize = (uint32_t)arg.bufferDataSize;
+											m_vshConstantBufferAlignmentMask = (uint32_t)arg.bufferAlignment - 1;
+										}
+										else
+										{
+											m_fshConstantBufferSize = (uint32_t)arg.bufferDataSize;
+											m_fshConstantBufferAlignmentMask = (uint32_t)arg.bufferAlignment - 1;
+										}
+										
+										for( MTLStructMember* uniform in arg.bufferStructType.members )
+										{
+											const char* name = utf8String(uniform.name);
+											BX_TRACE("uniform: %s type:%d", name, uniform.dataType);
+											
+											MTLDataType dataType = uniform.dataType;
+											uint32_t num = 1;
+											
+											if (dataType==MTLDataTypeArray)
+											{
+												dataType = uniform.arrayType.elementType;
+												num = (uint32_t)uniform.arrayType.arrayLength;
+											}
+											
+											switch (dataType) {
+												case MTLDataTypeFloat4 :
+													num *= 1;
+													break;
+												case MTLDataTypeFloat4x4:
+													num *= 4;
+													break;
+												case MTLDataTypeFloat3x3:
+													num *= 3;
+													break;
+												default:
+													BX_WARN(0, "Unsupported uniform MTLDataType: %d", uniform.dataType);
+													break;
+											}
+											
+											PredefinedUniform::Enum predefined = nameToPredefinedUniformEnum(name);
+											if (PredefinedUniform::Count != predefined)
+											{
+												m_predefined[m_numPredefined].m_loc   = uint32_t(uniform.offset);
+												m_predefined[m_numPredefined].m_count = uint16_t(num);
+												m_predefined[m_numPredefined].m_type  = uint8_t(predefined|fragmentBit);
+												m_numPredefined++;
+											}
+											else
+											{
+												const UniformInfo* info = s_renderMtl->m_uniformReg.find(name);
+												if (NULL != info)
+												{
+													if (NULL == constantBuffer)
+													{
+														constantBuffer = ConstantBuffer::create(1024);
+													}
+													
+													UniformType::Enum type = convertMtlType(dataType);
+													constantBuffer->writeUniformHandle((UniformType::Enum)(type|fragmentBit), uint32_t(uniform.offset), info->m_handle, uint16_t(num) );
+													BX_TRACE("store %s %d offset:%d", name, info->m_handle, uint32_t(uniform.offset));
+												}
+											}
+											
+										}
+									}
+								} else if (arg.type == MTLArgumentTypeTexture)
+								{
+									const char* name = utf8String(arg.name);
+									BX_TRACE("texture: %s index:%d", name, arg.index);
+								} else if (arg.type == MTLArgumentTypeSampler)
+								{
+									const char* name = utf8String(arg.name);
+									BX_TRACE("sampler: %s index:%d", name, arg.index);
+								}
+							}
+						}
+						if (NULL != constantBuffer)
+							constantBuffer->finish();
+					}
+				}
+				m_processedUniforms = true;
+			}
+			
+			m_renderPipelineStateCache.add(hash, rps);
+		}
+		
+		return rps;
+	}
+
+	void BufferMtl::create(uint32_t _size, void* _data, uint16_t _flags, uint16_t _stride, bool _vertex)
+	{
+		m_size = _size;
+		if ( NULL == _data )
+			m_buffer = s_renderMtl->m_device.newBufferWithLength(_size, 0);
+		else
+			m_buffer = s_renderMtl->m_device.newBufferWithBytes(_data, _size, 0);
+	}
+
+	void BufferMtl::update(uint32_t _offset, uint32_t _size, void* _data, bool _discard)
+	{
+		memcpy( (uint8_t*)m_buffer.contents() + _offset, _data, _size);
+	}
+
+	void VertexBufferMtl::create(uint32_t _size, void* _data, VertexDeclHandle _declHandle, uint16_t _flags)
+	{
+		m_decl = _declHandle;
+		uint16_t stride = isValid(_declHandle)
+		? s_renderMtl->m_vertexDecls[_declHandle.idx].m_stride
+		: 0
+		;
+		
+		BufferMtl::create(_size, _data, _flags, stride, true);
+	}
+
+	void TextureMtl::create(const Memory* _mem, uint32_t _flags, uint8_t _skip)
+	{
+		m_sampler = s_renderMtl->getSamplerState(_flags);
+		
+		ImageContainer imageContainer;
+		
+		if (imageParse(imageContainer, _mem->data, _mem->size) )
+		{
+			uint8_t numMips = imageContainer.m_numMips;
+			const uint8_t startLod = uint8_t(bx::uint32_min(_skip, numMips-1) );
+			numMips -= startLod;
+			const ImageBlockInfo& blockInfo = getBlockInfo(TextureFormat::Enum(imageContainer.m_format) );
+			const uint32_t textureWidth  = bx::uint32_max(blockInfo.blockWidth,  imageContainer.m_width >>startLod);
+			const uint32_t textureHeight = bx::uint32_max(blockInfo.blockHeight, imageContainer.m_height>>startLod);
+			
+			m_flags = _flags;
+			m_requestedFormat = (uint8_t)imageContainer.m_format;
+			m_textureFormat   = (uint8_t)imageContainer.m_format;
+			
+			const TextureFormatInfo& tfi = s_textureFormat[m_requestedFormat];
+			const bool convert = MTLPixelFormatInvalid == tfi.m_fmt;
+			
+			uint8_t bpp = getBitsPerPixel(TextureFormat::Enum(m_textureFormat) );
+			if (convert)
+			{
+				m_textureFormat = (uint8_t)TextureFormat::RGBA8;
+				bpp = 32;
+			}
+			
+			TextureDescriptor desc = s_renderMtl->m_textureDescriptor;
+			
+			if (imageContainer.m_cubeMap)
+			{
+				desc.textureType = MTLTextureTypeCube;
+			}
+			else if (imageContainer.m_depth > 1)
+			{
+				desc.textureType = MTLTextureType3D;
+			}
+			else
+			{
+				desc.textureType = MTLTextureType2D;
+			}
+			
+			m_numMips = numMips;
+			
+			const bool compressed = isCompressed(TextureFormat::Enum(m_textureFormat) );
+			
+			BX_TRACE("Texture %3d: %s (requested: %s), %dx%d%s%s."
+					 , this - s_renderMtl->m_textures
+					 , getName( (TextureFormat::Enum)m_textureFormat)
+					 , getName( (TextureFormat::Enum)m_requestedFormat)
+					 , textureWidth
+					 , textureHeight
+					 , imageContainer.m_cubeMap ? "x6" : ""
+					 , 0 != (_flags&BGFX_TEXTURE_RT_MASK) ? " (render target)" : ""
+					 );
+			
+			
+			const bool bufferOnly   = 0 != (_flags&BGFX_TEXTURE_RT_BUFFER_ONLY);
+			const bool computeWrite = 0 != (_flags&BGFX_TEXTURE_COMPUTE_WRITE);
+			const bool renderTarget = 0 != (_flags&BGFX_TEXTURE_RT_MASK);
+			const bool srgb			= 0 != (_flags&BGFX_TEXTURE_SRGB) || imageContainer.m_srgb;
+			const uint32_t msaaQuality = bx::uint32_satsub( (_flags&BGFX_TEXTURE_RT_MSAA_MASK)>>BGFX_TEXTURE_RT_MSAA_SHIFT, 1);
+//			const DXGI_SAMPLE_DESC& msaa = s_msaa[msaaQuality];
+			
+			MTLPixelFormat format = MTLPixelFormatInvalid;
+			if (srgb)
+			{
+				format      = s_textureFormat[m_textureFormat].m_fmtSrgb;
+				BX_WARN(format != MTLPixelFormatInvalid, "sRGB not supported for texture format %d", m_textureFormat);
+			}
+			
+			if (format == MTLPixelFormatInvalid)
+			{
+				// not swizzled and not sRGB, or sRGB unsupported
+				format		= s_textureFormat[m_textureFormat].m_fmt;
+			}
+			
+			desc.pixelFormat = format;
+			desc.width = textureWidth;
+			desc.height = textureHeight;
+			desc.depth = bx::uint32_max(1,imageContainer.m_depth);
+			desc.mipmapLevelCount = imageContainer.m_numMips;
+			desc.sampleCount = 1; //TODO: set samplecount -  If textureType is not MTLTextureType2DMultisample, the value must be 1.
+			
+			//TODO: set resource flags depending on usage(renderTarget/computeWrite/etc) on iOS9/OSX
+			
+			m_ptr = s_renderMtl->m_device.newTextureWithDescriptor(desc);
+			if ( m_requestedFormat == TextureFormat::D24S8 && desc.pixelFormat == MTLPixelFormatDepth32Float )
+			{
+				desc.pixelFormat = MTLPixelFormatStencil8;
+				m_ptrStencil = s_renderMtl->m_device.newTextureWithDescriptor(desc);
+			}
+			
+			uint8_t* temp = NULL;
+			if (convert)
+			{
+				temp = (uint8_t*)BX_ALLOC(g_allocator, textureWidth*textureHeight*4);
+			}
+			
+			for (uint8_t side = 0, numSides = imageContainer.m_cubeMap ? 6 : 1; side < numSides; ++side)
+			{
+				uint32_t width  = textureWidth;
+				uint32_t height = textureHeight;
+				uint32_t depth  = imageContainer.m_depth;
+				
+				for (uint8_t lod = 0, num = numMips; lod < num; ++lod)
+				{
+					width  = bx::uint32_max(1, width);
+					height = bx::uint32_max(1, height);
+					depth  = bx::uint32_max(1, depth);
+					
+					ImageMip mip;
+					if (imageGetRawData(imageContainer, side, lod+startLod, _mem->data, _mem->size, mip) )
+					{
+						const uint8_t* data = mip.m_data;
+						
+						if (convert)
+						{
+							imageDecodeToRgba8(temp
+											   , mip.m_data
+											   , mip.m_width
+											   , mip.m_height
+											   , mip.m_width*4
+											   , mip.m_format
+											   );
+							data = temp;
+						}
+						
+						MTLRegion region = { 0, 0, 0, width, height, depth};
+
+						uint32_t bytesPerRow;
+						uint32_t bytesPerImage;
+						
+						if ( compressed && !convert)
+						{
+							if ( format >= MTLPixelFormatPVRTC_RGB_2BPP && format <= MTLPixelFormatPVRTC_RGBA_4BPP_sRGB)
+							{
+								bytesPerRow = 0;
+								bytesPerImage = 0;
+							}
+							else
+							{
+								bytesPerRow = (mip.m_width / blockInfo.blockWidth )*mip.m_blockSize;
+								bytesPerImage = (desc.textureType == MTLTextureType3D) ? (mip.m_height/blockInfo.blockHeight)*bytesPerRow : 0;
+							}
+						}
+						else
+						{
+							bytesPerRow = width * bpp / 8;
+							bytesPerImage = (desc.textureType == MTLTextureType3D) ? width * height * bpp / 8 : 0;
+						}
+						
+						m_ptr.replaceRegion(region, lod, side, data, bytesPerRow, bytesPerImage);
+					}
+					else if (!computeWrite)
+					{
+						//TODO: do we need to clear to zero??
+					}
+					
+					width  >>= 1;
+					height >>= 1;
+					depth  >>= 1;
+				}
+			}
+			
+			if (NULL != temp)
+			{
+				BX_FREE(g_allocator, temp);
+			}
+		}
+	}
+
+	void TextureMtl::update(uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem)
+	{
+		MTLRegion region = { _rect.m_x, _rect.m_y, _z, _rect.m_width, _rect.m_height, _depth};
+		
+		const uint32_t bpp    = getBitsPerPixel(TextureFormat::Enum(m_textureFormat) );
+		const uint32_t rectpitch = _rect.m_width*bpp/8;
+		const uint32_t srcpitch  = UINT16_MAX == _pitch ? rectpitch : _pitch;
+		
+		const bool convert = m_textureFormat != m_requestedFormat;
+		
+		uint8_t* data = _mem->data;
+		uint8_t* temp = NULL;
+		
+		if (convert)
+		{
+			temp = (uint8_t*)BX_ALLOC(g_allocator, rectpitch*_rect.m_height);
+			imageDecodeToBgra8(temp, data, _rect.m_width, _rect.m_height, srcpitch, m_requestedFormat);
+			data = temp;
+		}
+		
+		m_ptr.replaceRegion(region, _mip, _side, data, srcpitch, srcpitch * _rect.m_height);
+		
+		if (NULL != temp)
+		{
+			BX_FREE(g_allocator, temp);
+		}
+	}
+
+	void TextureMtl::commit(uint8_t _stage, uint32_t _flags)
+	{
+		//TODO: vertex or fragment stage?
+		s_renderMtl->m_renderCommandEncoder.setFragmentTexture(m_ptr, _stage);
+		s_renderMtl->m_renderCommandEncoder.setFragmentSamplerState(0 == (BGFX_SAMPLER_DEFAULT_FLAGS & _flags)
+																	? s_renderMtl->getSamplerState(_flags)
+																	: m_sampler, _stage);
+	}
+
+	void FrameBufferMtl::create(uint8_t _num, const TextureHandle* _handles)
+	{
+		m_num = 0;
+		for (uint32_t ii = 0; ii < _num; ++ii)
+		{
+			TextureHandle handle = _handles[ii];
+			if (isValid(handle) )
+			{
+				const TextureMtl& texture = s_renderMtl->m_textures[handle.idx];
+				
+				//TODO: separate stencil buffer? or just use packed depth/stencil (which is not available on iOS8)
+				if (isDepth( (TextureFormat::Enum)texture.m_textureFormat) )
+				{
+					m_depthHandle = handle;
+				}
+				else
+				{
+					m_colorHandle[m_num] = handle;
+					m_num++;
+				}
+			}
+		}
+
+		bx::HashMurmur2A murmur;
+		murmur.begin();
+
+		murmur.add(m_num);
+		for (uint32_t ii = 0; ii < m_num; ++ii)
+		{
+			const TextureMtl& texture = s_renderMtl->m_textures[m_colorHandle[ii].idx];
+			murmur.add((uint32_t)texture.m_ptr.pixelFormat());
+		}
+		const TextureMtl& depthTexture = s_renderMtl->m_textures[m_depthHandle.idx];
+		murmur.add((uint32_t)depthTexture.m_ptr.pixelFormat());
+		murmur.add((uint32_t)MTLPixelFormatInvalid); //stencil
+	
+		m_pixelFormatHash = murmur.end();
+	}
+
+	void FrameBufferMtl::create(uint16_t _denseIdx, void* _nwh, uint32_t _width, uint32_t _height, TextureFormat::Enum _depthFormat)
+	{
+		BX_WARN(false, "FrameBufferMtl::create not yet implemented");
+	}
+
+	void FrameBufferMtl::postReset()
+	{
+		BX_WARN(false, "FrameBufferMtl::postReset not yet implemented");
+		//TODO: what should we do here?
+	}
+
+	uint16_t FrameBufferMtl::destroy()
+	{
+		m_num = 0;
+		m_depthHandle.idx = invalidHandle;
+		
+		uint16_t denseIdx = m_denseIdx;
+		m_denseIdx = UINT16_MAX;
+		
+		return denseIdx;
 	}
+
+	void RendererContextMtl::submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter) BX_OVERRIDE
+	{
+		m_commandBuffer = m_commandQueue.commandBuffer();
+		retain(m_commandBuffer); // keep alive to be useable at 'flip'
+
+		//TODO: multithreading with multiple commandbuffer
+		// is there a FAST way to tell which view is active?
+
+		//TODO: acquire CAMetalDrawable just before we really need it. When we are using an encoder with target metalLayer's texture
+		m_drawable = m_metalLayer.nextDrawable;
+		retain(m_drawable); // keep alive to be useable at 'flip'
+
+		m_uniformBufferVertexOffset = 0;
+		m_uniformBufferFragmentOffset = 0;
+
+		updateResolution(_render->m_resolution);
+
+		int64_t elapsed = -bx::getHPCounter();
+		int64_t captureElapsed = 0;
+
+		if (_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) )
+		{
+			//TODO
+			//m_gpuTimer.begin();
+		}
+
+		if (0 < _render->m_iboffset)
+		{
+			TransientIndexBuffer* ib = _render->m_transientIb;
+			m_indexBuffers[ib->handle.idx].update(0, _render->m_iboffset, ib->data);
+		}
+
+		if (0 < _render->m_vboffset)
+		{
+			TransientVertexBuffer* vb = _render->m_transientVb;
+			m_vertexBuffers[vb->handle.idx].update(0, _render->m_vboffset, vb->data);
+		}
+
+		_render->sort();
+
+		RenderDraw currentState;
+		currentState.clear();
+		currentState.m_flags = BGFX_STATE_NONE;
+		currentState.m_stencil = packStencil(BGFX_STENCIL_NONE, BGFX_STENCIL_NONE);
+
+		_render->m_hmdInitialized = false;
+
+		const bool hmdEnabled = false;
+		ViewState viewState(_render, hmdEnabled);
+		uint32_t blendFactor = 0;
+
+		bool wireframe = !!(_render->m_debug&BGFX_DEBUG_WIREFRAME);
+
+		//TODO: REMOVE THIS - TEMPORARY HACK
+		m_textureDescriptor.textureType = MTLTextureType2D;
+		m_textureDescriptor.pixelFormat = MTLPixelFormatRGBA8Unorm;
+		m_textureDescriptor.width = 4;
+		m_textureDescriptor.height = 4;
+		m_textureDescriptor.depth = 1;
+		m_textureDescriptor.mipmapLevelCount = 1;
+		m_textureDescriptor.sampleCount = 1; //TODO: set samplecount -  If textureType is not MTLTextureType2DMultisample, the value must be 1.
+		Texture zeroTexture = m_device.newTextureWithDescriptor(m_textureDescriptor);
+
+		uint16_t programIdx = invalidHandle;
+		SortKey key;
+		uint8_t view = 0xff;
+		FrameBufferHandle fbh = BGFX_INVALID_HANDLE;
+
+		//ASK: why should we use this? It changes topology, so possible renders a big mess, doesn't it?
+		//const uint64_t primType = _render->m_debug&BGFX_DEBUG_WIREFRAME ? BGFX_STATE_PT_LINES : 0;
+		const uint64_t primType = 0;
+		uint8_t primIndex = uint8_t(primType>>BGFX_STATE_PT_SHIFT);
+		PrimInfo prim = s_primInfo[primIndex];
+
+		ProgramMtl* currentProgram = NULL;
+		mtl::RenderCommandEncoder  rce;
+
+		bool wasCompute = false;
+		bool viewHasScissor = false;
+		Rect viewScissorRect;
+		viewScissorRect.clear();
+
+		uint32_t statsNumPrimsSubmitted[BX_COUNTOF(s_primInfo)] = {};
+		uint32_t statsNumPrimsRendered[BX_COUNTOF(s_primInfo)] = {};
+		uint32_t statsNumInstances[BX_COUNTOF(s_primInfo)] = {};
+		uint32_t statsNumDrawIndirect[BX_COUNTOF(s_primInfo)] = {};
+		uint32_t statsNumIndices = 0;
+		uint32_t statsKeyType[2] = {};
+
+		if (0 == (_render->m_debug&BGFX_DEBUG_IFH) )
+		{
+			bool viewRestart = false;
+			uint8_t eye = 0;
+			uint8_t restartState = 0;
+			viewState.m_rect = _render->m_rect[0];
+	
+			int32_t numItems = _render->m_num;
+			for (int32_t item = 0, restartItem = numItems; item < numItems || restartItem < numItems;)
+			{
+				const bool isCompute = key.decode(_render->m_sortKeys[item], _render->m_viewRemap);
+				statsKeyType[isCompute]++;
+		
+				const bool viewChanged = 0
+					|| key.m_view != view
+					|| item == numItems
+				;
+				const RenderItem& renderItem = _render->m_renderItem[_render->m_sortValues[item] ];
+				++item;
+		
+				if (viewChanged)
+				{
+					if (1 == restartState)
+					{
+						restartState = 2;
+						item = restartItem;
+						restartItem = numItems;
+						view = 0xff;
+						continue;
+					}
+			
+					view = key.m_view;
+					programIdx = invalidHandle;
+			
+			
+					viewRestart = ( (BGFX_VIEW_STEREO == (_render->m_viewFlags[view] & BGFX_VIEW_STEREO) ) );
+					viewRestart &= hmdEnabled;
+					if (viewRestart)
+					{
+						if (0 == restartState)
+						{
+							restartState = 1;
+							restartItem  = item - 1;
+						}
+						
+						eye = (restartState - 1) & 1;
+						restartState &= 1;
+					}
+					else
+					{
+						eye = 0;
+					}
+			
+					viewState.m_rect = _render->m_rect[view];
+					if (viewRestart)
+					{
+						viewState.m_rect.m_x = eye * (viewState.m_rect.m_width+1)/2;
+						viewState.m_rect.m_width /= 2;
+					}
+			
+					const Rect& scissorRect = _render->m_scissor[view];
+					viewHasScissor = !scissorRect.isZero();
+					viewScissorRect = viewHasScissor ? scissorRect : viewState.m_rect;
+					Clear& clr = _render->m_clear[view];
+			
+					mtl::RenderPassDescriptor renderPassDescriptor = newRenderPassDescriptor();
+			
+					//todo: check FB size
+					uint32_t width  = getBufferWidth();
+					uint32_t height = getBufferHeight();
+					Rect viewRect = viewState.m_rect;
+					bool fullscreenRect = (0 == viewRect.m_x && 0 == viewRect.m_y	&&  width  == viewRect.m_width	&&  height == viewRect.m_height);
+			
+					//TODO/OPTIMIZATION: merge views with same target framebuffer into one renderPass
+					
+					fbh = _render->m_fb[view];
+					setFrameBuffer(renderPassDescriptor, fbh);
+			
+					RenderPassColorAttachmentDescriptor colorAttachment0 = renderPassDescriptor.colorAttachments[0];
+					if (BGFX_CLEAR_COLOR & clr.m_flags)
+					{
+						if (BGFX_CLEAR_COLOR_USE_PALETTE & clr.m_flags)
+						{
+							uint8_t index = (uint8_t)bx::uint32_min(BGFX_CONFIG_MAX_CLEAR_COLOR_PALETTE-1, clr.m_index[0]);
+							const float* rgba = _render->m_clearColor[index];
+							const float rr = rgba[0];
+							const float gg = rgba[1];
+							const float bb = rgba[2];
+							const float aa = rgba[3];
+							colorAttachment0.clearColor = MTLClearColorMake(rr,gg,bb,aa);
+						}
+						else
+						{
+							float rr = clr.m_index[0]*1.0f/255.0f;
+							float gg = clr.m_index[1]*1.0f/255.0f;
+							float bb = clr.m_index[2]*1.0f/255.0f;
+							float aa = clr.m_index[3]*1.0f/255.0f;
+							colorAttachment0.clearColor = MTLClearColorMake(rr,gg,bb,aa);
+						}
+						
+						colorAttachment0.loadAction = MTLLoadActionClear;
+					}
+					else
+						colorAttachment0.loadAction = MTLLoadActionLoad;
+				
+					//TODO: optimize store actions use discard flag
+					RenderPassDepthAttachmentDescriptor depthAttachment = renderPassDescriptor.depthAttachment;
+					if ( NULL != depthAttachment.texture)
+					{
+						depthAttachment.clearDepth = clr.m_depth;
+						depthAttachment.loadAction = (BGFX_CLEAR_DEPTH & clr.m_flags) ? MTLLoadActionClear : MTLLoadActionLoad;
+						depthAttachment.storeAction = MTLStoreActionStore;
+					}
+			
+					RenderPassStencilAttachmentDescriptor stencilAttachment = renderPassDescriptor.stencilAttachment;
+					if ( NULL != stencilAttachment.texture )
+					{
+						stencilAttachment.clearStencil = clr.m_stencil;
+						stencilAttachment.loadAction = (BGFX_CLEAR_STENCIL & clr.m_flags) ? MTLLoadActionClear : MTLLoadActionLoad;
+						stencilAttachment.storeAction = MTLStoreActionStore;
+					}
+			
+					if ( 0 != m_renderCommandEncoder)
+					{
+						m_renderCommandEncoder.endEncoding();
+					}
+					rce = m_commandBuffer.renderCommandEncoderWithDescriptor(renderPassDescriptor);
+					m_renderCommandEncoder = rce;
+					MTL_RELEASE(renderPassDescriptor);
+			
+					//TODO: REMOVE THIS!!!!
+					// TERRIBLE HACK TO SUPPRESS DEBUG LAYER WARNING ABOUT MISSING TEXTURE/SAMPLER AT 0 in 20-nanovg
+					m_renderCommandEncoder.setFragmentTexture(zeroTexture, 0);
+					m_renderCommandEncoder.setFragmentSamplerState(getSamplerState(0), 0);
+			
+					rce.setTriangleFillMode(wireframe? MTLTriangleFillModeLines : MTLTriangleFillModeFill);
+			
+					if (BX_ENABLED(BGFX_CONFIG_DEBUG_MTL) )
+					{
+						if ( item != 1) //ASK: better check ? I don't get the whole restart thing
+							rce.popDebugGroup();
+						
+						rce.pushDebugGroup(s_viewName[view]);
+					}
+			
+					MTLViewport vp;
+					vp.originX = viewState.m_rect.m_x;
+					vp.originY = viewState.m_rect.m_y;
+					vp.width    = viewState.m_rect.m_width;
+					vp.height   = viewState.m_rect.m_height;
+					vp.znear = 0.0f;
+					vp.zfar = 1.0f;
+					rce.setViewport(vp);
+			
+					if (BGFX_CLEAR_NONE != (clr.m_flags & BGFX_CLEAR_MASK) && !fullscreenRect)
+					{	//TODO: fallback to clear with quad
+						//clearQuad(_clearQuad, viewState.m_rect, clr, _render->m_clearColor);
+					}
+				}
+		
+		//TODO: iscompute
+		
+				bool resetState = viewChanged || wasCompute;
+		
+				if (wasCompute)
+				{
+					wasCompute = false;
+			
+					programIdx = invalidHandle;
+					currentProgram = NULL;
+			
+					//TODO
+					//invalidateCompute();
+				}
+		
+				const RenderDraw& draw = renderItem.draw;
+		
+				const uint64_t newFlags = draw.m_flags;
+				uint64_t changedFlags = currentState.m_flags ^ draw.m_flags;
+				currentState.m_flags = newFlags;
+		
+				const uint64_t newStencil = draw.m_stencil;
+				uint64_t changedStencil = currentState.m_stencil ^ draw.m_stencil;
+				currentState.m_stencil = newStencil;
+		
+				if (resetState)
+				{
+					currentState.clear();
+					currentState.m_scissor = !draw.m_scissor;
+					changedFlags = BGFX_STATE_MASK;
+					changedStencil = packStencil(BGFX_STENCIL_MASK, BGFX_STENCIL_MASK);
+					currentState.m_flags = newFlags;
+					currentState.m_stencil = newStencil;
+			
+					programIdx = invalidHandle;
+					setDepthStencilState(newFlags, packStencil(BGFX_STENCIL_DEFAULT, BGFX_STENCIL_DEFAULT));
+			
+					const uint64_t pt = newFlags&BGFX_STATE_PT_MASK;
+					primIndex = uint8_t(pt>>BGFX_STATE_PT_SHIFT);
+				}
+		
+				if (prim.m_type != s_primInfo[primIndex].m_type)
+				{
+					prim = s_primInfo[primIndex];
+				}
+		
+				uint16_t scissor = draw.m_scissor;
+				if (currentState.m_scissor != scissor)
+				{
+					currentState.m_scissor = scissor;
+			
+					MTLScissorRect rc;
+					if (UINT16_MAX == scissor)
+					{
+						if (viewHasScissor)
+						{
+							rc.x   = viewScissorRect.m_x;
+							rc.y    = viewScissorRect.m_y;
+							rc.width  = viewScissorRect.m_width;
+							rc.height = viewScissorRect.m_height;
+						}
+						else
+						{   // can't disable: set to view rect
+							rc.x   = viewState.m_rect.m_x;
+							rc.y    = viewState.m_rect.m_y;
+							rc.width  = viewState.m_rect.m_width;
+							rc.height = viewState.m_rect.m_height;
+						}
+					}
+					else
+					{
+						Rect scissorRect;
+						scissorRect.intersect(viewScissorRect, _render->m_rectCache.m_cache[scissor]);
+						rc.x   = scissorRect.m_x;
+						rc.y    = scissorRect.m_y;
+						rc.width  = scissorRect.m_width;
+						rc.height = scissorRect.m_height;
+					}
+					rce.setScissorRect(rc);
+				}
+		
+				if ( (BGFX_STATE_DEPTH_WRITE|BGFX_STATE_DEPTH_TEST_MASK) & changedFlags
+					|| 0 != changedStencil)
+				{
+					setDepthStencilState(newFlags,newStencil);
+				}
+		
+				if ( (0
+					  | BGFX_STATE_CULL_MASK
+					  | BGFX_STATE_ALPHA_REF_MASK
+					  | BGFX_STATE_PT_MASK
+					  //| BGFX_STATE_POINT_SIZE_MASK //TODO: not supported. could be supported with uniform
+					  ) & changedFlags)
+				{
+					if (BGFX_STATE_CULL_MASK & changedFlags)
+					{
+						const uint64_t pt = newFlags&BGFX_STATE_CULL_MASK;
+						uint8_t cullIndex = uint8_t(pt>>BGFX_STATE_CULL_SHIFT);
+						rce.setCullMode(s_cullMode[cullIndex]);
+					}
+			
+					if (BGFX_STATE_ALPHA_REF_MASK & changedFlags)
+					{
+						uint32_t ref = (newFlags&BGFX_STATE_ALPHA_REF_MASK)>>BGFX_STATE_ALPHA_REF_SHIFT;
+						viewState.m_alphaRef = ref/255.0f;
+					}
+			
+					const uint64_t pt = newFlags&BGFX_STATE_PT_MASK;
+					primIndex = uint8_t(pt>>BGFX_STATE_PT_SHIFT);
+					if (prim.m_type != s_primInfo[primIndex].m_type)
+					{
+						prim = s_primInfo[primIndex];
+					}
+				}
+		
+				if ( (blendFactor != draw.m_rgba) && !(newFlags & BGFX_STATE_BLEND_INDEPENDENT) )
+				{
+					const uint32_t rgba = draw.m_rgba;
+					float rr = ( (rgba>>24)     )/255.0f;
+					float gg = ( (rgba>>16)&0xff)/255.0f;
+					float bb = ( (rgba>> 8)&0xff)/255.0f;
+					float aa = ( (rgba    )&0xff)/255.0f;
+					rce.setBlendColor(rr,gg,bb,aa);
+					
+					blendFactor = draw.m_rgba;
+				}
+		
+				bool programChanged = false;
+				bool constantsChanged = draw.m_constBegin < draw.m_constEnd;
+				rendererUpdateUniforms(this, _render->m_constantBuffer, draw.m_constBegin, draw.m_constEnd);
+		
+				if (key.m_program != programIdx ||
+					(BGFX_STATE_BLEND_MASK|BGFX_STATE_BLEND_EQUATION_MASK|BGFX_STATE_ALPHA_WRITE|BGFX_STATE_RGB_WRITE|BGFX_STATE_BLEND_INDEPENDENT|BGFX_STATE_MSAA) & changedFlags ||
+					currentState.m_vertexBuffer.idx != draw.m_vertexBuffer.idx ||
+					currentState.m_vertexDecl.idx != draw.m_vertexDecl.idx ||
+					currentState.m_instanceDataStride != draw.m_instanceDataStride ||
+					( (blendFactor != draw.m_rgba) && !!(newFlags & BGFX_STATE_BLEND_INDEPENDENT) ) )
+				{
+					programIdx = key.m_program;
+					currentState.m_vertexDecl         = draw.m_vertexDecl;
+					currentState.m_instanceDataStride = draw.m_instanceDataStride;
+			
+					if (invalidHandle == programIdx)
+					{
+						currentProgram = NULL;
+						continue;
+					}
+					else
+					{
+						ProgramMtl& program = m_program[programIdx];
+						currentProgram = &program;
+				
+						uint16_t handle = draw.m_vertexBuffer.idx;
+						const VertexBufferMtl& vb = m_vertexBuffers[handle];
+						VertexDeclHandle decl;
+						decl.idx = !isValid(vb.m_decl) ? draw.m_vertexDecl.idx : vb.m_decl.idx;
+				
+						RenderPipelineState pipelineState = program.getRenderPipelineState(newFlags, draw.m_rgba, fbh, decl, draw.m_instanceDataStride/16);
+						if ( NULL == pipelineState )
+						{  //call with invalid program
+							currentProgram = NULL;
+							programIdx = invalidHandle;
+							continue;
+						}
+				
+						rce.setRenderPipelineState(pipelineState);
+					}
+			
+					programChanged =
+					constantsChanged = true;
+				}
+		
+				if (invalidHandle != programIdx)
+				{
+					ProgramMtl& program = m_program[programIdx];
+			
+					uint32_t vertexUniformBufferSize = program.m_vshConstantBufferSize;
+					uint32_t fragmentUniformBufferSize = program.m_fshConstantBufferSize;
+			
+					if ( vertexUniformBufferSize )
+					{
+						m_uniformBufferVertexOffset = BX_ALIGN_MASK(m_uniformBufferVertexOffset, program.m_vshConstantBufferAlignmentMask);
+						rce.setVertexBuffer(m_uniformBuffer, m_uniformBufferVertexOffset, 0);
+					}
+			
+					m_uniformBufferFragmentOffset = m_uniformBufferVertexOffset + vertexUniformBufferSize;
+					if ( fragmentUniformBufferSize )
+					{
+						m_uniformBufferFragmentOffset = BX_ALIGN_MASK(m_uniformBufferFragmentOffset, program.m_fshConstantBufferAlignmentMask);
+						rce.setFragmentBuffer(m_uniformBuffer, m_uniformBufferFragmentOffset, 0);
+					}
+			
+					//TODO: create new UniformBuffer when not enough place for next buffer
+			
+					if (constantsChanged)
+					{
+						ConstantBuffer* vcb = program.m_vshConstantBuffer;
+						if (NULL != vcb)
+						{
+							commit(*vcb);
+						}
+				
+						ConstantBuffer* fcb = program.m_fshConstantBuffer;
+						if (NULL != fcb)
+						{
+							commit(*fcb);
+						}
+					}
+			
+					viewState.setPredefined<4>(this, view, eye, program, _render, draw);
+			
+					m_uniformBufferFragmentOffset += fragmentUniformBufferSize;
+					m_uniformBufferVertexOffset = m_uniformBufferFragmentOffset;
+				}
+		
+				{
+					for (uint8_t stage = 0; stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS; ++stage)
+					{
+						const Binding& sampler = draw.m_bind[stage];
+						Binding& current = currentState.m_bind[stage];
+						if (current.m_idx != sampler.m_idx
+							||  current.m_un.m_draw.m_flags != sampler.m_un.m_draw.m_flags
+							||  programChanged)
+						{
+							if (invalidHandle != sampler.m_idx)
+							{
+								TextureMtl& texture = m_textures[sampler.m_idx];
+								texture.commit(stage, sampler.m_un.m_draw.m_flags);
+							}
+						}
+						
+						current = sampler;
+					}
+				}
+		
+				if (currentState.m_vertexBuffer.idx       != draw.m_vertexBuffer.idx
+					||  currentState.m_startVertex			  != draw.m_startVertex
+					||  currentState.m_instanceDataBuffer.idx != draw.m_instanceDataBuffer.idx
+					||  currentState.m_instanceDataOffset     != draw.m_instanceDataOffset
+					)
+				{
+					currentState.m_vertexBuffer           = draw.m_vertexBuffer;
+					currentState.m_startVertex           = draw.m_startVertex;
+					currentState.m_instanceDataBuffer.idx = draw.m_instanceDataBuffer.idx;
+					currentState.m_instanceDataOffset     = draw.m_instanceDataOffset;
+			
+					uint16_t handle = draw.m_vertexBuffer.idx;
+					if (invalidHandle != handle)
+					{
+						const VertexBufferMtl& vb = m_vertexBuffers[handle];
+				
+						uint16_t decl = !isValid(vb.m_decl) ? draw.m_vertexDecl.idx : vb.m_decl.idx;
+						const VertexDecl& vertexDecl = m_vertexDecls[decl];
+						uint32_t offset = draw.m_startVertex  * vertexDecl.getStride();
+				
+						rce.setVertexBuffer(vb.m_buffer, offset, 1);
+				
+						if (isValid(draw.m_instanceDataBuffer) )
+						{
+							const VertexBufferMtl& inst = m_vertexBuffers[draw.m_instanceDataBuffer.idx];
+							rce.setVertexBuffer(inst.m_buffer, draw.m_instanceDataOffset, 2);
+						}
+					}
+				}
+		
+				if (isValid(currentState.m_vertexBuffer) )
+				{
+					uint32_t numVertices = draw.m_numVertices;
+					if (UINT32_MAX == numVertices)
+					{
+						const VertexBufferMtl& vb = m_vertexBuffers[currentState.m_vertexBuffer.idx];
+						uint16_t decl = !isValid(vb.m_decl) ? draw.m_vertexDecl.idx : vb.m_decl.idx;
+						const VertexDecl& vertexDecl = m_vertexDecls[decl];
+						numVertices = vb.m_size/vertexDecl.m_stride;
+					}
+					
+					uint32_t numIndices        = 0;
+					uint32_t numPrimsSubmitted = 0;
+					uint32_t numInstances      = 0;
+					uint32_t numPrimsRendered  = 0;
+					uint32_t numDrawIndirect   = 0;
+			
+					if (isValid(draw.m_indirectBuffer) )
+					{
+						 // TODO: indirect draw
+					}
+					else
+					{
+						if (isValid(draw.m_indexBuffer) )
+						{
+							const IndexBufferMtl& ib = m_indexBuffers[draw.m_indexBuffer.idx];
+							MTLIndexType indexType = 0 == (ib.m_flags & BGFX_BUFFER_INDEX32) ? MTLIndexTypeUInt16 : MTLIndexTypeUInt32;
+					
+							if (UINT32_MAX == draw.m_numIndices)
+							{
+								const uint32_t indexSize = 0 == (ib.m_flags & BGFX_BUFFER_INDEX32) ? 2 : 4;
+								numIndices        = ib.m_size/indexSize;
+								numPrimsSubmitted = numIndices/prim.m_div - prim.m_sub;
+								numInstances      = draw.m_numInstances;
+								numPrimsRendered  = numPrimsSubmitted*draw.m_numInstances;
+						
+								rce.drawIndexedPrimitives(prim.m_type, numIndices, indexType, ib.m_buffer, 0, draw.m_numInstances);
+							}
+							else if (prim.m_min <= draw.m_numIndices)
+							{
+								const uint32_t indexSize = 0 == (ib.m_flags & BGFX_BUFFER_INDEX32) ? 2 : 4;
+								numIndices        = draw.m_numIndices;
+								numPrimsSubmitted = numIndices/prim.m_div - prim.m_sub;
+								numInstances      = draw.m_numInstances;
+								numPrimsRendered  = numPrimsSubmitted*draw.m_numInstances;
+						
+								rce.drawIndexedPrimitives(prim.m_type, numIndices, indexType, ib.m_buffer, draw.m_startIndex * indexSize,numInstances);
+							}
+						}
+						else
+						{
+							numPrimsSubmitted = numVertices/prim.m_div - prim.m_sub;
+							numInstances      = draw.m_numInstances;
+							numPrimsRendered  = numPrimsSubmitted*draw.m_numInstances;
+					
+							rce.drawPrimitives(prim.m_type, 0, draw.m_numVertices, draw.m_numInstances);
+						}
+					}
+			
+					statsNumPrimsSubmitted[primIndex] += numPrimsSubmitted;
+					statsNumPrimsRendered[primIndex]  += numPrimsRendered;
+					statsNumInstances[primIndex]      += numInstances;
+					statsNumDrawIndirect[primIndex]   += numDrawIndirect;
+					statsNumIndices                   += numIndices;
+				}
+			}
+	
+			if (wasCompute)
+			{
+				//TODO
+				//invalidateCompute();
+			}
+	
+			if (0 < _render->m_num)
+			{
+				//ASK: we now using one commandBuffer that is commited in flush. Should we implement this?
+				//if (0 != (m_resolution.m_flags & BGFX_RESET_FLUSH_AFTER_RENDER) )
+				{
+					// ????
+					//deviceCtx->Flush();
+				}
+		
+				captureElapsed = -bx::getHPCounter();
+				//TODO
+				//capture();
+				captureElapsed += bx::getHPCounter();
+			}
+		}
+
+		if (BX_ENABLED(BGFX_CONFIG_DEBUG_MTL) )
+		{
+			if ( 0 < _render->m_num)
+				rce.popDebugGroup();
+		}
+
+		//TODO: debug stats
+		int64_t now = bx::getHPCounter();
+		elapsed += now;
+
+		static int64_t last = now;
+		int64_t frameTime = now - last;
+		last = now;
+
+		static int64_t min = frameTime;
+		static int64_t max = frameTime;
+		min = min > frameTime ? frameTime : min;
+		max = max < frameTime ? frameTime : max;
+
+		if (_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) )
+		{
+			rce.pushDebugGroup("debugstats");
+
+			static uint32_t maxGpuLatency = 0;
+			static double   maxGpuElapsed = 0.0f;
+			double elapsedGpuMs = 0.0;
+	
+			//TODO: gputimer
+			/*			m_gpuTimer.end();
+	 
+			 while (m_gpuTimer.get() )
+			 {
+				double toGpuMs = 1000.0 / double(m_gpuTimer.m_frequency);
+				elapsedGpuMs   = m_gpuTimer.m_elapsed * toGpuMs;
+				maxGpuElapsed  = elapsedGpuMs > maxGpuElapsed ? elapsedGpuMs : maxGpuElapsed;
+			 }
+			 maxGpuLatency = bx::uint32_imax(maxGpuLatency, m_gpuTimer.m_control.available()-1);
+			 */
+			TextVideoMem& tvm = m_textVideoMem;
+	
+			static int64_t next = now;
+	
+			if (now >= next)
+			{
+				next = now + bx::getHPFrequency();
+
+				double freq = double(bx::getHPFrequency() );
+				double toMs = 1000.0/freq;
+		
+				tvm.clear();
+				uint16_t pos = 0;
+				tvm.printf(0, pos++, BGFX_CONFIG_DEBUG ? 0x89 : 0x8f, " %s / " BX_COMPILER_NAME " / " BX_CPU_NAME " / " BX_ARCH_NAME " / " BX_PLATFORM_NAME " "
+				   , getRendererName()
+				   );
+		
+				//const D3DADAPTER_IDENTIFIER9& identifier = m_identifier;
+				//tvm.printf(0, pos++, 0x0f, " Device: %s (%s)", identifier.Description, identifier.Driver);
+		
+				pos = 10;
+				tvm.printf(10, pos++, 0x8e, "       Frame: %7.3f, % 7.3f \x1f, % 7.3f \x1e [ms] / % 6.2f FPS "
+						   , double(frameTime)*toMs
+						   , double(min)*toMs
+						   , double(max)*toMs
+						   , freq/frameTime
+						   );
+		
+				/*				
+				 const uint32_t msaa = (m_resolution.m_flags&BGFX_RESET_MSAA_MASK)>>BGFX_RESET_MSAA_SHIFT;
+				 tvm.printf(10, pos++, 0x8e, " Reset flags: [%c] vsync, [%c] MSAAx%d, [%c] MaxAnisotropy "
+				 , !!(m_resolution.m_flags&BGFX_RESET_VSYNC) ? '\xfe' : ' '
+					, 0 != msaa ? '\xfe' : ' '
+				 , 1<<msaa
+				 , !!(m_resolution.m_flags&BGFX_RESET_MAXANISOTROPY) ? '\xfe' : ' '
+				 );
+		 */
+				double elapsedCpuMs = double(elapsed)*toMs;
+				tvm.printf(10, pos++, 0x8e, "   Submitted: %4d (draw %4d, compute %4d) / CPU %3.4f [ms] %c GPU %3.4f [ms] (latency %d)"
+						   , _render->m_num
+						   , statsKeyType[0]
+						   , statsKeyType[1]
+						   , elapsedCpuMs
+						   , elapsedCpuMs > maxGpuElapsed ? '>' : '<'
+						   , maxGpuElapsed
+						   , maxGpuLatency
+						   );
+				maxGpuLatency = 0;
+				maxGpuElapsed = 0.0;
+		
+				for (uint32_t ii = 0; ii < BX_COUNTOF(s_primName); ++ii)
+				{
+					tvm.printf(10, pos++, 0x8e, "   %9s: %7d (#inst: %5d), submitted: %7d"
+					   , s_primName[ii]
+					   , statsNumPrimsRendered[ii]
+					   , statsNumInstances[ii]
+					   , statsNumPrimsSubmitted[ii]
+					   );
+				}
+		
+				tvm.printf(10, pos++, 0x8e, "     Indices: %7d", statsNumIndices);
+				tvm.printf(10, pos++, 0x8e, "    DVB size: %7d", _render->m_vboffset);
+				tvm.printf(10, pos++, 0x8e, "    DIB size: %7d", _render->m_iboffset);
+		
+				double captureMs = double(captureElapsed)*toMs;
+				tvm.printf(10, pos++, 0x8e, "     Capture: %3.4f [ms]", captureMs);
+		
+				uint8_t attr[2] = { 0x89, 0x8a };
+				uint8_t attrIndex = _render->m_waitSubmit < _render->m_waitRender;
+		
+				tvm.printf(10, pos++, attr[attrIndex&1], " Submit wait: %3.4f [ms]", _render->m_waitSubmit*toMs);
+				tvm.printf(10, pos++, attr[(attrIndex+1)&1], " Render wait: %3.4f [ms]", _render->m_waitRender*toMs);
+		
+				min = frameTime;
+				max = frameTime;
+			}
+	
+			blit(this, _textVideoMemBlitter, tvm);
+	
+			rce.popDebugGroup();
+		}
+		else if (_render->m_debug & BGFX_DEBUG_TEXT)
+		{
+			rce.pushDebugGroup("debugtext");
+	
+			blit(this, _textVideoMemBlitter, _render->m_textVideoMem);
+	
+			rce.popDebugGroup();
+		}
+
+		//TODO: REMOVE THIS - TEMPORARY HACK
+		release(zeroTexture);
+
+		rce.endEncoding();
+		m_renderCommandEncoder = 0;
+	}
+
+
 } /* namespace mtl */ } // namespace bgfx
 
-#endif // BGFX_CONFIG_RENDERER_METAL
+#else
+
+namespace bgfx { namespace mtl
+	{
+		RendererContextI* rendererCreate()
+		{
+			return NULL;
+		}
+		
+		void rendererDestroy()
+		{
+		}
+	} /* namespace mtl */ } // namespace bgfx
+
+#endif // BGFX_CONFIG_RENDERER_NULL

+ 35 - 0
src/vs_clear.bin.h

@@ -46,3 +46,38 @@ static const uint8_t vs_clear_dx11[254] =
 	0x36, 0x00, 0x00, 0x05, 0x82, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, // 6.... .......@..
 	0x00, 0x00, 0x80, 0x3f, 0x3e, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00,             // ...?>.........
 };
+static const uint8_t vs_clear_mtl[500] =
+{
+	0x56, 0x53, 0x48, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe5, 0x01, 0x00, 0x00, 0x75, 0x73, // VSH...........us
+	0x69, 0x6e, 0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x6d, 0x65, // ing namespace me
+	0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // tal;.struct xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x7b, // MtlShaderInput {
+	0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x20, 0x61, 0x5f, 0x70, 0x6f, 0x73, 0x69, // .  float3 a_posi
+	0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5b, 0x5b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, // tion [[attribute
+	0x28, 0x30, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, // (0)]];.};.struct
+	0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, //  xlatMtlShaderOu
+	0x74, 0x70, 0x75, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, // tput {.  float4
+	0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5b, 0x5b, 0x70, 0x6f, // gl_Position [[po
+	0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5d, 0x5d, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, // sition]];.};.str
+	0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, // uct xlatMtlShade
+	0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x7b, 0x0a, 0x7d, 0x3b, 0x0a, 0x76, 0x65, // rUniform {.};.ve
+	0x72, 0x74, 0x65, 0x78, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, // rtex xlatMtlShad
+	0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, // erOutput xlatMtl
+	0x4d, 0x61, 0x69, 0x6e, 0x20, 0x28, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, // Main (xlatMtlSha
+	0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x20, // derInput _mtl_i
+	0x5b, 0x5b, 0x73, 0x74, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x6e, 0x5d, 0x5d, 0x2c, 0x20, 0x63, 0x6f, // [[stage_in]], co
+	0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, // nstant xlatMtlSh
+	0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x26, 0x20, 0x5f, 0x6d, 0x74, // aderUniform& _mt
+	0x6c, 0x5f, 0x75, 0x20, 0x5b, 0x5b, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x28, 0x30, 0x29, 0x5d, // l_u [[buffer(0)]
+	0x5d, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, // ]).{.  xlatMtlSh
+	0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, // aderOutput _mtl_
+	0x6f, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, // o;.  float4 tmpv
+	0x61, 0x72, 0x5f, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, // ar_1;.  tmpvar_1
+	0x2e, 0x77, 0x20, 0x3d, 0x20, 0x31, 0x2e, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, // .w = 1.0;.  tmpv
+	0x61, 0x72, 0x5f, 0x31, 0x2e, 0x78, 0x79, 0x7a, 0x20, 0x3d, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, // ar_1.xyz = _mtl_
+	0x69, 0x2e, 0x61, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x0a, 0x20, 0x20, // i.a_position;.
+	0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, // _mtl_o.gl_Positi
+	0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x3b, 0x0a, 0x20, // on = tmpvar_1;.
+	0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, //  return _mtl_o;.
+	0x7d, 0x0a, 0x0a, 0x00,                                                                         // }...
+};

+ 56 - 0
src/vs_debugfont.bin.h

@@ -109,3 +109,59 @@ static const uint8_t vs_debugfont_dx11[714] =
 	0x00, 0x00, 0x46, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x00, 0x04, // ..F.......>.....
 	0x05, 0x00, 0x06, 0x00, 0x01, 0x00, 0x10, 0x00, 0x40, 0x00,                                     // ........@.
 };
+static const uint8_t vs_debugfont_mtl[843] =
+{
+	0x56, 0x53, 0x48, 0x04, 0xb8, 0xbe, 0x22, 0x66, 0x00, 0x00, 0x3c, 0x03, 0x00, 0x00, 0x75, 0x73, // VSH..."f..<...us
+	0x69, 0x6e, 0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x6d, 0x65, // ing namespace me
+	0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, 0x6c, 0x61, 0x74, // tal;.struct xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x7b, // MtlShaderInput {
+	0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x61, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, // .  float4 a_colo
+	0x72, 0x30, 0x20, 0x5b, 0x5b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x30, // r0 [[attribute(0
+	0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x61, 0x5f, // )]];.  float4 a_
+	0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x31, 0x20, 0x5b, 0x5b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, // color1 [[attribu
+	0x74, 0x65, 0x28, 0x31, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, // te(1)]];.  float
+	0x33, 0x20, 0x61, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5b, 0x5b, 0x61, // 3 a_position [[a
+	0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x32, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, // ttribute(2)]];.
+	0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x61, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, //  float2 a_texcoo
+	0x72, 0x64, 0x30, 0x20, 0x5b, 0x5b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, // rd0 [[attribute(
+	0x33, 0x29, 0x5d, 0x5d, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, // 3)]];.};.struct
+	0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, // xlatMtlShaderOut
+	0x70, 0x75, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x67, // put {.  float4 g
+	0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5b, 0x5b, 0x70, 0x6f, 0x73, // l_Position [[pos
+	0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5d, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, // ition]];.  float
+	0x34, 0x20, 0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, // 4 v_color0;.  fl
+	0x6f, 0x61, 0x74, 0x34, 0x20, 0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x31, 0x3b, 0x0a, 0x20, // oat4 v_color1;.
+	0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, //  float2 v_texcoo
+	0x72, 0x64, 0x30, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x78, // rd0;.};.struct x
+	0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, // latMtlShaderUnif
+	0x6f, 0x72, 0x6d, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x78, 0x34, // orm {.  float4x4
+	0x20, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, //  u_modelViewProj
+	0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x20, 0x78, 0x6c, 0x61, 0x74, // ;.};.vertex xlat
+	0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, // MtlShaderOutput
+	0x78, 0x6c, 0x61, 0x74, 0x4d, 0x74, 0x6c, 0x4d, 0x61, 0x69, 0x6e, 0x20, 0x28, 0x78, 0x6c, 0x61, // xlatMtlMain (xla
+	0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, // tMtlShaderInput
+	0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x20, 0x5b, 0x5b, 0x73, 0x74, 0x61, 0x67, 0x65, 0x5f, 0x69, // _mtl_i [[stage_i
+	0x6e, 0x5d, 0x5d, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x20, 0x78, 0x6c, // n]], constant xl
+	0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x55, 0x6e, 0x69, 0x66, 0x6f, // atMtlShaderUnifo
+	0x72, 0x6d, 0x26, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x75, 0x20, 0x5b, 0x5b, 0x62, 0x75, 0x66, // rm& _mtl_u [[buf
+	0x66, 0x65, 0x72, 0x28, 0x30, 0x29, 0x5d, 0x5d, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x78, 0x6c, // fer(0)]]).{.  xl
+	0x61, 0x74, 0x4d, 0x74, 0x6c, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, // atMtlShaderOutpu
+	0x74, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, // t _mtl_o;.  floa
+	0x74, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x74, // t4 tmpvar_1;.  t
+	0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x2e, 0x77, 0x20, 0x3d, 0x20, 0x31, 0x2e, 0x30, 0x3b, // mpvar_1.w = 1.0;
+	0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x2e, 0x78, 0x79, 0x7a, 0x20, // .  tmpvar_1.xyz
+	0x3d, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x61, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, // = _mtl_i.a_posit
+	0x69, 0x6f, 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x67, 0x6c, // ion;.  _mtl_o.gl
+	0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x28, 0x5f, 0x6d, 0x74, // _Position = (_mt
+	0x6c, 0x5f, 0x75, 0x2e, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, // l_u.u_modelViewP
+	0x72, 0x6f, 0x6a, 0x20, 0x2a, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x29, 0x3b, // roj * tmpvar_1);
+	0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, // .  _mtl_o.v_texc
+	0x6f, 0x6f, 0x72, 0x64, 0x30, 0x20, 0x3d, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x61, // oord0 = _mtl_i.a
+	0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x5f, 0x6d, // _texcoord0;.  _m
+	0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x20, 0x3d, 0x20, // tl_o.v_color0 =
+	0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x61, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x3b, // _mtl_i.a_color0;
+	0x0a, 0x20, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x2e, 0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, // .  _mtl_o.v_colo
+	0x72, 0x31, 0x20, 0x3d, 0x20, 0x5f, 0x6d, 0x74, 0x6c, 0x5f, 0x69, 0x2e, 0x61, 0x5f, 0x63, 0x6f, // r1 = _mtl_i.a_co
+	0x6c, 0x6f, 0x72, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, // lor1;.  return _
+	0x6d, 0x74, 0x6c, 0x5f, 0x6f, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00,                               // mtl_o;.}...
+};