Texture, Pipeline, Sample, Renderer Improvements
This commit is contained in:
parent
ebaf1d8258
commit
1e36815713
5 changed files with 181 additions and 54 deletions
|
@ -182,6 +182,20 @@ namespace Ryujinx.Graphics.Metal
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static MTLTextureSwizzle Convert(this SwizzleComponent swizzleComponent)
|
||||||
|
{
|
||||||
|
return swizzleComponent switch
|
||||||
|
{
|
||||||
|
SwizzleComponent.Zero => MTLTextureSwizzle.Zero,
|
||||||
|
SwizzleComponent.One => MTLTextureSwizzle.One,
|
||||||
|
SwizzleComponent.Red => MTLTextureSwizzle.Red,
|
||||||
|
SwizzleComponent.Green => MTLTextureSwizzle.Green,
|
||||||
|
SwizzleComponent.Blue => MTLTextureSwizzle.Blue,
|
||||||
|
SwizzleComponent.Alpha => MTLTextureSwizzle.Alpha,
|
||||||
|
_ => LogInvalidAndReturn(swizzleComponent, nameof(SwizzleComponent), MTLTextureSwizzle.Zero),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private static T2 LogInvalidAndReturn<T1, T2>(T1 value, string name, T2 defaultValue = default)
|
private static T2 LogInvalidAndReturn<T1, T2>(T1 value, string name, T2 defaultValue = default)
|
||||||
{
|
{
|
||||||
Logger.Debug?.Print(LogClass.Gpu, $"Invalid {name} enum value: {value}.");
|
Logger.Debug?.Print(LogClass.Gpu, $"Invalid {name} enum value: {value}.");
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.Shader.Translation;
|
using Ryujinx.Graphics.Shader.Translation;
|
||||||
|
using SharpMetal.Metal;
|
||||||
using System;
|
using System;
|
||||||
using SharpMetal;
|
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
|
|
||||||
|
@ -28,10 +28,10 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
public void Initialize(GraphicsDebugLevel logLevel)
|
public void Initialize(GraphicsDebugLevel logLevel)
|
||||||
{
|
{
|
||||||
_device = MTLDevice.MTLCreateSystemDefaultDevice();
|
_device = MTLDevice.CreateSystemDefaultDevice();
|
||||||
Queue = _device.NewCommandQueueWithMaxCommandBufferCount(Constants.MaxCommandBuffersPerQueue);
|
Queue = _device.NewCommandQueue();
|
||||||
|
|
||||||
var commandBuffer = Queue.CommandBufferWithDescriptor(new MTLCommandBufferDescriptor { RetainedReferences = true });
|
var commandBuffer = Queue.CommandBuffer();
|
||||||
|
|
||||||
_pipeline = new Pipeline(_device, commandBuffer);
|
_pipeline = new Pipeline(_device, commandBuffer);
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
{
|
{
|
||||||
BufferCount++;
|
BufferCount++;
|
||||||
|
|
||||||
var buffer = _device.NewBufferWithBytesLengthOptions(pointer, (ulong)size, MTLResourceOptions.StorageModeShared);
|
var buffer = _device.NewBuffer(pointer, (ulong)size, MTLResourceOptions.ResourceStorageModeShared);
|
||||||
var bufferPtr = buffer.NativePtr;
|
var bufferPtr = buffer.NativePtr;
|
||||||
return Unsafe.As<IntPtr, BufferHandle>(ref bufferPtr);
|
return Unsafe.As<IntPtr, BufferHandle>(ref bufferPtr);
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
{
|
{
|
||||||
BufferCount++;
|
BufferCount++;
|
||||||
|
|
||||||
var buffer = _device.NewBufferWithLengthOptions((ulong)size, MTLResourceOptions.StorageModeShared);
|
var buffer = _device.NewBuffer((ulong)size, MTLResourceOptions.ResourceStorageModeShared);
|
||||||
var bufferPtr = buffer.NativePtr;
|
var bufferPtr = buffer.NativePtr;
|
||||||
return Unsafe.As<IntPtr, BufferHandle>(ref bufferPtr);
|
return Unsafe.As<IntPtr, BufferHandle>(ref bufferPtr);
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
{
|
{
|
||||||
(MTLSamplerMinMagFilter minFilter, MTLSamplerMipFilter mipFilter) = info.MinFilter.Convert();
|
(MTLSamplerMinMagFilter minFilter, MTLSamplerMipFilter mipFilter) = info.MinFilter.Convert();
|
||||||
|
|
||||||
var sampler = _device.CreateSamplerState(new MTLSamplerDescriptor
|
var sampler = _device.NewSamplerState(new MTLSamplerDescriptor
|
||||||
{
|
{
|
||||||
BorderColor = MTLSamplerBorderColor.TransparentBlack,
|
BorderColor = MTLSamplerBorderColor.TransparentBlack,
|
||||||
MinFilter = minFilter,
|
MinFilter = minFilter,
|
||||||
|
@ -90,10 +90,10 @@ namespace Ryujinx.Graphics.Metal
|
||||||
RAddressMode = info.AddressP.Convert()
|
RAddressMode = info.AddressP.Convert()
|
||||||
});
|
});
|
||||||
|
|
||||||
throw new NotImplementedException();
|
return new Sampler(sampler);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ITexture CreateTexture(TextureCreateInfo info, float scale)
|
public ITexture CreateTexture(TextureCreateInfo info)
|
||||||
{
|
{
|
||||||
MTLTextureDescriptor descriptor = new()
|
MTLTextureDescriptor descriptor = new()
|
||||||
{
|
{
|
||||||
|
@ -105,10 +105,10 @@ namespace Ryujinx.Graphics.Metal
|
||||||
SampleCount = (ulong)info.Samples,
|
SampleCount = (ulong)info.Samples,
|
||||||
};
|
};
|
||||||
|
|
||||||
return CreateTextureView(info, scale);
|
return CreateTextureView(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal TextureView CreateTextureView(TextureCreateInfo info, float scale)
|
internal Texture CreateTextureView(TextureCreateInfo info)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
@ -160,17 +160,21 @@ namespace Ryujinx.Graphics.Metal
|
||||||
supportsFragmentShaderOrderingIntel: false,
|
supportsFragmentShaderOrderingIntel: false,
|
||||||
supportsGeometryShader: false,
|
supportsGeometryShader: false,
|
||||||
supportsGeometryShaderPassthrough: false,
|
supportsGeometryShaderPassthrough: false,
|
||||||
|
supportsTransformFeedback: false,
|
||||||
supportsImageLoadFormatted: false,
|
supportsImageLoadFormatted: false,
|
||||||
supportsLayerVertexTessellation: false,
|
supportsLayerVertexTessellation: false,
|
||||||
supportsMismatchingViewFormat: true,
|
supportsMismatchingViewFormat: true,
|
||||||
supportsCubemapView: true,
|
supportsCubemapView: true,
|
||||||
supportsNonConstantTextureOffset: false,
|
supportsNonConstantTextureOffset: false,
|
||||||
supportsShaderBallot: false,
|
supportsShaderBallot: false,
|
||||||
|
supportsShaderBarrierDivergence: false,
|
||||||
|
supportsShaderFloat64: false,
|
||||||
supportsTextureShadowLod: false,
|
supportsTextureShadowLod: false,
|
||||||
supportsViewportIndexVertexTessellation: false,
|
supportsViewportIndexVertexTessellation: false,
|
||||||
supportsViewportMask: false,
|
supportsViewportMask: false,
|
||||||
supportsViewportSwizzle: false,
|
supportsViewportSwizzle: false,
|
||||||
supportsIndirectParameters: true,
|
supportsIndirectParameters: true,
|
||||||
|
supportsDepthClipControl: false,
|
||||||
maximumUniformBuffersPerStage: Constants.MaxUniformBuffersPerStage,
|
maximumUniformBuffersPerStage: Constants.MaxUniformBuffersPerStage,
|
||||||
maximumStorageBuffersPerStage: Constants.MaxStorageBuffersPerStage,
|
maximumStorageBuffersPerStage: Constants.MaxStorageBuffersPerStage,
|
||||||
maximumTexturesPerStage: Constants.MaxTexturesPerStage,
|
maximumTexturesPerStage: Constants.MaxTexturesPerStage,
|
||||||
|
@ -212,7 +216,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ICounterEvent ReportCounter(CounterType type, EventHandler<ulong> resultHandler, bool hostReserved)
|
public ICounterEvent ReportCounter(CounterType type, EventHandler<ulong> resultHandler, float divisor, bool hostReserved)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
@ -243,4 +247,4 @@ namespace Ryujinx.Graphics.Metal
|
||||||
_pipeline.Dispose();
|
_pipeline.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.Shader;
|
using Ryujinx.Graphics.Shader;
|
||||||
|
using SharpMetal.Foundation;
|
||||||
|
using SharpMetal.Metal;
|
||||||
using System;
|
using System;
|
||||||
using SharpMetal;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Metal
|
namespace Ryujinx.Graphics.Metal
|
||||||
|
@ -9,16 +11,30 @@ namespace Ryujinx.Graphics.Metal
|
||||||
[SupportedOSPlatform("macos")]
|
[SupportedOSPlatform("macos")]
|
||||||
public class Pipeline : IPipeline, IDisposable
|
public class Pipeline : IPipeline, IDisposable
|
||||||
{
|
{
|
||||||
|
private MTLDevice _device;
|
||||||
private MTLCommandBuffer _commandBuffer;
|
private MTLCommandBuffer _commandBuffer;
|
||||||
private MTLRenderCommandEncoder _renderCommandEncoder;
|
private MTLRenderCommandEncoder _renderCommandEncoder;
|
||||||
|
|
||||||
|
private PrimitiveTopology _topology;
|
||||||
|
|
||||||
|
private MTLBuffer _indexBuffer;
|
||||||
|
private MTLIndexType _indexType;
|
||||||
|
private ulong _indexBufferOffset;
|
||||||
|
|
||||||
public Pipeline(MTLDevice device, MTLCommandBuffer commandBuffer)
|
public Pipeline(MTLDevice device, MTLCommandBuffer commandBuffer)
|
||||||
{
|
{
|
||||||
var renderPipelineDescriptor = new MTLRenderPipelineDescriptor();
|
var renderPipelineDescriptor = new MTLRenderPipelineDescriptor();
|
||||||
var renderPipelineState = device.CreateRenderPipelineState(renderPipelineDescriptor, out NSError _);
|
var error = new NSError(IntPtr.Zero);
|
||||||
|
_device = device;
|
||||||
|
var renderPipelineState = _device.NewRenderPipelineState(renderPipelineDescriptor, ref error);
|
||||||
|
if (error != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
// throw new Exception($"Failed to create render pipeline state! {StringHelp}");
|
||||||
|
throw new Exception($"Failed to create render pipeline state!");
|
||||||
|
}
|
||||||
|
|
||||||
_commandBuffer = commandBuffer;
|
_commandBuffer = commandBuffer;
|
||||||
_renderCommandEncoder = _commandBuffer.CreateRenderCommandEncoder(new MTLRenderPassDescriptor());
|
_renderCommandEncoder = _commandBuffer.RenderCommandEncoder(new MTLRenderPassDescriptor());
|
||||||
_renderCommandEncoder.SetRenderPipelineState(renderPipelineState);
|
_renderCommandEncoder.SetRenderPipelineState(renderPipelineState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +61,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
public void CommandBufferBarrier()
|
public void CommandBufferBarrier()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
// TODO: Only required for MTLHeap or untracked resources
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CopyBuffer(BufferHandle source, BufferHandle destination, int srcOffset, int dstOffset, int size)
|
public void CopyBuffer(BufferHandle source, BufferHandle destination, int srcOffset, int dstOffset, int size)
|
||||||
|
@ -60,12 +76,18 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
public void Draw(int vertexCount, int instanceCount, int firstVertex, int firstInstance)
|
public void Draw(int vertexCount, int instanceCount, int firstVertex, int firstInstance)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
// TODO: Support topology re-indexing to provide support for TriangleFans
|
||||||
|
var _primitiveType = _topology.Convert();
|
||||||
|
|
||||||
|
_renderCommandEncoder.DrawPrimitives(_primitiveType, (ulong)firstVertex, (ulong)vertexCount, (ulong)instanceCount, (ulong)firstInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DrawIndexed(int indexCount, int instanceCount, int firstIndex, int firstVertex, int firstInstance)
|
public void DrawIndexed(int indexCount, int instanceCount, int firstIndex, int firstVertex, int firstInstance)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
// TODO: Support topology re-indexing to provide support for TriangleFans
|
||||||
|
var _primitiveType = _topology.Convert();
|
||||||
|
|
||||||
|
_renderCommandEncoder.DrawIndexedPrimitives(_primitiveType, (ulong)indexCount, _indexType, _indexBuffer, _indexBufferOffset, (ulong)instanceCount, firstVertex, (ulong)firstInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DrawIndexedIndirect(BufferRange indirectBuffer)
|
public void DrawIndexedIndirect(BufferRange indirectBuffer)
|
||||||
|
@ -95,7 +117,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
public void SetAlphaTest(bool enable, float reference, CompareOp op)
|
public void SetAlphaTest(bool enable, float reference, CompareOp op)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
// Metal does not support alpha test.
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetBlendState(AdvancedBlendDescriptor blend)
|
public void SetBlendState(AdvancedBlendDescriptor blend)
|
||||||
|
@ -130,17 +152,23 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
public void SetFaceCulling(bool enable, Face face)
|
public void SetFaceCulling(bool enable, Face face)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
_renderCommandEncoder.SetCullMode(enable ? face.Convert() : MTLCullMode.None);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetFrontFace(FrontFace frontFace)
|
public void SetFrontFace(FrontFace frontFace)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
_renderCommandEncoder.SetFrontFacingWinding(frontFace.Convert());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetIndexBuffer(BufferRange buffer, IndexType type)
|
public void SetIndexBuffer(BufferRange buffer, IndexType type)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
if (buffer.Handle != BufferHandle.Null)
|
||||||
|
{
|
||||||
|
_indexType = type.Convert();
|
||||||
|
_indexBufferOffset = (ulong)buffer.Offset;
|
||||||
|
var handle = buffer.Handle;
|
||||||
|
_indexBuffer = new(Unsafe.As<BufferHandle, IntPtr>(ref handle));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetImage(int binding, ITexture texture, Format imageFormat)
|
public void SetImage(int binding, ITexture texture, Format imageFormat)
|
||||||
|
@ -150,12 +178,12 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
public void SetLineParameters(float width, bool smooth)
|
public void SetLineParameters(float width, bool smooth)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
// Not supported in Metal
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetLogicOpState(bool enable, LogicalOp op)
|
public void SetLogicOpState(bool enable, LogicalOp op)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
// Not supported in Metal
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetMultisampleState(MultisampleDescriptor multisample)
|
public void SetMultisampleState(MultisampleDescriptor multisample)
|
||||||
|
@ -175,17 +203,20 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
public void SetPolygonMode(PolygonMode frontMode, PolygonMode backMode)
|
public void SetPolygonMode(PolygonMode frontMode, PolygonMode backMode)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
// Not supported in Metal
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetPrimitiveRestart(bool enable, int index)
|
public void SetPrimitiveRestart(bool enable, int index)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
// TODO: Supported for LineStrip and TriangleStrip
|
||||||
|
// https://github.com/gpuweb/gpuweb/issues/1220#issuecomment-732483263
|
||||||
|
// https://developer.apple.com/documentation/metal/mtlrendercommandencoder/1515520-drawindexedprimitives
|
||||||
|
// https://stackoverflow.com/questions/70813665/how-to-render-multiple-trianglestrips-using-metal
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetPrimitiveTopology(PrimitiveTopology topology)
|
public void SetPrimitiveTopology(PrimitiveTopology topology)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
_topology = topology;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetProgram(IProgram program)
|
public void SetProgram(IProgram program)
|
||||||
|
@ -198,11 +229,6 @@ namespace Ryujinx.Graphics.Metal
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetRenderTargetScale(float scale)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetRenderTargetColorMasks(ReadOnlySpan<uint> componentMask)
|
public void SetRenderTargetColorMasks(ReadOnlySpan<uint> componentMask)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
|
@ -213,14 +239,33 @@ namespace Ryujinx.Graphics.Metal
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetScissors(ReadOnlySpan<Rectangle<int>> regions)
|
public unsafe void SetScissors(ReadOnlySpan<Rectangle<int>> regions)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
// TODO: Test max allowed scissor rects on device
|
||||||
|
var mtlScissorRects = new MTLScissorRect[regions.Length];
|
||||||
|
|
||||||
|
for (int i = 0; i < regions.Length; i++)
|
||||||
|
{
|
||||||
|
var region = regions[i];
|
||||||
|
mtlScissorRects[i] = new MTLScissorRect
|
||||||
|
{
|
||||||
|
height = (ulong)region.Height,
|
||||||
|
width = (ulong)region.Width,
|
||||||
|
x = (ulong)region.X,
|
||||||
|
y = (ulong)region.Y
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fixed (MTLScissorRect* pMtlScissorRects = mtlScissorRects)
|
||||||
|
{
|
||||||
|
// TODO: Fix this function which currently wont accept pointer as intended
|
||||||
|
// _renderCommandEncoder.SetScissorRects(pMtlScissorRects, regions.Length);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetStencilTest(StencilTestDescriptor stencilTest)
|
public void SetStencilTest(StencilTestDescriptor stencilTest)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetStorageBuffers(ReadOnlySpan<BufferAssignment> buffers)
|
public void SetStorageBuffers(ReadOnlySpan<BufferAssignment> buffers)
|
||||||
|
@ -253,9 +298,30 @@ namespace Ryujinx.Graphics.Metal
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetViewports(ReadOnlySpan<Viewport> viewports, bool disableTransform)
|
public unsafe void SetViewports(ReadOnlySpan<Viewport> viewports)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
// TODO: Test max allowed viewports on device
|
||||||
|
var mtlViewports = new MTLViewport[viewports.Length];
|
||||||
|
|
||||||
|
for (int i = 0; i < viewports.Length; i++)
|
||||||
|
{
|
||||||
|
var viewport = viewports[i];
|
||||||
|
mtlViewports[i] = new MTLViewport
|
||||||
|
{
|
||||||
|
originX = viewport.Region.X,
|
||||||
|
originY = viewport.Region.Y,
|
||||||
|
width = viewport.Region.Width,
|
||||||
|
height = viewport.Region.Height,
|
||||||
|
znear = viewport.DepthNear,
|
||||||
|
zfar = viewport.DepthFar
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fixed (MTLViewport* pMtlViewports = mtlViewports)
|
||||||
|
{
|
||||||
|
// TODO: Fix this function which currently wont accept pointer as intended
|
||||||
|
// _renderCommandEncoder.SetViewports(pMtlViewports, viewports.Length);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void TextureBarrier()
|
public void TextureBarrier()
|
||||||
|
@ -270,40 +336,34 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
public bool TryHostConditionalRendering(ICounterEvent value, ulong compare, bool isEqual)
|
public bool TryHostConditionalRendering(ICounterEvent value, ulong compare, bool isEqual)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
// TODO: Implementable via indirect draw commands
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryHostConditionalRendering(ICounterEvent value, ICounterEvent compare, bool isEqual)
|
public bool TryHostConditionalRendering(ICounterEvent value, ICounterEvent compare, bool isEqual)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
// TODO: Implementable via indirect draw commands
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void EndHostConditionalRendering()
|
public void EndHostConditionalRendering()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
// TODO: Implementable via indirect draw commands
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateRenderScale(ReadOnlySpan<float> scales, int totalCount, int fragmentCount)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void BeginTransformFeedback(PrimitiveTopology topology)
|
public void BeginTransformFeedback(PrimitiveTopology topology)
|
||||||
{
|
{
|
||||||
// Metal does not support Transform Feedback
|
// Metal does not support Transform Feedback
|
||||||
throw new NotSupportedException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void EndTransformFeedback()
|
public void EndTransformFeedback()
|
||||||
{
|
{
|
||||||
// Metal does not support Transform Feedback
|
// Metal does not support Transform Feedback
|
||||||
throw new NotSupportedException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetTransformFeedbackBuffers(ReadOnlySpan<BufferRange> buffers)
|
public void SetTransformFeedbackBuffers(ReadOnlySpan<BufferRange> buffers)
|
||||||
{
|
{
|
||||||
// Metal does not support Transform Feedback
|
// Metal does not support Transform Feedback
|
||||||
throw new NotSupportedException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
@ -311,4 +371,4 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
19
src/Ryujinx.Graphics.Metal/Sampler.cs
Normal file
19
src/Ryujinx.Graphics.Metal/Sampler.cs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
using Ryujinx.Graphics.GAL;
|
||||||
|
using SharpMetal.Metal;
|
||||||
|
|
||||||
|
namespace Ryujinx.Graphics.Metal
|
||||||
|
{
|
||||||
|
public class Sampler : ISampler
|
||||||
|
{
|
||||||
|
private MTLSamplerState _mtlSamplerState;
|
||||||
|
|
||||||
|
public Sampler(MTLSamplerState mtlSamplerState)
|
||||||
|
{
|
||||||
|
_mtlSamplerState = mtlSamplerState;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,14 +1,44 @@
|
||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
|
using SharpMetal.Metal;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Runtime.Versioning;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Metal
|
namespace Ryujinx.Graphics.Metal
|
||||||
{
|
{
|
||||||
class TextureView : ITexture, IDisposable
|
[SupportedOSPlatform("macos")]
|
||||||
|
class Texture : ITexture, IDisposable
|
||||||
{
|
{
|
||||||
public int Width { get; }
|
private readonly TextureCreateInfo _info;
|
||||||
public int Height { get; }
|
|
||||||
public float ScaleFactor { get; }
|
public MTLTexture MTLTexture;
|
||||||
|
public TextureCreateInfo Info => Info;
|
||||||
|
public int Width => Info.Width;
|
||||||
|
public int Height => Info.Height;
|
||||||
|
|
||||||
|
public Texture(MTLDevice device, TextureCreateInfo info, int firstLayer, int firstLevel)
|
||||||
|
{
|
||||||
|
_info = info;
|
||||||
|
|
||||||
|
var descriptor = new MTLTextureDescriptor();
|
||||||
|
descriptor.PixelFormat = FormatTable.GetFormat(Info.Format);
|
||||||
|
// descriptor.Usage =
|
||||||
|
descriptor.Width = (ulong)Width;
|
||||||
|
descriptor.Height = (ulong)Height;
|
||||||
|
descriptor.Depth = (ulong)Info.Depth;
|
||||||
|
descriptor.SampleCount = (ulong)Info.Samples;
|
||||||
|
descriptor.TextureType = Info.Target.Convert();
|
||||||
|
descriptor.Swizzle = new MTLTextureSwizzleChannels
|
||||||
|
{
|
||||||
|
red = Info.SwizzleR.Convert(),
|
||||||
|
green = Info.SwizzleG.Convert(),
|
||||||
|
blue = Info.SwizzleB.Convert(),
|
||||||
|
alpha = Info.SwizzleA.Convert()
|
||||||
|
};
|
||||||
|
|
||||||
|
MTLTexture = device.NewTexture(descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
public void CopyTo(ITexture destination, int firstLayer, int firstLevel)
|
public void CopyTo(ITexture destination, int firstLayer, int firstLevel)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
Loading…
Reference in a new issue