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:
Evan Husted
2025-02-22 21:26:46 -06:00
committed by GitHub
parent eb6b0e9adc
commit fe1617ffea
135 changed files with 302 additions and 15077 deletions

View File

@@ -14,7 +14,7 @@ namespace Ryujinx.Graphics.Shader.Translation
private const int DefaultLocalMemorySize = 128;
private const int DefaultSharedMemorySize = 4096;
private static readonly string[] _stagePrefixes = ["cp", "vp", "tcp", "tep", "gp", "fp"];
private static readonly string[] _stagePrefixes = new string[] { "cp", "vp", "tcp", "tep", "gp", "fp" };
private readonly IGpuAccessor _gpuAccessor;
private readonly ShaderStage _stage;
@@ -43,11 +43,6 @@ namespace Ryujinx.Graphics.Shader.Translation
private readonly Dictionary<TextureInfo, TextureMeta> _usedTextures;
private readonly Dictionary<TextureInfo, TextureMeta> _usedImages;
private readonly List<BufferDefinition> _vacConstantBuffers;
private readonly List<BufferDefinition> _vacStorageBuffers;
private readonly List<TextureDefinition> _vacTextures;
private readonly List<TextureDefinition> _vacImages;
public int LocalMemoryId { get; private set; }
public int SharedMemoryId { get; private set; }
@@ -78,16 +73,11 @@ namespace Ryujinx.Graphics.Shader.Translation
_sbSlots = new();
_sbSlotsReverse = new();
_usedConstantBufferBindings = [];
_usedConstantBufferBindings = new();
_usedTextures = new();
_usedImages = new();
_vacConstantBuffers = [];
_vacStorageBuffers = [];
_vacTextures = [];
_vacImages = [];
Properties.AddOrUpdateConstantBuffer(new(BufferLayout.Std140, 0, SupportBuffer.Binding, "support_buffer", SupportBuffer.GetStructureType()));
LocalMemoryId = -1;
@@ -103,7 +93,7 @@ namespace Ryujinx.Graphics.Shader.Translation
size = DefaultLocalMemorySize;
}
MemoryDefinition lmem = new("local_memory", AggregateType.Array | AggregateType.U32, BitUtils.DivRoundUp(size, sizeof(uint)));
var lmem = new MemoryDefinition("local_memory", AggregateType.Array | AggregateType.U32, BitUtils.DivRoundUp(size, sizeof(uint)));
LocalMemoryId = Properties.AddLocalMemory(lmem);
}
@@ -122,7 +112,7 @@ namespace Ryujinx.Graphics.Shader.Translation
size = DefaultSharedMemorySize;
}
MemoryDefinition smem = new("shared_memory", AggregateType.Array | AggregateType.U32, BitUtils.DivRoundUp(size, sizeof(uint)));
var smem = new MemoryDefinition("shared_memory", AggregateType.Array | AggregateType.U32, BitUtils.DivRoundUp(size, sizeof(uint)));
SharedMemoryId = Properties.AddSharedMemory(smem);
}
@@ -283,16 +273,16 @@ namespace Ryujinx.Graphics.Shader.Translation
bool coherent,
bool separate)
{
int dimensions = type == SamplerType.None ? 0 : type.GetDimensions();
Dictionary<TextureInfo, TextureMeta> dict = isImage ? _usedImages : _usedTextures;
var dimensions = type == SamplerType.None ? 0 : type.GetDimensions();
var dict = isImage ? _usedImages : _usedTextures;
TextureUsageFlags usageFlags = TextureUsageFlags.None;
var usageFlags = TextureUsageFlags.None;
if (intCoords)
{
usageFlags |= TextureUsageFlags.NeedsScaleValue;
bool canScale = _stage.SupportsRenderScale() && arrayLength == 1 && !write && dimensions == 2;
var canScale = _stage.SupportsRenderScale() && arrayLength == 1 && !write && dimensions == 2;
if (!canScale)
{
@@ -314,9 +304,9 @@ namespace Ryujinx.Graphics.Shader.Translation
// For array textures, we also want to use type as key,
// since we may have texture handles stores in the same buffer, but for textures with different types.
SamplerType keyType = arrayLength > 1 ? type : SamplerType.None;
TextureInfo info = new(cbufSlot, handle, arrayLength, separate, keyType, format);
TextureMeta meta = new()
var keyType = arrayLength > 1 ? type : SamplerType.None;
var info = new TextureInfo(cbufSlot, handle, arrayLength, separate, keyType, format);
var meta = new TextureMeta()
{
AccurateType = accurateType,
Type = type,
@@ -326,7 +316,7 @@ namespace Ryujinx.Graphics.Shader.Translation
int setIndex;
int binding;
if (dict.TryGetValue(info, out TextureMeta existingMeta))
if (dict.TryGetValue(info, out var existingMeta))
{
dict[info] = MergeTextureMeta(meta, existingMeta);
setIndex = existingMeta.Set;
@@ -383,7 +373,7 @@ namespace Ryujinx.Graphics.Shader.Translation
nameSuffix = cbufSlot < 0 ? $"{prefix}_tcb_{handle:X}" : $"{prefix}_cb{cbufSlot}_{handle:X}";
}
TextureDefinition definition = new(
var definition = new TextureDefinition(
setIndex,
binding,
arrayLength,
@@ -443,8 +433,8 @@ namespace Ryujinx.Graphics.Shader.Translation
{
selectedMeta.UsageFlags |= TextureUsageFlags.NeedsScaleValue;
int dimensions = type.GetDimensions();
bool canScale = _stage.SupportsRenderScale() && selectedInfo.ArrayLength == 1 && dimensions == 2;
var dimensions = type.GetDimensions();
var canScale = _stage.SupportsRenderScale() && selectedInfo.ArrayLength == 1 && dimensions == 2;
if (!canScale)
{
@@ -464,7 +454,7 @@ namespace Ryujinx.Graphics.Shader.Translation
public BufferDescriptor[] GetConstantBufferDescriptors()
{
BufferDescriptor[] descriptors = new BufferDescriptor[_usedConstantBufferBindings.Count];
var descriptors = new BufferDescriptor[_usedConstantBufferBindings.Count];
int descriptorIndex = 0;
@@ -488,7 +478,7 @@ namespace Ryujinx.Graphics.Shader.Translation
public BufferDescriptor[] GetStorageBufferDescriptors()
{
BufferDescriptor[] descriptors = new BufferDescriptor[_sbSlots.Count];
var descriptors = new BufferDescriptor[_sbSlots.Count];
int descriptorIndex = 0;
@@ -524,7 +514,7 @@ namespace Ryujinx.Graphics.Shader.Translation
private static TextureDescriptor[] GetDescriptors(IReadOnlyDictionary<TextureInfo, TextureMeta> usedResources, bool includeArrays)
{
List<TextureDescriptor> descriptors = [];
List<TextureDescriptor> descriptors = new();
bool hasAnyArray = false;
@@ -573,75 +563,6 @@ namespace Ryujinx.Graphics.Shader.Translation
return descriptors.ToArray();
}
public ShaderProgramInfo GetVertexAsComputeInfo(bool isVertex = false)
{
BufferDescriptor[] cbDescriptors = new BufferDescriptor[_vacConstantBuffers.Count];
int cbDescriptorIndex = 0;
foreach (BufferDefinition definition in _vacConstantBuffers)
{
cbDescriptors[cbDescriptorIndex++] = new BufferDescriptor(definition.Set, definition.Binding, 0, 0, 0, BufferUsageFlags.None);
}
BufferDescriptor[] sbDescriptors = new BufferDescriptor[_vacStorageBuffers.Count];
int sbDescriptorIndex = 0;
foreach (BufferDefinition definition in _vacStorageBuffers)
{
sbDescriptors[sbDescriptorIndex++] = new BufferDescriptor(definition.Set, definition.Binding, 0, 0, 0, BufferUsageFlags.Write);
}
TextureDescriptor[] tDescriptors = new TextureDescriptor[_vacTextures.Count];
int tDescriptorIndex = 0;
foreach (TextureDefinition definition in _vacTextures)
{
tDescriptors[tDescriptorIndex++] = new TextureDescriptor(
definition.Set,
definition.Binding,
definition.Type,
definition.Format,
0,
0,
definition.ArrayLength,
definition.Separate,
definition.Flags);
}
TextureDescriptor[] iDescriptors = new TextureDescriptor[_vacImages.Count];
int iDescriptorIndex = 0;
foreach (TextureDefinition definition in _vacImages)
{
iDescriptors[iDescriptorIndex++] = new TextureDescriptor(
definition.Set,
definition.Binding,
definition.Type,
definition.Format,
0,
0,
definition.ArrayLength,
definition.Separate,
definition.Flags);
}
return new ShaderProgramInfo(
cbDescriptors,
sbDescriptors,
tDescriptors,
iDescriptors,
isVertex ? ShaderStage.Vertex : ShaderStage.Compute,
0,
0,
0,
false,
false,
false,
false,
0,
0);
}
public bool TryGetCbufSlotAndHandleForTexture(int binding, out int cbufSlot, out int handle)
{
foreach ((TextureInfo info, TextureMeta meta) in _usedTextures)
@@ -690,46 +611,24 @@ namespace Ryujinx.Graphics.Shader.Translation
private void AddNewConstantBuffer(int setIndex, int binding, string name)
{
StructureType type = new([
new StructureField(AggregateType.Array | AggregateType.Vector4 | AggregateType.FP32, "data", Constants.ConstantBufferSize / 16)
]);
StructureType type = new(new[]
{
new StructureField(AggregateType.Array | AggregateType.Vector4 | AggregateType.FP32, "data", Constants.ConstantBufferSize / 16),
});
Properties.AddOrUpdateConstantBuffer(new(BufferLayout.Std140, setIndex, binding, name, type));
}
private void AddNewStorageBuffer(int setIndex, int binding, string name)
{
StructureType type = new([
new StructureField(AggregateType.Array | AggregateType.U32, "data", 0)
]);
StructureType type = new(new[]
{
new StructureField(AggregateType.Array | AggregateType.U32, "data", 0),
});
Properties.AddOrUpdateStorageBuffer(new(BufferLayout.Std430, setIndex, binding, name, type));
}
public void AddVertexAsComputeConstantBuffer(BufferDefinition definition)
{
_vacConstantBuffers.Add(definition);
Properties.AddOrUpdateConstantBuffer(definition);
}
public void AddVertexAsComputeStorageBuffer(BufferDefinition definition)
{
_vacStorageBuffers.Add(definition);
Properties.AddOrUpdateStorageBuffer(definition);
}
public void AddVertexAsComputeTexture(TextureDefinition definition)
{
_vacTextures.Add(definition);
Properties.AddOrUpdateTexture(definition);
}
public void AddVertexAsComputeImage(TextureDefinition definition)
{
_vacImages.Add(definition);
Properties.AddOrUpdateImage(definition);
}
public static string GetShaderStagePrefix(ShaderStage stage)
{
uint index = (uint)stage;