misc: chore: Use explicit types in Metal project

This commit is contained in:
Evan Husted 2025-01-25 14:06:26 -06:00
parent 1ae349efb1
commit 76ec047eb7
28 changed files with 315 additions and 313 deletions

View File

@ -46,7 +46,7 @@ namespace Ryujinx.Graphics.Host1x
public void RegisterDevice(ClassId classId, IDeviceState device) public void RegisterDevice(ClassId classId, IDeviceState device)
{ {
ThiDevice thi = new ThiDevice(classId, device ?? throw new ArgumentNullException(nameof(device)), _syncptIncrMgr); ThiDevice thi = new(classId, device ?? throw new ArgumentNullException(nameof(device)), _syncptIncrMgr);
_devices.RegisterDevice(classId, thi); _devices.RegisterDevice(classId, thi);
} }

View File

@ -97,7 +97,7 @@ namespace Ryujinx.Graphics.Metal
{ {
lock (_resources) lock (_resources)
{ {
foreach (var resource in _resources.Values) foreach (BackgroundResource resource in _resources.Values)
{ {
resource.Dispose(); resource.Dispose();
} }

View File

@ -103,7 +103,7 @@ namespace Ryujinx.Graphics.Metal
if (_flushFence != null) if (_flushFence != null)
{ {
var fence = _flushFence; FenceHolder fence = _flushFence;
Interlocked.Increment(ref _flushWaiting); Interlocked.Increment(ref _flushWaiting);
// Don't wait in the lock. // Don't wait in the lock.
@ -219,8 +219,8 @@ namespace Ryujinx.Graphics.Metal
BufferHolder srcHolder = _renderer.BufferManager.Create(dataSize); BufferHolder srcHolder = _renderer.BufferManager.Create(dataSize);
srcHolder.SetDataUnchecked(0, data); srcHolder.SetDataUnchecked(0, data);
var srcBuffer = srcHolder.GetBuffer(); Auto<DisposableBuffer> srcBuffer = srcHolder.GetBuffer();
var dstBuffer = this.GetBuffer(true); Auto<DisposableBuffer> dstBuffer = this.GetBuffer(true);
Copy(cbs.Value, srcBuffer, dstBuffer, 0, offset, dataSize); Copy(cbs.Value, srcBuffer, dstBuffer, 0, offset, dataSize);
@ -262,8 +262,8 @@ namespace Ryujinx.Graphics.Metal
int size, int size,
bool registerSrcUsage = true) bool registerSrcUsage = true)
{ {
var srcBuffer = registerSrcUsage ? src.Get(cbs, srcOffset, size).Value : src.GetUnsafe().Value; MTLBuffer srcBuffer = registerSrcUsage ? src.Get(cbs, srcOffset, size).Value : src.GetUnsafe().Value;
var dstbuffer = dst.Get(cbs, dstOffset, size, true).Value; MTLBuffer dstbuffer = dst.Get(cbs, dstOffset, size, true).Value;
cbs.Encoders.EnsureBlitEncoder().CopyFromBuffer( cbs.Encoders.EnsureBlitEncoder().CopyFromBuffer(
srcBuffer, srcBuffer,
@ -302,9 +302,9 @@ namespace Ryujinx.Graphics.Metal
return null; return null;
} }
var key = new I8ToI16CacheKey(_renderer); I8ToI16CacheKey key = new I8ToI16CacheKey(_renderer);
if (!_cachedConvertedBuffers.TryGetValue(offset, size, key, out var holder)) if (!_cachedConvertedBuffers.TryGetValue(offset, size, key, out BufferHolder holder))
{ {
holder = _renderer.BufferManager.Create((size * 2 + 3) & ~3); holder = _renderer.BufferManager.Create((size * 2 + 3) & ~3);
@ -325,9 +325,9 @@ namespace Ryujinx.Graphics.Metal
return null; return null;
} }
var key = new TopologyConversionCacheKey(_renderer, pattern, indexSize); TopologyConversionCacheKey key = new TopologyConversionCacheKey(_renderer, pattern, indexSize);
if (!_cachedConvertedBuffers.TryGetValue(offset, size, key, out var holder)) if (!_cachedConvertedBuffers.TryGetValue(offset, size, key, out BufferHolder holder))
{ {
// The destination index size is always I32. // The destination index size is always I32.

View File

@ -65,7 +65,7 @@ namespace Ryujinx.Graphics.Metal
public BufferHandle Create(nint pointer, int size) public BufferHandle Create(nint pointer, int size)
{ {
// TODO: This is the wrong Metal method, we need no-copy which SharpMetal isn't giving us. // TODO: This is the wrong Metal method, we need no-copy which SharpMetal isn't giving us.
var buffer = _device.NewBuffer(pointer, (ulong)size, MTLResourceOptions.ResourceStorageModeShared); MTLBuffer buffer = _device.NewBuffer(pointer, (ulong)size, MTLResourceOptions.ResourceStorageModeShared);
if (buffer == IntPtr.Zero) if (buffer == IntPtr.Zero)
{ {
@ -74,7 +74,7 @@ namespace Ryujinx.Graphics.Metal
return BufferHandle.Null; return BufferHandle.Null;
} }
var holder = new BufferHolder(_renderer, _pipeline, buffer, size); BufferHolder holder = new BufferHolder(_renderer, _pipeline, buffer, size);
BufferCount++; BufferCount++;
@ -123,7 +123,7 @@ namespace Ryujinx.Graphics.Metal
public BufferHolder Create(int size) public BufferHolder Create(int size)
{ {
var buffer = _device.NewBuffer((ulong)size, MTLResourceOptions.ResourceStorageModeShared); MTLBuffer buffer = _device.NewBuffer((ulong)size, MTLResourceOptions.ResourceStorageModeShared);
if (buffer != IntPtr.Zero) if (buffer != IntPtr.Zero)
{ {
@ -137,7 +137,7 @@ namespace Ryujinx.Graphics.Metal
public Auto<DisposableBuffer> GetBuffer(BufferHandle handle, bool isWrite, out int size) public Auto<DisposableBuffer> GetBuffer(BufferHandle handle, bool isWrite, out int size)
{ {
if (TryGetBuffer(handle, out var holder)) if (TryGetBuffer(handle, out BufferHolder holder))
{ {
size = holder.Size; size = holder.Size;
return holder.GetBuffer(isWrite); return holder.GetBuffer(isWrite);
@ -149,7 +149,7 @@ namespace Ryujinx.Graphics.Metal
public Auto<DisposableBuffer> GetBuffer(BufferHandle handle, int offset, int size, bool isWrite) public Auto<DisposableBuffer> GetBuffer(BufferHandle handle, int offset, int size, bool isWrite)
{ {
if (TryGetBuffer(handle, out var holder)) if (TryGetBuffer(handle, out BufferHolder holder))
{ {
return holder.GetBuffer(offset, size, isWrite); return holder.GetBuffer(offset, size, isWrite);
} }
@ -159,7 +159,7 @@ namespace Ryujinx.Graphics.Metal
public Auto<DisposableBuffer> GetBuffer(BufferHandle handle, bool isWrite) public Auto<DisposableBuffer> GetBuffer(BufferHandle handle, bool isWrite)
{ {
if (TryGetBuffer(handle, out var holder)) if (TryGetBuffer(handle, out BufferHolder holder))
{ {
return holder.GetBuffer(isWrite); return holder.GetBuffer(isWrite);
} }
@ -169,7 +169,7 @@ namespace Ryujinx.Graphics.Metal
public Auto<DisposableBuffer> GetBufferI8ToI16(CommandBufferScoped cbs, BufferHandle handle, int offset, int size) public Auto<DisposableBuffer> GetBufferI8ToI16(CommandBufferScoped cbs, BufferHandle handle, int offset, int size)
{ {
if (TryGetBuffer(handle, out var holder)) if (TryGetBuffer(handle, out BufferHolder holder))
{ {
return holder.GetBufferI8ToI16(cbs, offset, size); return holder.GetBufferI8ToI16(cbs, offset, size);
} }
@ -179,7 +179,7 @@ namespace Ryujinx.Graphics.Metal
public Auto<DisposableBuffer> GetBufferTopologyConversion(CommandBufferScoped cbs, BufferHandle handle, int offset, int size, IndexBufferPattern pattern, int indexSize) public Auto<DisposableBuffer> GetBufferTopologyConversion(CommandBufferScoped cbs, BufferHandle handle, int offset, int size, IndexBufferPattern pattern, int indexSize)
{ {
if (TryGetBuffer(handle, out var holder)) if (TryGetBuffer(handle, out BufferHolder holder))
{ {
return holder.GetBufferTopologyConversion(cbs, offset, size, pattern, indexSize); return holder.GetBufferTopologyConversion(cbs, offset, size, pattern, indexSize);
} }
@ -189,7 +189,7 @@ namespace Ryujinx.Graphics.Metal
public PinnedSpan<byte> GetData(BufferHandle handle, int offset, int size) public PinnedSpan<byte> GetData(BufferHandle handle, int offset, int size)
{ {
if (TryGetBuffer(handle, out var holder)) if (TryGetBuffer(handle, out BufferHolder holder))
{ {
return holder.GetData(offset, size); return holder.GetData(offset, size);
} }
@ -204,7 +204,7 @@ namespace Ryujinx.Graphics.Metal
public void SetData(BufferHandle handle, int offset, ReadOnlySpan<byte> data, CommandBufferScoped? cbs) public void SetData(BufferHandle handle, int offset, ReadOnlySpan<byte> data, CommandBufferScoped? cbs)
{ {
if (TryGetBuffer(handle, out var holder)) if (TryGetBuffer(handle, out BufferHolder holder))
{ {
holder.SetData(offset, data, cbs); holder.SetData(offset, data, cbs);
} }
@ -212,7 +212,7 @@ namespace Ryujinx.Graphics.Metal
public void Delete(BufferHandle handle) public void Delete(BufferHandle handle)
{ {
if (TryGetBuffer(handle, out var holder)) if (TryGetBuffer(handle, out BufferHolder holder))
{ {
holder.Dispose(); holder.Dispose();
_buffers.Remove((int)Unsafe.As<BufferHandle, ulong>(ref handle)); _buffers.Remove((int)Unsafe.As<BufferHandle, ulong>(ref handle));
@ -228,7 +228,7 @@ namespace Ryujinx.Graphics.Metal
{ {
StagingBuffer.Dispose(); StagingBuffer.Dispose();
foreach (var buffer in _buffers) foreach (BufferHolder buffer in _buffers)
{ {
buffer.Dispose(); buffer.Dispose();
} }

View File

@ -137,7 +137,7 @@ class CommandBufferEncoder
{ {
EndCurrentPass(); EndCurrentPass();
var renderCommandEncoder = _encoderFactory.CreateRenderCommandEncoder(); MTLRenderCommandEncoder renderCommandEncoder = _encoderFactory.CreateRenderCommandEncoder();
CurrentEncoder = renderCommandEncoder; CurrentEncoder = renderCommandEncoder;
CurrentEncoderType = EncoderType.Render; CurrentEncoderType = EncoderType.Render;
@ -149,8 +149,8 @@ class CommandBufferEncoder
{ {
EndCurrentPass(); EndCurrentPass();
using var descriptor = new MTLBlitPassDescriptor(); using MTLBlitPassDescriptor descriptor = new MTLBlitPassDescriptor();
var blitCommandEncoder = _commandBuffer.BlitCommandEncoder(descriptor); MTLBlitCommandEncoder blitCommandEncoder = _commandBuffer.BlitCommandEncoder(descriptor);
CurrentEncoder = blitCommandEncoder; CurrentEncoder = blitCommandEncoder;
CurrentEncoderType = EncoderType.Blit; CurrentEncoderType = EncoderType.Blit;
@ -161,7 +161,7 @@ class CommandBufferEncoder
{ {
EndCurrentPass(); EndCurrentPass();
var computeCommandEncoder = _encoderFactory.CreateComputeCommandEncoder(); MTLComputeCommandEncoder computeCommandEncoder = _encoderFactory.CreateComputeCommandEncoder();
CurrentEncoder = computeCommandEncoder; CurrentEncoder = computeCommandEncoder;
CurrentEncoderType = EncoderType.Compute; CurrentEncoderType = EncoderType.Compute;

View File

@ -101,7 +101,7 @@ namespace Ryujinx.Graphics.Metal
{ {
for (int i = 0; i < _totalCommandBuffers; i++) for (int i = 0; i < _totalCommandBuffers; i++)
{ {
ref var entry = ref _commandBuffers[i]; ref ReservedCommandBuffer entry = ref _commandBuffers[i];
if (entry.InConsumption) if (entry.InConsumption)
{ {
@ -117,7 +117,7 @@ namespace Ryujinx.Graphics.Metal
{ {
for (int i = 0; i < _totalCommandBuffers; i++) for (int i = 0; i < _totalCommandBuffers; i++)
{ {
ref var entry = ref _commandBuffers[i]; ref ReservedCommandBuffer entry = ref _commandBuffers[i];
if (entry.InUse) if (entry.InUse)
{ {
@ -129,7 +129,7 @@ namespace Ryujinx.Graphics.Metal
public void AddWaitable(int cbIndex, MultiFenceHolder waitable) public void AddWaitable(int cbIndex, MultiFenceHolder waitable)
{ {
ref var entry = ref _commandBuffers[cbIndex]; ref ReservedCommandBuffer entry = ref _commandBuffers[cbIndex];
if (waitable.AddFence(cbIndex, entry.Fence)) if (waitable.AddFence(cbIndex, entry.Fence))
{ {
entry.Waitables.Add(waitable); entry.Waitables.Add(waitable);
@ -142,7 +142,7 @@ namespace Ryujinx.Graphics.Metal
{ {
for (int i = 0; i < _totalCommandBuffers; i++) for (int i = 0; i < _totalCommandBuffers; i++)
{ {
ref var entry = ref _commandBuffers[i]; ref ReservedCommandBuffer entry = ref _commandBuffers[i];
if (entry.InUse && entry.Fence == fence) if (entry.InUse && entry.Fence == fence)
{ {
@ -172,7 +172,7 @@ namespace Ryujinx.Graphics.Metal
{ {
int index = _queuedIndexes[_queuedIndexesPtr]; int index = _queuedIndexes[_queuedIndexesPtr];
ref var entry = ref _commandBuffers[index]; ref ReservedCommandBuffer entry = ref _commandBuffers[index];
if (wait || !entry.InConsumption || entry.Fence.IsSignaled()) if (wait || !entry.InConsumption || entry.Fence.IsSignaled())
{ {
@ -207,7 +207,7 @@ namespace Ryujinx.Graphics.Metal
for (int i = 0; i < _totalCommandBuffers; i++) for (int i = 0; i < _totalCommandBuffers; i++)
{ {
ref var entry = ref _commandBuffers[cursor]; ref ReservedCommandBuffer entry = ref _commandBuffers[cursor];
if (!entry.InUse && !entry.InConsumption) if (!entry.InUse && !entry.InConsumption)
{ {
@ -234,7 +234,7 @@ namespace Ryujinx.Graphics.Metal
{ {
int cbIndex = cbs.CommandBufferIndex; int cbIndex = cbs.CommandBufferIndex;
ref var entry = ref _commandBuffers[cbIndex]; ref ReservedCommandBuffer entry = ref _commandBuffers[cbIndex];
Debug.Assert(entry.InUse); Debug.Assert(entry.InUse);
Debug.Assert(entry.CommandBuffer.NativePtr == cbs.CommandBuffer.NativePtr); Debug.Assert(entry.CommandBuffer.NativePtr == cbs.CommandBuffer.NativePtr);
@ -243,7 +243,7 @@ namespace Ryujinx.Graphics.Metal
entry.SubmissionCount++; entry.SubmissionCount++;
_inUseCount--; _inUseCount--;
var commandBuffer = entry.CommandBuffer; MTLCommandBuffer commandBuffer = entry.CommandBuffer;
commandBuffer.Commit(); commandBuffer.Commit();
int ptr = (_queuedIndexesPtr + _queuedCount) % _totalCommandBuffers; int ptr = (_queuedIndexesPtr + _queuedCount) % _totalCommandBuffers;
@ -254,7 +254,7 @@ namespace Ryujinx.Graphics.Metal
private void WaitAndDecrementRef(int cbIndex) private void WaitAndDecrementRef(int cbIndex)
{ {
ref var entry = ref _commandBuffers[cbIndex]; ref ReservedCommandBuffer entry = ref _commandBuffers[cbIndex];
if (entry.InConsumption) if (entry.InConsumption)
{ {
@ -262,12 +262,12 @@ namespace Ryujinx.Graphics.Metal
entry.InConsumption = false; entry.InConsumption = false;
} }
foreach (var dependant in entry.Dependants) foreach (IAuto dependant in entry.Dependants)
{ {
dependant.DecrementReferenceCount(cbIndex); dependant.DecrementReferenceCount(cbIndex);
} }
foreach (var waitable in entry.Waitables) foreach (MultiFenceHolder waitable in entry.Waitables)
{ {
waitable.RemoveFence(cbIndex); waitable.RemoveFence(cbIndex);
waitable.RemoveBufferUses(cbIndex); waitable.RemoveBufferUses(cbIndex);

View File

@ -25,7 +25,7 @@ namespace Ryujinx.Graphics.Metal
ref StencilUid frontUid = ref descriptor.FrontFace; ref StencilUid frontUid = ref descriptor.FrontFace;
using var frontFaceStencil = new MTLStencilDescriptor using MTLStencilDescriptor frontFaceStencil = new MTLStencilDescriptor
{ {
StencilFailureOperation = frontUid.StencilFailureOperation, StencilFailureOperation = frontUid.StencilFailureOperation,
DepthFailureOperation = frontUid.DepthFailureOperation, DepthFailureOperation = frontUid.DepthFailureOperation,
@ -37,7 +37,7 @@ namespace Ryujinx.Graphics.Metal
ref StencilUid backUid = ref descriptor.BackFace; ref StencilUid backUid = ref descriptor.BackFace;
using var backFaceStencil = new MTLStencilDescriptor using MTLStencilDescriptor backFaceStencil = new MTLStencilDescriptor
{ {
StencilFailureOperation = backUid.StencilFailureOperation, StencilFailureOperation = backUid.StencilFailureOperation,
DepthFailureOperation = backUid.DepthFailureOperation, DepthFailureOperation = backUid.DepthFailureOperation,
@ -47,7 +47,7 @@ namespace Ryujinx.Graphics.Metal
WriteMask = backUid.WriteMask WriteMask = backUid.WriteMask
}; };
var mtlDescriptor = new MTLDepthStencilDescriptor MTLDepthStencilDescriptor mtlDescriptor = new MTLDepthStencilDescriptor
{ {
DepthCompareFunction = descriptor.DepthCompareFunction, DepthCompareFunction = descriptor.DepthCompareFunction,
DepthWriteEnabled = descriptor.DepthWriteEnabled DepthWriteEnabled = descriptor.DepthWriteEnabled

View File

@ -165,7 +165,7 @@ namespace Ryujinx.Graphics.Metal
{ {
// Inherit render target related information without causing a render encoder split. // Inherit render target related information without causing a render encoder split.
var oldState = new RenderTargetCopy RenderTargetCopy oldState = new RenderTargetCopy
{ {
Scissors = other.Scissors, Scissors = other.Scissors,
RenderTargets = other.RenderTargets, RenderTargets = other.RenderTargets,
@ -180,7 +180,7 @@ namespace Ryujinx.Graphics.Metal
Pipeline.Internal.ColorBlendState = other.Pipeline.Internal.ColorBlendState; Pipeline.Internal.ColorBlendState = other.Pipeline.Internal.ColorBlendState;
Pipeline.DepthStencilFormat = other.Pipeline.DepthStencilFormat; Pipeline.DepthStencilFormat = other.Pipeline.DepthStencilFormat;
ref var blendStates = ref Pipeline.Internal.ColorBlendState; ref Array8<ColorBlendStateUid> blendStates = ref Pipeline.Internal.ColorBlendState;
// Mask out irrelevant attachments. // Mask out irrelevant attachments.
for (int i = 0; i < blendStates.Length; i++) for (int i = 0; i < blendStates.Length; i++)

View File

@ -1,4 +1,5 @@
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Common.Memory;
using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.Metal.State; using Ryujinx.Graphics.Metal.State;
using Ryujinx.Graphics.Shader; using Ryujinx.Graphics.Shader;
@ -124,21 +125,21 @@ namespace Ryujinx.Graphics.Metal
public readonly MTLRenderCommandEncoder CreateRenderCommandEncoder() public readonly MTLRenderCommandEncoder CreateRenderCommandEncoder()
{ {
// Initialise Pass & State // Initialise Pass & State
using var renderPassDescriptor = new MTLRenderPassDescriptor(); using MTLRenderPassDescriptor renderPassDescriptor = new MTLRenderPassDescriptor();
for (int i = 0; i < Constants.MaxColorAttachments; i++) for (int i = 0; i < Constants.MaxColorAttachments; i++)
{ {
if (_currentState.RenderTargets[i] is Texture tex) if (_currentState.RenderTargets[i] is Texture tex)
{ {
var passAttachment = renderPassDescriptor.ColorAttachments.Object((ulong)i); MTLRenderPassColorAttachmentDescriptor passAttachment = renderPassDescriptor.ColorAttachments.Object((ulong)i);
tex.PopulateRenderPassAttachment(passAttachment); tex.PopulateRenderPassAttachment(passAttachment);
passAttachment.LoadAction = _currentState.ClearLoadAction ? MTLLoadAction.Clear : MTLLoadAction.Load; passAttachment.LoadAction = _currentState.ClearLoadAction ? MTLLoadAction.Clear : MTLLoadAction.Load;
passAttachment.StoreAction = MTLStoreAction.Store; passAttachment.StoreAction = MTLStoreAction.Store;
} }
} }
var depthAttachment = renderPassDescriptor.DepthAttachment; MTLRenderPassDepthAttachmentDescriptor depthAttachment = renderPassDescriptor.DepthAttachment;
var stencilAttachment = renderPassDescriptor.StencilAttachment; MTLRenderPassStencilAttachmentDescriptor stencilAttachment = renderPassDescriptor.StencilAttachment;
if (_currentState.DepthStencil != null) if (_currentState.DepthStencil != null)
{ {
@ -177,15 +178,15 @@ namespace Ryujinx.Graphics.Metal
} }
// Initialise Encoder // Initialise Encoder
var renderCommandEncoder = _pipeline.CommandBuffer.RenderCommandEncoder(renderPassDescriptor); MTLRenderCommandEncoder renderCommandEncoder = _pipeline.CommandBuffer.RenderCommandEncoder(renderPassDescriptor);
return renderCommandEncoder; return renderCommandEncoder;
} }
public readonly MTLComputeCommandEncoder CreateComputeCommandEncoder() public readonly MTLComputeCommandEncoder CreateComputeCommandEncoder()
{ {
using var descriptor = new MTLComputePassDescriptor(); using MTLComputePassDescriptor descriptor = new MTLComputePassDescriptor();
var computeCommandEncoder = _pipeline.CommandBuffer.ComputeCommandEncoder(descriptor); MTLComputeCommandEncoder computeCommandEncoder = _pipeline.CommandBuffer.ComputeCommandEncoder(descriptor);
return computeCommandEncoder; return computeCommandEncoder;
} }
@ -292,17 +293,17 @@ namespace Ryujinx.Graphics.Metal
SetScissors(renderCommandEncoder); SetScissors(renderCommandEncoder);
} }
foreach (var resource in _currentState.RenderEncoderBindings.Resources) foreach (Resource resource in _currentState.RenderEncoderBindings.Resources)
{ {
renderCommandEncoder.UseResource(resource.MtlResource, resource.ResourceUsage, resource.Stages); renderCommandEncoder.UseResource(resource.MtlResource, resource.ResourceUsage, resource.Stages);
} }
foreach (var buffer in _currentState.RenderEncoderBindings.VertexBuffers) foreach (BufferResource buffer in _currentState.RenderEncoderBindings.VertexBuffers)
{ {
renderCommandEncoder.SetVertexBuffer(buffer.Buffer, buffer.Offset, buffer.Binding); renderCommandEncoder.SetVertexBuffer(buffer.Buffer, buffer.Offset, buffer.Binding);
} }
foreach (var buffer in _currentState.RenderEncoderBindings.FragmentBuffers) foreach (BufferResource buffer in _currentState.RenderEncoderBindings.FragmentBuffers)
{ {
renderCommandEncoder.SetFragmentBuffer(buffer.Buffer, buffer.Offset, buffer.Binding); renderCommandEncoder.SetFragmentBuffer(buffer.Buffer, buffer.Offset, buffer.Binding);
} }
@ -317,12 +318,12 @@ namespace Ryujinx.Graphics.Metal
SetComputePipelineState(computeCommandEncoder); SetComputePipelineState(computeCommandEncoder);
} }
foreach (var resource in _currentState.ComputeEncoderBindings.Resources) foreach (Resource resource in _currentState.ComputeEncoderBindings.Resources)
{ {
computeCommandEncoder.UseResource(resource.MtlResource, resource.ResourceUsage); computeCommandEncoder.UseResource(resource.MtlResource, resource.ResourceUsage);
} }
foreach (var buffer in _currentState.ComputeEncoderBindings.Buffers) foreach (BufferResource buffer in _currentState.ComputeEncoderBindings.Buffers)
{ {
computeCommandEncoder.SetBuffer(buffer.Buffer, buffer.Offset, buffer.Binding); computeCommandEncoder.SetBuffer(buffer.Buffer, buffer.Offset, buffer.Binding);
} }
@ -350,7 +351,7 @@ namespace Ryujinx.Graphics.Metal
return; return;
} }
var pipelineState = PipelineState.CreateComputePipeline(_device, _currentState.ComputeProgram); MTLComputePipelineState pipelineState = PipelineState.CreateComputePipeline(_device, _currentState.ComputeProgram);
computeCommandEncoder.SetComputePipelineState(pipelineState); computeCommandEncoder.SetComputePipelineState(pipelineState);
} }
@ -418,7 +419,7 @@ namespace Ryujinx.Graphics.Metal
public readonly void UpdateRenderTargetColorMasks(ReadOnlySpan<uint> componentMask) public readonly void UpdateRenderTargetColorMasks(ReadOnlySpan<uint> componentMask)
{ {
ref var blendState = ref _currentState.Pipeline.Internal.ColorBlendState; ref Array8<ColorBlendStateUid> blendState = ref _currentState.Pipeline.Internal.ColorBlendState;
for (int i = 0; i < componentMask.Length; i++) for (int i = 0; i < componentMask.Length; i++)
{ {
@ -427,7 +428,7 @@ namespace Ryujinx.Graphics.Metal
bool blue = (componentMask[i] & (0x1 << 2)) != 0; bool blue = (componentMask[i] & (0x1 << 2)) != 0;
bool alpha = (componentMask[i] & (0x1 << 3)) != 0; bool alpha = (componentMask[i] & (0x1 << 3)) != 0;
var mask = MTLColorWriteMask.None; MTLColorWriteMask mask = MTLColorWriteMask.None;
mask |= red ? MTLColorWriteMask.Red : 0; mask |= red ? MTLColorWriteMask.Red : 0;
mask |= green ? MTLColorWriteMask.Green : 0; mask |= green ? MTLColorWriteMask.Green : 0;
@ -480,7 +481,7 @@ namespace Ryujinx.Graphics.Metal
// Look for textures that are masked out. // Look for textures that are masked out.
ref PipelineState pipeline = ref _currentState.Pipeline; ref PipelineState pipeline = ref _currentState.Pipeline;
ref var blendState = ref pipeline.Internal.ColorBlendState; ref Array8<ColorBlendStateUid> blendState = ref pipeline.Internal.ColorBlendState;
pipeline.ColorBlendAttachmentStateCount = (uint)colors.Length; pipeline.ColorBlendAttachmentStateCount = (uint)colors.Length;
@ -491,7 +492,7 @@ namespace Ryujinx.Graphics.Metal
continue; continue;
} }
var mtlMask = blendState[i].WriteMask; MTLColorWriteMask mtlMask = blendState[i].WriteMask;
for (int j = 0; j < i; j++) for (int j = 0; j < i; j++)
{ {
@ -501,7 +502,7 @@ namespace Ryujinx.Graphics.Metal
{ {
// Prefer the binding with no write mask. // Prefer the binding with no write mask.
var mtlMask2 = blendState[j].WriteMask; MTLColorWriteMask mtlMask2 = blendState[j].WriteMask;
if (mtlMask == 0) if (mtlMask == 0)
{ {
@ -574,7 +575,7 @@ namespace Ryujinx.Graphics.Metal
public readonly void UpdateBlendDescriptors(int index, BlendDescriptor blend) public readonly void UpdateBlendDescriptors(int index, BlendDescriptor blend)
{ {
ref var blendState = ref _currentState.Pipeline.Internal.ColorBlendState[index]; ref ColorBlendStateUid blendState = ref _currentState.Pipeline.Internal.ColorBlendState[index];
blendState.Enable = blend.Enable; blendState.Enable = blend.Enable;
blendState.AlphaBlendOperation = blend.AlphaOp.Convert(); blendState.AlphaBlendOperation = blend.AlphaOp.Convert();
@ -687,7 +688,7 @@ namespace Ryujinx.Graphics.Metal
{ {
for (int i = 0; i < regions.Length; i++) for (int i = 0; i < regions.Length; i++)
{ {
var region = regions[i]; Rectangle<int> region = regions[i];
_currentState.Scissors[i] = new MTLScissorRect _currentState.Scissors[i] = new MTLScissorRect
{ {
@ -717,7 +718,7 @@ namespace Ryujinx.Graphics.Metal
for (int i = 0; i < viewports.Length; i++) for (int i = 0; i < viewports.Length; i++)
{ {
var viewport = viewports[i]; Viewport viewport = viewports[i];
// Y coordinate is inverted // Y coordinate is inverted
_currentState.Viewports[i] = new MTLViewport _currentState.Viewports[i] = new MTLViewport
{ {
@ -746,7 +747,7 @@ namespace Ryujinx.Graphics.Metal
{ {
if (i < vertexBuffers.Length) if (i < vertexBuffers.Length)
{ {
var vertexBuffer = vertexBuffers[i]; VertexBufferDescriptor vertexBuffer = vertexBuffers[i];
_currentState.VertexBuffers[i] = new VertexBufferState( _currentState.VertexBuffers[i] = new VertexBufferState(
vertexBuffer.Buffer.Handle, vertexBuffer.Buffer.Handle,
@ -771,7 +772,7 @@ namespace Ryujinx.Graphics.Metal
{ {
foreach (BufferAssignment assignment in buffers) foreach (BufferAssignment assignment in buffers)
{ {
var buffer = assignment.Range; BufferRange buffer = assignment.Range;
int index = assignment.Binding; int index = assignment.Binding;
Auto<DisposableBuffer> mtlBuffer = buffer.Handle == BufferHandle.Null Auto<DisposableBuffer> mtlBuffer = buffer.Handle == BufferHandle.Null
@ -788,7 +789,7 @@ namespace Ryujinx.Graphics.Metal
{ {
foreach (BufferAssignment assignment in buffers) foreach (BufferAssignment assignment in buffers)
{ {
var buffer = assignment.Range; BufferRange buffer = assignment.Range;
int index = assignment.Binding; int index = assignment.Binding;
Auto<DisposableBuffer> mtlBuffer = buffer.Handle == BufferHandle.Null Auto<DisposableBuffer> mtlBuffer = buffer.Handle == BufferHandle.Null
@ -805,7 +806,7 @@ namespace Ryujinx.Graphics.Metal
{ {
for (int i = 0; i < buffers.Length; i++) for (int i = 0; i < buffers.Length; i++)
{ {
var mtlBuffer = buffers[i]; Auto<DisposableBuffer> mtlBuffer = buffers[i];
int index = first + i; int index = first + i;
_currentState.StorageBufferRefs[index] = new BufferRef(mtlBuffer); _currentState.StorageBufferRefs[index] = new BufferRef(mtlBuffer);
@ -816,7 +817,7 @@ namespace Ryujinx.Graphics.Metal
public void UpdateCullMode(bool enable, Face face) public void UpdateCullMode(bool enable, Face face)
{ {
var dirtyScissor = (face == Face.FrontAndBack) != _currentState.CullBoth; bool dirtyScissor = (face == Face.FrontAndBack) != _currentState.CullBoth;
_currentState.CullMode = enable ? face.Convert() : MTLCullMode.None; _currentState.CullMode = enable ? face.Convert() : MTLCullMode.None;
_currentState.CullBoth = face == Face.FrontAndBack; _currentState.CullBoth = face == Face.FrontAndBack;
@ -980,7 +981,7 @@ namespace Ryujinx.Graphics.Metal
private unsafe void SetScissors(MTLRenderCommandEncoder renderCommandEncoder) private unsafe void SetScissors(MTLRenderCommandEncoder renderCommandEncoder)
{ {
var isTriangles = (_currentState.Topology == PrimitiveTopology.Triangles) || bool isTriangles = (_currentState.Topology == PrimitiveTopology.Triangles) ||
(_currentState.Topology == PrimitiveTopology.TriangleStrip); (_currentState.Topology == PrimitiveTopology.TriangleStrip);
if (_currentState.CullBoth && isTriangles) if (_currentState.CullBoth && isTriangles)
@ -1017,7 +1018,7 @@ namespace Ryujinx.Graphics.Metal
for (int i = 0; i < attribDescriptors.Length; i++) for (int i = 0; i < attribDescriptors.Length; i++)
{ {
ref var attrib = ref pipeline.Internal.VertexAttributes[i]; ref VertexInputAttributeUid attrib = ref pipeline.Internal.VertexAttributes[i];
if (attribDescriptors[i].IsZero) if (attribDescriptors[i].IsZero)
{ {
@ -1037,7 +1038,7 @@ namespace Ryujinx.Graphics.Metal
for (int i = 0; i < bufferDescriptors.Length; i++) for (int i = 0; i < bufferDescriptors.Length; i++)
{ {
ref var layout = ref pipeline.Internal.VertexBindings[i]; ref VertexInputLayoutUid layout = ref pipeline.Internal.VertexBindings[i];
if ((indexMask & (1u << i)) != 0) if ((indexMask & (1u << i)) != 0)
{ {
@ -1069,7 +1070,7 @@ namespace Ryujinx.Graphics.Metal
} }
} }
ref var zeroBufLayout = ref pipeline.Internal.VertexBindings[(int)Constants.ZeroBufferIndex]; ref VertexInputLayoutUid zeroBufLayout = ref pipeline.Internal.VertexBindings[(int)Constants.ZeroBufferIndex];
// Zero buffer // Zero buffer
if ((indexMask & (1u << (int)Constants.ZeroBufferIndex)) != 0) if ((indexMask & (1u << (int)Constants.ZeroBufferIndex)) != 0)
@ -1108,7 +1109,7 @@ namespace Ryujinx.Graphics.Metal
return; return;
} }
var zeroMtlBuffer = autoZeroBuffer.Get(_pipeline.Cbs).Value; MTLBuffer zeroMtlBuffer = autoZeroBuffer.Get(_pipeline.Cbs).Value;
bindings.VertexBuffers.Add(new BufferResource(zeroMtlBuffer, 0, Constants.ZeroBufferIndex)); bindings.VertexBuffers.Add(new BufferResource(zeroMtlBuffer, 0, Constants.ZeroBufferIndex));
} }
@ -1117,12 +1118,12 @@ namespace Ryujinx.Graphics.Metal
ulong gpuAddress = 0; ulong gpuAddress = 0;
IntPtr nativePtr = IntPtr.Zero; IntPtr nativePtr = IntPtr.Zero;
var range = buffer.Range; BufferRange? range = buffer.Range;
var autoBuffer = buffer.Buffer; Auto<DisposableBuffer> autoBuffer = buffer.Buffer;
if (autoBuffer != null) if (autoBuffer != null)
{ {
var offset = 0; int offset = 0;
MTLBuffer mtlBuffer; MTLBuffer mtlBuffer;
if (range.HasValue) if (range.HasValue)
@ -1144,7 +1145,7 @@ namespace Ryujinx.Graphics.Metal
private readonly (ulong gpuAddress, IntPtr nativePtr) AddressForTexture(ref TextureRef texture) private readonly (ulong gpuAddress, IntPtr nativePtr) AddressForTexture(ref TextureRef texture)
{ {
var storage = texture.Storage; TextureBase storage = texture.Storage;
ulong gpuAddress = 0; ulong gpuAddress = 0;
IntPtr nativePtr = IntPtr.Zero; IntPtr nativePtr = IntPtr.Zero;
@ -1156,7 +1157,7 @@ namespace Ryujinx.Graphics.Metal
textureBuffer.RebuildStorage(false); textureBuffer.RebuildStorage(false);
} }
var mtlTexture = storage.GetHandle(); MTLTexture mtlTexture = storage.GetHandle();
gpuAddress = mtlTexture.GpuResourceID._impl; gpuAddress = mtlTexture.GpuResourceID._impl;
nativePtr = mtlTexture.NativePtr; nativePtr = mtlTexture.NativePtr;
@ -1167,14 +1168,14 @@ namespace Ryujinx.Graphics.Metal
private readonly (ulong gpuAddress, IntPtr nativePtr) AddressForImage(ref ImageRef image) private readonly (ulong gpuAddress, IntPtr nativePtr) AddressForImage(ref ImageRef image)
{ {
var storage = image.Storage; Texture storage = image.Storage;
ulong gpuAddress = 0; ulong gpuAddress = 0;
IntPtr nativePtr = IntPtr.Zero; IntPtr nativePtr = IntPtr.Zero;
if (storage != null) if (storage != null)
{ {
var mtlTexture = storage.GetHandle(); MTLTexture mtlTexture = storage.GetHandle();
gpuAddress = mtlTexture.GpuResourceID._impl; gpuAddress = mtlTexture.GpuResourceID._impl;
nativePtr = mtlTexture.NativePtr; nativePtr = mtlTexture.NativePtr;
@ -1192,7 +1193,7 @@ namespace Ryujinx.Graphics.Metal
{ {
bufferTexture.RebuildStorage(false); bufferTexture.RebuildStorage(false);
var mtlTexture = bufferTexture.GetHandle(); MTLTexture mtlTexture = bufferTexture.GetHandle();
gpuAddress = mtlTexture.GpuResourceID._impl; gpuAddress = mtlTexture.GpuResourceID._impl;
nativePtr = mtlTexture.NativePtr; nativePtr = mtlTexture.NativePtr;
@ -1221,7 +1222,7 @@ namespace Ryujinx.Graphics.Metal
private readonly void UpdateAndBind(Program program, uint setIndex, ref readonly RenderEncoderBindings bindings) private readonly void UpdateAndBind(Program program, uint setIndex, ref readonly RenderEncoderBindings bindings)
{ {
var bindingSegments = program.BindingSegments[setIndex]; ResourceBindingSegment[] bindingSegments = program.BindingSegments[setIndex];
if (bindingSegments.Length == 0) if (bindingSegments.Length == 0)
{ {
@ -1244,8 +1245,8 @@ namespace Ryujinx.Graphics.Metal
Span<ulong> vertResourceIds = stackalloc ulong[program.ArgumentBufferSizes[setIndex]]; Span<ulong> vertResourceIds = stackalloc ulong[program.ArgumentBufferSizes[setIndex]];
Span<ulong> fragResourceIds = stackalloc ulong[program.FragArgumentBufferSizes[setIndex]]; Span<ulong> fragResourceIds = stackalloc ulong[program.FragArgumentBufferSizes[setIndex]];
var vertResourceIdIndex = 0; int vertResourceIdIndex = 0;
var fragResourceIdIndex = 0; int fragResourceIdIndex = 0;
foreach (ResourceBindingSegment segment in bindingSegments) foreach (ResourceBindingSegment segment in bindingSegments)
{ {
@ -1260,7 +1261,7 @@ namespace Ryujinx.Graphics.Metal
int index = binding + i; int index = binding + i;
ref BufferRef buffer = ref _currentState.UniformBufferRefs[index]; ref BufferRef buffer = ref _currentState.UniformBufferRefs[index];
var (gpuAddress, nativePtr) = AddressForBuffer(ref buffer); (ulong gpuAddress, IntPtr nativePtr) = AddressForBuffer(ref buffer);
MTLRenderStages renderStages = 0; MTLRenderStages renderStages = 0;
@ -1289,7 +1290,7 @@ namespace Ryujinx.Graphics.Metal
int index = binding + i; int index = binding + i;
ref BufferRef buffer = ref _currentState.StorageBufferRefs[index]; ref BufferRef buffer = ref _currentState.StorageBufferRefs[index];
var (gpuAddress, nativePtr) = AddressForBuffer(ref buffer); (ulong gpuAddress, IntPtr nativePtr) = AddressForBuffer(ref buffer);
MTLRenderStages renderStages = 0; MTLRenderStages renderStages = 0;
@ -1319,8 +1320,8 @@ namespace Ryujinx.Graphics.Metal
{ {
int index = binding + i; int index = binding + i;
ref var texture = ref _currentState.TextureRefs[index]; ref TextureRef texture = ref _currentState.TextureRefs[index];
var (gpuAddress, nativePtr) = AddressForTexture(ref texture); (ulong gpuAddress, IntPtr nativePtr) = AddressForTexture(ref texture);
MTLRenderStages renderStages = 0; MTLRenderStages renderStages = 0;
@ -1357,17 +1358,17 @@ namespace Ryujinx.Graphics.Metal
} }
else else
{ {
var textureArray = _currentState.TextureArrayRefs[binding].Array; TextureArray textureArray = _currentState.TextureArrayRefs[binding].Array;
if (segment.Type != ResourceType.BufferTexture) if (segment.Type != ResourceType.BufferTexture)
{ {
var textures = textureArray.GetTextureRefs(); TextureRef[] textures = textureArray.GetTextureRefs();
var samplers = new Auto<DisposableSampler>[textures.Length]; Auto<DisposableSampler>[] samplers = new Auto<DisposableSampler>[textures.Length];
for (int i = 0; i < textures.Length; i++) for (int i = 0; i < textures.Length; i++)
{ {
TextureRef texture = textures[i]; TextureRef texture = textures[i];
var (gpuAddress, nativePtr) = AddressForTexture(ref texture); (ulong gpuAddress, IntPtr nativePtr) = AddressForTexture(ref texture);
samplers[i] = texture.Sampler; samplers[i] = texture.Sampler;
@ -1392,7 +1393,7 @@ namespace Ryujinx.Graphics.Metal
AddResource(nativePtr, MTLResourceUsage.Read, renderStages, in bindings); AddResource(nativePtr, MTLResourceUsage.Read, renderStages, in bindings);
} }
foreach (var sampler in samplers) foreach (Auto<DisposableSampler> sampler in samplers)
{ {
ulong gpuAddress = 0; ulong gpuAddress = 0;
@ -1416,12 +1417,12 @@ namespace Ryujinx.Graphics.Metal
} }
else else
{ {
var bufferTextures = textureArray.GetBufferTextureRefs(); TextureBuffer[] bufferTextures = textureArray.GetBufferTextureRefs();
for (int i = 0; i < bufferTextures.Length; i++) for (int i = 0; i < bufferTextures.Length; i++)
{ {
TextureBuffer bufferTexture = bufferTextures[i]; TextureBuffer bufferTexture = bufferTextures[i];
var (gpuAddress, nativePtr) = AddressForTextureBuffer(ref bufferTexture); (ulong gpuAddress, IntPtr nativePtr) = AddressForTextureBuffer(ref bufferTexture);
MTLRenderStages renderStages = 0; MTLRenderStages renderStages = 0;
@ -1453,8 +1454,8 @@ namespace Ryujinx.Graphics.Metal
{ {
int index = binding + i; int index = binding + i;
ref var image = ref _currentState.ImageRefs[index]; ref ImageRef image = ref _currentState.ImageRefs[index];
var (gpuAddress, nativePtr) = AddressForImage(ref image); (ulong gpuAddress, IntPtr nativePtr) = AddressForImage(ref image);
MTLRenderStages renderStages = 0; MTLRenderStages renderStages = 0;
@ -1477,16 +1478,16 @@ namespace Ryujinx.Graphics.Metal
} }
else else
{ {
var imageArray = _currentState.ImageArrayRefs[binding].Array; ImageArray imageArray = _currentState.ImageArrayRefs[binding].Array;
if (segment.Type != ResourceType.BufferImage) if (segment.Type != ResourceType.BufferImage)
{ {
var images = imageArray.GetTextureRefs(); TextureRef[] images = imageArray.GetTextureRefs();
for (int i = 0; i < images.Length; i++) for (int i = 0; i < images.Length; i++)
{ {
TextureRef image = images[i]; TextureRef image = images[i];
var (gpuAddress, nativePtr) = AddressForTexture(ref image); (ulong gpuAddress, IntPtr nativePtr) = AddressForTexture(ref image);
MTLRenderStages renderStages = 0; MTLRenderStages renderStages = 0;
@ -1509,12 +1510,12 @@ namespace Ryujinx.Graphics.Metal
} }
else else
{ {
var bufferImages = imageArray.GetBufferTextureRefs(); TextureBuffer[] bufferImages = imageArray.GetBufferTextureRefs();
for (int i = 0; i < bufferImages.Length; i++) for (int i = 0; i < bufferImages.Length; i++)
{ {
TextureBuffer image = bufferImages[i]; TextureBuffer image = bufferImages[i];
var (gpuAddress, nativePtr) = AddressForTextureBuffer(ref image); (ulong gpuAddress, IntPtr nativePtr) = AddressForTextureBuffer(ref image);
MTLRenderStages renderStages = 0; MTLRenderStages renderStages = 0;
@ -1543,21 +1544,21 @@ namespace Ryujinx.Graphics.Metal
if (program.ArgumentBufferSizes[setIndex] > 0) if (program.ArgumentBufferSizes[setIndex] > 0)
{ {
vertArgBuffer.Holder.SetDataUnchecked(vertArgBuffer.Offset, MemoryMarshal.AsBytes(vertResourceIds)); vertArgBuffer.Holder.SetDataUnchecked(vertArgBuffer.Offset, MemoryMarshal.AsBytes(vertResourceIds));
var mtlVertArgBuffer = _bufferManager.GetBuffer(vertArgBuffer.Handle, false).Get(_pipeline.Cbs).Value; MTLBuffer mtlVertArgBuffer = _bufferManager.GetBuffer(vertArgBuffer.Handle, false).Get(_pipeline.Cbs).Value;
bindings.VertexBuffers.Add(new BufferResource(mtlVertArgBuffer, (uint)vertArgBuffer.Range.Offset, SetIndexToBindingIndex(setIndex))); bindings.VertexBuffers.Add(new BufferResource(mtlVertArgBuffer, (uint)vertArgBuffer.Range.Offset, SetIndexToBindingIndex(setIndex)));
} }
if (program.FragArgumentBufferSizes[setIndex] > 0) if (program.FragArgumentBufferSizes[setIndex] > 0)
{ {
fragArgBuffer.Holder.SetDataUnchecked(fragArgBuffer.Offset, MemoryMarshal.AsBytes(fragResourceIds)); fragArgBuffer.Holder.SetDataUnchecked(fragArgBuffer.Offset, MemoryMarshal.AsBytes(fragResourceIds));
var mtlFragArgBuffer = _bufferManager.GetBuffer(fragArgBuffer.Handle, false).Get(_pipeline.Cbs).Value; MTLBuffer mtlFragArgBuffer = _bufferManager.GetBuffer(fragArgBuffer.Handle, false).Get(_pipeline.Cbs).Value;
bindings.FragmentBuffers.Add(new BufferResource(mtlFragArgBuffer, (uint)fragArgBuffer.Range.Offset, SetIndexToBindingIndex(setIndex))); bindings.FragmentBuffers.Add(new BufferResource(mtlFragArgBuffer, (uint)fragArgBuffer.Range.Offset, SetIndexToBindingIndex(setIndex)));
} }
} }
private readonly void UpdateAndBind(Program program, uint setIndex, ref readonly ComputeEncoderBindings bindings) private readonly void UpdateAndBind(Program program, uint setIndex, ref readonly ComputeEncoderBindings bindings)
{ {
var bindingSegments = program.BindingSegments[setIndex]; ResourceBindingSegment[] bindingSegments = program.BindingSegments[setIndex];
if (bindingSegments.Length == 0) if (bindingSegments.Length == 0)
{ {
@ -1572,7 +1573,7 @@ namespace Ryujinx.Graphics.Metal
} }
Span<ulong> resourceIds = stackalloc ulong[program.ArgumentBufferSizes[setIndex]]; Span<ulong> resourceIds = stackalloc ulong[program.ArgumentBufferSizes[setIndex]];
var resourceIdIndex = 0; int resourceIdIndex = 0;
foreach (ResourceBindingSegment segment in bindingSegments) foreach (ResourceBindingSegment segment in bindingSegments)
{ {
@ -1587,7 +1588,7 @@ namespace Ryujinx.Graphics.Metal
int index = binding + i; int index = binding + i;
ref BufferRef buffer = ref _currentState.UniformBufferRefs[index]; ref BufferRef buffer = ref _currentState.UniformBufferRefs[index];
var (gpuAddress, nativePtr) = AddressForBuffer(ref buffer); (ulong gpuAddress, IntPtr nativePtr) = AddressForBuffer(ref buffer);
if ((segment.Stages & ResourceStages.Compute) != 0) if ((segment.Stages & ResourceStages.Compute) != 0)
{ {
@ -1604,7 +1605,7 @@ namespace Ryujinx.Graphics.Metal
int index = binding + i; int index = binding + i;
ref BufferRef buffer = ref _currentState.StorageBufferRefs[index]; ref BufferRef buffer = ref _currentState.StorageBufferRefs[index];
var (gpuAddress, nativePtr) = AddressForBuffer(ref buffer); (ulong gpuAddress, IntPtr nativePtr) = AddressForBuffer(ref buffer);
if ((segment.Stages & ResourceStages.Compute) != 0) if ((segment.Stages & ResourceStages.Compute) != 0)
{ {
@ -1621,8 +1622,8 @@ namespace Ryujinx.Graphics.Metal
{ {
int index = binding + i; int index = binding + i;
ref var texture = ref _currentState.TextureRefs[index]; ref TextureRef texture = ref _currentState.TextureRefs[index];
var (gpuAddress, nativePtr) = AddressForTexture(ref texture); (ulong gpuAddress, IntPtr nativePtr) = AddressForTexture(ref texture);
if ((segment.Stages & ResourceStages.Compute) != 0) if ((segment.Stages & ResourceStages.Compute) != 0)
{ {
@ -1640,17 +1641,17 @@ namespace Ryujinx.Graphics.Metal
} }
else else
{ {
var textureArray = _currentState.TextureArrayRefs[binding].Array; TextureArray textureArray = _currentState.TextureArrayRefs[binding].Array;
if (segment.Type != ResourceType.BufferTexture) if (segment.Type != ResourceType.BufferTexture)
{ {
var textures = textureArray.GetTextureRefs(); TextureRef[] textures = textureArray.GetTextureRefs();
var samplers = new Auto<DisposableSampler>[textures.Length]; Auto<DisposableSampler>[] samplers = new Auto<DisposableSampler>[textures.Length];
for (int i = 0; i < textures.Length; i++) for (int i = 0; i < textures.Length; i++)
{ {
TextureRef texture = textures[i]; TextureRef texture = textures[i];
var (gpuAddress, nativePtr) = AddressForTexture(ref texture); (ulong gpuAddress, IntPtr nativePtr) = AddressForTexture(ref texture);
if ((segment.Stages & ResourceStages.Compute) != 0) if ((segment.Stages & ResourceStages.Compute) != 0)
{ {
@ -1662,7 +1663,7 @@ namespace Ryujinx.Graphics.Metal
} }
} }
foreach (var sampler in samplers) foreach (Auto<DisposableSampler> sampler in samplers)
{ {
if (sampler != null) if (sampler != null)
{ {
@ -1673,12 +1674,12 @@ namespace Ryujinx.Graphics.Metal
} }
else else
{ {
var bufferTextures = textureArray.GetBufferTextureRefs(); TextureBuffer[] bufferTextures = textureArray.GetBufferTextureRefs();
for (int i = 0; i < bufferTextures.Length; i++) for (int i = 0; i < bufferTextures.Length; i++)
{ {
TextureBuffer bufferTexture = bufferTextures[i]; TextureBuffer bufferTexture = bufferTextures[i];
var (gpuAddress, nativePtr) = AddressForTextureBuffer(ref bufferTexture); (ulong gpuAddress, IntPtr nativePtr) = AddressForTextureBuffer(ref bufferTexture);
if ((segment.Stages & ResourceStages.Compute) != 0) if ((segment.Stages & ResourceStages.Compute) != 0)
{ {
@ -1697,8 +1698,8 @@ namespace Ryujinx.Graphics.Metal
{ {
int index = binding + i; int index = binding + i;
ref var image = ref _currentState.ImageRefs[index]; ref ImageRef image = ref _currentState.ImageRefs[index];
var (gpuAddress, nativePtr) = AddressForImage(ref image); (ulong gpuAddress, IntPtr nativePtr) = AddressForImage(ref image);
if ((segment.Stages & ResourceStages.Compute) != 0) if ((segment.Stages & ResourceStages.Compute) != 0)
{ {
@ -1710,16 +1711,16 @@ namespace Ryujinx.Graphics.Metal
} }
else else
{ {
var imageArray = _currentState.ImageArrayRefs[binding].Array; ImageArray imageArray = _currentState.ImageArrayRefs[binding].Array;
if (segment.Type != ResourceType.BufferImage) if (segment.Type != ResourceType.BufferImage)
{ {
var images = imageArray.GetTextureRefs(); TextureRef[] images = imageArray.GetTextureRefs();
for (int i = 0; i < images.Length; i++) for (int i = 0; i < images.Length; i++)
{ {
TextureRef image = images[i]; TextureRef image = images[i];
var (gpuAddress, nativePtr) = AddressForTexture(ref image); (ulong gpuAddress, IntPtr nativePtr) = AddressForTexture(ref image);
if ((segment.Stages & ResourceStages.Compute) != 0) if ((segment.Stages & ResourceStages.Compute) != 0)
{ {
@ -1731,12 +1732,12 @@ namespace Ryujinx.Graphics.Metal
} }
else else
{ {
var bufferImages = imageArray.GetBufferTextureRefs(); TextureBuffer[] bufferImages = imageArray.GetBufferTextureRefs();
for (int i = 0; i < bufferImages.Length; i++) for (int i = 0; i < bufferImages.Length; i++)
{ {
TextureBuffer image = bufferImages[i]; TextureBuffer image = bufferImages[i];
var (gpuAddress, nativePtr) = AddressForTextureBuffer(ref image); (ulong gpuAddress, IntPtr nativePtr) = AddressForTextureBuffer(ref image);
if ((segment.Stages & ResourceStages.Compute) != 0) if ((segment.Stages & ResourceStages.Compute) != 0)
{ {
@ -1754,7 +1755,7 @@ namespace Ryujinx.Graphics.Metal
if (program.ArgumentBufferSizes[setIndex] > 0) if (program.ArgumentBufferSizes[setIndex] > 0)
{ {
argBuffer.Holder.SetDataUnchecked(argBuffer.Offset, MemoryMarshal.AsBytes(resourceIds)); argBuffer.Holder.SetDataUnchecked(argBuffer.Offset, MemoryMarshal.AsBytes(resourceIds));
var mtlArgBuffer = _bufferManager.GetBuffer(argBuffer.Handle, false).Get(_pipeline.Cbs).Value; MTLBuffer mtlArgBuffer = _bufferManager.GetBuffer(argBuffer.Handle, false).Get(_pipeline.Cbs).Value;
bindings.Buffers.Add(new BufferResource(mtlArgBuffer, (uint)argBuffer.Range.Offset, SetIndexToBindingIndex(setIndex))); bindings.Buffers.Add(new BufferResource(mtlArgBuffer, (uint)argBuffer.Range.Offset, SetIndexToBindingIndex(setIndex)));
} }
} }

View File

@ -170,7 +170,7 @@ namespace Ryujinx.Graphics.Metal
public static MTLPixelFormat GetFormat(Format format) public static MTLPixelFormat GetFormat(Format format)
{ {
var mtlFormat = _table[(int)format]; MTLPixelFormat mtlFormat = _table[(int)format];
if (IsD24S8(format)) if (IsD24S8(format))
{ {

View File

@ -45,33 +45,33 @@ namespace Ryujinx.Graphics.Metal
public static string GetVendor() public static string GetVendor()
{ {
var serviceDict = IOServiceMatching("IOGPU"); IntPtr serviceDict = IOServiceMatching("IOGPU");
var service = IOServiceGetMatchingService(IntPtr.Zero, serviceDict); IntPtr service = IOServiceGetMatchingService(IntPtr.Zero, serviceDict);
var cfString = CFStringCreateWithCString(_kCFAllocatorDefault, "vendor-id", _kCFStringEncodingASCII); IntPtr cfString = CFStringCreateWithCString(_kCFAllocatorDefault, "vendor-id", _kCFStringEncodingASCII);
var cfProperty = IORegistryEntryCreateCFProperty(service, cfString, _kCFAllocatorDefault, 0); IntPtr cfProperty = IORegistryEntryCreateCFProperty(service, cfString, _kCFAllocatorDefault, 0);
byte[] buffer = new byte[4]; byte[] buffer = new byte[4];
var bufferPtr = CFDataGetBytePtr(cfProperty); IntPtr bufferPtr = CFDataGetBytePtr(cfProperty);
Marshal.Copy(bufferPtr, buffer, 0, buffer.Length); Marshal.Copy(bufferPtr, buffer, 0, buffer.Length);
var vendorId = BitConverter.ToUInt32(buffer); uint vendorId = BitConverter.ToUInt32(buffer);
return GetNameFromId(vendorId); return GetNameFromId(vendorId);
} }
public static string GetModel() public static string GetModel()
{ {
var serviceDict = IOServiceMatching("IOGPU"); IntPtr serviceDict = IOServiceMatching("IOGPU");
var service = IOServiceGetMatchingService(IntPtr.Zero, serviceDict); IntPtr service = IOServiceGetMatchingService(IntPtr.Zero, serviceDict);
var cfString = CFStringCreateWithCString(_kCFAllocatorDefault, "model", _kCFStringEncodingASCII); IntPtr cfString = CFStringCreateWithCString(_kCFAllocatorDefault, "model", _kCFStringEncodingASCII);
var cfProperty = IORegistryEntryCreateCFProperty(service, cfString, _kCFAllocatorDefault, 0); IntPtr cfProperty = IORegistryEntryCreateCFProperty(service, cfString, _kCFAllocatorDefault, 0);
char[] buffer = new char[64]; char[] buffer = new char[64];
IntPtr bufferPtr = Marshal.AllocHGlobal(buffer.Length); IntPtr bufferPtr = Marshal.AllocHGlobal(buffer.Length);
if (CFStringGetCString(cfProperty, bufferPtr, buffer.Length, _kCFStringEncodingASCII)) if (CFStringGetCString(cfProperty, bufferPtr, buffer.Length, _kCFStringEncodingASCII))
{ {
var model = Marshal.PtrToStringUTF8(bufferPtr); string model = Marshal.PtrToStringUTF8(bufferPtr);
Marshal.FreeHGlobal(bufferPtr); Marshal.FreeHGlobal(bufferPtr);
return model; return model;
} }

View File

@ -65,7 +65,7 @@ namespace Ryujinx.Graphics.Metal
public void Add(ref TKey key, TValue value) public void Add(ref TKey key, TValue value)
{ {
var entry = new Entry Entry entry = new()
{ {
Hash = key.GetHashCode(), Hash = key.GetHashCode(),
Key = key, Key = key,
@ -75,7 +75,7 @@ namespace Ryujinx.Graphics.Metal
int hashCode = key.GetHashCode(); int hashCode = key.GetHashCode();
int bucketIndex = hashCode & TotalBucketsMask; int bucketIndex = hashCode & TotalBucketsMask;
ref var bucket = ref _hashTable[bucketIndex]; ref Bucket bucket = ref _hashTable[bucketIndex];
if (bucket.Entries != null) if (bucket.Entries != null)
{ {
int index = bucket.Length; int index = bucket.Length;
@ -102,11 +102,11 @@ namespace Ryujinx.Graphics.Metal
{ {
int hashCode = key.GetHashCode(); int hashCode = key.GetHashCode();
ref var bucket = ref _hashTable[hashCode & TotalBucketsMask]; ref Bucket bucket = ref _hashTable[hashCode & TotalBucketsMask];
var entries = bucket.AsSpan(); Span<Entry> entries = bucket.AsSpan();
for (int i = 0; i < entries.Length; i++) for (int i = 0; i < entries.Length; i++)
{ {
ref var entry = ref entries[i]; ref Entry entry = ref entries[i];
if (entry.Hash == hashCode && entry.Key.Equals(ref key)) if (entry.Hash == hashCode && entry.Key.Equals(ref key))
{ {
@ -124,10 +124,10 @@ namespace Ryujinx.Graphics.Metal
{ {
int hashCode = key.GetHashCode(); int hashCode = key.GetHashCode();
var entries = _hashTable[hashCode & TotalBucketsMask].AsSpan(); Span<Entry> entries = _hashTable[hashCode & TotalBucketsMask].AsSpan();
for (int i = 0; i < entries.Length; i++) for (int i = 0; i < entries.Length; i++)
{ {
ref var entry = ref entries[i]; ref Entry entry = ref entries[i];
if (entry.Hash == hashCode && entry.Key.Equals(ref key)) if (entry.Hash == hashCode && entry.Key.Equals(ref key))
{ {

View File

@ -50,58 +50,58 @@ namespace Ryujinx.Graphics.Metal
_samplerNearest = new SamplerHolder(renderer, _device, SamplerCreateInfo.Create(MinFilter.Nearest, MagFilter.Nearest)); _samplerNearest = new SamplerHolder(renderer, _device, SamplerCreateInfo.Create(MinFilter.Nearest, MagFilter.Nearest));
_samplerLinear = new SamplerHolder(renderer, _device, SamplerCreateInfo.Create(MinFilter.Linear, MagFilter.Linear)); _samplerLinear = new SamplerHolder(renderer, _device, SamplerCreateInfo.Create(MinFilter.Linear, MagFilter.Linear));
var blitResourceLayout = new ResourceLayoutBuilder() ResourceLayout blitResourceLayout = new ResourceLayoutBuilder()
.Add(ResourceStages.Vertex, ResourceType.UniformBuffer, 0) .Add(ResourceStages.Vertex, ResourceType.UniformBuffer, 0)
.Add(ResourceStages.Fragment, ResourceType.TextureAndSampler, 0).Build(); .Add(ResourceStages.Fragment, ResourceType.TextureAndSampler, 0).Build();
var blitSource = ReadMsl("Blit.metal"); string blitSource = ReadMsl("Blit.metal");
var blitSourceF = blitSource.Replace("FORMAT", "float", StringComparison.Ordinal); string blitSourceF = blitSource.Replace("FORMAT", "float", StringComparison.Ordinal);
_programColorBlitF = new Program(renderer, device, [ _programColorBlitF = new Program(renderer, device, [
new ShaderSource(blitSourceF, ShaderStage.Fragment, TargetLanguage.Msl), new ShaderSource(blitSourceF, ShaderStage.Fragment, TargetLanguage.Msl),
new ShaderSource(blitSourceF, ShaderStage.Vertex, TargetLanguage.Msl) new ShaderSource(blitSourceF, ShaderStage.Vertex, TargetLanguage.Msl)
], blitResourceLayout); ], blitResourceLayout);
var blitSourceI = blitSource.Replace("FORMAT", "int"); string blitSourceI = blitSource.Replace("FORMAT", "int");
_programColorBlitI = new Program(renderer, device, [ _programColorBlitI = new Program(renderer, device, [
new ShaderSource(blitSourceI, ShaderStage.Fragment, TargetLanguage.Msl), new ShaderSource(blitSourceI, ShaderStage.Fragment, TargetLanguage.Msl),
new ShaderSource(blitSourceI, ShaderStage.Vertex, TargetLanguage.Msl) new ShaderSource(blitSourceI, ShaderStage.Vertex, TargetLanguage.Msl)
], blitResourceLayout); ], blitResourceLayout);
var blitSourceU = blitSource.Replace("FORMAT", "uint"); string blitSourceU = blitSource.Replace("FORMAT", "uint");
_programColorBlitU = new Program(renderer, device, [ _programColorBlitU = new Program(renderer, device, [
new ShaderSource(blitSourceU, ShaderStage.Fragment, TargetLanguage.Msl), new ShaderSource(blitSourceU, ShaderStage.Fragment, TargetLanguage.Msl),
new ShaderSource(blitSourceU, ShaderStage.Vertex, TargetLanguage.Msl) new ShaderSource(blitSourceU, ShaderStage.Vertex, TargetLanguage.Msl)
], blitResourceLayout); ], blitResourceLayout);
var blitMsSource = ReadMsl("BlitMs.metal"); string blitMsSource = ReadMsl("BlitMs.metal");
var blitMsSourceF = blitMsSource.Replace("FORMAT", "float"); string blitMsSourceF = blitMsSource.Replace("FORMAT", "float");
_programColorBlitMsF = new Program(renderer, device, [ _programColorBlitMsF = new Program(renderer, device, [
new ShaderSource(blitMsSourceF, ShaderStage.Fragment, TargetLanguage.Msl), new ShaderSource(blitMsSourceF, ShaderStage.Fragment, TargetLanguage.Msl),
new ShaderSource(blitMsSourceF, ShaderStage.Vertex, TargetLanguage.Msl) new ShaderSource(blitMsSourceF, ShaderStage.Vertex, TargetLanguage.Msl)
], blitResourceLayout); ], blitResourceLayout);
var blitMsSourceI = blitMsSource.Replace("FORMAT", "int"); string blitMsSourceI = blitMsSource.Replace("FORMAT", "int");
_programColorBlitMsI = new Program(renderer, device, [ _programColorBlitMsI = new Program(renderer, device, [
new ShaderSource(blitMsSourceI, ShaderStage.Fragment, TargetLanguage.Msl), new ShaderSource(blitMsSourceI, ShaderStage.Fragment, TargetLanguage.Msl),
new ShaderSource(blitMsSourceI, ShaderStage.Vertex, TargetLanguage.Msl) new ShaderSource(blitMsSourceI, ShaderStage.Vertex, TargetLanguage.Msl)
], blitResourceLayout); ], blitResourceLayout);
var blitMsSourceU = blitMsSource.Replace("FORMAT", "uint"); string blitMsSourceU = blitMsSource.Replace("FORMAT", "uint");
_programColorBlitMsU = new Program(renderer, device, [ _programColorBlitMsU = new Program(renderer, device, [
new ShaderSource(blitMsSourceU, ShaderStage.Fragment, TargetLanguage.Msl), new ShaderSource(blitMsSourceU, ShaderStage.Fragment, TargetLanguage.Msl),
new ShaderSource(blitMsSourceU, ShaderStage.Vertex, TargetLanguage.Msl) new ShaderSource(blitMsSourceU, ShaderStage.Vertex, TargetLanguage.Msl)
], blitResourceLayout); ], blitResourceLayout);
var colorClearResourceLayout = new ResourceLayoutBuilder() ResourceLayout colorClearResourceLayout = new ResourceLayoutBuilder()
.Add(ResourceStages.Fragment, ResourceType.UniformBuffer, 0).Build(); .Add(ResourceStages.Fragment, ResourceType.UniformBuffer, 0).Build();
var colorClearSource = ReadMsl("ColorClear.metal"); string colorClearSource = ReadMsl("ColorClear.metal");
for (int i = 0; i < Constants.MaxColorAttachments; i++) for (int i = 0; i < Constants.MaxColorAttachments; i++)
{ {
var crntSource = colorClearSource.Replace("COLOR_ATTACHMENT_INDEX", i.ToString()).Replace("FORMAT", "float"); string crntSource = colorClearSource.Replace("COLOR_ATTACHMENT_INDEX", i.ToString()).Replace("FORMAT", "float");
_programsColorClearF.Add(new Program(renderer, device, [ _programsColorClearF.Add(new Program(renderer, device, [
new ShaderSource(crntSource, ShaderStage.Fragment, TargetLanguage.Msl), new ShaderSource(crntSource, ShaderStage.Fragment, TargetLanguage.Msl),
new ShaderSource(crntSource, ShaderStage.Vertex, TargetLanguage.Msl) new ShaderSource(crntSource, ShaderStage.Vertex, TargetLanguage.Msl)
@ -110,7 +110,7 @@ namespace Ryujinx.Graphics.Metal
for (int i = 0; i < Constants.MaxColorAttachments; i++) for (int i = 0; i < Constants.MaxColorAttachments; i++)
{ {
var crntSource = colorClearSource.Replace("COLOR_ATTACHMENT_INDEX", i.ToString()).Replace("FORMAT", "int"); string crntSource = colorClearSource.Replace("COLOR_ATTACHMENT_INDEX", i.ToString()).Replace("FORMAT", "int");
_programsColorClearI.Add(new Program(renderer, device, [ _programsColorClearI.Add(new Program(renderer, device, [
new ShaderSource(crntSource, ShaderStage.Fragment, TargetLanguage.Msl), new ShaderSource(crntSource, ShaderStage.Fragment, TargetLanguage.Msl),
new ShaderSource(crntSource, ShaderStage.Vertex, TargetLanguage.Msl) new ShaderSource(crntSource, ShaderStage.Vertex, TargetLanguage.Msl)
@ -119,68 +119,68 @@ namespace Ryujinx.Graphics.Metal
for (int i = 0; i < Constants.MaxColorAttachments; i++) for (int i = 0; i < Constants.MaxColorAttachments; i++)
{ {
var crntSource = colorClearSource.Replace("COLOR_ATTACHMENT_INDEX", i.ToString()).Replace("FORMAT", "uint"); string crntSource = colorClearSource.Replace("COLOR_ATTACHMENT_INDEX", i.ToString()).Replace("FORMAT", "uint");
_programsColorClearU.Add(new Program(renderer, device, [ _programsColorClearU.Add(new Program(renderer, device, [
new ShaderSource(crntSource, ShaderStage.Fragment, TargetLanguage.Msl), new ShaderSource(crntSource, ShaderStage.Fragment, TargetLanguage.Msl),
new ShaderSource(crntSource, ShaderStage.Vertex, TargetLanguage.Msl) new ShaderSource(crntSource, ShaderStage.Vertex, TargetLanguage.Msl)
], colorClearResourceLayout)); ], colorClearResourceLayout));
} }
var depthStencilClearSource = ReadMsl("DepthStencilClear.metal"); string depthStencilClearSource = ReadMsl("DepthStencilClear.metal");
_programDepthStencilClear = new Program(renderer, device, [ _programDepthStencilClear = new Program(renderer, device, [
new ShaderSource(depthStencilClearSource, ShaderStage.Fragment, TargetLanguage.Msl), new ShaderSource(depthStencilClearSource, ShaderStage.Fragment, TargetLanguage.Msl),
new ShaderSource(depthStencilClearSource, ShaderStage.Vertex, TargetLanguage.Msl) new ShaderSource(depthStencilClearSource, ShaderStage.Vertex, TargetLanguage.Msl)
], colorClearResourceLayout); ], colorClearResourceLayout);
var strideChangeResourceLayout = new ResourceLayoutBuilder() ResourceLayout strideChangeResourceLayout = new ResourceLayoutBuilder()
.Add(ResourceStages.Compute, ResourceType.UniformBuffer, 0) .Add(ResourceStages.Compute, ResourceType.UniformBuffer, 0)
.Add(ResourceStages.Compute, ResourceType.StorageBuffer, 1) .Add(ResourceStages.Compute, ResourceType.StorageBuffer, 1)
.Add(ResourceStages.Compute, ResourceType.StorageBuffer, 2, true).Build(); .Add(ResourceStages.Compute, ResourceType.StorageBuffer, 2, true).Build();
var strideChangeSource = ReadMsl("ChangeBufferStride.metal"); string strideChangeSource = ReadMsl("ChangeBufferStride.metal");
_programStrideChange = new Program(renderer, device, [ _programStrideChange = new Program(renderer, device, [
new ShaderSource(strideChangeSource, ShaderStage.Compute, TargetLanguage.Msl) new ShaderSource(strideChangeSource, ShaderStage.Compute, TargetLanguage.Msl)
], strideChangeResourceLayout, new ComputeSize(64, 1, 1)); ], strideChangeResourceLayout, new ComputeSize(64, 1, 1));
var convertD32S8ToD24S8ResourceLayout = new ResourceLayoutBuilder() ResourceLayout convertD32S8ToD24S8ResourceLayout = new ResourceLayoutBuilder()
.Add(ResourceStages.Compute, ResourceType.UniformBuffer, 0) .Add(ResourceStages.Compute, ResourceType.UniformBuffer, 0)
.Add(ResourceStages.Compute, ResourceType.StorageBuffer, 1) .Add(ResourceStages.Compute, ResourceType.StorageBuffer, 1)
.Add(ResourceStages.Compute, ResourceType.StorageBuffer, 2, true).Build(); .Add(ResourceStages.Compute, ResourceType.StorageBuffer, 2, true).Build();
var convertD32S8ToD24S8Source = ReadMsl("ConvertD32S8ToD24S8.metal"); string convertD32S8ToD24S8Source = ReadMsl("ConvertD32S8ToD24S8.metal");
_programConvertD32S8ToD24S8 = new Program(renderer, device, [ _programConvertD32S8ToD24S8 = new Program(renderer, device, [
new ShaderSource(convertD32S8ToD24S8Source, ShaderStage.Compute, TargetLanguage.Msl) new ShaderSource(convertD32S8ToD24S8Source, ShaderStage.Compute, TargetLanguage.Msl)
], convertD32S8ToD24S8ResourceLayout, new ComputeSize(64, 1, 1)); ], convertD32S8ToD24S8ResourceLayout, new ComputeSize(64, 1, 1));
var convertIndexBufferLayout = new ResourceLayoutBuilder() ResourceLayout convertIndexBufferLayout = new ResourceLayoutBuilder()
.Add(ResourceStages.Compute, ResourceType.StorageBuffer, 1) .Add(ResourceStages.Compute, ResourceType.StorageBuffer, 1)
.Add(ResourceStages.Compute, ResourceType.StorageBuffer, 2, true) .Add(ResourceStages.Compute, ResourceType.StorageBuffer, 2, true)
.Add(ResourceStages.Compute, ResourceType.StorageBuffer, 3).Build(); .Add(ResourceStages.Compute, ResourceType.StorageBuffer, 3).Build();
var convertIndexBufferSource = ReadMsl("ConvertIndexBuffer.metal"); string convertIndexBufferSource = ReadMsl("ConvertIndexBuffer.metal");
_programConvertIndexBuffer = new Program(renderer, device, [ _programConvertIndexBuffer = new Program(renderer, device, [
new ShaderSource(convertIndexBufferSource, ShaderStage.Compute, TargetLanguage.Msl) new ShaderSource(convertIndexBufferSource, ShaderStage.Compute, TargetLanguage.Msl)
], convertIndexBufferLayout, new ComputeSize(16, 1, 1)); ], convertIndexBufferLayout, new ComputeSize(16, 1, 1));
var depthBlitSource = ReadMsl("DepthBlit.metal"); string depthBlitSource = ReadMsl("DepthBlit.metal");
_programDepthBlit = new Program(renderer, device, [ _programDepthBlit = new Program(renderer, device, [
new ShaderSource(depthBlitSource, ShaderStage.Fragment, TargetLanguage.Msl), new ShaderSource(depthBlitSource, ShaderStage.Fragment, TargetLanguage.Msl),
new ShaderSource(blitSourceF, ShaderStage.Vertex, TargetLanguage.Msl) new ShaderSource(blitSourceF, ShaderStage.Vertex, TargetLanguage.Msl)
], blitResourceLayout); ], blitResourceLayout);
var depthBlitMsSource = ReadMsl("DepthBlitMs.metal"); string depthBlitMsSource = ReadMsl("DepthBlitMs.metal");
_programDepthBlitMs = new Program(renderer, device, [ _programDepthBlitMs = new Program(renderer, device, [
new ShaderSource(depthBlitMsSource, ShaderStage.Fragment, TargetLanguage.Msl), new ShaderSource(depthBlitMsSource, ShaderStage.Fragment, TargetLanguage.Msl),
new ShaderSource(blitSourceF, ShaderStage.Vertex, TargetLanguage.Msl) new ShaderSource(blitSourceF, ShaderStage.Vertex, TargetLanguage.Msl)
], blitResourceLayout); ], blitResourceLayout);
var stencilBlitSource = ReadMsl("StencilBlit.metal"); string stencilBlitSource = ReadMsl("StencilBlit.metal");
_programStencilBlit = new Program(renderer, device, [ _programStencilBlit = new Program(renderer, device, [
new ShaderSource(stencilBlitSource, ShaderStage.Fragment, TargetLanguage.Msl), new ShaderSource(stencilBlitSource, ShaderStage.Fragment, TargetLanguage.Msl),
new ShaderSource(blitSourceF, ShaderStage.Vertex, TargetLanguage.Msl) new ShaderSource(blitSourceF, ShaderStage.Vertex, TargetLanguage.Msl)
], blitResourceLayout); ], blitResourceLayout);
var stencilBlitMsSource = ReadMsl("StencilBlitMs.metal"); string stencilBlitMsSource = ReadMsl("StencilBlitMs.metal");
_programStencilBlitMs = new Program(renderer, device, [ _programStencilBlitMs = new Program(renderer, device, [
new ShaderSource(stencilBlitMsSource, ShaderStage.Fragment, TargetLanguage.Msl), new ShaderSource(stencilBlitMsSource, ShaderStage.Fragment, TargetLanguage.Msl),
new ShaderSource(blitSourceF, ShaderStage.Vertex, TargetLanguage.Msl) new ShaderSource(blitSourceF, ShaderStage.Vertex, TargetLanguage.Msl)
@ -189,7 +189,7 @@ namespace Ryujinx.Graphics.Metal
private static string ReadMsl(string fileName) private static string ReadMsl(string fileName)
{ {
var msl = EmbeddedResources.ReadAllText(string.Join('/', ShadersSourcePath, fileName)); string msl = EmbeddedResources.ReadAllText(string.Join('/', ShadersSourcePath, fileName));
#pragma warning disable IDE0055 // Disable formatting #pragma warning disable IDE0055 // Disable formatting
msl = msl.Replace("CONSTANT_BUFFERS_INDEX", $"{Constants.ConstantBuffersIndex}") msl = msl.Replace("CONSTANT_BUFFERS_INDEX", $"{Constants.ConstantBuffersIndex}")
@ -214,7 +214,7 @@ namespace Ryujinx.Graphics.Metal
const int RegionBufferSize = 16; const int RegionBufferSize = 16;
var sampler = linearFilter ? _samplerLinear : _samplerNearest; ISampler sampler = linearFilter ? _samplerLinear : _samplerNearest;
_pipeline.SetTextureAndSampler(ShaderStage.Fragment, 0, src, sampler); _pipeline.SetTextureAndSampler(ShaderStage.Fragment, 0, src, sampler);
@ -235,11 +235,11 @@ namespace Ryujinx.Graphics.Metal
(region[2], region[3]) = (region[3], region[2]); (region[2], region[3]) = (region[3], region[2]);
} }
using var buffer = _renderer.BufferManager.ReserveOrCreate(cbs, RegionBufferSize); using ScopedTemporaryBuffer buffer = _renderer.BufferManager.ReserveOrCreate(cbs, RegionBufferSize);
buffer.Holder.SetDataUnchecked<float>(buffer.Offset, region); buffer.Holder.SetDataUnchecked<float>(buffer.Offset, region);
_pipeline.SetUniformBuffers([new BufferAssignment(0, buffer.Range)]); _pipeline.SetUniformBuffers([new BufferAssignment(0, buffer.Range)]);
var rect = new Rectangle<float>( Rectangle<float> rect = new Rectangle<float>(
MathF.Min(dstRegion.X1, dstRegion.X2), MathF.Min(dstRegion.X1, dstRegion.X2),
MathF.Min(dstRegion.Y1, dstRegion.Y2), MathF.Min(dstRegion.Y1, dstRegion.Y2),
MathF.Abs(dstRegion.X2 - dstRegion.X1), MathF.Abs(dstRegion.X2 - dstRegion.X1),
@ -266,7 +266,7 @@ namespace Ryujinx.Graphics.Metal
return; return;
} }
var debugGroupName = "Blit Color "; string debugGroupName = "Blit Color ";
if (src.Info.Target.IsMultisample()) if (src.Info.Target.IsMultisample())
{ {
@ -359,13 +359,13 @@ namespace Ryujinx.Graphics.Metal
(region[2], region[3]) = (region[3], region[2]); (region[2], region[3]) = (region[3], region[2]);
} }
using var buffer = _renderer.BufferManager.ReserveOrCreate(cbs, RegionBufferSize); using ScopedTemporaryBuffer buffer = _renderer.BufferManager.ReserveOrCreate(cbs, RegionBufferSize);
buffer.Holder.SetDataUnchecked<float>(buffer.Offset, region); buffer.Holder.SetDataUnchecked<float>(buffer.Offset, region);
_pipeline.SetUniformBuffers([new BufferAssignment(0, buffer.Range)]); _pipeline.SetUniformBuffers([new BufferAssignment(0, buffer.Range)]);
Span<Viewport> viewports = stackalloc Viewport[16]; Span<Viewport> viewports = stackalloc Viewport[16];
var rect = new Rectangle<float>( Rectangle<float> rect = new Rectangle<float>(
MathF.Min(dstRegion.X1, dstRegion.X2), MathF.Min(dstRegion.X1, dstRegion.X2),
MathF.Min(dstRegion.Y1, dstRegion.Y2), MathF.Min(dstRegion.Y1, dstRegion.Y2),
MathF.Abs(dstRegion.X2 - dstRegion.X1), MathF.Abs(dstRegion.X2 - dstRegion.X1),
@ -400,7 +400,7 @@ namespace Ryujinx.Graphics.Metal
Format.D32FloatS8Uint or Format.D32FloatS8Uint or
Format.S8UintD24Unorm) Format.S8UintD24Unorm)
{ {
var depthTexture = CreateDepthOrStencilView(src, DepthStencilMode.Depth); Texture depthTexture = CreateDepthOrStencilView(src, DepthStencilMode.Depth);
BlitDepthStencilDraw(depthTexture, isDepth: true); BlitDepthStencilDraw(depthTexture, isDepth: true);
@ -416,7 +416,7 @@ namespace Ryujinx.Graphics.Metal
Format.D32FloatS8Uint or Format.D32FloatS8Uint or
Format.S8UintD24Unorm) Format.S8UintD24Unorm)
{ {
var stencilTexture = CreateDepthOrStencilView(src, DepthStencilMode.Stencil); Texture stencilTexture = CreateDepthOrStencilView(src, DepthStencilMode.Stencil);
BlitDepthStencilDraw(stencilTexture, isDepth: false); BlitDepthStencilDraw(stencilTexture, isDepth: false);
@ -494,7 +494,7 @@ namespace Ryujinx.Graphics.Metal
Extents2DF dstRegion) Extents2DF dstRegion)
{ {
// Save current state // Save current state
var state = _pipeline.SavePredrawState(); PredrawState state = _pipeline.SavePredrawState();
_pipeline.SetFaceCulling(false, Face.Front); _pipeline.SetFaceCulling(false, Face.Front);
_pipeline.SetStencilTest(new StencilTestDescriptor()); _pipeline.SetStencilTest(new StencilTestDescriptor());
@ -521,13 +521,13 @@ namespace Ryujinx.Graphics.Metal
(region[2], region[3]) = (region[3], region[2]); (region[2], region[3]) = (region[3], region[2]);
} }
var bufferHandle = _renderer.BufferManager.CreateWithHandle(RegionBufferSize); BufferHandle bufferHandle = _renderer.BufferManager.CreateWithHandle(RegionBufferSize);
_renderer.BufferManager.SetData<float>(bufferHandle, 0, region); _renderer.BufferManager.SetData<float>(bufferHandle, 0, region);
_pipeline.SetUniformBuffers([new BufferAssignment(0, new BufferRange(bufferHandle, 0, RegionBufferSize))]); _pipeline.SetUniformBuffers([new BufferAssignment(0, new BufferRange(bufferHandle, 0, RegionBufferSize))]);
Span<Viewport> viewports = stackalloc Viewport[16]; Span<Viewport> viewports = stackalloc Viewport[16];
var rect = new Rectangle<float>( Rectangle<float> rect = new Rectangle<float>(
MathF.Min(dstRegion.X1, dstRegion.X2), MathF.Min(dstRegion.X1, dstRegion.X2),
MathF.Min(dstRegion.Y1, dstRegion.Y2), MathF.Min(dstRegion.Y1, dstRegion.Y2),
MathF.Abs(dstRegion.X2 - dstRegion.X1), MathF.Abs(dstRegion.X2 - dstRegion.X1),
@ -569,8 +569,8 @@ namespace Ryujinx.Graphics.Metal
{ {
int elems = size / stride; int elems = size / stride;
var srcBuffer = src.GetBuffer(); Auto<DisposableBuffer> srcBuffer = src.GetBuffer();
var dstBuffer = dst.GetBuffer(); Auto<DisposableBuffer> dstBuffer = dst.GetBuffer();
const int ParamsBufferSize = 4 * sizeof(int); const int ParamsBufferSize = 4 * sizeof(int);
@ -584,7 +584,7 @@ namespace Ryujinx.Graphics.Metal
shaderParams[2] = size; shaderParams[2] = size;
shaderParams[3] = srcOffset; shaderParams[3] = srcOffset;
using var buffer = _renderer.BufferManager.ReserveOrCreate(cbs, ParamsBufferSize); using ScopedTemporaryBuffer buffer = _renderer.BufferManager.ReserveOrCreate(cbs, ParamsBufferSize);
buffer.Holder.SetDataUnchecked<int>(buffer.Offset, shaderParams); buffer.Holder.SetDataUnchecked<int>(buffer.Offset, shaderParams);
_pipeline.SetUniformBuffers([new BufferAssignment(0, buffer.Range)]); _pipeline.SetUniformBuffers([new BufferAssignment(0, buffer.Range)]);
@ -605,7 +605,7 @@ namespace Ryujinx.Graphics.Metal
{ {
int inSize = pixelCount * 2 * sizeof(int); int inSize = pixelCount * 2 * sizeof(int);
var srcBuffer = src.GetBuffer(); Auto<DisposableBuffer> srcBuffer = src.GetBuffer();
const int ParamsBufferSize = sizeof(int) * 2; const int ParamsBufferSize = sizeof(int) * 2;
@ -617,7 +617,7 @@ namespace Ryujinx.Graphics.Metal
shaderParams[0] = pixelCount; shaderParams[0] = pixelCount;
shaderParams[1] = dstOffset; shaderParams[1] = dstOffset;
using var buffer = _renderer.BufferManager.ReserveOrCreate(cbs, ParamsBufferSize); using ScopedTemporaryBuffer buffer = _renderer.BufferManager.ReserveOrCreate(cbs, ParamsBufferSize);
buffer.Holder.SetDataUnchecked<int>(buffer.Offset, shaderParams); buffer.Holder.SetDataUnchecked<int>(buffer.Offset, shaderParams);
_pipeline.SetUniformBuffers([new BufferAssignment(0, buffer.Range)]); _pipeline.SetUniformBuffers([new BufferAssignment(0, buffer.Range)]);
@ -648,8 +648,8 @@ namespace Ryujinx.Graphics.Metal
int primitiveCount = pattern.GetPrimitiveCount(indexCount); int primitiveCount = pattern.GetPrimitiveCount(indexCount);
int outputIndexSize = 4; int outputIndexSize = 4;
var srcBuffer = src.GetBuffer(); Auto<DisposableBuffer> srcBuffer = src.GetBuffer();
var dstBuffer = dst.GetBuffer(); Auto<DisposableBuffer> dstBuffer = dst.GetBuffer();
const int ParamsBufferSize = 16 * sizeof(int); const int ParamsBufferSize = 16 * sizeof(int);
@ -669,7 +669,7 @@ namespace Ryujinx.Graphics.Metal
pattern.OffsetIndex.CopyTo(shaderParams[..pattern.OffsetIndex.Length]); pattern.OffsetIndex.CopyTo(shaderParams[..pattern.OffsetIndex.Length]);
using var patternScoped = _renderer.BufferManager.ReserveOrCreate(cbs, ParamsBufferSize); using ScopedTemporaryBuffer patternScoped = _renderer.BufferManager.ReserveOrCreate(cbs, ParamsBufferSize);
patternScoped.Holder.SetDataUnchecked<int>(patternScoped.Offset, shaderParams); patternScoped.Holder.SetDataUnchecked<int>(patternScoped.Offset, shaderParams);
Span<Auto<DisposableBuffer>> sbRanges = new Auto<DisposableBuffer>[2]; Span<Auto<DisposableBuffer>> sbRanges = new Auto<DisposableBuffer>[2];
@ -707,7 +707,7 @@ namespace Ryujinx.Graphics.Metal
// TODO: Flush // TODO: Flush
using var buffer = _renderer.BufferManager.ReserveOrCreate(_pipeline.Cbs, ClearColorBufferSize); using ScopedTemporaryBuffer buffer = _renderer.BufferManager.ReserveOrCreate(_pipeline.Cbs, ClearColorBufferSize);
buffer.Holder.SetDataUnchecked(buffer.Offset, clearColor); buffer.Holder.SetDataUnchecked(buffer.Offset, clearColor);
_pipeline.SetUniformBuffers([new BufferAssignment(0, buffer.Range)]); _pipeline.SetUniformBuffers([new BufferAssignment(0, buffer.Range)]);
@ -726,7 +726,7 @@ namespace Ryujinx.Graphics.Metal
Span<uint> componentMasks = stackalloc uint[index + 1]; Span<uint> componentMasks = stackalloc uint[index + 1];
componentMasks[index] = componentMask; componentMasks[index] = componentMask;
var debugGroupName = "Clear Color "; string debugGroupName = "Clear Color ";
if (format.IsSint()) if (format.IsSint())
{ {
@ -768,7 +768,7 @@ namespace Ryujinx.Graphics.Metal
{ {
// Keep original scissor // Keep original scissor
DirtyFlags clearFlags = DirtyFlags.All & (~DirtyFlags.Scissors); DirtyFlags clearFlags = DirtyFlags.All & (~DirtyFlags.Scissors);
var helperScissors = _helperShaderState.Scissors; MTLScissorRect[] helperScissors = _helperShaderState.Scissors;
// Save current state // Save current state
EncoderState originalState = _pipeline.SwapState(_helperShaderState, clearFlags, false); EncoderState originalState = _pipeline.SwapState(_helperShaderState, clearFlags, false);
@ -778,7 +778,7 @@ namespace Ryujinx.Graphics.Metal
const int ClearDepthBufferSize = 16; const int ClearDepthBufferSize = 16;
using var buffer = _renderer.BufferManager.ReserveOrCreate(_pipeline.Cbs, ClearDepthBufferSize); using ScopedTemporaryBuffer buffer = _renderer.BufferManager.ReserveOrCreate(_pipeline.Cbs, ClearDepthBufferSize);
buffer.Holder.SetDataUnchecked(buffer.Offset, new ReadOnlySpan<float>(ref depthValue)); buffer.Holder.SetDataUnchecked(buffer.Offset, new ReadOnlySpan<float>(ref depthValue));
_pipeline.SetUniformBuffers([new BufferAssignment(0, buffer.Range)]); _pipeline.SetUniformBuffers([new BufferAssignment(0, buffer.Range)]);
@ -844,17 +844,17 @@ namespace Ryujinx.Graphics.Metal
_programColorBlitMsI.Dispose(); _programColorBlitMsI.Dispose();
_programColorBlitMsU.Dispose(); _programColorBlitMsU.Dispose();
foreach (var programColorClear in _programsColorClearF) foreach (IProgram programColorClear in _programsColorClearF)
{ {
programColorClear.Dispose(); programColorClear.Dispose();
} }
foreach (var programColorClear in _programsColorClearU) foreach (IProgram programColorClear in _programsColorClearU)
{ {
programColorClear.Dispose(); programColorClear.Dispose();
} }
foreach (var programColorClear in _programsColorClearI) foreach (IProgram programColorClear in _programsColorClearI)
{ {
programColorClear.Dispose(); programColorClear.Dispose();
} }

View File

@ -76,7 +76,7 @@ namespace Ryujinx.Graphics.Metal
int firstIndexOffset = firstIndex * indexSize; int firstIndexOffset = firstIndex * indexSize;
var autoBuffer = renderer.BufferManager.GetBufferTopologyConversion(cbs, _handle, _offset + firstIndexOffset, indexCount * indexSize, pattern, indexSize); Auto<DisposableBuffer> autoBuffer = renderer.BufferManager.GetBufferTopologyConversion(cbs, _handle, _offset + firstIndexOffset, indexCount * indexSize, pattern, indexSize);
int size = convertedCount * 4; int size = convertedCount * 4;

View File

@ -61,7 +61,7 @@ namespace Ryujinx.Graphics.Metal
public void Initialize(GraphicsDebugLevel logLevel) public void Initialize(GraphicsDebugLevel logLevel)
{ {
var layer = _getMetalLayer(); CAMetalLayer layer = _getMetalLayer();
layer.Device = _device; layer.Device = _device;
layer.FramebufferOnly = false; layer.FramebufferOnly = false;
@ -253,7 +253,7 @@ namespace Ryujinx.Graphics.Metal
public ICounterEvent ReportCounter(CounterType type, EventHandler<ulong> resultHandler, float divisor, bool hostReserved) public ICounterEvent ReportCounter(CounterType type, EventHandler<ulong> resultHandler, float divisor, bool hostReserved)
{ {
// https://developer.apple.com/documentation/metal/gpu_counters_and_counter_sample_buffers/creating_a_counter_sample_buffer_to_store_a_gpu_s_counter_data_during_a_pass?language=objc // https://developer.apple.com/documentation/metal/gpu_counters_and_counter_sample_buffers/creating_a_counter_sample_buffer_to_store_a_gpu_s_counter_data_during_a_pass?language=objc
var counterEvent = new CounterEvent(); CounterEvent counterEvent = new CounterEvent();
resultHandler?.Invoke(counterEvent, type == CounterType.SamplesPassed ? (ulong)1 : 0); resultHandler?.Invoke(counterEvent, type == CounterType.SamplesPassed ? (ulong)1 : 0);
return counterEvent; return counterEvent;
} }
@ -295,12 +295,12 @@ namespace Ryujinx.Graphics.Metal
{ {
BackgroundResources.Dispose(); BackgroundResources.Dispose();
foreach (var program in Programs) foreach (Program program in Programs)
{ {
program.Dispose(); program.Dispose();
} }
foreach (var sampler in Samplers) foreach (SamplerHolder sampler in Samplers)
{ {
sampler.Dispose(); sampler.Dispose();
} }

View File

@ -189,14 +189,14 @@ namespace Ryujinx.Graphics.Metal
if (indefinite) if (indefinite)
{ {
foreach (var fence in fences) foreach (MTLCommandBuffer fence in fences)
{ {
fence.WaitUntilCompleted(); fence.WaitUntilCompleted();
} }
} }
else else
{ {
foreach (var fence in fences) foreach (MTLCommandBuffer fence in fences)
{ {
if (fence.Status != MTLCommandBufferStatus.Completed) if (fence.Status != MTLCommandBufferStatus.Completed)
{ {
@ -224,7 +224,7 @@ namespace Ryujinx.Graphics.Metal
for (int i = 0; i < _fences.Length; i++) for (int i = 0; i < _fences.Length; i++)
{ {
var fence = _fences[i]; FenceHolder fence = _fences[i];
if (fence != null) if (fence != null)
{ {
@ -248,7 +248,7 @@ namespace Ryujinx.Graphics.Metal
for (int i = 0; i < _fences.Length; i++) for (int i = 0; i < _fences.Length; i++)
{ {
var fence = _fences[i]; FenceHolder fence = _fences[i];
if (fence != null && _bufferUsageBitmap.OverlapsWith(i, offset, size)) if (fence != null && _bufferUsageBitmap.OverlapsWith(i, offset, size))
{ {

View File

@ -1,4 +1,5 @@
using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.GAL;
using SharpMetal.Metal;
using System; using System;
using System.Runtime.Versioning; using System.Runtime.Versioning;
@ -18,7 +19,7 @@ namespace Ryujinx.Graphics.Metal
private BufferHolder ResizeIfNeeded(int size) private BufferHolder ResizeIfNeeded(int size)
{ {
var flushStorage = _flushStorage; BufferHolder flushStorage = _flushStorage;
if (flushStorage == null || size > _flushStorage.Size) if (flushStorage == null || size > _flushStorage.Size)
{ {
@ -33,13 +34,13 @@ namespace Ryujinx.Graphics.Metal
public Span<byte> GetBufferData(CommandBufferPool cbp, BufferHolder buffer, int offset, int size) public Span<byte> GetBufferData(CommandBufferPool cbp, BufferHolder buffer, int offset, int size)
{ {
var flushStorage = ResizeIfNeeded(size); BufferHolder flushStorage = ResizeIfNeeded(size);
Auto<DisposableBuffer> srcBuffer; Auto<DisposableBuffer> srcBuffer;
using (var cbs = cbp.Rent()) using (CommandBufferScoped cbs = cbp.Rent())
{ {
srcBuffer = buffer.GetBuffer(); srcBuffer = buffer.GetBuffer();
var dstBuffer = flushStorage.GetBuffer(); Auto<DisposableBuffer> dstBuffer = flushStorage.GetBuffer();
if (srcBuffer.TryIncrementReferenceCount()) if (srcBuffer.TryIncrementReferenceCount())
{ {
@ -61,12 +62,12 @@ namespace Ryujinx.Graphics.Metal
{ {
TextureCreateInfo info = view.Info; TextureCreateInfo info = view.Info;
var flushStorage = ResizeIfNeeded(size); BufferHolder flushStorage = ResizeIfNeeded(size);
using (var cbs = cbp.Rent()) using (CommandBufferScoped cbs = cbp.Rent())
{ {
var buffer = flushStorage.GetBuffer().Get(cbs).Value; MTLBuffer buffer = flushStorage.GetBuffer().Get(cbs).Value;
var image = view.GetHandle(); MTLTexture image = view.GetHandle();
view.CopyFromOrToBuffer(cbs, buffer, image, size, true, 0, 0, info.GetLayers(), info.Levels, singleSlice: false); view.CopyFromOrToBuffer(cbs, buffer, image, size, true, 0, 0, info.GetLayers(), info.Levels, singleSlice: false);
} }
@ -77,12 +78,12 @@ namespace Ryujinx.Graphics.Metal
public Span<byte> GetTextureData(CommandBufferPool cbp, Texture view, int size, int layer, int level) public Span<byte> GetTextureData(CommandBufferPool cbp, Texture view, int size, int layer, int level)
{ {
var flushStorage = ResizeIfNeeded(size); BufferHolder flushStorage = ResizeIfNeeded(size);
using (var cbs = cbp.Rent()) using (CommandBufferScoped cbs = cbp.Rent())
{ {
var buffer = flushStorage.GetBuffer().Get(cbs).Value; MTLBuffer buffer = flushStorage.GetBuffer().Get(cbs).Value;
var image = view.GetHandle(); MTLTexture image = view.GetHandle();
view.CopyFromOrToBuffer(cbs, buffer, image, size, true, layer, level, 1, 1, singleSlice: true); view.CopyFromOrToBuffer(cbs, buffer, image, size, true, layer, level, 1, 1, singleSlice: true);
} }

View File

@ -149,8 +149,8 @@ namespace Ryujinx.Graphics.Metal
public void Present(CAMetalDrawable drawable, Texture src, Extents2D srcRegion, Extents2D dstRegion, bool isLinear) public void Present(CAMetalDrawable drawable, Texture src, Extents2D srcRegion, Extents2D dstRegion, bool isLinear)
{ {
// TODO: Clean this up // TODO: Clean this up
var textureInfo = new TextureCreateInfo((int)drawable.Texture.Width, (int)drawable.Texture.Height, (int)drawable.Texture.Depth, (int)drawable.Texture.MipmapLevelCount, (int)drawable.Texture.SampleCount, 0, 0, 0, Format.B8G8R8A8Unorm, 0, Target.Texture2D, SwizzleComponent.Red, SwizzleComponent.Green, SwizzleComponent.Blue, SwizzleComponent.Alpha); TextureCreateInfo textureInfo = new TextureCreateInfo((int)drawable.Texture.Width, (int)drawable.Texture.Height, (int)drawable.Texture.Depth, (int)drawable.Texture.MipmapLevelCount, (int)drawable.Texture.SampleCount, 0, 0, 0, Format.B8G8R8A8Unorm, 0, Target.Texture2D, SwizzleComponent.Red, SwizzleComponent.Green, SwizzleComponent.Blue, SwizzleComponent.Alpha);
var dst = new Texture(_device, _renderer, this, textureInfo, drawable.Texture, 0, 0); Texture dst = new Texture(_device, _renderer, this, textureInfo, drawable.Texture, 0, 0);
_renderer.HelperShader.BlitColor(Cbs, src, dst, srcRegion, dstRegion, isLinear, true); _renderer.HelperShader.BlitColor(Cbs, src, dst, srcRegion, dstRegion, isLinear, true);
@ -248,14 +248,14 @@ namespace Ryujinx.Graphics.Metal
{ {
case EncoderType.Render: case EncoderType.Render:
{ {
var scope = MTLBarrierScope.Buffers | MTLBarrierScope.Textures | MTLBarrierScope.RenderTargets; MTLBarrierScope scope = MTLBarrierScope.Buffers | MTLBarrierScope.Textures | MTLBarrierScope.RenderTargets;
MTLRenderStages stages = MTLRenderStages.RenderStageVertex | MTLRenderStages.RenderStageFragment; MTLRenderStages stages = MTLRenderStages.RenderStageVertex | MTLRenderStages.RenderStageFragment;
Encoders.RenderEncoder.MemoryBarrier(scope, stages, stages); Encoders.RenderEncoder.MemoryBarrier(scope, stages, stages);
break; break;
} }
case EncoderType.Compute: case EncoderType.Compute:
{ {
var scope = MTLBarrierScope.Buffers | MTLBarrierScope.Textures | MTLBarrierScope.RenderTargets; MTLBarrierScope scope = MTLBarrierScope.Buffers | MTLBarrierScope.Textures | MTLBarrierScope.RenderTargets;
Encoders.ComputeEncoder.MemoryBarrier(scope); Encoders.ComputeEncoder.MemoryBarrier(scope);
break; break;
} }
@ -264,9 +264,9 @@ namespace Ryujinx.Graphics.Metal
public void ClearBuffer(BufferHandle destination, int offset, int size, uint value) public void ClearBuffer(BufferHandle destination, int offset, int size, uint value)
{ {
var blitCommandEncoder = GetOrCreateBlitEncoder(); MTLBlitCommandEncoder blitCommandEncoder = GetOrCreateBlitEncoder();
var mtlBuffer = _renderer.BufferManager.GetBuffer(destination, offset, size, true).Get(Cbs, offset, size, true).Value; MTLBuffer mtlBuffer = _renderer.BufferManager.GetBuffer(destination, offset, size, true).Get(Cbs, offset, size, true).Value;
// Might need a closer look, range's count, lower, and upper bound // Might need a closer look, range's count, lower, and upper bound
// must be a multiple of 4 // must be a multiple of 4
@ -282,7 +282,7 @@ namespace Ryujinx.Graphics.Metal
public void ClearRenderTargetColor(int index, int layer, int layerCount, uint componentMask, ColorF color) public void ClearRenderTargetColor(int index, int layer, int layerCount, uint componentMask, ColorF color)
{ {
float[] colors = [color.Red, color.Green, color.Blue, color.Alpha]; float[] colors = [color.Red, color.Green, color.Blue, color.Alpha];
var dst = _encoderStateManager.RenderTargets[index]; Texture dst = _encoderStateManager.RenderTargets[index];
// TODO: Remove workaround for Wonder which has an invalid texture due to unsupported format // TODO: Remove workaround for Wonder which has an invalid texture due to unsupported format
if (dst == null) if (dst == null)
@ -296,7 +296,7 @@ namespace Ryujinx.Graphics.Metal
public void ClearRenderTargetDepthStencil(int layer, int layerCount, float depthValue, bool depthMask, int stencilValue, int stencilMask) public void ClearRenderTargetDepthStencil(int layer, int layerCount, float depthValue, bool depthMask, int stencilValue, int stencilMask)
{ {
var depthStencil = _encoderStateManager.DepthStencil; Texture depthStencil = _encoderStateManager.DepthStencil;
if (depthStencil == null) if (depthStencil == null)
{ {
@ -313,16 +313,16 @@ namespace Ryujinx.Graphics.Metal
public void CopyBuffer(BufferHandle src, BufferHandle dst, int srcOffset, int dstOffset, int size) public void CopyBuffer(BufferHandle src, BufferHandle dst, int srcOffset, int dstOffset, int size)
{ {
var srcBuffer = _renderer.BufferManager.GetBuffer(src, srcOffset, size, false); Auto<DisposableBuffer> srcBuffer = _renderer.BufferManager.GetBuffer(src, srcOffset, size, false);
var dstBuffer = _renderer.BufferManager.GetBuffer(dst, dstOffset, size, true); Auto<DisposableBuffer> dstBuffer = _renderer.BufferManager.GetBuffer(dst, dstOffset, size, true);
BufferHolder.Copy(Cbs, srcBuffer, dstBuffer, srcOffset, dstOffset, size); BufferHolder.Copy(Cbs, srcBuffer, dstBuffer, srcOffset, dstOffset, size);
} }
public void PushDebugGroup(string name) public void PushDebugGroup(string name)
{ {
var encoder = Encoders.CurrentEncoder; MTLCommandEncoder? encoder = Encoders.CurrentEncoder;
var debugGroupName = StringHelper.NSString(name); NSString debugGroupName = StringHelper.NSString(name);
if (encoder == null) if (encoder == null)
{ {
@ -345,7 +345,7 @@ namespace Ryujinx.Graphics.Metal
public void PopDebugGroup() public void PopDebugGroup()
{ {
var encoder = Encoders.CurrentEncoder; MTLCommandEncoder? encoder = Encoders.CurrentEncoder;
if (encoder == null) if (encoder == null)
{ {
@ -373,7 +373,7 @@ namespace Ryujinx.Graphics.Metal
public void DispatchCompute(int groupsX, int groupsY, int groupsZ, string debugGroupName) public void DispatchCompute(int groupsX, int groupsY, int groupsZ, string debugGroupName)
{ {
var computeCommandEncoder = GetOrCreateComputeEncoder(true); MTLComputeCommandEncoder computeCommandEncoder = GetOrCreateComputeEncoder(true);
ComputeSize localSize = _encoderStateManager.ComputeLocalSize; ComputeSize localSize = _encoderStateManager.ComputeLocalSize;
@ -404,17 +404,17 @@ namespace Ryujinx.Graphics.Metal
return; return;
} }
var primitiveType = TopologyRemap(_encoderStateManager.Topology).Convert(); MTLPrimitiveType primitiveType = TopologyRemap(_encoderStateManager.Topology).Convert();
if (TopologyUnsupported(_encoderStateManager.Topology)) if (TopologyUnsupported(_encoderStateManager.Topology))
{ {
var pattern = GetIndexBufferPattern(); IndexBufferPattern pattern = GetIndexBufferPattern();
BufferHandle handle = pattern.GetRepeatingBuffer(vertexCount, out int indexCount); BufferHandle handle = pattern.GetRepeatingBuffer(vertexCount, out int indexCount);
var buffer = _renderer.BufferManager.GetBuffer(handle, false); Auto<DisposableBuffer> buffer = _renderer.BufferManager.GetBuffer(handle, false);
var mtlBuffer = buffer.Get(Cbs, 0, indexCount * sizeof(int)).Value; MTLBuffer mtlBuffer = buffer.Get(Cbs, 0, indexCount * sizeof(int)).Value;
var renderCommandEncoder = GetOrCreateRenderEncoder(true); MTLRenderCommandEncoder renderCommandEncoder = GetOrCreateRenderEncoder(true);
renderCommandEncoder.DrawIndexedPrimitives( renderCommandEncoder.DrawIndexedPrimitives(
primitiveType, primitiveType,
@ -425,7 +425,7 @@ namespace Ryujinx.Graphics.Metal
} }
else else
{ {
var renderCommandEncoder = GetOrCreateRenderEncoder(true); MTLRenderCommandEncoder renderCommandEncoder = GetOrCreateRenderEncoder(true);
if (debugGroupName != String.Empty) if (debugGroupName != String.Empty)
{ {
@ -488,11 +488,11 @@ namespace Ryujinx.Graphics.Metal
MTLIndexType type; MTLIndexType type;
int finalIndexCount = indexCount; int finalIndexCount = indexCount;
var primitiveType = TopologyRemap(_encoderStateManager.Topology).Convert(); MTLPrimitiveType primitiveType = TopologyRemap(_encoderStateManager.Topology).Convert();
if (TopologyUnsupported(_encoderStateManager.Topology)) if (TopologyUnsupported(_encoderStateManager.Topology))
{ {
var pattern = GetIndexBufferPattern(); IndexBufferPattern pattern = GetIndexBufferPattern();
int convertedCount = pattern.GetConvertedCount(indexCount); int convertedCount = pattern.GetConvertedCount(indexCount);
finalIndexCount = convertedCount; finalIndexCount = convertedCount;
@ -506,7 +506,7 @@ namespace Ryujinx.Graphics.Metal
if (mtlBuffer.NativePtr != IntPtr.Zero) if (mtlBuffer.NativePtr != IntPtr.Zero)
{ {
var renderCommandEncoder = GetOrCreateRenderEncoder(true); MTLRenderCommandEncoder renderCommandEncoder = GetOrCreateRenderEncoder(true);
renderCommandEncoder.DrawIndexedPrimitives( renderCommandEncoder.DrawIndexedPrimitives(
primitiveType, primitiveType,
@ -533,17 +533,17 @@ namespace Ryujinx.Graphics.Metal
Logger.Warning?.Print(LogClass.Gpu, $"Drawing indexed with unsupported topology: {_encoderStateManager.Topology}"); Logger.Warning?.Print(LogClass.Gpu, $"Drawing indexed with unsupported topology: {_encoderStateManager.Topology}");
} }
var buffer = _renderer.BufferManager MTLBuffer buffer = _renderer.BufferManager
.GetBuffer(indirectBuffer.Handle, indirectBuffer.Offset, indirectBuffer.Size, false) .GetBuffer(indirectBuffer.Handle, indirectBuffer.Offset, indirectBuffer.Size, false)
.Get(Cbs, indirectBuffer.Offset, indirectBuffer.Size).Value; .Get(Cbs, indirectBuffer.Offset, indirectBuffer.Size).Value;
var primitiveType = TopologyRemap(_encoderStateManager.Topology).Convert(); MTLPrimitiveType primitiveType = TopologyRemap(_encoderStateManager.Topology).Convert();
(MTLBuffer indexBuffer, int indexOffset, MTLIndexType type) = _encoderStateManager.IndexBuffer.GetIndexBuffer(_renderer, Cbs); (MTLBuffer indexBuffer, int indexOffset, MTLIndexType type) = _encoderStateManager.IndexBuffer.GetIndexBuffer(_renderer, Cbs);
if (indexBuffer.NativePtr != IntPtr.Zero && buffer.NativePtr != IntPtr.Zero) if (indexBuffer.NativePtr != IntPtr.Zero && buffer.NativePtr != IntPtr.Zero)
{ {
var renderCommandEncoder = GetOrCreateRenderEncoder(true); MTLRenderCommandEncoder renderCommandEncoder = GetOrCreateRenderEncoder(true);
renderCommandEncoder.DrawIndexedPrimitives( renderCommandEncoder.DrawIndexedPrimitives(
primitiveType, primitiveType,
@ -576,12 +576,12 @@ namespace Ryujinx.Graphics.Metal
Logger.Warning?.Print(LogClass.Gpu, $"Drawing indirect with unsupported topology: {_encoderStateManager.Topology}"); Logger.Warning?.Print(LogClass.Gpu, $"Drawing indirect with unsupported topology: {_encoderStateManager.Topology}");
} }
var buffer = _renderer.BufferManager MTLBuffer buffer = _renderer.BufferManager
.GetBuffer(indirectBuffer.Handle, indirectBuffer.Offset, indirectBuffer.Size, false) .GetBuffer(indirectBuffer.Handle, indirectBuffer.Offset, indirectBuffer.Size, false)
.Get(Cbs, indirectBuffer.Offset, indirectBuffer.Size).Value; .Get(Cbs, indirectBuffer.Offset, indirectBuffer.Size).Value;
var primitiveType = TopologyRemap(_encoderStateManager.Topology).Convert(); MTLPrimitiveType primitiveType = TopologyRemap(_encoderStateManager.Topology).Convert();
var renderCommandEncoder = GetOrCreateRenderEncoder(true); MTLRenderCommandEncoder renderCommandEncoder = GetOrCreateRenderEncoder(true);
renderCommandEncoder.DrawPrimitives( renderCommandEncoder.DrawPrimitives(
primitiveType, primitiveType,

View File

@ -56,12 +56,12 @@ namespace Ryujinx.Graphics.Metal
{ {
ShaderSource shader = _shaders[i]; ShaderSource shader = _shaders[i];
using var compileOptions = new MTLCompileOptions using MTLCompileOptions compileOptions = new MTLCompileOptions
{ {
PreserveInvariance = true, PreserveInvariance = true,
LanguageVersion = MTLLanguageVersion.Version31, LanguageVersion = MTLLanguageVersion.Version31,
}; };
var index = i; int index = i;
_handles[i] = device.NewLibrary(StringHelper.NSString(shader.Code), compileOptions, (library, error) => CompilationResultHandler(library, error, index)); _handles[i] = device.NewLibrary(StringHelper.NSString(shader.Code), compileOptions, (library, error) => CompilationResultHandler(library, error, index));
} }
@ -71,7 +71,7 @@ namespace Ryujinx.Graphics.Metal
public void CompilationResultHandler(MTLLibrary library, NSError error, int index) public void CompilationResultHandler(MTLLibrary library, NSError error, int index)
{ {
var shader = _shaders[index]; ShaderSource shader = _shaders[index];
if (_handles[index].IsAllocated) if (_handles[index].IsAllocated)
{ {
@ -142,7 +142,7 @@ namespace Ryujinx.Graphics.Metal
currentUsage.Stages, currentUsage.Stages,
currentUsage.ArrayLength > 1)); currentUsage.ArrayLength > 1));
var size = currentCount * ResourcePointerSize(currentUsage.Type); int size = currentCount * ResourcePointerSize(currentUsage.Type);
if (currentUsage.Stages.HasFlag(ResourceStages.Fragment)) if (currentUsage.Stages.HasFlag(ResourceStages.Fragment))
{ {
fragArgBufferSizes[setIndex] += size; fragArgBufferSizes[setIndex] += size;
@ -173,7 +173,7 @@ namespace Ryujinx.Graphics.Metal
currentUsage.Stages, currentUsage.Stages,
currentUsage.ArrayLength > 1)); currentUsage.ArrayLength > 1));
var size = currentCount * ResourcePointerSize(currentUsage.Type); int size = currentCount * ResourcePointerSize(currentUsage.Type);
if (currentUsage.Stages.HasFlag(ResourceStages.Fragment)) if (currentUsage.Stages.HasFlag(ResourceStages.Fragment))
{ {
fragArgBufferSizes[setIndex] += size; fragArgBufferSizes[setIndex] += size;

View File

@ -44,8 +44,8 @@ namespace Ryujinx.Graphics.Metal
public ResourceLayout Build() public ResourceLayout Build()
{ {
var descriptors = new ResourceDescriptorCollection[TotalSets]; ResourceDescriptorCollection[] descriptors = new ResourceDescriptorCollection[TotalSets];
var usages = new ResourceUsageCollection[TotalSets]; ResourceUsageCollection[] usages = new ResourceUsageCollection[TotalSets];
for (int index = 0; index < TotalSets; index++) for (int index = 0; index < TotalSets; index++)
{ {

View File

@ -21,7 +21,7 @@ namespace Ryujinx.Graphics.Metal
MTLSamplerBorderColor borderColor = GetConstrainedBorderColor(info.BorderColor, out _); MTLSamplerBorderColor borderColor = GetConstrainedBorderColor(info.BorderColor, out _);
using var descriptor = new MTLSamplerDescriptor using MTLSamplerDescriptor descriptor = new MTLSamplerDescriptor
{ {
BorderColor = borderColor, BorderColor = borderColor,
MinFilter = minFilter, MinFilter = minFilter,
@ -38,7 +38,7 @@ namespace Ryujinx.Graphics.Metal
SupportArgumentBuffers = true SupportArgumentBuffers = true
}; };
var sampler = device.NewSamplerState(descriptor); MTLSamplerState sampler = device.NewSamplerState(descriptor);
_sampler = new Auto<DisposableSampler>(new DisposableSampler(sampler)); _sampler = new Auto<DisposableSampler>(new DisposableSampler(sampler));
} }

View File

@ -108,8 +108,8 @@ namespace Ryujinx.Graphics.Metal
private void PushDataImpl(CommandBufferScoped cbs, BufferHolder dst, int dstOffset, ReadOnlySpan<byte> data) private void PushDataImpl(CommandBufferScoped cbs, BufferHolder dst, int dstOffset, ReadOnlySpan<byte> data)
{ {
var srcBuffer = _buffer.GetBuffer(); Auto<DisposableBuffer> srcBuffer = _buffer.GetBuffer();
var dstBuffer = dst.GetBuffer(dstOffset, data.Length, true); Auto<DisposableBuffer> dstBuffer = dst.GetBuffer(dstOffset, data.Length, true);
int offset = _freeOffset; int offset = _freeOffset;
int capacity = BufferSize - offset; int capacity = BufferSize - offset;
@ -241,7 +241,7 @@ namespace Ryujinx.Graphics.Metal
private bool WaitFreeCompleted(CommandBufferPool cbp) private bool WaitFreeCompleted(CommandBufferPool cbp)
{ {
if (_pendingCopies.TryPeek(out var pc)) if (_pendingCopies.TryPeek(out PendingCopy pc))
{ {
if (!pc.Fence.IsSignaled()) if (!pc.Fence.IsSignaled())
{ {
@ -253,7 +253,7 @@ namespace Ryujinx.Graphics.Metal
pc.Fence.Wait(); pc.Fence.Wait();
} }
var dequeued = _pendingCopies.Dequeue(); PendingCopy dequeued = _pendingCopies.Dequeue();
Debug.Assert(dequeued.Fence == pc.Fence); Debug.Assert(dequeued.Fence == pc.Fence);
_freeSize += pc.Size; _freeSize += pc.Size;
pc.Fence.Put(); pc.Fence.Put();
@ -265,10 +265,10 @@ namespace Ryujinx.Graphics.Metal
public void FreeCompleted() public void FreeCompleted()
{ {
FenceHolder signalledFence = null; FenceHolder signalledFence = null;
while (_pendingCopies.TryPeek(out var pc) && (pc.Fence == signalledFence || pc.Fence.IsSignaled())) while (_pendingCopies.TryPeek(out PendingCopy pc) && (pc.Fence == signalledFence || pc.Fence.IsSignaled()))
{ {
signalledFence = pc.Fence; // Already checked - don't need to do it again. signalledFence = pc.Fence; // Already checked - don't need to do it again.
var dequeued = _pendingCopies.Dequeue(); PendingCopy dequeued = _pendingCopies.Dequeue();
Debug.Assert(dequeued.Fence == pc.Fence); Debug.Assert(dequeued.Fence == pc.Fence);
_freeSize += pc.Size; _freeSize += pc.Size;
pc.Fence.Put(); pc.Fence.Put();
@ -279,7 +279,7 @@ namespace Ryujinx.Graphics.Metal
{ {
_renderer.BufferManager.Delete(Handle); _renderer.BufferManager.Delete(Handle);
while (_pendingCopies.TryDequeue(out var pc)) while (_pendingCopies.TryDequeue(out PendingCopy pc))
{ {
pc.Fence.Put(); pc.Fence.Put();
} }

View File

@ -118,13 +118,13 @@ namespace Ryujinx.Graphics.Metal
private readonly MTLVertexDescriptor BuildVertexDescriptor() private readonly MTLVertexDescriptor BuildVertexDescriptor()
{ {
var vertexDescriptor = new MTLVertexDescriptor(); MTLVertexDescriptor vertexDescriptor = new MTLVertexDescriptor();
for (int i = 0; i < VertexAttributeDescriptionsCount; i++) for (int i = 0; i < VertexAttributeDescriptionsCount; i++)
{ {
VertexInputAttributeUid uid = Internal.VertexAttributes[i]; VertexInputAttributeUid uid = Internal.VertexAttributes[i];
var attrib = vertexDescriptor.Attributes.Object((ulong)i); MTLVertexAttributeDescriptor attrib = vertexDescriptor.Attributes.Object((ulong)i);
attrib.Format = uid.Format; attrib.Format = uid.Format;
attrib.Offset = uid.Offset; attrib.Offset = uid.Offset;
attrib.BufferIndex = uid.BufferIndex; attrib.BufferIndex = uid.BufferIndex;
@ -134,7 +134,7 @@ namespace Ryujinx.Graphics.Metal
{ {
VertexInputLayoutUid uid = Internal.VertexBindings[i]; VertexInputLayoutUid uid = Internal.VertexBindings[i];
var layout = vertexDescriptor.Layouts.Object((ulong)i); MTLVertexBufferLayoutDescriptor layout = vertexDescriptor.Layouts.Object((ulong)i);
layout.StepFunction = uid.StepFunction; layout.StepFunction = uid.StepFunction;
layout.StepRate = uid.StepRate; layout.StepRate = uid.StepRate;
@ -146,15 +146,15 @@ namespace Ryujinx.Graphics.Metal
private MTLRenderPipelineDescriptor CreateRenderDescriptor(Program program) private MTLRenderPipelineDescriptor CreateRenderDescriptor(Program program)
{ {
var renderPipelineDescriptor = new MTLRenderPipelineDescriptor(); MTLRenderPipelineDescriptor renderPipelineDescriptor = new MTLRenderPipelineDescriptor();
for (int i = 0; i < Constants.MaxColorAttachments; i++) for (int i = 0; i < Constants.MaxColorAttachments; i++)
{ {
var blendState = Internal.ColorBlendState[i]; ColorBlendStateUid blendState = Internal.ColorBlendState[i];
if (blendState.PixelFormat != MTLPixelFormat.Invalid) if (blendState.PixelFormat != MTLPixelFormat.Invalid)
{ {
var pipelineAttachment = renderPipelineDescriptor.ColorAttachments.Object((ulong)i); MTLRenderPipelineColorAttachmentDescriptor pipelineAttachment = renderPipelineDescriptor.ColorAttachments.Object((ulong)i);
BuildColorAttachment(pipelineAttachment, blendState); BuildColorAttachment(pipelineAttachment, blendState);
} }
@ -195,7 +195,7 @@ namespace Ryujinx.Graphics.Metal
renderPipelineDescriptor.RasterizationEnabled = !RasterizerDiscardEnable; renderPipelineDescriptor.RasterizationEnabled = !RasterizerDiscardEnable;
renderPipelineDescriptor.SampleCount = Math.Max(1, SamplesCount); renderPipelineDescriptor.SampleCount = Math.Max(1, SamplesCount);
var vertexDescriptor = BuildVertexDescriptor(); MTLVertexDescriptor vertexDescriptor = BuildVertexDescriptor();
renderPipelineDescriptor.VertexDescriptor = vertexDescriptor; renderPipelineDescriptor.VertexDescriptor = vertexDescriptor;
renderPipelineDescriptor.VertexFunction = program.VertexFunction; renderPipelineDescriptor.VertexFunction = program.VertexFunction;
@ -210,14 +210,14 @@ namespace Ryujinx.Graphics.Metal
public MTLRenderPipelineState CreateRenderPipeline(MTLDevice device, Program program) public MTLRenderPipelineState CreateRenderPipeline(MTLDevice device, Program program)
{ {
if (program.TryGetGraphicsPipeline(ref Internal, out var pipelineState)) if (program.TryGetGraphicsPipeline(ref Internal, out MTLRenderPipelineState pipelineState))
{ {
return pipelineState; return pipelineState;
} }
using var descriptor = CreateRenderDescriptor(program); using MTLRenderPipelineDescriptor descriptor = CreateRenderDescriptor(program);
var error = new NSError(IntPtr.Zero); NSError error = new NSError(IntPtr.Zero);
pipelineState = device.NewRenderPipelineState(descriptor, ref error); pipelineState = device.NewRenderPipelineState(descriptor, ref error);
if (error != IntPtr.Zero) if (error != IntPtr.Zero)
{ {
@ -240,7 +240,7 @@ namespace Ryujinx.Graphics.Metal
throw new InvalidOperationException($"Local thread size for compute cannot be 0 in any dimension."); throw new InvalidOperationException($"Local thread size for compute cannot be 0 in any dimension.");
} }
var descriptor = new MTLComputePipelineDescriptor MTLComputePipelineDescriptor descriptor = new MTLComputePipelineDescriptor
{ {
ComputeFunction = program.ComputeFunction, ComputeFunction = program.ComputeFunction,
MaxTotalThreadsPerThreadgroup = maxThreads, MaxTotalThreadsPerThreadgroup = maxThreads,
@ -252,14 +252,14 @@ namespace Ryujinx.Graphics.Metal
public static MTLComputePipelineState CreateComputePipeline(MTLDevice device, Program program) public static MTLComputePipelineState CreateComputePipeline(MTLDevice device, Program program)
{ {
if (program.TryGetComputePipeline(out var pipelineState)) if (program.TryGetComputePipeline(out MTLComputePipelineState pipelineState))
{ {
return pipelineState; return pipelineState;
} }
using MTLComputePipelineDescriptor descriptor = CreateComputeDescriptor(program); using MTLComputePipelineDescriptor descriptor = CreateComputeDescriptor(program);
var error = new NSError(IntPtr.Zero); NSError error = new NSError(IntPtr.Zero);
pipelineState = device.NewComputePipelineState(descriptor, MTLPipelineOption.None, 0, ref error); pipelineState = device.NewComputePipelineState(descriptor, MTLPipelineOption.None, 0, ref error);
if (error != IntPtr.Zero) if (error != IntPtr.Zero)
{ {

View File

@ -114,7 +114,7 @@ namespace Ryujinx.Graphics.Metal
public void Swap(ColorBlendStateUid uid) public void Swap(ColorBlendStateUid uid)
{ {
var format = PixelFormat; MTLPixelFormat format = PixelFormat;
this = uid; this = uid;
PixelFormat = format; PixelFormat = format;

View File

@ -25,14 +25,14 @@ namespace Ryujinx.Graphics.Metal
public T GetOrCreate(TDescriptor descriptor) public T GetOrCreate(TDescriptor descriptor)
{ {
var hash = GetHash(descriptor); THash hash = GetHash(descriptor);
if (_cache.TryGetValue(hash, out T value)) if (_cache.TryGetValue(hash, out T value))
{ {
return value; return value;
} }
else else
{ {
var newValue = CreateValue(descriptor); T newValue = CreateValue(descriptor);
_cache.Add(hash, newValue); _cache.Add(hash, newValue);
return newValue; return newValue;

View File

@ -18,7 +18,7 @@ namespace Ryujinx.Graphics.Metal
{ {
MTLPixelFormat pixelFormat = FormatTable.GetFormat(Info.Format); MTLPixelFormat pixelFormat = FormatTable.GetFormat(Info.Format);
var descriptor = new MTLTextureDescriptor MTLTextureDescriptor descriptor = new MTLTextureDescriptor
{ {
PixelFormat = pixelFormat, PixelFormat = pixelFormat,
Usage = MTLTextureUsage.Unknown, Usage = MTLTextureUsage.Unknown,
@ -65,7 +65,7 @@ namespace Ryujinx.Graphics.Metal
public Texture(MTLDevice device, MetalRenderer renderer, Pipeline pipeline, TextureCreateInfo info, MTLTexture sourceTexture, int firstLayer, int firstLevel) : base(device, renderer, pipeline, info) public Texture(MTLDevice device, MetalRenderer renderer, Pipeline pipeline, TextureCreateInfo info, MTLTexture sourceTexture, int firstLayer, int firstLevel) : base(device, renderer, pipeline, info)
{ {
var pixelFormat = FormatTable.GetFormat(Info.Format); MTLPixelFormat pixelFormat = FormatTable.GetFormat(Info.Format);
if (info.DepthStencilMode == DepthStencilMode.Stencil) if (info.DepthStencilMode == DepthStencilMode.Stencil)
{ {
@ -77,7 +77,7 @@ namespace Ryujinx.Graphics.Metal
}; };
} }
var textureType = Info.Target.Convert(); MTLTextureType textureType = Info.Target.Convert();
NSRange levels; NSRange levels;
levels.location = (ulong)firstLevel; levels.location = (ulong)firstLevel;
levels.length = (ulong)Info.Levels; levels.length = (ulong)Info.Levels;
@ -85,7 +85,7 @@ namespace Ryujinx.Graphics.Metal
slices.location = (ulong)firstLayer; slices.location = (ulong)firstLayer;
slices.length = textureType == MTLTextureType.Type3D ? 1 : (ulong)info.GetDepthOrLayers(); slices.length = textureType == MTLTextureType.Type3D ? 1 : (ulong)info.GetDepthOrLayers();
var swizzle = GetSwizzle(info, pixelFormat); MTLTextureSwizzleChannels swizzle = GetSwizzle(info, pixelFormat);
_identitySwizzleHandle = sourceTexture.NewTextureView(pixelFormat, textureType, levels, slices); _identitySwizzleHandle = sourceTexture.NewTextureView(pixelFormat, textureType, levels, slices);
@ -131,10 +131,10 @@ namespace Ryujinx.Graphics.Metal
private MTLTextureSwizzleChannels GetSwizzle(TextureCreateInfo info, MTLPixelFormat pixelFormat) private MTLTextureSwizzleChannels GetSwizzle(TextureCreateInfo info, MTLPixelFormat pixelFormat)
{ {
var swizzleR = Info.SwizzleR.Convert(); MTLTextureSwizzle swizzleR = Info.SwizzleR.Convert();
var swizzleG = Info.SwizzleG.Convert(); MTLTextureSwizzle swizzleG = Info.SwizzleG.Convert();
var swizzleB = Info.SwizzleB.Convert(); MTLTextureSwizzle swizzleB = Info.SwizzleB.Convert();
var swizzleA = Info.SwizzleA.Convert(); MTLTextureSwizzle swizzleA = Info.SwizzleA.Convert();
if (info.Format == Format.R5G5B5A1Unorm || if (info.Format == Format.R5G5B5A1Unorm ||
info.Format == Format.R5G5B5X1Unorm || info.Format == Format.R5G5B5X1Unorm ||
@ -144,8 +144,8 @@ namespace Ryujinx.Graphics.Metal
} }
else if (pixelFormat == MTLPixelFormat.ABGR4Unorm || info.Format == Format.A1B5G5R5Unorm) else if (pixelFormat == MTLPixelFormat.ABGR4Unorm || info.Format == Format.A1B5G5R5Unorm)
{ {
var tempB = swizzleB; MTLTextureSwizzle tempB = swizzleB;
var tempA = swizzleA; MTLTextureSwizzle tempA = swizzleA;
swizzleB = swizzleG; swizzleB = swizzleG;
swizzleA = swizzleR; swizzleA = swizzleR;
@ -174,8 +174,8 @@ namespace Ryujinx.Graphics.Metal
return; return;
} }
var srcImage = GetHandle(); MTLTexture srcImage = GetHandle();
var dstImage = dst.GetHandle(); MTLTexture dstImage = dst.GetHandle();
if (!dst.Info.Target.IsMultisample() && Info.Target.IsMultisample()) if (!dst.Info.Target.IsMultisample() && Info.Target.IsMultisample())
{ {
@ -231,8 +231,8 @@ namespace Ryujinx.Graphics.Metal
return; return;
} }
var srcImage = GetHandle(); MTLTexture srcImage = GetHandle();
var dstImage = dst.GetHandle(); MTLTexture dstImage = dst.GetHandle();
if (!dst.Info.Target.IsMultisample() && Info.Target.IsMultisample()) if (!dst.Info.Target.IsMultisample() && Info.Target.IsMultisample())
{ {
@ -276,7 +276,7 @@ namespace Ryujinx.Graphics.Metal
return; return;
} }
var dst = (Texture)destination; Texture dst = (Texture)destination;
bool isDepthOrStencil = dst.Info.Format.IsDepthOrStencil(); bool isDepthOrStencil = dst.Info.Format.IsDepthOrStencil();
@ -285,15 +285,15 @@ namespace Ryujinx.Graphics.Metal
public void CopyTo(BufferRange range, int layer, int level, int stride) public void CopyTo(BufferRange range, int layer, int level, int stride)
{ {
var cbs = Pipeline.Cbs; CommandBufferScoped cbs = Pipeline.Cbs;
int outSize = Info.GetMipSize(level); int outSize = Info.GetMipSize(level);
int hostSize = GetBufferDataLength(outSize); int hostSize = GetBufferDataLength(outSize);
int offset = range.Offset; int offset = range.Offset;
var autoBuffer = Renderer.BufferManager.GetBuffer(range.Handle, true); Auto<DisposableBuffer> autoBuffer = Renderer.BufferManager.GetBuffer(range.Handle, true);
var mtlBuffer = autoBuffer.Get(cbs, range.Offset, outSize).Value; MTLBuffer mtlBuffer = autoBuffer.Get(cbs, range.Offset, outSize).Value;
if (PrepareOutputBuffer(cbs, hostSize, mtlBuffer, out MTLBuffer copyToBuffer, out BufferHolder tempCopyHolder)) if (PrepareOutputBuffer(cbs, hostSize, mtlBuffer, out MTLBuffer copyToBuffer, out BufferHolder tempCopyHolder))
{ {
@ -511,13 +511,13 @@ namespace Ryujinx.Graphics.Metal
public void SetData(MemoryOwner<byte> data) public void SetData(MemoryOwner<byte> data)
{ {
var blitCommandEncoder = Pipeline.GetOrCreateBlitEncoder(); MTLBlitCommandEncoder blitCommandEncoder = Pipeline.GetOrCreateBlitEncoder();
var dataSpan = data.Memory.Span; Span<byte> dataSpan = data.Memory.Span;
var buffer = Renderer.BufferManager.Create(dataSpan.Length); BufferHolder buffer = Renderer.BufferManager.Create(dataSpan.Length);
buffer.SetDataUnchecked(0, dataSpan); buffer.SetDataUnchecked(0, dataSpan);
var mtlBuffer = buffer.GetBuffer(false).Get(Pipeline.Cbs).Value; MTLBuffer mtlBuffer = buffer.GetBuffer(false).Get(Pipeline.Cbs).Value;
int width = Info.Width; int width = Info.Width;
int height = Info.Height; int height = Info.Height;
@ -572,16 +572,16 @@ namespace Ryujinx.Graphics.Metal
{ {
int bufferDataLength = GetBufferDataLength(data.Length); int bufferDataLength = GetBufferDataLength(data.Length);
using var bufferHolder = Renderer.BufferManager.Create(bufferDataLength); using BufferHolder bufferHolder = Renderer.BufferManager.Create(bufferDataLength);
// TODO: loadInline logic // TODO: loadInline logic
var cbs = Pipeline.Cbs; CommandBufferScoped cbs = Pipeline.Cbs;
CopyDataToBuffer(bufferHolder.GetDataStorage(0, bufferDataLength), data); CopyDataToBuffer(bufferHolder.GetDataStorage(0, bufferDataLength), data);
var buffer = bufferHolder.GetBuffer().Get(cbs).Value; MTLBuffer buffer = bufferHolder.GetBuffer().Get(cbs).Value;
var image = GetHandle(); MTLTexture image = GetHandle();
CopyFromOrToBuffer(cbs, buffer, image, bufferDataLength, false, layer, level, layers, levels, singleSlice); CopyFromOrToBuffer(cbs, buffer, image, bufferDataLength, false, layer, level, layers, levels, singleSlice);
} }
@ -595,7 +595,7 @@ namespace Ryujinx.Graphics.Metal
public void SetData(MemoryOwner<byte> data, int layer, int level, Rectangle<int> region) public void SetData(MemoryOwner<byte> data, int layer, int level, Rectangle<int> region)
{ {
var blitCommandEncoder = Pipeline.GetOrCreateBlitEncoder(); MTLBlitCommandEncoder blitCommandEncoder = Pipeline.GetOrCreateBlitEncoder();
ulong bytesPerRow = (ulong)Info.GetMipStride(level); ulong bytesPerRow = (ulong)Info.GetMipStride(level);
ulong bytesPerImage = 0; ulong bytesPerImage = 0;
@ -604,11 +604,11 @@ namespace Ryujinx.Graphics.Metal
bytesPerImage = bytesPerRow * (ulong)Info.Height; bytesPerImage = bytesPerRow * (ulong)Info.Height;
} }
var dataSpan = data.Memory.Span; Span<byte> dataSpan = data.Memory.Span;
var buffer = Renderer.BufferManager.Create(dataSpan.Length); BufferHolder buffer = Renderer.BufferManager.Create(dataSpan.Length);
buffer.SetDataUnchecked(0, dataSpan); buffer.SetDataUnchecked(0, dataSpan);
var mtlBuffer = buffer.GetBuffer(false).Get(Pipeline.Cbs).Value; MTLBuffer mtlBuffer = buffer.GetBuffer(false).Get(Pipeline.Cbs).Value;
blitCommandEncoder.CopyFromBuffer( blitCommandEncoder.CopyFromBuffer(
mtlBuffer, mtlBuffer,

View File

@ -49,7 +49,7 @@ namespace Ryujinx.Graphics.Metal
if (autoBuffer != null) if (autoBuffer != null)
{ {
int offset = _offset; int offset = _offset;
var buffer = autoBuffer.Get(cbs, offset, _size).Value; MTLBuffer buffer = autoBuffer.Get(cbs, offset, _size).Value;
return (buffer, offset); return (buffer, offset);
} }

View File

@ -47,7 +47,7 @@ namespace Ryujinx.Graphics.Metal
if (_requestedWidth != 0 && _requestedHeight != 0) if (_requestedWidth != 0 && _requestedHeight != 0)
{ {
// TODO: This is actually a CGSize, but there is no overload for that, so fill the first two fields of rect with the size. // TODO: This is actually a CGSize, but there is no overload for that, so fill the first two fields of rect with the size.
var rect = new NSRect(_requestedWidth, _requestedHeight, 0, 0); NSRect rect = new NSRect(_requestedWidth, _requestedHeight, 0, 0);
ObjectiveC.objc_msgSend(_metalLayer, "setDrawableSize:", rect); ObjectiveC.objc_msgSend(_metalLayer, "setDrawableSize:", rect);
@ -62,7 +62,7 @@ namespace Ryujinx.Graphics.Metal
{ {
ResizeIfNeeded(); ResizeIfNeeded();
var drawable = new CAMetalDrawable(ObjectiveC.IntPtr_objc_msgSend(_metalLayer, "nextDrawable")); CAMetalDrawable drawable = new CAMetalDrawable(ObjectiveC.IntPtr_objc_msgSend(_metalLayer, "nextDrawable"));
_width = (int)drawable.Texture.Width; _width = (int)drawable.Texture.Width;
_height = (int)drawable.Texture.Height; _height = (int)drawable.Texture.Height;