public MTLSampler(ref SamplerDescription description, MTLGraphicsDevice gd) { MTLFormats.GetMinMagMipFilter( description.Filter, out MTLSamplerMinMagFilter min, out MTLSamplerMinMagFilter mag, out MTLSamplerMipFilter mip); MTLSamplerDescriptor mtlDesc = MTLUtil.AllocInit <MTLSamplerDescriptor>(); mtlDesc.rAddressMode = MTLFormats.VdToMTLAddressMode(description.AddressModeU); mtlDesc.sAddressMode = MTLFormats.VdToMTLAddressMode(description.AddressModeV); mtlDesc.tAddressMode = MTLFormats.VdToMTLAddressMode(description.AddressModeW); mtlDesc.minFilter = min; mtlDesc.magFilter = mag; mtlDesc.mipFilter = mip; mtlDesc.borderColor = MTLFormats.VdToMTLBorderColor(description.BorderColor); if (description.ComparisonKind != null) { mtlDesc.compareFunction = MTLFormats.VdToMTLCompareFunction(description.ComparisonKind.Value); } mtlDesc.lodMinClamp = description.MinimumLod; mtlDesc.lodMaxClamp = description.MaximumLod; mtlDesc.maxAnisotropy = (UIntPtr)(Math.Max(1, description.MaximumAnisotropy)); DeviceSampler = gd.Device.newSamplerStateWithDescriptor(mtlDesc); ObjectiveCRuntime.release(mtlDesc.NativePtr); }
internal MTLComputePipelineState GetUnalignedBufferCopyPipeline() { lock (_unalignedBufferCopyPipelineLock) { if (_unalignedBufferCopyPipeline.IsNull) { MTLComputePipelineDescriptor descriptor = MTLUtil.AllocInit <MTLComputePipelineDescriptor>( nameof(MTLComputePipelineDescriptor)); MTLPipelineBufferDescriptor buffer0 = descriptor.buffers[0]; buffer0.mutability = MTLMutability.Mutable; MTLPipelineBufferDescriptor buffer1 = descriptor.buffers[1]; buffer0.mutability = MTLMutability.Mutable; Debug.Assert(_unalignedBufferCopyShader == null); string name = MetalFeatures.IsMacOS ? UnalignedBufferCopyPipelineMacOSName : UnalignedBufferCopyPipelineiOSName; using (Stream resourceStream = typeof(MTLGraphicsDevice).Assembly.GetManifestResourceStream(name)) { byte[] data = new byte[resourceStream.Length]; using (MemoryStream ms = new MemoryStream(data)) { resourceStream.CopyTo(ms); ShaderDescription shaderDesc = new ShaderDescription(ShaderStages.Compute, data, "copy_bytes"); _unalignedBufferCopyShader = new MTLShader(ref shaderDesc, this); } } descriptor.computeFunction = _unalignedBufferCopyShader.Function; _unalignedBufferCopyPipeline = _device.newComputePipelineStateWithDescriptor(descriptor); ObjectiveCRuntime.release(descriptor.NativePtr); } return(_unalignedBufferCopyPipeline); } }
public override MTLRenderPassDescriptor CreateRenderPassDescriptor() { MTLRenderPassDescriptor ret = MTLUtil.AllocInit <MTLRenderPassDescriptor>(); for (int i = 0; i < ColorTargets.Count; i++) { FramebufferAttachment colorTarget = ColorTargets[i]; MTLTexture mtlTarget = Util.AssertSubtype <Texture, MTLTexture>(colorTarget.Target); MTLRenderPassColorAttachmentDescriptor colorDescriptor = ret.colorAttachments[(uint)i]; colorDescriptor.texture = mtlTarget.DeviceTexture; colorDescriptor.loadAction = MTLLoadAction.Load; colorDescriptor.slice = (UIntPtr)colorTarget.ArrayLayer; } if (DepthTarget != null) { MTLTexture mtlDepthTarget = Util.AssertSubtype <Texture, MTLTexture>(DepthTarget.Value.Target); MTLRenderPassDepthAttachmentDescriptor depthDescriptor = ret.depthAttachment; depthDescriptor.loadAction = MTLLoadAction.Load; depthDescriptor.storeAction = MTLStoreAction.Store; depthDescriptor.texture = mtlDepthTarget.DeviceTexture; depthDescriptor.slice = (UIntPtr)DepthTarget.Value.ArrayLayer; if (FormatHelpers.IsStencilFormat(mtlDepthTarget.Format)) { MTLRenderPassStencilAttachmentDescriptor stencilDescriptor = ret.stencilAttachment; stencilDescriptor.loadAction = MTLLoadAction.Load; stencilDescriptor.storeAction = MTLStoreAction.Store; stencilDescriptor.texture = mtlDepthTarget.DeviceTexture; stencilDescriptor.slice = (UIntPtr)DepthTarget.Value.ArrayLayer; } } return(ret); }
public MTLTexture(ref TextureDescription description, MTLGraphicsDevice _gd) { Width = description.Width; Height = description.Height; Depth = description.Depth; ArrayLayers = description.ArrayLayers; MipLevels = description.MipLevels; Format = description.Format; Usage = description.Usage; Type = description.Type; SampleCount = description.SampleCount; bool isDepth = (Usage & TextureUsage.DepthStencil) == TextureUsage.DepthStencil; MTLPixelFormat = MTLFormats.VdToMTLPixelFormat(Format, isDepth); MTLTextureType = MTLFormats.VdToMTLTextureType( Type, ArrayLayers, SampleCount != TextureSampleCount.Count1, (Usage & TextureUsage.Cubemap) != 0); if (Usage != TextureUsage.Staging) { MTLTextureDescriptor texDescriptor = MTLUtil.AllocInit <MTLTextureDescriptor>(); texDescriptor.width = (UIntPtr)Width; texDescriptor.height = (UIntPtr)Height; texDescriptor.depth = (UIntPtr)Depth; texDescriptor.mipmapLevelCount = (UIntPtr)MipLevels; texDescriptor.arrayLength = (UIntPtr)ArrayLayers; texDescriptor.sampleCount = (UIntPtr)FormatHelpers.GetSampleCountUInt32(SampleCount); texDescriptor.textureType = MTLTextureType; texDescriptor.pixelFormat = MTLPixelFormat; texDescriptor.textureUsage = MTLFormats.VdToMTLTextureUsage(Usage); texDescriptor.storageMode = MTLStorageMode.Private; DeviceTexture = _gd.Device.newTextureWithDescriptor(texDescriptor); ObjectiveCRuntime.release(texDescriptor.NativePtr); } else { uint blockSize = FormatHelpers.IsCompressedFormat(Format) ? 4u : 1u; uint totalStorageSize = 0; for (uint level = 0; level < MipLevels; level++) { Util.GetMipDimensions(this, level, out uint levelWidth, out uint levelHeight, out uint levelDepth); uint storageWidth = Math.Max(levelWidth, blockSize); uint storageHeight = Math.Max(levelHeight, blockSize); totalStorageSize += levelDepth * FormatHelpers.GetDepthPitch( FormatHelpers.GetRowPitch(levelWidth, Format), levelHeight, Format); } totalStorageSize *= ArrayLayers; StagingBuffer = _gd.Device.newBufferWithLengthOptions( (UIntPtr)totalStorageSize, MTLResourceOptions.StorageModeManaged); } }
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); }
public override MTLRenderPassDescriptor CreateRenderPassDescriptor() { var ret = MTLUtil.AllocInit <MTLRenderPassDescriptor>(); var color0 = ret.colorAttachments[0]; color0.texture = _drawable.texture; color0.loadAction = MTLLoadAction.Load; if (_depthTarget != null) { var depthAttachment = ret.depthAttachment; depthAttachment.texture = _depthTexture.DeviceTexture; depthAttachment.loadAction = MTLLoadAction.Load; } return(ret); }
public MTLPipeline(ref GraphicsPipelineDescription description, MTLGraphicsDevice gd) : base(ref description) { PrimitiveType = MTLFormats.VdToMTLPrimitiveTopology(description.PrimitiveTopology); ResourceLayouts = new MTLResourceLayout[description.ResourceLayouts.Length]; NonVertexBufferCount = 0; for (int i = 0; i < ResourceLayouts.Length; i++) { ResourceLayouts[i] = Util.AssertSubtype <ResourceLayout, MTLResourceLayout>(description.ResourceLayouts[i]); NonVertexBufferCount += ResourceLayouts[i].BufferCount; } ResourceBindingModel = description.ResourceBindingModel ?? gd.ResourceBindingModel; CullMode = MTLFormats.VdToMTLCullMode(description.RasterizerState.CullMode); FrontFace = MTLFormats.VdVoMTLFrontFace(description.RasterizerState.FrontFace); FillMode = MTLFormats.VdToMTLFillMode(description.RasterizerState.FillMode); ScissorTestEnabled = description.RasterizerState.ScissorTestEnabled; MTLRenderPipelineDescriptor mtlDesc = MTLRenderPipelineDescriptor.New(); foreach (Shader shader in description.ShaderSet.Shaders) { MTLShader mtlShader = Util.AssertSubtype <Shader, MTLShader>(shader); MTLFunction specializedFunction; if (mtlShader.HasFunctionConstants) { // Need to create specialized MTLFunction. MTLFunctionConstantValues constantValues = CreateConstantValues(description.ShaderSet.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; } if (shader.Stage == ShaderStages.Vertex) { mtlDesc.vertexFunction = specializedFunction; } else if (shader.Stage == ShaderStages.Fragment) { mtlDesc.fragmentFunction = specializedFunction; } } // Vertex layouts VertexLayoutDescription[] vdVertexLayouts = description.ShaderSet.VertexLayouts; MTLVertexDescriptor vertexDescriptor = mtlDesc.vertexDescriptor; for (uint i = 0; i < vdVertexLayouts.Length; i++) { uint layoutIndex = ResourceBindingModel == ResourceBindingModel.Improved ? NonVertexBufferCount + i : i; MTLVertexBufferLayoutDescriptor mtlLayout = vertexDescriptor.layouts[layoutIndex]; mtlLayout.stride = (UIntPtr)vdVertexLayouts[i].Stride; uint stepRate = vdVertexLayouts[i].InstanceStepRate; mtlLayout.stepFunction = stepRate == 0 ? MTLVertexStepFunction.PerVertex : MTLVertexStepFunction.PerInstance; mtlLayout.stepRate = (UIntPtr)Math.Max(1, stepRate); } uint element = 0; for (uint i = 0; i < vdVertexLayouts.Length; i++) { uint offset = 0; VertexLayoutDescription vdDesc = vdVertexLayouts[i]; for (uint j = 0; j < vdDesc.Elements.Length; j++) { VertexElementDescription elementDesc = vdDesc.Elements[j]; MTLVertexAttributeDescriptor mtlAttribute = vertexDescriptor.attributes[element]; mtlAttribute.bufferIndex = (UIntPtr)(ResourceBindingModel == ResourceBindingModel.Improved ? NonVertexBufferCount + i : i); mtlAttribute.format = MTLFormats.VdToMTLVertexFormat(elementDesc.Format); mtlAttribute.offset = elementDesc.Offset != 0 ? (UIntPtr)elementDesc.Offset : (UIntPtr)offset; offset += FormatHelpers.GetSizeInBytes(elementDesc.Format); element += 1; } } VertexBufferCount = (uint)vdVertexLayouts.Length; // Outputs OutputDescription outputs = description.Outputs; BlendStateDescription blendStateDesc = description.BlendState; BlendColor = blendStateDesc.BlendFactor; if (outputs.SampleCount != TextureSampleCount.Count1) { mtlDesc.sampleCount = (UIntPtr)FormatHelpers.GetSampleCountUInt32(outputs.SampleCount); } if (outputs.DepthAttachment != null) { PixelFormat depthFormat = outputs.DepthAttachment.Value.Format; MTLPixelFormat mtlDepthFormat = MTLFormats.VdToMTLPixelFormat(depthFormat, true); mtlDesc.depthAttachmentPixelFormat = mtlDepthFormat; if ((FormatHelpers.IsStencilFormat(depthFormat))) { HasStencil = true; mtlDesc.stencilAttachmentPixelFormat = mtlDepthFormat; } } for (uint i = 0; i < outputs.ColorAttachments.Length; i++) { BlendAttachmentDescription attachmentBlendDesc = blendStateDesc.AttachmentStates[i]; MTLRenderPipelineColorAttachmentDescriptor colorDesc = mtlDesc.colorAttachments[i]; colorDesc.pixelFormat = MTLFormats.VdToMTLPixelFormat(outputs.ColorAttachments[i].Format, false); colorDesc.blendingEnabled = attachmentBlendDesc.BlendEnabled; colorDesc.alphaBlendOperation = MTLFormats.VdToMTLBlendOp(attachmentBlendDesc.AlphaFunction); colorDesc.sourceAlphaBlendFactor = MTLFormats.VdToMTLBlendFactor(attachmentBlendDesc.SourceAlphaFactor); colorDesc.destinationAlphaBlendFactor = MTLFormats.VdToMTLBlendFactor(attachmentBlendDesc.DestinationAlphaFactor); colorDesc.rgbBlendOperation = MTLFormats.VdToMTLBlendOp(attachmentBlendDesc.ColorFunction); colorDesc.sourceRGBBlendFactor = MTLFormats.VdToMTLBlendFactor(attachmentBlendDesc.SourceColorFactor); colorDesc.destinationRGBBlendFactor = MTLFormats.VdToMTLBlendFactor(attachmentBlendDesc.DestinationColorFactor); } RenderPipelineState = gd.Device.newRenderPipelineStateWithDescriptor(mtlDesc); ObjectiveCRuntime.release(mtlDesc.NativePtr); if (outputs.DepthAttachment != null) { MTLDepthStencilDescriptor depthDescriptor = MTLUtil.AllocInit <MTLDepthStencilDescriptor>( nameof(MTLDepthStencilDescriptor)); depthDescriptor.depthCompareFunction = MTLFormats.VdToMTLCompareFunction( description.DepthStencilState.DepthComparison); depthDescriptor.depthWriteEnabled = description.DepthStencilState.DepthWriteEnabled; bool stencilEnabled = description.DepthStencilState.StencilTestEnabled; if (stencilEnabled) { StencilReference = description.DepthStencilState.StencilReference; StencilBehaviorDescription vdFrontDesc = description.DepthStencilState.StencilFront; MTLStencilDescriptor front = MTLUtil.AllocInit <MTLStencilDescriptor>(nameof(MTLStencilDescriptor)); front.readMask = stencilEnabled ? description.DepthStencilState.StencilReadMask : 0u; front.writeMask = stencilEnabled ? description.DepthStencilState.StencilWriteMask : 0u; front.depthFailureOperation = MTLFormats.VdToMTLStencilOperation(vdFrontDesc.DepthFail); front.stencilFailureOperation = MTLFormats.VdToMTLStencilOperation(vdFrontDesc.Fail); front.depthStencilPassOperation = MTLFormats.VdToMTLStencilOperation(vdFrontDesc.Pass); front.stencilCompareFunction = MTLFormats.VdToMTLCompareFunction(vdFrontDesc.Comparison); depthDescriptor.frontFaceStencil = front; StencilBehaviorDescription vdBackDesc = description.DepthStencilState.StencilBack; MTLStencilDescriptor back = MTLUtil.AllocInit <MTLStencilDescriptor>(nameof(MTLStencilDescriptor)); back.readMask = stencilEnabled ? description.DepthStencilState.StencilReadMask : 0u; back.writeMask = stencilEnabled ? description.DepthStencilState.StencilWriteMask : 0u; back.depthFailureOperation = MTLFormats.VdToMTLStencilOperation(vdBackDesc.DepthFail); back.stencilFailureOperation = MTLFormats.VdToMTLStencilOperation(vdBackDesc.Fail); back.depthStencilPassOperation = MTLFormats.VdToMTLStencilOperation(vdBackDesc.Pass); back.stencilCompareFunction = MTLFormats.VdToMTLCompareFunction(vdBackDesc.Comparison); depthDescriptor.backFaceStencil = back; ObjectiveCRuntime.release(front.NativePtr); ObjectiveCRuntime.release(back.NativePtr); } DepthStencilState = gd.Device.newDepthStencilStateWithDescriptor(depthDescriptor); ObjectiveCRuntime.release(depthDescriptor.NativePtr); } DepthClipMode = description.DepthStencilState.DepthTestEnabled ? MTLDepthClipMode.Clip : MTLDepthClipMode.Clamp; }
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 static CAEAGLLayer New() { return(MTLUtil.AllocInit <CAEAGLLayer>("CAEAGLLayer")); }