Add support for float immediates, implement FSETP (immediate) on shader decoder
This commit is contained in:
parent
2d669d4c23
commit
2000e904f1
7 changed files with 74 additions and 48 deletions
|
@ -106,7 +106,7 @@ namespace Ryujinx.Graphics.Gal.Shader
|
|||
Op.Inst == ShaderIrInst.Texb ||
|
||||
Op.Inst == ShaderIrInst.Texa)
|
||||
{
|
||||
int Handle = ((ShaderIrOperImm)Op.OperandC).Imm;
|
||||
int Handle = ((ShaderIrOperImm)Op.OperandC).Value;
|
||||
|
||||
int Index = Handle - TexStartIndex;
|
||||
|
||||
|
|
|
@ -264,11 +264,12 @@ namespace Ryujinx.Graphics.Gal.Shader
|
|||
{
|
||||
switch (Node)
|
||||
{
|
||||
case ShaderIrOperAbuf Abuf: return GetName(Abuf);
|
||||
case ShaderIrOperCbuf Cbuf: return GetName(Cbuf);
|
||||
case ShaderIrOperGpr Gpr: return GetName(Gpr);
|
||||
case ShaderIrOperImm Imm: return GetName(Imm);
|
||||
case ShaderIrOperPred Pred: return GetName(Pred);
|
||||
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;
|
||||
|
@ -332,9 +333,14 @@ namespace Ryujinx.Graphics.Gal.Shader
|
|||
return Gpr.IsConst ? "0" : GetNameWithSwizzle(Decl.Gprs, Gpr.Index);
|
||||
}
|
||||
|
||||
private string GetName(ShaderIrOperImm Imm)
|
||||
private string GetValue(ShaderIrOperImm Imm)
|
||||
{
|
||||
return Imm.Imm.ToString(CultureInfo.InvariantCulture);
|
||||
return Imm.Value.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
private string GetValue(ShaderIrOperImmf Immf)
|
||||
{
|
||||
return Immf.Value.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
private string GetName(ShaderIrOperPred Pred)
|
||||
|
@ -443,7 +449,7 @@ namespace Ryujinx.Graphics.Gal.Shader
|
|||
{
|
||||
ShaderIrOperImm Node = (ShaderIrOperImm)Op.OperandC;
|
||||
|
||||
int Handle = ((ShaderIrOperImm)Op.OperandC).Imm;
|
||||
int Handle = ((ShaderIrOperImm)Op.OperandC).Value;
|
||||
|
||||
if (!Decl.Textures.TryGetValue(Handle, out ShaderDeclInfo DeclInfo))
|
||||
{
|
||||
|
|
|
@ -8,30 +8,25 @@ namespace Ryujinx.Graphics.Gal.Shader
|
|||
{
|
||||
private enum ShaderOper
|
||||
{
|
||||
CR,
|
||||
RR,
|
||||
RC,
|
||||
CR,
|
||||
Imm
|
||||
}
|
||||
|
||||
public static void Fadd_R(ShaderIrBlock Block, long OpCode)
|
||||
{
|
||||
EmitAluBinary(Block, OpCode, ShaderOper.RR, ShaderIrInst.Fadd);
|
||||
}
|
||||
|
||||
public static void Fadd_C(ShaderIrBlock Block, long OpCode)
|
||||
{
|
||||
EmitAluBinary(Block, OpCode, ShaderOper.CR, ShaderIrInst.Fadd);
|
||||
}
|
||||
|
||||
public static void Fadd_Imm(ShaderIrBlock Block, long OpCode)
|
||||
public static void Fadd_I(ShaderIrBlock Block, long OpCode)
|
||||
{
|
||||
EmitAluBinary(Block, OpCode, ShaderOper.Imm, ShaderIrInst.Fadd);
|
||||
}
|
||||
|
||||
public static void Ffma_RR(ShaderIrBlock Block, long OpCode)
|
||||
public static void Fadd_R(ShaderIrBlock Block, long OpCode)
|
||||
{
|
||||
EmitAluFfma(Block, OpCode, ShaderOper.RR);
|
||||
EmitAluBinary(Block, OpCode, ShaderOper.RR, ShaderIrInst.Fadd);
|
||||
}
|
||||
|
||||
public static void Ffma_CR(ShaderIrBlock Block, long OpCode)
|
||||
|
@ -39,19 +34,19 @@ namespace Ryujinx.Graphics.Gal.Shader
|
|||
EmitAluFfma(Block, OpCode, ShaderOper.CR);
|
||||
}
|
||||
|
||||
public static void Ffma_I(ShaderIrBlock Block, long OpCode)
|
||||
{
|
||||
EmitAluFfma(Block, OpCode, ShaderOper.Imm);
|
||||
}
|
||||
|
||||
public static void Ffma_RC(ShaderIrBlock Block, long OpCode)
|
||||
{
|
||||
EmitAluFfma(Block, OpCode, ShaderOper.RC);
|
||||
}
|
||||
|
||||
public static void Ffma_Imm(ShaderIrBlock Block, long OpCode)
|
||||
public static void Ffma_RR(ShaderIrBlock Block, long OpCode)
|
||||
{
|
||||
EmitAluFfma(Block, OpCode, ShaderOper.Imm);
|
||||
}
|
||||
|
||||
public static void Fmul_R(ShaderIrBlock Block, long OpCode)
|
||||
{
|
||||
EmitAluBinary(Block, OpCode, ShaderOper.RR, ShaderIrInst.Fmul);
|
||||
EmitAluFfma(Block, OpCode, ShaderOper.RR);
|
||||
}
|
||||
|
||||
public static void Fmul_C(ShaderIrBlock Block, long OpCode)
|
||||
|
@ -59,14 +54,14 @@ namespace Ryujinx.Graphics.Gal.Shader
|
|||
EmitAluBinary(Block, OpCode, ShaderOper.CR, ShaderIrInst.Fmul);
|
||||
}
|
||||
|
||||
public static void Fmul_Imm(ShaderIrBlock Block, long OpCode)
|
||||
public static void Fmul_I(ShaderIrBlock Block, long OpCode)
|
||||
{
|
||||
EmitAluBinary(Block, OpCode, ShaderOper.Imm, ShaderIrInst.Fmul);
|
||||
}
|
||||
|
||||
public static void Fsetp_R(ShaderIrBlock Block, long OpCode)
|
||||
public static void Fmul_R(ShaderIrBlock Block, long OpCode)
|
||||
{
|
||||
EmitFsetp(Block, OpCode, ShaderOper.RR);
|
||||
EmitAluBinary(Block, OpCode, ShaderOper.RR, ShaderIrInst.Fmul);
|
||||
}
|
||||
|
||||
public static void Fsetp_C(ShaderIrBlock Block, long OpCode)
|
||||
|
@ -74,6 +69,16 @@ namespace Ryujinx.Graphics.Gal.Shader
|
|||
EmitFsetp(Block, OpCode, ShaderOper.CR);
|
||||
}
|
||||
|
||||
public static void Fsetp_I(ShaderIrBlock Block, long OpCode)
|
||||
{
|
||||
EmitFsetp(Block, OpCode, ShaderOper.Imm);
|
||||
}
|
||||
|
||||
public static void Fsetp_R(ShaderIrBlock Block, long OpCode)
|
||||
{
|
||||
EmitFsetp(Block, OpCode, ShaderOper.RR);
|
||||
}
|
||||
|
||||
public static void Ipa(ShaderIrBlock Block, long OpCode)
|
||||
{
|
||||
ShaderIrNode OperA = GetOperAbuf28(OpCode);
|
||||
|
@ -101,6 +106,8 @@ namespace Ryujinx.Graphics.Gal.Shader
|
|||
case 3: Inst = ShaderIrInst.Flg2; break;
|
||||
case 4: Inst = ShaderIrInst.Frcp; break;
|
||||
case 5: Inst = ShaderIrInst.Frsq; break;
|
||||
|
||||
default: throw new NotImplementedException(SubOp.ToString());
|
||||
}
|
||||
|
||||
ShaderIrNode OperA = GetOperGpr8(OpCode);
|
||||
|
@ -131,9 +138,9 @@ namespace Ryujinx.Graphics.Gal.Shader
|
|||
|
||||
switch (Oper)
|
||||
{
|
||||
case ShaderOper.RR: OperB = GetOperGpr20 (OpCode); break;
|
||||
case ShaderOper.CR: OperB = GetOperCbuf34 (OpCode); break;
|
||||
case ShaderOper.Imm: OperB = GetOperImmf19_20(OpCode); break;
|
||||
case ShaderOper.RR: OperB = GetOperGpr20 (OpCode); break;
|
||||
|
||||
default: throw new ArgumentException(nameof(Oper));
|
||||
}
|
||||
|
@ -156,10 +163,10 @@ namespace Ryujinx.Graphics.Gal.Shader
|
|||
|
||||
switch (Oper)
|
||||
{
|
||||
case ShaderOper.RR: OperB = GetOperGpr20 (OpCode); break;
|
||||
case ShaderOper.CR: OperB = GetOperCbuf34 (OpCode); break;
|
||||
case ShaderOper.RC: OperB = GetOperGpr39 (OpCode); break;
|
||||
case ShaderOper.Imm: OperB = GetOperImmf19_20(OpCode); break;
|
||||
case ShaderOper.RC: OperB = GetOperGpr39 (OpCode); break;
|
||||
case ShaderOper.RR: OperB = GetOperGpr20 (OpCode); break;
|
||||
|
||||
default: throw new ArgumentException(nameof(Oper));
|
||||
}
|
||||
|
@ -191,9 +198,9 @@ namespace Ryujinx.Graphics.Gal.Shader
|
|||
|
||||
switch (Oper)
|
||||
{
|
||||
case ShaderOper.RR: OperB = GetOperGpr20 (OpCode); break;
|
||||
case ShaderOper.CR: OperB = GetOperCbuf34 (OpCode); break;
|
||||
case ShaderOper.Imm: OperB = GetOperImmf19_20(OpCode); break;
|
||||
case ShaderOper.RR: OperB = GetOperGpr20 (OpCode); break;
|
||||
|
||||
default: throw new ArgumentException(nameof(Oper));
|
||||
}
|
||||
|
|
|
@ -62,8 +62,20 @@ namespace Ryujinx.Graphics.Gal.Shader
|
|||
|
||||
public static ShaderIrNode GetOperImmf19_20(long OpCode)
|
||||
{
|
||||
//TODO: This should be a float immediate.
|
||||
return new ShaderIrOperImm((int)(OpCode >> 36) & 0x1fff);
|
||||
uint Imm = (uint)(OpCode >> 20) & 0x7ffff;
|
||||
|
||||
bool Neg = ((OpCode >> 56) & 1) != 0;
|
||||
|
||||
Imm <<= 12;
|
||||
|
||||
if (Neg)
|
||||
{
|
||||
Imm |= 0x80000000;
|
||||
}
|
||||
|
||||
float Value = BitConverter.Int32BitsToSingle((int)Imm);
|
||||
|
||||
return new ShaderIrOperImmf(Value);
|
||||
}
|
||||
|
||||
public static ShaderIrOperImm GetOperImm13_36(long OpCode)
|
||||
|
|
|
@ -2,11 +2,11 @@ namespace Ryujinx.Graphics.Gal.Shader
|
|||
{
|
||||
class ShaderIrOperImm : ShaderIrNode
|
||||
{
|
||||
public int Imm { get; private set; }
|
||||
public int Value { get; private set; }
|
||||
|
||||
public ShaderIrOperImm(int Imm)
|
||||
public ShaderIrOperImm(int Value)
|
||||
{
|
||||
this.Imm = Imm;
|
||||
this.Value = Value;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,11 +2,11 @@ namespace Ryujinx.Graphics.Gal.Shader
|
|||
{
|
||||
class ShaderIrOperImmf : ShaderIrNode
|
||||
{
|
||||
public float Imm { get; private set; }
|
||||
public float Value { get; private set; }
|
||||
|
||||
public ShaderIrOperImmf(float Imm)
|
||||
public ShaderIrOperImmf(float Value)
|
||||
{
|
||||
this.Imm = Imm;
|
||||
this.Value = Value;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,18 +14,19 @@ namespace Ryujinx.Graphics.Gal.Shader
|
|||
|
||||
#region Instructions
|
||||
Set("111000110000xx", ShaderDecode.Exit);
|
||||
Set("0101110001011x", ShaderDecode.Fadd_R);
|
||||
Set("0100110001011x", ShaderDecode.Fadd_C);
|
||||
Set("0011100x01011x", ShaderDecode.Fadd_Imm);
|
||||
Set("010110011xxxxx", ShaderDecode.Ffma_RR);
|
||||
Set("010100011xxxxx", ShaderDecode.Ffma_RC);
|
||||
Set("0011100x01011x", ShaderDecode.Fadd_I);
|
||||
Set("0101110001011x", ShaderDecode.Fadd_R);
|
||||
Set("010010011xxxxx", ShaderDecode.Ffma_CR);
|
||||
Set("001100101xxxxx", ShaderDecode.Ffma_Imm);
|
||||
Set("0101110001101x", ShaderDecode.Fmul_R);
|
||||
Set("001100101xxxxx", ShaderDecode.Ffma_I);
|
||||
Set("010100011xxxxx", ShaderDecode.Ffma_RC);
|
||||
Set("010110011xxxxx", ShaderDecode.Ffma_RR);
|
||||
Set("0100110001101x", ShaderDecode.Fmul_C);
|
||||
Set("0011100x01101x", ShaderDecode.Fmul_Imm);
|
||||
Set("010110111011xx", ShaderDecode.Fsetp_R);
|
||||
Set("0011100x01101x", ShaderDecode.Fmul_I);
|
||||
Set("0101110001101x", ShaderDecode.Fmul_R);
|
||||
Set("010010111011xx", ShaderDecode.Fsetp_C);
|
||||
Set("0011011x1011xx", ShaderDecode.Fsetp_I);
|
||||
Set("010110111011xx", ShaderDecode.Fsetp_R);
|
||||
Set("11100000xxxxxx", ShaderDecode.Ipa);
|
||||
Set("111000110011xx", ShaderDecode.Kil);
|
||||
Set("1110111111011x", ShaderDecode.Ld_A);
|
||||
|
|
Loading…
Add table
Reference in a new issue