aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics/Gal
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2019-04-17 20:57:08 -0300
committerjduncanator <1518948+jduncanator@users.noreply.github.com>2019-04-18 09:57:08 +1000
commit6b23a2c125b9c48b5ebea92716004ef68698bb0f (patch)
tree69332df6fbbd8e2bddc522ba682fcc5c7a69e101 /Ryujinx.Graphics/Gal
parentb2e88b04a85b41cc60af3485d88c90429e84a218 (diff)
New shader translator implementation (#654)
* Start implementing a new shader translator * Fix shift instructions and a typo * Small refactoring on StructuredProgram, move RemovePhis method to a separate class * Initial geometry shader support * Implement TLD4 * Fix -- There's no negation on FMUL32I * Add constant folding and algebraic simplification optimizations, nits * Some leftovers from constant folding * Avoid cast for constant assignments * Add a branch elimination pass, and misc small fixes * Remove redundant branches, add expression propagation and other improvements on the code * Small leftovers -- add missing break and continue, remove unused properties, other improvements * Add null check to handle empty block cases on block visitor * Add HADD2 and HMUL2 half float shader instructions * Optimize pack/unpack sequences, some fixes related to half float instructions * Add TXQ, TLD, TLDS and TLD4S shader texture instructions, and some support for bindless textures, some refactoring on codegen * Fix copy paste mistake that caused RZ to be ignored on the AST instruction * Add workaround for conditional exit, and fix half float instruction with constant buffer * Add missing 0.0 source for TLDS.LZ variants * Simplify the switch for TLDS.LZ * Texture instructions related fixes * Implement the HFMA instruction, and some misc. fixes * Enable constant folding on UnpackHalf2x16 instructions * Refactor HFMA to use OpCode* for opcode decoding rather than on the helper methods * Remove the old shader translator * Remove ShaderDeclInfo and other unused things * Add dual vertex shader support * Add ShaderConfig, used to pass shader type and maximum cbuffer size * Move and rename some instruction enums * Move texture instructions into a separate file * Move operand GetExpression and locals management to OperandManager * Optimize opcode decoding using a simple list and binary search * Add missing condition for do-while on goto elimination * Misc. fixes on texture instructions * Simplify TLDS switch * Address PR feedback, and a nit
Diffstat (limited to 'Ryujinx.Graphics/Gal')
-rw-r--r--Ryujinx.Graphics/Gal/IGalShader.cs5
-rw-r--r--Ryujinx.Graphics/Gal/OpenGL/OglPipeline.cs5
-rw-r--r--Ryujinx.Graphics/Gal/OpenGL/OglShader.cs51
-rw-r--r--Ryujinx.Graphics/Gal/OpenGL/OglShaderProgram.cs13
-rw-r--r--Ryujinx.Graphics/Gal/Shader/GlslDecl.cs420
-rw-r--r--Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs1679
-rw-r--r--Ryujinx.Graphics/Gal/Shader/GlslProgram.cs22
-rw-r--r--Ryujinx.Graphics/Gal/Shader/ShaderDecodeAlu.cs1299
-rw-r--r--Ryujinx.Graphics/Gal/Shader/ShaderDecodeFlow.cs57
-rw-r--r--Ryujinx.Graphics/Gal/Shader/ShaderDecodeFunc.cs4
-rw-r--r--Ryujinx.Graphics/Gal/Shader/ShaderDecodeHelper.cs78
-rw-r--r--Ryujinx.Graphics/Gal/Shader/ShaderDecodeMem.cs878
-rw-r--r--Ryujinx.Graphics/Gal/Shader/ShaderDecodeMove.cs431
-rw-r--r--Ryujinx.Graphics/Gal/Shader/ShaderDecodeOpCode.cs313
-rw-r--r--Ryujinx.Graphics/Gal/Shader/ShaderDecodeSpecial.cs25
-rw-r--r--Ryujinx.Graphics/Gal/Shader/ShaderDecoder.cs218
-rw-r--r--Ryujinx.Graphics/Gal/Shader/ShaderHeader.cs146
-rw-r--r--Ryujinx.Graphics/Gal/Shader/ShaderIpaMode.cs10
-rw-r--r--Ryujinx.Graphics/Gal/Shader/ShaderIrAsg.cs14
-rw-r--r--Ryujinx.Graphics/Gal/Shader/ShaderIrBlock.cs46
-rw-r--r--Ryujinx.Graphics/Gal/Shader/ShaderIrCmnt.cs12
-rw-r--r--Ryujinx.Graphics/Gal/Shader/ShaderIrCond.cs17
-rw-r--r--Ryujinx.Graphics/Gal/Shader/ShaderIrInst.cs94
-rw-r--r--Ryujinx.Graphics/Gal/Shader/ShaderIrMeta.cs4
-rw-r--r--Ryujinx.Graphics/Gal/Shader/ShaderIrMetaIpa.cs12
-rw-r--r--Ryujinx.Graphics/Gal/Shader/ShaderIrMetaTex.cs24
-rw-r--r--Ryujinx.Graphics/Gal/Shader/ShaderIrMetaTexq.cs15
-rw-r--r--Ryujinx.Graphics/Gal/Shader/ShaderIrNode.cs4
-rw-r--r--Ryujinx.Graphics/Gal/Shader/ShaderIrOp.cs25
-rw-r--r--Ryujinx.Graphics/Gal/Shader/ShaderIrOperAbuf.cs15
-rw-r--r--Ryujinx.Graphics/Gal/Shader/ShaderIrOperCbuf.cs17
-rw-r--r--Ryujinx.Graphics/Gal/Shader/ShaderIrOperGpr.cs36
-rw-r--r--Ryujinx.Graphics/Gal/Shader/ShaderIrOperImm.cs12
-rw-r--r--Ryujinx.Graphics/Gal/Shader/ShaderIrOperImmf.cs12
-rw-r--r--Ryujinx.Graphics/Gal/Shader/ShaderIrOperPred.cs17
-rw-r--r--Ryujinx.Graphics/Gal/Shader/ShaderOpCodeTable.cs190
-rw-r--r--Ryujinx.Graphics/Gal/Shader/ShaderOper.cs11
-rw-r--r--Ryujinx.Graphics/Gal/Shader/ShaderRegisterSize.cs9
-rw-r--r--Ryujinx.Graphics/Gal/Shader/ShaderTexqInfo.cs13
-rw-r--r--Ryujinx.Graphics/Gal/ShaderDeclInfo.cs45
40 files changed, 35 insertions, 6263 deletions
diff --git a/Ryujinx.Graphics/Gal/IGalShader.cs b/Ryujinx.Graphics/Gal/IGalShader.cs
index 99cd4d76..6a9abe75 100644
--- a/Ryujinx.Graphics/Gal/IGalShader.cs
+++ b/Ryujinx.Graphics/Gal/IGalShader.cs
@@ -1,3 +1,4 @@
+using Ryujinx.Graphics.Shader;
using System.Collections.Generic;
namespace Ryujinx.Graphics.Gal
@@ -8,8 +9,8 @@ namespace Ryujinx.Graphics.Gal
void Create(IGalMemory memory, long vpAPos, long key, GalShaderType type);
- IEnumerable<ShaderDeclInfo> GetConstBufferUsage(long key);
- IEnumerable<ShaderDeclInfo> GetTextureUsage(long key);
+ IEnumerable<CBufferDescriptor> GetConstBufferUsage(long key);
+ IEnumerable<TextureDescriptor> GetTextureUsage(long key);
void Bind(long key);
diff --git a/Ryujinx.Graphics/Gal/OpenGL/OglPipeline.cs b/Ryujinx.Graphics/Gal/OpenGL/OglPipeline.cs
index 3c8ada3e..64768e28 100644
--- a/Ryujinx.Graphics/Gal/OpenGL/OglPipeline.cs
+++ b/Ryujinx.Graphics/Gal/OpenGL/OglPipeline.cs
@@ -1,4 +1,5 @@
using OpenTK.Graphics.OpenGL;
+using Ryujinx.Graphics.Shader;
using System;
using System.Collections.Generic;
@@ -529,9 +530,9 @@ namespace Ryujinx.Graphics.Gal.OpenGL
{
if (stage != null)
{
- foreach (ShaderDeclInfo declInfo in stage.ConstBufferUsage)
+ foreach (CBufferDescriptor desc in stage.ConstBufferUsage)
{
- long key = New.ConstBufferKeys[(int)stage.Type][declInfo.Cbuf];
+ long key = New.ConstBufferKeys[(int)stage.Type][desc.Slot];
if (key != 0 && _buffer.TryGetUbo(key, out int uboHandle))
{
diff --git a/Ryujinx.Graphics/Gal/OpenGL/OglShader.cs b/Ryujinx.Graphics/Gal/OpenGL/OglShader.cs
index 8faa9053..8f4072c5 100644
--- a/Ryujinx.Graphics/Gal/OpenGL/OglShader.cs
+++ b/Ryujinx.Graphics/Gal/OpenGL/OglShader.cs
@@ -1,5 +1,6 @@
using OpenTK.Graphics.OpenGL;
-using Ryujinx.Graphics.Gal.Shader;
+using Ryujinx.Graphics.Shader;
+using Ryujinx.Graphics.Shader.Translation;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -51,54 +52,54 @@ namespace Ryujinx.Graphics.Gal.OpenGL
bool isDualVp,
GalShaderType type)
{
- GlslProgram program;
+ ShaderConfig config = new ShaderConfig(type, OglLimit.MaxUboSize);
- GlslDecompiler decompiler = new GlslDecompiler(OglLimit.MaxUboSize, OglExtension.NvidiaDriver);
-
- int shaderDumpIndex = ShaderDumper.DumpIndex;
+ ShaderProgram program;
if (isDualVp)
{
ShaderDumper.Dump(memory, position, type, "a");
ShaderDumper.Dump(memory, positionB, type, "b");
- program = decompiler.Decompile(memory, position, positionB, type);
+ program = Translator.Translate(memory, (ulong)position, (ulong)positionB, config);
}
else
{
ShaderDumper.Dump(memory, position, type);
- program = decompiler.Decompile(memory, position, type);
+ program = Translator.Translate(memory, (ulong)position, config);
}
string code = program.Code;
if (ShaderDumper.IsDumpEnabled())
{
+ int shaderDumpIndex = ShaderDumper.DumpIndex;
+
code = "//Shader " + shaderDumpIndex + Environment.NewLine + code;
}
- return new OglShaderStage(type, code, program.Uniforms, program.Textures);
+ return new OglShaderStage(type, code, program.Info.CBuffers, program.Info.Textures);
}
- public IEnumerable<ShaderDeclInfo> GetConstBufferUsage(long key)
+ public IEnumerable<CBufferDescriptor> GetConstBufferUsage(long key)
{
if (_stages.TryGetValue(key, out OglShaderStage stage))
{
return stage.ConstBufferUsage;
}
- return Enumerable.Empty<ShaderDeclInfo>();
+ return Enumerable.Empty<CBufferDescriptor>();
}
- public IEnumerable<ShaderDeclInfo> GetTextureUsage(long key)
+ public IEnumerable<TextureDescriptor> GetTextureUsage(long key)
{
if (_stages.TryGetValue(key, out OglShaderStage stage))
{
return stage.TextureUsage;
}
- return Enumerable.Empty<ShaderDeclInfo>();
+ return Enumerable.Empty<TextureDescriptor>();
}
public unsafe void SetExtraData(float flipX, float flipY, int instance)
@@ -130,16 +131,6 @@ namespace Ryujinx.Graphics.Gal.OpenGL
private void Bind(OglShaderStage stage)
{
- if (stage.Type == GalShaderType.Geometry)
- {
- //Enhanced layouts are required for Geometry shaders
- //skip this stage if current driver has no ARB_enhanced_layouts
- if (!OglExtension.EnhancedLayouts)
- {
- return;
- }
- }
-
switch (stage.Type)
{
case GalShaderType.Vertex: Current.Vertex = stage; break;
@@ -221,7 +212,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
private void BindUniformBlocks(int programHandle)
{
- int extraBlockindex = GL.GetUniformBlockIndex(programHandle, GlslDecl.ExtraUniformBlockName);
+ int extraBlockindex = GL.GetUniformBlockIndex(programHandle, "Extra");
GL.UniformBlockBinding(programHandle, extraBlockindex, 0);
@@ -231,14 +222,16 @@ namespace Ryujinx.Graphics.Gal.OpenGL
{
if (stage != null)
{
- foreach (ShaderDeclInfo declInfo in stage.ConstBufferUsage)
+ foreach (CBufferDescriptor desc in stage.ConstBufferUsage)
{
- int blockIndex = GL.GetUniformBlockIndex(programHandle, declInfo.Name);
+ int blockIndex = GL.GetUniformBlockIndex(programHandle, desc.Name);
if (blockIndex < 0)
{
- //It is expected that its found, if it's not then driver might be in a malfunction
- throw new InvalidOperationException();
+ //This may be fine, the compiler may optimize away unused uniform buffers,
+ //and in this case the above call would return -1 as the buffer has been
+ //optimized away.
+ continue;
}
GL.UniformBlockBinding(programHandle, blockIndex, freeBinding);
@@ -263,9 +256,9 @@ namespace Ryujinx.Graphics.Gal.OpenGL
{
if (stage != null)
{
- foreach (ShaderDeclInfo decl in stage.TextureUsage)
+ foreach (TextureDescriptor desc in stage.TextureUsage)
{
- int location = GL.GetUniformLocation(programHandle, decl.Name);
+ int location = GL.GetUniformLocation(programHandle, desc.Name);
GL.Uniform1(location, index);
diff --git a/Ryujinx.Graphics/Gal/OpenGL/OglShaderProgram.cs b/Ryujinx.Graphics/Gal/OpenGL/OglShaderProgram.cs
index 9e68a8e6..86126bca 100644
--- a/Ryujinx.Graphics/Gal/OpenGL/OglShaderProgram.cs
+++ b/Ryujinx.Graphics/Gal/OpenGL/OglShaderProgram.cs
@@ -1,4 +1,5 @@
using OpenTK.Graphics.OpenGL;
+using Ryujinx.Graphics.Shader;
using System;
using System.Collections.Generic;
@@ -23,14 +24,14 @@ namespace Ryujinx.Graphics.Gal.OpenGL
public string Code { get; private set; }
- public IEnumerable<ShaderDeclInfo> ConstBufferUsage { get; private set; }
- public IEnumerable<ShaderDeclInfo> TextureUsage { get; private set; }
+ public IEnumerable<CBufferDescriptor> ConstBufferUsage { get; private set; }
+ public IEnumerable<TextureDescriptor> TextureUsage { get; private set; }
public OglShaderStage(
- GalShaderType type,
- string code,
- IEnumerable<ShaderDeclInfo> constBufferUsage,
- IEnumerable<ShaderDeclInfo> textureUsage)
+ GalShaderType type,
+ string code,
+ IEnumerable<CBufferDescriptor> constBufferUsage,
+ IEnumerable<TextureDescriptor> textureUsage)
{
Type = type;
Code = code;
diff --git a/Ryujinx.Graphics/Gal/Shader/GlslDecl.cs b/Ryujinx.Graphics/Gal/Shader/GlslDecl.cs
deleted file mode 100644
index 73426762..00000000
--- a/Ryujinx.Graphics/Gal/Shader/GlslDecl.cs
+++ /dev/null
@@ -1,420 +0,0 @@
-using Ryujinx.Graphics.Texture;
-using System;
-using System.Collections.Generic;
-
-namespace Ryujinx.Graphics.Gal.Shader
-{
- class GlslDecl
- {
- public const int LayerAttr = 0x064;
- public const int PointSizeAttr = 0x06c;
- public const int PointCoordAttrX = 0x2e0;
- public const int PointCoordAttrY = 0x2e4;
- public const int TessCoordAttrX = 0x2f0;
- public const int TessCoordAttrY = 0x2f4;
- public const int TessCoordAttrZ = 0x2f8;
- public const int InstanceIdAttr = 0x2f8;
- public const int VertexIdAttr = 0x2fc;
- public const int FaceAttr = 0x3fc;
-
- public const int GlPositionVec4Index = 7;
-
- public const int PositionOutAttrLocation = 15;
-
- private const int AttrStartIndex = 8;
- private const int TexStartIndex = 8;
-
- public const string PositionOutAttrName = "position";
-
- private const string TextureName = "tex";
- private const string UniformName = "c";
-
- private const string AttrName = "attr";
- private const string InAttrName = "in_" + AttrName;
- private const string OutAttrName = "out_" + AttrName;
-
- private const string GprName = "gpr";
- private const string PredName = "pred";
-
- public const string FragmentOutputName = "FragColor";
-
- public const string ExtraUniformBlockName = "Extra";
- public const string FlipUniformName = "flip";
- public const string InstanceUniformName = "instance";
-
- public const string BasicBlockName = "bb";
- public const string BasicBlockAName = BasicBlockName + "_a";
- public const string BasicBlockBName = BasicBlockName + "_b";
-
- public const int SsyStackSize = 16;
- public const string SsyStackName = "ssy_stack";
- public const string SsyCursorName = "ssy_cursor";
-
- private string[] _stagePrefixes = new string[] { "vp", "tcp", "tep", "gp", "fp" };
-
- private string _stagePrefix;
-
- private Dictionary<ShaderIrOp, ShaderDeclInfo> m_CbTextures;
-
- private Dictionary<int, ShaderDeclInfo> m_Textures;
- private Dictionary<int, ShaderDeclInfo> m_Uniforms;
-
- private Dictionary<int, ShaderDeclInfo> m_Attributes;
- private Dictionary<int, ShaderDeclInfo> m_InAttributes;
- private Dictionary<int, ShaderDeclInfo> m_OutAttributes;
-
- private Dictionary<int, ShaderDeclInfo> m_Gprs;
- private Dictionary<int, ShaderDeclInfo> m_GprsHalf;
- private Dictionary<int, ShaderDeclInfo> m_Preds;
-
- public IReadOnlyDictionary<ShaderIrOp, ShaderDeclInfo> CbTextures => m_CbTextures;
-
- public IReadOnlyDictionary<int, ShaderDeclInfo> Textures => m_Textures;
- public IReadOnlyDictionary<int, ShaderDeclInfo> Uniforms => m_Uniforms;
-
- public IReadOnlyDictionary<int, ShaderDeclInfo> Attributes => m_Attributes;
- public IReadOnlyDictionary<int, ShaderDeclInfo> InAttributes => m_InAttributes;
- public IReadOnlyDictionary<int, ShaderDeclInfo> OutAttributes => m_OutAttributes;
-
- public IReadOnlyDictionary<int, ShaderDeclInfo> Gprs => m_Gprs;
- public IReadOnlyDictionary<int, ShaderDeclInfo> GprsHalf => m_GprsHalf;
- public IReadOnlyDictionary<int, ShaderDeclInfo> Preds => m_Preds;
-
- public GalShaderType ShaderType { get; private set; }
-
- private GlslDecl(GalShaderType shaderType)
- {
- ShaderType = shaderType;
-
- m_CbTextures = new Dictionary<ShaderIrOp, ShaderDeclInfo>();
-
- m_Textures = new Dictionary<int, ShaderDeclInfo>();
- m_Uniforms = new Dictionary<int, ShaderDeclInfo>();
-
- m_Attributes = new Dictionary<int, ShaderDeclInfo>();
- m_InAttributes = new Dictionary<int, ShaderDeclInfo>();
- m_OutAttributes = new Dictionary<int, ShaderDeclInfo>();
-
- m_Gprs = new Dictionary<int, ShaderDeclInfo>();
- m_GprsHalf = new Dictionary<int, ShaderDeclInfo>();
- m_Preds = new Dictionary<int, ShaderDeclInfo>();
- }
-
- public GlslDecl(ShaderIrBlock[] blocks, GalShaderType shaderType, ShaderHeader header) : this(shaderType)
- {
- _stagePrefix = _stagePrefixes[(int)shaderType] + "_";
-
- if (shaderType == GalShaderType.Fragment)
- {
- int index = 0;
-
- for (int attachment = 0; attachment < 8; attachment++)
- {
- for (int component = 0; component < 4; component++)
- {
- if (header.OmapTargets[attachment].ComponentEnabled(component))
- {
- m_Gprs.TryAdd(index, new ShaderDeclInfo(GetGprName(index), index));
-
- index++;
- }
- }
- }
-
- if (header.OmapDepth)
- {
- index = header.DepthRegister;
-
- m_Gprs.TryAdd(index, new ShaderDeclInfo(GetGprName(index), index));
- }
- }
-
- foreach (ShaderIrBlock block in blocks)
- {
- ShaderIrNode[] nodes = block.GetNodes();
-
- foreach (ShaderIrNode node in nodes)
- {
- Traverse(nodes, null, node);
- }
- }
- }
-
- public static GlslDecl Merge(GlslDecl vpA, GlslDecl vpB)
- {
- GlslDecl combined = new GlslDecl(GalShaderType.Vertex);
-
- Merge(combined.m_Textures, vpA.m_Textures, vpB.m_Textures);
- Merge(combined.m_Uniforms, vpA.m_Uniforms, vpB.m_Uniforms);
-
- Merge(combined.m_Attributes, vpA.m_Attributes, vpB.m_Attributes);
- Merge(combined.m_OutAttributes, vpA.m_OutAttributes, vpB.m_OutAttributes);
-
- Merge(combined.m_Gprs, vpA.m_Gprs, vpB.m_Gprs);
- Merge(combined.m_GprsHalf, vpA.m_GprsHalf, vpB.m_GprsHalf);
- Merge(combined.m_Preds, vpA.m_Preds, vpB.m_Preds);
-
- //Merge input attributes.
- foreach (KeyValuePair<int, ShaderDeclInfo> kv in vpA.m_InAttributes)
- {
- combined.m_InAttributes.TryAdd(kv.Key, kv.Value);
- }
-
- foreach (KeyValuePair<int, ShaderDeclInfo> kv in vpB.m_InAttributes)
- {
- //If Vertex Program A already writes to this attribute,
- //then we don't need to add it as an input attribute since
- //Vertex Program A will already have written to it anyway,
- //and there's no guarantee that there is an input attribute
- //for this slot.
- if (!vpA.m_OutAttributes.ContainsKey(kv.Key))
- {
- combined.m_InAttributes.TryAdd(kv.Key, kv.Value);
- }
- }
-
- return combined;
- }
-
- public static string GetGprName(int index)
- {
- return GprName + index;
- }
-
- private static void Merge(
- Dictionary<int, ShaderDeclInfo> c,
- Dictionary<int, ShaderDeclInfo> a,
- Dictionary<int, ShaderDeclInfo> b)
- {
- foreach (KeyValuePair<int, ShaderDeclInfo> kv in a)
- {
- c.TryAdd(kv.Key, kv.Value);
- }
-
- foreach (KeyValuePair<int, ShaderDeclInfo> kv in b)
- {
- c.TryAdd(kv.Key, kv.Value);
- }
- }
-
- private void Traverse(ShaderIrNode[] nodes, ShaderIrNode parent, ShaderIrNode node)
- {
- switch (node)
- {
- case ShaderIrAsg asg:
- {
- Traverse(nodes, asg, asg.Dst);
- Traverse(nodes, asg, asg.Src);
-
- break;
- }
-
- case ShaderIrCond cond:
- {
- Traverse(nodes, cond, cond.Pred);
- Traverse(nodes, cond, cond.Child);
-
- break;
- }
-
- case ShaderIrOp op:
- {
- Traverse(nodes, op, op.OperandA);
- Traverse(nodes, op, op.OperandB);
- Traverse(nodes, op, op.OperandC);
-
- if (op.Inst == ShaderIrInst.Texq ||
- op.Inst == ShaderIrInst.Texs ||
- op.Inst == ShaderIrInst.Tld4 ||
- op.Inst == ShaderIrInst.Txlf)
- {
- int handle = ((ShaderIrOperImm)op.OperandC).Value;
-
- int index = handle - TexStartIndex;
-
- string name = _stagePrefix + TextureName + index;
-
- GalTextureTarget textureTarget;
-
- TextureInstructionSuffix textureInstructionSuffix;
-
- // TODO: Non 2D texture type for TEXQ?
- if (op.Inst == ShaderIrInst.Texq)
- {
- textureTarget = GalTextureTarget.TwoD;
- textureInstructionSuffix = TextureInstructionSuffix.None;
- }
- else
- {
- ShaderIrMetaTex meta = ((ShaderIrMetaTex)op.MetaData);
-
- textureTarget = meta.TextureTarget;
- textureInstructionSuffix = meta.TextureInstructionSuffix;
- }
-
- m_Textures.TryAdd(handle, new ShaderDeclInfo(name, handle, false, 0, 1, textureTarget, textureInstructionSuffix));
- }
- else if (op.Inst == ShaderIrInst.Texb)
- {
- ShaderIrNode handleSrc = null;
-
- int index = Array.IndexOf(nodes, parent) - 1;
-
- for (; index >= 0; index--)
- {
- ShaderIrNode curr = nodes[index];
-
- if (curr is ShaderIrAsg asg && asg.Dst is ShaderIrOperGpr gpr)
- {
- if (gpr.Index == ((ShaderIrOperGpr)op.OperandC).Index)
- {
- handleSrc = asg.Src;
-
- break;
- }
- }
- }
-
- if (handleSrc != null && handleSrc is ShaderIrOperCbuf cbuf)
- {
- ShaderIrMetaTex meta = ((ShaderIrMetaTex)op.MetaData);
- string name = _stagePrefix + TextureName + "_cb" + cbuf.Index + "_" + cbuf.Pos;
-
- m_CbTextures.Add(op, new ShaderDeclInfo(name, cbuf.Pos, true, cbuf.Index, 1, meta.TextureTarget, meta.TextureInstructionSuffix));
- }
- else
- {
- throw new NotImplementedException("Shader TEX.B instruction is not fully supported!");
- }
- }
- break;
- }
-
- case ShaderIrOperCbuf cbuf:
- {
- if (!m_Uniforms.ContainsKey(cbuf.Index))
- {
- string name = _stagePrefix + UniformName + cbuf.Index;
-
- ShaderDeclInfo declInfo = new ShaderDeclInfo(name, cbuf.Pos, true, cbuf.Index);
-
- m_Uniforms.Add(cbuf.Index, declInfo);
- }
- break;
- }
-
- case ShaderIrOperAbuf abuf:
- {
- //This is a built-in variable.
- if (abuf.Offs == LayerAttr ||
- abuf.Offs == PointSizeAttr ||
- abuf.Offs == PointCoordAttrX ||
- abuf.Offs == PointCoordAttrY ||
- abuf.Offs == VertexIdAttr ||
- abuf.Offs == InstanceIdAttr ||
- abuf.Offs == FaceAttr)
- {
- break;
- }
-
- int index = abuf.Offs >> 4;
- int elem = (abuf.Offs >> 2) & 3;
-
- int glslIndex = index - AttrStartIndex;
-
- if (glslIndex < 0)
- {
- return;
- }
-
- ShaderDeclInfo declInfo;
-
- if (parent is ShaderIrAsg asg && asg.Dst == node)
- {
- if (!m_OutAttributes.TryGetValue(index, out declInfo))
- {
- declInfo = new ShaderDeclInfo(OutAttrName + glslIndex, glslIndex);
-
- m_OutAttributes.Add(index, declInfo);
- }
- }
- else
- {
- if (!m_InAttributes.TryGetValue(index, out declInfo))
- {
- declInfo = new ShaderDeclInfo(InAttrName + glslIndex, glslIndex);
-
- m_InAttributes.Add(index, declInfo);
- }
- }
-
- declInfo.Enlarge(elem + 1);
-
- if (!m_Attributes.ContainsKey(index))
- {
- declInfo = new ShaderDeclInfo(AttrName + glslIndex, glslIndex, false, 0, 4);
-
- m_Attributes.Add(index, declInfo);
- }
-
- Traverse(nodes, abuf, abuf.Vertex);
-
- break;
- }
-
- case ShaderIrOperGpr gpr:
- {
- if (!gpr.IsConst)
- {
- string name = GetGprName(gpr.Index);
-
- if (gpr.RegisterSize == ShaderRegisterSize.Single)
- {
- m_Gprs.TryAdd(gpr.Index, new ShaderDeclInfo(name, gpr.Index));
- }
- else if (gpr.RegisterSize == ShaderRegisterSize.Half)
- {
- name += "_h" + gpr.HalfPart;
-
- m_GprsHalf.TryAdd((gpr.Index << 1) | gpr.HalfPart, new ShaderDeclInfo(name, gpr.Index));
- }
- else /* if (Gpr.RegisterSize == ShaderRegisterSize.Double) */
- {
- throw new NotImplementedException("Double types are not supported.");
- }
- }
- break;
- }
-
- case ShaderIrOperPred pred:
- {
- if (!pred.IsConst && !HasName(m_Preds, pred.Index))
- {
- string name = PredName + pred.Index;
-
- m_Preds.TryAdd(pred.Index, new ShaderDeclInfo(name, pred.Index));
- }
- break;
- }
- }
- }
-
- private bool HasName(Dictionary<int, ShaderDeclInfo> decls, int index)
- {
- //This is used to check if the dictionary already contains
- //a entry for a vector at a given index position.
- //Used to enable turning gprs into vectors.
- int vecIndex = index & ~3;
-
- if (decls.TryGetValue(vecIndex, out ShaderDeclInfo declInfo))
- {
- if (declInfo.Size > 1 && index < vecIndex + declInfo.Size)
- {
- return true;
- }
- }
-
- return decls.ContainsKey(index);
- }
- }
-}
diff --git a/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs b/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs
deleted file mode 100644
index 228a9018..00000000
--- a/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs
+++ /dev/null
@@ -1,1679 +0,0 @@
-using OpenTK.Graphics.OpenGL;
-using Ryujinx.Graphics.Texture;
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using System.Text;
-
-namespace Ryujinx.Graphics.Gal.Shader
-{
- public class GlslDecompiler
- {
- private delegate string GetInstExpr(ShaderIrOp op);
-
- private Dictionary<ShaderIrInst, GetInstExpr> _instsExpr;
-
- private enum OperType
- {
- Bool,
- F32,
- I32
- }
-
- private const string IdentationStr = " ";
-
- private const int MaxVertexInput = 3;
-
- private GlslDecl _decl;
-
- private ShaderHeader _header, _headerB;
-
- private ShaderIrBlock[] _blocks, _blocksB;
-
- private StringBuilder _sb;
-
- public int MaxUboSize { get; }
-
- private bool _isNvidiaDriver;
-
- public GlslDecompiler(int maxUboSize, bool isNvidiaDriver)
- {
- _instsExpr = new Dictionary<ShaderIrInst, GetInstExpr>()
- {
- { ShaderIrInst.Abs, GetAbsExpr },
- { ShaderIrInst.Add, GetAddExpr },
- { ShaderIrInst.And, GetAndExpr },
- { ShaderIrInst.Asr, GetAsrExpr },
- { ShaderIrInst.Band, GetBandExpr },
- { ShaderIrInst.Bnot, GetBnotExpr },
- { ShaderIrInst.Bor, GetBorExpr },
- { ShaderIrInst.Bxor, GetBxorExpr },
- { ShaderIrInst.Ceil, GetCeilExpr },
- { ShaderIrInst.Ceq, GetCeqExpr },
- { ShaderIrInst.Cge, GetCgeExpr },
- { ShaderIrInst.Cgt, GetCgtExpr },
- { ShaderIrInst.Clamps, GetClampsExpr },
- { ShaderIrInst.Clampu, GetClampuExpr },
- { ShaderIrInst.Cle, GetCleExpr },
- { ShaderIrInst.Clt, GetCltExpr },
- { ShaderIrInst.Cne, GetCneExpr },
- { ShaderIrInst.Cut, GetCutExpr },
- { ShaderIrInst.Exit, GetExitExpr },
- { ShaderIrInst.Fabs, GetAbsExpr },
- { ShaderIrInst.Fadd, GetAddExpr },
- { ShaderIrInst.Fceq, GetCeqExpr },
- { ShaderIrInst.Fcequ, GetCequExpr },
- { ShaderIrInst.Fcge, GetCgeExpr },
- { ShaderIrInst.Fcgeu, GetCgeuExpr },
- { ShaderIrInst.Fcgt, GetCgtExpr },
- { ShaderIrInst.Fcgtu, GetCgtuExpr },
- { ShaderIrInst.Fclamp, GetFclampExpr },
- { ShaderIrInst.Fcle, GetCleExpr },
- { ShaderIrInst.Fcleu, GetCleuExpr },
- { ShaderIrInst.Fclt, GetCltExpr },
- { ShaderIrInst.Fcltu, GetCltuExpr },
- { ShaderIrInst.Fcnan, GetCnanExpr },
- { ShaderIrInst.Fcne, GetCneExpr },
- { ShaderIrInst.Fcneu, GetCneuExpr },
- { ShaderIrInst.Fcnum, GetCnumExpr },
- { ShaderIrInst.Fcos, GetFcosExpr },
- { ShaderIrInst.Fex2, GetFex2Expr },
- { ShaderIrInst.Ffma, GetFfmaExpr },
- { ShaderIrInst.Flg2, GetFlg2Expr },
- { ShaderIrInst.Floor, GetFloorExpr },
- { ShaderIrInst.Fmax, GetMaxExpr },
- { ShaderIrInst.Fmin, GetMinExpr },
- { ShaderIrInst.Fmul, GetMulExpr },
- { ShaderIrInst.Fneg, GetNegExpr },
- { ShaderIrInst.Frcp, GetFrcpExpr },
- { ShaderIrInst.Frsq, GetFrsqExpr },
- { ShaderIrInst.Fsin, GetFsinExpr },
- { ShaderIrInst.Fsqrt, GetFsqrtExpr },
- { ShaderIrInst.Ftos, GetFtosExpr },
- { ShaderIrInst.Ftou, GetFtouExpr },
- { ShaderIrInst.Ipa, GetIpaExpr },
- { ShaderIrInst.Kil, GetKilExpr },
- { ShaderIrInst.Lsl, GetLslExpr },
- { ShaderIrInst.Lsr, GetLsrExpr },
- { ShaderIrInst.Max, GetMaxExpr },
- { ShaderIrInst.Min, GetMinExpr },
- { ShaderIrInst.Mul, GetMulExpr },
- { ShaderIrInst.Neg, GetNegExpr },
- { ShaderIrInst.Not, GetNotExpr },
- { ShaderIrInst.Or, GetOrExpr },
- { ShaderIrInst.Stof, GetStofExpr },
- { ShaderIrInst.Sub, GetSubExpr },
- { ShaderIrInst.Texb, GetTexbExpr },
- { ShaderIrInst.Texq, GetTexqExpr },
- { ShaderIrInst.Texs, GetTexsExpr },
- { ShaderIrInst.Tld4, GetTld4Expr },
- { ShaderIrInst.Trunc, GetTruncExpr },
- { ShaderIrInst.Txlf, GetTxlfExpr },
- { ShaderIrInst.Utof, GetUtofExpr },
- { ShaderIrInst.Xor, GetXorExpr }
- };
-
- MaxUboSize = maxUboSize / 16;
- _isNvidiaDriver = isNvidiaDriver;
- }
-
- public GlslProgram Decompile(
- IGalMemory memory,
- long vpAPosition,
- long vpBPosition,
- GalShaderType shaderType)
- {
- _header = new ShaderHeader(memory, vpAPosition);
- _headerB = new ShaderHeader(memory, vpBPosition);
-
- _blocks = ShaderDecoder.Decode(memory, vpAPosition);
- _blocksB = ShaderDecoder.Decode(memory, vpBPosition);
-
- GlslDecl declVpA = new GlslDecl(_blocks, shaderType, _header);
- GlslDecl declVpB = new GlslDecl(_blocksB, shaderType, _headerB);
-
- _decl = GlslDecl.Merge(declVpA, declVpB);
-
- return Decompile();
- }
-
- public GlslProgram Decompile(IGalMemory memory, long position, GalShaderType shaderType)
- {
- _header = new ShaderHeader(memory, position);
- _headerB = null;
-
- _blocks = ShaderDecoder.Decode(memory, position);
- _blocksB = null;
-
- _decl = new GlslDecl(_blocks, shaderType, _header);
-
- return Decompile();
- }
-
- private GlslProgram Decompile()
- {
- _sb = new StringBuilder();
-
- _sb.AppendLine("#version 410 core");
-
- PrintDeclHeader();
- PrintDeclTextures();
- PrintDeclUniforms();
- PrintDeclAttributes();
- PrintDeclInAttributes();
- PrintDeclOutAttributes();
- PrintDeclGprs();
- PrintDeclPreds();
- PrintDeclSsy();
-
- if (_blocksB != null)
- {
- PrintBlockScope(_blocks, GlslDecl.BasicBlockAName);
-
- _sb.AppendLine();
-
- PrintBlockScope(_blocksB, GlslDecl.BasicBlockBName);
- }
- else
- {
- PrintBlockScope(_blocks, GlslDecl.BasicBlockName);
- }
-
- _sb.AppendLine();
-
- PrintMain();
-
- string glslCode = _sb.ToString();
-
- List<ShaderDeclInfo> textureInfo = new List<ShaderDeclInfo>();
-
- textureInfo.AddRange(_decl.Textures.Values);
- textureInfo.AddRange(IterateCbTextures());
-
- return new GlslProgram(glslCode, textureInfo, _decl.Uniforms.Values);
- }
-
- private void PrintDeclHeader()
- {
- if (_decl.ShaderType == GalShaderType.Geometry)
- {
- int maxVertices = _header.MaxOutputVertexCount;
-
- string outputTopology;
-
- switch (_header.OutputTopology)
- {
- case ShaderHeader.PointList: outputTopology = "points"; break;
- case ShaderHeader.LineStrip: outputTopology = "line_strip"; break;
- case ShaderHeader.TriangleStrip: outputTopology = "triangle_strip"; break;
-
- default: throw new InvalidOperationException();
- }
-
- _sb.AppendLine("#extension GL_ARB_enhanced_layouts : require");
-
- _sb.AppendLine();
-
- _sb.AppendLine("// Stubbed. Maxwell geometry shaders don't inform input geometry type");
-
- _sb.AppendLine("layout(triangles) in;" + Environment.NewLine);
-
- _sb.AppendLine($"layout({outputTopology}, max_vertices = {maxVertices}) out;");
-
- _sb.AppendLine();
- }
- }
-
- private string GetSamplerType(TextureTarget textureTarget, bool hasShadow)
- {
- string result;
-
- switch (textureTarget)
- {
- case TextureTarget.Texture1D:
- result = "sampler1D";
- break;
- case TextureTarget.Texture2D:
- result = "sampler2D";
- break;
- case TextureTarget.Texture3D:
- result = "sampler3D";
- break;
- case TextureTarget.TextureCubeMap:
- result = "samplerCube";
- break;
- case TextureTarget.TextureRectangle:
- result = "sampler2DRect";
- break;
- case TextureTarget.Texture1DArray:
- result = "sampler1DArray";
- break;
- case TextureTarget.Texture2DArray:
- result = "sampler2DArray";
- break;
- case TextureTarget.TextureCubeMapArray:
- result = "samplerCubeArray";
- break;
- case TextureTarget.TextureBuffer:
- result = "samplerBuffer";
- break;
- case TextureTarget.Texture2DMultisample:
- result = "sampler2DMS";
- break;
- case TextureTarget.Texture2DMultisampleArray:
- result = "sampler2DMSArray";
- break;
- default:
- throw new NotSupportedException();
- }
-
- if (hasShadow)
- result += "Shadow";
-
- return result;
- }
-
- private void PrintDeclTextures()
- {
- foreach (ShaderDeclInfo declInfo in IterateCbTextures())
- {
- TextureTarget target = ImageUtils.GetTextureTarget(declInfo.TextureTarget);
- _sb.AppendLine($"// {declInfo.TextureSuffix}");
- _sb.AppendLine("uniform " + GetSamplerType(target, (declInfo.TextureSuffix & TextureInstructionSuffix.Dc) != 0) + " " + declInfo.Name + ";");
- }
-
- foreach (ShaderDeclInfo declInfo in _decl.Textures.Values.OrderBy(DeclKeySelector))
- {
- TextureTarget target = ImageUtils.GetTextureTarget(declInfo.TextureTarget);
- _sb.AppendLine($"// {declInfo.TextureSuffix}");
- _sb.AppendLine("uniform " + GetSamplerType(target, (declInfo.TextureSuffix & TextureInstructionSuffix.Dc) != 0) + " " + declInfo.Name + ";");
- }
- }
-
- private IEnumerable<ShaderDeclInfo> IterateCbTextures()
- {
- HashSet<string> names = new HashSet<string>();
-
- foreach (ShaderDeclInfo declInfo in _decl.CbTextures.Values.OrderBy(DeclKeySelector))
- {
- if (names.Add(declInfo.Name))
- {
- yield return declInfo;
- }
- }
- }
-
- private void PrintDeclUniforms()
- {
- if (_decl.ShaderType == GalShaderType.Vertex)
- {
- //Memory layout here is [flip_x, flip_y, instance, unused]
- //It's using 4 bytes, not 8
-
- _sb.AppendLine("layout (std140) uniform " + GlslDecl.ExtraUniformBlockName + " {");
-
- _sb.AppendLine(IdentationStr + "vec2 " + GlslDecl.FlipUniformName + ";");
-
- _sb.AppendLine(IdentationStr + "int " + GlslDecl.InstanceUniformName + ";");
-
- _sb.AppendLine("};");
- _sb.AppendLine();
- }
-
- foreach (ShaderDeclInfo declInfo in _decl.Uniforms.Values.OrderBy(DeclKeySelector))
- {
- _sb.AppendLine($"layout (std140) uniform {declInfo.Name} {{");
-
- _sb.AppendLine($"{IdentationStr}vec4 {declInfo.Name}_data[{MaxUboSize}];");
-
- _sb.AppendLine("};");
- }
-
- if (_decl.Uniforms.Count > 0)
- {
- _sb.AppendLine();
- }
- }
-
- private void PrintDeclAttributes()
- {
- string geometryArray = (_decl.ShaderType == GalShaderType.Geometry) ? "[" + MaxVertexInput + "]" : "";
-
- PrintDecls(_decl.Attributes, suffix: geometryArray);
- }
-
- private void PrintDeclInAttributes()
- {
- if (_decl.ShaderType == GalShaderType.Fragment)
- {
- _sb.AppendLine("layout (location = " + GlslDecl.PositionOutAttrLocation + ") in vec4 " + GlslDecl.PositionOutAttrName + ";");
- }
-
- if (_decl.ShaderType == GalShaderType.Geometry)
- {
- if (_decl.InAttributes.Count > 0)
- {
- _sb.AppendLine("in Vertex {");
-
- foreach (ShaderDeclInfo declInfo in _decl.InAttributes.Values.OrderBy(DeclKeySelector))
- {
- if (declInfo.Index >= 0)
- {
- _sb.AppendLine(IdentationStr + "layout (location = " + declInfo.Index + ") vec4 " + declInfo.Name + "; ");
- }
- }
-
- _sb.AppendLine("} block_in[];" + Environment.NewLine);
- }
- }
- else
- {
- PrintDeclAttributes(_decl.InAttributes.Values, "in");
- }
- }
-
- private void PrintDeclOutAttributes()
- {
- if (_decl.ShaderType == GalShaderType.Fragment)
- {
- int count = 0;
-
- for (int attachment = 0; attachment < 8; attachment++)
- {
- if (_header.OmapTargets[attachment].Enabled)
- {
- _sb.AppendLine("layout (location = " + attachment + ") out vec4 " + GlslDecl.FragmentOutputName + attachment + ";");
-
- count++;
- }
- }
-
- if (count > 0)
- {
- _sb.AppendLine();
- }
- }
- else
- {
- _sb.AppendLine("layout (location = " + GlslDecl.PositionOutAttrLocation + ") out vec4 " + GlslDecl.PositionOutAttrName + ";");
- _sb.AppendLine();
- }
-
- PrintDeclAttributes(_decl.OutAttributes.Values, "out");
- }
-
- private void PrintDeclAttributes(IEnumerable<ShaderDeclInfo> decls, string inOut)
- {
- int count = 0;
-
- foreach (ShaderDeclInfo declInfo in decls.OrderBy(DeclKeySelector))
- {
- if (declInfo.Index >= 0)
- {
- _sb.AppendLine("layout (location = " + declInfo.Index + ") " + inOut + " vec4 " + declInfo.Name + ";");
-
- count++;
- }
- }
-
- if (count > 0)
- {
- _sb.AppendLine();
- }
- }
-
- private void PrintDeclGprs()
- {
- PrintDecls(_decl.Gprs);
- PrintDecls(_decl.GprsHalf);
- }
-
- private void PrintDeclPreds()
- {
- PrintDecls(_decl.Preds, "bool");
- }
-
- private void PrintDeclSsy()
- {
- _sb.AppendLine("uint " + GlslDecl.SsyCursorName + " = 0;");
-
- _sb.AppendLine("uint " + GlslDecl.SsyStackName + "[" + GlslDecl.SsyStackSize + "];" + Environment.NewLine);
- }
-
- private void PrintDecls(IReadOnlyDictionary<int, ShaderDeclInfo> dict, string customType = null, string suffix = "")
- {
- foreach (ShaderDeclInfo declInfo in dict.Values.OrderBy(DeclKeySelector))
- {
- string name;
-
- if (customType != null)
- {
- name = customType + " " + declInfo.Name + suffix + ";";
- }
- else if (declInfo.Name.Contains(GlslDecl.FragmentOutputName))
- {
- name = "layout (location = " + declInfo.Index / 4 + ") out vec4 " + declInfo.Name + suffix + ";";
- }
- else
- {
- name = GetDecl(declInfo) + suffix + ";";
- }
-
- _sb.AppendLine(name);
- }
-
- if (dict.Count > 0)
- {
- _sb.AppendLine();
- }
- }
-
- private int DeclKeySelector(ShaderDeclInfo declInfo)
- {
- return declInfo.Cbuf << 24 | declInfo.Index;
- }
-
- private string GetDecl(ShaderDeclInfo declInfo)
- {
- if (declInfo.Size == 4)
- {
- return "vec4 " + declInfo.Name;
- }
- else
- {
- return "float " + declInfo.Name;
- }
- }
-
- private void PrintMain()
- {
- _sb.AppendLine("void main() {");
-
- foreach (KeyValuePair<int, ShaderDeclInfo> kv in _decl.InAttributes)
- {
- if (!_decl.Attributes.TryGetValue(kv.Key, out ShaderDeclInfo attr))
- {
- continue;
- }
-
- ShaderDeclInfo declInfo = kv.Value;
-
- if (_decl.ShaderType == GalShaderType.Geometry)
- {
- for (int vertex = 0; vertex < MaxVertexInput; vertex++)
- {
- string dst = attr.Name + "[" + vertex + "]";
-
- string src = "block_in[" + vertex + "]." + declInfo.Name;
-
- _sb.AppendLine(IdentationStr + dst + " = " + src + ";");
- }
- }
- else
- {
- _sb.AppendLine(IdentationStr + attr.Name + " = " + declInfo.Name + ";");
- }
- }
-
- _sb.AppendLine(IdentationStr + "uint pc;");
-
- if (_blocksB != null)
- {
- PrintProgram(_blocks, GlslDecl.BasicBlockAName);
- PrintProgram(_blocksB, GlslDecl.BasicBlockBName);
- }
- else
- {
- PrintProgram(_blocks, GlslDecl.BasicBlockName);
- }
-
- if (_decl.ShaderType != GalShaderType.Geometry)
- {
- PrintAttrToOutput();
- }
-
- if (_decl.ShaderType == GalShaderType.Fragment)
- {
- if (_header.OmapDepth)
- {
- _sb.AppendLine(IdentationStr + "gl_FragDepth = " + GlslDecl.GetGprName(_header.DepthRegister) + ";");
- }
-
- int gprIndex = 0;
-
- for (int attachment = 0; attachment < 8; attachment++)
- {
- string output = GlslDecl.FragmentOutputName + attachment;
-
- OmapTarget target = _header.OmapTargets[attachment];
-
- for (int component = 0; component < 4; component++)
- {
- if (target.ComponentEnabled(component))
- {
- _sb.AppendLine(IdentationStr + output + "[" + component + "] = " + GlslDecl.GetGprName(gprIndex) + ";");
-
- gprIndex++;
- }
- }
- }
- }
-
- _sb.AppendLine("}");
- }
-
- private void PrintProgram(ShaderIrBlock[] blocks, string name)
- {
- const string ident1 = IdentationStr;
- const string ident2 = ident1 + IdentationStr;
- const string ident3 = ident2 + IdentationStr;
- const string ident4 = ident3 + IdentationStr;
-
- _sb.AppendLine(ident1 + "pc = " + GetBlockPosition(blocks[0]) + ";");
- _sb.AppendLine(ident1 + "do {");
- _sb.AppendLine(ident2 + "switch (pc) {");
-
- foreach (ShaderIrBlock block in blocks)
- {
- string functionName = block.Position.ToString("x8");
-
- _sb.AppendLine(ident3 + "case 0x" + functionName + ": pc = " + name + "_" + functionName + "(); break;");
- }
-
- _sb.AppendLine(ident3 + "default:");
- _sb.AppendLine(ident4 + "pc = 0;");
- _sb.AppendLine(ident4 + "break;");
-
- _sb.AppendLine(ident2 + "}");
- _sb.AppendLine(ident1 + "} while (pc != 0);");
- }
-
- private void PrintAttrToOutput(string identation = IdentationStr)
- {
- foreach (KeyValuePair<int, ShaderDeclInfo> kv in _decl.OutAttributes)
- {
- if (!_decl.Attributes.TryGetValue(kv.Key, out ShaderDeclInfo attr))
- {
- continue;
- }
-
- ShaderDeclInfo declInfo = kv.Value;
-
- string name = attr.Name;
-
- if (_decl.ShaderType == GalShaderType.Geometry)
- {
- name += "[0]";
- }
-
- _sb.AppendLine(identation + declInfo.Name + " = " + name + ";");
- }
-
- if (_decl.ShaderType == GalShaderType.Vertex)
- {
- _sb.AppendLine(identation + "gl_Position.xy *= " + GlslDecl.FlipUniformName + ";");
- }
-
- if (_decl.ShaderType != GalShaderType.Fragment)
- {
- _sb.AppendLine(identation + GlslDecl.PositionOutAttrName + " = gl_Position;");
- _sb.AppendLine(identation + GlslDecl.PositionOutAttrName + ".w = 1;");
- }
- }
-
- private void PrintBlockScope(ShaderIrBlock[] blocks, string name)
- {
- foreach (ShaderIrBlock block in blocks)
- {
- _sb.AppendLine("uint " + name + "_" + block.Position.ToString("x8") + "() {");
-
- PrintNodes(block, block.GetNodes());
-
- _sb.AppendLine("}" + Environment.NewLine);
- }
- }
-
- private void PrintNodes(ShaderIrBlock block, ShaderIrNode[] nodes)
- {
- foreach (ShaderIrNode node in nodes)
- {
- PrintNode(block, node, IdentationStr);
- }
-
- if (nodes.Length == 0)
- {
- _sb.AppendLine(IdentationStr + "return 0u;");
-
- return;
- }
-
- ShaderIrNode last = nodes[nodes.Length - 1];
-
- bool unconditionalFlowChange = false;
-
- if (last is ShaderIrOp op)
- {
- switch (op.Inst)
- {
- case ShaderIrInst.Bra:
- case ShaderIrInst.Exit:
- case ShaderIrInst.Sync:
- unconditionalFlowChange = true;
- break;
- }
- }
-
- if (!unconditionalFlowChange)
- {
- if (block.Next != null)
- {
- _sb.AppendLine(IdentationStr + "return " + GetBlockPosition(block.Next) + ";");
- }
- else
- {
- _sb.AppendLine(IdentationStr + "return 0u;");
- }
- }
- }
-
- private void PrintNode(ShaderIrBlock block, ShaderIrNode node, string identation)
- {
- if (node is ShaderIrCond cond)
- {
- string ifExpr = GetSrcExpr(cond.Pred, true);
-
- if (cond.Not)
- {
- ifExpr = "!(" + ifExpr + ")";
- }
-
- _sb.AppendLine(identation + "if (" + ifExpr + ") {");
-
- PrintNode(block, cond.Child, identation + IdentationStr);
-
- _sb.AppendLine(identation + "}");
- }
- else if (node is ShaderIrAsg asg)
- {
- if (IsValidOutOper(asg.Dst))
- {
- string expr = GetSrcExpr(asg.Src, true);
-
- expr = GetExprWithCast(asg.Dst, asg.Src, expr);
-
- _sb.AppendLine(identation + GetDstOperName(asg.Dst) + " = " + expr + ";");
- }
- }
- else if (node is ShaderIrOp op)
- {
- switch (op.Inst)
- {
- case ShaderIrInst.Bra:
- {
- _sb.AppendLine(identation + "return " + GetBlockPosition(block.Branch) + ";");
-
- break;
- }
-
- case ShaderIrInst.Emit:
- {
- PrintAttrToOutput(identation);
-
- _sb.AppendLine(identation + "EmitVertex();");
-
- break;
- }
-
- case ShaderIrInst.Ssy:
- {
- string stackIndex = GlslDecl.SsyStackName + "[" + GlslDecl.SsyCursorName + "]";
-
- int targetPosition = (op.OperandA as ShaderIrOperImm).Value;
-
- string target = "0x" + targetPosition.ToString("x8") + "u";
-
- _sb.AppendLine(identation + stackIndex + " = " + target + ";");
-
- _sb.AppendLine(identation + GlslDecl.SsyCursorName + "++;");
-
- break;
- }
-
- case ShaderIrInst.Sync:
- {
- _sb.AppendLine(identation + GlslDecl.SsyCursorName + "--;");
-
- string target = GlslDecl.SsyStackName + "[" + GlslDecl.SsyCursorName + "]";
-
- _sb.AppendLine(identation + "return " + target + ";");
-
- break;
- }
-
- default:
- _sb.AppendLine(identation + GetSrcExpr(op, true) + ";");
-
- break;
- }
- }
- else if (node is ShaderIrCmnt cmnt)
- {
- _sb.AppendLine(identation + "// " + cmnt.Comment);
- }
- else
- {
- throw new InvalidOperationException();
- }
- }
-
- private bool IsValidOutOper(ShaderIrNode node)
- {
- if (node is ShaderIrOperGpr gpr && gpr.IsConst)
- {
- return false;
- }
- else if (node is ShaderIrOperPred pred && pred.IsConst)
- {
- return false;
- }
-
- return true;
- }
-
- private string GetDstOperName(ShaderIrNode node)
- {
- if (node is ShaderIrOperAbuf abuf)
- {
- return GetOutAbufName(abuf);
- }
- else if (node is ShaderIrOperGpr gpr)
- {
- return GetName(gpr);
- }
- else if (node is ShaderIrOperPred pred)
- {
- return GetName(pred);
- }
-
- throw new ArgumentException(nameof(node));
- }
-
- private string GetSrcExpr(ShaderIrNode node, bool entry = false)
- {
- switch (node)
- {
- case ShaderIrOperAbuf abuf: return GetName (abuf);
- case ShaderIrOperCbuf cbuf: return GetName (cbuf);
- case ShaderIrOperGpr gpr: return GetName (gpr);
- case ShaderIrOperImm imm: return GetValue(imm);
- case ShaderIrOperImmf immf: return GetValue(immf);
- case ShaderIrOperPred pred: return GetName (pred);
-
- case ShaderIrOp op:
- string expr;
-
- if (_instsExpr.TryGetValue(op.Inst, out GetInstExpr getExpr))
- {
- expr = getExpr(op);
- }
- else
- {
- throw new NotImplementedException(op.Inst.ToString());
- }
-
- if (!entry && NeedsParentheses(op))
- {
- expr = "(" + expr + ")";
- }
-
- return expr;
-
- default: throw new ArgumentException(nameof(node));
- }
- }
-
- private static bool NeedsParentheses(ShaderIrOp op)
- {
- switch (op.Inst)
- {
- case ShaderIrInst.Ipa:
- case ShaderIrInst.Texq:
- case ShaderIrInst.Texs:
- case ShaderIrInst.Tld4:
- case ShaderIrInst.Txlf:
- return false;
- }
-
- return true;
- }
-
- private string GetName(ShaderIrOperCbuf cbuf)
- {
- if (!_decl.Uniforms.TryGetValue(cbuf.Index, out ShaderDeclInfo declInfo))
- {
- throw new InvalidOperationException();
- }
-
- if (cbuf.Offs != null)
- {
- string offset = "floatBitsToInt(" + GetSrcExpr(cbuf.Offs) + ")";
-
- string index = "(" + cbuf.Pos * 4 + " + " + offset + ")";
-
- return $"{declInfo.Name}_data[{index} / 16][({index} / 4) % 4]";
- }
- else
- {
- return $"{declInfo.Name}_data[{cbuf.Pos / 4}][{cbuf.Pos % 4}]";
- }
- }
-
- private string GetOutAbufName(ShaderIrOperAbuf abuf)
- {
- if (_decl.ShaderType == GalShaderType.Geometry)
- {
- switch (abuf.Offs)
- {
- case GlslDecl.LayerAttr: return "gl_Layer";
- }
- }
-
- return GetAttrTempName(abuf);
- }
-
- private string GetName(ShaderIrOperAbuf abuf)
- {
- //Handle special scalar read-only attributes here.
- if (_decl.ShaderType == GalShaderType.Vertex)
- {
- switch (abuf.Offs)
- {
- case GlslDecl.VertexIdAttr: return "gl_VertexID";
- case GlslDecl.InstanceIdAttr: return GlslDecl.InstanceUniformName;
- }
- }
- else if (_decl.ShaderType == GalShaderType.TessEvaluation)
- {
- switch (abuf.Offs)
- {
- case GlslDecl.TessCoordAttrX: return "gl_TessCoord.x";
- case GlslDecl.TessCoordAttrY: return "gl_TessCoord.y";
- case GlslDecl.TessCoordAttrZ: return "gl_TessCoord.z";
- }
- }
- else if (_decl.ShaderType == GalShaderType.Fragment)
- {
- switch (abuf.Offs)
- {
- case GlslDecl.PointCoordAttrX: return "gl_PointCoord.x";
- case GlslDecl.PointCoordAttrY: return "gl_PointCoord.y";
- case GlslDecl.FaceAttr: return "(gl_FrontFacing ? -1 : 0)";
- }
- }
-
- return GetAttrTempName(abuf);
- }
-
- private string GetAttrTempName(ShaderIrOperAbuf abuf)
- {
- int index = abuf.Offs >> 4;
- int elem = (abuf.Offs >> 2) & 3;
-
- string swizzle = "." + GetAttrSwizzle(elem);
-
- if (!_decl.Attributes.TryGetValue(index, out ShaderDeclInfo declInfo))
- {
- //Handle special vec4 attributes here
- //(for example, index 7 is always gl_Position).
- if (index == GlslDecl.GlPositionVec4Index)
- {
- string name =
- _decl.ShaderType != GalShaderType.Vertex &&
- _decl.ShaderType != GalShaderType.Geometry ? GlslDecl.PositionOutAttrName : "gl_Position";
-
- return name + swizzle;
- }
- else if (abuf.Offs == GlslDecl.PointSizeAttr)
- {
- return "gl_PointSize";
- }
- }
-
- if (declInfo.Index >= 32)
- {
- throw new InvalidOperationException($"Shader attribute offset {abuf.Offs} is invalid.");
- }
-
- if (_decl.ShaderType == GalShaderType.Geometry)
- {
- string vertex = "floatBitsToInt(" + GetSrcExpr(abuf.Vertex) + ")";
-
- return declInfo.Name + "[" + vertex + "]" + swizzle;
- }
- else
- {
- return declInfo.Name + swizzle;
- }
- }
-
- private string GetName(ShaderIrOperGpr gpr)
- {
- if (gpr.IsConst)
- {
- return "0";
- }
-
- if (gpr.RegisterSize == ShaderRegisterSize.Single)
- {
- return GetNameWithSwizzle(_decl.Gprs, gpr.Index);
- }
- else if (gpr.RegisterSize == ShaderRegisterSize.Half)
- {
- return GetNameWithSwizzle(_decl.GprsHalf, (gpr.Index << 1) | gpr.HalfPart);
- }
- else /* if (Gpr.RegisterSize == ShaderRegisterSize.Double) */
- {
- throw new NotImplementedException("Double types are not supported.");
- }
- }
-
- private string GetValue(ShaderIrOperImm imm)
- {
- //Only use hex is the value is too big and would likely be hard to read as int.
- if (imm.Value > 0xfff ||
- imm.Value < -0xfff)
- {
- return "0x" + imm.Value.ToString("x8", CultureInfo.InvariantCulture);
- }
- else
- {
- return GetIntConst(imm.Value);
- }
- }
-
- private string GetValue(ShaderIrOperImmf immf)
- {
- return GetFloatConst(immf.Value);
- }
-
- private string GetName(ShaderIrOperPred pred)
- {
- return pred.IsConst ? "true" : GetNameWithSwizzle(_decl.Preds, pred.Index);
- }
-
- private string GetNameWithSwizzle(IReadOnlyDictionary<int, ShaderDeclInfo> dict, int index)
- {
- int vecIndex = index & ~3;
-
- if (dict.TryGetValue(vecIndex, out ShaderDeclInfo declInfo))
- {
- if (declInfo.Size > 1 && index < vecIndex + declInfo.Size)
- {
- return declInfo.Name + "." + GetAttrSwizzle(index & 3);
- }
- }
-
- if (!dict.TryGetValue(index, out declInfo))
- {
- throw new InvalidOperationException();
- }
-
- return declInfo.Name;
- }
-
- private string GetAttrSwizzle(int elem)
- {
- return "xyzw".Substring(elem, 1);
- }
-
- private string GetAbsExpr(ShaderIrOp op) => GetUnaryCall(op, "abs");
-
- private string GetAddExpr(ShaderIrOp op) => GetBinaryExpr(op, "+");
-
- private string GetAndExpr(ShaderIrOp op) => GetBinaryExpr(op, "&");
-
- private string GetAsrExpr(ShaderIrOp op) => GetBinaryExpr(op, ">>");
-
- private string GetBandExpr(ShaderIrOp op) => GetBinaryExpr(op, "&&");
-
- private string GetBnotExpr(ShaderIrOp op) => GetUnaryExpr(op, "!");
-
- private string GetBorExpr(ShaderIrOp op) => GetBinaryExpr(op, "||");
-
- private string GetBxorExpr(ShaderIrOp op) => GetBinaryExpr(op, "^^");
-
- private string GetCeilExpr(ShaderIrOp op) => GetUnaryCall(op, "ceil");
-
- private string GetClampsExpr(ShaderIrOp op)
- {
- return "clamp(" + GetOperExpr(op, op.OperandA) + ", " +
- GetOperExpr(op, op.OperandB) + ", " +
- GetOperExpr(op, op.OperandC) + ")";
- }
-
- private string GetClampuExpr(ShaderIrOp op)
- {
- return "int(clamp(uint(" + GetOperExpr(op, op.OperandA) + "), " +
- "uint(" + GetOperExpr(op, op.OperandB) + "), " +
- "uint(" + GetOperExpr(op, op.OperandC) + ")))";
- }
-
- private string GetCeqExpr(ShaderIrOp op) => GetBinaryExpr(op, "==");
-
- private string GetCequExpr(ShaderIrOp op) => GetBinaryExprWithNaN(op, "==");
-
- private string GetCgeExpr(ShaderIrOp op) => GetBinaryExpr(op, ">=");
-
- private string GetCgeuExpr(ShaderIrOp op) => GetBinaryExprWithNaN(op, ">=");
-
- private string GetCgtExpr(ShaderIrOp op) => GetBinaryExpr(op, ">");
-
- private string GetCgtuExpr(ShaderIrOp op) => GetBinaryExprWithNaN(op, ">");
-
- private string GetCleExpr(ShaderIrOp op) => GetBinaryExpr(op, "<=");
-
- private string GetCleuExpr(ShaderIrOp op) => GetBinaryExprWithNaN(op, "<=");
-
- private string GetCltExpr(ShaderIrOp op) => GetBinaryExpr(op, "<");
-
- private string GetCltuExpr(ShaderIrOp op) => GetBinaryExprWithNaN(op, "<");
-
- private string GetCnanExpr(ShaderIrOp op) => GetUnaryCall(op, "isnan");
-
- private string GetCneExpr(ShaderIrOp op) => GetBinaryExpr(op, "!=");
-
- private string GetCutExpr(ShaderIrOp op) => "EndPrimitive()";
-
- private string GetCneuExpr(ShaderIrOp op) => GetBinaryExprWithNaN(op, "!=");
-
- private string GetCnumExpr(ShaderIrOp op) => GetUnaryCall(op, "!isnan");
-
- private string GetExitExpr(ShaderIrOp op) => "return 0u";
-
- private string GetFcosExpr(ShaderIrOp op) => GetUnaryCall(op, "cos");
-
- private string GetFex2Expr(ShaderIrOp op) => GetUnaryCall(op, "exp2");
-
- private string GetFfmaExpr(ShaderIrOp op) => GetTernaryExpr(op, "*", "+");
-
- private string GetFclampExpr(ShaderIrOp op) => GetTernaryCall(op, "clamp");
-
- private string GetFlg2Expr(ShaderIrOp op) => GetUnaryCall(op, "log2");
-
- private string GetFloorExpr(ShaderIrOp op) => GetUnaryCall(op, "floor");
-
- private string GetFrcpExpr(ShaderIrOp op) => GetUnaryExpr(op, "1 / ");
-
- private string GetFrsqExpr(ShaderIrOp op) => GetUnaryCall(op, "inversesqrt");
-
- private string GetFsinExpr(ShaderIrOp op) => GetUnaryCall(op, "sin");
-
- private string GetFsqrtExpr(ShaderIrOp op) => GetUnaryCall(op, "sqrt");
-
- private string GetFtosExpr(ShaderIrOp op)
- {
- return "int(" + GetOperExpr(op, op.OperandA) + ")";
- }
-
- private string GetFtouExpr(ShaderIrOp op)
- {
- return "int(uint(" + GetOperExpr(op, op.OperandA) + "))";
- }
-
- private string GetIpaExpr(ShaderIrOp op)
- {
- ShaderIrMetaIpa meta = (ShaderIrMetaIpa)op.MetaData;
-
- ShaderIrOperAbuf abuf = (ShaderIrOperAbuf)op.OperandA;
-
- if (meta.Mode == ShaderIpaMode.Pass)
- {
- int index = abuf.Offs >> 4;
- int elem = (abuf.Offs >> 2) & 3;
-
- if (_decl.ShaderType == GalShaderType.Fragment && index == GlslDecl.GlPositionVec4Index)
- {
- switch (elem)
- {
- case 0: return "gl_FragCoord.x";
- case 1: return "gl_FragCoord.y";
- case 2: return "gl_FragCoord.z";
- case 3: return "1";
- }
- }
- }
-
- return GetSrcExpr(op.OperandA);
- }
-
- private string GetKilExpr(ShaderIrOp op) => "discard";
-
- private string GetLslExpr(ShaderIrOp op) => GetBinaryExpr(op, "<<");
- private string GetLsrExpr(ShaderIrOp op)
- {
- return "int(uint(" + GetOperExpr(op, op.OperandA) + ") >> " +
- GetOperExpr(op, op.OperandB) + ")";
- }
-
- private string GetMaxExpr(ShaderIrOp op) => GetBinaryCall(op, "max");
- private string GetMinExpr(ShaderIrOp op) => GetBinaryCall(op, "min");
-
- private string GetMulExpr(ShaderIrOp op) => GetBinaryExpr(op, "*");
-
- private string GetNegExpr(ShaderIrOp op) => GetUnaryExpr(op, "-");
-
- private string GetNotExpr(ShaderIrOp op) => GetUnaryExpr(op, "~");
-
- private string GetOrExpr(ShaderIrOp op) => GetBinaryExpr(op, "|");
-
- private string GetStofExpr(ShaderIrOp op)
- {
- return "float(" + GetOperExpr(op, op.OperandA) + ")";
- }
-
- private string GetSubExpr(ShaderIrOp op) => GetBinaryExpr(op, "-");
-
- private string GetTexbExpr(ShaderIrOp op)
- {
- ShaderIrMetaTex meta = (ShaderIrMetaTex)op.MetaData;
-
- if (!_decl.CbTextures.TryGetValue(op, out ShaderDeclInfo declInfo))
- {
- throw new InvalidOperationException();
- }
-
- string coords = GetTexSamplerCoords(op);
-
- string ch = "rgba".Substring(meta.Elem, 1);
-
- return GetTextureOperation(op, declInfo.Name, coords, ch);
- }
-
- private string GetTexqExpr(ShaderIrOp op)
- {
- ShaderIrMetaTexq meta = (ShaderIrMetaTexq)op.MetaData;
-
- string ch = "xyzw".Substring(meta.Elem, 1);
-
- if (meta.Info == ShaderTexqInfo.Dimension)
- {
- string sampler = GetTexSamplerName(op);
-
- string lod = GetOperExpr(op, op.OperandA); //???
-
- return "textureSize(" + sampler + ", " + lod + ")." + ch;
- }
- else
- {
- throw new NotImplementedException(meta.Info.ToString());
- }
- }
-
- private string GetTexsExpr(ShaderIrOp op)
- {
- ShaderIrMetaTex meta = (ShaderIrMetaTex)op.MetaData;
-
- string sampler = GetTexSamplerName(op);
-
- string coords = GetTexSamplerCoords(op);
-
- string ch = "rgba".Substring(meta.Elem, 1);
-
- return GetTextureOperation(op, sampler, coords, ch);
- }
-
- private string GetTld4Expr(ShaderIrOp op)
- {
- ShaderIrMetaTex meta = (ShaderIrMetaTex)op.MetaData;
-
- string sampler = GetTexSamplerName(op);
-
- string coords = GetTexSamplerCoords(op);
-
- string ch = "rgba".Substring(meta.Elem, 1);
-
- return GetTextureGatherOperation(op, sampler, coords, ch);
- }
-
- // TODO: support AOFFI on non nvidia drivers
- private string GetTxlfExpr(ShaderIrOp op)
- {
- // TODO: Support all suffixes
- ShaderIrMetaTex meta = (ShaderIrMetaTex)op.MetaData;
-
- TextureInstructionSuffix suffix = meta.TextureInstructionSuffix;
-
- string sampler = GetTexSamplerName(op);
-
- string coords = GetITexSamplerCoords(op);
-
- string ch = "rgba".Substring(meta.Elem, 1);
-
- string lod = "0";
-
- if (meta.LevelOfDetail != null)
- {
- lod = GetOperExpr(op, meta.LevelOfDetail);
- }
-
- if ((suffix & TextureInstructionSuffix.AOffI) != 0 && _isNvidiaDriver)
- {
- string offset = GetTextureOffset(meta, GetOperExpr(op, meta.Offset));
- return "texelFetchOffset(" + sampler + ", " + coords + ", " + lod + ", " + offset + ")." + ch;
- }
-
- return "texelFetch(" + sampler + ", " + coords + ", " + lod + ")." + ch;
- }
-
- private string GetTruncExpr(ShaderIrOp op) => GetUnaryCall(op, "trunc");
-
- private string GetUtofExpr(ShaderIrOp op)
- {
- return "float(uint(" + GetOperExpr(op, op.OperandA) + "))";
- }
-
- private string GetXorExpr(ShaderIrOp op) => GetBinaryExpr(op, "^");
-
- private string GetUnaryCall(ShaderIrOp op, string funcName)
- {
- return funcName + "(" + GetOperExpr(op, op.OperandA) + ")";
- }
-
- private string GetBinaryCall(ShaderIrOp op, string funcName)
- {
- return funcName + "(" + GetOperExpr(op, op.OperandA) + ", " +
- GetOperExpr(op, op.OperandB) + ")";
- }
-
- private string GetTernaryCall(ShaderIrOp op, string funcName)
- {
- return funcName + "(" + GetOperExpr(op, op.OperandA) + ", " +
- GetOperExpr(op, op.OperandB) + ", " +
- GetOperExpr(op, op.OperandC) + ")";
- }
-
- private string GetUnaryExpr(ShaderIrOp op, string opr)
- {
- return opr + GetOperExpr(op, op.OperandA);
- }
-
- private string GetBinaryExpr(ShaderIrOp op, string opr)
- {
- return GetOperExpr(op, op.OperandA) + " " + opr + " " +
- GetOperExpr(op, op.OperandB);
- }
-
- private string GetBinaryExprWithNaN(ShaderIrOp op, string opr)
- {
- string a = GetOperExpr(op, op.OperandA);
- string b = GetOperExpr(op, op.OperandB);
-
- string nanCheck =
- " || isnan(" + a + ")" +
- " || isnan(" + b + ")";
-
- return a + " " + opr + " " + b + nanCheck;
- }
-
- private string GetTernaryExpr(ShaderIrOp op, string opr1, string opr2)
- {
- return GetOperExpr(op, op.OperandA) + " " + opr1 + " " +
- GetOperExpr(op, op.OperandB) + " " + opr2 + " " +
- GetOperExpr(op, op.OperandC);
- }
-
- private string GetTexSamplerName(ShaderIrOp op)
- {
- ShaderIrOperImm node = (ShaderIrOperImm)op.OperandC;
-
- int handle = ((ShaderIrOperImm)op.OperandC).Value;
-
- if (!_decl.Textures.TryGetValue(handle, out ShaderDeclInfo declInfo))
- {
- throw new InvalidOperationException();
- }
-
- return declInfo.Name;
- }
-
- private string GetTexSamplerCoords(ShaderIrOp op)
- {
- ShaderIrMetaTex meta = (ShaderIrMetaTex)op.MetaData;
-
- bool hasDepth = (meta.TextureInstructionSuffix & TextureInstructionSuffix.Dc) != 0;
-
- int coords = ImageUtils.GetCoordsCountTextureTarget(meta.TextureTarget);
-
- bool isArray = ImageUtils.IsArray(meta.TextureTarget);
-
-
- string GetLastArgument(ShaderIrNode node)
- {
- string result = GetOperExpr(op, node);
-
- // array index is actually an integer so we need to pass it correctly
- if (isArray)
- {
- result = "float(floatBitsToInt(" + result + "))";
- }
-
- return result;
- }
-
- string lastArgument;
- string depthArgument = "";
-
- int vecSize = coords;
- if (hasDepth && op.Inst != ShaderIrInst.Tld4)
- {
- vecSize++;
- depthArgument = $", {GetOperExpr(op, meta.DepthCompare)}";
- }
-
- switch (coords)
- {
- case 1:
- if (hasDepth)
- {
- return $"vec3({GetOperExpr(op, meta.Coordinates[0])}, 0.0{depthArgument})";
- }
-
- return GetOperExpr(op, meta.Coordinates[0]);
- case 2:
- lastArgument = GetLastArgument(meta.Coordinates[1]);
-
- return $"vec{vecSize}({GetOperExpr(op, meta.Coordinates[0])}, {lastArgument}{depthArgument})";
- case 3:
- lastArgument = GetLastArgument(meta.Coordinates[2]);
-
- return $"vec{vecSize}({GetOperExpr(op, meta.Coordinates[0])}, {GetOperExpr(op, meta.Coordinates[1])}, {lastArgument}{depthArgument})";
- case 4:
- lastArgument = GetLastArgument(meta.Coordinates[3]);
-
- return $"vec4({GetOperExpr(op, meta.Coordinates[0])}, {GetOperExpr(op, meta.Coordinates[1])}, {GetOperExpr(op, meta.Coordinates[2])}, {lastArgument}){depthArgument}";
- default:
- throw new InvalidOperationException();
- }
-
- }
-
- private string GetTextureOffset(ShaderIrMetaTex meta, string oper, int shift = 4, int mask = 0xF)
- {
- string GetOffset(string operation, int index)
- {
- return $"({operation} >> {index * shift}) & 0x{mask:x}";
- }
-
- int coords = ImageUtils.GetCoordsCountTextureTarget(meta.TextureTarget);
-
- if (ImageUtils.IsArray(meta.TextureTarget))
- coords -= 1;
-
- switch (coords)
- {
- case 1:
- return GetOffset(oper, 0);
- case 2:
- return "ivec2(" + GetOffset(oper, 0) + ", " + GetOffset(oper, 1) + ")";
- case 3:
- return "ivec3(" + GetOffset(oper, 0) + ", " + GetOffset(oper, 1) + ", " + GetOffset(oper, 2) + ")";
- case 4:
- return "ivec4(" + GetOffset(oper, 0) + ", " + GetOffset(oper, 1) + ", " + GetOffset(oper, 2) + ", " + GetOffset(oper, 3) + ")";
- default:
- throw new InvalidOperationException();
- }
- }
-
- // TODO: support AOFFI on non nvidia drivers
- private string GetTextureGatherOperation(ShaderIrOp op, string sampler, string coords, string ch)
- {
- ShaderIrMetaTex meta = (ShaderIrMetaTex)op.MetaData;
-
- TextureInstructionSuffix suffix = meta.TextureInstructionSuffix;
-
- string chString = "." + ch;
-
- string comp = meta.Component.ToString();
-
- if ((suffix & TextureInstructionSuffix.Dc) != 0)
- {
- comp = GetOperExpr(op, meta.DepthCompare);
- }
-
- if ((suffix & TextureInstructionSuffix.AOffI) != 0 && _isNvidiaDriver)
- {
- string offset = GetTextureOffset(meta, "floatBitsToInt((" + GetOperExpr(op, meta.Offset) + "))", 8, 0x3F);
-
- if ((suffix & TextureInstructionSuffix.Dc) != 0)
- {
- return "textureGatherOffset(" + sampler + ", " + coords + ", " + comp + ", " + offset + ")" + chString;
- }
-
- return "textureGatherOffset(" + sampler + ", " + coords + ", " + offset + ", " + comp + ")" + chString;
- }
- // TODO: Support PTP
- else if ((suffix & TextureInstructionSuffix.Ptp) != 0)
- {
- throw new NotImplementedException();
- }
-
- return "textureGather(" + sampler + ", " + coords + ", " + comp + ")" + chString;
- }
-
- // TODO: support AOFFI on non nvidia drivers
- private string GetTextureOperation(ShaderIrOp op, string sampler, string coords, string ch)
- {
- ShaderIrMetaTex meta = (ShaderIrMetaTex)op.MetaData;
-
- TextureInstructionSuffix suffix = meta.TextureInstructionSuffix;
-
- string chString = "." + ch;
-
- if ((suffix & TextureInstructionSuffix.Dc) != 0)
- {
- chString = "";
- }
-
- // TODO: Support LBA and LLA
- if ((suffix & TextureInstructionSuffix.Lz) != 0)
- {
- if ((suffix & TextureInstructionSuffix.AOffI) != 0 && _isNvidiaDriver)
- {
- string offset = GetTextureOffset(meta, "floatBitsToInt((" + GetOperExpr(op, meta.Offset) + "))");
-
- return "textureLodOffset(" + sampler + ", " + coords + ", 0.0, " + offset + ")" + chString;
- }
-
- return "textureLod(" + sampler + ", " + coords + ", 0.0)" + chString;
- }
- else if ((suffix & TextureInstructionSuffix.Lb) != 0)
- {
- if ((suffix & TextureInstructionSuffix.AOffI) != 0 && _isNvidiaDriver)
- {
- string offset = GetTextureOffset(meta, "floatBitsToInt((" + GetOperExpr(op, meta.Offset) + "))");
-
- return "textureOffset(" + sampler + ", " + coords + ", " + offset + ", " + GetOperExpr(op, meta.LevelOfDetail) + ")" + chString;
- }
-
- return "texture(" + sampler + ", " + coords + ", " + GetOperExpr(op, meta.LevelOfDetail) + ")" + chString;
- }
- else if ((suffix & TextureInstructionSuffix.Ll) != 0)
- {
- if ((suffix & TextureInstructionSuffix.AOffI) != 0 && _isNvidiaDriver)
- {
- string offset = GetTextureOffset(meta, "floatBitsToInt((" + GetOperExpr(op, meta.Offset) + "))");
-
- return "textureLodOffset(" + sampler + ", " + coords + ", " + GetOperExpr(op, meta.LevelOfDetail) + ", " + offset + ")" + chString;
- }
-
- return "textureLod(" + sampler + ", " + coords + ", " + GetOperExpr(op, meta.LevelOfDetail) + ")" + chString;
- }
- else if ((suffix & TextureInstructionSuffix.AOffI) != 0 && _isNvidiaDriver)
- {
- string offset = GetTextureOffset(meta, "floatBitsToInt((" + GetOperExpr(op, meta.Offset) + "))");
-
- return "textureOffset(" + sampler + ", " + coords + ", " + offset + ")" + chString;
- }
- else
- {
- return "texture(" + sampler + ", " + coords + ")" + chString;
- }
- throw new NotImplementedException($"Texture Suffix {meta.TextureInstructionSuffix} is not implemented");
-
- }
-
- private string GetITexSamplerCoords(ShaderIrOp op)
- {
- ShaderIrMetaTex meta = (ShaderIrMetaTex)op.MetaData;
-
- switch (ImageUtils.GetCoordsCountTextureTarget(meta.TextureTarget))
- {
- case 1:
- return GetOperExpr(op, meta.Coordinates[0]);
- case 2:
- return "ivec2(" + GetOperExpr(op, meta.Coordinates[0]) + ", " + GetOperExpr(op, meta.Coordinates[1]) + ")";
- case 3:
- return "ivec3(" + GetOperExpr(op, meta.Coordinates[0]) + ", " + GetOperExpr(op, meta.Coordinates[1]) + ", " + GetOperExpr(op, meta.Coordinates[2]) + ")";
- default:
- throw new InvalidOperationException();
- }
- }
-
- private string GetOperExpr(ShaderIrOp op, ShaderIrNode oper)
- {
- return GetExprWithCast(op, oper, GetSrcExpr(oper));
- }
-
- private static string GetExprWithCast(ShaderIrNode dst, ShaderIrNode src, string expr)
- {
- //Note: The "DstType" (of the cast) is the type that the operation
- //uses on the source operands, while the "SrcType" is the destination
- //type of the operand result (if it is a operation) or just the type
- //of the variable for registers/uniforms/attributes.
- OperType dstType = GetSrcNodeType(dst);
- OperType srcType = GetDstNodeType(src);
-
- if (dstType != srcType)
- {
- //Check for invalid casts
- //(like bool to int/float and others).
- if (srcType != OperType.F32 &&
- srcType != OperType.I32)
- {
- throw new InvalidOperationException();
- }
-
- switch (src)
- {
- case ShaderIrOperGpr gpr:
- {
- //When the Gpr is ZR, just return the 0 value directly,
- //since the float encoding for 0 is 0.
- if (gpr.IsConst)
- {
- return "0";
- }
- break;
- }
- }
-
- switch (dstType)
- {
- case OperType.F32: expr = "intBitsToFloat(" + expr + ")"; break;
- case OperType.I32: expr = "floatBitsToInt(" + expr + ")"; break;
- }
- }
-
- return expr;
- }
-
- private static string GetIntConst(int value)
- {
- string expr = value.ToString(CultureInfo.InvariantCulture);
-
- return value < 0 ? "(" + expr + ")" : expr;
- }
-
- private static string GetFloatConst(float value)
- {
- string expr = value.ToString(CultureInfo.InvariantCulture);
-
- return value < 0 ? "(" + expr + ")" : expr;
- }
-
- private static OperType GetDstNodeType(ShaderIrNode node)
- {
- //Special case instructions with the result type different
- //from the input types (like integer <-> float conversion) here.
- if (node is ShaderIrOp op)
- {
- switch (op.Inst)
- {
- case ShaderIrInst.Stof:
- case ShaderIrInst.Txlf:
- case ShaderIrInst.Utof:
- return OperType.F32;
-
- case ShaderIrInst.Ftos:
- case ShaderIrInst.Ftou:
- return OperType.I32;
- }
- }
-
- return GetSrcNodeType(node);
- }
-
- private static OperType GetSrcNodeType(ShaderIrNode node)
- {
- switch (node)
- {
- case ShaderIrOperAbuf abuf:
- return abuf.Offs == GlslDecl.LayerAttr ||
- abuf.Offs == GlslDecl.InstanceIdAttr ||
- abuf.Offs == GlslDecl.VertexIdAttr ||
- abuf.Offs == GlslDecl.FaceAttr
- ? OperType.I32
- : OperType.F32;
-
- case ShaderIrOperCbuf cbuf: return OperType.F32;
- case ShaderIrOperGpr gpr: return OperType.F32;
- case ShaderIrOperImm imm: return OperType.I32;
- case ShaderIrOperImmf immf: return OperType.F32;
- case ShaderIrOperPred pred: return OperType.Bool;
-
- case ShaderIrOp op:
- if (op.Inst > ShaderIrInst.B_Start &&
- op.Inst < ShaderIrInst.B_End)
- {
- return OperType.Bool;
- }
- else if (op.Inst > ShaderIrInst.F_Start &&
- op.Inst < ShaderIrInst.F_End)
- {
- return OperType.F32;
- }
- else if (op.Inst > ShaderIrInst.I_Start &&
- op.Inst < ShaderIrInst.I_End)
- {
- return OperType.I32;
- }
- break;
- }
-
- throw new ArgumentException(nameof(node));
- }
-
- private static string GetBlockPosition(ShaderIrBlock block)
- {
- if (block != null)
- {
- return "0x" + block.Position.ToString("x8") + "u";
- }
- else
- {
- return "0u";
- }
- }
- }
-}
diff --git a/Ryujinx.Graphics/Gal/Shader/GlslProgram.cs b/Ryujinx.Graphics/Gal/Shader/GlslProgram.cs
deleted file mode 100644
index be8555d5..00000000
--- a/Ryujinx.Graphics/Gal/Shader/GlslProgram.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using System.Collections.Generic;
-
-namespace Ryujinx.Graphics.Gal.Shader
-{
- public struct GlslProgram
- {
- public string Code { get; private set; }
-
- public IEnumerable<ShaderDeclInfo> Textures { get; private set; }
- public IEnumerable<ShaderDeclInfo> Uniforms { get; private set; }
-
- public GlslProgram(
- string code,
- IEnumerable<ShaderDeclInfo> textures,
- IEnumerable<ShaderDeclInfo> uniforms)
- {
- Code = code;
- Textures = textures;
- Uniforms = uniforms;
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeAlu.cs b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeAlu.cs
deleted file mode 100644
index f935be74..00000000
--- a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeAlu.cs
+++ /dev/null
@@ -1,1299 +0,0 @@
-using System;
-
-using static Ryujinx.Graphics.Gal.Shader.ShaderDecodeHelper;
-
-namespace Ryujinx.Graphics.Gal.Shader
-{
- static partial class ShaderDecode
- {
- private enum HalfOutputType
- {
- PackedFp16,
- Fp32,
- MergeH0,
- MergeH1
- }
-
- public static void Bfe_C(ShaderIrBlock block, long opCode, int position)
- {
- EmitBfe(block, opCode, ShaderOper.Cr);
- }
-
- public static void Bfe_I(ShaderIrBlock block, long opCode, int position)
- {
- EmitBfe(block, opCode, ShaderOper.Imm);
- }
-
- public static void Bfe_R(ShaderIrBlock block, long opCode, int position)
- {
- EmitBfe(block, opCode, ShaderOper.Rr);
- }
-
- public static void Fadd_C(ShaderIrBlock block, long opCode, int position)
- {
- EmitFadd(block, opCode, ShaderOper.Cr);
- }
-
- public static void Fadd_I(ShaderIrBlock block, long opCode, int position)
- {
- EmitFadd(block, opCode, ShaderOper.Immf);
- }
-
- public static void Fadd_I32(ShaderIrBlock block, long opCode, int position)
- {
- ShaderIrNode operA = opCode.Gpr8();
- ShaderIrNode operB = opCode.Immf32_20();
-
- bool negB = opCode.Read(53);
- bool absA = opCode.Read(54);
- bool negA = opCode.Read(56);
- bool absB = opCode.Read(57);
-
- operA = GetAluFabsFneg(operA, absA, negA);
- operB = GetAluFabsFneg(operB, absB, negB);
-
- ShaderIrOp op = new ShaderIrOp(ShaderIrInst.Fadd, operA, operB);
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(opCode.Gpr0(), op)));
- }
-
- public static void Fadd_R(ShaderIrBlock block, long opCode, int position)
- {
- EmitFadd(block, opCode, ShaderOper.Rr);
- }
-
- public static void Ffma_CR(ShaderIrBlock block, long opCode, int position)
- {
- EmitFfma(block, opCode, ShaderOper.Cr);
- }
-
- public static void Ffma_I(ShaderIrBlock block, long opCode, int position)
- {
- EmitFfma(block, opCode, ShaderOper.Immf);
- }
-
- public static void Ffma_RC(ShaderIrBlock block, long opCode, int position)
- {
- EmitFfma(block, opCode, ShaderOper.Rc);
- }
-
- public static void Ffma_RR(ShaderIrBlock block, long opCode, int position)
- {
- EmitFfma(block, opCode, ShaderOper.Rr);
- }
-
- public static void Fmnmx_C(ShaderIrBlock block, long opCode, int position)
- {
- EmitFmnmx(block, opCode, ShaderOper.Cr);
- }
-
- public static void Fmnmx_I(ShaderIrBlock block, long opCode, int position)
- {
- EmitFmnmx(block, opCode, ShaderOper.Immf);
- }
-
- public static void Fmnmx_R(ShaderIrBlock block, long opCode, int position)
- {
- EmitFmnmx(block, opCode, ShaderOper.Rr);
- }
-
- public static void Fmul_I32(ShaderIrBlock block, long opCode, int position)
- {
- ShaderIrNode operA = opCode.Gpr8();
- ShaderIrNode operB = opCode.Immf32_20();
-
- ShaderIrOp op = new ShaderIrOp(ShaderIrInst.Fmul, operA, operB);
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(opCode.Gpr0(), op)));
- }
-
- public static void Fmul_C(ShaderIrBlock block, long opCode, int position)
- {
- EmitFmul(block, opCode, ShaderOper.Cr);
- }
-
- public static void Fmul_I(ShaderIrBlock block, long opCode, int position)
- {
- EmitFmul(block, opCode, ShaderOper.Immf);
- }
-
- public static void Fmul_R(ShaderIrBlock block, long opCode, int position)
- {
- EmitFmul(block, opCode, ShaderOper.Rr);
- }
-
- public static void Fset_C(ShaderIrBlock block, long opCode, int position)
- {
- EmitFset(block, opCode, ShaderOper.Cr);
- }
-
- public static void Fset_I(ShaderIrBlock block, long opCode, int position)
- {
- EmitFset(block, opCode, ShaderOper.Immf);
- }
-
- public static void Fset_R(ShaderIrBlock block, long opCode, int position)
- {
- EmitFset(block, opCode, ShaderOper.Rr);
- }
-
- public static void Fsetp_C(ShaderIrBlock block, long opCode, int position)
- {
- EmitFsetp(block, opCode, ShaderOper.Cr);
- }
-
- public static void Fsetp_I(ShaderIrBlock block, long opCode, int position)
- {
- EmitFsetp(block, opCode, ShaderOper.Immf);
- }
-
- public static void Fsetp_R(ShaderIrBlock block, long opCode, int position)
- {
- EmitFsetp(block, opCode, ShaderOper.Rr);
- }
-
- public static void Hadd2_R(ShaderIrBlock block, long opCode, int position)
- {
- EmitBinaryHalfOp(block, opCode, ShaderIrInst.Fadd);
- }
-
- public static void Hmul2_R(ShaderIrBlock block, long opCode, int position)
- {
- EmitBinaryHalfOp(block, opCode, ShaderIrInst.Fmul);
- }
-
- public static void Iadd_C(ShaderIrBlock block, long opCode, int position)
- {
- EmitIadd(block, opCode, ShaderOper.Cr);
- }
-
- public static void Iadd_I(ShaderIrBlock block, long opCode, int position)
- {
- EmitIadd(block, opCode, ShaderOper.Imm);
- }
-
- public static void Iadd_I32(ShaderIrBlock block, long opCode, int position)
- {
- ShaderIrNode operA = opCode.Gpr8();
- ShaderIrNode operB = opCode.Imm32_20();
-
- bool negA = opCode.Read(56);
-
- operA = GetAluIneg(operA, negA);
-
- ShaderIrOp op = new ShaderIrOp(ShaderIrInst.Add, operA, operB);
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(opCode.Gpr0(), op)));
- }
-
- public static void Iadd_R(ShaderIrBlock block, long opCode, int position)
- {
- EmitIadd(block, opCode, ShaderOper.Rr);
- }
-
- public static void Iadd3_C(ShaderIrBlock block, long opCode, int position)
- {
- EmitIadd3(block, opCode, ShaderOper.Cr);
- }
-
- public static void Iadd3_I(ShaderIrBlock block, long opCode, int position)
- {
- EmitIadd3(block, opCode, ShaderOper.Imm);
- }
-
- public static void Iadd3_R(ShaderIrBlock block, long opCode, int position)
- {
- EmitIadd3(block, opCode, ShaderOper.Rr);
- }
-
- public static void Imnmx_C(ShaderIrBlock block, long opCode, int position)
- {
- EmitImnmx(block, opCode, ShaderOper.Cr);
- }
-
- public static void Imnmx_I(ShaderIrBlock block, long opCode, int position)
- {
- EmitImnmx(block, opCode, ShaderOper.Imm);
- }
-
- public static void Imnmx_R(ShaderIrBlock block, long opCode, int position)
- {
- EmitImnmx(block, opCode, ShaderOper.Rr);
- }
-
- public static void Ipa(ShaderIrBlock block, long opCode, int position)
- {
- ShaderIrNode operA = opCode.Abuf28();
- ShaderIrNode operB = opCode.Gpr20();
-
- ShaderIpaMode mode = (ShaderIpaMode)(opCode.Read(54, 3));
-
- ShaderIrMetaIpa meta = new ShaderIrMetaIpa(mode);
-
- ShaderIrOp op = new ShaderIrOp(ShaderIrInst.Ipa, operA, operB, null, meta);
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(opCode.Gpr0(), op)));
- }
-
- public static void Iscadd_C(ShaderIrBlock block, long opCode, int position)
- {
- EmitIscadd(block, opCode, ShaderOper.Cr);
- }
-
- public static void Iscadd_I(ShaderIrBlock block, long opCode, int position)
- {
- EmitIscadd(block, opCode, ShaderOper.Imm);
- }
-
- public static void Iscadd_R(ShaderIrBlock block, long opCode, int position)
- {
- EmitIscadd(block, opCode, ShaderOper.Rr);
- }
-
- public static void Iset_C(ShaderIrBlock block, long opCode, int position)
- {
- EmitIset(block, opCode, ShaderOper.Cr);
- }
-
- public static void Iset_I(ShaderIrBlock block, long opCode, int position)
- {
- EmitIset(block, opCode, ShaderOper.Imm);
- }
-
- public static void Iset_R(ShaderIrBlock block, long opCode, int position)
- {
- EmitIset(block, opCode, ShaderOper.Rr);
- }
-
- public static void Isetp_C(ShaderIrBlock block, long opCode, int position)
- {
- EmitIsetp(block, opCode, ShaderOper.Cr);
- }
-
- public static void Isetp_I(ShaderIrBlock block, long opCode, int position)
- {
- EmitIsetp(block, opCode, ShaderOper.Imm);
- }
-
- public static void Isetp_R(ShaderIrBlock block, long opCode, int position)
- {
- EmitIsetp(block, opCode, ShaderOper.Rr);
- }
-
- public static void Lop_I32(ShaderIrBlock block, long opCode, int position)
- {
- int subOp = opCode.Read(53, 3);
-
- bool invA = opCode.Read(55);
- bool invB = opCode.Read(56);
-
- ShaderIrInst inst = 0;
-
- switch (subOp)
- {
- case 0: inst = ShaderIrInst.And; break;
- case 1: inst = ShaderIrInst.Or; break;
- case 2: inst = ShaderIrInst.Xor; break;
- }
-
- ShaderIrNode operB = GetAluNot(opCode.Imm32_20(), invB);
-
- //SubOp == 3 is pass, used by the not instruction
- //which just moves the inverted register value.
- if (subOp < 3)
- {
- ShaderIrNode operA = GetAluNot(opCode.Gpr8(), invA);
-
- ShaderIrOp op = new ShaderIrOp(inst, operA, operB);
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(opCode.Gpr0(), op)));
- }
- else
- {
- block.AddNode(opCode.PredNode(new ShaderIrAsg(opCode.Gpr0(), operB)));
- }
- }
-
- public static void Lop_C(ShaderIrBlock block, long opCode, int position)
- {
- EmitLop(block, opCode, ShaderOper.Cr);
- }
-
- public static void Lop_I(ShaderIrBlock block, long opCode, int position)
- {
- EmitLop(block, opCode, ShaderOper.Imm);
- }
-
- public static void Lop_R(ShaderIrBlock block, long opCode, int position)
- {
- EmitLop(block, opCode, ShaderOper.Rr);
- }
-
- public static void Mufu(ShaderIrBlock block, long opCode, int position)
- {
- int subOp = opCode.Read(20, 0xf);
-
- bool absA = opCode.Read(46);
- bool negA = opCode.Read(48);
-
- ShaderIrInst inst = 0;
-
- switch (subOp)
- {
- case 0: inst = ShaderIrInst.Fcos; break;
- case 1: inst = ShaderIrInst.Fsin; break;
- case 2: inst = ShaderIrInst.Fex2; break;
- case 3: inst = ShaderIrInst.Flg2; break;
- case 4: inst = ShaderIrInst.Frcp; break;
- case 5: inst = ShaderIrInst.Frsq; break;
- case 8: inst = ShaderIrInst.Fsqrt; break;
-
- default: throw new NotImplementedException(subOp.ToString());
- }
-
- ShaderIrNode operA = opCode.Gpr8();
-
- ShaderIrOp op = new ShaderIrOp(inst, GetAluFabsFneg(operA, absA, negA));
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(opCode.Gpr0(), op)));
- }
-
- public static void Psetp(ShaderIrBlock block, long opCode, int position)
- {
- bool negA = opCode.Read(15);
- bool negB = opCode.Read(32);
- bool negP = opCode.Read(42);
-
- ShaderIrInst lopInst = opCode.BLop24();
-
- ShaderIrNode operA = opCode.Pred12();
- ShaderIrNode operB = opCode.Pred29();
-
- if (negA)
- {
- operA = new ShaderIrOp(ShaderIrInst.Bnot, operA);
- }
-
- if (negB)
- {
- operB = new ShaderIrOp(ShaderIrInst.Bnot, operB);
- }
-
- ShaderIrOp op = new ShaderIrOp(lopInst, operA, operB);
-
- ShaderIrOperPred p0Node = opCode.Pred3();
- ShaderIrOperPred p1Node = opCode.Pred0();
- ShaderIrOperPred p2Node = opCode.Pred39();
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(p0Node, op)));
-
- lopInst = opCode.BLop45();
-
- if (lopInst == ShaderIrInst.Band && p1Node.IsConst && p2Node.IsConst)
- {
- return;
- }
-
- ShaderIrNode p2NNode = p2Node;
-
- if (negP)
- {
- p2NNode = new ShaderIrOp(ShaderIrInst.Bnot, p2NNode);
- }
-
- op = new ShaderIrOp(ShaderIrInst.Bnot, p0Node);
-
- op = new ShaderIrOp(lopInst, op, p2NNode);
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(p1Node, op)));
-
- op = new ShaderIrOp(lopInst, p0Node, p2NNode);
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(p0Node, op)));
- }
-
- public static void Rro_C(ShaderIrBlock block, long opCode, int position)
- {
- EmitRro(block, opCode, ShaderOper.Cr);
- }
-
- public static void Rro_I(ShaderIrBlock block, long opCode, int position)
- {
- EmitRro(block, opCode, ShaderOper.Immf);
- }
-
- public static void Rro_R(ShaderIrBlock block, long opCode, int position)
- {
- EmitRro(block, opCode, ShaderOper.Rr);
- }
-
- public static void Shl_C(ShaderIrBlock block, long opCode, int position)
- {
- EmitAluBinary(block, opCode, ShaderOper.Cr, ShaderIrInst.Lsl);
- }
-
- public static void Shl_I(ShaderIrBlock block, long opCode, int position)
- {
- EmitAluBinary(block, opCode, ShaderOper.Imm, ShaderIrInst.Lsl);
- }
-
- public static void Shl_R(ShaderIrBlock block, long opCode, int position)
- {
- EmitAluBinary(block, opCode, ShaderOper.Rr, ShaderIrInst.Lsl);
- }
-
- public static void Shr_C(ShaderIrBlock block, long opCode, int position)
- {
- EmitAluBinary(block, opCode, ShaderOper.Cr, GetShrInst(opCode));
- }
-
- public static void Shr_I(ShaderIrBlock block, long opCode, int position)
- {
- EmitAluBinary(block, opCode, ShaderOper.Imm, GetShrInst(opCode));
- }
-
- public static void Shr_R(ShaderIrBlock block, long opCode, int position)
- {
- EmitAluBinary(block, opCode, ShaderOper.Rr, GetShrInst(opCode));
- }
-
- private static ShaderIrInst GetShrInst(long opCode)
- {
- bool signed = opCode.Read(48);
-
- return signed ? ShaderIrInst.Asr : ShaderIrInst.Lsr;
- }
-
- public static void Vmad(ShaderIrBlock block, long opCode, int position)
- {
- ShaderIrNode operA = opCode.Gpr8();
-
- ShaderIrNode operB;
-
- if (opCode.Read(50))
- {
- operB = opCode.Gpr20();
- }
- else
- {
- operB = opCode.Imm19_20();
- }
-
- ShaderIrOperGpr operC = opCode.Gpr39();
-
- ShaderIrNode tmp = new ShaderIrOp(ShaderIrInst.Mul, operA, operB);
-
- ShaderIrNode final = new ShaderIrOp(ShaderIrInst.Add, tmp, operC);
-
- int shr = opCode.Read(51, 3);
-
- if (shr != 0)
- {
- int shift = (shr == 2) ? 15 : 7;
-
- final = new ShaderIrOp(ShaderIrInst.Lsr, final, new ShaderIrOperImm(shift));
- }
-
- block.AddNode(new ShaderIrCmnt("Stubbed. Instruction is reduced to a * b + c"));
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(opCode.Gpr0(), final)));
- }
-
- public static void Xmad_CR(ShaderIrBlock block, long opCode, int position)
- {
- EmitXmad(block, opCode, ShaderOper.Cr);
- }
-
- public static void Xmad_I(ShaderIrBlock block, long opCode, int position)
- {
- EmitXmad(block, opCode, ShaderOper.Imm);
- }
-
- public static void Xmad_RC(ShaderIrBlock block, long opCode, int position)
- {
- EmitXmad(block, opCode, ShaderOper.Rc);
- }
-
- public static void Xmad_RR(ShaderIrBlock block, long opCode, int position)
- {
- EmitXmad(block, opCode, ShaderOper.Rr);
- }
-
- private static void EmitAluBinary(
- ShaderIrBlock block,
- long opCode,
- ShaderOper oper,
- ShaderIrInst inst)
- {
- ShaderIrNode operA = opCode.Gpr8(), operB;
-
- switch (oper)
- {
- case ShaderOper.Cr: operB = opCode.Cbuf34(); break;
- case ShaderOper.Imm: operB = opCode.Imm19_20(); break;
- case ShaderOper.Rr: operB = opCode.Gpr20(); break;
-
- default: throw new ArgumentException(nameof(oper));
- }
-
- ShaderIrNode op = new ShaderIrOp(inst, operA, operB);
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(opCode.Gpr0(), op)));
- }
-
- private static void EmitBfe(ShaderIrBlock block, long opCode, ShaderOper oper)
- {
- //TODO: Handle the case where position + length
- //is greater than the word size, in this case the sign bit
- //needs to be replicated to fill the remaining space.
- bool negB = opCode.Read(48);
- bool negA = opCode.Read(49);
-
- ShaderIrNode operA = opCode.Gpr8(), operB;
-
- switch (oper)
- {
- case ShaderOper.Cr: operB = opCode.Cbuf34(); break;
- case ShaderOper.Imm: operB = opCode.Imm19_20(); break;
- case ShaderOper.Rr: operB = opCode.Gpr20(); break;
-
- default: throw new ArgumentException(nameof(oper));
- }
-
- ShaderIrNode op;
-
- bool signed = opCode.Read(48); //?
-
- if (operB is ShaderIrOperImm posLen)
- {
- int position = (posLen.Value >> 0) & 0xff;
- int length = (posLen.Value >> 8) & 0xff;
-
- int lSh = 32 - (position + length);
-
- ShaderIrInst rightShift = signed
- ? ShaderIrInst.Asr
- : ShaderIrInst.Lsr;
-
- op = new ShaderIrOp(ShaderIrInst.Lsl, operA, new ShaderIrOperImm(lSh));
- op = new ShaderIrOp(rightShift, op, new ShaderIrOperImm(lSh + position));
- }
- else
- {
- ShaderIrOperImm shift = new ShaderIrOperImm(8);
- ShaderIrOperImm mask = new ShaderIrOperImm(0xff);
-
- ShaderIrNode opPos, opLen;
-
- opPos = new ShaderIrOp(ShaderIrInst.And, operB, mask);
- opLen = new ShaderIrOp(ShaderIrInst.Lsr, operB, shift);
- opLen = new ShaderIrOp(ShaderIrInst.And, opLen, mask);
-
- op = new ShaderIrOp(ShaderIrInst.Lsr, operA, opPos);
-
- op = ExtendTo32(op, signed, opLen);
- }
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(opCode.Gpr0(), op)));
- }
-
- private static void EmitFadd(ShaderIrBlock block, long opCode, ShaderOper oper)
- {
- bool negB = opCode.Read(45);
- bool absA = opCode.Read(46);
- bool negA = opCode.Read(48);
- bool absB = opCode.Read(49);
- bool sat = opCode.Read(50);
-
- ShaderIrNode operA = opCode.Gpr8(), operB;
-
- operA = GetAluFabsFneg(operA, absA, negA);
-
- switch (oper)
- {
- case ShaderOper.Cr: operB = opCode.Cbuf34(); break;
- case ShaderOper.Immf: operB = opCode.Immf19_20(); break;
- case ShaderOper.Rr: operB = opCode.Gpr20(); break;
-
- default: throw new ArgumentException(nameof(oper));
- }
-
- operB = GetAluFabsFneg(operB, absB, negB);
-
- ShaderIrNode op = new ShaderIrOp(ShaderIrInst.Fadd, operA, operB);
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(opCode.Gpr0(), GetAluFsat(op, sat))));
- }
-
- private static void EmitFmul(ShaderIrBlock block, long opCode, ShaderOper oper)
- {
- bool negB = opCode.Read(48);
- bool sat = opCode.Read(50);
-
- ShaderIrNode operA = opCode.Gpr8(), operB;
-
- switch (oper)
- {
- case ShaderOper.Cr: operB = opCode.Cbuf34(); break;
- case ShaderOper.Immf: operB = opCode.Immf19_20(); break;
- case ShaderOper.Rr: operB = opCode.Gpr20(); break;
-
- default: throw new ArgumentException(nameof(oper));
- }
-
- operB = GetAluFneg(operB, negB);
-
- ShaderIrNode op = new ShaderIrOp(ShaderIrInst.Fmul, operA, operB);
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(opCode.Gpr0(), GetAluFsat(op, sat))));
- }
-
- private static void EmitFfma(ShaderIrBlock block, long opCode, ShaderOper oper)
- {
- bool negB = opCode.Read(48);
- bool negC = opCode.Read(49);
- bool sat = opCode.Read(50);
-
- ShaderIrNode operA = opCode.Gpr8(), operB, operC;
-
- switch (oper)
- {
- case ShaderOper.Cr: operB = opCode.Cbuf34(); break;
- case ShaderOper.Immf: operB = opCode.Immf19_20(); break;
- case ShaderOper.Rc: operB = opCode.Gpr39(); break;
- case ShaderOper.Rr: operB = opCode.Gpr20(); break;
-
- default: throw new ArgumentException(nameof(oper));
- }
-
- operB = GetAluFneg(operB, negB);
-
- if (oper == ShaderOper.Rc)
- {
- operC = GetAluFneg(opCode.Cbuf34(), negC);
- }
- else
- {
- operC = GetAluFneg(opCode.Gpr39(), negC);
- }
-
- ShaderIrOp op = new ShaderIrOp(ShaderIrInst.Ffma, operA, operB, operC);
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(opCode.Gpr0(), GetAluFsat(op, sat))));
- }
-
- private static void EmitIadd(ShaderIrBlock block, long opCode, ShaderOper oper)
- {
- ShaderIrNode operA = opCode.Gpr8();
- ShaderIrNode operB;
-
- switch (oper)
- {
- case ShaderOper.Cr: operB = opCode.Cbuf34(); break;
- case ShaderOper.Imm: operB = opCode.Imm19_20(); break;
- case ShaderOper.Rr: operB = opCode.Gpr20(); break;
-
- default: throw new ArgumentException(nameof(oper));
- }
-
- bool negA = opCode.Read(49);
- bool negB = opCode.Read(48);
-
- operA = GetAluIneg(operA, negA);
- operB = GetAluIneg(operB, negB);
-
- ShaderIrOp op = new ShaderIrOp(ShaderIrInst.Add, operA, operB);
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(opCode.Gpr0(), op)));
- }
-
- private static void EmitIadd3(ShaderIrBlock block, long opCode, ShaderOper oper)
- {
- int mode = opCode.Read(37, 3);
-
- bool neg1 = opCode.Read(51);
- bool neg2 = opCode.Read(50);
- bool neg3 = opCode.Read(49);
-
- int height1 = opCode.Read(35, 3);
- int height2 = opCode.Read(33, 3);
- int height3 = opCode.Read(31, 3);
-
- ShaderIrNode operB;
-
- switch (oper)
- {
- case ShaderOper.Cr: operB = opCode.Cbuf34(); break;
- case ShaderOper.Imm: operB = opCode.Imm19_20(); break;
- case ShaderOper.Rr: operB = opCode.Gpr20(); break;
-
- default: throw new ArgumentException(nameof(oper));
- }
-
- ShaderIrNode ApplyHeight(ShaderIrNode src, int height)
- {
- if (oper != ShaderOper.Rr)
- {
- return src;
- }
-
- switch (height)
- {
- case 0: return src;
- case 1: return new ShaderIrOp(ShaderIrInst.And, src, new ShaderIrOperImm(0xffff));
- case 2: return new ShaderIrOp(ShaderIrInst.Lsr, src, new ShaderIrOperImm(16));
-
- default: throw new InvalidOperationException();
- }
- }
-
- ShaderIrNode src1 = GetAluIneg(ApplyHeight(opCode.Gpr8(), height1), neg1);
- ShaderIrNode src2 = GetAluIneg(ApplyHeight(operB, height2), neg2);
- ShaderIrNode src3 = GetAluIneg(ApplyHeight(opCode.Gpr39(), height3), neg3);
-
- ShaderIrOp sum = new ShaderIrOp(ShaderIrInst.Add, src1, src2);
-
- if (oper == ShaderOper.Rr)
- {
- switch (mode)
- {
- case 1: sum = new ShaderIrOp(ShaderIrInst.Lsr, sum, new ShaderIrOperImm(16)); break;
- case 2: sum = new ShaderIrOp(ShaderIrInst.Lsl, sum, new ShaderIrOperImm(16)); break;
- }
- }
-
- //Note: Here there should be a "+ 1" when carry flag is set
- //but since carry is mostly ignored by other instructions, it's excluded for now
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(opCode.Gpr0(), new ShaderIrOp(ShaderIrInst.Add, sum, src3))));
- }
-
- private static void EmitIscadd(ShaderIrBlock block, long opCode, ShaderOper oper)
- {
- bool negB = opCode.Read(48);
- bool negA = opCode.Read(49);
-
- ShaderIrNode operA = opCode.Gpr8(), operB;
-
- ShaderIrOperImm scale = opCode.Imm5_39();
-
- switch (oper)
- {
- case ShaderOper.Cr: operB = opCode.Cbuf34(); break;
- case ShaderOper.Imm: operB = opCode.Imm19_20(); break;
- case ShaderOper.Rr: operB = opCode.Gpr20(); break;
-
- default: throw new ArgumentException(nameof(oper));
- }
-
- operA = GetAluIneg(operA, negA);
- operB = GetAluIneg(operB, negB);
-
- ShaderIrOp scaleOp = new ShaderIrOp(ShaderIrInst.Lsl, operA, scale);
- ShaderIrOp addOp = new ShaderIrOp(ShaderIrInst.Add, operB, scaleOp);
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(opCode.Gpr0(), addOp)));
- }
-
- private static void EmitFmnmx(ShaderIrBlock block, long opCode, ShaderOper oper)
- {
- EmitMnmx(block, opCode, true, oper);
- }
-
- private static void EmitImnmx(ShaderIrBlock block, long opCode, ShaderOper oper)
- {
- EmitMnmx(block, opCode, false, oper);
- }
-
- private static void EmitMnmx(ShaderIrBlock block, long opCode, bool isFloat, ShaderOper oper)
- {
- bool negB = opCode.Read(45);
- bool absA = opCode.Read(46);
- bool negA = opCode.Read(48);
- bool absB = opCode.Read(49);
-
- ShaderIrNode operA = opCode.Gpr8(), operB;
-
- if (isFloat)
- {
- operA = GetAluFabsFneg(operA, absA, negA);
- }
- else
- {
- operA = GetAluIabsIneg(operA, absA, negA);
- }
-
- switch (oper)
- {
- case ShaderOper.Cr: operB = opCode.Cbuf34(); break;
- case ShaderOper.Imm: operB = opCode.Imm19_20(); break;
- case ShaderOper.Immf: operB = opCode.Immf19_20(); break;
- case ShaderOper.Rr: operB = opCode.Gpr20(); break;
-
- default: throw new ArgumentException(nameof(oper));
- }
-
- if (isFloat)
- {
- operB = GetAluFabsFneg(operB, absB, negB);
- }
- else
- {
- operB = GetAluIabsIneg(operB, absB, negB);
- }
-
- ShaderIrOperPred pred = opCode.Pred39();
-
- ShaderIrOp op;
-
- ShaderIrInst maxInst = isFloat ? ShaderIrInst.Fmax : ShaderIrInst.Max;
- ShaderIrInst minInst = isFloat ? ShaderIrInst.Fmin : ShaderIrInst.Min;
-
- if (pred.IsConst)
- {
- bool isMax = opCode.Read(42);
-
- op = new ShaderIrOp(isMax
- ? maxInst
- : minInst, operA, operB);
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(opCode.Gpr0(), op)));
- }
- else
- {
- ShaderIrNode predN = opCode.Pred39N();
-
- ShaderIrOp opMax = new ShaderIrOp(maxInst, operA, operB);
- ShaderIrOp opMin = new ShaderIrOp(minInst, operA, operB);
-
- ShaderIrAsg asgMax = new ShaderIrAsg(opCode.Gpr0(), opMax);
- ShaderIrAsg asgMin = new ShaderIrAsg(opCode.Gpr0(), opMin);
-
- block.AddNode(opCode.PredNode(new ShaderIrCond(predN, asgMax, not: true)));
- block.AddNode(opCode.PredNode(new ShaderIrCond(predN, asgMin, not: false)));
- }
- }
-
- private static void EmitRro(ShaderIrBlock block, long opCode, ShaderOper oper)
- {
- //Note: this is a range reduction instruction and is supposed to
- //be used with Mufu, here it just moves the value and ignores the operation.
- bool negA = opCode.Read(45);
- bool absA = opCode.Read(49);
-
- ShaderIrNode operA;
-
- switch (oper)
- {
- case ShaderOper.Cr: operA = opCode.Cbuf34(); break;
- case ShaderOper.Immf: operA = opCode.Immf19_20(); break;
- case ShaderOper.Rr: operA = opCode.Gpr20(); break;
-
- default: throw new ArgumentException(nameof(oper));
- }
-
- operA = GetAluFabsFneg(operA, absA, negA);
-
- block.AddNode(new ShaderIrCmnt("Stubbed."));
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(opCode.Gpr0(), operA)));
- }
-
- private static void EmitFset(ShaderIrBlock block, long opCode, ShaderOper oper)
- {
- EmitSet(block, opCode, true, oper);
- }
-
- private static void EmitIset(ShaderIrBlock block, long opCode, ShaderOper oper)
- {
- EmitSet(block, opCode, false, oper);
- }
-
- private static void EmitSet(ShaderIrBlock block, long opCode, bool isFloat, ShaderOper oper)
- {
- bool negA = opCode.Read(43);
- bool absB = opCode.Read(44);
- bool negB = opCode.Read(53);
- bool absA = opCode.Read(54);
-
- bool boolFloat = opCode.Read(isFloat ? 52 : 44);
-
- ShaderIrNode operA = opCode.Gpr8(), operB;
-
- switch (oper)
- {
- case ShaderOper.Cr: operB = opCode.Cbuf34(); break;
- case ShaderOper.Imm: operB = opCode.Imm19_20(); break;
- case ShaderOper.Immf: operB = opCode.Immf19_20(); break;
- case ShaderOper.Rr: operB = opCode.Gpr20(); break;
-
- default: throw new ArgumentException(nameof(oper));
- }
-
- ShaderIrInst cmpInst;
-
- if (isFloat)
- {
- operA = GetAluFabsFneg(operA, absA, negA);
- operB = GetAluFabsFneg(operB, absB, negB);
-
- cmpInst = opCode.CmpF();
- }
- else
- {
- cmpInst = opCode.Cmp();
- }
-
- ShaderIrOp op = new ShaderIrOp(cmpInst, operA, operB);
-
- ShaderIrInst lopInst = opCode.BLop45();
-
- ShaderIrOperPred pNode = opCode.Pred39();
-
- ShaderIrNode imm0, imm1;
-
- if (boolFloat)
- {
- imm0 = new ShaderIrOperImmf(0);
- imm1 = new ShaderIrOperImmf(1);
- }
- else
- {
- imm0 = new ShaderIrOperImm(0);
- imm1 = new ShaderIrOperImm(-1);
- }
-
- ShaderIrNode asg0 = new ShaderIrAsg(opCode.Gpr0(), imm0);
- ShaderIrNode asg1 = new ShaderIrAsg(opCode.Gpr0(), imm1);
-
- if (lopInst != ShaderIrInst.Band || !pNode.IsConst)
- {
- ShaderIrOp op2 = new ShaderIrOp(lopInst, op, pNode);
-
- asg0 = new ShaderIrCond(op2, asg0, not: true);
- asg1 = new ShaderIrCond(op2, asg1, not: false);
- }
- else
- {
- asg0 = new ShaderIrCond(op, asg0, not: true);
- asg1 = new ShaderIrCond(op, asg1, not: false);
- }
-
- block.AddNode(opCode.PredNode(asg0));
- block.AddNode(opCode.PredNode(asg1));
- }
-
- private static void EmitFsetp(ShaderIrBlock block, long opCode, ShaderOper oper)
- {
- EmitSetp(block, opCode, true, oper);
- }
-
- private static void EmitIsetp(ShaderIrBlock block, long opCode, ShaderOper oper)
- {
- EmitSetp(block, opCode, false, oper);
- }
-
- private static void EmitSetp(ShaderIrBlock block, long opCode, bool isFloat, ShaderOper oper)
- {
- bool absA = opCode.Read(7);
- bool negP = opCode.Read(42);
- bool negA = opCode.Read(43);
- bool absB = opCode.Read(44);
-
- ShaderIrNode operA = opCode.Gpr8(), operB;
-
- switch (oper)
- {
- case ShaderOper.Cr: operB = opCode.Cbuf34(); break;
- case ShaderOper.Imm: operB = opCode.Imm19_20(); break;
- case ShaderOper.Immf: operB = opCode.Immf19_20(); break;
- case ShaderOper.Rr: operB = opCode.Gpr20(); break;
-
- default: throw new ArgumentException(nameof(oper));
- }
-
- ShaderIrInst cmpInst;
-
- if (isFloat)
- {
- operA = GetAluFabsFneg(operA, absA, negA);
- operB = GetAluFabs (operB, absB);
-
- cmpInst = opCode.CmpF();
- }
- else
- {
- cmpInst = opCode.Cmp();
- }
-
- ShaderIrOp op = new ShaderIrOp(cmpInst, operA, operB);
-
- ShaderIrOperPred p0Node = opCode.Pred3();
- ShaderIrOperPred p1Node = opCode.Pred0();
- ShaderIrOperPred p2Node = opCode.Pred39();
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(p0Node, op)));
-
- ShaderIrInst lopInst = opCode.BLop45();
-
- if (lopInst == ShaderIrInst.Band && p1Node.IsConst && p2Node.IsConst)
- {
- return;
- }
-
- ShaderIrNode p2NNode = p2Node;
-
- if (negP)
- {
- p2NNode = new ShaderIrOp(ShaderIrInst.Bnot, p2NNode);
- }
-
- op = new ShaderIrOp(ShaderIrInst.Bnot, p0Node);
-
- op = new ShaderIrOp(lopInst, op, p2NNode);
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(p1Node, op)));
-
- op = new ShaderIrOp(lopInst, p0Node, p2NNode);
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(p0Node, op)));
- }
-
- private static void EmitBinaryHalfOp(ShaderIrBlock block, long opCode, ShaderIrInst inst)
- {
- bool absB = opCode.Read(30);
- bool negB = opCode.Read(31);
- bool sat = opCode.Read(32);
- bool absA = opCode.Read(44);
-
- ShaderIrOperGpr[] vecA = opCode.GprHalfVec8();
- ShaderIrOperGpr[] vecB = opCode.GprHalfVec20();
-
- HalfOutputType outputType = (HalfOutputType)opCode.Read(49, 3);
-
- int elems = outputType == HalfOutputType.PackedFp16 ? 2 : 1;
- int first = outputType == HalfOutputType.MergeH1 ? 1 : 0;
-
- for (int index = first; index < elems; index++)
- {
- ShaderIrNode operA = GetAluFabs (vecA[index], absA);
- ShaderIrNode operB = GetAluFabsFneg(vecB[index], absB, negB);
-
- ShaderIrNode op = new ShaderIrOp(inst, operA, operB);
-
- ShaderIrOperGpr dst = GetHalfDst(opCode, outputType, index);
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(dst, GetAluFsat(op, sat))));
- }
- }
-
- private static ShaderIrOperGpr GetHalfDst(long opCode, HalfOutputType outputType, int index)
- {
- switch (outputType)
- {
- case HalfOutputType.PackedFp16: return opCode.GprHalf0(index);
- case HalfOutputType.Fp32: return opCode.Gpr0();
- case HalfOutputType.MergeH0: return opCode.GprHalf0(0);
- case HalfOutputType.MergeH1: return opCode.GprHalf0(1);
- }
-
- throw new ArgumentException(nameof(outputType));
- }
-
- private static void EmitLop(ShaderIrBlock block, long opCode, ShaderOper oper)
- {
- int subOp = opCode.Read(41, 3);
-
- bool invA = opCode.Read(39);
- bool invB = opCode.Read(40);
-
- ShaderIrInst inst = 0;
-
- switch (subOp)
- {
- case 0: inst = ShaderIrInst.And; break;
- case 1: inst = ShaderIrInst.Or; break;
- case 2: inst = ShaderIrInst.Xor; break;
- }
-
- ShaderIrNode operA = GetAluNot(opCode.Gpr8(), invA);
- ShaderIrNode operB;
-
- switch (oper)
- {
- case ShaderOper.Cr: operB = opCode.Cbuf34(); break;
- case ShaderOper.Imm: operB = opCode.Imm19_20(); break;
- case ShaderOper.Rr: operB = opCode.Gpr20(); break;
-
- default: throw new ArgumentException(nameof(oper));
- }
-
- operB = GetAluNot(operB, invB);
-
- ShaderIrNode op;
-
- if (subOp < 3)
- {
- op = new ShaderIrOp(inst, operA, operB);
- }
- else
- {
- op = operB;
- }
-
- ShaderIrNode compare = new ShaderIrOp(ShaderIrInst.Cne, op, new ShaderIrOperImm(0));
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(opCode.Pred48(), compare)));
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(opCode.Gpr0(), op)));
- }
-
- private enum XmadMode
- {
- Cfull = 0,
- Clo = 1,
- Chi = 2,
- Csfu = 3,
- Cbcc = 4
- }
-
- private static void EmitXmad(ShaderIrBlock block, long opCode, ShaderOper oper)
- {
- bool signedA = opCode.Read(48);
- bool signedB = opCode.Read(49);
- bool highB = opCode.Read(52);
- bool highA = opCode.Read(53);
-
- int mode = opCode.Read(50, 7);
-
- ShaderIrNode operA = opCode.Gpr8(), operB, operC;
-
- switch (oper)
- {
- case ShaderOper.Cr: operB = opCode.Cbuf34(); break;
- case ShaderOper.Imm: operB = opCode.ImmU16_20(); break;
- case ShaderOper.Rc: operB = opCode.Gpr39(); break;
- case ShaderOper.Rr: operB = opCode.Gpr20(); break;
-
- default: throw new ArgumentException(nameof(oper));
- }
-
- ShaderIrNode operB2 = operB;
-
- if (oper == ShaderOper.Imm)
- {
- int imm = ((ShaderIrOperImm)operB2).Value;
-
- if (!highB)
- {
- imm <<= 16;
- }
-
- if (signedB)
- {
- imm >>= 16;
- }
- else
- {
- imm = (int)((uint)imm >> 16);
- }
-
- operB2 = new ShaderIrOperImm(imm);
- }
-
- ShaderIrOperImm imm16 = new ShaderIrOperImm(16);
-
- //If we are working with the lower 16-bits of the A/B operands,
- //we need to shift the lower 16-bits to the top 16-bits. Later,
- //they will be right shifted. For U16 types, this will be a logical
- //right shift, and for S16 types, a arithmetic right shift.
- if (!highA)
- {
- operA = new ShaderIrOp(ShaderIrInst.Lsl, operA, imm16);
- }
-
- if (!highB && oper != ShaderOper.Imm)
- {
- operB2 = new ShaderIrOp(ShaderIrInst.Lsl, operB2, imm16);
- }
-
- ShaderIrInst shiftA = signedA ? ShaderIrInst.Asr : ShaderIrInst.Lsr;
- ShaderIrInst shiftB = signedB ? ShaderIrInst.Asr : ShaderIrInst.Lsr;
-
- operA = new ShaderIrOp(shiftA, operA, imm16);
-
- if (oper != ShaderOper.Imm)
- {
- operB2 = new ShaderIrOp(shiftB, operB2, imm16);
- }
-
- bool productShiftLeft = false;
- bool merge = false;
-
- if (oper == ShaderOper.Rc)
- {
- operC = opCode.Cbuf34();
- }
- else
- {
- operC = opCode.Gpr39();
-
- productShiftLeft = opCode.Read(36);
- merge = opCode.Read(37);
- }
-
- ShaderIrOp mulOp = new ShaderIrOp(ShaderIrInst.Mul, operA, operB2);
-
- if (productShiftLeft)
- {
- mulOp = new ShaderIrOp(ShaderIrInst.Lsl, mulOp, imm16);
- }
-
- switch ((XmadMode)mode)
- {
- case XmadMode.Clo: operC = ExtendTo32(operC, signed: false, size: 16); break;
-
- case XmadMode.Chi: operC = new ShaderIrOp(ShaderIrInst.Lsr, operC, imm16); break;
-
- case XmadMode.Cbcc:
- {
- ShaderIrOp operBLsh16 = new ShaderIrOp(ShaderIrInst.Lsl, operB, imm16);
-
- operC = new ShaderIrOp(ShaderIrInst.Add, operC, operBLsh16);
-
- break;
- }
-
- case XmadMode.Csfu:
- {
- ShaderIrOperImm imm31 = new ShaderIrOperImm(31);
-
- ShaderIrOp signAdjustA = new ShaderIrOp(ShaderIrInst.Lsr, operA, imm31);
- ShaderIrOp signAdjustB = new ShaderIrOp(ShaderIrInst.Lsr, operB2, imm31);
-
- signAdjustA = new ShaderIrOp(ShaderIrInst.Lsl, signAdjustA, imm16);
- signAdjustB = new ShaderIrOp(ShaderIrInst.Lsl, signAdjustB, imm16);
-
- ShaderIrOp signAdjust = new ShaderIrOp(ShaderIrInst.Add, signAdjustA, signAdjustB);
-
- operC = new ShaderIrOp(ShaderIrInst.Sub, operC, signAdjust);
-
- break;
- }
- }
-
- ShaderIrOp addOp = new ShaderIrOp(ShaderIrInst.Add, mulOp, operC);
-
- if (merge)
- {
- ShaderIrOperImm imm16Mask = new ShaderIrOperImm(0xffff);
-
- addOp = new ShaderIrOp(ShaderIrInst.And, addOp, imm16Mask);
- operB = new ShaderIrOp(ShaderIrInst.Lsl, operB, imm16);
- addOp = new ShaderIrOp(ShaderIrInst.Or, addOp, operB);
- }
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(opCode.Gpr0(), addOp)));
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeFlow.cs b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeFlow.cs
deleted file mode 100644
index fc992693..00000000
--- a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeFlow.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-using System;
-
-namespace Ryujinx.Graphics.Gal.Shader
-{
- static partial class ShaderDecode
- {
- public static void Bra(ShaderIrBlock block, long opCode, int position)
- {
- if ((opCode & 0x20) != 0)
- {
- //This reads the target offset from the constant buffer.
- //Almost impossible to support with GLSL.
- throw new NotImplementedException();
- }
-
- ShaderIrOperImm imm = new ShaderIrOperImm(position + opCode.Branch());
-
- block.AddNode(opCode.PredNode(new ShaderIrOp(ShaderIrInst.Bra, imm)));
- }
-
- public static void Exit(ShaderIrBlock block, long opCode, int position)
- {
- int cCode = (int)opCode & 0x1f;
-
- //TODO: Figure out what the other condition codes mean...
- if (cCode == 0xf)
- {
- block.AddNode(opCode.PredNode(new ShaderIrOp(ShaderIrInst.Exit)));
- }
- }
-
- public static void Kil(ShaderIrBlock block, long opCode, int position)
- {
- block.AddNode(opCode.PredNode(new ShaderIrOp(ShaderIrInst.Kil)));
- }
-
- public static void Ssy(ShaderIrBlock block, long opCode, int position)
- {
- if ((opCode & 0x20) != 0)
- {
- //This reads the target offset from the constant buffer.
- //Almost impossible to support with GLSL.
- throw new NotImplementedException();
- }
-
- ShaderIrOperImm imm = new ShaderIrOperImm(position + opCode.Branch());
-
- block.AddNode(new ShaderIrOp(ShaderIrInst.Ssy, imm));
- }
-
- public static void Sync(ShaderIrBlock block, long opCode, int position)
- {
- //TODO: Implement Sync condition codes
- block.AddNode(opCode.PredNode(new ShaderIrOp(ShaderIrInst.Sync)));
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeFunc.cs b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeFunc.cs
deleted file mode 100644
index cc385aa4..00000000
--- a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeFunc.cs
+++ /dev/null
@@ -1,4 +0,0 @@
-namespace Ryujinx.Graphics.Gal.Shader
-{
- delegate void ShaderDecodeFunc(ShaderIrBlock block, long opCode, int position);
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeHelper.cs b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeHelper.cs
deleted file mode 100644
index 9a84e612..00000000
--- a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeHelper.cs
+++ /dev/null
@@ -1,78 +0,0 @@
-namespace Ryujinx.Graphics.Gal.Shader
-{
- static class ShaderDecodeHelper
- {
- private static readonly ShaderIrOperImmf ImmfZero = new ShaderIrOperImmf(0);
- private static readonly ShaderIrOperImmf ImmfOne = new ShaderIrOperImmf(1);
-
- public static ShaderIrNode GetAluFabsFneg(ShaderIrNode node, bool abs, bool neg)
- {
- return GetAluFneg(GetAluFabs(node, abs), neg);
- }
-
- public static ShaderIrNode GetAluFabs(ShaderIrNode node, bool abs)
- {
- return abs ? new ShaderIrOp(ShaderIrInst.Fabs, node) : node;
- }
-
- public static ShaderIrNode GetAluFneg(ShaderIrNode node, bool neg)
- {
- return neg ? new ShaderIrOp(ShaderIrInst.Fneg, node) : node;
- }
-
- public static ShaderIrNode GetAluFsat(ShaderIrNode node, bool sat)
- {
- return sat ? new ShaderIrOp(ShaderIrInst.Fclamp, node, ImmfZero, ImmfOne) : node;
- }
-
- public static ShaderIrNode GetAluIabsIneg(ShaderIrNode node, bool abs, bool neg)
- {
- return GetAluIneg(GetAluIabs(node, abs), neg);
- }
-
- public static ShaderIrNode GetAluIabs(ShaderIrNode node, bool abs)
- {
- return abs ? new ShaderIrOp(ShaderIrInst.Abs, node) : node;
- }
-
- public static ShaderIrNode GetAluIneg(ShaderIrNode node, bool neg)
- {
- return neg ? new ShaderIrOp(ShaderIrInst.Neg, node) : node;
- }
-
- public static ShaderIrNode GetAluNot(ShaderIrNode node, bool not)
- {
- return not ? new ShaderIrOp(ShaderIrInst.Not, node) : node;
- }
-
- public static ShaderIrNode ExtendTo32(ShaderIrNode node, bool signed, int size)
- {
- int shift = 32 - size;
-
- ShaderIrInst rightShift = signed
- ? ShaderIrInst.Asr
- : ShaderIrInst.Lsr;
-
- node = new ShaderIrOp(ShaderIrInst.Lsl, node, new ShaderIrOperImm(shift));
- node = new ShaderIrOp(rightShift, node, new ShaderIrOperImm(shift));
-
- return node;
- }
-
- public static ShaderIrNode ExtendTo32(ShaderIrNode node, bool signed, ShaderIrNode size)
- {
- ShaderIrOperImm wordSize = new ShaderIrOperImm(32);
-
- ShaderIrOp shift = new ShaderIrOp(ShaderIrInst.Sub, wordSize, size);
-
- ShaderIrInst rightShift = signed
- ? ShaderIrInst.Asr
- : ShaderIrInst.Lsr;
-
- node = new ShaderIrOp(ShaderIrInst.Lsl, node, shift);
- node = new ShaderIrOp(rightShift, node, shift);
-
- return node;
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeMem.cs b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeMem.cs
deleted file mode 100644
index 7ce126b0..00000000
--- a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeMem.cs
+++ /dev/null
@@ -1,878 +0,0 @@
-using Ryujinx.Graphics.Texture;
-using System;
-
-using static Ryujinx.Graphics.Gal.Shader.ShaderDecodeHelper;
-
-namespace Ryujinx.Graphics.Gal.Shader
-{
- static partial class ShaderDecode
- {
- // ReSharper disable InconsistentNaming
- private const int ____ = 0x0;
- private const int R___ = 0x1;
- private const int _G__ = 0x2;
- private const int RG__ = 0x3;
- private const int __B_ = 0x4;
- private const int RGB_ = 0x7;
- private const int ___A = 0x8;
- private const int R__A = 0x9;
- private const int _G_A = 0xa;
- private const int RG_A = 0xb;
- private const int __BA = 0xc;
- private const int R_BA = 0xd;
- private const int _GBA = 0xe;
- private const int RGBA = 0xf;
- // ReSharper restore InconsistentNaming
-
- private static int[,] _maskLut = new int[,]
- {
- { ____, ____, ____, ____, ____, ____, ____, ____ },
- { R___, _G__, __B_, ___A, RG__, R__A, _G_A, __BA },
- { R___, _G__, __B_, ___A, RG__, ____, ____, ____ },
- { RGB_, RG_A, R_BA, _GBA, RGBA, ____, ____, ____ }
- };
-
- private static GalTextureTarget TexToTextureTarget(int texType, bool isArray)
- {
- switch (texType)
- {
- case 0:
- return isArray ? GalTextureTarget.OneDArray : GalTextureTarget.OneD;
- case 2:
- return isArray ? GalTextureTarget.TwoDArray : GalTextureTarget.TwoD;
- case 4:
- if (isArray)
- throw new InvalidOperationException("ARRAY bit set on a TEX with 3D texture!");
- return GalTextureTarget.ThreeD;
- case 6:
- return isArray ? GalTextureTarget.CubeArray : GalTextureTarget.CubeMap;
- default:
- throw new InvalidOperationException();
- }
- }
-
- private static GalTextureTarget TexsToTextureTarget(int texType)
- {
- switch (texType)
- {
- case 0:
- return GalTextureTarget.OneD;
- case 2:
- case 4:
- case 6:
- case 8:
- case 0xa:
- case 0xc:
- return GalTextureTarget.TwoD;
- case 0xe:
- case 0x10:
- case 0x12:
- return GalTextureTarget.TwoDArray;
- case 0x14:
- case 0x16:
- return GalTextureTarget.ThreeD;
- case 0x18:
- case 0x1a:
- return GalTextureTarget.CubeMap;
- default:
- throw new InvalidOperationException();
- }
- }
-
- public static GalTextureTarget TldsToTextureTarget(int texType)
- {
- switch (texType)
- {
- case 0:
- case 2:
- return GalTextureTarget.OneD;
- case 4:
- case 8:
- case 0xa:
- case 0xc:
- case 0x18:
- return GalTextureTarget.TwoD;
- case 0x10:
- return GalTextureTarget.TwoDArray;
- case 0xe:
- return GalTextureTarget.ThreeD;
- default:
- throw new InvalidOperationException();
- }
- }
-
- public static void Ld_A(ShaderIrBlock block, long opCode, int position)
- {
- ShaderIrNode[] opers = opCode.Abuf20();
-
- //Used by GS
- ShaderIrOperGpr vertex = opCode.Gpr39();
-
- int index = 0;
-
- foreach (ShaderIrNode operA in opers)
- {
- ShaderIrOperGpr operD = opCode.Gpr0();
-
- operD.Index += index++;
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(operD, operA)));
- }
- }
-
- public static void Ld_C(ShaderIrBlock block, long opCode, int position)
- {
- int cbufPos = opCode.Read(22, 0x3fff);
- int cbufIndex = opCode.Read(36, 0x1f);
- int type = opCode.Read(48, 7);
-
- if (type > 5)
- {
- throw new InvalidOperationException();
- }
-
- ShaderIrOperGpr temp = ShaderIrOperGpr.MakeTemporary();
-
- block.AddNode(new ShaderIrAsg(temp, opCode.Gpr8()));
-
- int count = type == 5 ? 2 : 1;
-
- for (int index = 0; index < count; index++)
- {
- ShaderIrOperCbuf operA = new ShaderIrOperCbuf(cbufIndex, cbufPos, temp);
-
- ShaderIrOperGpr operD = opCode.Gpr0();
-
- operA.Pos += index;
- operD.Index += index;
-
- if (!operD.IsValidRegister)
- {
- break;
- }
-
- ShaderIrNode node = operA;
-
- if (type < 4)
- {
- //This is a 8 or 16 bits type.
- bool signed = (type & 1) != 0;
-
- int size = 8 << (type >> 1);
-
- node = ExtendTo32(node, signed, size);
- }
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(operD, node)));
- }
- }
-
- public static void St_A(ShaderIrBlock block, long opCode, int position)
- {
- ShaderIrNode[] opers = opCode.Abuf20();
-
- int index = 0;
-
- foreach (ShaderIrNode operA in opers)
- {
- ShaderIrOperGpr operD = opCode.Gpr0();
-
- operD.Index += index++;
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(operA, operD)));
- }
- }
-
- public static void Texq(ShaderIrBlock block, long opCode, int position)
- {
- ShaderIrNode operD = opCode.Gpr0();
- ShaderIrNode operA = opCode.Gpr8();
-
- ShaderTexqInfo info = (ShaderTexqInfo)(opCode.Read(22, 0x1f));
-
- ShaderIrMetaTexq meta0 = new ShaderIrMetaTexq(info, 0);
- ShaderIrMetaTexq meta1 = new ShaderIrMetaTexq(info, 1);
-
- ShaderIrNode operC = opCode.Imm13_36();
-
- ShaderIrOp op0 = new ShaderIrOp(ShaderIrInst.Texq, operA, null, operC, meta0);
- ShaderIrOp op1 = new ShaderIrOp(ShaderIrInst.Texq, operA, null, operC, meta1);
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(operD, op0)));
- block.AddNode(opCode.PredNode(new ShaderIrAsg(operA, op1))); //Is this right?
- }
-
- public static void Tex(ShaderIrBlock block, long opCode, int position)
- {
- TextureInstructionSuffix suffix;
-
- int rawSuffix = opCode.Read(0x34, 0x38);
-
- switch (rawSuffix)
- {
- case 0:
- suffix = TextureInstructionSuffix.None;
- break;
- case 0x8:
- suffix = TextureInstructionSuffix.Lz;
- break;
- case 0x10:
- suffix = TextureInstructionSuffix.Lb;
- break;
- case 0x18:
- suffix = TextureInstructionSuffix.Ll;
- break;
- case 0x30:
- suffix = TextureInstructionSuffix.Lba;
- break;
- case 0x38:
- suffix = TextureInstructionSuffix.Lla;
- break;
- default:
- throw new InvalidOperationException($"Invalid Suffix for TEX instruction {rawSuffix}");
- }
-
- bool isOffset = opCode.Read(0x36);
-
- if (isOffset)
- suffix |= TextureInstructionSuffix.AOffI;
-
- EmitTex(block, opCode, suffix, gprHandle: false);
- }
-
- public static void Tex_B(ShaderIrBlock block, long opCode, int position)
- {
- TextureInstructionSuffix suffix;
-
- int rawSuffix = opCode.Read(0x24, 0xe);
-
- switch (rawSuffix)
- {
- case 0:
- suffix = TextureInstructionSuffix.None;
- break;
- case 0x2:
- suffix = TextureInstructionSuffix.Lz;
- break;
- case 0x4:
- suffix = TextureInstructionSuffix.Lb;
- break;
- case 0x6:
- suffix = TextureInstructionSuffix.Ll;
- break;
- case 0xc:
- suffix = TextureInstructionSuffix.Lba;
- break;
- case 0xe:
- suffix = TextureInstructionSuffix.Lla;
- break;
- default:
- throw new InvalidOperationException($"Invalid Suffix for TEX.B instruction {rawSuffix}");
- }
-
- bool isOffset = opCode.Read(0x23);
-
- if (isOffset)
- suffix |= TextureInstructionSuffix.AOffI;
-
- EmitTex(block, opCode, suffix, gprHandle: true);
- }
-
- private static void EmitTex(ShaderIrBlock block, long opCode, TextureInstructionSuffix textureInstructionSuffix, bool gprHandle)
- {
- bool isArray = opCode.HasArray();
-
- GalTextureTarget textureTarget = TexToTextureTarget(opCode.Read(28, 6), isArray);
-
- bool hasDepthCompare = opCode.Read(0x32);
-
- if (hasDepthCompare)
- {
- textureInstructionSuffix |= TextureInstructionSuffix.Dc;
- }
-
- ShaderIrOperGpr[] coords = new ShaderIrOperGpr[ImageUtils.GetCoordsCountTextureTarget(textureTarget)];
-
- int indexExtraCoord = 0;
-
- if (isArray)
- {
- indexExtraCoord++;
-
- coords[coords.Length - 1] = opCode.Gpr8();
- }
-
-
- for (int index = 0; index < coords.Length - indexExtraCoord; index++)
- {
- ShaderIrOperGpr coordReg = opCode.Gpr8();
-
- coordReg.Index += index;
-
- coordReg.Index += indexExtraCoord;
-
- if (!coordReg.IsValidRegister)
- {
- coordReg.Index = ShaderIrOperGpr.ZrIndex;
- }
-
- coords[index] = coordReg;
- }
-
- int chMask = opCode.Read(31, 0xf);
-
- ShaderIrOperGpr levelOfDetail = null;
- ShaderIrOperGpr offset = null;
- ShaderIrOperGpr depthCompare = null;
-
- // TODO: determine first argument when TEX.B is used
- int operBIndex = gprHandle ? 1 : 0;
-
- if ((textureInstructionSuffix & TextureInstructionSuffix.Ll) != 0 ||
- (textureInstructionSuffix & TextureInstructionSuffix.Lb) != 0 ||
- (textureInstructionSuffix & TextureInstructionSuffix.Lba) != 0 ||
- (textureInstructionSuffix & TextureInstructionSuffix.Lla) != 0)
- {
- levelOfDetail = opCode.Gpr20();
- levelOfDetail.Index += operBIndex;
-
- operBIndex++;
- }
-
- if ((textureInstructionSuffix & TextureInstructionSuffix.AOffI) != 0)
- {
- offset = opCode.Gpr20();
- offset.Index += operBIndex;
-
- operBIndex++;
- }
-
- if ((textureInstructionSuffix & TextureInstructionSuffix.Dc) != 0)
- {
- depthCompare = opCode.Gpr20();
- depthCompare.Index += operBIndex;
-
- operBIndex++;
- }
-
- // ???
- ShaderIrNode operC = gprHandle
- ? (ShaderIrNode)opCode.Gpr20()
- : (ShaderIrNode)opCode.Imm13_36();
-
- ShaderIrInst inst = gprHandle ? ShaderIrInst.Texb : ShaderIrInst.Texs;
-
- coords = CoordsRegistersToTempRegisters(block, coords);
-
- int regInc = 0;
-
- for (int ch = 0; ch < 4; ch++)
- {
- if (!IsChannelUsed(chMask, ch))
- {
- continue;
- }
-
- ShaderIrOperGpr dst = opCode.Gpr0();
-
- dst.Index += regInc++;
-
- if (!dst.IsValidRegister || dst.IsConst)
- {
- continue;
- }
-
- ShaderIrMetaTex meta = new ShaderIrMetaTex(ch, textureTarget, textureInstructionSuffix, coords)
- {
- LevelOfDetail = levelOfDetail,
- Offset = offset,
- DepthCompare = depthCompare
- };
-
- ShaderIrOp op = new ShaderIrOp(inst, coords[0], coords.Length > 1 ? coords[1] : null, operC, meta);
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(dst, op)));
- }
- }
-
- public static void Texs(ShaderIrBlock block, long opCode, int position)
- {
- TextureInstructionSuffix suffix;
-
- int rawSuffix = opCode.Read(0x34, 0x1e);
-
- switch (rawSuffix)
- {
- case 0:
- case 0x4:
- case 0x10:
- case 0x16:
- suffix = TextureInstructionSuffix.Lz;
- break;
- case 0x6:
- case 0x1a:
- suffix = TextureInstructionSuffix.Ll;
- break;
- case 0x8:
- suffix = TextureInstructionSuffix.Dc;
- break;
- case 0x2:
- case 0xe:
- case 0x14:
- case 0x18:
- suffix = TextureInstructionSuffix.None;
- break;
- case 0xa:
- suffix = TextureInstructionSuffix.Ll | TextureInstructionSuffix.Dc;
- break;
- case 0xc:
- case 0x12:
- suffix = TextureInstructionSuffix.Lz | TextureInstructionSuffix.Dc;
- break;
- default:
- throw new InvalidOperationException($"Invalid Suffix for TEXS instruction {rawSuffix}");
- }
-
- GalTextureTarget textureTarget = TexsToTextureTarget(opCode.Read(52, 0x1e));
-
- EmitTexs(block, opCode, ShaderIrInst.Texs, textureTarget, suffix);
- }
-
- public static void Tlds(ShaderIrBlock block, long opCode, int position)
- {
- TextureInstructionSuffix suffix;
-
- int rawSuffix = opCode.Read(0x34, 0x1e);
-
- switch (rawSuffix)
- {
- case 0:
- case 0x4:
- case 0x8:
- suffix = TextureInstructionSuffix.Lz | TextureInstructionSuffix.AOffI;
- break;
- case 0xc:
- suffix = TextureInstructionSuffix.Lz | TextureInstructionSuffix.Mz;
- break;
- case 0xe:
- case 0x10:
- suffix = TextureInstructionSuffix.Lz;
- break;
- case 0x2:
- case 0xa:
- suffix = TextureInstructionSuffix.Ll;
- break;
- case 0x18:
- suffix = TextureInstructionSuffix.Ll | TextureInstructionSuffix.AOffI;
- break;
- default:
- throw new InvalidOperationException($"Invalid Suffix for TLDS instruction {rawSuffix}");
- }
-
- GalTextureTarget textureTarget = TldsToTextureTarget(opCode.Read(52, 0x1e));
-
- EmitTexs(block, opCode, ShaderIrInst.Txlf, textureTarget, suffix);
- }
-
- public static void Tld4(ShaderIrBlock block, long opCode, int position)
- {
- TextureInstructionSuffix suffix;
-
- int rawSuffix = opCode.Read(0x34, 0xc);
-
- switch (rawSuffix)
- {
- case 0:
- suffix = TextureInstructionSuffix.None;
- break;
- case 0x4:
- suffix = TextureInstructionSuffix.AOffI;
- break;
- case 0x8:
- suffix = TextureInstructionSuffix.Ptp;
- break;
- default:
- throw new InvalidOperationException($"Invalid Suffix for TLD4 instruction {rawSuffix}");
- }
-
- bool isShadow = opCode.Read(0x32);
-
- bool isArray = opCode.HasArray();
- int chMask = opCode.Read(31, 0xf);
-
- GalTextureTarget textureTarget = TexToTextureTarget(opCode.Read(28, 6), isArray);
-
- if (isShadow)
- {
- suffix |= TextureInstructionSuffix.Dc;
- }
-
- EmitTld4(block, opCode, textureTarget, suffix, chMask, opCode.Read(0x38, 0x3), false);
- }
-
- public static void Tld4S(ShaderIrBlock block, long opCode, int position)
- {
- TextureInstructionSuffix suffix = TextureInstructionSuffix.None;
-
- bool isOffset = opCode.Read(0x33);
- bool isShadow = opCode.Read(0x32);
-
- if (isOffset)
- {
- suffix |= TextureInstructionSuffix.AOffI;
- }
-
- if (isShadow)
- {
- suffix |= TextureInstructionSuffix.Dc;
- }
-
- // TLD4S seems to only support 2D textures with RGBA mask?
- EmitTld4(block, opCode, GalTextureTarget.TwoD, suffix, RGBA, opCode.Read(0x34, 0x3), true);
- }
-
- private static void EmitTexs(ShaderIrBlock block,
- long opCode,
- ShaderIrInst inst,
- GalTextureTarget textureTarget,
- TextureInstructionSuffix textureInstructionSuffix)
- {
- if (inst == ShaderIrInst.Txlf && textureTarget == GalTextureTarget.CubeArray)
- {
- throw new InvalidOperationException("TLDS instructions cannot use CUBE modifier!");
- }
-
- bool isArray = ImageUtils.IsArray(textureTarget);
-
- ShaderIrOperGpr[] coords = new ShaderIrOperGpr[ImageUtils.GetCoordsCountTextureTarget(textureTarget)];
-
- ShaderIrOperGpr operA = opCode.Gpr8();
- ShaderIrOperGpr operB = opCode.Gpr20();
-
- ShaderIrOperGpr suffixExtra = opCode.Gpr20();
- suffixExtra.Index += 1;
-
- int coordStartIndex = 0;
-
- if (isArray)
- {
- coordStartIndex++;
- coords[coords.Length - 1] = opCode.Gpr8();
- }
-
- switch (coords.Length - coordStartIndex)
- {
- case 1:
- coords[0] = opCode.Gpr8();
-
- break;
- case 2:
- coords[0] = opCode.Gpr8();
- coords[0].Index += coordStartIndex;
-
- break;
- case 3:
- coords[0] = opCode.Gpr8();
- coords[0].Index += coordStartIndex;
-
- coords[1] = opCode.Gpr8();
- coords[1].Index += 1 + coordStartIndex;
-
- break;
- default:
- throw new NotSupportedException($"{coords.Length - coordStartIndex} coords textures aren't supported in TEXS");
- }
-
- int operBIndex = 0;
-
- ShaderIrOperGpr levelOfDetail = null;
- ShaderIrOperGpr offset = null;
- ShaderIrOperGpr depthCompare = null;
-
- // OperB is always the last value
- // Not applicable to 1d textures
- if (coords.Length - coordStartIndex != 1)
- {
- coords[coords.Length - coordStartIndex - 1] = operB;
- operBIndex++;
- }
-
- // Encoding of TEXS/TLDS is a bit special and change for 2d textures
- // NOTE: OperA seems to hold at best two args.
- // On 2D textures, if no suffix need an additional values, Y is stored in OperB, otherwise coords are in OperA and the additional values is in OperB.
- if (textureInstructionSuffix != TextureInstructionSuffix.None && textureInstructionSuffix != TextureInstructionSuffix.Lz && textureTarget == GalTextureTarget.TwoD)
- {
- coords[coords.Length - coordStartIndex - 1] = opCode.Gpr8();
- coords[coords.Length - coordStartIndex - 1].Index += coords.Length - coordStartIndex - 1;
- operBIndex--;
- }
-
- // TODO: Find what MZ does and what changes about the encoding (Maybe Multisample?)
- if ((textureInstructionSuffix & TextureInstructionSuffix.Ll) != 0)
- {
- levelOfDetail = opCode.Gpr20();
- levelOfDetail.Index += operBIndex;
- operBIndex++;
- }
-
- if ((textureInstructionSuffix & TextureInstructionSuffix.AOffI) != 0)
- {
- offset = opCode.Gpr20();
- offset.Index += operBIndex;
- operBIndex++;
- }
-
- if ((textureInstructionSuffix & TextureInstructionSuffix.Dc) != 0)
- {
- depthCompare = opCode.Gpr20();
- depthCompare.Index += operBIndex;
- operBIndex++;
- }
-
- int lutIndex;
-
- lutIndex = !opCode.Gpr0().IsConst ? 1 : 0;
- lutIndex |= !opCode.Gpr28().IsConst ? 2 : 0;
-
- if (lutIndex == 0)
- {
- //Both destination registers are RZ, do nothing.
- return;
- }
-
- bool fp16 = !opCode.Read(59);
-
- int dstIncrement = 0;
-
- ShaderIrOperGpr GetDst()
- {
- ShaderIrOperGpr dst;
-
- if (fp16)
- {
- //FP16 mode, two components are packed on the two
- //halfs of a 32-bits register, as two half-float values.
- int halfPart = dstIncrement & 1;
-
- switch (lutIndex)
- {
- case 1: dst = opCode.GprHalf0(halfPart); break;
- case 2: dst = opCode.GprHalf28(halfPart); break;
- case 3: dst = (dstIncrement >> 1) != 0
- ? opCode.GprHalf28(halfPart)
- : opCode.GprHalf0(halfPart); break;
-
- default: throw new InvalidOperationException();
- }
- }
- else
- {
- //32-bits mode, each component uses one register.
- //Two components uses two consecutive registers.
- switch (lutIndex)
- {
- case 1: dst = opCode.Gpr0(); break;
- case 2: dst = opCode.Gpr28(); break;
- case 3: dst = (dstIncrement >> 1) != 0
- ? opCode.Gpr28()
- : opCode.Gpr0(); break;
-
- default: throw new InvalidOperationException();
- }
-
- dst.Index += dstIncrement & 1;
- }
-
- dstIncrement++;
-
- return dst;
- }
-
- int chMask = _maskLut[lutIndex, opCode.Read(50, 7)];
-
- if (chMask == 0)
- {
- //All channels are disabled, do nothing.
- return;
- }
-
- ShaderIrNode operC = opCode.Imm13_36();
- coords = CoordsRegistersToTempRegisters(block, coords);
-
- for (int ch = 0; ch < 4; ch++)
- {
- if (!IsChannelUsed(chMask, ch))
- {
- continue;
- }
-
- ShaderIrMetaTex meta = new ShaderIrMetaTex(ch, textureTarget, textureInstructionSuffix, coords)
- {
- LevelOfDetail = levelOfDetail,
- Offset = offset,
- DepthCompare = depthCompare
- };
- ShaderIrOp op = new ShaderIrOp(inst, operA, operB, operC, meta);
-
- ShaderIrOperGpr dst = GetDst();
-
- if (dst.IsValidRegister && !dst.IsConst)
- {
- block.AddNode(opCode.PredNode(new ShaderIrAsg(dst, op)));
- }
- }
- }
-
- private static void EmitTld4(ShaderIrBlock block, long opCode, GalTextureTarget textureType, TextureInstructionSuffix textureInstructionSuffix, int chMask, int component, bool scalar)
- {
- ShaderIrOperGpr operA = opCode.Gpr8();
- ShaderIrOperGpr operB = opCode.Gpr20();
- ShaderIrOperImm operC = opCode.Imm13_36();
-
- ShaderIrOperGpr[] coords = new ShaderIrOperGpr[ImageUtils.GetCoordsCountTextureTarget(textureType)];
-
- ShaderIrOperGpr offset = null;
- ShaderIrOperGpr depthCompare = null;
-
- bool isArray = ImageUtils.IsArray(textureType);
-
- int operBIndex = 0;
-
- if (scalar)
- {
- int coordStartIndex = 0;
-
- if (isArray)
- {
- coordStartIndex++;
- coords[coords.Length - 1] = operB;
- }
-
- switch (coords.Length - coordStartIndex)
- {
- case 1:
- coords[0] = opCode.Gpr8();
-
- break;
- case 2:
- coords[0] = opCode.Gpr8();
- coords[0].Index += coordStartIndex;
-
- break;
- case 3:
- coords[0] = opCode.Gpr8();
- coords[0].Index += coordStartIndex;
-
- coords[1] = opCode.Gpr8();
- coords[1].Index += 1 + coordStartIndex;
-
- break;
- default:
- throw new NotSupportedException($"{coords.Length - coordStartIndex} coords textures aren't supported in TLD4S");
- }
-
- if (coords.Length - coordStartIndex != 1)
- {
- coords[coords.Length - coordStartIndex - 1] = operB;
- operBIndex++;
- }
-
- if (textureInstructionSuffix != TextureInstructionSuffix.None && textureType == GalTextureTarget.TwoD)
- {
- coords[coords.Length - coordStartIndex - 1] = opCode.Gpr8();
- coords[coords.Length - coordStartIndex - 1].Index += coords.Length - coordStartIndex - 1;
- operBIndex--;
- }
- }
- else
- {
- int indexExtraCoord = 0;
-
- if (isArray)
- {
- indexExtraCoord++;
-
- coords[coords.Length - 1] = opCode.Gpr8();
- }
-
- for (int index = 0; index < coords.Length - indexExtraCoord; index++)
- {
- coords[index] = opCode.Gpr8();
-
- coords[index].Index += index;
-
- coords[index].Index += indexExtraCoord;
-
- if (coords[index].Index > ShaderIrOperGpr.ZrIndex)
- {
- coords[index].Index = ShaderIrOperGpr.ZrIndex;
- }
- }
- }
-
- if ((textureInstructionSuffix & TextureInstructionSuffix.AOffI) != 0)
- {
- offset = opCode.Gpr20();
- offset.Index += operBIndex;
- operBIndex++;
- }
-
- if ((textureInstructionSuffix & TextureInstructionSuffix.Dc) != 0)
- {
- depthCompare = opCode.Gpr20();
- depthCompare.Index += operBIndex;
- operBIndex++;
- }
-
- coords = CoordsRegistersToTempRegisters(block, coords);
-
- int regInc = 0;
-
- for (int ch = 0; ch < 4; ch++)
- {
- if (!IsChannelUsed(chMask, ch))
- {
- continue;
- }
-
- ShaderIrOperGpr dst = opCode.Gpr0();
-
- dst.Index += regInc++;
-
- if (!dst.IsValidRegister || dst.IsConst)
- {
- continue;
- }
-
- ShaderIrMetaTex meta = new ShaderIrMetaTex(ch, textureType, textureInstructionSuffix, coords)
- {
- Component = component,
- Offset = offset,
- DepthCompare = depthCompare
- };
-
- ShaderIrOp op = new ShaderIrOp(ShaderIrInst.Tld4, operA, operB, operC, meta);
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(dst, op)));
- }
- }
-
- private static bool IsChannelUsed(int chMask, int ch)
- {
- return (chMask & (1 << ch)) != 0;
- }
-
- private static ShaderIrOperGpr[] CoordsRegistersToTempRegisters(ShaderIrBlock block, params ShaderIrOperGpr[] registers)
- {
- ShaderIrOperGpr[] res = new ShaderIrOperGpr[registers.Length];
-
- for (int index = 0; index < res.Length; index++)
- {
- res[index] = ShaderIrOperGpr.MakeTemporary(index);
- block.AddNode(new ShaderIrAsg(res[index], registers[index]));
- }
-
- return res;
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeMove.cs b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeMove.cs
deleted file mode 100644
index 0a2b4232..00000000
--- a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeMove.cs
+++ /dev/null
@@ -1,431 +0,0 @@
-using System;
-
-using static Ryujinx.Graphics.Gal.Shader.ShaderDecodeHelper;
-
-namespace Ryujinx.Graphics.Gal.Shader
-{
- static partial class ShaderDecode
- {
- private enum IntType
- {
- U8 = 0,
- U16 = 1,
- U32 = 2,
- U64 = 3,
- S8 = 4,
- S16 = 5,
- S32 = 6,
- S64 = 7
- }
-
- private enum FloatType
- {
- F16 = 1,
- F32 = 2,
- F64 = 3
- }
-
- public static void F2f_C(ShaderIrBlock block, long opCode, int position)
- {
- EmitF2F(block, opCode, ShaderOper.Cr);
- }
-
- public static void F2f_I(ShaderIrBlock block, long opCode, int position)
- {
- EmitF2F(block, opCode, ShaderOper.Immf);
- }
-
- public static void F2f_R(ShaderIrBlock block, long opCode, int position)
- {
- EmitF2F(block, opCode, ShaderOper.Rr);
- }
-
- public static void F2i_C(ShaderIrBlock block, long opCode, int position)
- {
- EmitF2I(block, opCode, ShaderOper.Cr);
- }
-
- public static void F2i_I(ShaderIrBlock block, long opCode, int position)
- {
- EmitF2I(block, opCode, ShaderOper.Immf);
- }
-
- public static void F2i_R(ShaderIrBlock block, long opCode, int position)
- {
- EmitF2I(block, opCode, ShaderOper.Rr);
- }
-
- public static void I2f_C(ShaderIrBlock block, long opCode, int position)
- {
- EmitI2F(block, opCode, ShaderOper.Cr);
- }
-
- public static void I2f_I(ShaderIrBlock block, long opCode, int position)
- {
- EmitI2F(block, opCode, ShaderOper.Imm);
- }
-
- public static void I2f_R(ShaderIrBlock block, long opCode, int position)
- {
- EmitI2F(block, opCode, ShaderOper.Rr);
- }
-
- public static void I2i_C(ShaderIrBlock block, long opCode, int position)
- {
- EmitI2I(block, opCode, ShaderOper.Cr);
- }
-
- public static void I2i_I(ShaderIrBlock block, long opCode, int position)
- {
- EmitI2I(block, opCode, ShaderOper.Imm);
- }
-
- public static void I2i_R(ShaderIrBlock block, long opCode, int position)
- {
- EmitI2I(block, opCode, ShaderOper.Rr);
- }
-
- public static void Isberd(ShaderIrBlock block, long opCode, int position)
- {
- //This instruction seems to be used to translate from an address to a vertex index in a GS
- //Stub it as such
-
- block.AddNode(new ShaderIrCmnt("Stubbed."));
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(opCode.Gpr0(), opCode.Gpr8())));
- }
-
- public static void Mov_C(ShaderIrBlock block, long opCode, int position)
- {
- ShaderIrOperCbuf cbuf = opCode.Cbuf34();
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(opCode.Gpr0(), cbuf)));
- }
-
- public static void Mov_I(ShaderIrBlock block, long opCode, int position)
- {
- ShaderIrOperImm imm = opCode.Imm19_20();
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(opCode.Gpr0(), imm)));
- }
-
- public static void Mov_I32(ShaderIrBlock block, long opCode, int position)
- {
- ShaderIrOperImm imm = opCode.Imm32_20();
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(opCode.Gpr0(), imm)));
- }
-
- public static void Mov_R(ShaderIrBlock block, long opCode, int position)
- {
- ShaderIrOperGpr gpr = opCode.Gpr20();
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(opCode.Gpr0(), gpr)));
- }
-
- public static void Sel_C(ShaderIrBlock block, long opCode, int position)
- {
- EmitSel(block, opCode, ShaderOper.Cr);
- }
-
- public static void Sel_I(ShaderIrBlock block, long opCode, int position)
- {
- EmitSel(block, opCode, ShaderOper.Imm);
- }
-
- public static void Sel_R(ShaderIrBlock block, long opCode, int position)
- {
- EmitSel(block, opCode, ShaderOper.Rr);
- }
-
- public static void Mov_S(ShaderIrBlock block, long opCode, int position)
- {
- block.AddNode(new ShaderIrCmnt("Stubbed."));
-
- //Zero is used as a special number to get a valid "0 * 0 + VertexIndex" in a GS
- ShaderIrNode source = new ShaderIrOperImm(0);
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(opCode.Gpr0(), source)));
- }
-
- private static void EmitF2F(ShaderIrBlock block, long opCode, ShaderOper oper)
- {
- bool negA = opCode.Read(45);
- bool absA = opCode.Read(49);
-
- ShaderIrNode operA;
-
- switch (oper)
- {
- case ShaderOper.Cr: operA = opCode.Cbuf34(); break;
- case ShaderOper.Immf: operA = opCode.Immf19_20(); break;
- case ShaderOper.Rr: operA = opCode.Gpr20(); break;
-
- default: throw new ArgumentException(nameof(oper));
- }
-
- operA = GetAluFabsFneg(operA, absA, negA);
-
- ShaderIrInst roundInst = GetRoundInst(opCode);
-
- if (roundInst != ShaderIrInst.Invalid)
- {
- operA = new ShaderIrOp(roundInst, operA);
- }
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(opCode.Gpr0(), operA)));
- }
-
- private static void EmitF2I(ShaderIrBlock block, long opCode, ShaderOper oper)
- {
- IntType type = GetIntType(opCode);
-
- if (type == IntType.U64 ||
- type == IntType.S64)
- {
- //TODO: 64-bits support.
- //Note: GLSL doesn't support 64-bits integers.
- throw new NotImplementedException();
- }
-
- bool negA = opCode.Read(45);
- bool absA = opCode.Read(49);
-
- ShaderIrNode operA;
-
- switch (oper)
- {
- case ShaderOper.Cr: operA = opCode.Cbuf34(); break;
- case ShaderOper.Immf: operA = opCode.Immf19_20(); break;
- case ShaderOper.Rr: operA = opCode.Gpr20(); break;
-
- default: throw new ArgumentException(nameof(oper));
- }
-
- operA = GetAluFabsFneg(operA, absA, negA);
-
- ShaderIrInst roundInst = GetRoundInst(opCode);
-
- if (roundInst != ShaderIrInst.Invalid)
- {
- operA = new ShaderIrOp(roundInst, operA);
- }
-
- bool signed = type >= IntType.S8;
-
- int size = 8 << ((int)type & 3);
-
- if (size < 32)
- {
- uint mask = uint.MaxValue >> (32 - size);
-
- float cMin = 0;
- float cMax = mask;
-
- if (signed)
- {
- uint halfMask = mask >> 1;
-
- cMin -= halfMask + 1;
- cMax = halfMask;
- }
-
- ShaderIrOperImmf min = new ShaderIrOperImmf(cMin);
- ShaderIrOperImmf max = new ShaderIrOperImmf(cMax);
-
- operA = new ShaderIrOp(ShaderIrInst.Fclamp, operA, min, max);
- }
-
- ShaderIrInst inst = signed
- ? ShaderIrInst.Ftos
- : ShaderIrInst.Ftou;
-
- ShaderIrNode op = new ShaderIrOp(inst, operA);
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(opCode.Gpr0(), op)));
- }
-
- private static void EmitI2F(ShaderIrBlock block, long opCode, ShaderOper oper)
- {
- IntType type = GetIntType(opCode);
-
- if (type == IntType.U64 ||
- type == IntType.S64)
- {
- //TODO: 64-bits support.
- //Note: GLSL doesn't support 64-bits integers.
- throw new NotImplementedException();
- }
-
- int sel = opCode.Read(41, 3);
-
- bool negA = opCode.Read(45);
- bool absA = opCode.Read(49);
-
- ShaderIrNode operA;
-
- switch (oper)
- {
- case ShaderOper.Cr: operA = opCode.Cbuf34(); break;
- case ShaderOper.Imm: operA = opCode.Imm19_20(); break;
- case ShaderOper.Rr: operA = opCode.Gpr20(); break;
-
- default: throw new ArgumentException(nameof(oper));
- }
-
- operA = GetAluIabsIneg(operA, absA, negA);
-
- bool signed = type >= IntType.S8;
-
- int shift = sel * 8;
-
- int size = 8 << ((int)type & 3);
-
- if (shift != 0)
- {
- operA = new ShaderIrOp(ShaderIrInst.Asr, operA, new ShaderIrOperImm(shift));
- }
-
- if (size < 32)
- {
- operA = ExtendTo32(operA, signed, size);
- }
-
- ShaderIrInst inst = signed
- ? ShaderIrInst.Stof
- : ShaderIrInst.Utof;
-
- ShaderIrNode op = new ShaderIrOp(inst, operA);
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(opCode.Gpr0(), op)));
- }
-
- private static void EmitI2I(ShaderIrBlock block, long opCode, ShaderOper oper)
- {
- IntType type = GetIntType(opCode);
-
- if (type == IntType.U64 ||
- type == IntType.S64)
- {
- //TODO: 64-bits support.
- //Note: GLSL doesn't support 64-bits integers.
- throw new NotImplementedException();
- }
-
- int sel = opCode.Read(41, 3);
-
- bool negA = opCode.Read(45);
- bool absA = opCode.Read(49);
- bool satA = opCode.Read(50);
-
- ShaderIrNode operA;
-
- switch (oper)
- {
- case ShaderOper.Cr: operA = opCode.Cbuf34(); break;
- case ShaderOper.Immf: operA = opCode.Immf19_20(); break;
- case ShaderOper.Rr: operA = opCode.Gpr20(); break;
-
- default: throw new ArgumentException(nameof(oper));
- }
-
- operA = GetAluIabsIneg(operA, absA, negA);
-
- bool signed = type >= IntType.S8;
-
- int shift = sel * 8;
-
- int size = 8 << ((int)type & 3);
-
- if (shift != 0)
- {
- operA = new ShaderIrOp(ShaderIrInst.Asr, operA, new ShaderIrOperImm(shift));
- }
-
- if (size < 32)
- {
- uint mask = uint.MaxValue >> (32 - size);
-
- if (satA)
- {
- uint cMin = 0;
- uint cMax = mask;
-
- if (signed)
- {
- uint halfMask = mask >> 1;
-
- cMin -= halfMask + 1;
- cMax = halfMask;
- }
-
- ShaderIrOperImm min = new ShaderIrOperImm((int)cMin);
- ShaderIrOperImm max = new ShaderIrOperImm((int)cMax);
-
- operA = new ShaderIrOp(signed
- ? ShaderIrInst.Clamps
- : ShaderIrInst.Clampu, operA, min, max);
- }
- else
- {
- operA = ExtendTo32(operA, signed, size);
- }
- }
-
- block.AddNode(opCode.PredNode(new ShaderIrAsg(opCode.Gpr0(), operA)));
- }
-
- private static void EmitSel(ShaderIrBlock block, long opCode, ShaderOper oper)
- {
- ShaderIrOperGpr dst = opCode.Gpr0();
- ShaderIrNode pred = opCode.Pred39N();
-
- ShaderIrNode resultA = opCode.Gpr8();
- ShaderIrNode resultB;
-
- switch (oper)
- {
- case ShaderOper.Cr: resultB = opCode.Cbuf34(); break;
- case ShaderOper.Imm: resultB = opCode.Imm19_20(); break;
- case ShaderOper.Rr: resultB = opCode.Gpr20(); break;
-
- default: throw new ArgumentException(nameof(oper));
- }
-
- block.AddNode(opCode.PredNode(new ShaderIrCond(pred, new ShaderIrAsg(dst, resultA), false)));
-
- block.AddNode(opCode.PredNode(new ShaderIrCond(pred, new ShaderIrAsg(dst, resultB), true)));
- }
-
- private static IntType GetIntType(long opCode)
- {
- bool signed = opCode.Read(13);
-
- IntType type = (IntType)(opCode.Read(10, 3));
-
- if (signed)
- {
- type += (int)IntType.S8;
- }
-
- return type;
- }
-
- private static FloatType GetFloatType(long opCode)
- {
- return (FloatType)(opCode.Read(8, 3));
- }
-
- private static ShaderIrInst GetRoundInst(long opCode)
- {
- switch (opCode.Read(39, 3))
- {
- case 1: return ShaderIrInst.Floor;
- case 2: return ShaderIrInst.Ceil;
- case 3: return ShaderIrInst.Trunc;
- }
-
- return ShaderIrInst.Invalid;
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeOpCode.cs b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeOpCode.cs
deleted file mode 100644
index 4b1e4046..00000000
--- a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeOpCode.cs
+++ /dev/null
@@ -1,313 +0,0 @@
-using System;
-
-namespace Ryujinx.Graphics.Gal.Shader
-{
- static partial class ShaderDecode
- {
- private static int Read(this long opCode, int position, int mask)
- {
- return (int)(opCode >> position) & mask;
- }
-
- private static bool Read(this long opCode, int position)
- {
- return ((opCode >> position) & 1) != 0;
- }
-
- private static int Branch(this long opCode)
- {
- return ((int)(opCode >> 20) << 8) >> 8;
- }
-
- private static bool HasArray(this long opCode)
- {
- return opCode.Read(0x1c);
- }
-
- private static ShaderIrOperAbuf[] Abuf20(this long opCode)
- {
- int abuf = opCode.Read(20, 0x3ff);
- int size = opCode.Read(47, 3);
-
- ShaderIrOperGpr vertex = opCode.Gpr39();
-
- ShaderIrOperAbuf[] opers = new ShaderIrOperAbuf[size + 1];
-
- for (int index = 0; index <= size; index++)
- {
- opers[index] = new ShaderIrOperAbuf(abuf + index * 4, vertex);
- }
-
- return opers;
- }
-
- private static ShaderIrOperAbuf Abuf28(this long opCode)
- {
- int abuf = opCode.Read(28, 0x3ff);
-
- return new ShaderIrOperAbuf(abuf, opCode.Gpr39());
- }
-
- private static ShaderIrOperCbuf Cbuf34(this long opCode)
- {
- return new ShaderIrOperCbuf(
- opCode.Read(34, 0x1f),
- opCode.Read(20, 0x3fff));
- }
-
- private static ShaderIrOperGpr Gpr8(this long opCode)
- {
- return new ShaderIrOperGpr(opCode.Read(8, 0xff));
- }
-
- private static ShaderIrOperGpr Gpr20(this long opCode)
- {
- return new ShaderIrOperGpr(opCode.Read(20, 0xff));
- }
-
- private static ShaderIrOperGpr Gpr39(this long opCode)
- {
- return new ShaderIrOperGpr(opCode.Read(39, 0xff));
- }
-
- private static ShaderIrOperGpr Gpr0(this long opCode)
- {
- return new ShaderIrOperGpr(opCode.Read(0, 0xff));
- }
-
- private static ShaderIrOperGpr Gpr28(this long opCode)
- {
- return new ShaderIrOperGpr(opCode.Read(28, 0xff));
- }
-
- private static ShaderIrOperGpr[] GprHalfVec8(this long opCode)
- {
- return GetGprHalfVec2(opCode.Read(8, 0xff), opCode.Read(47, 3));
- }
-
- private static ShaderIrOperGpr[] GprHalfVec20(this long opCode)
- {
- return GetGprHalfVec2(opCode.Read(20, 0xff), opCode.Read(28, 3));
- }
-
- private static ShaderIrOperGpr[] GetGprHalfVec2(int gpr, int mask)
- {
- if (mask == 1)
- {
- //This value is used for FP32, the whole 32-bits register
- //is used as each element on the vector.
- return new ShaderIrOperGpr[]
- {
- new ShaderIrOperGpr(gpr),
- new ShaderIrOperGpr(gpr)
- };
- }
-
- ShaderIrOperGpr low = new ShaderIrOperGpr(gpr, 0);
- ShaderIrOperGpr high = new ShaderIrOperGpr(gpr, 1);
-
- return new ShaderIrOperGpr[]
- {
- (mask & 1) != 0 ? high : low,
- (mask & 2) != 0 ? high : low
- };
- }
-
- private static ShaderIrOperGpr GprHalf0(this long opCode, int halfPart)
- {
- return new ShaderIrOperGpr(opCode.Read(0, 0xff), halfPart);
- }
-
- private static ShaderIrOperGpr GprHalf28(this long opCode, int halfPart)
- {
- return new ShaderIrOperGpr(opCode.Read(28, 0xff), halfPart);
- }
-
- private static ShaderIrOperImm Imm5_39(this long opCode)
- {
- return new ShaderIrOperImm(opCode.Read(39, 0x1f));
- }
-
- private static ShaderIrOperImm Imm13_36(this long opCode)
- {
- return new ShaderIrOperImm(opCode.Read(36, 0x1fff));
- }
-
- private static ShaderIrOperImm Imm32_20(this long opCode)
- {
- return new ShaderIrOperImm((int)(opCode >> 20));
- }
-
- private static ShaderIrOperImmf Immf32_20(this long opCode)
- {
- return new ShaderIrOperImmf(BitConverter.Int32BitsToSingle((int)(opCode >> 20)));
- }
-
- private static ShaderIrOperImm ImmU16_20(this long opCode)
- {
- return new ShaderIrOperImm(opCode.Read(20, 0xffff));
- }
-
- private static ShaderIrOperImm Imm19_20(this long opCode)
- {
- int value = opCode.Read(20, 0x7ffff);
-
- bool neg = opCode.Read(56);
-
- if (neg)
- {
- value = -value;
- }
-
- return new ShaderIrOperImm(value);
- }
-
- private static ShaderIrOperImmf Immf19_20(this long opCode)
- {
- uint imm = (uint)(opCode >> 20) & 0x7ffff;
-
- bool neg = opCode.Read(56);
-
- imm <<= 12;
-
- if (neg)
- {
- imm |= 0x80000000;
- }
-
- float value = BitConverter.Int32BitsToSingle((int)imm);
-
- return new ShaderIrOperImmf(value);
- }
-
- private static ShaderIrOperPred Pred0(this long opCode)
- {
- return new ShaderIrOperPred(opCode.Read(0, 7));
- }
-
- private static ShaderIrOperPred Pred3(this long opCode)
- {
- return new ShaderIrOperPred(opCode.Read(3, 7));
- }
-
- private static ShaderIrOperPred Pred12(this long opCode)
- {
- return new ShaderIrOperPred(opCode.Read(12, 7));
- }
-
- private static ShaderIrOperPred Pred29(this long opCode)
- {
- return new ShaderIrOperPred(opCode.Read(29, 7));
- }
-
- private static ShaderIrNode Pred39N(this long opCode)
- {
- ShaderIrNode node = opCode.Pred39();
-
- if (opCode.Read(42))
- {
- node = new ShaderIrOp(ShaderIrInst.Bnot, node);
- }
-
- return node;
- }
-
- private static ShaderIrOperPred Pred39(this long opCode)
- {
- return new ShaderIrOperPred(opCode.Read(39, 7));
- }
-
- private static ShaderIrOperPred Pred48(this long opCode)
- {
- return new ShaderIrOperPred(opCode.Read(48, 7));
- }
-
- private static ShaderIrInst Cmp(this long opCode)
- {
- switch (opCode.Read(49, 7))
- {
- case 1: return ShaderIrInst.Clt;
- case 2: return ShaderIrInst.Ceq;
- case 3: return ShaderIrInst.Cle;
- case 4: return ShaderIrInst.Cgt;
- case 5: return ShaderIrInst.Cne;
- case 6: return ShaderIrInst.Cge;
- }
-
- throw new ArgumentException(nameof(opCode));
- }
-
- private static ShaderIrInst CmpF(this long opCode)
- {
- switch (opCode.Read(48, 0xf))
- {
- case 0x1: return ShaderIrInst.Fclt;
- case 0x2: return ShaderIrInst.Fceq;
- case 0x3: return ShaderIrInst.Fcle;
- case 0x4: return ShaderIrInst.Fcgt;
- case 0x5: return ShaderIrInst.Fcne;
- case 0x6: return ShaderIrInst.Fcge;
- case 0x7: return ShaderIrInst.Fcnum;
- case 0x8: return ShaderIrInst.Fcnan;
- case 0x9: return ShaderIrInst.Fcltu;
- case 0xa: return ShaderIrInst.Fcequ;
- case 0xb: return ShaderIrInst.Fcleu;
- case 0xc: return ShaderIrInst.Fcgtu;
- case 0xd: return ShaderIrInst.Fcneu;
- case 0xe: return ShaderIrInst.Fcgeu;
- }
-
- throw new ArgumentException(nameof(opCode));
- }
-
- private static ShaderIrInst BLop45(this long opCode)
- {
- switch (opCode.Read(45, 3))
- {
- case 0: return ShaderIrInst.Band;
- case 1: return ShaderIrInst.Bor;
- case 2: return ShaderIrInst.Bxor;
- }
-
- throw new ArgumentException(nameof(opCode));
- }
-
- private static ShaderIrInst BLop24(this long opCode)
- {
- switch (opCode.Read(24, 3))
- {
- case 0: return ShaderIrInst.Band;
- case 1: return ShaderIrInst.Bor;
- case 2: return ShaderIrInst.Bxor;
- }
-
- throw new ArgumentException(nameof(opCode));
- }
-
- private static ShaderIrNode PredNode(this long opCode, ShaderIrNode node)
- {
- ShaderIrOperPred pred = opCode.PredNode();
-
- if (pred.Index != ShaderIrOperPred.UnusedIndex)
- {
- bool inv = opCode.Read(19);
-
- node = new ShaderIrCond(pred, node, inv);
- }
-
- return node;
- }
-
- private static ShaderIrOperPred PredNode(this long opCode)
- {
- int pred = opCode.Read(16, 0xf);
-
- if (pred != 0xf)
- {
- pred &= 7;
- }
-
- return new ShaderIrOperPred(pred);
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeSpecial.cs b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeSpecial.cs
deleted file mode 100644
index 9098ca5e..00000000
--- a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeSpecial.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-namespace Ryujinx.Graphics.Gal.Shader
-{
- static partial class ShaderDecode
- {
- public static void Out_R(ShaderIrBlock block, long opCode, int position)
- {
- //TODO: Those registers have to be used for something
- ShaderIrOperGpr gpr0 = opCode.Gpr0();
- ShaderIrOperGpr gpr8 = opCode.Gpr8();
- ShaderIrOperGpr gpr20 = opCode.Gpr20();
-
- int type = opCode.Read(39, 3);
-
- if ((type & 1) != 0)
- {
- block.AddNode(opCode.PredNode(new ShaderIrOp(ShaderIrInst.Emit)));
- }
-
- if ((type & 2) != 0)
- {
- block.AddNode(opCode.PredNode(new ShaderIrOp(ShaderIrInst.Cut)));
- }
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderDecoder.cs b/Ryujinx.Graphics/Gal/Shader/ShaderDecoder.cs
deleted file mode 100644
index 4b23f8d0..00000000
--- a/Ryujinx.Graphics/Gal/Shader/ShaderDecoder.cs
+++ /dev/null
@@ -1,218 +0,0 @@
-using System.Collections.Generic;
-
-namespace Ryujinx.Graphics.Gal.Shader
-{
- static class ShaderDecoder
- {
- private const long HeaderSize = 0x50;
-
- private const bool AddDbgComments = true;
-
- public static ShaderIrBlock[] Decode(IGalMemory memory, long start)
- {
- Dictionary<int, ShaderIrBlock> visited = new Dictionary<int, ShaderIrBlock>();
- Dictionary<int, ShaderIrBlock> visitedEnd = new Dictionary<int, ShaderIrBlock>();
-
- Queue<ShaderIrBlock> blocks = new Queue<ShaderIrBlock>();
-
- long beginning = start + HeaderSize;
-
- ShaderIrBlock Enqueue(int position, ShaderIrBlock source = null)
- {
- if (!visited.TryGetValue(position, out ShaderIrBlock output))
- {
- output = new ShaderIrBlock(position);
-
- blocks.Enqueue(output);
-
- visited.Add(position, output);
- }
-
- if (source != null)
- {
- output.Sources.Add(source);
- }
-
- return output;
- }
-
- ShaderIrBlock entry = Enqueue(0);
-
- while (blocks.Count > 0)
- {
- ShaderIrBlock current = blocks.Dequeue();
-
- FillBlock(memory, current, beginning);
-
- //Set child blocks. "Branch" is the block the branch instruction
- //points to (when taken), "Next" is the block at the next address,
- //executed when the branch is not taken. For Unconditional Branches
- //or end of shader, Next is null.
- if (current.Nodes.Count > 0)
- {
- ShaderIrNode lastNode = current.GetLastNode();
-
- ShaderIrOp innerOp = GetInnermostOp(lastNode);
-
- if (innerOp?.Inst == ShaderIrInst.Bra)
- {
- int target = ((ShaderIrOperImm)innerOp.OperandA).Value;
-
- current.Branch = Enqueue(target, current);
- }
-
- foreach (ShaderIrNode node in current.Nodes)
- {
- innerOp = GetInnermostOp(node);
-
- if (innerOp is ShaderIrOp currOp && currOp.Inst == ShaderIrInst.Ssy)
- {
- int target = ((ShaderIrOperImm)currOp.OperandA).Value;
-
- Enqueue(target, current);
- }
- }
-
- if (NodeHasNext(lastNode))
- {
- current.Next = Enqueue(current.EndPosition);
- }
- }
-
- //If we have on the graph two blocks with the same end position,
- //then we need to split the bigger block and have two small blocks,
- //the end position of the bigger "Current" block should then be == to
- //the position of the "Smaller" block.
- while (visitedEnd.TryGetValue(current.EndPosition, out ShaderIrBlock smaller))
- {
- if (current.Position > smaller.Position)
- {
- ShaderIrBlock temp = smaller;
-
- smaller = current;
- current = temp;
- }
-
- current.EndPosition = smaller.Position;
- current.Next = smaller;
- current.Branch = null;
-
- current.Nodes.RemoveRange(
- current.Nodes.Count - smaller.Nodes.Count,
- smaller.Nodes.Count);
-
- visitedEnd[smaller.EndPosition] = smaller;
- }
-
- visitedEnd.Add(current.EndPosition, current);
- }
-
- //Make and sort Graph blocks array by position.
- ShaderIrBlock[] graph = new ShaderIrBlock[visited.Count];
-
- while (visited.Count > 0)
- {
- uint firstPos = uint.MaxValue;
-
- foreach (ShaderIrBlock block in visited.Values)
- {
- if (firstPos > (uint)block.Position)
- firstPos = (uint)block.Position;
- }
-
- ShaderIrBlock current = visited[(int)firstPos];
-
- do
- {
- graph[graph.Length - visited.Count] = current;
-
- visited.Remove(current.Position);
-
- current = current.Next;
- }
- while (current != null);
- }
-
- return graph;
- }
-
- private static void FillBlock(IGalMemory memory, ShaderIrBlock block, long beginning)
- {
- int position = block.Position;
-
- do
- {
- //Ignore scheduling instructions, which are written every 32 bytes.
- if ((position & 0x1f) == 0)
- {
- position += 8;
-
- continue;
- }
-
- uint word0 = (uint)memory.ReadInt32(position + beginning + 0);
- uint word1 = (uint)memory.ReadInt32(position + beginning + 4);
-
- position += 8;
-
- long opCode = word0 | (long)word1 << 32;
-
- ShaderDecodeFunc decode = ShaderOpCodeTable.GetDecoder(opCode);
-
- if (AddDbgComments)
- {
- string dbgOpCode = $"0x{(position - 8):x16}: 0x{opCode:x16} ";
-
- dbgOpCode += (decode?.Method.Name ?? "???");
-
- if (decode == ShaderDecode.Bra || decode == ShaderDecode.Ssy)
- {
- int offset = ((int)(opCode >> 20) << 8) >> 8;
-
- long target = position + offset;
-
- dbgOpCode += " (0x" + target.ToString("x16") + ")";
- }
-
- block.AddNode(new ShaderIrCmnt(dbgOpCode));
- }
-
- if (decode == null)
- {
- continue;
- }
-
- decode(block, opCode, position);
- }
- while (!IsFlowChange(block.GetLastNode()));
-
- block.EndPosition = position;
- }
-
- private static bool IsFlowChange(ShaderIrNode node)
- {
- return !NodeHasNext(GetInnermostOp(node));
- }
-
- private static ShaderIrOp GetInnermostOp(ShaderIrNode node)
- {
- if (node is ShaderIrCond cond)
- {
- node = cond.Child;
- }
-
- return node is ShaderIrOp op ? op : null;
- }
-
- private static bool NodeHasNext(ShaderIrNode node)
- {
- if (!(node is ShaderIrOp op))
- {
- return true;
- }
-
- return op.Inst != ShaderIrInst.Exit &&
- op.Inst != ShaderIrInst.Bra;
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderHeader.cs b/Ryujinx.Graphics/Gal/Shader/ShaderHeader.cs
deleted file mode 100644
index 2f9326e1..00000000
--- a/Ryujinx.Graphics/Gal/Shader/ShaderHeader.cs
+++ /dev/null
@@ -1,146 +0,0 @@
-using System;
-
-namespace Ryujinx.Graphics.Gal.Shader
-{
- struct OmapTarget
- {
- public bool Red;
- public bool Green;
- public bool Blue;
- public bool Alpha;
-
- public bool Enabled => Red || Green || Blue || Alpha;
-
- public bool ComponentEnabled(int component)
- {
- switch (component)
- {
- case 0: return Red;
- case 1: return Green;
- case 2: return Blue;
- case 3: return Alpha;
- }
-
- throw new ArgumentException(nameof(component));
- }
- }
-
- class ShaderHeader
- {
- public const int PointList = 1;
- public const int LineStrip = 6;
- public const int TriangleStrip = 7;
-
- public int SphType { get; private set; }
- public int Version { get; private set; }
- public int ShaderType { get; private set; }
- public bool MrtEnable { get; private set; }
- public bool KillsPixels { get; private set; }
- public bool DoesGlobalStore { get; private set; }
- public int SassVersion { get; private set; }
- public bool DoesLoadOrStore { get; private set; }
- public bool DoesFp64 { get; private set; }
- public int StreamOutMask { get; private set; }
-
- public int ShaderLocalMemoryLowSize { get; private set; }
- public int PerPatchAttributeCount { get; private set; }
-
- public int ShaderLocalMemoryHighSize { get; private set; }
- public int ThreadsPerInputPrimitive { get; private set; }
-
- public int ShaderLocalMemoryCrsSize { get; private set; }
- public int OutputTopology { get; private set; }
-
- public int MaxOutputVertexCount { get; private set; }
- public int StoreReqStart { get; private set; }
- public int StoreReqEnd { get; private set; }
-
- public OmapTarget[] OmapTargets { get; private set; }
- public bool OmapSampleMask { get; private set; }
- public bool OmapDepth { get; private set; }
-
- public ShaderHeader(IGalMemory memory, long position)
- {
- uint commonWord0 = (uint)memory.ReadInt32(position + 0);
- uint commonWord1 = (uint)memory.ReadInt32(position + 4);
- uint commonWord2 = (uint)memory.ReadInt32(position + 8);
- uint commonWord3 = (uint)memory.ReadInt32(position + 12);
- uint commonWord4 = (uint)memory.ReadInt32(position + 16);
-
- SphType = ReadBits(commonWord0, 0, 5);
- Version = ReadBits(commonWord0, 5, 5);
- ShaderType = ReadBits(commonWord0, 10, 4);
- MrtEnable = ReadBits(commonWord0, 14, 1) != 0;
- KillsPixels = ReadBits(commonWord0, 15, 1) != 0;
- DoesGlobalStore = ReadBits(commonWord0, 16, 1) != 0;
- SassVersion = ReadBits(commonWord0, 17, 4);
- DoesLoadOrStore = ReadBits(commonWord0, 26, 1) != 0;
- DoesFp64 = ReadBits(commonWord0, 27, 1) != 0;
- StreamOutMask = ReadBits(commonWord0, 28, 4);
-
- ShaderLocalMemoryLowSize = ReadBits(commonWord1, 0, 24);
- PerPatchAttributeCount = ReadBits(commonWord1, 24, 8);
-
- ShaderLocalMemoryHighSize = ReadBits(commonWord2, 0, 24);
- ThreadsPerInputPrimitive = ReadBits(commonWord2, 24, 8);
-
- ShaderLocalMemoryCrsSize = ReadBits(commonWord3, 0, 24);
- OutputTopology = ReadBits(commonWord3, 24, 4);
-
- MaxOutputVertexCount = ReadBits(commonWord4, 0, 12);
- StoreReqStart = ReadBits(commonWord4, 12, 8);
- StoreReqEnd = ReadBits(commonWord4, 24, 8);
-
- //Type 2 (fragment?) reading
- uint type2OmapTarget = (uint)memory.ReadInt32(position + 72);
- uint type2Omap = (uint)memory.ReadInt32(position + 76);
-
- OmapTargets = new OmapTarget[8];
-
- for (int i = 0; i < OmapTargets.Length; i++)
- {
- int offset = i * 4;
-
- OmapTargets[i] = new OmapTarget
- {
- Red = ReadBits(type2OmapTarget, offset + 0, 1) != 0,
- Green = ReadBits(type2OmapTarget, offset + 1, 1) != 0,
- Blue = ReadBits(type2OmapTarget, offset + 2, 1) != 0,
- Alpha = ReadBits(type2OmapTarget, offset + 3, 1) != 0
- };
- }
-
- OmapSampleMask = ReadBits(type2Omap, 0, 1) != 0;
- OmapDepth = ReadBits(type2Omap, 1, 1) != 0;
- }
-
- public int DepthRegister
- {
- get
- {
- int count = 0;
-
- for (int index = 0; index < OmapTargets.Length; index++)
- {
- for (int component = 0; component < 4; component++)
- {
- if (OmapTargets[index].ComponentEnabled(component))
- {
- count++;
- }
- }
- }
-
- // Depth register is always two registers after the last color output
- return count + 1;
- }
- }
-
- private static int ReadBits(uint word, int offset, int bitWidth)
- {
- uint mask = (1u << bitWidth) - 1u;
-
- return (int)((word >> offset) & mask);
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderIpaMode.cs b/Ryujinx.Graphics/Gal/Shader/ShaderIpaMode.cs
deleted file mode 100644
index b3713fa4..00000000
--- a/Ryujinx.Graphics/Gal/Shader/ShaderIpaMode.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace Ryujinx.Graphics.Gal.Shader
-{
- enum ShaderIpaMode
- {
- Pass = 0,
- None = 1,
- Constant = 2,
- Sc = 3
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderIrAsg.cs b/Ryujinx.Graphics/Gal/Shader/ShaderIrAsg.cs
deleted file mode 100644
index 53871a14..00000000
--- a/Ryujinx.Graphics/Gal/Shader/ShaderIrAsg.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-namespace Ryujinx.Graphics.Gal.Shader
-{
- class ShaderIrAsg : ShaderIrNode
- {
- public ShaderIrNode Dst { get; set; }
- public ShaderIrNode Src { get; set; }
-
- public ShaderIrAsg(ShaderIrNode dst, ShaderIrNode src)
- {
- Dst = dst;
- Src = src;
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderIrBlock.cs b/Ryujinx.Graphics/Gal/Shader/ShaderIrBlock.cs
deleted file mode 100644
index 49257d28..00000000
--- a/Ryujinx.Graphics/Gal/Shader/ShaderIrBlock.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-using System.Collections.Generic;
-
-namespace Ryujinx.Graphics.Gal.Shader
-{
- class ShaderIrBlock
- {
- public int Position { get; set; }
- public int EndPosition { get; set; }
-
- public ShaderIrBlock Next { get; set; }
- public ShaderIrBlock Branch { get; set; }
-
- public List<ShaderIrBlock> Sources { get; private set; }
-
- public List<ShaderIrNode> Nodes { get; private set; }
-
- public ShaderIrBlock(int position)
- {
- Position = position;
-
- Sources = new List<ShaderIrBlock>();
-
- Nodes = new List<ShaderIrNode>();
- }
-
- public void AddNode(ShaderIrNode node)
- {
- Nodes.Add(node);
- }
-
- public ShaderIrNode[] GetNodes()
- {
- return Nodes.ToArray();
- }
-
- public ShaderIrNode GetLastNode()
- {
- if (Nodes.Count > 0)
- {
- return Nodes[Nodes.Count - 1];
- }
-
- return null;
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderIrCmnt.cs b/Ryujinx.Graphics/Gal/Shader/ShaderIrCmnt.cs
deleted file mode 100644
index 5da04e5e..00000000
--- a/Ryujinx.Graphics/Gal/Shader/ShaderIrCmnt.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace Ryujinx.Graphics.Gal.Shader
-{
- class ShaderIrCmnt : ShaderIrNode
- {
- public string Comment { get; private set; }
-
- public ShaderIrCmnt(string comment)
- {
- Comment = comment;
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderIrCond.cs b/Ryujinx.Graphics/Gal/Shader/ShaderIrCond.cs
deleted file mode 100644
index 34acf90d..00000000
--- a/Ryujinx.Graphics/Gal/Shader/ShaderIrCond.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-namespace Ryujinx.Graphics.Gal.Shader
-{
- class ShaderIrCond : ShaderIrNode
- {
- public ShaderIrNode Pred { get; set; }
- public ShaderIrNode Child { get; set; }
-
- public bool Not { get; private set; }
-
- public ShaderIrCond(ShaderIrNode pred, ShaderIrNode child, bool not)
- {
- Pred = pred;
- Child = child;
- Not = not;
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderIrInst.cs b/Ryujinx.Graphics/Gal/Shader/ShaderIrInst.cs
deleted file mode 100644
index 68ff214e..00000000
--- a/Ryujinx.Graphics/Gal/Shader/ShaderIrInst.cs
+++ /dev/null
@@ -1,94 +0,0 @@
-namespace Ryujinx.Graphics.Gal.Shader
-{
- enum ShaderIrInst
- {
- Invalid,
-
- B_Start,
- Band,
- Bnot,
- Bor,
- Bxor,
- B_End,
-
- F_Start,
- Ceil,
-
- Fabs,
- Fadd,
- Fceq,
- Fcequ,
- Fcge,
- Fcgeu,
- Fcgt,
- Fcgtu,
- Fclamp,
- Fcle,
- Fcleu,
- Fclt,
- Fcltu,
- Fcnan,
- Fcne,
- Fcneu,
- Fcnum,
- Fcos,
- Fex2,
- Ffma,
- Flg2,
- Floor,
- Fmax,
- Fmin,
- Fmul,
- Fneg,
- Frcp,
- Frsq,
- Fsin,
- Fsqrt,
- Ftos,
- Ftou,
- Ipa,
- Texb,
- Texs,
- Tld4,
- Trunc,
- F_End,
-
- I_Start,
- Abs,
- Add,
- And,
- Asr,
- Ceq,
- Cge,
- Cgt,
- Clamps,
- Clampu,
- Cle,
- Clt,
- Cne,
- Lsl,
- Lsr,
- Max,
- Min,
- Mul,
- Neg,
- Not,
- Or,
- Stof,
- Sub,
- Texq,
- Txlf,
- Utof,
- Xor,
- I_End,
-
- Bra,
- Exit,
- Kil,
- Ssy,
- Sync,
-
- Emit,
- Cut
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderIrMeta.cs b/Ryujinx.Graphics/Gal/Shader/ShaderIrMeta.cs
deleted file mode 100644
index afb7503b..00000000
--- a/Ryujinx.Graphics/Gal/Shader/ShaderIrMeta.cs
+++ /dev/null
@@ -1,4 +0,0 @@
-namespace Ryujinx.Graphics.Gal.Shader
-{
- class ShaderIrMeta { }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderIrMetaIpa.cs b/Ryujinx.Graphics/Gal/Shader/ShaderIrMetaIpa.cs
deleted file mode 100644
index 07db6467..00000000
--- a/Ryujinx.Graphics/Gal/Shader/ShaderIrMetaIpa.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace Ryujinx.Graphics.Gal.Shader
-{
- class ShaderIrMetaIpa : ShaderIrMeta
- {
- public ShaderIpaMode Mode { get; private set; }
-
- public ShaderIrMetaIpa(ShaderIpaMode mode)
- {
- Mode = mode;
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderIrMetaTex.cs b/Ryujinx.Graphics/Gal/Shader/ShaderIrMetaTex.cs
deleted file mode 100644
index e0265138..00000000
--- a/Ryujinx.Graphics/Gal/Shader/ShaderIrMetaTex.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using Ryujinx.Graphics.Texture;
-
-namespace Ryujinx.Graphics.Gal.Shader
-{
- class ShaderIrMetaTex : ShaderIrMeta
- {
- public int Elem { get; private set; }
- public GalTextureTarget TextureTarget { get; private set; }
- public ShaderIrNode[] Coordinates { get; private set; }
- public TextureInstructionSuffix TextureInstructionSuffix { get; private set; }
- public ShaderIrOperGpr LevelOfDetail;
- public ShaderIrOperGpr Offset;
- public ShaderIrOperGpr DepthCompare;
- public int Component; // for TLD4(S)
-
- public ShaderIrMetaTex(int elem, GalTextureTarget textureTarget, TextureInstructionSuffix textureInstructionSuffix, params ShaderIrNode[] coordinates)
- {
- Elem = elem;
- TextureTarget = textureTarget;
- TextureInstructionSuffix = textureInstructionSuffix;
- Coordinates = coordinates;
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderIrMetaTexq.cs b/Ryujinx.Graphics/Gal/Shader/ShaderIrMetaTexq.cs
deleted file mode 100644
index c925ea4e..00000000
--- a/Ryujinx.Graphics/Gal/Shader/ShaderIrMetaTexq.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-namespace Ryujinx.Graphics.Gal.Shader
-{
- class ShaderIrMetaTexq : ShaderIrMeta
- {
- public ShaderTexqInfo Info { get; private set; }
-
- public int Elem { get; private set; }
-
- public ShaderIrMetaTexq(ShaderTexqInfo info, int elem)
- {
- Info = info;
- Elem = elem;
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderIrNode.cs b/Ryujinx.Graphics/Gal/Shader/ShaderIrNode.cs
deleted file mode 100644
index 2648164a..00000000
--- a/Ryujinx.Graphics/Gal/Shader/ShaderIrNode.cs
+++ /dev/null
@@ -1,4 +0,0 @@
-namespace Ryujinx.Graphics.Gal.Shader
-{
- class ShaderIrNode { }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderIrOp.cs b/Ryujinx.Graphics/Gal/Shader/ShaderIrOp.cs
deleted file mode 100644
index c91c3926..00000000
--- a/Ryujinx.Graphics/Gal/Shader/ShaderIrOp.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-namespace Ryujinx.Graphics.Gal.Shader
-{
- class ShaderIrOp : ShaderIrNode
- {
- public ShaderIrInst Inst { get; private set; }
- public ShaderIrNode OperandA { get; set; }
- public ShaderIrNode OperandB { get; set; }
- public ShaderIrNode OperandC { get; set; }
- public ShaderIrMeta MetaData { get; set; }
-
- public ShaderIrOp(
- ShaderIrInst inst,
- ShaderIrNode operandA = null,
- ShaderIrNode operandB = null,
- ShaderIrNode operandC = null,
- ShaderIrMeta metaData = null)
- {
- Inst = inst;
- OperandA = operandA;
- OperandB = operandB;
- OperandC = operandC;
- MetaData = metaData;
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderIrOperAbuf.cs b/Ryujinx.Graphics/Gal/Shader/ShaderIrOperAbuf.cs
deleted file mode 100644
index 1f339e80..00000000
--- a/Ryujinx.Graphics/Gal/Shader/ShaderIrOperAbuf.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-namespace Ryujinx.Graphics.Gal.Shader
-{
- class ShaderIrOperAbuf : ShaderIrNode
- {
- public int Offs { get; private set; }
-
- public ShaderIrNode Vertex { get; private set; }
-
- public ShaderIrOperAbuf(int offs, ShaderIrNode vertex)
- {
- Offs = offs;
- Vertex = vertex;
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderIrOperCbuf.cs b/Ryujinx.Graphics/Gal/Shader/ShaderIrOperCbuf.cs
deleted file mode 100644
index 9f419bbb..00000000
--- a/Ryujinx.Graphics/Gal/Shader/ShaderIrOperCbuf.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-namespace Ryujinx.Graphics.Gal.Shader
-{
- class ShaderIrOperCbuf : ShaderIrNode
- {
- public int Index { get; private set; }
- public int Pos { get; set; }
-
- public ShaderIrNode Offs { get; private set; }
-
- public ShaderIrOperCbuf(int index, int pos, ShaderIrNode offs = null)
- {
- Index = index;
- Pos = pos;
- Offs = offs;
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderIrOperGpr.cs b/Ryujinx.Graphics/Gal/Shader/ShaderIrOperGpr.cs
deleted file mode 100644
index 0d102d89..00000000
--- a/Ryujinx.Graphics/Gal/Shader/ShaderIrOperGpr.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-namespace Ryujinx.Graphics.Gal.Shader
-{
- class ShaderIrOperGpr : ShaderIrNode
- {
- public const int ZrIndex = 0xff;
-
- public bool IsConst => Index == ZrIndex;
-
- public bool IsValidRegister => (uint)Index <= ZrIndex;
-
- public int Index { get; set; }
- public int HalfPart { get; set; }
-
- public ShaderRegisterSize RegisterSize { get; private set; }
-
- public ShaderIrOperGpr(int index)
- {
- Index = index;
-
- RegisterSize = ShaderRegisterSize.Single;
- }
-
- public ShaderIrOperGpr(int index, int halfPart)
- {
- Index = index;
- HalfPart = halfPart;
-
- RegisterSize = ShaderRegisterSize.Half;
- }
-
- public static ShaderIrOperGpr MakeTemporary(int index = 0)
- {
- return new ShaderIrOperGpr(0x100 + index);
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderIrOperImm.cs b/Ryujinx.Graphics/Gal/Shader/ShaderIrOperImm.cs
deleted file mode 100644
index 6b23b365..00000000
--- a/Ryujinx.Graphics/Gal/Shader/ShaderIrOperImm.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace Ryujinx.Graphics.Gal.Shader
-{
- class ShaderIrOperImm : ShaderIrNode
- {
- public int Value { get; private set; }
-
- public ShaderIrOperImm(int value)
- {
- Value = value;
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderIrOperImmf.cs b/Ryujinx.Graphics/Gal/Shader/ShaderIrOperImmf.cs
deleted file mode 100644
index 5b08c5b1..00000000
--- a/Ryujinx.Graphics/Gal/Shader/ShaderIrOperImmf.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace Ryujinx.Graphics.Gal.Shader
-{
- class ShaderIrOperImmf : ShaderIrNode
- {
- public float Value { get; private set; }
-
- public ShaderIrOperImmf(float value)
- {
- Value = value;
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderIrOperPred.cs b/Ryujinx.Graphics/Gal/Shader/ShaderIrOperPred.cs
deleted file mode 100644
index 6c16a145..00000000
--- a/Ryujinx.Graphics/Gal/Shader/ShaderIrOperPred.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-namespace Ryujinx.Graphics.Gal.Shader
-{
- class ShaderIrOperPred : ShaderIrNode
- {
- public const int UnusedIndex = 0x7;
- public const int NeverExecute = 0xf;
-
- public bool IsConst => Index >= UnusedIndex;
-
- public int Index { get; set; }
-
- public ShaderIrOperPred(int index)
- {
- Index = index;
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderOpCodeTable.cs b/Ryujinx.Graphics/Gal/Shader/ShaderOpCodeTable.cs
deleted file mode 100644
index 1edf91a0..00000000
--- a/Ryujinx.Graphics/Gal/Shader/ShaderOpCodeTable.cs
+++ /dev/null
@@ -1,190 +0,0 @@
-using System;
-
-namespace Ryujinx.Graphics.Gal.Shader
-{
- static class ShaderOpCodeTable
- {
- private const int EncodingBits = 14;
-
- private class ShaderDecodeEntry
- {
- public ShaderDecodeFunc Func;
-
- public int XBits;
-
- public ShaderDecodeEntry(ShaderDecodeFunc func, int xBits)
- {
- Func = func;
- XBits = xBits;
- }
- }
-
- private static ShaderDecodeEntry[] _opCodes;
-
- static ShaderOpCodeTable()
- {
- _opCodes = new ShaderDecodeEntry[1 << EncodingBits];
-
-#region Instructions
- Set("0100110000000x", ShaderDecode.Bfe_C);
- Set("0011100x00000x", ShaderDecode.Bfe_I);
- Set("0101110000000x", ShaderDecode.Bfe_R);
- Set("111000100100xx", ShaderDecode.Bra);
- Set("111000110000xx", ShaderDecode.Exit);
- Set("0100110010101x", ShaderDecode.F2f_C);
- Set("0011100x10101x", ShaderDecode.F2f_I);
- Set("0101110010101x", ShaderDecode.F2f_R);
- Set("0100110010110x", ShaderDecode.F2i_C);
- Set("0011100x10110x", ShaderDecode.F2i_I);
- Set("0101110010110x", ShaderDecode.F2i_R);
- Set("0100110001011x", ShaderDecode.Fadd_C);
- Set("0011100x01011x", ShaderDecode.Fadd_I);
- Set("000010xxxxxxxx", ShaderDecode.Fadd_I32);
- Set("0101110001011x", ShaderDecode.Fadd_R);
- Set("010010011xxxxx", ShaderDecode.Ffma_CR);
- Set("0011001x1xxxxx", ShaderDecode.Ffma_I);
- Set("010100011xxxxx", ShaderDecode.Ffma_RC);
- Set("010110011xxxxx", ShaderDecode.Ffma_RR);
- Set("0100110001101x", ShaderDecode.Fmul_C);
- Set("0011100x01101x", ShaderDecode.Fmul_I);
- Set("00011110xxxxxx", ShaderDecode.Fmul_I32);
- Set("0101110001101x", ShaderDecode.Fmul_R);
- Set("0100110001100x", ShaderDecode.Fmnmx_C);
- Set("0011100x01100x", ShaderDecode.Fmnmx_I);
- Set("0101110001100x", ShaderDecode.Fmnmx_R);
- Set("0100100xxxxxxx", ShaderDecode.Fset_C);
- Set("0011000xxxxxxx", ShaderDecode.Fset_I);
- Set("01011000xxxxxx", ShaderDecode.Fset_R);
- Set("010010111011xx", ShaderDecode.Fsetp_C);
- Set("0011011x1011xx", ShaderDecode.Fsetp_I);
- Set("010110111011xx", ShaderDecode.Fsetp_R);
- Set("0101110100010x", ShaderDecode.Hadd2_R);
- Set("0101110100001x", ShaderDecode.Hmul2_R);
- Set("0100110010111x", ShaderDecode.I2f_C);
- Set("0011100x10111x", ShaderDecode.I2f_I);
- Set("0101110010111x", ShaderDecode.I2f_R);
- Set("0100110011100x", ShaderDecode.I2i_C);
- Set("0011100x11100x", ShaderDecode.I2i_I);
- Set("0101110011100x", ShaderDecode.I2i_R);
- Set("0100110000010x", ShaderDecode.Iadd_C);
- Set("0011100000010x", ShaderDecode.Iadd_I);
- Set("0001110x0xxxxx", ShaderDecode.Iadd_I32);
- Set("0101110000010x", ShaderDecode.Iadd_R);
- Set("010011001100xx", ShaderDecode.Iadd3_C);
- Set("001110001100xx", ShaderDecode.Iadd3_I);
- Set("010111001100xx", ShaderDecode.Iadd3_R);
- Set("0100110000100x", ShaderDecode.Imnmx_C);
- Set("0011100x00100x", ShaderDecode.Imnmx_I);
- Set("0101110000100x", ShaderDecode.Imnmx_R);
- Set("1110111111010x", ShaderDecode.Isberd);
- Set("11100000xxxxxx", ShaderDecode.Ipa);
- Set("0100110000011x", ShaderDecode.Iscadd_C);
- Set("0011100x00011x", ShaderDecode.Iscadd_I);
- Set("0101110000011x", ShaderDecode.Iscadd_R);
- Set("010010110101xx", ShaderDecode.Iset_C);
- Set("001101100101xx", ShaderDecode.Iset_I);
- Set("010110110101xx", ShaderDecode.Iset_R);
- Set("010010110110xx", ShaderDecode.Isetp_C);
- Set("0011011x0110xx", ShaderDecode.Isetp_I);
- Set("010110110110xx", ShaderDecode.Isetp_R);
- Set("111000110011xx", ShaderDecode.Kil);
- Set("1110111111011x", ShaderDecode.Ld_A);
- Set("1110111110010x", ShaderDecode.Ld_C);
- Set("0100110001000x", ShaderDecode.Lop_C);
- Set("0011100001000x", ShaderDecode.Lop_I);
- Set("000001xxxxxxxx", ShaderDecode.Lop_I32);
- Set("0101110001000x", ShaderDecode.Lop_R);
- Set("0100110010011x", ShaderDecode.Mov_C);
- Set("0011100x10011x", ShaderDecode.Mov_I);
- Set("000000010000xx", ShaderDecode.Mov_I32);
- Set("0101110010011x", ShaderDecode.Mov_R);
- Set("1111000011001x", ShaderDecode.Mov_S);
- Set("0101000010000x", ShaderDecode.Mufu);
- Set("1111101111100x", ShaderDecode.Out_R);
- Set("0101000010010x", ShaderDecode.Psetp);
- Set("0100110010010x", ShaderDecode.Rro_C);
- Set("0011100x10010x", ShaderDecode.Rro_I);
- Set("0101110010010x", ShaderDecode.Rro_R);
- Set("0100110010100x", ShaderDecode.Sel_C);
- Set("0011100010100x", ShaderDecode.Sel_I);
- Set("0101110010100x", ShaderDecode.Sel_R);
- Set("0100110001001x", ShaderDecode.Shl_C);
- Set("0011100x01001x", ShaderDecode.Shl_I);
- Set("0101110001001x", ShaderDecode.Shl_R);
- Set("0100110000101x", ShaderDecode.Shr_C);
- Set("0011100x00101x", ShaderDecode.Shr_I);
- Set("0101110000101x", ShaderDecode.Shr_R);
- Set("111000101001xx", ShaderDecode.Ssy);
- Set("1110111111110x", ShaderDecode.St_A);
- Set("1111000011111x", ShaderDecode.Sync);
- Set("110000xxxx111x", ShaderDecode.Tex);
- Set("1101111010111x", ShaderDecode.Tex_B);
- Set("1101111101001x", ShaderDecode.Texq);
- Set("1101x00xxxxxxx", ShaderDecode.Texs);
- Set("1101101xxxxxxx", ShaderDecode.Tlds);
- Set("110010xxxx111x", ShaderDecode.Tld4);
- Set("1101111100xxxx", ShaderDecode.Tld4S);
- Set("01011111xxxxxx", ShaderDecode.Vmad);
- Set("0100111xxxxxxx", ShaderDecode.Xmad_CR);
- Set("0011011x00xxxx", ShaderDecode.Xmad_I);
- Set("010100010xxxxx", ShaderDecode.Xmad_RC);
- Set("0101101100xxxx", ShaderDecode.Xmad_RR);
-#endregion
- }
-
- private static void Set(string encoding, ShaderDecodeFunc func)
- {
- if (encoding.Length != EncodingBits)
- {
- throw new ArgumentException(nameof(encoding));
- }
-
- int bit = encoding.Length - 1;
- int value = 0;
- int xMask = 0;
- int xBits = 0;
-
- int[] xPos = new int[encoding.Length];
-
- for (int index = 0; index < encoding.Length; index++, bit--)
- {
- char chr = encoding[index];
-
- if (chr == '1')
- {
- value |= 1 << bit;
- }
- else if (chr == 'x')
- {
- xMask |= 1 << bit;
-
- xPos[xBits++] = bit;
- }
- }
-
- xMask = ~xMask;
-
- ShaderDecodeEntry entry = new ShaderDecodeEntry(func, xBits);
-
- for (int index = 0; index < (1 << xBits); index++)
- {
- value &= xMask;
-
- for (int x = 0; x < xBits; x++)
- {
- value |= ((index >> x) & 1) << xPos[x];
- }
-
- if (_opCodes[value] == null || _opCodes[value].XBits > xBits)
- {
- _opCodes[value] = entry;
- }
- }
- }
-
- public static ShaderDecodeFunc GetDecoder(long opCode)
- {
- return _opCodes[(ulong)opCode >> (64 - EncodingBits)]?.Func;
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderOper.cs b/Ryujinx.Graphics/Gal/Shader/ShaderOper.cs
deleted file mode 100644
index 22a2ab85..00000000
--- a/Ryujinx.Graphics/Gal/Shader/ShaderOper.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-namespace Ryujinx.Graphics.Gal.Shader
-{
- enum ShaderOper
- {
- Cr,
- Imm,
- Immf,
- Rc,
- Rr
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderRegisterSize.cs b/Ryujinx.Graphics/Gal/Shader/ShaderRegisterSize.cs
deleted file mode 100644
index eb37359b..00000000
--- a/Ryujinx.Graphics/Gal/Shader/ShaderRegisterSize.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace Ryujinx.Graphics.Gal.Shader
-{
- enum ShaderRegisterSize
- {
- Half,
- Single,
- Double
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderTexqInfo.cs b/Ryujinx.Graphics/Gal/Shader/ShaderTexqInfo.cs
deleted file mode 100644
index 9158662c..00000000
--- a/Ryujinx.Graphics/Gal/Shader/ShaderTexqInfo.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-namespace Ryujinx.Graphics.Gal.Shader
-{
- enum ShaderTexqInfo
- {
- Dimension = 1,
- TextureType = 2,
- SamplePos = 5,
- Filter = 16,
- Lod = 18,
- Wrap = 20,
- BorderColor = 22
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/ShaderDeclInfo.cs b/Ryujinx.Graphics/Gal/ShaderDeclInfo.cs
deleted file mode 100644
index f1f4650c..00000000
--- a/Ryujinx.Graphics/Gal/ShaderDeclInfo.cs
+++ /dev/null
@@ -1,45 +0,0 @@
-using Ryujinx.Graphics.Texture;
-
-namespace Ryujinx.Graphics.Gal
-{
- public class ShaderDeclInfo
- {
- public string Name { get; private set; }
-
- public int Index { get; private set; }
- public bool IsCb { get; private set; }
- public int Cbuf { get; private set; }
- public int Size { get; private set; }
-
- public GalTextureTarget TextureTarget { get; private set; }
-
- public TextureInstructionSuffix TextureSuffix { get; private set; }
-
- public ShaderDeclInfo(
- string name,
- int index,
- bool isCb = false,
- int cbuf = 0,
- int size = 1,
- GalTextureTarget textureTarget = GalTextureTarget.TwoD,
- TextureInstructionSuffix textureSuffix = TextureInstructionSuffix.None)
- {
- Name = name;
- Index = index;
- IsCb = isCb;
- Cbuf = cbuf;
- Size = size;
-
- TextureTarget = textureTarget;
- TextureSuffix = textureSuffix;
- }
-
- internal void Enlarge(int newSize)
- {
- if (Size < newSize)
- {
- Size = newSize;
- }
- }
- }
-} \ No newline at end of file