Example #1
0
 public void Draw(MTKView view)
 {
     if (mApplication != null)
     {
         mApplication.Render();
     }
 }
        public override void ViewDidLoad()
        {
            metalView = (MTKView)View;

            // Set the view to use the default device.
            metalView.Device = MTLDevice.SystemDefault;

            // Make sure the current device supports MetalPerformanceShaders.
            if (metalView.Device == null)
            {
                return;
            }

            bool deviceSupportsMPS = MPSKernel.Supports(metalView.Device);

            if (!deviceSupportsMPS)
            {
                return;
            }

            MetalPerformanceShadersDisabledLabel.Hidden = true;
            SetupView();
            SetupMetal();
            LoadAssets();
        }
Example #3
0
        public void DrawableSizeWillChange(MTKView view, CGSize size)
        {
            float aspect = (float)Math.Abs(View.Bounds.Width / View.Bounds.Height);

            projectionMatrix = MathHelper.MatrixFromPerspectiveFovAspectLH(65f * (float)Math.PI / 180f, aspect, .1f, 100f);
            viewMatrix       = Matrix4.Identity;
        }
Example #4
0
        private void InitRenderer()
        {
            _renderer = new Renderer();
            var device = MTLDevice.SystemDefault;

            if (device == null)
            {
                throw new NotSupportedException("Metal is not supported");
            }
            MTKView mtkView = new MTKView(View.Frame, device)
            {
                TranslatesAutoresizingMaskIntoConstraints = false
            };

            View.AddSubview(mtkView);

            var constraints = new[]
            {
                mtkView.LeftAnchor.ConstraintEqualTo(View.LeftAnchor),
                mtkView.RightAnchor.ConstraintEqualTo(View.RightAnchor),
                mtkView.TopAnchor.ConstraintEqualTo(View.TopAnchor),
                mtkView.BottomAnchor.ConstraintEqualTo(View.BottomAnchor, 0.5f),
            };

            NSLayoutConstraint.ActivateConstraints(constraints);

            _renderer.InitRenderer(mtkView, device);
        }
Example #5
0
 public SwapChain(
     GraphicsDevice graphicsDevice,
     MTKView metalView)
 {
     _graphicsDevice = graphicsDevice;
     _metalView      = metalView;
 }
        public void Draw(MTKView view)
        {
            // Create a new command buffer for each renderpass to the current drawable
            IMTLCommandBuffer commandBuffer = commandQueue.CommandBuffer();

            // Call the view's completion handler which is required by the view since it will signal its semaphore and set up the next buffer
            var drawable = view.CurrentDrawable;

            // Obtain a renderPassDescriptor generated from the view's drawable textures
            MTLRenderPassDescriptor renderPassDescriptor = view.CurrentRenderPassDescriptor;

            // If we have a valid drawable, begin the commands to render into it
            if (renderPassDescriptor != null)
            {
                // Create a render command encoder so we can render into something
                IMTLRenderCommandEncoder renderEncoder = commandBuffer.CreateRenderCommandEncoder(renderPassDescriptor);

                // Set context state
                renderEncoder.SetDepthStencilState(depthState);
                renderEncoder.SetRenderPipelineState(pipelineState);
                renderEncoder.SetVertexBuffer(vertexBuffer, 0, 0);

                // Tell the render context we want to draw our primitives
                renderEncoder.DrawIndexedPrimitives(MTLPrimitiveType.Triangle, (nuint)indexData.Length, MTLIndexType.UInt16, indexBuffer, 0);

                // We're done encoding commands
                renderEncoder.EndEncoding();

                // Schedule a present once the framebuffer is complete using the current drawable
                commandBuffer.PresentDrawable(drawable);
            }

            // Finalize rendering here & push the command buffer to the GPU
            commandBuffer.Commit();
        }
Example #7
0
 public void DrawableSizeWillChange(MTKView view, CoreGraphics.CGSize size)
 {
     if (mApplication != null)
     {
         mApplication.Reshape((uint)size.Width, (uint)size.Height);
     }
 }
