diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2021-08-26 20:44:47 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-08-27 01:44:47 +0200 |
| commit | ee1038e54255797a94b89091f4d59b77daad1a7b (patch) | |
| tree | 5ea62d8a2bae97004a4abe2ebf0a21c634b912dc /Ryujinx.Graphics.Shader/Decoders | |
| parent | ec3e848d7998038ce22c41acdbf81032bf47991f (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.cs | 53 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Shader/Decoders/IOpCodeAttribute.cs | 3 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Shader/Decoders/OpCodeAl2p.cs | 24 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Shader/Decoders/OpCodeAttribute.cs | 9 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Shader/Decoders/OpCodeIpa.cs | 5 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs | 1 |
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); |
