using Ryujinx.Common; using Ryujinx.Graphics.GAL; using System; using System.Runtime.InteropServices; namespace Ryujinx.Graphics.Gpu.Engine.MME { /// /// Table with information about High-level implementations of GPU Macro code. /// static class MacroHLETable { /// /// Macroo High-level implementation table entry. /// struct TableEntry { /// /// Name of the Macro function. /// public MacroHLEFunctionName Name { get; } /// /// Hash of the original binary Macro function code. /// public Hash128 Hash { get; } /// /// Size (in bytes) of the original binary Macro function code. /// public int Length { get; } /// /// Creates a new table entry. /// /// Name of the Macro function /// Hash of the original binary Macro function code /// Size (in bytes) of the original binary Macro function code public TableEntry(MacroHLEFunctionName name, Hash128 hash, int length) { Name = name; Hash = hash; Length = length; } } private static readonly TableEntry[] Table = new TableEntry[] { new TableEntry(MacroHLEFunctionName.MultiDrawElementsIndirectCount, new Hash128(0x890AF57ED3FB1C37, 0x35D0C95C61F5386F), 0x19C) }; private static bool IsMacroHLESupported(Capabilities caps, MacroHLEFunctionName name) { if (name == MacroHLEFunctionName.MultiDrawElementsIndirectCount) { return caps.SupportsIndirectParameters; } return false; } /// /// Checks if there's a fast, High-level implementation of the specified Macro code available. /// /// Macro code to be checked /// Renderer capabilities to check for this macro HLE support /// Name of the function if a implementation is available and supported, otherwise /// True if there is a implementation available and supported, false otherwise public static bool TryGetMacroHLEFunction(ReadOnlySpan code, Capabilities caps, out MacroHLEFunctionName name) { var mc = MemoryMarshal.Cast(code); for (int i = 0; i < Table.Length; i++) { ref var entry = ref Table[i]; var hash = XXHash128.ComputeHash(mc.Slice(0, entry.Length)); if (hash == entry.Hash) { name = entry.Name; return IsMacroHLESupported(caps, name); } } name = MacroHLEFunctionName.None; return false; } } }