Example #8
0
        public override void Draw(MTKView view)
        {
#if BGFX
            Bgfx.Bgfx.Reset((int)view.Bounds.Size.Width, (int)view.Bounds.Size.Height, 0, 0);
            Bgfx.Bgfx.SetViewClear(0, (ClearTargets.Color | ClearTargets.Depth), 0x443355FF, 1.0f, 0);
            Bgfx.Bgfx.SetViewRect(0, 0, 0, (ushort)view.Bounds.Size.Width, (ushort)view.Bounds.Size.Height);

            var target     = Vector3.Zero;
            var camera     = new Vector3(0, 0, -5);
            var lookAtView = CreateLookAt(camera, target, Vector3.UnitY);


            var fov = MathOps.ToDegrees(60f);
            var projectionMatrix = CreatePerspectiveFieldOfView(fov, (float)(view.Bounds.Size.Width / view.Bounds.Size.Height), 0.1f, 100f);

            Bgfx.Bgfx.SetViewTransform(0, lookAtView.ToFloats(), projectionMatrix.ToFloats());

            float offset   = (float)_frame;
            var   rotation = Matrix4x4.CreateFromYawPitchRoll(offset * 0.01f, offset * 0.01f, offset * 0.01f);

            Bgfx.Bgfx.SetTransform(rotation.ToFloats());

            Bgfx.Bgfx.SetVertexBuffer(0, _vertexBuffer);
            Bgfx.Bgfx.SetIndexBuffer(_indexBuffer);
            Bgfx.Bgfx.Submit(0, _program);

            _frame = Bgfx.Bgfx.Frame();
            System.Diagnostics.Debug.WriteLine($"Frame {_frame}");
#endif
        }
Example #9
0
 MTKView MakeMTKView()
 {
     mtkView = new MTKView(this.Frame, MTLDevice.SystemDefault);
     mtkView.BackgroundColor         = UIColor.Blue;
     mtkView.ColorPixelFormat        = MTLPixelFormat.BGRA8Unorm;
     mtkView.DepthStencilPixelFormat = MTLPixelFormat.Invalid;
     mtkView.EnableSetNeedsDisplay   = false;
     return(mtkView);
 }
Example #10
0
        public void Draw(MTKView view)
        {
            // Update
            var time          = clock.ElapsedMilliseconds / 1000.0f;
            var viewProj      = Matrix4.Mult(this.view, this.proj);
            var worldViewProj = Matrix4.CreateRotationX(time) * Matrix4.CreateRotationY(time * 2) * Matrix4.CreateRotationZ(time * .7f) * viewProj;

            worldViewProj = Matrix4.Transpose(worldViewProj);

            int rawsize = Marshal.SizeOf <Matrix4>();
            var rawdata = new byte[rawsize];

            GCHandle pinnedUniforms = GCHandle.Alloc(worldViewProj, GCHandleType.Pinned);
            IntPtr   ptr            = pinnedUniforms.AddrOfPinnedObject();

            Marshal.Copy(ptr, rawdata, 0, rawsize);
            pinnedUniforms.Free();

            Marshal.Copy(rawdata, 0, constantBuffer.Contents + rawsize, rawsize);

            // Create a new command buffer for each renderpass to the current drawable
            IMTLCommandBuffer commandBuffer = commandQueue.CommandBuffer();

            // Call the view's completion handler which is required by the view since it will signal its semaphore and set up the next buffer
            var drawable = view.CurrentDrawable;

            // Obtain a renderPassDescriptor generated from the view's drawable textures
            MTLRenderPassDescriptor renderPassDescriptor = view.CurrentRenderPassDescriptor;

            // If we have a valid drawable, begin the commands to render into it
            if (renderPassDescriptor != null)
            {
                // Create a render command encoder so we can render into something
                IMTLRenderCommandEncoder renderEncoder = commandBuffer.CreateRenderCommandEncoder(renderPassDescriptor);
                renderEncoder.SetDepthStencilState(depthState);

                // Set context state
                renderEncoder.SetRenderPipelineState(pipelineState);
                renderEncoder.SetVertexBuffer(vertexBuffer, 0, 0);
                renderEncoder.SetVertexBuffer(constantBuffer, (nuint)Marshal.SizeOf <Matrix4>(), 1);
                renderEncoder.SetFragmentTexture(this.texture, 0);
                renderEncoder.SetFragmentSamplerState(this.sampler, 0);

                // Tell the render context we want to draw our primitives
                renderEncoder.DrawPrimitives(MTLPrimitiveType.Triangle, 0, (nuint)vertexData.Length);

                // We're done encoding commands
                renderEncoder.EndEncoding();

                // Schedule a present once the framebuffer is complete using the current drawable
                commandBuffer.PresentDrawable(drawable);
            }

            // Finalize rendering here & push the command buffer to the GPU
            commandBuffer.Commit();
        }
        void SetupView()
        {
            view          = (MTKView)View;
            view.Delegate = this;
            view.Device   = device;

            // Setup the render target, choose values based on your app
            view.SampleCount             = 4;
            view.DepthStencilPixelFormat = MTLPixelFormat.Depth32Float_Stencil8;
        }
        public void Draw(MTKView view)
        {
            // Update
            this.time += this.clock.ElapsedMilliseconds / 1000.0f;
            if (this.time > 2)
            {
                this.time = 0;
                clock.Restart();

                this.mipmapping++;

                if (this.mipmapping >= this.texture.MipmapLevelCount)
                {
                    this.mipmapping = 0;
                }

                SetConstantBuffer(this.mipmapping, this.constantBuffer);
            }

            // Create a new command buffer for each renderpass to the current drawable
            IMTLCommandBuffer commandBuffer = commandQueue.CommandBuffer();

            // Call the view's completion handler which is required by the view since it will signal its semaphore and set up the next buffer
            var drawable = view.CurrentDrawable;

            // Obtain a renderPassDescriptor generated from the view's drawable textures
            MTLRenderPassDescriptor renderPassDescriptor = view.CurrentRenderPassDescriptor;

            // If we have a valid drawable, begin the commands to render into it
            if (renderPassDescriptor != null)
            {
                // Create a render command encoder so we can render into something
                IMTLRenderCommandEncoder renderEncoder = commandBuffer.CreateRenderCommandEncoder(renderPassDescriptor);

                // Set context state
                renderEncoder.SetDepthStencilState(depthState);
                renderEncoder.SetRenderPipelineState(pipelineState);
                renderEncoder.SetVertexBuffer(vertexBuffer, 0, 0);
                renderEncoder.SetFragmentBuffer(constantBuffer, (nuint)sizeof(float), 1);
                renderEncoder.SetFragmentTexture(this.texture, 0);
                renderEncoder.SetFragmentSamplerState(this.sampler, 0);

                // Tell the render context we want to draw our primitives
                renderEncoder.DrawPrimitives(MTLPrimitiveType.Triangle, 0, (uint)vertexData.Length);

                // We're done encoding commands
                renderEncoder.EndEncoding();

                // Schedule a present once the framebuffer is complete using the current drawable
                commandBuffer.PresentDrawable(drawable);
            }

            // Finalize rendering here & push the command buffer to the GPU
            commandBuffer.Commit();
        }
