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();
        }
예제 #2
0
        public void Render(GameView view)
        {
            inflightSemaphore.WaitOne();

            PrepareToDraw();

            IMTLCommandBuffer       commandBuffer        = commandQueue.CommandBuffer();
            ICAMetalDrawable        drawable             = view.GetNextDrawable();
            MTLRenderPassDescriptor renderPassDescriptor = view.GetRenderPassDescriptor(drawable);

            if (renderPassDescriptor == null)
            {
                Console.WriteLine("ERROR: Failed to get render pass descriptor from view!");
            }

            IMTLRenderCommandEncoder renderEncoder = commandBuffer.CreateRenderCommandEncoder(renderPassDescriptor);

            renderEncoder.SetDepthStencilState(depthState);

            RenderBox(renderEncoder, view, 0, "Box1");
            RenderBox(renderEncoder, view, (nuint)Marshal.SizeOf <Uniforms> (), "Box2");
            renderEncoder.EndEncoding();

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

            commandBuffer.PresentDrawable(drawable);
            commandBuffer.Commit();

            constantDataBufferIndex = (constantDataBufferIndex + 1) % max_inflight_buffers;
        }
예제 #3
0
        /// <summary>
        /// Encode a MPSCnnKernel into a command Buffer. The operation shall proceed out-of-place.
        /// We calculate the appropriate offset as per how TensorFlow calculates its padding using input image size and stride here.
        /// This [Link](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/ops/nn.py) has an explanation in header comments how tensorFlow pads its convolution input images.
        /// </summary>
        /// <param name="commandBuffer">A valid MTLCommandBuffer to receive the encoded filter</param>
        /// <param name="sourceImage">A valid MPSImage object containing the source image.</param>
        /// <param name="destinationImage">A valid MPSImage to be overwritten by result image. destinationImage may not alias sourceImage</param>
        public override void EncodeToCommandBuffer(IMTLCommandBuffer commandBuffer, MPSImage sourceImage, MPSImage destinationImage)
        {
            // select offset according to padding being used or not
            if (padding)
            {
                var pad_along_height = ((destinationImage.Height - 1) * StrideInPixelsY + KernelHeight - sourceImage.Height);
                var pad_along_width  = ((destinationImage.Width - 1) * StrideInPixelsX + KernelWidth - sourceImage.Width);
                var pad_top          = pad_along_height / 2;
                var pad_left         = pad_along_width / 2;

                Offset = new MPSOffset {
                    X = (nint)(KernelWidth / 2 - pad_left),
                    Y = (nint)(KernelHeight / 2 - pad_top),
                    Z = 0
                };
            }
            else
            {
                Offset = new MPSOffset {
                    X = (nint)(KernelWidth / 2),
                    Y = (nint)(KernelHeight / 2),
                    Z = 0
                };
            }
            base.EncodeToCommandBuffer(commandBuffer, sourceImage, destinationImage);
        }
예제 #4
0
 public unsafe void ImportData(IMTLCommandBuffer cmdBuf, IMTLBuffer buffer, MPSDataType sourceDataType, nuint offset, nint[] rowStrides)
 {
     fixed(nint *p = rowStrides)
     {
         ImportData(cmdBuf, buffer, sourceDataType, offset, (IntPtr)p);
     }
 }
예제 #5
0
        public void Render(ImageView view)
        {
            inflightSemaphore.WaitOne();
            IMTLCommandBuffer commandBuffer = commandQueue.CommandBuffer();

            // compute image processing on the (same) drawable texture
            Compute(commandBuffer);
            ICAMetalDrawable drawable = view.GetNextDrawable();

            // create a render command encoder so we can render into something
            MTLRenderPassDescriptor renderPassDescriptor = view.GetRenderPassDescriptor(drawable);

            if (renderPassDescriptor == null)
            {
                inflightSemaphore.Release();
                return;
            }

            // Get a render encoder
            IMTLRenderCommandEncoder renderEncoder = commandBuffer.CreateRenderCommandEncoder(renderPassDescriptor);

            // render textured quad
            Encode(renderEncoder);

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

            commandBuffer.PresentDrawable(drawable);
            commandBuffer.Commit();
        }
예제 #6
0
 public void TearDown()
 {
     commandQ?.Dispose();
     commandQ = null;
     commandBuffer?.Dispose();
     commandBuffer = null;
     encoder?.Dispose();
     encoder = null;
 }
