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
        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();
        }
예제 #4
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();
        }
        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();
        }
예제 #8
0
        void Draw(IMTLTexture texture)
        {
            GCHandle pinnedTransform = GCHandle.Alloc(vertexFactory.Vertices.ToArray(), GCHandleType.Pinned);
            IntPtr   ptr             = pinnedTransform.AddrOfPinnedObject();

            pinnedTransform.Free();

            var rstate        = renderPipelineState;
            var commandBuffer = commandQueue.CommandBuffer();
            var currentRenderPassDescriptor = mtkView.CurrentRenderPassDescriptor;
            var encoder = commandBuffer.CreateRenderCommandEncoder(currentRenderPassDescriptor);

            encoder.PushDebugGroup("RenderFrame");
            encoder.SetRenderPipelineState(rstate);
            encoder.SetVertexBytes(ptr, (nuint)vertexFactory.Size(), index: 0);
            encoder.SetFragmentTexture(texture, index: 0);
            encoder.DrawPrimitives(MTLPrimitiveType.TriangleStrip, vertexStart: 0, vertexCount: 4, instanceCount: 1);
            encoder.PopDebugGroup();
            encoder.EndEncoding();
            commandBuffer.Commit();
        }
예제 #9
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);
        }
예제 #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.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();
        }
예제 #11
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();
        }
예제 #12
0
		public void Render(AmtQueueSubmission request)
		{
			foreach (var buffer in request.CommandBuffers)
			{
				if (buffer.IsQueueReady)
				{
					// GENERATE METAL BUFFER
					var cb = mCommandQueue.CommandBuffer();
					cb.Label = "MyCommand";

					AmtCommandRecording recording = GenerateRecording(cb, buffer);

					foreach (var context in buffer.Record.Contexts)
					{
						if (context.Category == AmtEncoderCategory.Compute)
						{
							recording.Compute.Encoder = cb.ComputeCommandEncoder;
						}
						else if (context.Category == AmtEncoderCategory.Blit)
						{
							recording.Blit.Encoder = cb.BlitCommandEncoder;
						}

						for (var i = context.First; i <= context.Last; ++i)
						{
							buffer.Record.Instructions[i].Perform(recording);
						}

						if (context.Category == AmtEncoderCategory.Compute)
						{
							recording.Compute.Encoder.EndEncoding();
							recording.Compute.Encoder = null;
						}
						else if (context.Category == AmtEncoderCategory.Blit)
						{
							recording.Blit.Encoder.EndEncoding();
							recording.Blit.Encoder = null;
						}
					}

					TriggerSemaphores(request.Signals, cb);
					SignalFenceWhenCompleted(request.OrderFence, cb);

					cb.Commit();
				}
			}
		}
예제 #13
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();
        }
예제 #14
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);
                }
            }
        }
예제 #15
0
        /// <summary>
        /// This function encodes all the layers of the network into given commandBuffer, it calls subroutines for each piece of the network
        /// Returns: Guess of the network as to what the digit is as UInt
        /// </summary>
        /// <param name="inputImage">Image coming in on which the network will run</param>
        /// <param name="imageNum">If the test set is being used we will get a value between 0 and 9999 for which of the 10,000 images is being evaluated</param>
        /// <param name="correctLabel">The correct label for the inputImage while testing</param>
        public virtual uint Forward(MPSImage inputImage = null, int imageNum = 9999, int correctLabel = 10)
        {
            uint label = 99;

            // Get command buffer to use in MetalPerformanceShaders.
            using (var commandBuffer = commandQueue.CommandBuffer()) {
                // output will be stored in this image
                var finalLayer = new MPSImage(commandBuffer.Device, DID);

                // encode layers to metal commandBuffer
                if (inputImage == null)
                {
                    layer.EncodeToCommandBuffer(commandBuffer, SrcImage, dstImage);
                }
                else
                {
                    layer.EncodeToCommandBuffer(commandBuffer, inputImage, dstImage);
                }

                softmax.EncodeToCommandBuffer(commandBuffer, dstImage, finalLayer);

                // add a completion handler to get the correct label the moment GPU is done and compare it to the correct output or return it
                commandBuffer.AddCompletedHandler(buffer => {
                    label = GetLabel(finalLayer);

                    if (correctLabel == label)
                    {
                        Atomics.Increment();
                    }
                });

                // commit commandbuffer to run on GPU and wait for completion
                commandBuffer.Commit();
                if (imageNum == 9999 || inputImage == null)
                {
                    commandBuffer.WaitUntilCompleted();
                }
            }

            return(label);
        }
예제 #16
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();
        }
예제 #17
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;
        }
예제 #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.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();
        }
예제 #19
0
        public override void BeginRender()
        {
            _cmdBuffer = _cmdQueue.CommandBuffer();

            _device.SetOffscreenCommandBuffer(_cmdBuffer.Handle);
        }
예제 #20
0
 private CommandBuffer PlatformGetCommandBuffer()
 {
     return(new CommandBuffer(GraphicsDevice, _deviceCommandQueue.CommandBuffer()));
 }
예제 #21
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();
        }