Example #13
0
        public AmtPresentationLayer(MTKView view, IMgSwapchainCollection swapchainCollection)
        {
            mView = view;

            mLayers    = new AmtLayerInfo[1];
            mLayers[0] = new AmtLayerInfo
            {
                Inflight = new Semaphore(1, 1),
            };
            mCollection = swapchainCollection;
        }
Example #14
0
        void IMTKViewDelegate.DrawableSizeWillChange(MTKView view, CGSize size)
        {
            CanvasSize = size.ToSKSize();

            if (Paused && EnableSetNeedsDisplay)
#if __IOS__
            { SetNeedsDisplay(); }
#elif __MACOS__
            { NeedsDisplay = true; }
#endif
        }
Example #15
0
        public MetalGraphicsView()
        {
            _graphicsDevice = new GraphicsDevice();

            _metalView = new MTKView(CGRect.Empty, _graphicsDevice.Device);
            _metalView.ColorPixelFormat = global::Metal.MTLPixelFormat.BGRA8Unorm;
            _metalView.Delegate         = this;
            AddSubview(_metalView);

            _swapChain = new SwapChain(_graphicsDevice, _metalView);
        }
        public void Draw(MTKView view)
        {
            // Update
            var time     = clock.ElapsedMilliseconds / 1000.0f;
            var viewProj = Matrix4.Mult(this.view, this.proj);
            var world    = Matrix4.CreateRotationX(time) * Matrix4.CreateRotationY(time * 2) * Matrix4.CreateRotationZ(time * .7f);

            var worldViewProj = world * viewProj;
            var worldInverse  = Matrix4.Invert(world);

            param.World = Matrix4.Transpose(world);
            param.WorldInverseTranspose = worldInverse;
            param.WorldViewProjection   = Matrix4.Transpose(worldViewProj);

            SetConstantBuffer(this.param, constantBuffer);

            // Create a new command buffer for each renderpass to the current drawable
            IMTLCommandBuffer commandBuffer = commandQueue.CommandBuffer();

            // Call the view's completion handler which is required by the view since it will signal its semaphore and set up the next buffer
            var drawable = view.CurrentDrawable;

            // Obtain a renderPassDescriptor generated from the view's drawable textures
            MTLRenderPassDescriptor renderPassDescriptor = view.CurrentRenderPassDescriptor;

            // If we have a valid drawable, begin the commands to render into it
            if (renderPassDescriptor != null)
            {
                // Create a render command encoder so we can render into something
                IMTLRenderCommandEncoder renderEncoder = commandBuffer.CreateRenderCommandEncoder(renderPassDescriptor);

                // Set context state
                renderEncoder.SetDepthStencilState(depthState);
                renderEncoder.SetRenderPipelineState(pipelineState);
                renderEncoder.SetVertexBuffer(vertexBuffer, 0, 0);
                renderEncoder.SetVertexBuffer(constantBuffer, (nuint)Marshal.SizeOf(this.param), 1);
                renderEncoder.SetFragmentBuffer(constantBuffer, (nuint)Marshal.SizeOf(this.param), 1);
                renderEncoder.SetFragmentTexture(this.texture, 0);
                renderEncoder.SetFragmentSamplerState(this.sampler, 0);

                // Tell the render context we want to draw our primitives
                renderEncoder.DrawIndexedPrimitives(MTLPrimitiveType.Triangle, (uint)indexDataArray.Length, MTLIndexType.UInt16, indexBuffer, 0);

                // We're done encoding commands
                renderEncoder.EndEncoding();

                // Schedule a present once the framebuffer is complete using the current drawable
                commandBuffer.PresentDrawable(drawable);
            }

            // Finalize rendering here & push the command buffer to the GPU
            commandBuffer.Commit();
        }
		public override void ViewDidLoad ()
		{
			metalView = (MTKView)View;

			// Make sure the current device supports MetalPerformanceShaders.
			if (!metalView.Device.SupportsFeatureSet (MTLFeatureSet.iOS_GPUFamily2_v1))
				return;

			MetalPerformanceShadersDisabledLabel.Hidden = true;
			SetupView ();
			SetupMetal ();
			LoadAssets ();
		}
