void SetupRenderPassDescriptorForTexture(IMTLTexture texture)
        {
            if (renderPassDescriptor == null)
            {
                renderPassDescriptor = MTLRenderPassDescriptor.CreateRenderPassDescriptor();
            }

            renderPassDescriptor.ColorAttachments [0].Texture     = texture;
            renderPassDescriptor.ColorAttachments [0].LoadAction  = MTLLoadAction.Clear;
            renderPassDescriptor.ColorAttachments [0].ClearColor  = new MTLClearColor(0.65f, 0.65f, 0.65f, 1.0f);
            renderPassDescriptor.ColorAttachments [0].StoreAction = MTLStoreAction.Store;

            if (depthTex == null || (depthTex.Width != texture.Width || depthTex.Height != texture.Height))
            {
                //  If we need a depth texture and don't have one, or if the depth texture we have is the wrong size
                //  Then allocate one of the proper size
                MTLTextureDescriptor desc = MTLTextureDescriptor.CreateTexture2DDescriptor(MTLPixelFormat.Depth32Float, texture.Width, texture.Height, false);
                if (ObjCRuntime.Runtime.Arch == ObjCRuntime.Arch.SIMULATOR)
                {
                    desc.StorageMode = MTLStorageMode.Private;
                }
                depthTex       = device.CreateTexture(desc);
                depthTex.Label = "Depth";

                renderPassDescriptor.DepthAttachment.Texture     = depthTex;
                renderPassDescriptor.DepthAttachment.LoadAction  = MTLLoadAction.Clear;
                renderPassDescriptor.DepthAttachment.ClearDepth  = 1.0f;
                renderPassDescriptor.DepthAttachment.StoreAction = MTLStoreAction.DontCare;
            }
        }
Esempio n. 2
0
        private void PlatformConstruct(
            GraphicsDevice graphicsDevice,
            ResourceUploadBatch uploadBatch,
            PixelFormat pixelFormat,
            int width,
            int height,
            TextureMipMapData[] mipMapData)
        {
            var textureDescriptor = MTLTextureDescriptor.CreateTexture2DDescriptor(
                pixelFormat.ToMTLPixelFormat(),
                (nuint)width,
                (nuint)height,
                true); // Ignored, because we'll set the mip level count explicitly below.

            textureDescriptor.Usage = MTLTextureUsage.ShaderRead;

            textureDescriptor.MipmapLevelCount = (nuint)mipMapData.Length;

            _originalPixelFormat = pixelFormat;

            DeviceTexture = AddDisposable(graphicsDevice.Device.CreateTexture(textureDescriptor));

            for (var i = 0; i < mipMapData.Length; i++)
            {
                SetData(
                    i,
                    mipMapData[i].Data,
                    mipMapData[i].BytesPerRow);
            }
        }
		public void MTLTextureDescriptorCreateTest ()
		{
			var arr = new MTLTextureDescriptor [10];
			for (nuint i = 0; i < 10; i++)
				arr [i] = MTLTextureDescriptor.CreateTexture2DDescriptor (MTLPixelFormat.Depth32Float, 50 + i, 50 + i, false);

			var resList = MPSStateResourceList.Create (arr[0], arr [1], arr [2], arr [3], arr [4], arr [5], arr [6], arr [7], arr [8], arr [9]);
			Assert.NotNull (resList, "resList");

			var state = new MPSState (device, resList);
			Assert.That (state.ResourceCount, Is.EqualTo (10), "ResourceCount");
		}
