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(); }
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; }
/// <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); }
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); } }
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(); }
public void TearDown() { commandQ?.Dispose(); commandQ = null; commandBuffer?.Dispose(); commandBuffer = null; encoder?.Dispose(); encoder = null; }
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(); }
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 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 (); }
// 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); }
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); }
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); }
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(); }
static void SignalFenceWhenCompleted(AmtSemaphore fence, IMTLCommandBuffer cb) { // SIGNAL ORDER.FENCE if (fence != null) { fence.Reset(); cb.AddCompletedHandler( (b) => { fence.Signal(); } ); } }
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(); } ); } }
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(); }
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(); }
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, }, }; }
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); } } }
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(); }
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; }
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(); }
internal CommandBuffer(GraphicsDevice graphicsDevice, IMTLCommandBuffer commandBuffer) : base(graphicsDevice) { _commandBuffer = commandBuffer; }
public static void SetHeapCacheDuration(IMTLCommandBuffer commandBuffer, double seconds) => MPSSetHeapCacheDuration(commandBuffer == null ? IntPtr.Zero : commandBuffer.Handle, seconds);
public static void HintTemporaryMemoryHighWaterMark(IMTLCommandBuffer commandBuffer, nuint sizeInBytes) => MPSHintTemporaryMemoryHighWaterMark(commandBuffer == null ? IntPtr.Zero : commandBuffer.Handle, sizeInBytes);
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(); }
public override void BeginRender() { _cmdBuffer = _cmdQueue.CommandBuffer(); _device.SetOffscreenCommandBuffer(_cmdBuffer.Handle); }
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); }