Example #18
0
        public void Draw(MTKView view)
        {
            // Update
            var time          = clock.ElapsedMilliseconds / 1000.0f;
            var viewProj      = Matrix4.Mult(this.view, this.proj);
            var worldViewProj = Matrix4.CreateRotationY(time * 2) * Matrix4.Scale(0.0015f) * viewProj;

            worldViewProj = Matrix4.Transpose(worldViewProj);
            this.param.WorldViewProjection = worldViewProj;
            SetConstantBuffer(this.param, constantBuffer);

            // Create a new command buffer for each renderpass to the current drawable
            IMTLCommandBuffer commandBuffer = commandQueue.CommandBuffer();

            // Call the view's completion handler which is required by the view since it will signal its semaphore and set up the next buffer
            var drawable = view.CurrentDrawable;

            // Obtain a renderPassDescriptor generated from the view's drawable textures
            MTLRenderPassDescriptor renderPassDescriptor = view.CurrentRenderPassDescriptor;

            // If we have a valid drawable, begin the commands to render into it
            if (renderPassDescriptor != null)
            {
                // Create a render command encoder so we can render into something
                IMTLRenderCommandEncoder renderEncoder = commandBuffer.CreateRenderCommandEncoder(renderPassDescriptor);

                // Set context state
                renderEncoder.SetDepthStencilState(depthState);
                renderEncoder.SetRenderPipelineState(pipelineState);
                renderEncoder.SetVertexBuffer(objMesh.VertexBuffers[0].Buffer, objMesh.VertexBuffers[0].Offset, 0);
                renderEncoder.SetVertexBuffer(constantBuffer, (nuint)Marshal.SizeOf <Matrix4>(), 1);
                renderEncoder.SetFragmentTexture(this.texture, 0);
                renderEncoder.SetFragmentSamplerState(this.sampler, 0);

                for (int i = 0; i < objMesh.Submeshes.Length; i++)
                {
                    MTKSubmesh submesh = objMesh.Submeshes[i];
                    renderEncoder.DrawIndexedPrimitives(submesh.PrimitiveType, submesh.IndexCount, submesh.IndexType, submesh.IndexBuffer.Buffer, submesh.IndexBuffer.Offset);
                }

                // We're done encoding commands
                renderEncoder.EndEncoding();

                // Schedule a present once the framebuffer is complete using the current drawable
                commandBuffer.PresentDrawable(drawable);
            }

            // Finalize rendering here & push the command buffer to the GPU
            commandBuffer.Commit();
        }
Example #19
0
        void IMTKViewDelegate.Draw(MTKView view)
        {
            if (designMode)
            {
                return;
            }

            if (backendContext.Device == null || backendContext.Queue == null || CurrentDrawable?.Texture == null)
            {
                return;
            }

            CanvasSize = DrawableSize.ToSKSize();

            if (CanvasSize.Width <= 0 || CanvasSize.Height <= 0)
            {
                return;
            }

            // create the contexts if not done already
            context ??= GRContext.CreateMetal(backendContext);

            const SKColorType     colorType     = SKColorType.Bgra8888;
            const GRSurfaceOrigin surfaceOrigin = GRSurfaceOrigin.TopLeft;

            // create the render target
            var metalInfo = new GRMtlTextureInfo(CurrentDrawable.Texture);

            using var renderTarget = new GRBackendRenderTarget((int)CanvasSize.Width, (int)CanvasSize.Height, (int)SampleCount, metalInfo);

            // create the surface
            using var surface = SKSurface.Create(context, renderTarget, surfaceOrigin, colorType);
            using var canvas  = surface.Canvas;

            // start drawing
            var e = new SKPaintMetalSurfaceEventArgs(surface, renderTarget, surfaceOrigin, colorType);

            OnPaintSurface(e);

            // flush the SkiaSharp contents
            canvas.Flush();
            surface.Flush();
            context.Flush();

            // present
            using var commandBuffer = backendContext.Queue.CommandBuffer();
            commandBuffer.PresentDrawable(CurrentDrawable);
            commandBuffer.Commit();
        }
