diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGen.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGen.cs index 5d36b76dda..ffb2105eac 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGen.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGen.cs @@ -6,6 +6,7 @@ using System; using static Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions.InstGenCall; using static Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions.InstGenHelper; using static Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions.InstGenMemory; +using static Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions.InstGenVector; using static Ryujinx.Graphics.Shader.StructuredIr.InstructionInfo; namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions @@ -137,9 +138,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions case Instruction.TextureSample: return TextureSample(context, operation); case Instruction.TextureSize: - return "|| TEXTURE SIZE ||"; + return TextureSize(context, operation); case Instruction.VectorExtract: - return "|| VECTOR EXTRACT ||"; + return VectorExtract(context, operation); case Instruction.VoteAllEqual: return "|| VOTE ALL EQUAL ||"; } diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGenMemory.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGenMemory.cs index d38b44dcb3..1773c17ab7 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGenMemory.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGenMemory.cs @@ -3,6 +3,7 @@ using Ryujinx.Graphics.Shader.StructuredIr; using Ryujinx.Graphics.Shader.Translation; using System; using static Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions.InstGenHelper; +using static Ryujinx.Graphics.Shader.StructuredIr.InstructionInfo; namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions { @@ -235,6 +236,12 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions return resourceDefinitions.Textures[textOp.Binding].Name; } + // TODO: Verify that this is valid in MSL + private static string GetMask(int index) + { + return $".{"rgba".AsSpan(index, 1)}"; + } + private static string GetMaskMultiDest(int mask) { string swizzle = "."; @@ -249,5 +256,51 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions return swizzle; } + + public static string TextureSize(CodeGenContext context, AstOperation operation) + { + AstTextureOperation texOp = (AstTextureOperation)operation; + + string textureName = "texture"; + string texCall = textureName + "."; + + if (texOp.Index == 3) + { + texCall += $"get_num_mip_levels()"; + } + else + { + context.Properties.Textures.TryGetValue(texOp.Binding, out TextureDefinition definition); + bool hasLod = !definition.Type.HasFlag(SamplerType.Multisample) && (definition.Type & SamplerType.Mask) != SamplerType.TextureBuffer; + texCall += "get_"; + + if (texOp.Index == 0) + { + texCall += "width"; + } + else if (texOp.Index == 1) + { + texCall += "height"; + } + else + { + texCall += "depth"; + } + + texCall += "("; + + if (hasLod) + { + IAstNode lod = operation.GetSource(0); + string lodExpr = GetSourceExpr(context, lod, GetSrcVarType(operation.Inst, 0)); + + texCall += $"{lodExpr}"; + } + + texCall += $"){GetMask(texOp.Index)}"; + } + + return texCall; + } } } diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGenVector.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGenVector.cs new file mode 100644 index 0000000000..9d8dae543b --- /dev/null +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGenVector.cs @@ -0,0 +1,32 @@ +using Ryujinx.Graphics.Shader.IntermediateRepresentation; +using Ryujinx.Graphics.Shader.StructuredIr; + +using static Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions.InstGenHelper; +using static Ryujinx.Graphics.Shader.StructuredIr.InstructionInfo; + +namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions +{ + static class InstGenVector + { + public static string VectorExtract(CodeGenContext context, AstOperation operation) + { + IAstNode vector = operation.GetSource(0); + IAstNode index = operation.GetSource(1); + + string vectorExpr = GetSourceExpr(context, vector, OperandManager.GetNodeDestType(context, vector)); + + if (index is AstOperand indexOperand && indexOperand.Type == OperandType.Constant) + { + char elem = "xyzw"[indexOperand.Value]; + + return $"{vectorExpr}.{elem}"; + } + else + { + string indexExpr = GetSourceExpr(context, index, GetSrcVarType(operation.Inst, 1)); + + return $"{vectorExpr}[{indexExpr}]"; + } + } + } +}