aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Ryujinx.Graphics.Shader/Decoders/Decoder.cs49
-rw-r--r--Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs33
2 files changed, 35 insertions, 47 deletions
diff --git a/Ryujinx.Graphics.Shader/Decoders/Decoder.cs b/Ryujinx.Graphics.Shader/Decoders/Decoder.cs
index cda88302..3e322e45 100644
--- a/Ryujinx.Graphics.Shader/Decoders/Decoder.cs
+++ b/Ryujinx.Graphics.Shader/Decoders/Decoder.cs
@@ -1,10 +1,8 @@
using Ryujinx.Graphics.Shader.Instructions;
using System;
using System.Buffers.Binary;
-using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
-using System.Reflection.Emit;
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
@@ -12,15 +10,6 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
static class Decoder
{
- private delegate object OpActivator(InstEmitter emitter, ulong address, long opCode);
-
- private static ConcurrentDictionary<Type, OpActivator> _opActivators;
-
- static Decoder()
- {
- _opActivators = new ConcurrentDictionary<Type, OpActivator>();
- }
-
public static Block[] Decode(ReadOnlySpan<byte> code, ulong headerSize)
{
List<Block> blocks = new List<Block>();
@@ -245,7 +234,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
long opCode = word0 | (long)word1 << 32;
- (InstEmitter emitter, Type opCodeType) = OpCodeTable.GetEmitter(opCode);
+ (InstEmitter emitter, OpCodeTable.OpActivator opActivator) = OpCodeTable.GetEmitter(opCode);
if (emitter == null)
{
@@ -256,7 +245,12 @@ namespace Ryujinx.Graphics.Shader.Decoders
continue;
}
- OpCode op = MakeOpCode(opCodeType, emitter, opAddress, opCode);
+ if (opActivator == null)
+ {
+ throw new ArgumentNullException(nameof(opActivator));
+ }
+
+ OpCode op = (OpCode)opActivator(emitter, opAddress, opCode);
block.OpCodes.Add(op);
}
@@ -295,35 +289,6 @@ namespace Ryujinx.Graphics.Shader.Decoders
return opCode is OpCodeExit;
}
- private static OpCode MakeOpCode(Type type, InstEmitter emitter, ulong address, long opCode)
- {
- if (type == null)
- {
- throw new ArgumentNullException(nameof(type));
- }
-
- OpActivator createInstance = _opActivators.GetOrAdd(type, CacheOpActivator);
-
- return (OpCode)createInstance(emitter, address, opCode);
- }
-
- private static OpActivator CacheOpActivator(Type type)
- {
- Type[] argTypes = new Type[] { typeof(InstEmitter), typeof(ulong), typeof(long) };
-
- DynamicMethod mthd = new DynamicMethod($"Make{type.Name}", type, argTypes);
-
- ILGenerator generator = mthd.GetILGenerator();
-
- generator.Emit(OpCodes.Ldarg_0);
- generator.Emit(OpCodes.Ldarg_1);
- generator.Emit(OpCodes.Ldarg_2);
- generator.Emit(OpCodes.Newobj, type.GetConstructor(argTypes));
- generator.Emit(OpCodes.Ret);
-
- return (OpActivator)mthd.CreateDelegate(typeof(OpActivator));
- }
-
private struct PathBlockState
{
public Block Block { get; }
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs
index e71c3186..9835be34 100644
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs
+++ b/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs
@@ -1,10 +1,13 @@
using Ryujinx.Graphics.Shader.Instructions;
using System;
+using System.Reflection.Emit;
namespace Ryujinx.Graphics.Shader.Decoders
{
static class OpCodeTable
{
+ public delegate object OpActivator(InstEmitter emitter, ulong address, long opCode);
+
private const int EncodingBits = 14;
private class TableEntry
@@ -15,11 +18,31 @@ namespace Ryujinx.Graphics.Shader.Decoders
public int XBits { get; }
+ public OpActivator OpActivator { get; }
+
public TableEntry(InstEmitter emitter, Type opCodeType, int xBits)
{
- Emitter = emitter;
- OpCodeType = opCodeType;
- XBits = xBits;
+ Emitter = emitter;
+ OpCodeType = opCodeType;
+ XBits = xBits;
+ OpActivator = CacheOpActivator(opCodeType);
+ }
+
+ private static OpActivator CacheOpActivator(Type type)
+ {
+ Type[] argTypes = new Type[] { typeof(InstEmitter), typeof(ulong), typeof(long) };
+
+ DynamicMethod mthd = new DynamicMethod($"Make{type.Name}", type, argTypes);
+
+ ILGenerator generator = mthd.GetILGenerator();
+
+ generator.Emit(OpCodes.Ldarg_0);
+ generator.Emit(OpCodes.Ldarg_1);
+ generator.Emit(OpCodes.Ldarg_2);
+ generator.Emit(OpCodes.Newobj, type.GetConstructor(argTypes));
+ generator.Emit(OpCodes.Ret);
+
+ return (OpActivator)mthd.CreateDelegate(typeof(OpActivator));
}
}
@@ -266,13 +289,13 @@ namespace Ryujinx.Graphics.Shader.Decoders
}
}
- public static (InstEmitter emitter, Type opCodeType) GetEmitter(long opCode)
+ public static (InstEmitter emitter, OpActivator opActivator) GetEmitter(long opCode)
{
TableEntry entry = _opCodes[(ulong)opCode >> (64 - EncodingBits)];
if (entry != null)
{
- return (entry.Emitter, entry.OpCodeType);
+ return (entry.Emitter, entry.OpActivator);
}
return (null, null);