Example #20
0
        public AmtSwapchainKHR(MTKView view, IAmtSwapchainImageView color)
        {
            mImages = new AmtSwapchainKHRImageInfo[NO_OF_BUFFERS];
            for (var i = 0; i < NO_OF_BUFFERS; ++i)
            {
                mImages[i] = new AmtSwapchainKHRImageInfo
                {
                    Drawable = null,
                };
                mImages[i].Inflight = new ManualResetEvent(true);
            }

            mView      = view;
            mColorView = color;
        }
Example #21
0
        public AmtSwapchainCollection(MTKView view)
        {
            mApplicationView = view;
            var color = new AmtNullImageView();

            mSwapchain = new AmtSwapchainKHR(view, color);

            Buffers = new MgSwapchainBuffer[]
            {
                new MgSwapchainBuffer
                {
                    View = color,
                },
            };
        }
Example #22
0
        void RegisterMagnesiumSingletons(IMTLDevice localDevice)
        {
            Debug.Assert(mContainer != null);

            // METAL SPECIFIC
            var deviceQuery = new AmtDeviceQuery {
                NoOfCommandBufferSlots = 5
            };

            mContainer.RegisterSingleton <Magnesium.Metal.IAmtDeviceQuery>(deviceQuery);
            mContainer.RegisterSingleton <IMTLDevice>(localDevice);

            mApplicationView = (MTKView)View;
            mContainer.RegisterSingleton <MTKView>(mApplicationView);
        }
		public override void ViewDidLoad ()
		{
			metalView = (MTKView)View;

			// Make sure the current device supports MetalPerformanceShaders.
			bool? deviceSupportsPerformanceShaders = null;
			deviceSupportsPerformanceShaders = metalView.Device?.SupportsFeatureSet (MTLFeatureSet.iOS_GPUFamily2_v1);
			if (!deviceSupportsPerformanceShaders.HasValue || !deviceSupportsPerformanceShaders.Value)
				return;

			MetalPerformanceShadersDisabledLabel.Hidden = true;
			SetupView ();
			SetupMetal ();
			LoadAssets ();
		}
Example #24
0
        public void Draw(MTKView view)
        {
            // Create a new command buffer for each renderpass to the current drawable
            IMTLCommandBuffer commandBuffer = commandQueue.CommandBuffer();

            // Compute commands
            IMTLComputeCommandEncoder computeCommandEncoder = commandBuffer.ComputeCommandEncoder;

            computeCommandEncoder.SetComputePipelineState(computePipelineState);

            computeCommandEncoder.SetBuffer(tessellationFactorsBuffer, 0, 2);

            computeCommandEncoder.DispatchThreadgroups(new MTLSize(1, 1, 1), new MTLSize(1, 1, 1));

            computeCommandEncoder.EndEncoding();

            // Render commands

            // Call the view's completion handler which is required by the view since it will signal its semaphore and set up the next buffer
            var drawable = view.CurrentDrawable;

            // Obtain a renderPassDescriptor generated from the view's drawable textures
            MTLRenderPassDescriptor renderPassDescriptor = view.CurrentRenderPassDescriptor;

            // Create a render command encoder so we can render into something
            IMTLRenderCommandEncoder renderCommandEncoder = commandBuffer.CreateRenderCommandEncoder(renderPassDescriptor);

            // Set context state
            renderCommandEncoder.SetTriangleFillMode(MTLTriangleFillMode.Lines);
            renderCommandEncoder.SetDepthStencilState(depthState);
            renderCommandEncoder.SetRenderPipelineState(renderPipelineState);
            renderCommandEncoder.SetVertexBuffer(controlPointsBuffer, 0, 0);
            renderCommandEncoder.SetTessellationFactorBuffer(tessellationFactorsBuffer, 0, 0);

            // Tell the render context we want to draw our primitives
            renderCommandEncoder.DrawPatches(3, 0, 1, null, 0, 1, 0);

            // We're done encoding commands
            renderCommandEncoder.EndEncoding();

            // Schedule a present once the framebuffer is complete using the current drawable
            commandBuffer.PresentDrawable(drawable);


            // Finalize rendering here & push the command buffer to the GPU
            commandBuffer.Commit();
        }