Esempio n. 4
0
        bool PrepareCompute()
        {
            NSError error;

            // Create a compute kernel function
            IMTLFunction function = shaderLibrary.CreateFunction("grayscale");

            if (function == null)
            {
                Console.WriteLine("ERROR: Failed creating a new function!");
                return(false);
            }

            // Create a compute kernel
            kernel = device.CreateComputePipelineState(function, out error);
            if (kernel == null)
            {
                Console.WriteLine("ERROR: Failed creating a compute kernel: %@", error.Description);
                return(false);
            }

            MTLTextureDescriptor texDesc = MTLTextureDescriptor.CreateTexture2DDescriptor(MTLPixelFormat.RGBA8Unorm, (nuint)size.Width, (nuint)size.Height, false);

            if (texDesc == null)
            {
                Console.WriteLine("ERROR: Failed creating a texture 2d descriptor with RGBA unnormalized pixel format!");
                return(false);
            }

            outTexture = device.CreateTexture(texDesc);
            if (outTexture == null)
            {
                Console.WriteLine("ERROR: Failed creating an output 2d texture!");
                return(false);
            }

            // Set the compute kernel's workgroup size and count
            workgroupSize = new MTLSize(1, 1, 1);
            localCount    = new MTLSize((nint)size.Width, (nint)size.Height, 1);
            return(true);
        }
Esempio n. 5
0
        public void Metal()
        {
            TestRuntime.AssertDevice();
            TestRuntime.AssertXcodeVersion(10, 0);

            device = MTLDevice.SystemDefault;
            // some older hardware won't have a default
            if (device == null || !MPSKernel.Supports(device))
            {
                Assert.Inconclusive("Metal is not supported");
            }

            cache = NSArray <MPSState> .FromNSObjects(
                new MPSState (device, MTLTextureDescriptor.CreateTexture2DDescriptor(MTLPixelFormat.RGBA32Float, 220, 220, false)),
                new MPSState (device, MTLTextureDescriptor.CreateTexture2DDescriptor(MTLPixelFormat.RGBA32Float, 221, 221, false)),
                new MPSState (device, MTLTextureDescriptor.CreateTexture2DDescriptor(MTLPixelFormat.RGBA32Float, 222, 222, false)),
                new MPSState (device, MTLTextureDescriptor.CreateTexture2DDescriptor(MTLPixelFormat.RGBA32Float, 223, 223, false)),
                new MPSState (device, MTLTextureDescriptor.CreateTexture2DDescriptor(MTLPixelFormat.RGBA32Float, 224, 224, false)),
                new MPSState (device, MTLTextureDescriptor.CreateTexture2DDescriptor(MTLPixelFormat.RGBA32Float, 225, 225, false))
                );
        }
