diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/CodeGenContext.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/CodeGenContext.cs index 435da9efb..551e7c281 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/CodeGenContext.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/CodeGenContext.cs @@ -14,7 +14,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl public ShaderConfig Config { get; } - public OperandManager OperandManager { get; } + public OperandManager OperandManager { get; } private readonly StringBuilder _sb; diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Declarations.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Declarations.cs index ee108893e..99f838d66 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Declarations.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Declarations.cs @@ -1,6 +1,9 @@ using Ryujinx.Graphics.Shader.StructuredIr; using Ryujinx.Graphics.Shader.Translation; using System; +using System.Collections; +using System.Collections.Generic; +using System.Numerics; namespace Ryujinx.Graphics.Shader.CodeGen.Msl { @@ -12,11 +15,14 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl context.AppendLine("#include "); context.AppendLine(); context.AppendLine("using namespace metal;"); + context.AppendLine(); if ((info.HelperFunctionsMask & HelperFunctionsMask.SwizzleAdd) != 0) { } + + DeclareInputAttributes(context, info); } public static void DeclareLocals(CodeGenContext context, StructuredFunction function) @@ -53,5 +59,28 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl _ => throw new ArgumentException($"Invalid variable type \"{type}\"."), }; } + + private static void DeclareInputAttributes(CodeGenContext context, StructuredProgramInfo info) + { + if (context.Config.UsedInputAttributes != 0) + { + context.AppendLine("struct VertexIn"); + context.EnterScope(); + + int usedAttributes = context.Config.UsedInputAttributes | context.Config.PassthroughAttributes; + while (usedAttributes != 0) + { + int index = BitOperations.TrailingZeroCount(usedAttributes); + + string name = $"{DefaultNames.IAttributePrefix}{index}"; + var type = context.Config.GpuAccessor.QueryAttributeType(index).ToVec4Type(TargetLanguage.Msl); + context.AppendLine($"{type} {name} [[attribute({index})]];"); + + usedAttributes &= ~(1 << index); + } + + context.LeaveScope(";"); + } + } } } \ No newline at end of file diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/MslGenerator.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/MslGenerator.cs index b11a7452d..31d370255 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/MslGenerator.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/MslGenerator.cs @@ -3,7 +3,7 @@ using Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions; using Ryujinx.Graphics.Shader.StructuredIr; using Ryujinx.Graphics.Shader.Translation; using System; - +using System.Linq; using static Ryujinx.Graphics.Shader.CodeGen.Msl.TypeConversion; namespace Ryujinx.Graphics.Shader.CodeGen.Msl @@ -77,6 +77,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl string funcKeyword = "inline"; string funcName = null; + if (isMainFunc) { if (stage == ShaderStage.Vertex) @@ -89,6 +90,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl funcKeyword = "fragment"; funcName = "fragmentMain"; } + + if (context.Config.UsedInputAttributes != 0) + { + args = args.Prepend("VertexIn in [[stage_in]]").ToArray(); + } } return $"{funcKeyword} {Declarations.GetVarTypeName(context, function.ReturnType)} {funcName ?? function.Name}({string.Join(", ", args)})"; diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/OperandManager.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/OperandManager.cs index 4aa177afa..389948169 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/OperandManager.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/OperandManager.cs @@ -11,7 +11,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl { class OperandManager { - private readonly Dictionary _locals; + private readonly Dictionary _locals; public OperandManager() { @@ -99,8 +99,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl IoVariable ioVariable = (IoVariable)varId.Value; bool isOutput = operation.StorageKind == StorageKind.Output || operation.StorageKind == StorageKind.OutputPerPatch; bool isPerPatch = operation.StorageKind == StorageKind.InputPerPatch || operation.StorageKind == StorageKind.OutputPerPatch; - int location = 0; - int component = 0; if (context.Config.HasPerLocationInputOrOutput(ioVariable, isOutput)) { @@ -109,14 +107,14 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl throw new InvalidOperationException($"Second input of {operation.Inst} with {operation.StorageKind} storage must be a constant operand."); } - location = vecIndex.Value; + int location = vecIndex.Value; if (operation.SourcesCount > 2 && operation.GetSource(2) is AstOperand elemIndex && elemIndex.Type == OperandType.Constant && context.Config.HasPerLocationInputOrOutputComponent(ioVariable, location, elemIndex.Value, isOutput)) { - component = elemIndex.Value; + int component = elemIndex.Value; } } diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/TypeConversion.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/TypeConversion.cs index edbdd77dd..44666c323 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/TypeConversion.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/TypeConversion.cs @@ -8,11 +8,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl { static class TypeConversion { -public static string ReinterpretCast( - CodeGenContext context, - IAstNode node, - AggregateType srcType, - AggregateType dstType) + public static string ReinterpretCast( + CodeGenContext context, + IAstNode node, + AggregateType srcType, + AggregateType dstType) { if (node is AstOperand operand && operand.Type == OperandType.Constant) { diff --git a/src/Ryujinx.Headless.SDL2/Metal/MetalWindow.cs b/src/Ryujinx.Headless.SDL2/Metal/MetalWindow.cs index c37bf2472..e10d6eb29 100644 --- a/src/Ryujinx.Headless.SDL2/Metal/MetalWindow.cs +++ b/src/Ryujinx.Headless.SDL2/Metal/MetalWindow.cs @@ -34,10 +34,7 @@ namespace Ryujinx.Headless.SDL2.Metal _caMetalLayer = new CAMetalLayer(SDL_Metal_GetLayer(SDL_Metal_CreateView(WindowHandle))); } - if (SDL2Driver.MainThreadDispatcher != null) - { - SDL2Driver.MainThreadDispatcher(CreateLayer); - } + SDL2Driver.MainThreadDispatcher?.Invoke(CreateLayer); } protected override void InitializeRenderer() { }