Skip to content

Commit a34f917

Browse files
committed
Fix float marshalling for sampler LOD on ARM64
- Ensures correct LOD max clamp setting on Apple Silicon by using explicit float P/Invoke to avoid ABI issues with objc_msgSend
1 parent b3131bb commit a34f917

3 files changed

Lines changed: 13 additions & 0 deletions

File tree

src/MewVG.Metal/Interop/Metal.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ public static class Sel
129129
public static readonly nint SetMinFilter = ObjCRuntime.RegisterSelector("setMinFilter:");
130130
public static readonly nint SetMagFilter = ObjCRuntime.RegisterSelector("setMagFilter:");
131131
public static readonly nint SetMipFilter = ObjCRuntime.RegisterSelector("setMipFilter:");
132+
public static readonly nint SetLodMaxClamp = ObjCRuntime.RegisterSelector("setLodMaxClamp:");
132133
public static readonly nint SetSAddressMode = ObjCRuntime.RegisterSelector("setSAddressMode:");
133134
public static readonly nint SetTAddressMode = ObjCRuntime.RegisterSelector("setTAddressMode:");
134135

src/MewVG.Metal/Interop/ObjCRuntime.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,15 @@ public static unsafe partial class ObjCRuntime
8585
[LibraryImport(LibObjC, EntryPoint = "objc_msgSend")]
8686
public static partial void SendMessageNoReturn(nint receiver, nint selector, double arg1);
8787

88+
// Use DllImport (not LibraryImport) for the float overload. LibraryImport's
89+
// source-generated marshalling for float was observed to corrupt subsequent
90+
// objc_msgSend calls on Apple Silicon (ARM64) — float failed to reliably land
91+
// in the s0 floating-point register. DllImport defers to the runtime's standard
92+
// platform ABI which handles float correctly on both ARM64 (s0) and x86_64
93+
// (xmm0). Single signature covers both architectures.
94+
[DllImport(LibObjC, EntryPoint = "objc_msgSend")]
95+
public static extern void SendMessageFloat(nint receiver, nint selector, float arg1);
96+
8897
[LibraryImport(LibObjC, EntryPoint = "objc_msgSend")]
8998
public static partial void SendMessageNoReturn(nint receiver, nint selector, MTLClearColor arg1);
9099

src/MewVG.Metal/MNVGcontext.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2335,6 +2335,9 @@ public int CreateTexture(int type, int width, int height, int imageFlags, ReadOn
23352335
if ((imageFlags & (int)NVGimageFlags.GenerateMipmaps) != 0)
23362336
{
23372337
ObjCRuntime.SendMessage(samplerDescriptor, MetalSelectors.setMipFilter, (ulong)MTLSamplerMipFilter.Linear);
2338+
// Use explicit float P/Invoke — LibraryImport float overload appears to
2339+
// mishandle the ARM64 ABI here, breaking subsequent text sampler creation.
2340+
ObjCRuntime.SendMessageFloat(samplerDescriptor, Metal.Sel.SetLodMaxClamp, 2.0f);
23382341
}
23392342

23402343
var repeatX = (imageFlags & (int)NVGimageFlags.RepeatX) != 0;

0 commit comments

Comments
 (0)