Example #25
0
        public void Draw(MTKView view)
        {
            inflightSemaphore.WaitOne();

            Update();

            IMTLCommandBuffer commandBuffer = commandQueue.CommandBuffer();

            commandBuffer.Label = "Main Command Buffer";

            MTLRenderPassDescriptor renderPassDescriptor = view.CurrentRenderPassDescriptor;

            // Create a render command encoder so we can render into something.
            IMTLRenderCommandEncoder renderEncoder = commandBuffer.CreateRenderCommandEncoder(renderPassDescriptor);

            renderEncoder.Label = "Final Pass Encoder";

            renderEncoder.SetViewport(new MTLViewport(0.0, 0.0, view.DrawableSize.Width, view.DrawableSize.Height, 0.0, 1.0));
            renderEncoder.SetDepthStencilState(depthState);
            renderEncoder.SetRenderPipelineState(pipelineState);

            // Set the our per frame uniforms.
            renderEncoder.SetVertexBuffer(frameUniformBuffers[constantDataBufferIndex], 0, (nuint)(int)BufferIndex.FrameUniformBuffer);
            renderEncoder.PushDebugGroup("Render Meshes");

            // Render each of our meshes.
            foreach (MetalKitEssentialsMesh mesh in meshes)
            {
                mesh.RenderWithEncoder(renderEncoder);
            }

            renderEncoder.PopDebugGroup();
            renderEncoder.EndEncoding();

            var drawable = view.CurrentDrawable;

            commandBuffer.AddCompletedHandler(_ => {
                inflightSemaphore.Release();
                drawable.Dispose();
            });

            constantDataBufferIndex = (constantDataBufferIndex + 1) % maxInflightBuffers;
            commandBuffer.PresentDrawable(drawable);
            commandBuffer.Commit();
        }
        public override void ViewDidLoad()
        {
            metalView = (MTKView)View;

            // Make sure the current device supports MetalPerformanceShaders.
            bool?deviceSupportsPerformanceShaders = null;

            deviceSupportsPerformanceShaders = metalView.Device?.SupportsFeatureSet(MTLFeatureSet.iOS_GPUFamily2_v1);
            if (!deviceSupportsPerformanceShaders.HasValue || !deviceSupportsPerformanceShaders.Value)
            {
                return;
            }

            MetalPerformanceShadersDisabledLabel.Hidden = true;
            SetupView();
            SetupMetal();
            LoadAssets();
        }
Example #27
0
        public void InitRenderer(MTKView view, IMTLDevice device)
        {
#if BGFX
            var platformData = new PlatformData();
            platformData.WindowHandle = view.Handle;
            platformData.Context      = device.Handle;

            Bgfx.Bgfx.SetPlatformData(platformData);

            var settings = new InitSettings();
            settings.Backend      = RendererBackend.Metal;
            settings.Width        = (int)view.Bounds.Width;
            settings.Height       = (int)view.Bounds.Height;
            settings.ResetFlags   = ResetFlags.Vsync;
            settings.PlatformData = platformData;
            //settings.limits.maxEncoders = 128;

            Bgfx.Bgfx.ManuallyRenderFrame();
            Bgfx.Bgfx.Init(settings);

            var vertexLayout = new VertexLayout();
            vertexLayout.Begin(RendererBackend.Metal);
            vertexLayout.Add(VertexAttributeUsage.Position, 3, VertexAttributeType.Float);
            vertexLayout.Add(VertexAttributeUsage.Color0, 4, VertexAttributeType.UInt8, true);
            vertexLayout.End();

            var vertexBuffer = new VertexBuffer(MemoryBlock.FromArray(Data.cubeVertices), vertexLayout);
            var indexBuffer  = new IndexBuffer(MemoryBlock.FromArray(Data.cubeTriList));

            var vertexShader   = LoadShader("vs_cubes.bin");
            var fragmentShader = LoadShader("fs_cubes.bin");
            var program        = new Program(vertexShader, fragmentShader);


            _vertexBuffer = vertexBuffer;
            _indexBuffer  = indexBuffer;
            _program      = program;

            Bgfx.Bgfx.Touch(0);
#endif
            view.Delegate = this;
        }