예제 #7
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();
        }
        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();
        }
        void Render()
        {
            inflightSemaphore.WaitOne();

            Update();

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

            commandBuffer.Label = "MyCommand";

            // 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;

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

            // 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.Label = "MyRenderEncoder";
                renderEncoder.SetDepthStencilState(depthState);

                // Set context state
                renderEncoder.PushDebugGroup("DrawCube");
                renderEncoder.SetRenderPipelineState(pipelineState);
                renderEncoder.SetVertexBuffer(boxMesh.VertexBuffers[0].Buffer, boxMesh.VertexBuffers[0].Offset, 0);
                renderEncoder.SetVertexBuffer(dynamicConstantBuffer, (nuint)Marshal.SizeOf <Uniforms>(), 1);

                MTKSubmesh submesh = boxMesh.Submeshes[0];
                // Tell the render context we want to draw our primitives
                renderEncoder.DrawIndexedPrimitives(submesh.PrimitiveType, submesh.IndexCount, submesh.IndexType, submesh.IndexBuffer.Buffer, submesh.IndexBuffer.Offset);
                renderEncoder.PopDebugGroup();

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

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

            // The render assumes it can now increment the buffer index and that the previous index won't be touched until we cycle back around to the same index
            constantDataBufferIndex = (constantDataBufferIndex + 1) % MaxInflightBuffers;

            // Finalize rendering here & push the command buffer to the GPU
            commandBuffer.Commit();
        }
예제 #10
0
        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();
        }
예제 #11
0
		public void Compute (IMTLCommandBuffer commandBuffer)
		{
			IMTLComputeCommandEncoder computeEncoder = commandBuffer.ComputeCommandEncoder;

			if (computeEncoder == null)
				return;

			computeEncoder.SetComputePipelineState (kernel);
			computeEncoder.SetTexture (mpInTexture.MetalTexture, 0);
			computeEncoder.SetTexture (outTexture, 1);
			computeEncoder.DispatchThreadgroups (localCount, workgroupSize);
			computeEncoder.EndEncoding ();
		}
예제 #12
0
        // Using 'NSArray<MPSImage>' instead of `MPSImage[]` because image array 'Handle' matters.
        public static void Synchronize(NSArray <MPSImage> imageBatch, IMTLCommandBuffer commandBuffer)
        {
            if (imageBatch == null)
            {
                throw new ArgumentNullException(nameof(imageBatch));
            }
            if (commandBuffer == null)
            {
                throw new ArgumentNullException(nameof(commandBuffer));
            }

            MPSImageBatchSynchronize(imageBatch.Handle, commandBuffer.Handle);
        }
예제 #13
0
        void Render()
        {
            inflightSemaphore.WaitOne();

            Update();

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

            commandBuffer.Label = "MyCommand";

            // Obtain a drawable texture for this render pass and set up the renderpass descriptor for the command encoder to render into
            ICAMetalDrawable drawable = GetCurrentDrawable();

            SetupRenderPassDescriptorForTexture(drawable.Texture);

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

            renderEncoder.Label = "MyRenderEncoder";
            renderEncoder.SetDepthStencilState(depthState);

            // Set context state
            renderEncoder.PushDebugGroup("DrawCube");
            renderEncoder.SetRenderPipelineState(pipelineState);
            renderEncoder.SetVertexBuffer(vertexBuffer, 0, 0);
            renderEncoder.SetVertexBuffer(dynamicConstantBuffer, (nuint)(Marshal.SizeOf(typeof(Uniforms)) * constantDataBufferIndex), 1);

            // Tell the render context we want to draw our primitives
            renderEncoder.DrawPrimitives(MTLPrimitiveType.Triangle, 0, 36, 1);
            renderEncoder.PopDebugGroup();

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

            // Call the view's completion handler which is required by the view since it will signal its semaphore and set up the next buffer
            commandBuffer.AddCompletedHandler(buffer =>
            {
                drawable.Dispose();
                inflightSemaphore.Release();
            });

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

            // Finalize rendering here & push the command buffer to the GPU
            commandBuffer.Commit();

            // The renderview assumes it can now increment the buffer index and that the previous index won't be touched until we cycle back around to the same index
            constantDataBufferIndex = (byte)((constantDataBufferIndex + 1) % max_inflight_buffers);
        }
예제 #14
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();
        }
        public override MPSCnnConvolutionWeightsAndBiasesState Update(IMTLCommandBuffer commandBuffer, MPSCnnConvolutionGradientState gradientState, MPSCnnConvolutionWeightsAndBiasesState sourceState)
        {
            updateCount++;

            updater.Encode(commandBuffer, gradientState, sourceState, momentumVectors, velocityVectors, convWtsAndBias);

            if (updateCount != updater.TimeStep)
            {
                throw new Exception($"Update time step is out of synch");
            }

            //Console.WriteLine ($"UpdateWeights of Conv2dDataSource {this.Label}");

            return(convWtsAndBias);
        }
