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;
}
}
}