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