예제 #16
0
        public void Compute(IMTLCommandBuffer commandBuffer)
        {
            IMTLComputeCommandEncoder computeEncoder = commandBuffer.ComputeCommandEncoder;

            if (computeEncoder == null)
            {
                return;
            }

            computeEncoder.SetComputePipelineState(kernel);
            computeEncoder.SetTexture(mpInTexture.MetalTexture, 0);
            computeEncoder.SetTexture(outTexture, 1);
            computeEncoder.DispatchThreadgroups(localCount, workgroupSize);
            computeEncoder.EndEncoding();
        }
예제 #17
0
		static void SignalFenceWhenCompleted(AmtSemaphore fence, IMTLCommandBuffer cb)
		{
			// SIGNAL ORDER.FENCE
			if (fence != null)
			{
				fence.Reset();

				cb.AddCompletedHandler(
					(b) =>
					{
						fence.Signal();
					}
				);
			}
		}
예제 #18
0
		static void TriggerSemaphores(AmtSemaphore[] signals, IMTLCommandBuffer cb)
		{
			// SIGNAL SEMAPHORE
			foreach (var signal in signals)
			{
				signal.Reset();
				// APPLY HANDLER TO COMMAND BUFFER

				cb.AddCompletedHandler(
					(b) =>
					{
						signal.Signal();
					}
				);
			}
		}
예제 #19
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();
        }
예제 #20
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();
        }
예제 #21
0
		static AmtCommandRecording GenerateRecording(IMTLCommandBuffer cb, AmtCommandBuffer buffer)
		{
			return new AmtCommandRecording
			{
				CommandBuffer = cb,
				Compute = new AmtComputeRecording
				{
					Grid = buffer.Record.ComputeGrid,
				},
				Graphics = new AmtGraphicsRecording
				{
					Grid = buffer.Record.GraphicsGrid,
				},
				Blit = new AmtBlitRecording
				{
					Grid = buffer.Record.BlitGrid,
				},
			};
		}
예제 #22
0
        void PerformRequests(long key)
        {
            AmtQueueSubmission request;

            if (mSubmissions.TryGetValue(key, out request))
            {
                int requirements = request.Waits.Length;
                int checks       = 0;
                foreach (var signal in request.Waits)
                {
                    if (signal.IsSignalled)
                    {
                        ++checks;
                    }
                }
                // render
                if (checks >= requirements)
                {
                    mRenderer.Render(request);

                    if (request.Swapchains != null)
                    {
                        foreach (var info in request.Swapchains)
                        {
                            IMTLCommandBuffer presentCmd = mPresentQueue.CommandBuffer();
                            var imageInfo = info.Swapchain.Images[info.ImageIndex];

                            presentCmd.AddCompletedHandler((buffer) =>
                            {
                                imageInfo.Drawable.Dispose();
                                imageInfo.Inflight.Set();
                            });
                            presentCmd.PresentDrawable(imageInfo.Drawable);
                            presentCmd.Commit();
                        }
                    }

                    AmtQueueSubmission removedItem;
                    mSubmissions.TryRemove(key, out removedItem);
                }
            }
        }
예제 #23
0
        void Render()
        {
            // Create a new command buffer for each renderpass to the current drawable.
            IMTLCommandBuffer commandBuffer = commandQueue.CommandBuffer();

            // Initialize MetalPerformanceShaders gaussianBlur with Sigma = 10.0f.
            var gaussianblur = new MPSImageGaussianBlur(metalView.Device, 10f);

            var drawable = ((CAMetalLayer)metalView.Layer).NextDrawable();

            // Run MetalPerformanceShader gaussianblur.
            gaussianblur.EncodeToCommandBuffer(commandBuffer, sourceTexture, drawable.Texture);

            // Schedule a present using the current drawable.
            commandBuffer.PresentDrawable(drawable);
            // Finalize command buffer.
            commandBuffer.Commit();
            commandBuffer.WaitUntilCompleted();

            // To reuse a CAMetalDrawable object’s texture, you must deallocate the drawable after presenting it.
            drawable.Dispose();
        }
예제 #24
0
        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;
        }
예제 #25
0
        public void Draw(MTKView view)
        {
            inflightSemaphore.WaitOne();

            // Perofm any app logic, including updating any Metal buffers.
            Update();

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

            commandBuffer.Label = "Main Command Buffer";

            // 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 renderEncoder = commandBuffer.CreateRenderCommandEncoder(renderPassDescriptor);

            renderEncoder.Label = "Final Pass Encoder";

            // Set context state.
            renderEncoder.SetViewport(new MTLViewport(0d, 0d, view.DrawableSize.Width, view.DrawableSize.Height, 0d, 1d));
            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();

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

            /*
             *      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;

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

            /*
             *      The renderview assumes it can now increment the buffer index and that
             *      the previous index won't be touched until we cycle back around to the same index.
             */
            constantDataBufferIndex = (constantDataBufferIndex + 1) % maxInflightBuffers;

            // 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();
        }
예제 #26
0
 internal CommandBuffer(GraphicsDevice graphicsDevice, IMTLCommandBuffer commandBuffer)
     : base(graphicsDevice)
 {
     _commandBuffer = commandBuffer;
 }
예제 #27
0
 public static void SetHeapCacheDuration(IMTLCommandBuffer commandBuffer, double seconds) => MPSSetHeapCacheDuration(commandBuffer == null ? IntPtr.Zero : commandBuffer.Handle, seconds);
예제 #28
0
 public static void HintTemporaryMemoryHighWaterMark(IMTLCommandBuffer commandBuffer, nuint sizeInBytes) => MPSHintTemporaryMemoryHighWaterMark(commandBuffer == null ? IntPtr.Zero : commandBuffer.Handle, sizeInBytes);
예제 #29
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);
            this.cubeParameters.WorldViewProjection = worldViewProj;
            this.SetConstantBuffer(this.cubeParameters, this.cubeConstantBuffer);

            // 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;

            renderPassDescriptor.ColorAttachments[0].Texture    = this.colorFrameBufferTexture;
            renderPassDescriptor.ColorAttachments[0].ClearColor = new MTLClearColor(0.5f, 0.75f, 1, 1);

            // If we have a valid drawable, begin the commands to render into it
            if (renderPassDescriptor != null)
            {
                //--------------------------------
                // Draw Triangle
                //--------------------------------

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

                triangleRenderEncoder.SetRenderPipelineState(trianglePipelineState);
                triangleRenderEncoder.SetVertexBuffer(triangleVertexBuffer, 0, 0);

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

                triangleRenderEncoder.EndEncoding();

                //--------------------------------
                // Draw Cube
                //--------------------------------
                renderPassDescriptor.ColorAttachments[0].Texture    = drawable.Texture;
                renderPassDescriptor.ColorAttachments[0].ClearColor = mtkView.ClearColor;
                IMTLRenderCommandEncoder cubeRenderEncoder = commandBuffer.CreateRenderCommandEncoder(renderPassDescriptor);
                cubeRenderEncoder.SetDepthStencilState(depthStencilState);

                // Set context state
                cubeRenderEncoder.SetRenderPipelineState(cubePipelineState);
                cubeRenderEncoder.SetVertexBuffer(cubeVertexBuffer, 0, 0);
                cubeRenderEncoder.SetVertexBuffer(cubeConstantBuffer, (nuint)Marshal.SizeOf(this.cubeParameters), 1);
                cubeRenderEncoder.SetFragmentTexture(this.colorFrameBufferTexture, 0);
                cubeRenderEncoder.SetFragmentSamplerState(this.sampler, 0);

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

                // We're done encoding commands
                cubeRenderEncoder.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();
        }
예제 #30
0
        public override void BeginRender()
        {
            _cmdBuffer = _cmdQueue.CommandBuffer();

            _device.SetOffscreenCommandBuffer(_cmdBuffer.Handle);
        }
예제 #31
0
 internal CommandBuffer(GraphicsDevice graphicsDevice, IMTLCommandBuffer deviceCommandBuffer)
     : base(graphicsDevice)
 {
     _deviceCommandBuffer = deviceCommandBuffer;
 }
		/// <summary>
		/// Encode a MPSCnnKernel into a command Buffer. The operation shall proceed out-of-place.
		/// We calculate the appropriate offset as per how TensorFlow calculates its padding using input image size and stride here.
		/// This [Link](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/ops/nn.py) has an explanation in header comments how tensorFlow pads its convolution input images.
		/// </summary>
		/// <param name="commandBuffer">A valid MTLCommandBuffer to receive the encoded filter</param>
		/// <param name="sourceImage">A valid MPSImage object containing the source image.</param>
		/// <param name="destinationImage">A valid MPSImage to be overwritten by result image. destinationImage may not alias sourceImage</param>
		public override void EncodeToCommandBuffer (IMTLCommandBuffer commandBuffer, MPSImage sourceImage, MPSImage destinationImage)
		{
			// select offset according to padding being used or not
			if (padding) {
				var pad_along_height = ((destinationImage.Height - 1) * StrideInPixelsY + KernelHeight - sourceImage.Height);
				var pad_along_width = ((destinationImage.Width - 1) * StrideInPixelsX + KernelWidth - sourceImage.Width);
				var pad_top = pad_along_height / 2;
				var pad_left = pad_along_width / 2;

				Offset = new MPSOffset {
					X = (nint)(KernelWidth / 2 - pad_left),
					Y = (nint)(KernelHeight / 2 - pad_top),
					Z = 0
				};
			} else {
				Offset = new MPSOffset {
					X = (nint)(KernelWidth / 2),
					Y = (nint)(KernelHeight / 2),
					Z = 0
				};
			}
			base.EncodeToCommandBuffer (commandBuffer, sourceImage, destinationImage);
		}