Esempio n. 6
0
        public void ReturnReleaseTest()
        {
            // This test tries to exercise all the Metal API that has a
            // ReturnRelease attribute. To test that the attribute does the
            // right thing: run the test app using instruments, run the test
            // several times by tapping on it, and do a heap mark between each
            // test. Then verify that there's at least one heap shot with 0
            // memory increase, which means that nothing is leaking.
            var    device = MTLDevice.SystemDefault;
            IntPtr buffer_mem;
            int    buffer_length;
            bool   freed;

            byte [] buffer_bytes;

            // some older hardware won't have a default
            if (device == null)
            {
                Assert.Inconclusive("Metal is not supported");
            }

            // Apple claims that "Indirect command buffers" are available with MTLGPUFamilyCommon2, but it crashes on at least one machine.
            // Log what the current device supports, just to have it in the log.
            foreach (MTLFeatureSet fs in Enum.GetValues(typeof(MTLFeatureSet)))
            {
                Console.WriteLine($"This device supports feature set: {fs}: {device.SupportsFeatureSet (fs)}");
            }
            if (TestRuntime.CheckXcodeVersion(11, 0))
            {
                foreach (MTLGpuFamily gf in Enum.GetValues(typeof(MTLGpuFamily)))
                {
                    Console.WriteLine($"This device supports Gpu family: {gf}: {device.SupportsFamily (gf)}");
                }
            }


            string metal_code          = File.ReadAllText(Path.Combine(NSBundle.MainBundle.ResourcePath, "metal-sample.metal"));
            string metallib_path       = Path.Combine(NSBundle.MainBundle.ResourcePath, "default.metallib");
            string fragmentshader_path = Path.Combine(NSBundle.MainBundle.ResourcePath, "fragmentShader.metallib");

#if !__MACOS__ && !__MACCATALYST__
            if (Runtime.Arch == Arch.SIMULATOR)
            {
                Assert.Ignore("Metal isn't available in the simulator");
            }
#endif
            using (var hd = new MTLHeapDescriptor()) {
                hd.CpuCacheMode = MTLCpuCacheMode.DefaultCache;
                hd.StorageMode  = MTLStorageMode.Private;
                using (var txt = MTLTextureDescriptor.CreateTexture2DDescriptor(MTLPixelFormat.RGBA8Unorm, 40, 40, false)) {
                    var sa = device.GetHeapTextureSizeAndAlign(txt);
                    hd.Size = sa.Size;
                    using (var heap = device.CreateHeap(hd)) {
                        Assert.IsNotNull(heap, $"NonNullHeap");
                    }
                }
            }

            using (var queue = device.CreateCommandQueue()) {
                Assert.IsNotNull(queue, "Queue: NonNull 1");
            }

#if __MACOS__
            if (TestRuntime.CheckXcodeVersion(10, 0) && device.SupportsFeatureSet(MTLFeatureSet.macOS_GPUFamily2_v1))
            {
                using (var descriptor = MTLTextureDescriptor.CreateTexture2DDescriptor(MTLPixelFormat.RGBA8Unorm, 64, 64, false)) {
                    descriptor.StorageMode = MTLStorageMode.Private;
                    using (var texture = device.CreateSharedTexture(descriptor)) {
                        Assert.IsNotNull(texture, "CreateSharedTexture (MTLTextureDescriptor): NonNull");

                        using (var handle = texture.CreateSharedTextureHandle())
                            using (var shared = device.CreateSharedTexture(handle))
                                Assert.IsNotNull(texture, "CreateSharedTexture (MTLSharedTextureHandle): NonNull");
                    }
                }
            }
#endif

            using (var queue = device.CreateCommandQueue(10)) {
                Assert.IsNotNull(queue, "Queue: NonNull 2");
            }

            using (var buffer = device.CreateBuffer(1024, MTLResourceOptions.CpuCacheModeDefault)) {
                Assert.IsNotNull(buffer, "CreateBuffer: NonNull 1");
            }

            buffer_mem = AllocPageAligned(1, out buffer_length);
            using (var buffer = device.CreateBuffer(buffer_mem, (nuint)buffer_length, MTLResourceOptions.CpuCacheModeDefault)) {
                Assert.IsNotNull(buffer, "CreateBuffer: NonNull 2");
            }
            FreePageAligned(buffer_mem, buffer_length);

            buffer_bytes = new byte [getpagesize()];
            using (var buffer = device.CreateBuffer(buffer_bytes, MTLResourceOptions.CpuCacheModeDefault)) {
                Assert.IsNotNull(buffer, "CreateBuffer: NonNull 3");
            }

            buffer_mem = AllocPageAligned(1, out buffer_length);
            freed      = false;
#if __MACOS__
            var resourceOptions7 = MTLResourceOptions.StorageModeManaged;
#else
            var resourceOptions7 = MTLResourceOptions.CpuCacheModeDefault;
#endif
            using (var buffer = device.CreateBufferNoCopy(buffer_mem, (nuint)buffer_length, resourceOptions7, (pointer, length) => { FreePageAligned(pointer, (int)length); freed = true; })) {
                Assert.IsNotNull(buffer, "CreateBufferNoCopy: NonNull 1");
            }
            Assert.IsTrue(freed, "CreateBufferNoCopy: Freed 1");

            using (var descriptor = new MTLDepthStencilDescriptor())
                using (var dss = device.CreateDepthStencilState(descriptor)) {
                    Assert.IsNotNull(dss, "CreateDepthStencilState: NonNull 1");
                }

            using (var descriptor = MTLTextureDescriptor.CreateTexture2DDescriptor(MTLPixelFormat.RGBA8Unorm, 64, 64, false)) {
                using (var texture = device.CreateTexture(descriptor))
                    Assert.NotNull(texture, "CreateTexture: NonNull 1");

                using (var surface = new IOSurface.IOSurface(new IOSurface.IOSurfaceOptions {
                    Width = 64,
                    Height = 64,
                    BytesPerElement = 4,
                })) {
                    using (var texture = device.CreateTexture(descriptor, surface, 0))
                        Assert.NotNull(texture, "CreateTexture: NonNull 2");
                }
            }

            using (var descriptor = new MTLSamplerDescriptor())
                using (var sampler = device.CreateSamplerState(descriptor))
                    Assert.IsNotNull(sampler, "CreateSamplerState: NonNull 1");

            using (var library = device.CreateDefaultLibrary())
                Assert.IsNotNull(library, "CreateDefaultLibrary: NonNull 1");

            using (var library = device.CreateLibrary(metallib_path, out var error)) {
                Assert.IsNotNull(library, "CreateLibrary: NonNull 1");
                Assert.IsNull(error, "CreateLibrary: NonNull error 1");
            }

            using (var data = DispatchData.FromByteBuffer(File.ReadAllBytes(metallib_path)))
                using (var library = device.CreateLibrary(data, out var error)) {
                    Assert.IsNotNull(library, "CreateLibrary: NonNull 2");
                    Assert.IsNull(error, "CreateLibrary: NonNull error 2");
                }

            using (var compile_options = new MTLCompileOptions())
                using (var library = device.CreateLibrary(metal_code, compile_options, out var error)) {
                    Assert.IsNotNull(library, "CreateLibrary: NonNull 3");
                    Assert.IsNull(error, "CreateLibrary: NonNull error 3");
                }

            using (var compile_options = new MTLCompileOptions()) {
                device.CreateLibrary(metal_code, compile_options, (library, error) => {
                    Assert.IsNotNull(library, "CreateLibrary: NonNull 4");
                    Assert.IsNull(error, "CreateLibrary: NonNull error 4");
                });
            }

            using (var library = device.CreateDefaultLibrary(NSBundle.MainBundle, out var error)) {
                Assert.IsNotNull(library, "CreateDefaultLibrary: NonNull 2");
                Assert.IsNull(error, "CreateDefaultLibrary: NonNull error 2");
            }

            using (var descriptor = new MTLRenderPipelineDescriptor())
                using (var library = device.CreateDefaultLibrary())
                    using (var func = library.CreateFunction("vertexShader")) {
                        descriptor.VertexFunction = func;
                        descriptor.ColorAttachments [0].PixelFormat = MTLPixelFormat.BGRA8Unorm_sRGB;
                        using (var rps = device.CreateRenderPipelineState(descriptor, out var error)) {
                            Assert.IsNotNull(rps, "CreateRenderPipelineState: NonNull 1");
                            Assert.IsNull(error, "CreateRenderPipelineState: NonNull error 1");
                        }
                    }

            using (var descriptor = new MTLRenderPipelineDescriptor())
                using (var library = device.CreateDefaultLibrary())
                    using (var func = library.CreateFunction("vertexShader")) {
                        descriptor.VertexFunction = func;
                        descriptor.ColorAttachments [0].PixelFormat = MTLPixelFormat.BGRA8Unorm_sRGB;
                        using (var rps = device.CreateRenderPipelineState(descriptor, MTLPipelineOption.BufferTypeInfo, out var reflection, out var error)) {
                            Assert.IsNotNull(rps, "CreateRenderPipelineState: NonNull 2");
                            Assert.IsNull(error, "CreateRenderPipelineState: NonNull error 2");
                            Assert.IsNotNull(reflection, "CreateRenderPipelineState: NonNull reflection 2");
                        }
                    }

            using (var library = device.CreateDefaultLibrary())
                using (var func = library.CreateFunction("grayscaleKernel"))
                    using (var cps = device.CreateComputePipelineState(func, MTLPipelineOption.ArgumentInfo, out var reflection, out var error)) {
                        Assert.IsNotNull(cps, "CreateComputePipelineState: NonNull 1");
                        Assert.IsNull(error, "CreateComputePipelineState: NonNull error 1");
                        Assert.IsNotNull(reflection, "CreateComputePipelineState: NonNull reflection 1");
                    }

            using (var library = device.CreateDefaultLibrary())
                using (var func = library.CreateFunction("grayscaleKernel"))
                    using (var cps = device.CreateComputePipelineState(func, out var error)) {
                        Assert.IsNotNull(cps, "CreateComputePipelineState: NonNull 2");
                        Assert.IsNull(error, "CreateComputePipelineState: NonNull error 2");
                    }

            using (var descriptor = new MTLComputePipelineDescriptor())
                using (var library = device.CreateDefaultLibrary())
                    using (var func = library.CreateFunction("grayscaleKernel")) {
                        descriptor.ComputeFunction = func;
                        using (var cps = device.CreateComputePipelineState(descriptor, MTLPipelineOption.BufferTypeInfo, out var reflection, out var error)) {
                            Assert.IsNotNull(cps, "CreateComputePipelineState: NonNull 3");
                            Assert.IsNull(error, "CreateComputePipelineState: NonNull error 3");
                            Assert.IsNotNull(reflection, "CreateComputePipelineState: NonNull reflection 3");
                        }
                    }

            using (var fence = device.CreateFence()) {
                Assert.IsNotNull(fence, "CreateFence 1: NonNull");
            }

            var url = "file://" + metallib_path;
            url = url.Replace(" ", "%20");              // url encode!
            using (var library = device.CreateLibrary(new NSUrl(url), out var error)) {
#if NET
                // Looks like creating a library with a url always fails: https://forums.developer.apple.com/thread/110416
                Assert.IsNotNull(library, "CreateLibrary (NSUrl, NSError): Null");
                Assert.IsNull(error, "CreateLibrary (NSUrl, NSError): NonNull error");
#else
                // Looks like creating a library with a url always fails: https://forums.developer.apple.com/thread/110416
                Assert.IsNull(library, "CreateLibrary (NSUrl, NSError): Null");
                Assert.IsNotNull(error, "CreateLibrary (NSUrl, NSError): NonNull error");
#endif
            }

            using (var library = device.CreateArgumentEncoder(new MTLArgumentDescriptor [] { new MTLArgumentDescriptor()
                                                                                             {
                                                                                                 DataType = MTLDataType.Int
                                                                                             } })) {
                Assert.IsNotNull(library, "CreateArgumentEncoder (MTLArgumentDescriptor[]): NonNull");
            }

            // Apple's charts say that "Indirect command buffers" are supported with MTLGpuFamilyCommon2
            var supportsIndirectCommandBuffers = TestRuntime.CheckXcodeVersion(11, 0) && device.SupportsFamily(MTLGpuFamily.Common2);
#if __MACOS__
            // but something's not quite right somewhere, so on macOS verify that the device supports a bit more than what Apple says.
            supportsIndirectCommandBuffers &= device.SupportsFeatureSet(MTLFeatureSet.macOS_GPUFamily2_v1);
#endif
            if (supportsIndirectCommandBuffers)
            {
                using (var descriptor = new MTLIndirectCommandBufferDescriptor()) {
                    using (var library = device.CreateIndirectCommandBuffer(descriptor, 1, MTLResourceOptions.CpuCacheModeDefault)) {
                        Assert.IsNotNull(library, "CreateIndirectCommandBuffer: NonNull");
                    }
                }

                using (var evt = device.CreateEvent()) {
                    Assert.IsNotNull(evt, "CreateEvent: NonNull");
                }

                using (var evt = device.CreateSharedEvent()) {
                    Assert.IsNotNull(evt, "CreateSharedEvent: NonNull");
                }

                using (var evt1 = device.CreateSharedEvent())
                    using (var evt_handle = evt1.CreateSharedEventHandle())
                        using (var evt = device.CreateSharedEvent(evt_handle)) {
                            Assert.IsNotNull(evt, "CreateSharedEvent (MTLSharedEventHandle): NonNull");
                        }
            }

            using (var descriptor = new MTLRenderPipelineDescriptor())
                using (var library = device.CreateDefaultLibrary())
                    using (var func = library.CreateFunction("vertexShader")) {
                        descriptor.VertexFunction = func;
                        descriptor.ColorAttachments [0].PixelFormat = MTLPixelFormat.BGRA8Unorm_sRGB;
                        using (var rps = device.CreateRenderPipelineState(descriptor, MTLPipelineOption.ArgumentInfo, out var reflection, out var error)) {
                            Assert.IsNotNull(rps, "CreateRenderPipelineState (MTLTileRenderPipelineDescriptor, MTLPipelineOption, MTLRenderPipelineReflection, NSError): NonNull");
                            Assert.IsNull(error, "CreateRenderPipelineState (MTLTileRenderPipelineDescriptor, MTLPipelineOption, MTLRenderPipelineReflection, NSError: NonNull error");
                            Assert.IsNotNull(reflection, "CreateRenderPipelineState (MTLTileRenderPipelineDescriptor, MTLPipelineOption, MTLRenderPipelineReflection, NSError): NonNull reflection");
                        }
                    }

            using (var buffer = device.CreateBuffer(1024, MTLResourceOptions.CpuCacheModeDefault))
                using (var descriptor = new MTLTextureDescriptor())
                    using (var texture = buffer.CreateTexture(descriptor, 0, 256)) {
                        Assert.IsNotNull(buffer, "MTLBuffer.CreateTexture (MTLTextureDescriptor, nuint, nuint): NonNull");
                    }

            using (var descriptor = MTLTextureDescriptor.CreateTexture2DDescriptor(MTLPixelFormat.RGBA8Unorm, 64, 64, false))
                using (var texture = device.CreateTexture(descriptor)) {
                    using (var view = texture.CreateTextureView(MTLPixelFormat.RGBA8Unorm)) {
                        Assert.IsNotNull(view, "MTLTexture.CreateTextureView (MTLPixelFormat): nonnull");
                    }
                    using (var view = texture.CreateTextureView(MTLPixelFormat.RGBA8Unorm, MTLTextureType.k2D, new NSRange(0, 1), new NSRange(0, 1))) {
                        Assert.IsNotNull(view, "MTLTexture.CreateTextureView (MTLPixelFormat, MTLTextureType, NSRange, NSRange): nonnull");
                    }
                }

            using (var library = device.CreateLibrary(fragmentshader_path, out var error)) {
                Assert.IsNull(error, "MTLFunction.CreateArgumentEncoder: library creation failure");
                using (var func = library.CreateFunction("fragmentShader2")) {
                    using (var enc = func.CreateArgumentEncoder(0)) {
                        Assert.IsNotNull(enc, "MTLFunction.CreateArgumentEncoder (nuint): NonNull");
                    }
                    using (var enc = func.CreateArgumentEncoder(0, out var reflection)) {
                        Assert.IsNotNull(enc, "MTLFunction.CreateArgumentEncoder (nuint, MTLArgument): NonNull");
                        Assert.IsNotNull(reflection, "MTLFunction.CreateArgumentEncoder (nuint, MTLArgument): NonNull reflection");
                    }
                }
            }

            using (var library = device.CreateDefaultLibrary()) {
                using (var func = library.CreateFunction("grayscaleKernel")) {
                    Assert.IsNotNull(func, "CreateFunction (string): nonnull");
                }
                if (TestRuntime.CheckXcodeVersion(9, 0))                    // MTLFunctionConstantValues didn't have a default ctor until Xcode 9.
                {
                    using (var constants = new MTLFunctionConstantValues())
                        using (var func = library.CreateFunction("grayscaleKernel", constants, out var error)) {
                            Assert.IsNotNull(func, "CreateFunction (string, MTLFunctionConstantValues, NSError): nonnull");
                            Assert.IsNull(error, "CreateFunction (string, MTLFunctionConstantValues, NSError): null error");
                        }
                }
            }

            using (var hd = new MTLHeapDescriptor()) {
                hd.CpuCacheMode = MTLCpuCacheMode.DefaultCache;
                hd.StorageMode  = MTLStorageMode.Private;
                using (var txt = MTLTextureDescriptor.CreateTexture2DDescriptor(MTLPixelFormat.RGBA8Unorm, 40, 40, false)) {
                    var sa = device.GetHeapTextureSizeAndAlign(txt);
                    hd.Size = sa.Size;
                    using (var heap = device.CreateHeap(hd))
                        using (var buffer = heap.CreateBuffer(1024, MTLResourceOptions.StorageModePrivate)) {
                            Assert.IsNotNull(buffer, "MTLHeap.CreateBuffer (nuint, MTLResourceOptions): nonnull");
                        }
                }
            }

            using (var hd = new MTLHeapDescriptor()) {
                hd.CpuCacheMode = MTLCpuCacheMode.DefaultCache;
#if __MACOS__ || __MACCATALYST__
                hd.StorageMode = MTLStorageMode.Private;
#else
                hd.StorageMode = MTLStorageMode.Shared;
#endif
                using (var txt = MTLTextureDescriptor.CreateTexture2DDescriptor(MTLPixelFormat.RGBA8Unorm, 40, 40, false)) {
                    var sa = device.GetHeapTextureSizeAndAlign(txt);
                    hd.Size = sa.Size;

                    using (var heap = device.CreateHeap(hd)) {
#if __MACOS__ || __MACCATALYST__
                        txt.StorageMode = MTLStorageMode.Private;
#endif
                        using (var texture = heap.CreateTexture(txt)) {
                            Assert.IsNotNull(texture, "MTLHeap.CreateTexture (MTLTextureDescriptor): nonnull");
                        }
                    }
                }
            }

            using (var scope = MTLCaptureManager.Shared.CreateNewCaptureScope(device)) {
                Assert.IsNotNull(scope, "MTLCaptureManager.CreateNewCaptureScope (MTLDevice): nonnull");
            }

            using (var queue = device.CreateCommandQueue())
                using (var scope = MTLCaptureManager.Shared.CreateNewCaptureScope(queue)) {
                    Assert.IsNotNull(scope, "MTLCaptureManager.CreateNewCaptureScope (MTLCommandQueue): nonnull");
                }

            TestRuntime.AssertXcodeVersion(10, 0);
            using (var evt = device.CreateSharedEvent())
                using (var shared = evt.CreateSharedEventHandle()) {
                    Assert.IsNotNull(shared, "MTLSharedEvent.CreateSharedEvent: NonNull");
                }
        }