Example #28
0
        public void Draw(MTKView view)
        {
            if (vkContext == null)
            {
                vkContext = new Graphics.Platform.Vulkan.PlatformRenderContext();
                PlatformRenderer.Initialize(vkContext);
            }
            if (vkSwapChain == null)
            {
                shouldUpdateMetalLayerSize = true;
            }
            if (shouldUpdateMetalLayerSize)
            {
                var screen       = Window?.Screen ?? UIScreen.MainScreen;
                var drawableSize = Bounds.Size;
                drawableSize.Width     *= screen.NativeScale;
                drawableSize.Height    *= screen.NativeScale;
                metalLayer.DrawableSize = drawableSize;
                if (vkSwapChain == null)
                {
                    vkSwapChain = new Graphics.Platform.Vulkan.Swapchain(vkContext, this.Handle, (int)metalLayer.DrawableSize.Width, (int)metalLayer.DrawableSize.Height);
                }
                else
                {
                    vkSwapChain.Resize((int)metalLayer.DrawableSize.Width, (int)metalLayer.DrawableSize.Height);
                }
                shouldUpdateMetalLayerSize = false;
            }
            shouldUpdateMetalLayerSize = false;
            var curUpdateTime = stopwatch.Elapsed;

            if (prevUpdateTime == TimeSpan.Zero)
            {
                prevUpdateTime = curUpdateTime;
            }
            var delta = (float)(curUpdateTime - prevUpdateTime).TotalSeconds;

            UpdateFrame?.Invoke(delta);
            prevUpdateTime = curUpdateTime;
            RenderFrame?.Invoke();
        }
		public override void ViewDidLoad ()
		{
			metalView = (MTKView)View;

			// Set the view to use the default device.
			metalView.Device = MTLDevice.SystemDefault;

			// Make sure the current device supports MetalPerformanceShaders.
			if (metalView.Device == null)
				return;

			bool deviceSupportsMPS = MPSKernel.Supports (metalView.Device);

			if (!deviceSupportsMPS)
				return;

			MetalPerformanceShadersDisabledLabel.Hidden = true;
			SetupView ();
			SetupMetal ();
			LoadAssets ();
		}
		public void Draw (MTKView view)
		{
			inflightSemaphore.WaitOne ();

			Update ();

			IMTLCommandBuffer commandBuffer = commandQueue.CommandBuffer ();
			commandBuffer.Label = "Main Command Buffer";

			MTLRenderPassDescriptor renderPassDescriptor = view.CurrentRenderPassDescriptor;

			// Create a render command encoder so we can render into something.
			IMTLRenderCommandEncoder renderEncoder = commandBuffer.CreateRenderCommandEncoder (renderPassDescriptor);
			renderEncoder.Label = "Final Pass Encoder";

			renderEncoder.SetViewport (new MTLViewport (0.0, 0.0, view.DrawableSize.Width, view.DrawableSize.Height, 0.0, 1.0));
			renderEncoder.SetDepthStencilState (depthState);
			renderEncoder.SetRenderPipelineState (pipelineState);

			// Set the our per frame uniforms.
			renderEncoder.SetVertexBuffer (frameUniformBuffers[constantDataBufferIndex], 0, (nuint)(int)BufferIndex.FrameUniformBuffer);
			renderEncoder.PushDebugGroup ("Render Meshes");

			// Render each of our meshes.
			foreach (MetalKitEssentialsMesh mesh in meshes)
				mesh.RenderWithEncoder (renderEncoder);

			renderEncoder.PopDebugGroup ();
			renderEncoder.EndEncoding ();

			var drawable = view.CurrentDrawable;
			commandBuffer.AddCompletedHandler (_ => {
				inflightSemaphore.Release ();
				drawable.Dispose ();
			});

			constantDataBufferIndex = (constantDataBufferIndex + 1) % maxInflightBuffers;
			commandBuffer.PresentDrawable (drawable);
			commandBuffer.Commit ();
		}
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            // Set the view to use the default device
            device = MTLDevice.SystemDefault;

            if (device == null)
            {
                Console.WriteLine("Metal is not supported on this device");
                View = new NSView(View.Frame);
            }

            // Create a new command queue
            commandQueue = device.CreateCommandQueue();

            // Load all the shader files with a metal file extension in the project
            defaultLibrary = device.CreateDefaultLibrary();

            // Setup view
            view          = (MTKView)View;
            view.Delegate = this;
            view.Device   = device;

            view.SampleCount              = 1;
            view.DepthStencilPixelFormat  = MTLPixelFormat.Depth32Float_Stencil8;
            view.ColorPixelFormat         = MTLPixelFormat.BGRA8Unorm;
            view.PreferredFramesPerSecond = 60;
            view.ClearColor = new MTLClearColor(0.5f, 0.5f, 0.5f, 1.0f);

            // Load the vertex program into the library
            IMTLFunction vertexProgram = defaultLibrary.CreateFunction("quad_vertex");

            // Load the fragment program into the library
            IMTLFunction fragmentProgram = defaultLibrary.CreateFunction("quad_fragment");

            // Create a vertex descriptor from the MTKMesh
            MTLVertexDescriptor vertexDescriptor = new MTLVertexDescriptor();

            vertexDescriptor.Attributes[0].Format      = MTLVertexFormat.Float4;
            vertexDescriptor.Attributes[0].BufferIndex = 0;
            vertexDescriptor.Attributes[0].Offset      = 0;
            vertexDescriptor.Attributes[1].Format      = MTLVertexFormat.Float2;
            vertexDescriptor.Attributes[1].BufferIndex = 0;
            vertexDescriptor.Attributes[1].Offset      = 4 * sizeof(float);

            vertexDescriptor.Layouts[0].Stride = 6 * sizeof(float);

            vertexDescriptor.Layouts[0].StepRate     = 1;
            vertexDescriptor.Layouts[0].StepFunction = MTLVertexStepFunction.PerVertex;

            this.vertexBuffer = device.CreateBuffer(vertexData, MTLResourceOptions.CpuCacheModeDefault);// (MTLResourceOptions)0);

            this.mipmapping     = 0;
            this.constantBuffer = device.CreateBuffer(sizeof(float), MTLResourceOptions.CpuCacheModeDefault);
            SetConstantBuffer(this.mipmapping, constantBuffer);

            // Create a reusable pipeline state
            var pipelineStateDescriptor = new MTLRenderPipelineDescriptor
            {
                SampleCount                  = view.SampleCount,
                VertexFunction               = vertexProgram,
                FragmentFunction             = fragmentProgram,
                VertexDescriptor             = vertexDescriptor,
                DepthAttachmentPixelFormat   = view.DepthStencilPixelFormat,
                StencilAttachmentPixelFormat = view.DepthStencilPixelFormat
            };

            pipelineStateDescriptor.ColorAttachments[0].PixelFormat = view.ColorPixelFormat;

            NSError error;

            pipelineState = device.CreateRenderPipelineState(pipelineStateDescriptor, out error);
            if (pipelineState == null)
            {
                Console.WriteLine("Failed to created pipeline state, error {0}", error);
            }

            var depthStateDesc = new MTLDepthStencilDescriptor
            {
                DepthCompareFunction = MTLCompareFunction.Less,
                DepthWriteEnabled    = true
            };

            depthState = device.CreateDepthStencilState(depthStateDesc);

            // Texture KTX
            NSUrl            url = NSBundle.MainBundle.GetUrlForResource("crate", "ktx");
            MTKTextureLoader mTKTextureLoader = new MTKTextureLoader(device);

            this.texture = mTKTextureLoader.FromUrl(url, new MTKTextureLoaderOptions(), out error);

            Console.WriteLine("Failed to created pipeline state, error {0}", error);

            MTLSamplerDescriptor samplerDescriptor = new MTLSamplerDescriptor()
            {
                MinFilter    = MTLSamplerMinMagFilter.Linear,
                MagFilter    = MTLSamplerMinMagFilter.Linear,
                MipFilter    = MTLSamplerMipFilter.Linear,
                SAddressMode = MTLSamplerAddressMode.ClampToEdge,
                TAddressMode = MTLSamplerAddressMode.ClampToEdge,
            };

            this.sampler = device.CreateSamplerState(samplerDescriptor);

            this.clock = new System.Diagnostics.Stopwatch();
            this.clock.Start();
            this.time = 0;
        }
		void SetupView ()
		{
			view = (MTKView)View;
			view.Delegate = this;
			view.Device = device;

			// Setup the render target, choose values based on your app.
			view.SampleCount = 4;
			view.DepthStencilPixelFormat = (MTLPixelFormat) 260;
		}
 public void DrawableSizeWillChange(MTKView view, CoreGraphics.CGSize size)
 {
 }
		public void Draw (MTKView view)
		{
			Render ();
		}
		public void DrawableSizeWillChange (MTKView view, CGSize size)
		{
			// Called whenever view changes orientation or layout is changed
		}
 public void Draw(MTKView view)
 {
     Render();
 }
 public void WillLayout(MTKView view, CoreGraphics.CGSize size)
 {
     // Called whenever view changes orientation or layout is changed
 }
		public void DrawableSizeWillChange (MTKView view, CGSize size)
		{
			float aspect = (float)Math.Abs (View.Bounds.Width / View.Bounds.Height);
			projectionMatrix = MathHelper.MatrixFromPerspectiveFovAspectLH (65f * (float)Math.PI / 180f, aspect, .1f, 100f);
			viewMatrix = Matrix4.Identity;
		}
		public void WillLayout (MTKView view, CoreGraphics.CGSize size)
		{
			// Called whenever view changes orientation or layout is changed
		}