mirror of
https://github.com/Ryubing/Ryujinx.git
synced 2025-03-10 17:14:25 +00:00
misc: chore: Use explicit types in Metal project
This commit is contained in:
parent
1ae349efb1
commit
76ec047eb7
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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++)
|
||||||
|
@ -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)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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))
|
||||||
{
|
{
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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))
|
||||||
{
|
{
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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))
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
|
@ -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++)
|
||||||
{
|
{
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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,
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user