Show More
Commit Description:
Add timers for Simulation and various engines...
Commit Description:
Add timers for Simulation and various engines Starting to add additional timers for different stages of the process of updating in order to get more insight into what is slowing it down. The update takes 9ms, which is much longer than it used to. Engine-specific timers are coming later.
File last commit:
Show/Diff file:
Action:
FNA/src/FNAPlatform/MetalDevice_MTL.cs
1909 lines | 51.3 KiB | text/x-csharp | CSharpLexer
#region License
/* FNA - XNA4 Reimplementation for Desktop Platforms
* Copyright 2009-2020 Ethan Lee and the MonoGame Team
*
* Released under the Microsoft Public License.
* See LICENSE for details.
*/
#endregion
#region Using Statements
using System;
using System.Runtime.InteropServices;
#endregion
/* =============================
* Objective-C Runtime Reference
* =============================
* A function call takes the form of objc_msgSend(<receiver>, <message>, <args>)
*
* To send the "quack" message to a "duck" instance, we need two things:
* 1) A pointer to the duck instance. This is the receiver.
* 2) A Selector (read: char* with extra metadata) for the "quack" message.
*
* To create a "quack" selector, we have to call sel_registerName() with a
* parameter of "quack" turned into an array of UTF8 bytes. This is tedious,
* so we do this here by calling the convenience method Selector("quack").
*
* To get a property of obj: objc_msgSend(obj, Selector("propertyName"))
* To set a property of obj: objc_msgSend(obj, Selector("setPropertyName"), val)
*
* ===========
* Other notes
* ===========
* The size of NSUInteger varies depending on CPU arch (32 bit / 64 bit).
* Since all modern Apple devices are 64 bit, we can just use ulong (UInt64)
* instead of uint (UInt32). This makes the structs the correct size.
*/
namespace Microsoft.Xna.Framework.Graphics
{
internal partial class MetalDevice : IGLDevice
{
#region Private ObjC Runtime Entry Points
const string objcLibrary = "/usr/lib/libobjc.A.dylib";
[DllImport(objcLibrary)]
private static extern IntPtr objc_getClass(string name);
[DllImport(objcLibrary)]
private static extern void objc_release(IntPtr obj);
[DllImport(objcLibrary)]
private static extern IntPtr objc_retain(IntPtr obj);
[DllImport(objcLibrary)]
private static extern IntPtr objc_autoreleasePoolPush();
[DllImport(objcLibrary)]
private static extern void objc_autoreleasePoolPop(IntPtr pool);
[DllImport(objcLibrary)]
private static extern IntPtr sel_registerName(byte[] name);
/* Here come the obj_msgSend overloads... */
// Void
[DllImport(objcLibrary, EntryPoint = "objc_msgSend")]
private static extern void objc_msgSend(IntPtr receiver, IntPtr selector);
[DllImport(objcLibrary, EntryPoint = "objc_msgSend")]
private static extern void objc_msgSend(IntPtr receiver, IntPtr selector, IntPtr arg);
[DllImport(objcLibrary, EntryPoint = "objc_msgSend")]
private static extern void objc_msgSend(IntPtr receiver, IntPtr selector, IntPtr arg1, ulong arg2);
[DllImport(objcLibrary, EntryPoint = "objc_msgSend")]
private static extern void objc_msgSend(IntPtr receiver, IntPtr selector, IntPtr arg1, ulong arg2, ulong arg3);
[DllImport(objcLibrary, EntryPoint = "objc_msgSend")]
private static extern void objc_msgSend(IntPtr receiver, IntPtr selector, ulong arg1, ulong arg2, ulong arg3);
[DllImport(objcLibrary, EntryPoint = "objc_msgSend")]
private static extern void objc_msgSend(IntPtr receiver, IntPtr selector, ulong arg1, ulong arg2);
[DllImport(objcLibrary, EntryPoint = "objc_msgSend")]
private static extern void objc_msgSend(IntPtr receiver, IntPtr selector, ulong arg);
[DllImport(objcLibrary, EntryPoint = "objc_msgSend")]
private static extern void objc_msgSend(IntPtr receiver, IntPtr selector, uint arg);
[DllImport(objcLibrary, EntryPoint = "objc_msgSend")]
private static extern void objc_msgSend(IntPtr receiver, IntPtr selector, bool arg);
[DllImport(objcLibrary, EntryPoint = "objc_msgSend")]
private static extern void objc_msgSend(IntPtr receiver, IntPtr selector, double arg);
[DllImport(objcLibrary, EntryPoint = "objc_msgSend")]
private static extern void objc_msgSend(IntPtr receiver, IntPtr selector, MTLViewport viewport);
[DllImport(objcLibrary, EntryPoint = "objc_msgSend")]
private static extern void objc_msgSend(IntPtr receiver, IntPtr selector, MTLScissorRect scissorRect);
[DllImport(objcLibrary, EntryPoint = "objc_msgSend")]
private static extern void objc_msgSend(IntPtr receiver, IntPtr selector, MTLClearColor color);
[DllImport(objcLibrary, EntryPoint = "objc_msgSend")]
private static extern void objc_msgSend(IntPtr receiver, IntPtr selector, NSRange range);
[DllImport(objcLibrary, EntryPoint = "objc_msgSend")]
private static extern void objc_msgSend(IntPtr receiver, IntPtr selector, float arg1, float arg2, float arg3);
[DllImport(objcLibrary, EntryPoint = "objc_msgSend")]
private static extern void objc_msgSend(IntPtr receiver, IntPtr selector, float arg1, float arg2, float arg3, float arg4);
[DllImport(objcLibrary, EntryPoint = "objc_msgSend")]
private static extern void objc_msgSend(IntPtr receiver, IntPtr selector, MTLRegion region, ulong level, ulong slice, IntPtr bytes, ulong bytesPerRow, ulong bytesPerImage);
[DllImport(objcLibrary, EntryPoint = "objc_msgSend")]
private static extern void objc_msgSend(IntPtr receiver, IntPtr selector, IntPtr srcTexture, ulong srcSlice, ulong srcLevel, MTLOrigin srcOrigin, MTLSize srcSize, IntPtr dstTexture, ulong dstSlice, ulong dstLevel, MTLOrigin dstOrigin);
[DllImport(objcLibrary, EntryPoint = "objc_msgSend")]
private static extern void objc_msgSend(IntPtr receiver, IntPtr selector, ulong primitiveType, ulong indexCount, ulong indexType, IntPtr indexBuffer, ulong indexBufferOffset, ulong instanceCount);
[DllImport(objcLibrary, EntryPoint = "objc_msgSend")]
private static extern void objc_msgSend(IntPtr receiver, IntPtr selector, IntPtr pixelBytes, ulong bytesPerRow, ulong bytesPerImage, MTLRegion region, ulong level, ulong slice);
// IntPtr
[DllImport(objcLibrary, EntryPoint = "objc_msgSend")]
private static extern IntPtr intptr_objc_msgSend(IntPtr receiver, IntPtr selector);
[DllImport(objcLibrary, EntryPoint = "objc_msgSend")]
private static extern IntPtr intptr_objc_msgSend(IntPtr receiver, IntPtr selector, IntPtr arg);
[DllImport(objcLibrary, EntryPoint = "objc_msgSend")]
private static extern IntPtr intptr_objc_msgSend(IntPtr receiver, IntPtr selector, string arg);
[DllImport(objcLibrary, EntryPoint = "objc_msgSend")]
private static extern IntPtr intptr_objc_msgSend(IntPtr receiver, IntPtr selector, ulong arg);
[DllImport(objcLibrary, EntryPoint = "objc_msgSend")]
private static extern IntPtr intptr_objc_msgSend(IntPtr receiver, IntPtr selector, ulong arg1, ulong arg2);
[DllImport(objcLibrary, EntryPoint = "objc_msgSend")]
private static extern IntPtr intptr_objc_msgSend(IntPtr receiver, IntPtr selector, MTLPixelFormat arg1, ulong arg2, bool arg3);
[DllImport(objcLibrary, EntryPoint = "objc_msgSend")]
private static extern IntPtr intptr_objc_msgSend(IntPtr receiver, IntPtr selector, MTLPixelFormat arg1, ulong arg2, ulong arg3, bool arg4);
[DllImport(objcLibrary, EntryPoint = "objc_msgSend")]
private static extern IntPtr intptr_objc_msgSend(IntPtr receiver, IntPtr selector, IntPtr arg1, out IntPtr arg2);
[DllImport(objcLibrary, EntryPoint = "objc_msgSend")]
private static extern IntPtr intptr_objc_msgSend(IntPtr receiver, IntPtr selector, IntPtr arg1, IntPtr arg2, out IntPtr arg3);
// Ulong
[DllImport(objcLibrary, EntryPoint = "objc_msgSend")]
private static extern ulong ulong_objc_msgSend(IntPtr receiver, IntPtr selector);
[DllImport(objcLibrary, EntryPoint = "objc_msgSend")]
private static extern ulong ulong_objc_msgSend(IntPtr receiver, IntPtr selector, ulong arg);
// Bool
[DllImport(objcLibrary, EntryPoint = "objc_msgSend")]
private static extern bool bool_objc_msgSend(IntPtr receiver, IntPtr selector);
[DllImport(objcLibrary, EntryPoint = "objc_msgSend")]
private static extern bool bool_objc_msgSend(IntPtr receiver, IntPtr selector, ulong arg);
[DllImport(objcLibrary, EntryPoint = "objc_msgSend")]
private static extern bool bool_objc_msgSend(IntPtr receiver, IntPtr selector, IntPtr arg);
[DllImport(objcLibrary, EntryPoint = "objc_msgSend")]
private static extern bool bool_objc_msgSend(IntPtr receiver, IntPtr selector, NSOperatingSystemVersion arg);
// CGSize
[DllImport(objcLibrary, EntryPoint = "objc_msgSend")]
private static extern CGSize cgsize_objc_msgSend(IntPtr receiver, IntPtr selector);
#endregion
#region C-Style Metal Function Imports
const string metalLibrary = "/System/Library/Frameworks/Metal.framework/Metal";
[DllImport(metalLibrary)]
internal static extern IntPtr MTLCreateSystemDefaultDevice();
#endregion
#region Private MTL Enums
private enum MTLLoadAction : ulong
{
DontCare = 0,
Load = 1,
Clear = 2
}
private enum MTLStoreAction : ulong
{
DontCare = 0,
Store = 1,
MultisampleResolve = 2
}
private enum MTLPrimitiveType : ulong
{
Point = 0,
Line = 1,
LineStrip = 2,
Triangle = 3,
TriangleStrip = 4
}
private enum MTLIndexType : ulong
{
UInt16 = 0,
UInt32 = 1
}
private enum MTLPixelFormat : ulong
{
Invalid = 0,
A8Unorm = 1,
R16Float = 25,
RG8Snorm = 32,
B5G6R5Unorm = 40,
ABGR4Unorm = 42,
BGR5A1Unorm = 43,
R32Float = 55,
RG16Unorm = 60,
RG16Snorm = 62,
RG16Float = 65,
RGBA8Unorm = 70,
BGRA8Unorm = 80,
RGB10A2Unorm = 90,
RG32Float = 105,
RGBA16Unorm = 110,
RGBA16Float = 115,
RGBA32Float = 125,
BC1_RGBA = 130,
BC2_RGBA = 132,
BC3_RGBA = 134,
Depth16Unorm = 250,
Depth32Float = 252,
Depth24Unorm_Stencil8 = 255,
Depth32Float_Stencil8 = 260,
}
private enum MTLSamplerMinMagFilter
{
Nearest = 0,
Linear = 1
}
private enum MTLTextureUsage
{
ShaderRead = 1,
RenderTarget = 4
}
private enum MTLTextureType
{
Multisample2D = 4,
Texture3D = 7
}
private enum MTLStorageMode
{
Private = 2
}
private enum MTLBlendFactor
{
Zero = 0,
One = 1,
SourceColor = 2,
OneMinusSourceColor = 3,
SourceAlpha = 4,
OneMinusSourceAlpha = 5,
DestinationColor = 6,
OneMinusDestinationColor = 7,
DestinationAlpha = 8,
OneMinusDestinationAlpha = 9,
SourceAlphaSaturated = 10,
BlendColor = 11,
OneMinusBlendColor = 12
}
private enum MTLBlendOperation
{
Add = 0,
Subtract = 1,
ReverseSubtract = 2,
Min = 3,
Max = 4
}
private enum MTLCullMode
{
None = 0,
Front = 1,
Back = 2
}
private enum MTLTriangleFillMode
{
Fill = 0,
Lines = 1
}
private enum MTLSamplerAddressMode
{
ClampToEdge = 0,
Repeat = 2,
MirrorRepeat = 3
}
private enum MTLSamplerMipFilter
{
Nearest = 1,
Linear = 2
}
private enum MTLVertexFormat
{
UChar4 = 3,
UChar4Normalized = 9,
Short2 = 16,
Short4 = 18,
Short2Normalized = 22,
Short4Normalized = 24,
Half2 = 25,
Half4 = 27,
Float = 28,
Float2 = 29,
Float3 = 30,
Float4 = 31
}
private enum MTLVertexStepFunction
{
PerInstance = 2
}
private enum MTLCompareFunction
{
Never = 0,
Less = 1,
Equal = 2,
LessEqual = 3,
Greater = 4,
NotEqual = 5,
GreaterEqual = 6,
Always = 7
}
private enum MTLStencilOperation
{
Keep = 0,
Zero = 1,
Replace = 2,
IncrementClamp = 3,
DecrementClamp = 4,
Invert = 5,
IncrementWrap = 6,
DecrementWrap = 7
}
private enum MTLVisibilityResultMode
{
Disabled = 0,
Counting = 2
}
private enum MTLResourceOptions
{
CPUCacheModeDefaultCache = 0,
CPUCacheModeWriteCombined = 1
}
private enum MTLPurgeableState
{
NonVolatile = 2,
Empty = 4
}
#endregion
#region Private MTL Structs
[StructLayout(LayoutKind.Sequential, Pack = 1)]
private struct MTLClearColor
{
public double red;
public double green;
public double blue;
public double alpha;
public MTLClearColor(
double red,
double green,
double blue,
double alpha
) {
this.red = red;
this.green = green;
this.blue = blue;
this.alpha = alpha;
}
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
private struct MTLViewport
{
public double originX;
public double originY;
public double width;
public double height;
public double znear;
public double zfar;
public MTLViewport(
double originX,
double originY,
double width,
double height,
double znear,
double zfar
) {
this.originX = originX;
this.originY = originY;
this.width = width;
this.height = height;
this.znear = znear;
this.zfar = zfar;
}
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
private struct MTLScissorRect
{
ulong x;
ulong y;
ulong width;
ulong height;
public MTLScissorRect(
int x,
int y,
int width,
int height
) {
this.x = (ulong) x;
this.y = (ulong) y;
this.width = (ulong) width;
this.height = (ulong) height;
}
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
private struct MTLOrigin
{
ulong x;
ulong y;
ulong z;
public MTLOrigin(int x, int y, int z)
{
this.x = (ulong) x;
this.y = (ulong) y;
this.z = (ulong) z;
}
public static MTLOrigin Zero = new MTLOrigin(0, 0, 0);
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
private struct MTLSize
{
ulong width;
ulong height;
ulong depth;
public MTLSize(int width, int height, int depth)
{
this.width = (ulong) width;
this.height = (ulong) height;
this.depth = (ulong) depth;
}
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
private struct MTLRegion
{
MTLOrigin origin;
MTLSize size;
public MTLRegion(MTLOrigin origin, MTLSize size)
{
this.origin = origin;
this.size = size;
}
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
private struct CGSize
{
public double width;
public double height;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
private struct NSRange
{
public ulong loc;
public ulong len;
public NSRange(int loc, int len)
{
this.loc = (ulong) loc;
this.len = (ulong) len;
}
}
#endregion
#region Selectors
private static IntPtr Selector(string name)
{
name += Char.MinValue; // null terminator
return sel_registerName(System.Text.Encoding.UTF8.GetBytes(name));
}
private static IntPtr selRespondsToSelector = Selector("respondsToSelector:");
private static bool RespondsToSelector(IntPtr obj, IntPtr selector)
{
return bool_objc_msgSend(obj, selRespondsToSelector, selector);
}
#endregion
#region ObjC Class References
private static IntPtr classTextureDescriptor = objc_getClass("MTLTextureDescriptor");
private static IntPtr classRenderPassDescriptor = objc_getClass("MTLRenderPassDescriptor");
private static IntPtr classRenderPipelineDescriptor = objc_getClass("MTLRenderPipelineDescriptor");
private static IntPtr classDepthStencilDescriptor = objc_getClass("MTLDepthStencilDescriptor");
private static IntPtr classStencilDescriptor = objc_getClass("MTLStencilDescriptor");
private static IntPtr classMTLSamplerDescriptor = objc_getClass("MTLSamplerDescriptor");
private static IntPtr classMTLVertexDescriptor = objc_getClass("MTLVertexDescriptor");
private static IntPtr classNSProcessInfo = objc_getClass("NSProcessInfo");
private static IntPtr classNSString = objc_getClass("NSString");
#endregion
#region NSString <-> C# String
private static IntPtr selUtf8 = Selector("UTF8String");
private static string NSStringToUTF8(IntPtr nsstr)
{
return Marshal.PtrToStringAnsi(
intptr_objc_msgSend(nsstr, selUtf8)
);
}
private static IntPtr selAlloc = Selector("alloc");
private static IntPtr selInitWithUtf8 = Selector("initWithUTF8String:");
private static IntPtr UTF8ToNSString(string str)
{
return intptr_objc_msgSend(
intptr_objc_msgSend(classNSString, selAlloc),
selInitWithUtf8,
str
);
}
#endregion
#region iOS/tvOS GPU Check
private static IntPtr selSupportsFamily = Selector("supportsFamily:");
private static IntPtr selSupportsFeatureSet = Selector("supportsFeatureSet:");
private bool HasModernAppleGPU()
{
// "Modern" = A9 or later
const ulong GPUFamilyCommon2 = 3002;
const ulong iOS_GPUFamily3_v1 = 4;
const ulong tvOS_GPUFamily2_v1 = 30003;
// Can we use the GPUFamily API?
if (RespondsToSelector(device, selSupportsFamily))
{
return bool_objc_msgSend(
device,
selSupportsFamily,
GPUFamilyCommon2
);
}
// Fall back to checking FeatureSets...
bool iosCompat = bool_objc_msgSend(
device,
selSupportsFeatureSet,
iOS_GPUFamily3_v1
);
bool tvosCompat = bool_objc_msgSend(
device,
selSupportsFeatureSet,
tvOS_GPUFamily2_v1
);
return iosCompat || tvosCompat;
}
#endregion
#region OS Version Check
[StructLayout(LayoutKind.Sequential, Pack = 1)]
private struct NSOperatingSystemVersion
{
public long major;
public long minor;
public long patch;
}
private static IntPtr selOperatingSystemAtLeast = Selector("isOperatingSystemAtLeastVersion:");
private static IntPtr selProcessInfo = Selector("processInfo");
private static bool OperatingSystemAtLeast(long major, long minor, long patch)
{
NSOperatingSystemVersion version = new NSOperatingSystemVersion
{
major = major,
minor = minor,
patch = patch
};
IntPtr processInfo = intptr_objc_msgSend(
classNSProcessInfo,
selProcessInfo
);
return bool_objc_msgSend(
processInfo,
selOperatingSystemAtLeast,
version
);
}
#endregion
#region MTLDevice
private static IntPtr selName = Selector("name");
private static string mtlGetDeviceName(IntPtr device)
{
return NSStringToUTF8(intptr_objc_msgSend(device, selName));
}
private static IntPtr selSupportsSampleCount = Selector("supportsSampleCount:");
private static bool mtlSupportsSampleCount(IntPtr device, int count)
{
return bool_objc_msgSend(device, selSupportsSampleCount, (ulong) count);
}
private static IntPtr selCommandQueue = Selector("newCommandQueue");
private static IntPtr mtlNewCommandQueue(IntPtr device)
{
return intptr_objc_msgSend(device, selCommandQueue);
}
private static IntPtr selNewBufferWithLength = Selector("newBufferWithLength:options:");
private static IntPtr mtlNewBufferWithLength(IntPtr device, int length, MTLResourceOptions options)
{
return intptr_objc_msgSend(
device,
selNewBufferWithLength,
(ulong) length,
(ulong) options
);
}
private static IntPtr selNewTextureWithDescriptor = Selector("newTextureWithDescriptor:");
private static IntPtr mtlNewTextureWithDescriptor(IntPtr device, IntPtr texDesc)
{
return intptr_objc_msgSend(
device,
selNewTextureWithDescriptor,
texDesc
);
}
private static IntPtr selNewSamplerStateWithDescriptor = Selector("newSamplerStateWithDescriptor:");
private static IntPtr mtlNewSamplerStateWithDescriptor(IntPtr device, IntPtr sampDesc)
{
return intptr_objc_msgSend(
device,
selNewSamplerStateWithDescriptor,
sampDesc
);
}
private static IntPtr selSupportsDepth24Stencil8 = Selector("isDepth24Stencil8PixelFormatSupported");
private static bool mtlSupportsDepth24Stencil8(IntPtr device)
{
return bool_objc_msgSend(device, selSupportsDepth24Stencil8);
}
#endregion
#region MTLBuffer
private static IntPtr selContents = Selector("contents");
private static IntPtr mtlGetBufferContentsPtr(IntPtr buffer)
{
return intptr_objc_msgSend(buffer, selContents);
}
#endregion
#region MTLCommandBuffer
private static IntPtr selRenderCommandEncoder = Selector("renderCommandEncoderWithDescriptor:");
private static IntPtr mtlMakeRenderCommandEncoder(
IntPtr commandBuffer,
IntPtr renderPassDesc
) {
return intptr_objc_msgSend(
commandBuffer,
selRenderCommandEncoder,
renderPassDesc
);
}
private static IntPtr selPresentDrawable = Selector("presentDrawable:");
private static void mtlPresentDrawable(
IntPtr commandBuffer,
IntPtr drawable
) {
objc_msgSend(
commandBuffer,
selPresentDrawable,
drawable
);
}
private static IntPtr selCommit = Selector("commit");
private static void mtlCommitCommandBuffer(IntPtr commandBuffer)
{
objc_msgSend(commandBuffer, selCommit);
}
private static IntPtr selWaitUntilCompleted = Selector("waitUntilCompleted");
private static void mtlCommandBufferWaitUntilCompleted(IntPtr commandBuffer)
{
objc_msgSend(commandBuffer, selWaitUntilCompleted);
}
#endregion
#region MTLCommandQueue
private static IntPtr selCommandBuffer = Selector("commandBuffer");
private static IntPtr mtlMakeCommandBuffer(IntPtr queue)
{
return intptr_objc_msgSend(queue, selCommandBuffer);
}
#endregion
#region Attachment Methods
private static IntPtr selColorAttachments = Selector("colorAttachments");
private static IntPtr selObjectAtIndexedSubscript = Selector("objectAtIndexedSubscript:");
private static IntPtr mtlGetColorAttachment(IntPtr desc, int index)
{
IntPtr attachments = intptr_objc_msgSend(
desc,
selColorAttachments
);
return intptr_objc_msgSend(
attachments,
selObjectAtIndexedSubscript,
(ulong) index
);
}
private static IntPtr selDepthAttachment = Selector("depthAttachment");
private static IntPtr mtlGetDepthAttachment(IntPtr desc)
{
return intptr_objc_msgSend(desc, selDepthAttachment);
}
private static IntPtr selStencilAttachment = Selector("stencilAttachment");
private static IntPtr mtlGetStencilAttachment(IntPtr desc)
{
return intptr_objc_msgSend(desc, selStencilAttachment);
}
private static IntPtr selSetLoadAction = Selector("setLoadAction:");
private static void mtlSetAttachmentLoadAction(
IntPtr attachment,
MTLLoadAction loadAction
) {
objc_msgSend(attachment, selSetLoadAction, (ulong) loadAction);
}
private static IntPtr selSetStoreAction = Selector("setStoreAction:");
private static void mtlSetAttachmentStoreAction(
IntPtr attachment,
MTLStoreAction storeAction
) {
objc_msgSend(attachment, selSetStoreAction, (ulong) storeAction);
}
private static IntPtr selSetTexture = Selector("setTexture:");
private static void mtlSetAttachmentTexture(
IntPtr attachment,
IntPtr texture
) {
objc_msgSend(attachment, selSetTexture, texture);
}
private static IntPtr selSetSlice = Selector("setSlice:");
private static void mtlSetAttachmentSlice(
IntPtr attachment,
int slice
) {
objc_msgSend(attachment, selSetSlice, (ulong) slice);
}
private static IntPtr selSetPixelFormat = Selector("setPixelFormat:");
private static void mtlSetAttachmentPixelFormat(
IntPtr attachment,
MTLPixelFormat pixelFormat
) {
objc_msgSend(attachment, selSetPixelFormat, (ulong) pixelFormat);
}
private static IntPtr selSetResolveTexture = Selector("setResolveTexture:");
private static void mtlSetAttachmentResolveTexture(
IntPtr attachment,
IntPtr resolveTexture
) {
objc_msgSend(attachment, selSetResolveTexture, resolveTexture);
}
private static IntPtr selSetResolveSlice = Selector("setResolveSlice:");
private static void mtlSetAttachmentResolveSlice(
IntPtr attachment,
int resolveSlice
) {
objc_msgSend(attachment, selSetResolveSlice, (ulong) resolveSlice);
}
private static IntPtr selSetClearColor = Selector("setClearColor:");
private static void mtlSetColorAttachmentClearColor(
IntPtr colorAttachment,
float r,
float g,
float b,
float a
) {
MTLClearColor clearColor = new MTLClearColor(r, g, b, a);
objc_msgSend(colorAttachment, selSetClearColor, clearColor);
}
private static IntPtr selSetClearDepth = Selector("setClearDepth:");
private static void mtlSetDepthAttachmentClearDepth(
IntPtr depthAttachment,
float clearDepth
) {
objc_msgSend(depthAttachment, selSetClearDepth, clearDepth);
}
private static IntPtr selSetClearStencil = Selector("setClearStencil:");
private static void mtlSetStencilAttachmentClearStencil(
IntPtr stencilAttachment,
int clearStencil
) {
objc_msgSend(stencilAttachment, selSetClearStencil, (ulong) clearStencil);
}
private static IntPtr selBlendingEnabled = Selector("setBlendingEnabled:");
private static void mtlSetAttachmentBlendingEnabled(
IntPtr colorAttachment,
bool enabled
) {
objc_msgSend(colorAttachment, selBlendingEnabled, enabled);
}
private static IntPtr selSetAlphaBlendOperation = Selector("setAlphaBlendOperation:");
private static void mtlSetAttachmentAlphaBlendOperation(
IntPtr colorAttachment,
MTLBlendOperation op
) {
objc_msgSend(colorAttachment, selSetAlphaBlendOperation, (ulong) op);
}
private static IntPtr selSetRGBBlendOperation = Selector("setRgbBlendOperation:");
private static void mtlSetAttachmentRGBBlendOperation(
IntPtr colorAttachment,
MTLBlendOperation op
) {
objc_msgSend(colorAttachment, selSetRGBBlendOperation, (ulong) op);
}
private static IntPtr selSetDestinationAlphaBlendFactor = Selector("setDestinationAlphaBlendFactor:");
private static void mtlSetAttachmentDestinationAlphaBlendFactor(
IntPtr colorAttachment,
MTLBlendFactor blend
) {
objc_msgSend(colorAttachment, selSetDestinationAlphaBlendFactor, (ulong) blend);
}
private static IntPtr selSetDestinationRGBBlendFactor = Selector("setDestinationRGBBlendFactor:");
private static void mtlSetAttachmentDestinationRGBBlendFactor(
IntPtr colorAttachment,
MTLBlendFactor blend
) {
objc_msgSend(colorAttachment, selSetDestinationRGBBlendFactor, (ulong) blend);
}
private static IntPtr selSetSourceAlphaBlendFactor = Selector("setSourceAlphaBlendFactor:");
private static void mtlSetAttachmentSourceAlphaBlendFactor(
IntPtr colorAttachment,
MTLBlendFactor blend
) {
objc_msgSend(colorAttachment, selSetSourceAlphaBlendFactor, (ulong) blend);
}
private static IntPtr selSetSourceRGBBlendFactor = Selector("setSourceRGBBlendFactor:");
private static void mtlSetAttachmentSourceRGBBlendFactor(
IntPtr colorAttachment,
MTLBlendFactor blend
) {
objc_msgSend(colorAttachment, selSetSourceRGBBlendFactor, (ulong) blend);
}
private static IntPtr selSetWriteMask = Selector("setWriteMask:");
private static void mtlSetAttachmentWriteMask(
IntPtr colorAttachment,
int mask
) {
objc_msgSend(colorAttachment, selSetWriteMask, (ulong) mask);
}
#endregion
#region MTLRenderPassDescriptor
private static IntPtr selRenderPassDescriptor = Selector("renderPassDescriptor");
private static IntPtr mtlMakeRenderPassDescriptor()
{
return intptr_objc_msgSend(classRenderPassDescriptor, selRenderPassDescriptor);
}
private static IntPtr selSetVisibilityBuffer = Selector("setVisibilityResultBuffer:");
private static void mtlSetVisibilityResultBuffer(
IntPtr renderPassDesc,
IntPtr buffer
) {
objc_msgSend(renderPassDesc, selSetVisibilityBuffer, buffer);
}
#endregion
#region MTLRenderCommandEncoder
private static IntPtr selSetBlendColor = Selector("setBlendColorRed:green:blue:alpha:");
private static void mtlSetBlendColor(
IntPtr renderCommandEncoder,
float red,
float green,
float blue,
float alpha
) {
objc_msgSend(renderCommandEncoder, selSetBlendColor, red, green, blue, alpha);
}
private static IntPtr selSetStencilReference = Selector("setStencilReferenceValue:");
private static void mtlSetStencilReferenceValue(
IntPtr renderCommandEncoder,
uint referenceValue
) {
objc_msgSend(renderCommandEncoder, selSetStencilReference, referenceValue);
}
private static IntPtr selSetViewport = Selector("setViewport:");
private static void mtlSetViewport(
IntPtr renderCommandEncoder,
int x,
int y,
int w,
int h,
double minDepth,
double maxDepth
) {
MTLViewport viewport = new MTLViewport(x, y, w, h, minDepth, maxDepth);
objc_msgSend(renderCommandEncoder, selSetViewport, viewport);
}
private static IntPtr selSetScissorRect = Selector("setScissorRect:");
private static void mtlSetScissorRect(
IntPtr renderCommandEncoder,
int x,
int y,
int w,
int h
) {
MTLScissorRect rect = new MTLScissorRect(x, y, w, h);
objc_msgSend(renderCommandEncoder, selSetScissorRect, rect);
}
private static IntPtr selEndEncoding = Selector("endEncoding");
private static void mtlEndEncoding(IntPtr commandEncoder)
{
objc_msgSend(commandEncoder, selEndEncoding);
}
private static IntPtr selDrawIndexedPrimitives = Selector("drawIndexedPrimitives:indexCount:indexType:indexBuffer:indexBufferOffset:instanceCount:");
private static void mtlDrawIndexedPrimitives(
IntPtr renderCommandEncoder,
MTLPrimitiveType primitiveType,
int indexCount,
MTLIndexType indexType,
IntPtr indexBuffer,
int indexBufferOffset,
int instanceCount
) {
objc_msgSend(
renderCommandEncoder,
selDrawIndexedPrimitives,
(ulong) primitiveType,
(ulong) indexCount,
(ulong) indexType,
indexBuffer,
(ulong) indexBufferOffset,
(ulong) instanceCount
);
}
private static IntPtr selDrawPrimitives = Selector("drawPrimitives:vertexStart:vertexCount:");
private static void mtlDrawPrimitives(
IntPtr renderCommandEncoder,
MTLPrimitiveType primitive,
int vertexStart,
int vertexCount
) {
objc_msgSend(
renderCommandEncoder,
selDrawPrimitives,
(ulong) primitive,
(ulong) vertexStart,
(ulong) vertexCount
);
}
private static IntPtr selSetCullMode = Selector("setCullMode:");
private static void mtlSetCullMode(
IntPtr renderCommandEncoder,
MTLCullMode cullMode
) {
objc_msgSend(
renderCommandEncoder,
selSetCullMode,
(ulong) cullMode
);
}
private static IntPtr selSetTriangleFillMode = Selector("setTriangleFillMode:");
private static void mtlSetTriangleFillMode(
IntPtr renderCommandEncoder,
MTLTriangleFillMode fillMode
) {
objc_msgSend(
renderCommandEncoder,
selSetTriangleFillMode,
(ulong) fillMode
);
}
private static IntPtr selSetDepthBias = Selector("setDepthBias:slopeScale:clamp:");
private static void mtlSetDepthBias(
IntPtr renderCommandEncoder,
float depthBias,
float slopeScaleDepthBias,
float clamp
) {
objc_msgSend(
renderCommandEncoder,
selSetDepthBias,
depthBias,
slopeScaleDepthBias,
clamp
);
}
private static IntPtr selSetDepthStencilState = Selector("setDepthStencilState:");
private static void mtlSetDepthStencilState(
IntPtr renderCommandEncoder,
IntPtr depthStencilState
) {
objc_msgSend(
renderCommandEncoder,
selSetDepthStencilState,
depthStencilState
);
}
private static IntPtr selInsertDebugSignpost = Selector("insertDebugSignpost:");
private static void mtlInsertDebugSignpost(
IntPtr renderCommandEncoder,
string message
) {
objc_msgSend(
renderCommandEncoder,
selInsertDebugSignpost,
UTF8ToNSString(message)
);
}
private static IntPtr selSetRenderPipelineState = Selector("setRenderPipelineState:");
private static void mtlSetRenderPipelineState(
IntPtr renderCommandEncoder,
IntPtr pipelineState
) {
objc_msgSend(renderCommandEncoder, selSetRenderPipelineState, pipelineState);
}
private static IntPtr selSetVertexBuffer = Selector("setVertexBuffer:offset:atIndex:");
private static void mtlSetVertexBuffer(
IntPtr renderCommandEncoder,
IntPtr vertexBuffer,
int offset,
int index
) {
objc_msgSend(
renderCommandEncoder,
selSetVertexBuffer,
vertexBuffer,
(ulong) offset,
(ulong) index
);
}
private static IntPtr selSetVertexBufferOffset = Selector("setVertexBufferOffset:atIndex:");
private static void mtlSetVertexBufferOffset(
IntPtr renderCommandEncoder,
int offset,
int index
) {
objc_msgSend(
renderCommandEncoder,
selSetVertexBufferOffset,
(ulong) offset,
(ulong) index
);
}
private static IntPtr selSetFragmentBuffer = Selector("setFragmentBuffer:offset:atIndex:");
private static void mtlSetFragmentBuffer(
IntPtr renderCommandEncoder,
IntPtr fragmentBuffer,
int offset,
int index
) {
objc_msgSend(
renderCommandEncoder,
selSetFragmentBuffer,
fragmentBuffer,
(ulong) offset,
(ulong) index
);
}
private static IntPtr selSetFragmentBufferOffset = Selector("setFragmentBufferOffset:atIndex:");
private static void mtlSetFragmentBufferOffset(
IntPtr renderCommandEncoder,
int offset,
int index
) {
objc_msgSend(
renderCommandEncoder,
selSetFragmentBufferOffset,
(ulong) offset,
(ulong) index
);
}
private static IntPtr selSetFragmentTexture = Selector("setFragmentTexture:atIndex:");
private static void mtlSetFragmentTexture(
IntPtr renderCommandEncoder,
IntPtr fragmentTexture,
int index
) {
objc_msgSend(
renderCommandEncoder,
selSetFragmentTexture,
fragmentTexture,
(ulong) index
);
}
private static IntPtr selSetFragmentSamplerState = Selector("setFragmentSamplerState:atIndex:");
private static void mtlSetFragmentSamplerState(
IntPtr renderCommandEncoder,
IntPtr samplerState,
int index
) {
objc_msgSend(
renderCommandEncoder,
selSetFragmentSamplerState,
samplerState,
(ulong) index
);
}
private static IntPtr selSetVisibilityResultMode = Selector("setVisibilityResultMode:offset:");
private static void mtlSetVisibilityResultMode(
IntPtr renderCommandEncoder,
MTLVisibilityResultMode mode,
int offset
) {
objc_msgSend(
renderCommandEncoder,
selSetVisibilityResultMode,
(ulong) mode,
(ulong) offset
);
}
#endregion
#region CAMetalLayer
private static IntPtr selLayer = Selector("layer");
private static IntPtr mtlGetLayer(IntPtr view)
{
return intptr_objc_msgSend(view, selLayer);
}
private static IntPtr selSetDevice = Selector("setDevice:");
private static void mtlSetLayerDevice(IntPtr layer, IntPtr device)
{
objc_msgSend(layer, selSetDevice, device);
}
private static IntPtr selNextDrawable = Selector("nextDrawable");
private static IntPtr mtlNextDrawable(IntPtr layer)
{
return intptr_objc_msgSend(layer, selNextDrawable);
}
private static IntPtr selPixelFormat = Selector("pixelFormat");
private static MTLPixelFormat mtlGetLayerPixelFormat(IntPtr layer)
{
return (MTLPixelFormat) ulong_objc_msgSend(layer, selPixelFormat);
}
private static IntPtr selDrawableSize = Selector("drawableSize");
private static CGSize mtlGetDrawableSize(IntPtr layer)
{
return (CGSize) cgsize_objc_msgSend(layer, selDrawableSize);
}
private static IntPtr selDisplaySyncEnabled = Selector("setDisplaySyncEnabled:");
private static void mtlSetDisplaySyncEnabled(
IntPtr layer,
bool enabled
) {
objc_msgSend(layer, selDisplaySyncEnabled, enabled);
}
private static IntPtr selSetFramebufferOnly = Selector("setFramebufferOnly:");
private static void mtlSetLayerFramebufferOnly(
IntPtr layer,
bool framebufferOnly
) {
objc_msgSend(layer, selSetFramebufferOnly, framebufferOnly);
}
private static IntPtr selSetMagnificationFilter = Selector("setMagnificationFilter:");
private static void mtlSetLayerMagnificationFilter(
IntPtr layer,
IntPtr val
) {
objc_msgSend(layer, selSetMagnificationFilter, val);
}
#endregion
#region CAMetalDrawable
private static IntPtr selTexture = Selector("texture");
private static IntPtr mtlGetTextureFromDrawable(IntPtr drawable)
{
return intptr_objc_msgSend(drawable, selTexture);
}
#endregion
#region MTLTextureDescriptor
private static IntPtr selTexture2DDescriptor = Selector("texture2DDescriptorWithPixelFormat:width:height:mipmapped:");
private static IntPtr mtlMakeTexture2DDescriptor(
MTLPixelFormat pixelFormat,
int width,
int height,
bool mipmapped
) {
return intptr_objc_msgSend(
classTextureDescriptor,
selTexture2DDescriptor,
pixelFormat,
(ulong) width,
(ulong) height,
mipmapped
);
}
private static IntPtr selTextureCubeDescriptor = Selector("textureCubeDescriptorWithPixelFormat:size:mipmapped:");
private static IntPtr mtlMakeTextureCubeDescriptor(
MTLPixelFormat pixelFormat,
int size,
bool mipmapped
) {
return intptr_objc_msgSend(
classTextureDescriptor,
selTextureCubeDescriptor,
pixelFormat,
(ulong) size,
mipmapped
);
}
private static IntPtr selSetUsage = Selector("setUsage:");
private static void mtlSetTextureUsage(
IntPtr texDesc,
MTLTextureUsage usage
) {
objc_msgSend(texDesc, selSetUsage, (ulong) usage);
}
private static IntPtr selSetTextureType = Selector("setTextureType:");
private static void mtlSetTextureType(
IntPtr texDesc,
MTLTextureType type
) {
objc_msgSend(texDesc, selSetTextureType, (ulong) type);
}
private static IntPtr selSetSampleCount = Selector("setSampleCount:");
private static void mtlSetTextureSampleCount(
IntPtr texDesc,
int sampleCount
) {
objc_msgSend(texDesc, selSetSampleCount, (ulong) sampleCount);
}
private static IntPtr selSetDepth = Selector("setDepth:");
private static void mtlSetTextureDepth(
IntPtr texDesc,
int depth
) {
objc_msgSend(texDesc, selSetDepth, (ulong) depth);
}
#endregion
#region MTLTexture
private static IntPtr selReplaceRegion = Selector("replaceRegion:mipmapLevel:slice:withBytes:bytesPerRow:bytesPerImage:");
private static void mtlReplaceRegion(
IntPtr texture,
MTLRegion region,
int level,
int slice,
IntPtr pixelBytes,
int bytesPerRow,
int bytesPerImage
) {
objc_msgSend(
texture,
selReplaceRegion,
region,
(ulong) level,
(ulong) slice,
pixelBytes,
(ulong) bytesPerRow,
(ulong) bytesPerImage
);
}
private static IntPtr selGetBytes = Selector("getBytes:bytesPerRow:bytesPerImage:fromRegion:mipmapLevel:slice:");
private static void mtlGetTextureBytes(
IntPtr texture,
IntPtr pixelBytes,
int bytesPerRow,
int bytesPerImage,
MTLRegion region,
int level,
int slice
) {
objc_msgSend(
texture,
selGetBytes,
pixelBytes,
(ulong) bytesPerRow,
(ulong) bytesPerImage,
region,
(ulong) level,
(ulong) slice
);
}
private static IntPtr selWidth = Selector("width");
private static ulong mtlGetTextureWidth(IntPtr texture)
{
return ulong_objc_msgSend(texture, selWidth);
}
private static IntPtr selHeight = Selector("height");
private static ulong mtlGetTextureHeight(IntPtr texture)
{
return ulong_objc_msgSend(texture, selHeight);
}
private static IntPtr selSetPurgeableState = Selector("setPurgeableState:");
private static MTLPurgeableState mtlSetPurgeableState(
IntPtr resource,
MTLPurgeableState state
) {
return (MTLPurgeableState) ulong_objc_msgSend(
resource,
selSetPurgeableState,
(ulong) state
);
}
#region MTLBlitCommandEncoder
private static IntPtr selBlitCommandEncoder = Selector("blitCommandEncoder");
private static IntPtr mtlMakeBlitCommandEncoder(IntPtr commandBuffer)
{
return intptr_objc_msgSend(commandBuffer, selBlitCommandEncoder);
}
private static IntPtr selCopyFromTexture = Selector("copyFromTexture:sourceSlice:sourceLevel:sourceOrigin:sourceSize:toTexture:destinationSlice:destinationLevel:destinationOrigin:");
private static void mtlBlitTextureToTexture(
IntPtr blitCommandEncoder,
IntPtr srcTexture,
int srcSlice,
int srcLevel,
MTLOrigin srcOrigin,
MTLSize srcSize,
IntPtr dstTexture,
int dstSlice,
int dstLevel,
MTLOrigin dstOrigin
) {
objc_msgSend(
blitCommandEncoder,
selCopyFromTexture,
srcTexture,
(ulong) srcSlice,
(ulong) srcLevel,
srcOrigin,
srcSize,
dstTexture,
(ulong) dstSlice,
(ulong) dstLevel,
dstOrigin
);
}
private static IntPtr selSynchronizeResource = Selector("synchronizeResource:");
private static void mtlSynchronizeResource(
IntPtr blitCommandEncoder,
IntPtr resource
) {
objc_msgSend(blitCommandEncoder, selSynchronizeResource, resource);
}
private static IntPtr selGenerateMipmaps = Selector("generateMipmapsForTexture:");
private static void mtlGenerateMipmapsForTexture(
IntPtr blitCommandEncoder,
IntPtr texture
) {
objc_msgSend(blitCommandEncoder, selGenerateMipmaps, texture);
}
#endregion
#region MTLRenderPipelineState
private static IntPtr selNew = Selector("new");
private static IntPtr mtlNewRenderPipelineDescriptor()
{
return intptr_objc_msgSend(classRenderPipelineDescriptor, selNew);
}
private static IntPtr selSetVertexFunction = Selector("setVertexFunction:");
private static void mtlSetPipelineVertexFunction(
IntPtr pipelineDescriptor,
IntPtr vertexFunction
) {
objc_msgSend(pipelineDescriptor, selSetVertexFunction, vertexFunction);
}
private static IntPtr selSetFragmentFunction = Selector("setFragmentFunction:");
private static void mtlSetPipelineFragmentFunction(
IntPtr pipelineDescriptor,
IntPtr fragmentFunction
) {
objc_msgSend(pipelineDescriptor, selSetFragmentFunction, fragmentFunction);
}
private static IntPtr selSetVertexDescriptor = Selector("setVertexDescriptor:");
private static void mtlSetPipelineVertexDescriptor(
IntPtr pipelineDescriptor,
IntPtr vertexDescriptor
) {
objc_msgSend(pipelineDescriptor, selSetVertexDescriptor, vertexDescriptor);
}
private static IntPtr selNewRenderPipelineState = Selector("newRenderPipelineStateWithDescriptor:error:");
private static IntPtr mtlNewRenderPipelineStateWithDescriptor(
IntPtr device,
IntPtr pipelineDescriptor
) {
IntPtr error = IntPtr.Zero;
IntPtr pipeline = intptr_objc_msgSend(
device,
selNewRenderPipelineState,
pipelineDescriptor,
out error
);
if (error != IntPtr.Zero)
{
throw new Exception("Metal Error: " + GetNSErrorDescription(error));
}
return pipeline;
}
private static IntPtr selSetDepthAttachmentPixelFormat = Selector("setDepthAttachmentPixelFormat:");
private static void mtlSetDepthAttachmentPixelFormat(
IntPtr pipelineDescriptor,
MTLPixelFormat format
) {
objc_msgSend(pipelineDescriptor, selSetDepthAttachmentPixelFormat, (ulong) format);
}
private static IntPtr selSetStencilAttachmentPixelFormat = Selector("setStencilAttachmentPixelFormat:");
private static void mtlSetStencilAttachmentPixelFormat(
IntPtr pipelineDescriptor,
MTLPixelFormat format
) {
objc_msgSend(pipelineDescriptor, selSetStencilAttachmentPixelFormat, (ulong) format);
}
private static void mtlSetPipelineSampleCount(
IntPtr pipelineDescriptor,
int sampleCount
) {
objc_msgSend(pipelineDescriptor, selSetSampleCount, (ulong) sampleCount);
}
#endregion
#region Sampler Descriptor
// selNew already defined
private static IntPtr mtlNewSamplerDescriptor()
{
return intptr_objc_msgSend(classMTLSamplerDescriptor, selNew);
}
private static IntPtr selSetMinFilter = Selector("setMinFilter:");
private static void mtlSetSamplerMinFilter(
IntPtr samplerDesc,
MTLSamplerMinMagFilter filter
) {
objc_msgSend(samplerDesc, selSetMinFilter, (uint) filter);
}
private static IntPtr selSetMagFilter = Selector("setMagFilter:");
private static void mtlSetSamplerMagFilter(
IntPtr samplerDesc,
MTLSamplerMinMagFilter filter
) {
objc_msgSend(samplerDesc, selSetMagFilter, (uint) filter);
}
private static IntPtr selSetMipFilter = Selector("setMipFilter:");
private static void mtlSetSamplerMipFilter(
IntPtr samplerDesc,
MTLSamplerMipFilter filter
) {
objc_msgSend(samplerDesc, selSetMipFilter, (uint) filter);
}
private static IntPtr selSetLodMinClamp = Selector("setLodMinClamp:");
private static void mtlSetSamplerLodMinClamp(
IntPtr samplerDesc,
float clamp
) {
objc_msgSend(samplerDesc, selSetLodMinClamp, clamp);
}
private static IntPtr selSetMaxAnisotropy = Selector("setMaxAnisotropy:");
private static void mtlSetSamplerMaxAnisotropy(
IntPtr samplerDesc,
int maxAnisotropy
) {
objc_msgSend(samplerDesc, selSetMaxAnisotropy, (ulong) maxAnisotropy);
}
private static IntPtr selSetRAddressMode = Selector("setRAddressMode:");
private static void mtlSetSampler_rAddressMode(
IntPtr samplerDesc,
MTLSamplerAddressMode mode
) {
objc_msgSend(samplerDesc, selSetRAddressMode, (ulong) mode);
}
private static IntPtr selSetSAddressMode = Selector("setSAddressMode:");
private static void mtlSetSampler_sAddressMode(
IntPtr samplerDesc,
MTLSamplerAddressMode mode
) {
objc_msgSend(samplerDesc, selSetSAddressMode, (ulong) mode);
}
private static IntPtr selSetTAddressMode = Selector("setTAddressMode:");
private static void mtlSetSampler_tAddressMode(
IntPtr samplerDesc,
MTLSamplerAddressMode mode
) {
objc_msgSend(samplerDesc, selSetTAddressMode, (ulong) mode);
}
#endregion
#region Vertex Descriptor
private static IntPtr selVertexDescriptor = Selector("vertexDescriptor");
private static IntPtr mtlMakeVertexDescriptor()
{
return intptr_objc_msgSend(classMTLVertexDescriptor, selVertexDescriptor);
}
private static IntPtr selAttributes = Selector("attributes");
private static IntPtr mtlGetVertexAttributeDescriptor(
IntPtr vertexDesc,
int index
) {
IntPtr attributes = intptr_objc_msgSend(
vertexDesc,
selAttributes
);
return intptr_objc_msgSend(
attributes,
selObjectAtIndexedSubscript,
(ulong) index
);
}
private static IntPtr selSetFormat = Selector("setFormat:");
private static void mtlSetVertexAttributeFormat(
IntPtr vertexAttribute,
MTLVertexFormat format
) {
objc_msgSend(vertexAttribute, selSetFormat, (ulong) format);
}
private static IntPtr selSetOffset = Selector("setOffset:");
private static void mtlSetVertexAttributeOffset(
IntPtr vertexAttribute,
int offset
) {
objc_msgSend(vertexAttribute, selSetOffset, (ulong) offset);
}
private static IntPtr selSetBufferIndex = Selector("setBufferIndex:");
private static void mtlSetVertexAttributeBufferIndex(
IntPtr vertexAttribute,
int bufferIndex
) {
objc_msgSend(vertexAttribute, selSetBufferIndex, (ulong) bufferIndex);
}
private static IntPtr selLayouts = Selector("layouts");
private static IntPtr mtlGetVertexBufferLayoutDescriptor(
IntPtr vertexDesc,
int index
) {
IntPtr layouts = intptr_objc_msgSend(
vertexDesc,
selLayouts
);
return intptr_objc_msgSend(
layouts,
selObjectAtIndexedSubscript,
(ulong) index
);
}
private static IntPtr selSetStride = Selector("setStride:");
private static void mtlSetVertexBufferLayoutStride(
IntPtr vertexBufferLayout,
int stride
) {
objc_msgSend(vertexBufferLayout, selSetStride, (ulong) stride);
}
private static IntPtr selSetStepFunction = Selector("setStepFunction:");
private static void mtlSetVertexBufferLayoutStepFunction(
IntPtr vertexBufferLayout,
MTLVertexStepFunction stepFunc
) {
objc_msgSend(vertexBufferLayout, selSetStepFunction, (ulong) stepFunc);
}
private static IntPtr selSetStepRate = Selector("setStepRate:");
private static void mtlSetVertexBufferLayoutStepRate(
IntPtr vertexBufferLayout,
int stepRate
) {
objc_msgSend(vertexBufferLayout, selSetStepRate, (ulong) stepRate);
}
#endregion
#region Storage Modes
private static IntPtr selSetStorageMode = Selector("setStorageMode:");
private static void mtlSetStorageMode(
IntPtr resource,
MTLStorageMode mode
) {
objc_msgSend(resource, selSetStorageMode, (ulong) mode);
}
#endregion
#region MTLLibrary
private static IntPtr selNewLibraryWithSource = Selector("newLibraryWithSource:options:error:");
private static IntPtr mtlNewLibraryWithSource(
IntPtr device,
IntPtr shaderSourceNSString,
IntPtr compileOptions
) {
IntPtr error = IntPtr.Zero;
IntPtr library = intptr_objc_msgSend(
device,
selNewLibraryWithSource,
shaderSourceNSString,
compileOptions,
out error
);
if (error != IntPtr.Zero)
{
throw new Exception("Metal Error: " + GetNSErrorDescription(error));
}
return library;
}
private static IntPtr selNewFunctionWithName = Selector("newFunctionWithName:");
private static IntPtr mtlNewFunctionWithName(
IntPtr library,
IntPtr shaderNameNSString
) {
return intptr_objc_msgSend(
library,
selNewFunctionWithName,
shaderNameNSString
);
}
#endregion
#region Depth-Stencil State
private static IntPtr mtlNewDepthStencilDescriptor()
{
return intptr_objc_msgSend(classDepthStencilDescriptor, selNew);
}
private static IntPtr mtlNewStencilDescriptor()
{
return intptr_objc_msgSend(classStencilDescriptor, selNew);
}
private static IntPtr selSetDepthCompareFunction = Selector("setDepthCompareFunction:");
private static void mtlSetDepthCompareFunction(
IntPtr depthStencilDescriptor,
MTLCompareFunction func
) {
objc_msgSend(depthStencilDescriptor, selSetDepthCompareFunction, (ulong) func);
}
private static IntPtr selSetDepthWriteEnabled = Selector("setDepthWriteEnabled:");
private static void mtlSetDepthWriteEnabled(
IntPtr depthStencilDescriptor,
bool enabled
) {
objc_msgSend(depthStencilDescriptor, selSetDepthWriteEnabled, enabled);
}
private static IntPtr selSetBackFaceStencil = Selector("setBackFaceStencil:");
private static void mtlSetBackFaceStencil(
IntPtr depthStencilDescriptor,
IntPtr stencilDescriptor
) {
objc_msgSend(depthStencilDescriptor, selSetBackFaceStencil, stencilDescriptor);
}
private static IntPtr selSetFrontFaceStencil = Selector("setFrontFaceStencil:");
private static void mtlSetFrontFaceStencil(
IntPtr depthStencilDescriptor,
IntPtr stencilDescriptor
) {
objc_msgSend(depthStencilDescriptor, selSetFrontFaceStencil, stencilDescriptor);
}
private static IntPtr selNewDepthStencilStateWithDescriptor = Selector("newDepthStencilStateWithDescriptor:");
private static IntPtr mtlNewDepthStencilStateWithDescriptor(
IntPtr device,
IntPtr descriptor
) {
return intptr_objc_msgSend(
device,
selNewDepthStencilStateWithDescriptor,
descriptor
);
}
private static IntPtr selSetStencilFailureOperation = Selector("setStencilFailureOperation:");
private static void mtlSetStencilFailureOperation(
IntPtr stencilDescriptor,
MTLStencilOperation op
) {
objc_msgSend(stencilDescriptor, selSetStencilFailureOperation, (ulong) op);
}
private static IntPtr selSetDepthFailureOperation = Selector("setDepthFailureOperation:");
private static void mtlSetDepthFailureOperation(
IntPtr stencilDescriptor,
MTLStencilOperation op
) {
objc_msgSend(stencilDescriptor, selSetDepthFailureOperation, (ulong) op);
}
private static IntPtr selSetDepthStencilPassOperation = Selector("setDepthStencilPassOperation:");
private static void mtlSetDepthStencilPassOperation(
IntPtr stencilDescriptor,
MTLStencilOperation op
) {
objc_msgSend(stencilDescriptor, selSetDepthStencilPassOperation, (ulong) op);
}
private static IntPtr selSetStencilCompareFunction = Selector("setStencilCompareFunction:");
private static void mtlSetStencilCompareFunction(
IntPtr stencilDescriptor,
MTLCompareFunction func
) {
objc_msgSend(stencilDescriptor, selSetStencilCompareFunction, (ulong) func);
}
private static IntPtr selSetStencilReadMask = Selector("setReadMask:");
private static void mtlSetStencilReadMask(
IntPtr stencilDescriptor,
uint mask
) {
objc_msgSend(stencilDescriptor, selSetStencilReadMask, mask);
}
private static IntPtr selSetStencilWriteMask = Selector("setWriteMask:");
private static void mtlSetStencilWriteMask(
IntPtr stencilDescriptor,
uint mask
) {
objc_msgSend(stencilDescriptor, selSetStencilWriteMask, mask);
}
#endregion
#region Error Handling
private static IntPtr selLocalizedDescription = Selector("localizedDescription");
private static string GetNSErrorDescription(IntPtr error)
{
return NSStringToUTF8(intptr_objc_msgSend(error, selLocalizedDescription));
}
#endregion
#endregion
}
}