Esempio n. 7
0
        void SetupRenderPassDescriptorForTexture(IMTLTexture texture)
        {
            if (renderPassDescriptor == null)
            {
                renderPassDescriptor = new MTLRenderPassDescriptor();
            }

            MTLRenderPassColorAttachmentDescriptor colorAttachment = renderPassDescriptor.ColorAttachments [0];

            colorAttachment.Texture    = texture;
            colorAttachment.LoadAction = MTLLoadAction.Clear;
            colorAttachment.ClearColor = new MTLClearColor(0.65f, 0.65f, 0.65f, 1.0f);

            if (SampleCount > 1)
            {
                if (msaaTex == null || NeedUpdate(texture, msaaTex))
                {
                    var desc = MTLTextureDescriptor.CreateTexture2DDescriptor(MTLPixelFormat.BGRA8Unorm, texture.Width, texture.Height, false);
                    desc.TextureType = MTLTextureType.k2DMultisample;
                    desc.SampleCount = SampleCount;
                    msaaTex          = device.CreateTexture(desc);
                }

                colorAttachment.Texture        = msaaTex;
                colorAttachment.ResolveTexture = texture;

                // set store action to resolve in this case
                colorAttachment.StoreAction = MTLStoreAction.MultisampleResolve;
            }
            else
            {
                colorAttachment.StoreAction = MTLStoreAction.Store;
            }

            if (DepthPixelFormat != MTLPixelFormat.Invalid)
            {
                if (depthTex == null || NeedUpdate(texture, depthTex))
                {
                    var desc = MTLTextureDescriptor.CreateTexture2DDescriptor(DepthPixelFormat, texture.Width, texture.Height, false);
                    desc.TextureType = (SampleCount > 1) ? MTLTextureType.k2DMultisample : MTLTextureType.k2D;
                    desc.SampleCount = SampleCount;
                    depthTex         = device.CreateTexture(desc);

                    MTLRenderPassDepthAttachmentDescriptor depthAttachment = renderPassDescriptor.DepthAttachment;
                    depthAttachment.Texture     = depthTex;
                    depthAttachment.LoadAction  = MTLLoadAction.Clear;
                    depthAttachment.StoreAction = MTLStoreAction.DontCare;
                    depthAttachment.ClearDepth  = 1.0;
                }
            }

            if (StencilPixelFormat != MTLPixelFormat.Invalid)
            {
                if (stencilTex == null || NeedUpdate(texture, stencilTex))
                {
                    var desc = MTLTextureDescriptor.CreateTexture2DDescriptor(StencilPixelFormat, texture.Width, texture.Height, false);
                    desc.TextureType = (SampleCount > 1) ? MTLTextureType.k2DMultisample : MTLTextureType.k2D;
                    desc.SampleCount = SampleCount;
                    depthTex         = device.CreateTexture(desc);

                    MTLRenderPassStencilAttachmentDescriptor stencilAttachment = renderPassDescriptor.StencilAttachment;
                    stencilAttachment.Texture      = depthTex;
                    stencilAttachment.LoadAction   = MTLLoadAction.Clear;
                    stencilAttachment.StoreAction  = MTLStoreAction.DontCare;
                    stencilAttachment.ClearStencil = 1;
                }
            }
        }
