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
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
135 changed files with 302 additions and 15077 deletions

View file

@ -26,6 +26,5 @@ namespace Ryujinx.Graphics.Shader.Translation
SharedMemory = 1 << 11,
Store = 1 << 12,
VtgAsCompute = 1 << 13,
Precise = 1 << 14,
}
}

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;

View file

@ -4,6 +4,5 @@ namespace Ryujinx.Graphics.Shader.Translation
{
OpenGL,
Vulkan,
Metal
}
}

View file

@ -4,6 +4,6 @@ namespace Ryujinx.Graphics.Shader.Translation
{
Glsl,
Spirv,
Msl
Arb,
}
}

View file

@ -27,8 +27,6 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
addOp.Inst == (Instruction.FP32 | Instruction.Add) &&
addOp.GetSource(1).Type == OperandType.Constant)
{
context.UsedFeatures |= FeatureFlags.Precise;
addOp.ForcePrecise = true;
}

View file

@ -1,6 +1,5 @@
using Ryujinx.Graphics.Shader.CodeGen;
using Ryujinx.Graphics.Shader.CodeGen.Glsl;
using Ryujinx.Graphics.Shader.CodeGen.Msl;
using Ryujinx.Graphics.Shader.CodeGen.Spirv;
using Ryujinx.Graphics.Shader.Decoders;
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
@ -243,8 +242,8 @@ namespace Ryujinx.Graphics.Shader.Translation
usedFeatures |= FeatureFlags.VtgAsCompute;
}
ControlFlowGraph[] cfgs = new ControlFlowGraph[functions.Length];
RegisterUsage.FunctionRegisterUsage[] frus = new RegisterUsage.FunctionRegisterUsage[functions.Length];
var cfgs = new ControlFlowGraph[functions.Length];
var frus = new RegisterUsage.FunctionRegisterUsage[functions.Length];
for (int i = 0; i < functions.Length; i++)
{
@ -267,14 +266,14 @@ namespace Ryujinx.Graphics.Shader.Translation
for (int i = 0; i < functions.Length; i++)
{
ControlFlowGraph cfg = cfgs[i];
var cfg = cfgs[i];
int inArgumentsCount = 0;
int outArgumentsCount = 0;
if (i != 0)
{
RegisterUsage.FunctionRegisterUsage fru = frus[i];
var fru = frus[i];
inArgumentsCount = fru.InArguments.Length;
outArgumentsCount = fru.OutArguments.Length;
@ -326,13 +325,12 @@ namespace Ryujinx.Graphics.Shader.Translation
FeatureFlags usedFeatures,
byte clipDistancesWritten)
{
StructuredProgramInfo sInfo = StructuredProgram.MakeStructuredProgram(
var sInfo = StructuredProgram.MakeStructuredProgram(
funcs,
attributeUsage,
definitions,
resourceManager,
Options.TargetLanguage,
usedFeatures.HasFlag(FeatureFlags.Precise),
Options.Flags.HasFlag(TranslationFlags.DebugMode));
int geometryVerticesPerPrimitive = Definitions.OutputTopology switch
@ -342,7 +340,7 @@ namespace Ryujinx.Graphics.Shader.Translation
_ => 1
};
ShaderProgramInfo info = new(
var info = new ShaderProgramInfo(
resourceManager.GetConstantBufferDescriptors(),
resourceManager.GetStorageBufferDescriptors(),
resourceManager.GetTextureDescriptors(),
@ -358,7 +356,7 @@ namespace Ryujinx.Graphics.Shader.Translation
clipDistancesWritten,
originalDefinitions.OmapTargets);
HostCapabilities hostCapabilities = new(
var hostCapabilities = new HostCapabilities(
GpuAccessor.QueryHostReducedPrecision(),
GpuAccessor.QueryHostSupportsFragmentShaderInterlock(),
GpuAccessor.QueryHostSupportsFragmentShaderOrderingIntel(),
@ -369,13 +367,12 @@ namespace Ryujinx.Graphics.Shader.Translation
GpuAccessor.QueryHostSupportsTextureShadowLod(),
GpuAccessor.QueryHostSupportsViewportMask());
CodeGenParameters parameters = new(attributeUsage, definitions, resourceManager.Properties, hostCapabilities, GpuAccessor, Options.TargetApi);
var parameters = new CodeGenParameters(attributeUsage, definitions, resourceManager.Properties, hostCapabilities, GpuAccessor, Options.TargetApi);
return Options.TargetLanguage switch
{
TargetLanguage.Glsl => new ShaderProgram(info, TargetLanguage.Glsl, GlslGenerator.Generate(sInfo, parameters)),
TargetLanguage.Spirv => new ShaderProgram(info, TargetLanguage.Spirv, SpirvGenerator.Generate(sInfo, parameters)),
TargetLanguage.Msl => new ShaderProgram(info, TargetLanguage.Msl, MslGenerator.Generate(sInfo, parameters)),
_ => throw new NotImplementedException(Options.TargetLanguage.ToString()),
};
}
@ -386,15 +383,16 @@ namespace Ryujinx.Graphics.Shader.Translation
if (IsTransformFeedbackEmulated)
{
StructureType tfeDataStruct = new([
new(AggregateType.Array | AggregateType.U32, "data", 0)
]);
StructureType tfeDataStruct = new(new StructureField[]
{
new StructureField(AggregateType.Array | AggregateType.U32, "data", 0)
});
for (int i = 0; i < ResourceReservations.TfeBuffersCount; i++)
{
int binding = resourceManager.Reservations.GetTfeBufferStorageBufferBinding(i);
BufferDefinition tfeDataBuffer = new(BufferLayout.Std430, 1, binding, $"tfe_data{i}", tfeDataStruct);
resourceManager.AddVertexAsComputeStorageBuffer(tfeDataBuffer);
resourceManager.Properties.AddOrUpdateStorageBuffer(tfeDataBuffer);
}
}
@ -402,21 +400,22 @@ namespace Ryujinx.Graphics.Shader.Translation
{
int vertexInfoCbBinding = resourceManager.Reservations.VertexInfoConstantBufferBinding;
BufferDefinition vertexInfoBuffer = new(BufferLayout.Std140, 0, vertexInfoCbBinding, "vb_info", VertexInfoBuffer.GetStructureType());
resourceManager.AddVertexAsComputeConstantBuffer(vertexInfoBuffer);
resourceManager.Properties.AddOrUpdateConstantBuffer(vertexInfoBuffer);
StructureType vertexOutputStruct = new([
new(AggregateType.Array | AggregateType.FP32, "data", 0)
]);
StructureType vertexOutputStruct = new(new StructureField[]
{
new StructureField(AggregateType.Array | AggregateType.FP32, "data", 0)
});
int vertexOutputSbBinding = resourceManager.Reservations.VertexOutputStorageBufferBinding;
BufferDefinition vertexOutputBuffer = new(BufferLayout.Std430, 1, vertexOutputSbBinding, "vertex_output", vertexOutputStruct);
resourceManager.AddVertexAsComputeStorageBuffer(vertexOutputBuffer);
resourceManager.Properties.AddOrUpdateStorageBuffer(vertexOutputBuffer);
if (Stage == ShaderStage.Vertex)
{
SetBindingPair ibSetAndBinding = resourceManager.Reservations.GetIndexBufferTextureSetAndBinding();
TextureDefinition indexBuffer = new(ibSetAndBinding.SetIndex, ibSetAndBinding.Binding, "ib_data", SamplerType.TextureBuffer);
resourceManager.AddVertexAsComputeTexture(indexBuffer);
resourceManager.Properties.AddOrUpdateTexture(indexBuffer);
int inputMap = _program.AttributeUsage.UsedInputAttributes;
@ -425,7 +424,7 @@ namespace Ryujinx.Graphics.Shader.Translation
int location = BitOperations.TrailingZeroCount(inputMap);
SetBindingPair setAndBinding = resourceManager.Reservations.GetVertexBufferTextureSetAndBinding(location);
TextureDefinition vaBuffer = new(setAndBinding.SetIndex, setAndBinding.Binding, $"vb_data{location}", SamplerType.TextureBuffer);
resourceManager.AddVertexAsComputeTexture(vaBuffer);
resourceManager.Properties.AddOrUpdateTexture(vaBuffer);
inputMap &= ~(1 << location);
}
@ -434,19 +433,20 @@ namespace Ryujinx.Graphics.Shader.Translation
{
SetBindingPair trbSetAndBinding = resourceManager.Reservations.GetTopologyRemapBufferTextureSetAndBinding();
TextureDefinition remapBuffer = new(trbSetAndBinding.SetIndex, trbSetAndBinding.Binding, "trb_data", SamplerType.TextureBuffer);
resourceManager.AddVertexAsComputeTexture(remapBuffer);
resourceManager.Properties.AddOrUpdateTexture(remapBuffer);
int geometryVbOutputSbBinding = resourceManager.Reservations.GeometryVertexOutputStorageBufferBinding;
BufferDefinition geometryVbOutputBuffer = new(BufferLayout.Std430, 1, geometryVbOutputSbBinding, "geometry_vb_output", vertexOutputStruct);
resourceManager.AddVertexAsComputeStorageBuffer(geometryVbOutputBuffer);
resourceManager.Properties.AddOrUpdateStorageBuffer(geometryVbOutputBuffer);
StructureType geometryIbOutputStruct = new([
new(AggregateType.Array | AggregateType.U32, "data", 0)
]);
StructureType geometryIbOutputStruct = new(new StructureField[]
{
new StructureField(AggregateType.Array | AggregateType.U32, "data", 0)
});
int geometryIbOutputSbBinding = resourceManager.Reservations.GeometryIndexOutputStorageBufferBinding;
BufferDefinition geometryIbOutputBuffer = new(BufferLayout.Std430, 1, geometryIbOutputSbBinding, "geometry_ib_output", geometryIbOutputStruct);
resourceManager.AddVertexAsComputeStorageBuffer(geometryIbOutputBuffer);
resourceManager.Properties.AddOrUpdateStorageBuffer(geometryIbOutputBuffer);
}
resourceManager.SetVertexAsComputeLocalMemories(Definitions.Stage, Definitions.InputTopology);
@ -479,40 +479,36 @@ namespace Ryujinx.Graphics.Shader.Translation
return new ResourceReservations(GpuAccessor, IsTransformFeedbackEmulated, vertexAsCompute: true, _vertexOutput, ioUsage);
}
public ShaderProgramInfo GetVertexAsComputeInfo()
{
return CreateResourceManager(true).GetVertexAsComputeInfo();
}
public void SetVertexOutputMapForGeometryAsCompute(TranslatorContext vertexContext)
{
_vertexOutput = vertexContext._program.GetIoUsage();
}
public (ShaderProgram, ShaderProgramInfo) GenerateVertexPassthroughForCompute()
public ShaderProgram GenerateVertexPassthroughForCompute()
{
AttributeUsage attributeUsage = new(GpuAccessor);
ResourceManager resourceManager = new(ShaderStage.Vertex, GpuAccessor);
var attributeUsage = new AttributeUsage(GpuAccessor);
var resourceManager = new ResourceManager(ShaderStage.Vertex, GpuAccessor);
ResourceReservations reservations = GetResourceReservations();
var reservations = GetResourceReservations();
int vertexInfoCbBinding = reservations.VertexInfoConstantBufferBinding;
if (Stage == ShaderStage.Vertex)
{
BufferDefinition vertexInfoBuffer = new(BufferLayout.Std140, 0, vertexInfoCbBinding, "vb_info", VertexInfoBuffer.GetStructureType());
resourceManager.AddVertexAsComputeConstantBuffer(vertexInfoBuffer);
resourceManager.Properties.AddOrUpdateConstantBuffer(vertexInfoBuffer);
}
StructureType vertexInputStruct = new([
new(AggregateType.Array | AggregateType.FP32, "data", 0)
]);
StructureType vertexInputStruct = new(new StructureField[]
{
new StructureField(AggregateType.Array | AggregateType.FP32, "data", 0)
});
int vertexDataSbBinding = reservations.VertexOutputStorageBufferBinding;
BufferDefinition vertexOutputBuffer = new(BufferLayout.Std430, 1, vertexDataSbBinding, "vb_input", vertexInputStruct);
resourceManager.AddVertexAsComputeStorageBuffer(vertexOutputBuffer);
resourceManager.Properties.AddOrUpdateStorageBuffer(vertexOutputBuffer);
EmitterContext context = new();
var context = new EmitterContext();
Operand vertexIndex = Options.TargetApi == TargetApi.OpenGL
? context.Load(StorageKind.Input, IoVariable.VertexId)
@ -557,25 +553,25 @@ namespace Ryujinx.Graphics.Shader.Translation
}
}
Operation[] operations = context.GetOperations();
ControlFlowGraph cfg = ControlFlowGraph.Create(operations);
Function function = new(cfg.Blocks, "main", false, 0, 0);
var operations = context.GetOperations();
var cfg = ControlFlowGraph.Create(operations);
var function = new Function(cfg.Blocks, "main", false, 0, 0);
TransformFeedbackOutput[] transformFeedbackOutputs = GetTransformFeedbackOutputs(GpuAccessor, out ulong transformFeedbackVecMap);
var transformFeedbackOutputs = GetTransformFeedbackOutputs(GpuAccessor, out ulong transformFeedbackVecMap);
ShaderDefinitions definitions = new(ShaderStage.Vertex, transformFeedbackVecMap, transformFeedbackOutputs)
var definitions = new ShaderDefinitions(ShaderStage.Vertex, transformFeedbackVecMap, transformFeedbackOutputs)
{
LastInVertexPipeline = true
};
return (Generate(
[function],
return Generate(
new[] { function },
attributeUsage,
definitions,
definitions,
resourceManager,
FeatureFlags.None,
0), resourceManager.GetVertexAsComputeInfo(isVertex: true));
0);
}
public ShaderProgram GenerateGeometryPassthrough()
@ -608,10 +604,10 @@ namespace Ryujinx.Graphics.Shader.Translation
break;
}
AttributeUsage attributeUsage = new(GpuAccessor);
ResourceManager resourceManager = new(ShaderStage.Geometry, GpuAccessor);
var attributeUsage = new AttributeUsage(GpuAccessor);
var resourceManager = new ResourceManager(ShaderStage.Geometry, GpuAccessor);
EmitterContext context = new();
var context = new EmitterContext();
for (int v = 0; v < maxOutputVertices; v++)
{
@ -652,11 +648,11 @@ namespace Ryujinx.Graphics.Shader.Translation
context.EndPrimitive();
Operation[] operations = context.GetOperations();
ControlFlowGraph cfg = ControlFlowGraph.Create(operations);
Function function = new(cfg.Blocks, "main", false, 0, 0);
var operations = context.GetOperations();
var cfg = ControlFlowGraph.Create(operations);
var function = new Function(cfg.Blocks, "main", false, 0, 0);
ShaderDefinitions definitions = new(
var definitions = new ShaderDefinitions(
ShaderStage.Geometry,
GpuAccessor.QueryGraphicsState(),
false,
@ -665,7 +661,7 @@ namespace Ryujinx.Graphics.Shader.Translation
maxOutputVertices);
return Generate(
[function],
new[] { function },
attributeUsage,
definitions,
definitions,