Add fixes for Metal for XAM_CORE_4. Fixing the methods takes us to a dangerous path, so we do not do it unless we have issues about the methods. Fixes https://github.com/xamarin/xamarin-macios/issues/9649
This commit is contained in:
Родитель
8a92716c89
Коммит
2c78255dbe
|
@ -1,11 +1,40 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Foundation;
|
||||
using ObjCRuntime;
|
||||
|
||||
namespace Metal {
|
||||
|
||||
|
||||
public static partial class MTLArgumentEncoder_Extensions {
|
||||
#if XAMCORE_4_0
|
||||
public static void SetBuffers (this IMTLArgumentEncoder encoder, IMTLBuffer[] buffers, nuint[] offsets, NSRange range)
|
||||
{
|
||||
if (buffers == null)
|
||||
throw new ArgumentNullException (nameof (buffers));
|
||||
if (offsets == null)
|
||||
throw new ArgumentNullException (nameof (offsets));
|
||||
|
||||
var bufferPtrArray = buffers.Length <= 1024 ? stackalloc IntPtr[buffers.Length] : new IntPtr [buffers.Length];
|
||||
// get all intptr from the array to pass to the lower level call
|
||||
for (var i = 0; i < buffers.Length; i++) {
|
||||
bufferPtrArray [i] = buffers [i].Handle;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
fixed (void* buffersPtr = bufferPtrArray)
|
||||
fixed (void* offsetsPtr = offsets) { // can use fixed
|
||||
encoder.SetBuffers ((IntPtr) buffersPtr, (IntPtr) offsetsPtr, range);
|
||||
}
|
||||
}
|
||||
GC.KeepAlive (buffers)
|
||||
}
|
||||
#else
|
||||
public unsafe static void SetBuffers (this IMTLArgumentEncoder This, IMTLBuffer [] buffers, nint [] offsets, Foundation.NSRange range)
|
||||
{
|
||||
fixed (void* handle = offsets)
|
||||
This.SetBuffers (buffers, (IntPtr)handle, range);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Foundation;
|
||||
using ObjCRuntime;
|
||||
|
||||
namespace Metal {
|
||||
|
||||
#if XAMCORE_4_0
|
||||
|
||||
// add some extension methods to make the API of the protocol nicer
|
||||
public static class IMTLComputeCommandEncoderExtensions {
|
||||
|
||||
public static void SetBuffers (this IMTLComputeCommandEncoder table, IMTLBuffer[] buffers, nuint[] offsets, NSRange range)
|
||||
{
|
||||
if (buffers == null)
|
||||
throw new ArgumentNullException (nameof (buffers));
|
||||
if (offsets == null)
|
||||
throw new ArgumentNullException (nameof (offsets));
|
||||
|
||||
var bufferPtrArray = buffers.Length <= 1024 ? stackalloc IntPtr[buffers.Length] : new IntPtr [buffers.Length];
|
||||
// get all intptr from the array to pass to the lower level call
|
||||
for (var i = 0; i < buffers.Length; i++) {
|
||||
bufferPtrArray [i] = buffers [i].Handle;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
fixed (void* buffersPtr = bufferPtrArray)
|
||||
fixed (void* offsetsPtr = offsets) { // can use fixed
|
||||
table.SetBuffers ((IntPtr) buffersPtr, (IntPtr) offsetsPtr, range);
|
||||
}
|
||||
}
|
||||
GC.KeepAlive (buffers)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -1078,6 +1078,7 @@ METAL_SOURCES = \
|
|||
Metal/MTLArgumentEncoder.cs \
|
||||
Metal/MTLBlitPassSampleBufferAttachmentDescriptorArray.cs \
|
||||
Metal/MTLCompat.cs \
|
||||
Metal/MTLComputeCommandEncoder.cs \
|
||||
Metal/MTLComputePassSampleBufferAttachmentDescriptorArray.cs \
|
||||
Metal/MTLDevice.cs \
|
||||
Metal/MTLIntersectionFunctionTable.cs \
|
||||
|
|
13
src/metal.cs
13
src/metal.cs
|
@ -495,9 +495,16 @@ namespace Metal {
|
|||
[Export ("dispatchThreadgroupsWithIndirectBuffer:indirectBufferOffset:threadsPerThreadgroup:")]
|
||||
void DispatchThreadgroups (IMTLBuffer indirectBuffer, nuint indirectBufferOffset, MTLSize threadsPerThreadgroup);
|
||||
|
||||
#if XAMCORE_4_0
|
||||
[Abstract]
|
||||
[Export ("setBuffers:offsets:withRange:")]
|
||||
void SetBuffers (IntPtr buffers, IntPtr offsets, NSRange range);
|
||||
#else
|
||||
[Abstract]
|
||||
[Export ("setBuffers:offsets:withRange:")]
|
||||
void SetBuffers (IMTLBuffer [] buffers, IntPtr offsets, NSRange range);
|
||||
#endif
|
||||
|
||||
|
||||
[Abstract]
|
||||
[Export ("setSamplerStates:lodMinClamps:lodMaxClamps:withRange:")]
|
||||
|
@ -3911,9 +3918,15 @@ namespace Metal {
|
|||
[Export ("setBuffer:offset:atIndex:")]
|
||||
void SetBuffer ([NullAllowed] IMTLBuffer buffer, nuint offset, nuint index);
|
||||
|
||||
#if XAMCORE_4_0
|
||||
[Abstract]
|
||||
[Export ("setBuffers:offsets:withRange:")]
|
||||
void SetBuffers (IntPtr buffers, IntPtr offsets, NSRange range);
|
||||
#else
|
||||
[Abstract]
|
||||
[Export ("setBuffers:offsets:withRange:")]
|
||||
void SetBuffers (IMTLBuffer[] buffers, IntPtr offsets, NSRange range);
|
||||
#endif
|
||||
|
||||
[Abstract]
|
||||
[Export ("setTexture:atIndex:")]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
#if !__WATCHOS__
|
||||
|
||||
using System;
|
||||
using Foundation;
|
||||
using Metal;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace MonoTouchFixtures.Metal {
|
||||
|
||||
[TestFixture]
|
||||
public class MTLArgumentEncoderTest {
|
||||
IMTLDevice device;
|
||||
IMTLLibrary library;
|
||||
IMTLFunction function;
|
||||
IMTLArgumentEncoder encoder;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp ()
|
||||
{
|
||||
device = MTLDevice.SystemDefault;
|
||||
// some older hardware won't have a default
|
||||
if (device == null)
|
||||
Assert.Inconclusive ("Metal is not supported");
|
||||
|
||||
library = device.CreateDefaultLibrary ();
|
||||
if (library == null) // this happens on a simulator
|
||||
Assert.Inconclusive ("Could not get the functions library for the device.");
|
||||
|
||||
if (library.FunctionNames.Length == 0)
|
||||
Assert.Inconclusive ("Could not get functions for the pipeline.");
|
||||
|
||||
function = library.CreateFunction (library.FunctionNames [0]);
|
||||
encoder = function.CreateArgumentEncoder (0);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown ()
|
||||
{
|
||||
library?.Dispose ();
|
||||
library = null;
|
||||
function?.Dispose ();
|
||||
function = null;
|
||||
encoder?.Dispose ();
|
||||
encoder = null;
|
||||
}
|
||||
|
||||
#if XAMCORE_4_0
|
||||
[Test]
|
||||
public void SetBuffers ()
|
||||
{
|
||||
Assert.Throws<ArgumentNullException> (() => {
|
||||
encoder.SetBuffers (null, new nuint [0], new NSRange ());
|
||||
}, "Null buffers should throw.");
|
||||
|
||||
Assert.Throws<ArgumentNullException> (() => {
|
||||
encoder.SetBuffers (new IMTLBuffer [0], null, new NSRange ());
|
||||
}, "Null offsets should throw.");
|
||||
|
||||
// assert we do not crash or throw, we are testing the extension method
|
||||
Assert.DoesNotThrow (() => {
|
||||
encoder.SetBuffers (new IMTLBuffer [0], new nuint [0], new NSRange ());
|
||||
|
||||
}, "Should not throw");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,69 @@
|
|||
#if !__WATCHOS__
|
||||
|
||||
using System;
|
||||
using Foundation;
|
||||
using Metal;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace MonoTouchFixtures.Metal {
|
||||
|
||||
[TestFixture]
|
||||
public class MTLComputeCommandEncoderTest {
|
||||
IMTLDevice device;
|
||||
IMTLCommandQueue commandQ;
|
||||
IMTLCommandBuffer commandBuffer;
|
||||
IMTLComputeCommandEncoder encoder;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp ()
|
||||
{
|
||||
device = MTLDevice.SystemDefault;
|
||||
// some older hardware won't have a default
|
||||
if (device == null)
|
||||
Assert.Inconclusive ("Metal is not supported");
|
||||
|
||||
commandQ = device.CreateCommandQueue ();
|
||||
if (commandQ == null) // this happens on a simulator
|
||||
Assert.Inconclusive ("Could not get the functions library for the device.");
|
||||
|
||||
commandBuffer = commandQ.CommandBuffer ();
|
||||
if (commandBuffer == null) // happens on sim
|
||||
Assert.Inconclusive ("Could not get the command buffer for the device.");
|
||||
|
||||
encoder = commandBuffer.ComputeCommandEncoder;
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown ()
|
||||
{
|
||||
commandQ?.Dispose ();
|
||||
commandQ = null;
|
||||
commandBuffer?.Dispose ();
|
||||
commandBuffer = null;
|
||||
encoder?.Dispose ();
|
||||
encoder = null;
|
||||
}
|
||||
|
||||
#if XAMCORE_4_0
|
||||
[Test]
|
||||
public void SetBuffers ()
|
||||
{
|
||||
Assert.Throws<ArgumentNullException> (() => {
|
||||
encoder.SetBuffers (null, new nuint [0], new NSRange ());
|
||||
}, "Null buffers should throw.");
|
||||
|
||||
Assert.Throws<ArgumentNullException> (() => {
|
||||
encoder.SetBuffers (new IMTLBuffer [0], null, new NSRange ());
|
||||
}, "Null offsets should throw.");
|
||||
|
||||
// assert we do not crash or throw, we are testing the extension method
|
||||
Assert.DoesNotThrow (() => {
|
||||
encoder.SetBuffers (new IMTLBuffer [0], new nuint [0], new NSRange ());
|
||||
|
||||
}, "Should not throw");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
Загрузка…
Ссылка в новой задаче