aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Shader/Decoders
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2021-08-26 20:44:47 -0300
committerGitHub <noreply@github.com>2021-08-27 01:44:47 +0200
commitee1038e54255797a94b89091f4d59b77daad1a7b (patch)
tree5ea62d8a2bae97004a4abe2ebf0a21c634b912dc /Ryujinx.Graphics.Shader/Decoders
parentec3e848d7998038ce22c41acdbf81032bf47991f (diff)
Initial support for shader attribute indexing (#2546)
* Initial support for shader attribute indexing * Support output indexing too, other improvements * Fix order * Address feedback
Diffstat (limited to 'Ryujinx.Graphics.Shader/Decoders')
-rw-r--r--Ryujinx.Graphics.Shader/Decoders/Decoder.cs53
-rw-r--r--Ryujinx.Graphics.Shader/Decoders/IOpCodeAttribute.cs3
-rw-r--r--Ryujinx.Graphics.Shader/Decoders/OpCodeAl2p.cs24
-rw-r--r--Ryujinx.Graphics.Shader/Decoders/OpCodeAttribute.cs9
-rw-r--r--Ryujinx.Graphics.Shader/Decoders/OpCodeIpa.cs5
-rw-r--r--Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs1
6 files changed, 75 insertions, 20 deletions
diff --git a/Ryujinx.Graphics.Shader/Decoders/Decoder.cs b/Ryujinx.Graphics.Shader/Decoders/Decoder.cs
index 12b49d35..c2901eab 100644
--- a/Ryujinx.Graphics.Shader/Decoders/Decoder.cs
+++ b/Ryujinx.Graphics.Shader/Decoders/Decoder.cs
@@ -282,23 +282,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
// Populate used attributes.
if (op is IOpCodeAttribute opAttr)
{
- for (int elemIndex = 0; elemIndex < opAttr.Count; elemIndex++)
- {
- int attr = opAttr.AttributeOffset + elemIndex * 4;
- if (attr >= AttributeConsts.UserAttributeBase && attr < AttributeConsts.UserAttributeEnd)
- {
- int index = (attr - AttributeConsts.UserAttributeBase) / 16;
-
- if (op.Emitter == InstEmit.Ast)
- {
- config.SetOutputUserAttribute(index);
- }
- else
- {
- config.SetInputUserAttribute(index);
- }
- }
- }
+ SetUserAttributeUses(config, opAttr);
}
block.OpCodes.Add(op);
@@ -310,6 +294,41 @@ namespace Ryujinx.Graphics.Shader.Decoders
block.UpdatePushOps();
}
+ private static void SetUserAttributeUses(ShaderConfig config, IOpCodeAttribute opAttr)
+ {
+ if (opAttr.Indexed)
+ {
+ if (opAttr.Emitter == InstEmit.Ast)
+ {
+ config.SetAllOutputUserAttributes();
+ }
+ else
+ {
+ config.SetAllInputUserAttributes();
+ }
+ }
+ else
+ {
+ for (int elemIndex = 0; elemIndex < opAttr.Count; elemIndex++)
+ {
+ int attr = opAttr.AttributeOffset + elemIndex * 4;
+ if (attr >= AttributeConsts.UserAttributeBase && attr < AttributeConsts.UserAttributeEnd)
+ {
+ int index = (attr - AttributeConsts.UserAttributeBase) / 16;
+
+ if (opAttr.Emitter == InstEmit.Ast)
+ {
+ config.SetOutputUserAttribute(index);
+ }
+ else
+ {
+ config.SetInputUserAttribute(index);
+ }
+ }
+ }
+ }
+ }
+
private static bool IsUnconditionalBranch(OpCode opCode)
{
return IsUnconditional(opCode) && IsControlFlowChange(opCode);
diff --git a/Ryujinx.Graphics.Shader/Decoders/IOpCodeAttribute.cs b/Ryujinx.Graphics.Shader/Decoders/IOpCodeAttribute.cs
index b5b16f1b..2b6835be 100644
--- a/Ryujinx.Graphics.Shader/Decoders/IOpCodeAttribute.cs
+++ b/Ryujinx.Graphics.Shader/Decoders/IOpCodeAttribute.cs
@@ -1,8 +1,9 @@
namespace Ryujinx.Graphics.Shader.Decoders
{
- interface IOpCodeAttribute
+ interface IOpCodeAttribute : IOpCode
{
int AttributeOffset { get; }
int Count { get; }
+ bool Indexed { get; }
}
} \ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeAl2p.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeAl2p.cs
new file mode 100644
index 00000000..d924b393
--- /dev/null
+++ b/Ryujinx.Graphics.Shader/Decoders/OpCodeAl2p.cs
@@ -0,0 +1,24 @@
+using Ryujinx.Graphics.Shader.Instructions;
+
+namespace Ryujinx.Graphics.Shader.Decoders
+{
+ class OpCodeAl2p : OpCode, IOpCodeRd, IOpCodeRa
+ {
+ public Register Rd { get; }
+ public Register Ra { get; }
+ public Register Predicate44 { get; }
+
+ public int Immediate { get; }
+
+ public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeAl2p(emitter, address, opCode);
+
+ public OpCodeAl2p(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
+ {
+ Rd = new Register(opCode.Extract(0, 8), RegisterType.Gpr);
+ Ra = new Register(opCode.Extract(8, 8), RegisterType.Gpr);
+ Predicate44 = new Register(opCode.Extract(44, 3), RegisterType.Predicate);
+
+ Immediate = ((int)opCode << 1) >> 21;
+ }
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeAttribute.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeAttribute.cs
index f9119665..0a24d4c8 100644
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeAttribute.cs
+++ b/Ryujinx.Graphics.Shader/Decoders/OpCodeAttribute.cs
@@ -4,14 +4,19 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
class OpCodeAttribute : OpCodeAluReg, IOpCodeAttribute
{
- public int AttributeOffset { get; }
- public int Count { get; }
+ public int AttributeOffset { get; }
+ public bool Patch { get; }
+ public int Count { get; }
+
+ public bool Phys => !Patch && AttributeOffset == 0 && !Ra.IsRZ;
+ public bool Indexed => Phys;
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeAttribute(emitter, address, opCode);
public OpCodeAttribute(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{
AttributeOffset = opCode.Extract(20, 10);
+ Patch = opCode.Extract(31);
Count = opCode.Extract(47, 2) + 1;
}
}
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeIpa.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeIpa.cs
index dc4e03e3..d38a1b3a 100644
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeIpa.cs
+++ b/Ryujinx.Graphics.Shader/Decoders/OpCodeIpa.cs
@@ -7,6 +7,9 @@ namespace Ryujinx.Graphics.Shader.Decoders
public int AttributeOffset { get; }
public int Count => 1;
+ public bool Idx { get; }
+ public bool Indexed => Idx;
+
public InterpolationMode Mode { get; }
public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeIpa(emitter, address, opCode);
@@ -15,6 +18,8 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
AttributeOffset = opCode.Extract(28, 10);
+ Idx = opCode.Extract(38);
+
Saturate = opCode.Extract(51);
Mode = (InterpolationMode)opCode.Extract(54, 2);
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs
index 8b9cb20d..e5bcd7e5 100644
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs
+++ b/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs
@@ -32,6 +32,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
_opCodes = new TableEntry[1 << EncodingBits];
#region Instructions
+ Set("1110111110100x", InstEmit.Al2p, OpCodeAl2p.Create);
Set("1110111111011x", InstEmit.Ald, OpCodeAttribute.Create);
Set("1110111111110x", InstEmit.Ast, OpCodeAttribute.Create);
Set("11101101xxxxxx", InstEmit.Atom, OpCodeAtom.Create);