Esempio n. 8
0
        public bool Finalize(IMTLDevice device)
        {
            if (MetalTexture != null)
            {
                return(true);
            }

            UIImage image = UIImage.FromFile(path);

            if (image == null)
            {
                return(false);
            }

            using (CGColorSpace colorSpace = CGColorSpace.CreateDeviceRGB()) {
                if (colorSpace == null)
                {
                    return(false);
                }

                Width  = image.CGImage.Width;
                Height = image.CGImage.Height;

                nuint width    = (nuint)Width;
                nuint height   = (nuint)Height;
                nuint rowBytes = width * 4;

                var context = new CGBitmapContext(IntPtr.Zero,
                                                  (int)width,
                                                  (int)height,
                                                  8,
                                                  (int)rowBytes,
                                                  colorSpace,
                                                  CGImageAlphaInfo.PremultipliedLast);

                if (context == null)
                {
                    return(false);
                }

                var bounds = new CGRect(0f, 0f, width, height);
                context.ClearRect(bounds);

                // Vertical Reflect
                if (flip)
                {
                    context.TranslateCTM(width, height);
                    context.ScaleCTM(-1f, -1f);
                }

                context.DrawImage(bounds, image.CGImage);
                MTLTextureDescriptor texDesc = MTLTextureDescriptor.CreateTexture2DDescriptor(MTLPixelFormat.RGBA8Unorm, width, height, false);

                if (texDesc == null)
                {
                    return(false);
                }

                MetalTexture = device.CreateTexture(texDesc);

                if (MetalTexture == null)
                {
                    context.Dispose();
                    return(false);
                }

                IntPtr pixels = context.Data;

                if (pixels != IntPtr.Zero)
                {
                    var region = new MTLRegion();
                    region.Origin.X    = 0;
                    region.Origin.Y    = 0;
                    region.Size.Width  = (nint)width;
                    region.Size.Height = (nint)height;

                    MetalTexture.ReplaceRegion(region, 0, pixels, rowBytes);
                }

                context.Dispose();
            }

            return(true);
        }