mirror of
https://github.com/Ryubing/Ryujinx.git
synced 2025-11-20 11:30:55 -05:00
Revert the Metal Experiment (#701)
Metal sounded like a good idea to get in the emulator but frankly I underestimated just how experimental and not ready it was. From my write up in the Discord: ``` As is, Metal supports only a few games. The games it does support freeze on first use of not playing them via Vulkan, because shader translation is broken. So you need to use a dirty hack to not delete all your shaders. Not to mention it breaks many games via MoltenVK because of changes to the shared GPU code. Merging Metal seemed like a great idea, because of the few games it does support. But I don't think it's worth it. Many of the games it breaks via MoltenVK *don't work via Metal*. Which effectively makes current Ryubing worse for Mac users than Ryujinx 1.1.1403. I think what I'm gonna do is revert Metal, and reopen it as a PR. That way, you can still take advantage of the Metal backend as is, but without making other games worse with no solution. ``` For what it's worth, the shader translation part could at least be "fixed" by always applying a 30ms delay for shader translation to Metal. That being said, that solution sucks ass. The MoltenVK regressions are even worse. I hope this is not a let down to the Mac users. I hope you realize I'm reverting this because you're actively getting a worse experience with it in the emulator.
This commit is contained in:
@@ -1,118 +0,0 @@
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
namespace Ryujinx.Graphics.Metal
|
||||
{
|
||||
[SupportedOSPlatform("macos")]
|
||||
internal class IndexBufferPattern : IDisposable
|
||||
{
|
||||
public int PrimitiveVertices { get; }
|
||||
public int PrimitiveVerticesOut { get; }
|
||||
public int BaseIndex { get; }
|
||||
public int[] OffsetIndex { get; }
|
||||
public int IndexStride { get; }
|
||||
public bool RepeatStart { get; }
|
||||
|
||||
private readonly MetalRenderer _renderer;
|
||||
private int _currentSize;
|
||||
private BufferHandle _repeatingBuffer;
|
||||
|
||||
public IndexBufferPattern(MetalRenderer renderer,
|
||||
int primitiveVertices,
|
||||
int primitiveVerticesOut,
|
||||
int baseIndex,
|
||||
int[] offsetIndex,
|
||||
int indexStride,
|
||||
bool repeatStart)
|
||||
{
|
||||
PrimitiveVertices = primitiveVertices;
|
||||
PrimitiveVerticesOut = primitiveVerticesOut;
|
||||
BaseIndex = baseIndex;
|
||||
OffsetIndex = offsetIndex;
|
||||
IndexStride = indexStride;
|
||||
RepeatStart = repeatStart;
|
||||
|
||||
_renderer = renderer;
|
||||
}
|
||||
|
||||
public int GetPrimitiveCount(int vertexCount)
|
||||
{
|
||||
return Math.Max(0, (vertexCount - BaseIndex) / IndexStride);
|
||||
}
|
||||
|
||||
public int GetConvertedCount(int indexCount)
|
||||
{
|
||||
int primitiveCount = GetPrimitiveCount(indexCount);
|
||||
return primitiveCount * OffsetIndex.Length;
|
||||
}
|
||||
|
||||
public BufferHandle GetRepeatingBuffer(int vertexCount, out int indexCount)
|
||||
{
|
||||
int primitiveCount = GetPrimitiveCount(vertexCount);
|
||||
indexCount = primitiveCount * PrimitiveVerticesOut;
|
||||
|
||||
int expectedSize = primitiveCount * OffsetIndex.Length;
|
||||
|
||||
if (expectedSize <= _currentSize && _repeatingBuffer != BufferHandle.Null)
|
||||
{
|
||||
return _repeatingBuffer;
|
||||
}
|
||||
|
||||
// Expand the repeating pattern to the number of requested primitives.
|
||||
BufferHandle newBuffer = _renderer.BufferManager.CreateWithHandle(expectedSize * sizeof(int));
|
||||
|
||||
// Copy the old data to the new one.
|
||||
if (_repeatingBuffer != BufferHandle.Null)
|
||||
{
|
||||
_renderer.Pipeline.CopyBuffer(_repeatingBuffer, newBuffer, 0, 0, _currentSize * sizeof(int));
|
||||
_renderer.BufferManager.Delete(_repeatingBuffer);
|
||||
}
|
||||
|
||||
_repeatingBuffer = newBuffer;
|
||||
|
||||
// Add the additional repeats on top.
|
||||
int newPrimitives = primitiveCount;
|
||||
int oldPrimitives = (_currentSize) / OffsetIndex.Length;
|
||||
|
||||
int[] newData;
|
||||
|
||||
newPrimitives -= oldPrimitives;
|
||||
newData = new int[expectedSize - _currentSize];
|
||||
|
||||
int outOffset = 0;
|
||||
int index = oldPrimitives * IndexStride + BaseIndex;
|
||||
|
||||
for (int i = 0; i < newPrimitives; i++)
|
||||
{
|
||||
if (RepeatStart)
|
||||
{
|
||||
// Used for triangle fan
|
||||
newData[outOffset++] = 0;
|
||||
}
|
||||
|
||||
for (int j = RepeatStart ? 1 : 0; j < OffsetIndex.Length; j++)
|
||||
{
|
||||
newData[outOffset++] = index + OffsetIndex[j];
|
||||
}
|
||||
|
||||
index += IndexStride;
|
||||
}
|
||||
|
||||
_renderer.SetBufferData(newBuffer, _currentSize * sizeof(int), MemoryMarshal.Cast<int, byte>(newData));
|
||||
_currentSize = expectedSize;
|
||||
|
||||
return newBuffer;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_repeatingBuffer != BufferHandle.Null)
|
||||
{
|
||||
_renderer.BufferManager.Delete(_repeatingBuffer);
|
||||
_repeatingBuffer = BufferHandle.Null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user