void InitializeThreadsPerGroupSize(MgComputePipelineCreateInfo createInfo) { var groupSize = createInfo.ThreadsPerWorkgroup; if (IntPtr.Size == 4) { if (groupSize.X < 0 || groupSize.X > nint.MaxValue) { throw new ArgumentOutOfRangeException(nameof(createInfo.ThreadsPerWorkgroup.X) + " must be between 0 and " + nint.MaxValue); } if (groupSize.Y < 0 || groupSize.Y > nint.MaxValue) { throw new ArgumentOutOfRangeException(nameof(createInfo.ThreadsPerWorkgroup.Y) + " must be between 0 and " + nint.MaxValue); } if (groupSize.Z < 0 || groupSize.Z > nint.MaxValue) { throw new ArgumentOutOfRangeException(nameof(createInfo.ThreadsPerWorkgroup.Z) + " must be between 0 and " + nint.MaxValue); } } ThreadsPerGroupSize = new MTLSize( (nint)createInfo.ThreadsPerWorkgroup.X, (nint)createInfo.ThreadsPerWorkgroup.Y, (nint)createInfo.ThreadsPerWorkgroup.Z); }
public MTLPipeline(ref ComputePipelineDescription description, MTLGraphicsDevice gd) : base(ref description) { IsComputePipeline = true; ResourceLayouts = new MTLResourceLayout[description.ResourceLayouts.Length]; for (int i = 0; i < ResourceLayouts.Length; i++) { ResourceLayouts[i] = Util.AssertSubtype <ResourceLayout, MTLResourceLayout>(description.ResourceLayouts[i]); } ThreadsPerThreadgroup = new MTLSize( description.ThreadGroupSizeX, description.ThreadGroupSizeY, description.ThreadGroupSizeZ); MTLComputePipelineDescriptor mtlDesc = MTLUtil.AllocInit <MTLComputePipelineDescriptor>( nameof(MTLComputePipelineDescriptor)); MTLShader mtlShader = Util.AssertSubtype <Shader, MTLShader>(description.ComputeShader); mtlDesc.computeFunction = mtlShader.Function; MTLPipelineBufferDescriptorArray buffers = mtlDesc.buffers; uint bufferIndex = 0; foreach (MTLResourceLayout layout in ResourceLayouts) { foreach (ResourceKind kind in layout.ResourceKinds) { if (kind == ResourceKind.UniformBuffer || kind == ResourceKind.StructuredBufferReadOnly) { MTLPipelineBufferDescriptor bufferDesc = buffers[bufferIndex]; bufferDesc.mutability = MTLMutability.Immutable; bufferIndex += 1; } else if (kind == ResourceKind.StructuredBufferReadWrite) { MTLPipelineBufferDescriptor bufferDesc = buffers[bufferIndex]; bufferDesc.mutability = MTLMutability.Mutable; bufferIndex += 1; } } } ComputePipelineState = gd.Device.newComputePipelineStateWithDescriptor(mtlDesc); ObjectiveCRuntime.release(mtlDesc.NativePtr); }
bool PrepareCompute() { NSError error; // Create a compute kernel function IMTLFunction function = shaderLibrary.CreateFunction("grayscale"); if (function == null) { Console.WriteLine("ERROR: Failed creating a new function!"); return(false); } // Create a compute kernel kernel = device.CreateComputePipelineState(function, out error); if (kernel == null) { Console.WriteLine("ERROR: Failed creating a compute kernel: %@", error.Description); return(false); } MTLTextureDescriptor texDesc = MTLTextureDescriptor.CreateTexture2DDescriptor(MTLPixelFormat.RGBA8Unorm, (nuint)size.Width, (nuint)size.Height, false); if (texDesc == null) { Console.WriteLine("ERROR: Failed creating a texture 2d descriptor with RGBA unnormalized pixel format!"); return(false); } outTexture = device.CreateTexture(texDesc); if (outTexture == null) { Console.WriteLine("ERROR: Failed creating an output 2d texture!"); return(false); } // Set the compute kernel's workgroup size and count workgroupSize = new MTLSize(1, 1, 1); localCount = new MTLSize((nint)size.Width, (nint)size.Height, 1); return(true); }
public MTLPipeline(ref ComputePipelineDescription description, MTLGraphicsDevice gd) : base(ref description) { IsComputePipeline = true; ResourceLayouts = new MTLResourceLayout[description.ResourceLayouts.Length]; for (int i = 0; i < ResourceLayouts.Length; i++) { ResourceLayouts[i] = Util.AssertSubtype <ResourceLayout, MTLResourceLayout>(description.ResourceLayouts[i]); } ThreadsPerThreadgroup = new MTLSize( description.ThreadGroupSizeX, description.ThreadGroupSizeY, description.ThreadGroupSizeZ); MTLComputePipelineDescriptor mtlDesc = MTLUtil.AllocInit <MTLComputePipelineDescriptor>( nameof(MTLComputePipelineDescriptor)); MTLShader mtlShader = Util.AssertSubtype <Shader, MTLShader>(description.ComputeShader); MTLFunction specializedFunction; if (mtlShader.HasFunctionConstants) { // Need to create specialized MTLFunction. MTLFunctionConstantValues constantValues = CreateConstantValues(description.Specializations); specializedFunction = mtlShader.Library.newFunctionWithNameConstantValues(mtlShader.EntryPoint, constantValues); AddSpecializedFunction(specializedFunction); ObjectiveCRuntime.release(constantValues.NativePtr); Debug.Assert(specializedFunction.NativePtr != IntPtr.Zero, "Failed to create specialized MTLFunction"); } else { specializedFunction = mtlShader.Function; } mtlDesc.computeFunction = specializedFunction; MTLPipelineBufferDescriptorArray buffers = mtlDesc.buffers; uint bufferIndex = 0; foreach (MTLResourceLayout layout in ResourceLayouts) { foreach (ResourceKind kind in layout.ResourceKinds) { if (kind == ResourceKind.UniformBuffer || kind == ResourceKind.StructuredBufferReadOnly) { MTLPipelineBufferDescriptor bufferDesc = buffers[bufferIndex]; bufferDesc.mutability = MTLMutability.Immutable; bufferIndex += 1; } else if (kind == ResourceKind.StructuredBufferReadWrite) { MTLPipelineBufferDescriptor bufferDesc = buffers[bufferIndex]; bufferDesc.mutability = MTLMutability.Mutable; bufferIndex += 1; } } } ComputePipelineState = gd.Device.newComputePipelineStateWithDescriptor(mtlDesc); ObjectiveCRuntime.release(mtlDesc.NativePtr); }
public MTLRegion(MTLOrigin origin, MTLSize size) { this.origin = origin; this.size = size; }
public void SetUp() { size = new MTLSize(10, 10, 10); TestRuntime.AssertXcodeVersion(13, 0); descriptor = MTLRasterizationRateMapDescriptor.Create(size); }
bool PrepareCompute () { NSError error; // Create a compute kernel function IMTLFunction function = shaderLibrary.CreateFunction ("grayscale"); if(function == null) { Console.WriteLine ("ERROR: Failed creating a new function!"); return false; } // Create a compute kernel kernel = device.CreateComputePipelineState (function, out error); if(kernel == null) { Console.WriteLine ("ERROR: Failed creating a compute kernel: %@", error.Description); return false; } MTLTextureDescriptor texDesc = MTLTextureDescriptor.CreateTexture2DDescriptor (MTLPixelFormat.RGBA8Unorm, (nuint)size.Width, (nuint)size.Height, false); if(texDesc == null) { Console.WriteLine ("ERROR: Failed creating a texture 2d descriptor with RGBA unnormalized pixel format!"); return false; } outTexture = device.CreateTexture (texDesc); if(outTexture == null) { Console.WriteLine ("ERROR: Failed creating an output 2d texture!"); return false; } // Set the compute kernel's workgroup size and count workgroupSize = new MTLSize (1, 1, 1); localCount = new MTLSize ((nint)size.Width, (nint)size.Height, 1); return true; }
public void Deform(ClothSimMetalNode mesh, SimulationData simData) { var w = this.pipelineStateClothSim.ThreadExecutionWidth; var threadsPerThreadgroup = new MTLSize((nint)w, 1, 1); var threadgroupsPerGrid = new MTLSize((mesh.VertexCount + (int)w - 1) / (int)w, 1, 1); var clothSimCommandBuffer = this.commandQueue.CommandBuffer(); var clothSimCommandEncoder = clothSimCommandBuffer?.ComputeCommandEncoder; if (clothSimCommandEncoder != null) { clothSimCommandEncoder.SetComputePipelineState(pipelineStateClothSim); clothSimCommandEncoder.SetBuffer(mesh.Vb1, 0, 0); clothSimCommandEncoder.SetBuffer(mesh.Vb2, 0, 1); clothSimCommandEncoder.SetBuffer(mesh.VelocityBuffers[mesh.CurrentBufferIndex], 0, 2); mesh.CurrentBufferIndex = (mesh.CurrentBufferIndex + 1) % 2; clothSimCommandEncoder.SetBuffer(mesh.VelocityBuffers[mesh.CurrentBufferIndex], 0, 3); //var pointer = System.Runtime.InteropServices.Marshal.GetComInterfaceForObject(simData, typeof(SimulationData)); //clothSimCommandEncoder?.SetBytes(pointer, (nuint)System.Runtime.InteropServices.Marshal.SizeOf<SimulationData>(), 4); clothSimCommandEncoder.DispatchThreadgroups(threadgroupsPerGrid, threadsPerThreadgroup: threadsPerThreadgroup); clothSimCommandEncoder.EndEncoding(); } clothSimCommandBuffer?.Commit(); // var normalComputeCommandBuffer = this.commandQueue.CommandBuffer(); var normalComputeCommandEncoder = normalComputeCommandBuffer?.ComputeCommandEncoder; if (normalComputeCommandEncoder != null) { normalComputeCommandEncoder.SetComputePipelineState(pipelineStateNormalUpdate); normalComputeCommandEncoder.SetBuffer(mesh.Vb2, 0, 0); normalComputeCommandEncoder.SetBuffer(mesh.Vb1, 0, 1); normalComputeCommandEncoder.SetBuffer(mesh.NormalWorkBuffer, 0, 2); normalComputeCommandEncoder.DispatchThreadgroups(threadgroupsPerGrid, threadsPerThreadgroup); normalComputeCommandEncoder.EndEncoding(); } normalComputeCommandBuffer?.Commit(); // var normalSmoothComputeCommandBuffer = this.commandQueue.CommandBuffer(); var normalSmoothComputeCommandEncoder = normalSmoothComputeCommandBuffer?.ComputeCommandEncoder; if (normalSmoothComputeCommandEncoder != null) { normalSmoothComputeCommandEncoder.SetComputePipelineState(pipelineStateNormalSmooth); normalSmoothComputeCommandEncoder.SetBuffer(mesh.NormalWorkBuffer, 0, 0); normalSmoothComputeCommandEncoder.SetBuffer(mesh.NormalBuffer, 0, 1); normalSmoothComputeCommandEncoder.DispatchThreadgroups(threadgroupsPerGrid, threadsPerThreadgroup); normalSmoothComputeCommandEncoder.EndEncoding(); } normalSmoothComputeCommandBuffer?.Commit(); }