Initial support for shader attribute indexing (#2546)
* Initial support for shader attribute indexing * Support output indexing too, other improvements * Fix order * Address feedback
This commit is contained in:
parent
ec3e848d79
commit
ee1038e542
22 changed files with 298 additions and 86 deletions
|
@ -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);
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
namespace Ryujinx.Graphics.Shader.Decoders
|
||||
{
|
||||
interface IOpCodeAttribute
|
||||
interface IOpCodeAttribute : IOpCode
|
||||
{
|
||||
int AttributeOffset { get; }
|
||||
int Count { get; }
|
||||
bool Indexed { get; }
|
||||
}
|
||||
}
|
24
Ryujinx.Graphics.Shader/Decoders/OpCodeAl2p.cs
Normal file
24
Ryujinx.Graphics.Shader/Decoders/OpCodeAl2p.cs
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue