Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
9becbd7d72 | ||
|
e055217292 | ||
|
fbaf62c230 |
@@ -1296,11 +1296,11 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const byte mask = 0b01_00_11_10;
|
const byte Mask = 0b01_00_11_10;
|
||||||
|
|
||||||
context.Assembler.Pshufd(src1, src1, mask);
|
context.Assembler.Pshufd(src1, src1, Mask);
|
||||||
context.Assembler.Movq(dest, src1);
|
context.Assembler.Movq(dest, src1);
|
||||||
context.Assembler.Pshufd(src1, src1, mask);
|
context.Assembler.Pshufd(src1, src1, Mask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1853,9 +1853,9 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
// that the OS will map all pages that we'll use. We do that by
|
// that the OS will map all pages that we'll use. We do that by
|
||||||
// doing a dummy read on those pages, forcing a page fault and
|
// doing a dummy read on those pages, forcing a page fault and
|
||||||
// the OS to map them. If they are already mapped, nothing happens.
|
// the OS to map them. If they are already mapped, nothing happens.
|
||||||
const int pageMask = PageSize - 1;
|
const int PageMask = PageSize - 1;
|
||||||
|
|
||||||
size = (size + pageMask) & ~pageMask;
|
size = (size + PageMask) & ~PageMask;
|
||||||
|
|
||||||
Operand rsp = Register(X86Register.Rsp);
|
Operand rsp = Register(X86Register.Rsp);
|
||||||
Operand temp = Register(CallingConvention.GetIntReturnRegister());
|
Operand temp = Register(CallingConvention.GetIntReturnRegister());
|
||||||
|
@@ -304,9 +304,9 @@ namespace ARMeilleure.Decoders
|
|||||||
}
|
}
|
||||||
else if (opCode is IOpCode32MemMult opMemMult)
|
else if (opCode is IOpCode32MemMult opMemMult)
|
||||||
{
|
{
|
||||||
const int pcMask = 1 << RegisterAlias.Aarch32Pc;
|
const int PCMask = 1 << RegisterAlias.Aarch32Pc;
|
||||||
|
|
||||||
rt = (opMemMult.RegisterMask & pcMask) != 0 ? RegisterAlias.Aarch32Pc : 0;
|
rt = (opMemMult.RegisterMask & PCMask) != 0 ? RegisterAlias.Aarch32Pc : 0;
|
||||||
rn = opMemMult.Rn;
|
rn = opMemMult.Rn;
|
||||||
wBack = opMemMult.PostOffset != 0;
|
wBack = opMemMult.PostOffset != 0;
|
||||||
isLoad = opMemMult.IsLoad;
|
isLoad = opMemMult.IsLoad;
|
||||||
|
@@ -17,7 +17,7 @@ namespace ARMeilleure.Decoders.Optimizations
|
|||||||
throw new InvalidOperationException("Function entry point is not contained in a block.");
|
throw new InvalidOperationException("Function entry point is not contained in a block.");
|
||||||
}
|
}
|
||||||
|
|
||||||
const ulong allowance = 4;
|
const ulong Allowance = 4;
|
||||||
|
|
||||||
Block entryBlock = blocks[entryBlockId];
|
Block entryBlock = blocks[entryBlockId];
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ namespace ARMeilleure.Decoders.Optimizations
|
|||||||
{
|
{
|
||||||
Block block = blocks[i];
|
Block block = blocks[i];
|
||||||
|
|
||||||
if (endBlock.EndAddress < block.Address - allowance)
|
if (endBlock.EndAddress < block.Address - Allowance)
|
||||||
{
|
{
|
||||||
break; // End of contiguous function.
|
break; // End of contiguous function.
|
||||||
}
|
}
|
||||||
@@ -44,7 +44,7 @@ namespace ARMeilleure.Decoders.Optimizations
|
|||||||
{
|
{
|
||||||
Block block = blocks[i];
|
Block block = blocks[i];
|
||||||
|
|
||||||
if (startBlock.Address > block.EndAddress + allowance)
|
if (startBlock.Address > block.EndAddress + Allowance)
|
||||||
{
|
{
|
||||||
break; // End of contiguous function.
|
break; // End of contiguous function.
|
||||||
}
|
}
|
||||||
|
@@ -1299,17 +1299,17 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
Debug.Assert((op.Size & 1) == 0 && op.RegisterSize == RegisterSize.Simd128);
|
Debug.Assert((op.Size & 1) == 0 && op.RegisterSize == RegisterSize.Simd128);
|
||||||
|
|
||||||
const int sm0 = 0 << 6 | 0 << 4 | 0 << 2 | 0 << 0;
|
const int SM0 = 0 << 6 | 0 << 4 | 0 << 2 | 0 << 0;
|
||||||
const int sm1 = 1 << 6 | 1 << 4 | 1 << 2 | 1 << 0;
|
const int SM1 = 1 << 6 | 1 << 4 | 1 << 2 | 1 << 0;
|
||||||
const int sm2 = 2 << 6 | 2 << 4 | 2 << 2 | 2 << 0;
|
const int SM2 = 2 << 6 | 2 << 4 | 2 << 2 | 2 << 0;
|
||||||
const int sm3 = 3 << 6 | 3 << 4 | 3 << 2 | 3 << 0;
|
const int SM3 = 3 << 6 | 3 << 4 | 3 << 2 | 3 << 0;
|
||||||
|
|
||||||
Operand nCopy = context.Copy(GetVec(op.Rn));
|
Operand nCopy = context.Copy(GetVec(op.Rn));
|
||||||
|
|
||||||
Operand part0 = context.AddIntrinsic(Intrinsic.X86Shufps, nCopy, nCopy, Const(sm0));
|
Operand part0 = context.AddIntrinsic(Intrinsic.X86Shufps, nCopy, nCopy, Const(SM0));
|
||||||
Operand part1 = context.AddIntrinsic(Intrinsic.X86Shufps, nCopy, nCopy, Const(sm1));
|
Operand part1 = context.AddIntrinsic(Intrinsic.X86Shufps, nCopy, nCopy, Const(SM1));
|
||||||
Operand part2 = context.AddIntrinsic(Intrinsic.X86Shufps, nCopy, nCopy, Const(sm2));
|
Operand part2 = context.AddIntrinsic(Intrinsic.X86Shufps, nCopy, nCopy, Const(SM2));
|
||||||
Operand part3 = context.AddIntrinsic(Intrinsic.X86Shufps, nCopy, nCopy, Const(sm3));
|
Operand part3 = context.AddIntrinsic(Intrinsic.X86Shufps, nCopy, nCopy, Const(SM3));
|
||||||
|
|
||||||
Operand res = emit(emit(part0, part1), emit(part2, part3));
|
Operand res = emit(emit(part0, part1), emit(part2, part3));
|
||||||
|
|
||||||
@@ -1340,13 +1340,13 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
if ((op.Size & 1) == 0)
|
if ((op.Size & 1) == 0)
|
||||||
{
|
{
|
||||||
const int sm0 = 2 << 6 | 2 << 4 | 2 << 2 | 0 << 0;
|
const int SM0 = 2 << 6 | 2 << 4 | 2 << 2 | 0 << 0;
|
||||||
const int sm1 = 2 << 6 | 2 << 4 | 2 << 2 | 1 << 0;
|
const int SM1 = 2 << 6 | 2 << 4 | 2 << 2 | 1 << 0;
|
||||||
|
|
||||||
Operand zeroN = context.VectorZeroUpper64(n);
|
Operand zeroN = context.VectorZeroUpper64(n);
|
||||||
|
|
||||||
op0 = context.AddIntrinsic(Intrinsic.X86Pshufd, zeroN, Const(sm0));
|
op0 = context.AddIntrinsic(Intrinsic.X86Pshufd, zeroN, Const(SM0));
|
||||||
op1 = context.AddIntrinsic(Intrinsic.X86Pshufd, zeroN, Const(sm1));
|
op1 = context.AddIntrinsic(Intrinsic.X86Pshufd, zeroN, Const(SM1));
|
||||||
}
|
}
|
||||||
else /* if ((op.Size & 1) == 1) */
|
else /* if ((op.Size & 1) == 1) */
|
||||||
{
|
{
|
||||||
@@ -1412,11 +1412,11 @@ namespace ARMeilleure.Instructions
|
|||||||
}
|
}
|
||||||
else /* if (op.RegisterSize == RegisterSize.Simd128) */
|
else /* if (op.RegisterSize == RegisterSize.Simd128) */
|
||||||
{
|
{
|
||||||
const int sm0 = 2 << 6 | 0 << 4 | 2 << 2 | 0 << 0;
|
const int SM0 = 2 << 6 | 0 << 4 | 2 << 2 | 0 << 0;
|
||||||
const int sm1 = 3 << 6 | 1 << 4 | 3 << 2 | 1 << 0;
|
const int SM1 = 3 << 6 | 1 << 4 | 3 << 2 | 1 << 0;
|
||||||
|
|
||||||
Operand part0 = context.AddIntrinsic(Intrinsic.X86Shufps, nCopy, mCopy, Const(sm0));
|
Operand part0 = context.AddIntrinsic(Intrinsic.X86Shufps, nCopy, mCopy, Const(SM0));
|
||||||
Operand part1 = context.AddIntrinsic(Intrinsic.X86Shufps, nCopy, mCopy, Const(sm1));
|
Operand part1 = context.AddIntrinsic(Intrinsic.X86Shufps, nCopy, mCopy, Const(SM1));
|
||||||
|
|
||||||
context.Copy(GetVec(op.Rd), emit(part0, part1));
|
context.Copy(GetVec(op.Rd), emit(part0, part1));
|
||||||
}
|
}
|
||||||
|
@@ -408,7 +408,7 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
if (Optimizations.UseGfni)
|
if (Optimizations.UseGfni)
|
||||||
{
|
{
|
||||||
const long bitMatrix =
|
const long BitMatrix =
|
||||||
(0b10000000L << 56) |
|
(0b10000000L << 56) |
|
||||||
(0b01000000L << 48) |
|
(0b01000000L << 48) |
|
||||||
(0b00100000L << 40) |
|
(0b00100000L << 40) |
|
||||||
@@ -418,7 +418,7 @@ namespace ARMeilleure.Instructions
|
|||||||
(0b00000010L << 8) |
|
(0b00000010L << 8) |
|
||||||
(0b00000001L << 0);
|
(0b00000001L << 0);
|
||||||
|
|
||||||
Operand vBitMatrix = X86GetAllElements(context, bitMatrix);
|
Operand vBitMatrix = X86GetAllElements(context, BitMatrix);
|
||||||
|
|
||||||
Operand res = context.AddIntrinsic(Intrinsic.X86Gf2p8affineqb, GetVec(op.Rn), vBitMatrix, Const(0));
|
Operand res = context.AddIntrinsic(Intrinsic.X86Gf2p8affineqb, GetVec(op.Rn), vBitMatrix, Const(0));
|
||||||
|
|
||||||
@@ -469,12 +469,12 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
Operand n = GetVec(op.Rn);
|
Operand n = GetVec(op.Rn);
|
||||||
|
|
||||||
const long maskE0 = 06L << 56 | 07L << 48 | 04L << 40 | 05L << 32 | 02L << 24 | 03L << 16 | 00L << 8 | 01L << 0;
|
const long MaskE0 = 06L << 56 | 07L << 48 | 04L << 40 | 05L << 32 | 02L << 24 | 03L << 16 | 00L << 8 | 01L << 0;
|
||||||
const long maskE1 = 14L << 56 | 15L << 48 | 12L << 40 | 13L << 32 | 10L << 24 | 11L << 16 | 08L << 8 | 09L << 0;
|
const long MaskE1 = 14L << 56 | 15L << 48 | 12L << 40 | 13L << 32 | 10L << 24 | 11L << 16 | 08L << 8 | 09L << 0;
|
||||||
|
|
||||||
Operand mask = X86GetScalar(context, maskE0);
|
Operand mask = X86GetScalar(context, MaskE0);
|
||||||
|
|
||||||
mask = EmitVectorInsert(context, mask, Const(maskE1), 1, 3);
|
mask = EmitVectorInsert(context, mask, Const(MaskE1), 1, 3);
|
||||||
|
|
||||||
Operand res = context.AddIntrinsic(Intrinsic.X86Pshufb, n, mask);
|
Operand res = context.AddIntrinsic(Intrinsic.X86Pshufb, n, mask);
|
||||||
|
|
||||||
@@ -503,21 +503,21 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
if (op.Size == 0)
|
if (op.Size == 0)
|
||||||
{
|
{
|
||||||
const long maskE0 = 04L << 56 | 05L << 48 | 06L << 40 | 07L << 32 | 00L << 24 | 01L << 16 | 02L << 8 | 03L << 0;
|
const long MaskE0 = 04L << 56 | 05L << 48 | 06L << 40 | 07L << 32 | 00L << 24 | 01L << 16 | 02L << 8 | 03L << 0;
|
||||||
const long maskE1 = 12L << 56 | 13L << 48 | 14L << 40 | 15L << 32 | 08L << 24 | 09L << 16 | 10L << 8 | 11L << 0;
|
const long MaskE1 = 12L << 56 | 13L << 48 | 14L << 40 | 15L << 32 | 08L << 24 | 09L << 16 | 10L << 8 | 11L << 0;
|
||||||
|
|
||||||
mask = X86GetScalar(context, maskE0);
|
mask = X86GetScalar(context, MaskE0);
|
||||||
|
|
||||||
mask = EmitVectorInsert(context, mask, Const(maskE1), 1, 3);
|
mask = EmitVectorInsert(context, mask, Const(MaskE1), 1, 3);
|
||||||
}
|
}
|
||||||
else /* if (op.Size == 1) */
|
else /* if (op.Size == 1) */
|
||||||
{
|
{
|
||||||
const long maskE0 = 05L << 56 | 04L << 48 | 07L << 40 | 06L << 32 | 01L << 24 | 00L << 16 | 03L << 8 | 02L << 0;
|
const long MaskE0 = 05L << 56 | 04L << 48 | 07L << 40 | 06L << 32 | 01L << 24 | 00L << 16 | 03L << 8 | 02L << 0;
|
||||||
const long maskE1 = 13L << 56 | 12L << 48 | 15L << 40 | 14L << 32 | 09L << 24 | 08L << 16 | 11L << 8 | 10L << 0;
|
const long MaskE1 = 13L << 56 | 12L << 48 | 15L << 40 | 14L << 32 | 09L << 24 | 08L << 16 | 11L << 8 | 10L << 0;
|
||||||
|
|
||||||
mask = X86GetScalar(context, maskE0);
|
mask = X86GetScalar(context, MaskE0);
|
||||||
|
|
||||||
mask = EmitVectorInsert(context, mask, Const(maskE1), 1, 3);
|
mask = EmitVectorInsert(context, mask, Const(MaskE1), 1, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
Operand res = context.AddIntrinsic(Intrinsic.X86Pshufb, n, mask);
|
Operand res = context.AddIntrinsic(Intrinsic.X86Pshufb, n, mask);
|
||||||
@@ -547,30 +547,30 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
if (op.Size == 0)
|
if (op.Size == 0)
|
||||||
{
|
{
|
||||||
const long maskE0 = 00L << 56 | 01L << 48 | 02L << 40 | 03L << 32 | 04L << 24 | 05L << 16 | 06L << 8 | 07L << 0;
|
const long MaskE0 = 00L << 56 | 01L << 48 | 02L << 40 | 03L << 32 | 04L << 24 | 05L << 16 | 06L << 8 | 07L << 0;
|
||||||
const long maskE1 = 08L << 56 | 09L << 48 | 10L << 40 | 11L << 32 | 12L << 24 | 13L << 16 | 14L << 8 | 15L << 0;
|
const long MaskE1 = 08L << 56 | 09L << 48 | 10L << 40 | 11L << 32 | 12L << 24 | 13L << 16 | 14L << 8 | 15L << 0;
|
||||||
|
|
||||||
mask = X86GetScalar(context, maskE0);
|
mask = X86GetScalar(context, MaskE0);
|
||||||
|
|
||||||
mask = EmitVectorInsert(context, mask, Const(maskE1), 1, 3);
|
mask = EmitVectorInsert(context, mask, Const(MaskE1), 1, 3);
|
||||||
}
|
}
|
||||||
else if (op.Size == 1)
|
else if (op.Size == 1)
|
||||||
{
|
{
|
||||||
const long maskE0 = 01L << 56 | 00L << 48 | 03L << 40 | 02L << 32 | 05L << 24 | 04L << 16 | 07L << 8 | 06L << 0;
|
const long MaskE0 = 01L << 56 | 00L << 48 | 03L << 40 | 02L << 32 | 05L << 24 | 04L << 16 | 07L << 8 | 06L << 0;
|
||||||
const long maskE1 = 09L << 56 | 08L << 48 | 11L << 40 | 10L << 32 | 13L << 24 | 12L << 16 | 15L << 8 | 14L << 0;
|
const long MaskE1 = 09L << 56 | 08L << 48 | 11L << 40 | 10L << 32 | 13L << 24 | 12L << 16 | 15L << 8 | 14L << 0;
|
||||||
|
|
||||||
mask = X86GetScalar(context, maskE0);
|
mask = X86GetScalar(context, MaskE0);
|
||||||
|
|
||||||
mask = EmitVectorInsert(context, mask, Const(maskE1), 1, 3);
|
mask = EmitVectorInsert(context, mask, Const(MaskE1), 1, 3);
|
||||||
}
|
}
|
||||||
else /* if (op.Size == 2) */
|
else /* if (op.Size == 2) */
|
||||||
{
|
{
|
||||||
const long maskE0 = 03L << 56 | 02L << 48 | 01L << 40 | 00L << 32 | 07L << 24 | 06L << 16 | 05L << 8 | 04L << 0;
|
const long MaskE0 = 03L << 56 | 02L << 48 | 01L << 40 | 00L << 32 | 07L << 24 | 06L << 16 | 05L << 8 | 04L << 0;
|
||||||
const long maskE1 = 11L << 56 | 10L << 48 | 09L << 40 | 08L << 32 | 15L << 24 | 14L << 16 | 13L << 8 | 12L << 0;
|
const long MaskE1 = 11L << 56 | 10L << 48 | 09L << 40 | 08L << 32 | 15L << 24 | 14L << 16 | 13L << 8 | 12L << 0;
|
||||||
|
|
||||||
mask = X86GetScalar(context, maskE0);
|
mask = X86GetScalar(context, MaskE0);
|
||||||
|
|
||||||
mask = EmitVectorInsert(context, mask, Const(maskE1), 1, 3);
|
mask = EmitVectorInsert(context, mask, Const(MaskE1), 1, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
Operand res = context.AddIntrinsic(Intrinsic.X86Pshufb, n, mask);
|
Operand res = context.AddIntrinsic(Intrinsic.X86Pshufb, n, mask);
|
||||||
|
@@ -175,10 +175,10 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
public static ushort FPRoundCv(double real, ExecutionContext context)
|
public static ushort FPRoundCv(double real, ExecutionContext context)
|
||||||
{
|
{
|
||||||
const int minimumExp = -14;
|
const int MinimumExp = -14;
|
||||||
|
|
||||||
const int e = 5;
|
const int E = 5;
|
||||||
const int f = 10;
|
const int F = 10;
|
||||||
|
|
||||||
bool sign;
|
bool sign;
|
||||||
double mantissa;
|
double mantissa;
|
||||||
@@ -208,15 +208,15 @@ namespace ARMeilleure.Instructions
|
|||||||
exponent++;
|
exponent++;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint biasedExp = (uint)Math.Max(exponent - minimumExp + 1, 0);
|
uint biasedExp = (uint)Math.Max(exponent - MinimumExp + 1, 0);
|
||||||
|
|
||||||
if (biasedExp == 0u)
|
if (biasedExp == 0u)
|
||||||
{
|
{
|
||||||
mantissa /= Math.Pow(2d, minimumExp - exponent);
|
mantissa /= Math.Pow(2d, MinimumExp - exponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint intMant = (uint)Math.Floor(mantissa * Math.Pow(2d, f));
|
uint intMant = (uint)Math.Floor(mantissa * Math.Pow(2d, F));
|
||||||
double error = mantissa * Math.Pow(2d, f) - (double)intMant;
|
double error = mantissa * Math.Pow(2d, F) - (double)intMant;
|
||||||
|
|
||||||
if (biasedExp == 0u && (error != 0d || (context.Fpcr & FPCR.Ufe) != 0))
|
if (biasedExp == 0u && (error != 0d || (context.Fpcr & FPCR.Ufe) != 0))
|
||||||
{
|
{
|
||||||
@@ -256,12 +256,12 @@ namespace ARMeilleure.Instructions
|
|||||||
{
|
{
|
||||||
intMant++;
|
intMant++;
|
||||||
|
|
||||||
if (intMant == 1u << f)
|
if (intMant == 1u << F)
|
||||||
{
|
{
|
||||||
biasedExp = 1u;
|
biasedExp = 1u;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (intMant == 1u << (f + 1))
|
if (intMant == 1u << (F + 1))
|
||||||
{
|
{
|
||||||
biasedExp++;
|
biasedExp++;
|
||||||
intMant >>= 1;
|
intMant >>= 1;
|
||||||
@@ -272,7 +272,7 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
if ((context.Fpcr & FPCR.Ahp) == 0)
|
if ((context.Fpcr & FPCR.Ahp) == 0)
|
||||||
{
|
{
|
||||||
if (biasedExp >= (1u << e) - 1u)
|
if (biasedExp >= (1u << E) - 1u)
|
||||||
{
|
{
|
||||||
resultBits = overflowToInf ? FPInfinity(sign) : FPMaxNormal(sign);
|
resultBits = overflowToInf ? FPInfinity(sign) : FPMaxNormal(sign);
|
||||||
|
|
||||||
@@ -287,7 +287,7 @@ namespace ARMeilleure.Instructions
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (biasedExp >= 1u << e)
|
if (biasedExp >= 1u << E)
|
||||||
{
|
{
|
||||||
resultBits = (ushort)((sign ? 1u : 0u) << 15 | 0x7FFFu);
|
resultBits = (ushort)((sign ? 1u : 0u) << 15 | 0x7FFFu);
|
||||||
|
|
||||||
@@ -354,10 +354,10 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
private static float FPRoundCv(double real, ExecutionContext context)
|
private static float FPRoundCv(double real, ExecutionContext context)
|
||||||
{
|
{
|
||||||
const int minimumExp = -126;
|
const int MinimumExp = -126;
|
||||||
|
|
||||||
const int e = 8;
|
const int E = 8;
|
||||||
const int f = 23;
|
const int F = 23;
|
||||||
|
|
||||||
bool sign;
|
bool sign;
|
||||||
double mantissa;
|
double mantissa;
|
||||||
@@ -387,22 +387,22 @@ namespace ARMeilleure.Instructions
|
|||||||
exponent++;
|
exponent++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((context.Fpcr & FPCR.Fz) != 0 && exponent < minimumExp)
|
if ((context.Fpcr & FPCR.Fz) != 0 && exponent < MinimumExp)
|
||||||
{
|
{
|
||||||
context.Fpsr |= FPSR.Ufc;
|
context.Fpsr |= FPSR.Ufc;
|
||||||
|
|
||||||
return SoftFloat32.FPZero(sign);
|
return SoftFloat32.FPZero(sign);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint biasedExp = (uint)Math.Max(exponent - minimumExp + 1, 0);
|
uint biasedExp = (uint)Math.Max(exponent - MinimumExp + 1, 0);
|
||||||
|
|
||||||
if (biasedExp == 0u)
|
if (biasedExp == 0u)
|
||||||
{
|
{
|
||||||
mantissa /= Math.Pow(2d, minimumExp - exponent);
|
mantissa /= Math.Pow(2d, MinimumExp - exponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint intMant = (uint)Math.Floor(mantissa * Math.Pow(2d, f));
|
uint intMant = (uint)Math.Floor(mantissa * Math.Pow(2d, F));
|
||||||
double error = mantissa * Math.Pow(2d, f) - (double)intMant;
|
double error = mantissa * Math.Pow(2d, F) - (double)intMant;
|
||||||
|
|
||||||
if (biasedExp == 0u && (error != 0d || (context.Fpcr & FPCR.Ufe) != 0))
|
if (biasedExp == 0u && (error != 0d || (context.Fpcr & FPCR.Ufe) != 0))
|
||||||
{
|
{
|
||||||
@@ -442,12 +442,12 @@ namespace ARMeilleure.Instructions
|
|||||||
{
|
{
|
||||||
intMant++;
|
intMant++;
|
||||||
|
|
||||||
if (intMant == 1u << f)
|
if (intMant == 1u << F)
|
||||||
{
|
{
|
||||||
biasedExp = 1u;
|
biasedExp = 1u;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (intMant == 1u << (f + 1))
|
if (intMant == 1u << (F + 1))
|
||||||
{
|
{
|
||||||
biasedExp++;
|
biasedExp++;
|
||||||
intMant >>= 1;
|
intMant >>= 1;
|
||||||
@@ -456,7 +456,7 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
float result;
|
float result;
|
||||||
|
|
||||||
if (biasedExp >= (1u << e) - 1u)
|
if (biasedExp >= (1u << E) - 1u)
|
||||||
{
|
{
|
||||||
result = overflowToInf ? SoftFloat32.FPInfinity(sign) : SoftFloat32.FPMaxNormal(sign);
|
result = overflowToInf ? SoftFloat32.FPInfinity(sign) : SoftFloat32.FPMaxNormal(sign);
|
||||||
|
|
||||||
@@ -529,10 +529,10 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
private static double FPRoundCv(double real, ExecutionContext context)
|
private static double FPRoundCv(double real, ExecutionContext context)
|
||||||
{
|
{
|
||||||
const int minimumExp = -1022;
|
const int MinimumExp = -1022;
|
||||||
|
|
||||||
const int e = 11;
|
const int E = 11;
|
||||||
const int f = 52;
|
const int F = 52;
|
||||||
|
|
||||||
bool sign;
|
bool sign;
|
||||||
double mantissa;
|
double mantissa;
|
||||||
@@ -562,22 +562,22 @@ namespace ARMeilleure.Instructions
|
|||||||
exponent++;
|
exponent++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((context.Fpcr & FPCR.Fz) != 0 && exponent < minimumExp)
|
if ((context.Fpcr & FPCR.Fz) != 0 && exponent < MinimumExp)
|
||||||
{
|
{
|
||||||
context.Fpsr |= FPSR.Ufc;
|
context.Fpsr |= FPSR.Ufc;
|
||||||
|
|
||||||
return SoftFloat64.FPZero(sign);
|
return SoftFloat64.FPZero(sign);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint biasedExp = (uint)Math.Max(exponent - minimumExp + 1, 0);
|
uint biasedExp = (uint)Math.Max(exponent - MinimumExp + 1, 0);
|
||||||
|
|
||||||
if (biasedExp == 0u)
|
if (biasedExp == 0u)
|
||||||
{
|
{
|
||||||
mantissa /= Math.Pow(2d, minimumExp - exponent);
|
mantissa /= Math.Pow(2d, MinimumExp - exponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
ulong intMant = (ulong)Math.Floor(mantissa * Math.Pow(2d, f));
|
ulong intMant = (ulong)Math.Floor(mantissa * Math.Pow(2d, F));
|
||||||
double error = mantissa * Math.Pow(2d, f) - (double)intMant;
|
double error = mantissa * Math.Pow(2d, F) - (double)intMant;
|
||||||
|
|
||||||
if (biasedExp == 0u && (error != 0d || (context.Fpcr & FPCR.Ufe) != 0))
|
if (biasedExp == 0u && (error != 0d || (context.Fpcr & FPCR.Ufe) != 0))
|
||||||
{
|
{
|
||||||
@@ -617,12 +617,12 @@ namespace ARMeilleure.Instructions
|
|||||||
{
|
{
|
||||||
intMant++;
|
intMant++;
|
||||||
|
|
||||||
if (intMant == 1ul << f)
|
if (intMant == 1ul << F)
|
||||||
{
|
{
|
||||||
biasedExp = 1u;
|
biasedExp = 1u;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (intMant == 1ul << (f + 1))
|
if (intMant == 1ul << (F + 1))
|
||||||
{
|
{
|
||||||
biasedExp++;
|
biasedExp++;
|
||||||
intMant >>= 1;
|
intMant >>= 1;
|
||||||
@@ -631,7 +631,7 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
double result;
|
double result;
|
||||||
|
|
||||||
if (biasedExp >= (1u << e) - 1u)
|
if (biasedExp >= (1u << E) - 1u)
|
||||||
{
|
{
|
||||||
result = overflowToInf ? SoftFloat64.FPInfinity(sign) : SoftFloat64.FPMaxNormal(sign);
|
result = overflowToInf ? SoftFloat64.FPInfinity(sign) : SoftFloat64.FPMaxNormal(sign);
|
||||||
|
|
||||||
|
@@ -5,7 +5,6 @@ using ARMeilleure.Translation.Cache;
|
|||||||
using System;
|
using System;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
|
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
|
||||||
|
|
||||||
namespace ARMeilleure.Signal
|
namespace ARMeilleure.Signal
|
||||||
@@ -261,20 +260,20 @@ namespace ARMeilleure.Signal
|
|||||||
{
|
{
|
||||||
if (OperatingSystem.IsMacOS())
|
if (OperatingSystem.IsMacOS())
|
||||||
{
|
{
|
||||||
const ulong mcontextOffset = 48; // uc_mcontext
|
const ulong McontextOffset = 48; // uc_mcontext
|
||||||
Operand ctxPtr = context.Load(OperandType.I64, context.Add(ucontextPtr, Const(mcontextOffset)));
|
Operand ctxPtr = context.Load(OperandType.I64, context.Add(ucontextPtr, Const(McontextOffset)));
|
||||||
|
|
||||||
if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
|
if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
|
||||||
{
|
{
|
||||||
const ulong esrOffset = 8; // __es.__esr
|
const ulong EsrOffset = 8; // __es.__esr
|
||||||
Operand esr = context.Load(OperandType.I64, context.Add(ctxPtr, Const(esrOffset)));
|
Operand esr = context.Load(OperandType.I64, context.Add(ctxPtr, Const(EsrOffset)));
|
||||||
return context.BitwiseAnd(esr, Const(0x40ul));
|
return context.BitwiseAnd(esr, Const(0x40ul));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RuntimeInformation.ProcessArchitecture == Architecture.X64)
|
if (RuntimeInformation.ProcessArchitecture == Architecture.X64)
|
||||||
{
|
{
|
||||||
const ulong errOffset = 4; // __es.__err
|
const ulong ErrOffset = 4; // __es.__err
|
||||||
Operand err = context.Load(OperandType.I64, context.Add(ctxPtr, Const(errOffset)));
|
Operand err = context.Load(OperandType.I64, context.Add(ctxPtr, Const(ErrOffset)));
|
||||||
return context.BitwiseAnd(err, Const(2ul));
|
return context.BitwiseAnd(err, Const(2ul));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -287,10 +286,10 @@ namespace ARMeilleure.Signal
|
|||||||
Operand loopLabel = Label();
|
Operand loopLabel = Label();
|
||||||
Operand successLabel = Label();
|
Operand successLabel = Label();
|
||||||
|
|
||||||
const ulong auxOffset = 464; // uc_mcontext.__reserved
|
const ulong AuxOffset = 464; // uc_mcontext.__reserved
|
||||||
const uint esrMagic = 0x45535201;
|
const uint EsrMagic = 0x45535201;
|
||||||
|
|
||||||
context.Copy(auxPtr, context.Add(ucontextPtr, Const(auxOffset)));
|
context.Copy(auxPtr, context.Add(ucontextPtr, Const(AuxOffset)));
|
||||||
|
|
||||||
context.MarkLabel(loopLabel);
|
context.MarkLabel(loopLabel);
|
||||||
|
|
||||||
@@ -299,7 +298,7 @@ namespace ARMeilleure.Signal
|
|||||||
// _aarch64_ctx::size
|
// _aarch64_ctx::size
|
||||||
Operand size = context.Load(OperandType.I32, context.Add(auxPtr, Const(4ul)));
|
Operand size = context.Load(OperandType.I32, context.Add(auxPtr, Const(4ul)));
|
||||||
|
|
||||||
context.BranchIf(successLabel, magic, Const(esrMagic), Comparison.Equal);
|
context.BranchIf(successLabel, magic, Const(EsrMagic), Comparison.Equal);
|
||||||
|
|
||||||
context.Copy(auxPtr, context.Add(auxPtr, context.ZeroExtend32(OperandType.I64, size)));
|
context.Copy(auxPtr, context.Add(auxPtr, context.ZeroExtend32(OperandType.I64, size)));
|
||||||
|
|
||||||
@@ -314,8 +313,8 @@ namespace ARMeilleure.Signal
|
|||||||
|
|
||||||
if (RuntimeInformation.ProcessArchitecture == Architecture.X64)
|
if (RuntimeInformation.ProcessArchitecture == Architecture.X64)
|
||||||
{
|
{
|
||||||
const int errOffset = 192; // uc_mcontext.gregs[REG_ERR]
|
const int ErrOffset = 192; // uc_mcontext.gregs[REG_ERR]
|
||||||
Operand err = context.Load(OperandType.I64, context.Add(ucontextPtr, Const(errOffset)));
|
Operand err = context.Load(OperandType.I64, context.Add(ucontextPtr, Const(ErrOffset)));
|
||||||
return context.BitwiseAnd(err, Const(2ul));
|
return context.BitwiseAnd(err, Const(2ul));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -880,7 +880,7 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
|
|
||||||
private void ReportProgress(object state)
|
private void ReportProgress(object state)
|
||||||
{
|
{
|
||||||
const int refreshRate = 50; // ms.
|
const int RefreshRate = 50; // ms.
|
||||||
|
|
||||||
AutoResetEvent endEvent = (AutoResetEvent)state;
|
AutoResetEvent endEvent = (AutoResetEvent)state;
|
||||||
|
|
||||||
@@ -896,7 +896,7 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
count = newCount;
|
count = newCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (!endEvent.WaitOne(refreshRate));
|
while (!endEvent.WaitOne(RefreshRate));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Hash128 ComputeHash(IMemoryManager memory, ulong address, ulong guestSize)
|
public static Hash128 ComputeHash(IMemoryManager memory, ulong address, ulong guestSize)
|
||||||
|
@@ -43,7 +43,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
|
|
||||||
public void Process(CommandList context)
|
public void Process(CommandList context)
|
||||||
{
|
{
|
||||||
const int targetChannelCount = 2;
|
const int TargetChannelCount = 2;
|
||||||
|
|
||||||
ulong currentOffset = CurrentOffset;
|
ulong currentOffset = CurrentOffset;
|
||||||
|
|
||||||
@@ -59,10 +59,10 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
|
|
||||||
for (int y = 0; y < context.SampleCount; y++)
|
for (int y = 0; y < context.SampleCount; y++)
|
||||||
{
|
{
|
||||||
context.MemoryManager.Write(targetOffset + (ulong)y * targetChannelCount, PcmHelper.Saturate(inputBuffer[y]));
|
context.MemoryManager.Write(targetOffset + (ulong)y * TargetChannelCount, PcmHelper.Saturate(inputBuffer[y]));
|
||||||
}
|
}
|
||||||
|
|
||||||
currentOffset += context.SampleCount * targetChannelCount;
|
currentOffset += context.SampleCount * TargetChannelCount;
|
||||||
|
|
||||||
if (currentOffset >= CircularBufferSize)
|
if (currentOffset >= CircularBufferSize)
|
||||||
{
|
{
|
||||||
|
@@ -56,7 +56,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||||
private unsafe void ProcessDelayMono(ref DelayState state, float* outputBuffer, float* inputBuffer, uint sampleCount)
|
private unsafe void ProcessDelayMono(ref DelayState state, float* outputBuffer, float* inputBuffer, uint sampleCount)
|
||||||
{
|
{
|
||||||
const ushort channelCount = 1;
|
const ushort ChannelCount = 1;
|
||||||
|
|
||||||
float feedbackGain = FixedPointHelper.ToFloat(Parameter.FeedbackGain, FixedPointPrecision);
|
float feedbackGain = FixedPointHelper.ToFloat(Parameter.FeedbackGain, FixedPointPrecision);
|
||||||
float inGain = FixedPointHelper.ToFloat(Parameter.InGain, FixedPointPrecision);
|
float inGain = FixedPointHelper.ToFloat(Parameter.InGain, FixedPointPrecision);
|
||||||
@@ -70,7 +70,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
|
|
||||||
float temp = input * inGain + delayLineValue * feedbackGain;
|
float temp = input * inGain + delayLineValue * feedbackGain;
|
||||||
|
|
||||||
state.UpdateLowPassFilter(ref temp, channelCount);
|
state.UpdateLowPassFilter(ref temp, ChannelCount);
|
||||||
|
|
||||||
outputBuffer[i] = (input * dryGain + delayLineValue * outGain) / 64;
|
outputBuffer[i] = (input * dryGain + delayLineValue * outGain) / 64;
|
||||||
}
|
}
|
||||||
@@ -79,7 +79,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||||
private unsafe void ProcessDelayStereo(ref DelayState state, Span<IntPtr> outputBuffers, ReadOnlySpan<IntPtr> inputBuffers, uint sampleCount)
|
private unsafe void ProcessDelayStereo(ref DelayState state, Span<IntPtr> outputBuffers, ReadOnlySpan<IntPtr> inputBuffers, uint sampleCount)
|
||||||
{
|
{
|
||||||
const ushort channelCount = 2;
|
const ushort ChannelCount = 2;
|
||||||
|
|
||||||
float delayFeedbackBaseGain = state.DelayFeedbackBaseGain;
|
float delayFeedbackBaseGain = state.DelayFeedbackBaseGain;
|
||||||
float delayFeedbackCrossGain = state.DelayFeedbackCrossGain;
|
float delayFeedbackCrossGain = state.DelayFeedbackCrossGain;
|
||||||
@@ -106,7 +106,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
|
|
||||||
Vector2 temp = MatrixHelper.Transform(ref delayLineValues, ref delayFeedback) + channelInput * inGain;
|
Vector2 temp = MatrixHelper.Transform(ref delayLineValues, ref delayFeedback) + channelInput * inGain;
|
||||||
|
|
||||||
state.UpdateLowPassFilter(ref Unsafe.As<Vector2, float>(ref temp), channelCount);
|
state.UpdateLowPassFilter(ref Unsafe.As<Vector2, float>(ref temp), ChannelCount);
|
||||||
|
|
||||||
*((float*)outputBuffers[0] + i) = (channelInput.X * dryGain + delayLineValues.X * outGain) / 64;
|
*((float*)outputBuffers[0] + i) = (channelInput.X * dryGain + delayLineValues.X * outGain) / 64;
|
||||||
*((float*)outputBuffers[1] + i) = (channelInput.Y * dryGain + delayLineValues.Y * outGain) / 64;
|
*((float*)outputBuffers[1] + i) = (channelInput.Y * dryGain + delayLineValues.Y * outGain) / 64;
|
||||||
@@ -116,7 +116,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||||
private unsafe void ProcessDelayQuadraphonic(ref DelayState state, Span<IntPtr> outputBuffers, ReadOnlySpan<IntPtr> inputBuffers, uint sampleCount)
|
private unsafe void ProcessDelayQuadraphonic(ref DelayState state, Span<IntPtr> outputBuffers, ReadOnlySpan<IntPtr> inputBuffers, uint sampleCount)
|
||||||
{
|
{
|
||||||
const ushort channelCount = 4;
|
const ushort ChannelCount = 4;
|
||||||
|
|
||||||
float delayFeedbackBaseGain = state.DelayFeedbackBaseGain;
|
float delayFeedbackBaseGain = state.DelayFeedbackBaseGain;
|
||||||
float delayFeedbackCrossGain = state.DelayFeedbackCrossGain;
|
float delayFeedbackCrossGain = state.DelayFeedbackCrossGain;
|
||||||
@@ -150,7 +150,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
|
|
||||||
Vector4 temp = MatrixHelper.Transform(ref delayLineValues, ref delayFeedback) + channelInput * inGain;
|
Vector4 temp = MatrixHelper.Transform(ref delayLineValues, ref delayFeedback) + channelInput * inGain;
|
||||||
|
|
||||||
state.UpdateLowPassFilter(ref Unsafe.As<Vector4, float>(ref temp), channelCount);
|
state.UpdateLowPassFilter(ref Unsafe.As<Vector4, float>(ref temp), ChannelCount);
|
||||||
|
|
||||||
*((float*)outputBuffers[0] + i) = (channelInput.X * dryGain + delayLineValues.X * outGain) / 64;
|
*((float*)outputBuffers[0] + i) = (channelInput.X * dryGain + delayLineValues.X * outGain) / 64;
|
||||||
*((float*)outputBuffers[1] + i) = (channelInput.Y * dryGain + delayLineValues.Y * outGain) / 64;
|
*((float*)outputBuffers[1] + i) = (channelInput.Y * dryGain + delayLineValues.Y * outGain) / 64;
|
||||||
@@ -162,7 +162,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||||
private unsafe void ProcessDelaySurround(ref DelayState state, Span<IntPtr> outputBuffers, ReadOnlySpan<IntPtr> inputBuffers, uint sampleCount)
|
private unsafe void ProcessDelaySurround(ref DelayState state, Span<IntPtr> outputBuffers, ReadOnlySpan<IntPtr> inputBuffers, uint sampleCount)
|
||||||
{
|
{
|
||||||
const ushort channelCount = 6;
|
const ushort ChannelCount = 6;
|
||||||
|
|
||||||
float feedbackGain = FixedPointHelper.ToFloat(Parameter.FeedbackGain, FixedPointPrecision);
|
float feedbackGain = FixedPointHelper.ToFloat(Parameter.FeedbackGain, FixedPointPrecision);
|
||||||
float delayFeedbackBaseGain = state.DelayFeedbackBaseGain;
|
float delayFeedbackBaseGain = state.DelayFeedbackBaseGain;
|
||||||
@@ -202,7 +202,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
|
|
||||||
Vector6 temp = MatrixHelper.Transform(ref delayLineValues, ref delayFeedback) + channelInput * inGain;
|
Vector6 temp = MatrixHelper.Transform(ref delayLineValues, ref delayFeedback) + channelInput * inGain;
|
||||||
|
|
||||||
state.UpdateLowPassFilter(ref Unsafe.As<Vector6, float>(ref temp), channelCount);
|
state.UpdateLowPassFilter(ref Unsafe.As<Vector6, float>(ref temp), ChannelCount);
|
||||||
|
|
||||||
*((float*)outputBuffers[0] + i) = (channelInput.X * dryGain + delayLineValues.X * outGain) / 64;
|
*((float*)outputBuffers[0] + i) = (channelInput.X * dryGain + delayLineValues.X * outGain) / 64;
|
||||||
*((float*)outputBuffers[1] + i) = (channelInput.Y * dryGain + delayLineValues.Y * outGain) / 64;
|
*((float*)outputBuffers[1] + i) = (channelInput.Y * dryGain + delayLineValues.Y * outGain) / 64;
|
||||||
|
@@ -65,7 +65,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
int channelCount = (int)device.GetChannelCount();
|
int channelCount = (int)device.GetChannelCount();
|
||||||
uint bufferCount = Math.Min(device.GetChannelCount(), InputCount);
|
uint bufferCount = Math.Min(device.GetChannelCount(), InputCount);
|
||||||
|
|
||||||
const int sampleCount = Constants.TargetSampleCount;
|
const int SampleCount = Constants.TargetSampleCount;
|
||||||
|
|
||||||
uint inputCount;
|
uint inputCount;
|
||||||
|
|
||||||
@@ -79,13 +79,13 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
inputCount = bufferCount;
|
inputCount = bufferCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
short[] outputBuffer = new short[inputCount * sampleCount];
|
short[] outputBuffer = new short[inputCount * SampleCount];
|
||||||
|
|
||||||
for (int i = 0; i < bufferCount; i++)
|
for (int i = 0; i < bufferCount; i++)
|
||||||
{
|
{
|
||||||
ReadOnlySpan<float> inputBuffer = GetBuffer(InputBufferIndices[i], sampleCount);
|
ReadOnlySpan<float> inputBuffer = GetBuffer(InputBufferIndices[i], SampleCount);
|
||||||
|
|
||||||
for (int j = 0; j < sampleCount; j++)
|
for (int j = 0; j < SampleCount; j++)
|
||||||
{
|
{
|
||||||
outputBuffer[i + j * channelCount] = PcmHelper.Saturate(inputBuffer[j]);
|
outputBuffer[i + j * channelCount] = PcmHelper.Saturate(inputBuffer[j]);
|
||||||
}
|
}
|
||||||
|
@@ -96,7 +96,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
|
|
||||||
private unsafe void ProcessReverb3dGeneric(ref Reverb3dState state, ReadOnlySpan<IntPtr> outputBuffers, ReadOnlySpan<IntPtr> inputBuffers, uint sampleCount, ReadOnlySpan<int> outputEarlyIndicesTable, ReadOnlySpan<int> targetEarlyDelayLineIndicesTable, ReadOnlySpan<int> targetOutputFeedbackIndicesTable)
|
private unsafe void ProcessReverb3dGeneric(ref Reverb3dState state, ReadOnlySpan<IntPtr> outputBuffers, ReadOnlySpan<IntPtr> inputBuffers, uint sampleCount, ReadOnlySpan<int> outputEarlyIndicesTable, ReadOnlySpan<int> targetEarlyDelayLineIndicesTable, ReadOnlySpan<int> targetOutputFeedbackIndicesTable)
|
||||||
{
|
{
|
||||||
const int delayLineSampleIndexOffset = 1;
|
const int DelayLineSampleIndexOffset = 1;
|
||||||
|
|
||||||
bool isMono = Parameter.ChannelCount == 1;
|
bool isMono = Parameter.ChannelCount == 1;
|
||||||
bool isSurround = Parameter.ChannelCount == 6;
|
bool isSurround = Parameter.ChannelCount == 6;
|
||||||
@@ -111,14 +111,14 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||||||
{
|
{
|
||||||
outputValues.Fill(0);
|
outputValues.Fill(0);
|
||||||
|
|
||||||
float tapOut = state.PreDelayLine.TapUnsafe(state.ReflectionDelayTime, delayLineSampleIndexOffset);
|
float tapOut = state.PreDelayLine.TapUnsafe(state.ReflectionDelayTime, DelayLineSampleIndexOffset);
|
||||||
|
|
||||||
for (int i = 0; i < targetEarlyDelayLineIndicesTable.Length; i++)
|
for (int i = 0; i < targetEarlyDelayLineIndicesTable.Length; i++)
|
||||||
{
|
{
|
||||||
int earlyDelayIndex = targetEarlyDelayLineIndicesTable[i];
|
int earlyDelayIndex = targetEarlyDelayLineIndicesTable[i];
|
||||||
int outputIndex = outputEarlyIndicesTable[earlyDelayIndex];
|
int outputIndex = outputEarlyIndicesTable[earlyDelayIndex];
|
||||||
|
|
||||||
float tempTapOut = state.PreDelayLine.TapUnsafe(state.EarlyDelayTime[earlyDelayIndex], delayLineSampleIndexOffset);
|
float tempTapOut = state.PreDelayLine.TapUnsafe(state.EarlyDelayTime[earlyDelayIndex], DelayLineSampleIndexOffset);
|
||||||
|
|
||||||
outputValues[outputIndex] += tempTapOut * state.EarlyGain[earlyDelayIndex];
|
outputValues[outputIndex] += tempTapOut * state.EarlyGain[earlyDelayIndex];
|
||||||
}
|
}
|
||||||
|
@@ -44,9 +44,9 @@ namespace Ryujinx.Audio.Renderer.Dsp
|
|||||||
|
|
||||||
public static void ProcessWaveBuffers(IVirtualMemoryManager memoryManager, Span<float> outputBuffer, ref WaveBufferInformation info, Span<WaveBuffer> wavebuffers, ref VoiceUpdateState voiceState, uint targetSampleRate, int sampleCount)
|
public static void ProcessWaveBuffers(IVirtualMemoryManager memoryManager, Span<float> outputBuffer, ref WaveBufferInformation info, Span<WaveBuffer> wavebuffers, ref VoiceUpdateState voiceState, uint targetSampleRate, int sampleCount)
|
||||||
{
|
{
|
||||||
const int tempBufferSize = 0x3F00;
|
const int TempBufferSize = 0x3F00;
|
||||||
|
|
||||||
Span<short> tempBuffer = stackalloc short[tempBufferSize];
|
Span<short> tempBuffer = stackalloc short[TempBufferSize];
|
||||||
|
|
||||||
float sampleRateRatio = (float)info.SourceSampleRate / targetSampleRate * info.Pitch;
|
float sampleRateRatio = (float)info.SourceSampleRate / targetSampleRate * info.Pitch;
|
||||||
|
|
||||||
@@ -60,11 +60,11 @@ namespace Ryujinx.Audio.Renderer.Dsp
|
|||||||
|
|
||||||
int totalNeededSize = (int)MathF.Truncate(fraction + sampleRateRatio * sampleCount);
|
int totalNeededSize = (int)MathF.Truncate(fraction + sampleRateRatio * sampleCount);
|
||||||
|
|
||||||
if (totalNeededSize + pitchMaxLength <= tempBufferSize && totalNeededSize >= 0)
|
if (totalNeededSize + pitchMaxLength <= TempBufferSize && totalNeededSize >= 0)
|
||||||
{
|
{
|
||||||
int sourceSampleCountToProcess = sampleCount;
|
int sourceSampleCountToProcess = sampleCount;
|
||||||
|
|
||||||
int maxSampleCountPerIteration = Math.Min((int)MathF.Truncate((tempBufferSize - fraction) / sampleRateRatio), sampleCount);
|
int maxSampleCountPerIteration = Math.Min((int)MathF.Truncate((TempBufferSize - fraction) / sampleRateRatio), sampleCount);
|
||||||
|
|
||||||
bool isStarving = false;
|
bool isStarving = false;
|
||||||
|
|
||||||
|
@@ -32,11 +32,11 @@ namespace Ryujinx.Audio.Renderer.Dsp
|
|||||||
|
|
||||||
float BlackmanWindow(float x)
|
float BlackmanWindow(float x)
|
||||||
{
|
{
|
||||||
const float a = 0.18f;
|
const float A = 0.18f;
|
||||||
const float a0 = 0.5f - 0.5f * a;
|
const float A0 = 0.5f - 0.5f * A;
|
||||||
const float a1 = -0.5f;
|
const float A1 = -0.5f;
|
||||||
const float a2 = 0.5f * a;
|
const float A2 = 0.5f * A;
|
||||||
return a0 + a1 * MathF.Cos(2 * MathF.PI * x) + a2 * MathF.Cos(4 * MathF.PI * x);
|
return A0 + A1 * MathF.Cos(2 * MathF.PI * x) + A2 * MathF.Cos(4 * MathF.PI * x);
|
||||||
}
|
}
|
||||||
|
|
||||||
Array20<float> result = new Array20<float>();
|
Array20<float> result = new Array20<float>();
|
||||||
|
@@ -60,7 +60,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
|
|
||||||
public uint Estimate(MixRampGroupedCommand command)
|
public uint Estimate(MixRampGroupedCommand command)
|
||||||
{
|
{
|
||||||
const float costPerSample = 7.245f;
|
const float CostPerSample = 7.245f;
|
||||||
|
|
||||||
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
|
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (uint)(_sampleCount * costPerSample * volumeCount);
|
return (uint)(_sampleCount * CostPerSample * volumeCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint Estimate(MixRampCommand command)
|
public uint Estimate(MixRampCommand command)
|
||||||
|
@@ -256,19 +256,19 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
|
|||||||
|
|
||||||
MemoryPoolUserState outputState;
|
MemoryPoolUserState outputState;
|
||||||
|
|
||||||
const uint pageSize = 0x1000;
|
const uint PageSize = 0x1000;
|
||||||
|
|
||||||
if (inputState != MemoryPoolUserState.RequestAttach && inputState != MemoryPoolUserState.RequestDetach)
|
if (inputState != MemoryPoolUserState.RequestAttach && inputState != MemoryPoolUserState.RequestDetach)
|
||||||
{
|
{
|
||||||
return UpdateResult.Success;
|
return UpdateResult.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inParameter.CpuAddress == 0 || (inParameter.CpuAddress % pageSize) != 0)
|
if (inParameter.CpuAddress == 0 || (inParameter.CpuAddress % PageSize) != 0)
|
||||||
{
|
{
|
||||||
return UpdateResult.InvalidParameter;
|
return UpdateResult.InvalidParameter;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inParameter.Size == 0 || (inParameter.Size % pageSize) != 0)
|
if (inParameter.Size == 0 || (inParameter.Size % PageSize) != 0)
|
||||||
{
|
{
|
||||||
return UpdateResult.InvalidParameter;
|
return UpdateResult.InvalidParameter;
|
||||||
}
|
}
|
||||||
|
@@ -10,8 +10,8 @@ using Ryujinx.Ava.UI.Helpers;
|
|||||||
using Ryujinx.Ava.UI.ViewModels;
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
using Ryujinx.Ava.UI.Windows;
|
using Ryujinx.Ava.UI.Windows;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Ui.App.Common;
|
|
||||||
using Ryujinx.HLE.HOS;
|
using Ryujinx.HLE.HOS;
|
||||||
|
using Ryujinx.Ui.App.Common;
|
||||||
using Ryujinx.Ui.Common.Helper;
|
using Ryujinx.Ui.Common.Helper;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@@ -40,9 +40,9 @@ namespace Ryujinx.Ava.UI.Models
|
|||||||
|
|
||||||
private string GetSizeString()
|
private string GetSizeString()
|
||||||
{
|
{
|
||||||
const int scale = 1024;
|
const int Scale = 1024;
|
||||||
string[] orders = { "GiB", "MiB", "KiB" };
|
string[] orders = { "GiB", "MiB", "KiB" };
|
||||||
long max = (long)Math.Pow(scale, orders.Length);
|
long max = (long)Math.Pow(Scale, orders.Length);
|
||||||
|
|
||||||
foreach (string order in orders)
|
foreach (string order in orders)
|
||||||
{
|
{
|
||||||
@@ -51,7 +51,7 @@ namespace Ryujinx.Ava.UI.Models
|
|||||||
return $"{decimal.Divide(Size, max):##.##} {order}";
|
return $"{decimal.Divide(Size, max):##.##} {order}";
|
||||||
}
|
}
|
||||||
|
|
||||||
max /= scale;
|
max /= Scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
return "0 KiB";
|
return "0 KiB";
|
||||||
|
@@ -1124,13 +1124,13 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
|
|
||||||
var dominantColor = IconColorPicker.GetFilteredColor(gameIconBmp).ToPixel<Bgra32>();
|
var dominantColor = IconColorPicker.GetFilteredColor(gameIconBmp).ToPixel<Bgra32>();
|
||||||
|
|
||||||
const float colorMultiple = 0.5f;
|
const float ColorMultiple = 0.5f;
|
||||||
|
|
||||||
Color progressFgColor = Color.FromRgb(dominantColor.R, dominantColor.G, dominantColor.B);
|
Color progressFgColor = Color.FromRgb(dominantColor.R, dominantColor.G, dominantColor.B);
|
||||||
Color progressBgColor = Color.FromRgb(
|
Color progressBgColor = Color.FromRgb(
|
||||||
(byte)(dominantColor.R * colorMultiple),
|
(byte)(dominantColor.R * ColorMultiple),
|
||||||
(byte)(dominantColor.G * colorMultiple),
|
(byte)(dominantColor.G * ColorMultiple),
|
||||||
(byte)(dominantColor.B * colorMultiple));
|
(byte)(dominantColor.B * ColorMultiple));
|
||||||
|
|
||||||
ProgressBarForegroundColor = new SolidColorBrush(progressFgColor);
|
ProgressBarForegroundColor = new SolidColorBrush(progressFgColor);
|
||||||
ProgressBarBackgroundColor = new SolidColorBrush(progressBgColor);
|
ProgressBarBackgroundColor = new SolidColorBrush(progressBgColor);
|
||||||
|
@@ -18,14 +18,14 @@ using Ryujinx.HLE.FileSystem;
|
|||||||
using Ryujinx.HLE.HOS.Services.Time.TimeZone;
|
using Ryujinx.HLE.HOS.Services.Time.TimeZone;
|
||||||
using Ryujinx.Ui.Common.Configuration;
|
using Ryujinx.Ui.Common.Configuration;
|
||||||
using Ryujinx.Ui.Common.Configuration.System;
|
using Ryujinx.Ui.Common.Configuration.System;
|
||||||
|
using Silk.NET.Vulkan;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Net.NetworkInformation;
|
using System.Net.NetworkInformation;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using TimeZone = Ryujinx.Ava.UI.Models.TimeZone;
|
using TimeZone = Ryujinx.Ava.UI.Models.TimeZone;
|
||||||
using Silk.NET.Vulkan;
|
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.ViewModels
|
namespace Ryujinx.Ava.UI.ViewModels
|
||||||
{
|
{
|
||||||
|
@@ -44,10 +44,10 @@ namespace Ryujinx.Common.SystemInfo
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int flavor = 4; // HOST_VM_INFO64
|
const int Flavor = 4; // HOST_VM_INFO64
|
||||||
uint count = (uint)(Marshal.SizeOf<VMStatistics64>() / sizeof(int)); // HOST_VM_INFO64_COUNT
|
uint count = (uint)(Marshal.SizeOf<VMStatistics64>() / sizeof(int)); // HOST_VM_INFO64_COUNT
|
||||||
VMStatistics64 stats = new();
|
VMStatistics64 stats = new();
|
||||||
result = host_statistics64(port, flavor, ref stats, ref count);
|
result = host_statistics64(port, Flavor, ref stats, ref count);
|
||||||
|
|
||||||
if (result != 0)
|
if (result != 0)
|
||||||
{
|
{
|
||||||
|
@@ -29,10 +29,10 @@ namespace Ryujinx.Common.SystemInterop
|
|||||||
[SupportedOSPlatform("macos")]
|
[SupportedOSPlatform("macos")]
|
||||||
private void RegisterPosix()
|
private void RegisterPosix()
|
||||||
{
|
{
|
||||||
const int stdErrFileno = 2;
|
const int StdErrFileno = 2;
|
||||||
|
|
||||||
(int readFd, int writeFd) = MakePipe();
|
(int readFd, int writeFd) = MakePipe();
|
||||||
dup2(writeFd, stdErrFileno);
|
dup2(writeFd, StdErrFileno);
|
||||||
|
|
||||||
_pipeReader = CreateFileDescriptorStream(readFd);
|
_pipeReader = CreateFileDescriptorStream(readFd);
|
||||||
_pipeWriter = CreateFileDescriptorStream(writeFd);
|
_pipeWriter = CreateFileDescriptorStream(writeFd);
|
||||||
|
@@ -6,8 +6,8 @@ using Ryujinx.Memory.Range;
|
|||||||
using Ryujinx.Memory.Tracking;
|
using Ryujinx.Memory.Tracking;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Gpu.Memory
|
namespace Ryujinx.Graphics.Gpu.Memory
|
||||||
|
@@ -9,6 +9,6 @@ namespace Ryujinx.Graphics.Shader
|
|||||||
Greater,
|
Greater,
|
||||||
NotEqual,
|
NotEqual,
|
||||||
GreaterOrEqual,
|
GreaterOrEqual,
|
||||||
Always
|
Always,
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -8,7 +8,7 @@ namespace Ryujinx.Graphics.Shader
|
|||||||
// Generic types.
|
// Generic types.
|
||||||
Float,
|
Float,
|
||||||
Sint,
|
Sint,
|
||||||
Uint
|
Uint,
|
||||||
}
|
}
|
||||||
|
|
||||||
static class AttributeTypeExtensions
|
static class AttributeTypeExtensions
|
||||||
@@ -20,7 +20,7 @@ namespace Ryujinx.Graphics.Shader
|
|||||||
AttributeType.Float => "vec4",
|
AttributeType.Float => "vec4",
|
||||||
AttributeType.Sint => "ivec4",
|
AttributeType.Sint => "ivec4",
|
||||||
AttributeType.Uint => "uvec4",
|
AttributeType.Uint => "uvec4",
|
||||||
_ => throw new ArgumentException($"Invalid attribute type \"{type}\".")
|
_ => throw new ArgumentException($"Invalid attribute type \"{type}\"."),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ namespace Ryujinx.Graphics.Shader
|
|||||||
AttributeType.Float => AggregateType.FP32,
|
AttributeType.Float => AggregateType.FP32,
|
||||||
AttributeType.Sint => AggregateType.S32,
|
AttributeType.Sint => AggregateType.S32,
|
||||||
AttributeType.Uint => AggregateType.U32,
|
AttributeType.Uint => AggregateType.U32,
|
||||||
_ => throw new ArgumentException($"Invalid attribute type \"{type}\".")
|
_ => throw new ArgumentException($"Invalid attribute type \"{type}\"."),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -13,6 +13,6 @@ namespace Ryujinx.Graphics.Shader
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Buffer is written to.
|
/// Buffer is written to.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Write = 1 << 0
|
Write = 1 << 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -244,16 +244,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetTfLayout(TransformFeedbackOutput tfOutput)
|
|
||||||
{
|
|
||||||
if (tfOutput.Valid)
|
|
||||||
{
|
|
||||||
return $"layout (xfb_buffer = {tfOutput.Buffer}, xfb_offset = {tfOutput.Offset}, xfb_stride = {tfOutput.Stride}) ";
|
|
||||||
}
|
|
||||||
|
|
||||||
return string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void DeclareLocals(CodeGenContext context, StructuredFunction function)
|
public static void DeclareLocals(CodeGenContext context, StructuredFunction function)
|
||||||
{
|
{
|
||||||
foreach (AstOperand decl in function.Locals)
|
foreach (AstOperand decl in function.Locals)
|
||||||
@@ -294,7 +284,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
AggregateType.Vector4 | AggregateType.FP64 => "dvec4",
|
AggregateType.Vector4 | AggregateType.FP64 => "dvec4",
|
||||||
AggregateType.Vector4 | AggregateType.S32 => "ivec4",
|
AggregateType.Vector4 | AggregateType.S32 => "ivec4",
|
||||||
AggregateType.Vector4 | AggregateType.U32 => "uvec4",
|
AggregateType.Vector4 | AggregateType.U32 => "uvec4",
|
||||||
_ => throw new ArgumentException($"Invalid variable type \"{type}\".")
|
_ => throw new ArgumentException($"Invalid variable type \"{type}\"."),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -315,7 +305,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
string layout = buffer.Layout switch
|
string layout = buffer.Layout switch
|
||||||
{
|
{
|
||||||
BufferLayout.Std140 => "std140",
|
BufferLayout.Std140 => "std140",
|
||||||
_ => "std430"
|
_ => "std430",
|
||||||
};
|
};
|
||||||
|
|
||||||
string set = string.Empty;
|
string set = string.Empty;
|
||||||
@@ -507,7 +497,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
{
|
{
|
||||||
PixelImap.Constant => "flat ",
|
PixelImap.Constant => "flat ",
|
||||||
PixelImap.ScreenLinear => "noperspective ",
|
PixelImap.ScreenLinear => "noperspective ",
|
||||||
_ => string.Empty
|
_ => string.Empty,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -524,7 +514,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
2 => "vec2",
|
2 => "vec2",
|
||||||
3 => "vec3",
|
3 => "vec3",
|
||||||
4 => "vec4",
|
4 => "vec4",
|
||||||
_ => "float"
|
_ => "float",
|
||||||
};
|
};
|
||||||
|
|
||||||
context.AppendLine($"layout (location = {attr}) in {type} {name};");
|
context.AppendLine($"layout (location = {attr}) in {type} {name};");
|
||||||
@@ -611,7 +601,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
2 => "vec2",
|
2 => "vec2",
|
||||||
3 => "vec3",
|
3 => "vec3",
|
||||||
4 => "vec4",
|
4 => "vec4",
|
||||||
_ => "float"
|
_ => "float",
|
||||||
};
|
};
|
||||||
|
|
||||||
string xfb = string.Empty;
|
string xfb = string.Empty;
|
||||||
@@ -647,7 +637,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
{
|
{
|
||||||
AttributeType.Sint => "ivec4",
|
AttributeType.Sint => "ivec4",
|
||||||
AttributeType.Uint => "uvec4",
|
AttributeType.Uint => "uvec4",
|
||||||
_ => "vec4"
|
_ => "vec4",
|
||||||
};
|
};
|
||||||
|
|
||||||
if (context.Config.GpuAccessor.QueryHostReducedPrecision() && context.Config.Stage == ShaderStage.Vertex && attr == 0)
|
if (context.Config.GpuAccessor.QueryHostReducedPrecision() && context.Config.Stage == ShaderStage.Vertex && attr == 0)
|
||||||
|
@@ -13,7 +13,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
|
|
||||||
public static string Generate(StructuredProgramInfo info, ShaderConfig config)
|
public static string Generate(StructuredProgramInfo info, ShaderConfig config)
|
||||||
{
|
{
|
||||||
CodeGenContext context = new CodeGenContext(info, config);
|
CodeGenContext context = new(info, config);
|
||||||
|
|
||||||
Declarations.Declare(context, info);
|
Declarations.Declare(context, info);
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
|
|
||||||
private static void PrintBlock(CodeGenContext context, AstBlock block, bool isMainFunction)
|
private static void PrintBlock(CodeGenContext context, AstBlock block, bool isMainFunction)
|
||||||
{
|
{
|
||||||
AstBlockVisitor visitor = new AstBlockVisitor(block);
|
AstBlockVisitor visitor = new(block);
|
||||||
|
|
||||||
visitor.BlockEntered += (sender, e) =>
|
visitor.BlockEntered += (sender, e) =>
|
||||||
{
|
{
|
||||||
@@ -96,7 +96,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
context.AppendLine($"if ({GetCondExpr(context, e.Block.Condition)})");
|
context.AppendLine($"if ({GetCondExpr(context, e.Block.Condition)})");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: throw new InvalidOperationException($"Found unexpected block type \"{e.Block.Type}\".");
|
default:
|
||||||
|
throw new InvalidOperationException($"Found unexpected block type \"{e.Block.Type}\".");
|
||||||
}
|
}
|
||||||
|
|
||||||
context.EnterScope();
|
context.EnterScope();
|
||||||
|
@@ -14,6 +14,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||||||
{
|
{
|
||||||
_infoTable = new InstInfo[(int)Instruction.Count];
|
_infoTable = new InstInfo[(int)Instruction.Count];
|
||||||
|
|
||||||
|
#pragma warning disable IDE0055 // Disable formatting
|
||||||
Add(Instruction.AtomicAdd, InstType.AtomicBinary, "atomicAdd");
|
Add(Instruction.AtomicAdd, InstType.AtomicBinary, "atomicAdd");
|
||||||
Add(Instruction.AtomicAnd, InstType.AtomicBinary, "atomicAnd");
|
Add(Instruction.AtomicAnd, InstType.AtomicBinary, "atomicAnd");
|
||||||
Add(Instruction.AtomicCompareAndSwap, InstType.AtomicTernary, "atomicCompSwap");
|
Add(Instruction.AtomicCompareAndSwap, InstType.AtomicTernary, "atomicCompSwap");
|
||||||
@@ -125,6 +126,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||||||
Add(Instruction.VoteAll, InstType.CallUnary, "allInvocationsARB");
|
Add(Instruction.VoteAll, InstType.CallUnary, "allInvocationsARB");
|
||||||
Add(Instruction.VoteAllEqual, InstType.CallUnary, "allInvocationsEqualARB");
|
Add(Instruction.VoteAllEqual, InstType.CallUnary, "allInvocationsEqualARB");
|
||||||
Add(Instruction.VoteAny, InstType.CallUnary, "anyInvocationARB");
|
Add(Instruction.VoteAny, InstType.CallUnary, "anyInvocationARB");
|
||||||
|
#pragma warning restore IDE0055
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Add(Instruction inst, InstType flags, string opName = null, int precedence = 0)
|
private static void Add(Instruction inst, InstType flags, string opName = null, int precedence = 0)
|
||||||
@@ -163,7 +165,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||||||
{
|
{
|
||||||
// If the node isn't a operation, then it can only be a operand,
|
// If the node isn't a operation, then it can only be a operand,
|
||||||
// and those never needs to be surrounded in parenthesis.
|
// and those never needs to be surrounded in parenthesis.
|
||||||
if (!(node is AstOperation operation))
|
if (node is not AstOperation operation)
|
||||||
{
|
{
|
||||||
// This is sort of a special case, if this is a negative constant,
|
// This is sort of a special case, if this is a negative constant,
|
||||||
// and it is consumed by a unary operation, we need to put on the parenthesis,
|
// and it is consumed by a unary operation, we need to put on the parenthesis,
|
||||||
@@ -208,7 +210,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||||||
|
|
||||||
private static bool IsNegativeConst(IAstNode node)
|
private static bool IsNegativeConst(IAstNode node)
|
||||||
{
|
{
|
||||||
if (!(node is AstOperand operand))
|
if (node is not AstOperand operand)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@@ -3,7 +3,6 @@ using Ryujinx.Graphics.Shader.StructuredIr;
|
|||||||
using Ryujinx.Graphics.Shader.Translation;
|
using Ryujinx.Graphics.Shader.Translation;
|
||||||
using System;
|
using System;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
using static Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions.InstGenHelper;
|
using static Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions.InstGenHelper;
|
||||||
using static Ryujinx.Graphics.Shader.StructuredIr.InstructionInfo;
|
using static Ryujinx.Graphics.Shader.StructuredIr.InstructionInfo;
|
||||||
|
|
||||||
@@ -49,7 +48,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||||||
|
|
||||||
if (texOp.Inst == Instruction.ImageAtomic)
|
if (texOp.Inst == Instruction.ImageAtomic)
|
||||||
{
|
{
|
||||||
texCallBuilder.Append((texOp.Flags & TextureFlags.AtomicMask) switch {
|
texCallBuilder.Append((texOp.Flags & TextureFlags.AtomicMask) switch
|
||||||
|
{
|
||||||
|
#pragma warning disable IDE0055 // Disable formatting
|
||||||
TextureFlags.Add => "imageAtomicAdd",
|
TextureFlags.Add => "imageAtomicAdd",
|
||||||
TextureFlags.Minimum => "imageAtomicMin",
|
TextureFlags.Minimum => "imageAtomicMin",
|
||||||
TextureFlags.Maximum => "imageAtomicMax",
|
TextureFlags.Maximum => "imageAtomicMax",
|
||||||
@@ -61,6 +62,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||||||
TextureFlags.Swap => "imageAtomicExchange",
|
TextureFlags.Swap => "imageAtomicExchange",
|
||||||
TextureFlags.CAS => "imageAtomicCompSwap",
|
TextureFlags.CAS => "imageAtomicCompSwap",
|
||||||
_ => "imageAtomicAdd",
|
_ => "imageAtomicAdd",
|
||||||
|
#pragma warning restore IDE0055
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -131,7 +133,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||||||
{
|
{
|
||||||
AggregateType.S32 => NumberFormatter.FormatInt(0),
|
AggregateType.S32 => NumberFormatter.FormatInt(0),
|
||||||
AggregateType.U32 => NumberFormatter.FormatUint(0),
|
AggregateType.U32 => NumberFormatter.FormatUint(0),
|
||||||
_ => NumberFormatter.FormatFloat(0)
|
_ => NumberFormatter.FormatFloat(0),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -140,7 +142,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||||||
{
|
{
|
||||||
AggregateType.S32 => "i",
|
AggregateType.S32 => "i",
|
||||||
AggregateType.U32 => "u",
|
AggregateType.U32 => "u",
|
||||||
_ => string.Empty
|
_ => string.Empty,
|
||||||
};
|
};
|
||||||
|
|
||||||
Append($"{prefix}vec4({string.Join(", ", cElems)})");
|
Append($"{prefix}vec4({string.Join(", ", cElems)})");
|
||||||
@@ -159,7 +161,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||||||
{
|
{
|
||||||
TextureFlags.Increment => NumberFormatter.FormatInt(1, type), // TODO: Clamp value
|
TextureFlags.Increment => NumberFormatter.FormatInt(1, type), // TODO: Clamp value
|
||||||
TextureFlags.Decrement => NumberFormatter.FormatInt(-1, type), // TODO: Clamp value
|
TextureFlags.Decrement => NumberFormatter.FormatInt(-1, type), // TODO: Clamp value
|
||||||
_ => Src(type)
|
_ => Src(type),
|
||||||
};
|
};
|
||||||
|
|
||||||
Append(value);
|
Append(value);
|
||||||
@@ -584,7 +586,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||||||
{
|
{
|
||||||
case StorageKind.ConstantBuffer:
|
case StorageKind.ConstantBuffer:
|
||||||
case StorageKind.StorageBuffer:
|
case StorageKind.StorageBuffer:
|
||||||
if (!(operation.GetSource(srcIndex++) is AstOperand bindingIndex) || bindingIndex.Type != OperandType.Constant)
|
if (operation.GetSource(srcIndex++) is not AstOperand bindingIndex || bindingIndex.Type != OperandType.Constant)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"First input of {operation.Inst} with {storageKind} storage must be a constant operand.");
|
throw new InvalidOperationException($"First input of {operation.Inst} with {storageKind} storage must be a constant operand.");
|
||||||
}
|
}
|
||||||
@@ -594,7 +596,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||||||
? context.Config.Properties.ConstantBuffers[binding]
|
? context.Config.Properties.ConstantBuffers[binding]
|
||||||
: context.Config.Properties.StorageBuffers[binding];
|
: context.Config.Properties.StorageBuffers[binding];
|
||||||
|
|
||||||
if (!(operation.GetSource(srcIndex++) is AstOperand fieldIndex) || fieldIndex.Type != OperandType.Constant)
|
if (operation.GetSource(srcIndex++) is not AstOperand fieldIndex || fieldIndex.Type != OperandType.Constant)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"Second input of {operation.Inst} with {storageKind} storage must be a constant operand.");
|
throw new InvalidOperationException($"Second input of {operation.Inst} with {storageKind} storage must be a constant operand.");
|
||||||
}
|
}
|
||||||
@@ -606,7 +608,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||||||
|
|
||||||
case StorageKind.LocalMemory:
|
case StorageKind.LocalMemory:
|
||||||
case StorageKind.SharedMemory:
|
case StorageKind.SharedMemory:
|
||||||
if (!(operation.GetSource(srcIndex++) is AstOperand bindingId) || bindingId.Type != OperandType.Constant)
|
if (operation.GetSource(srcIndex++) is not AstOperand { Type: OperandType.Constant } bindingId)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"First input of {operation.Inst} with {storageKind} storage must be a constant operand.");
|
throw new InvalidOperationException($"First input of {operation.Inst} with {storageKind} storage must be a constant operand.");
|
||||||
}
|
}
|
||||||
@@ -623,7 +625,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||||||
case StorageKind.InputPerPatch:
|
case StorageKind.InputPerPatch:
|
||||||
case StorageKind.Output:
|
case StorageKind.Output:
|
||||||
case StorageKind.OutputPerPatch:
|
case StorageKind.OutputPerPatch:
|
||||||
if (!(operation.GetSource(srcIndex++) is AstOperand varId) || varId.Type != OperandType.Constant)
|
if (operation.GetSource(srcIndex++) is not AstOperand varId || varId.Type != OperandType.Constant)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"First input of {operation.Inst} with {storageKind} storage must be a constant operand.");
|
throw new InvalidOperationException($"First input of {operation.Inst} with {storageKind} storage must be a constant operand.");
|
||||||
}
|
}
|
||||||
@@ -636,7 +638,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||||||
|
|
||||||
if (context.Config.HasPerLocationInputOrOutput(ioVariable, isOutput))
|
if (context.Config.HasPerLocationInputOrOutput(ioVariable, isOutput))
|
||||||
{
|
{
|
||||||
if (!(operation.GetSource(srcIndex++) is AstOperand vecIndex) || vecIndex.Type != OperandType.Constant)
|
if (operation.GetSource(srcIndex++) is not AstOperand vecIndex || vecIndex.Type != OperandType.Constant)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"Second input of {operation.Inst} with {storageKind} storage must be a constant operand.");
|
throw new InvalidOperationException($"Second input of {operation.Inst} with {storageKind} storage must be a constant operand.");
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
||||||
{
|
{
|
||||||
[Flags]
|
[Flags]
|
||||||
|
[SuppressMessage("Design", "CA1069: Enums values should not be duplicated")]
|
||||||
enum InstType
|
enum InstType
|
||||||
{
|
{
|
||||||
OpNullary = Op | 0,
|
OpNullary = Op | 0,
|
||||||
@@ -28,6 +30,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||||||
Atomic = 1 << 11,
|
Atomic = 1 << 11,
|
||||||
Special = 1 << 12,
|
Special = 1 << 12,
|
||||||
|
|
||||||
ArityMask = 0xff
|
ArityMask = 0xff,
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -56,7 +56,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||||||
IoVariable.VertexIndex => ("gl_VertexIndex", AggregateType.S32),
|
IoVariable.VertexIndex => ("gl_VertexIndex", AggregateType.S32),
|
||||||
IoVariable.ViewportIndex => ("gl_ViewportIndex", AggregateType.S32),
|
IoVariable.ViewportIndex => ("gl_ViewportIndex", AggregateType.S32),
|
||||||
IoVariable.ViewportMask => ("gl_ViewportMask", AggregateType.Array | AggregateType.S32),
|
IoVariable.ViewportMask => ("gl_ViewportMask", AggregateType.Array | AggregateType.S32),
|
||||||
_ => (null, AggregateType.Invalid)
|
_ => (null, AggregateType.Invalid),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -5,7 +5,6 @@ using Ryujinx.Graphics.Shader.Translation;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
|
||||||
using static Ryujinx.Graphics.Shader.StructuredIr.InstructionInfo;
|
using static Ryujinx.Graphics.Shader.StructuredIr.InstructionInfo;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
||||||
@@ -14,7 +13,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
{
|
{
|
||||||
private static readonly string[] _stagePrefixes = new string[] { "cp", "vp", "tcp", "tep", "gp", "fp" };
|
private static readonly string[] _stagePrefixes = new string[] { "cp", "vp", "tcp", "tep", "gp", "fp" };
|
||||||
|
|
||||||
private Dictionary<AstOperand, string> _locals;
|
private readonly Dictionary<AstOperand, string> _locals;
|
||||||
|
|
||||||
public OperandManager()
|
public OperandManager()
|
||||||
{
|
{
|
||||||
@@ -38,7 +37,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
OperandType.Constant => NumberFormatter.FormatInt(operand.Value),
|
OperandType.Constant => NumberFormatter.FormatInt(operand.Value),
|
||||||
OperandType.LocalVariable => _locals[operand],
|
OperandType.LocalVariable => _locals[operand],
|
||||||
OperandType.Undefined => DefaultNames.UndefinedName,
|
OperandType.Undefined => DefaultNames.UndefinedName,
|
||||||
_ => throw new ArgumentException($"Invalid operand type \"{operand.Type}\".")
|
_ => throw new ArgumentException($"Invalid operand type \"{operand.Type}\"."),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,11 +95,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
return _stagePrefixes[index];
|
return _stagePrefixes[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
private static char GetSwizzleMask(int value)
|
|
||||||
{
|
|
||||||
return "xyzw"[value];
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string GetArgumentName(int argIndex)
|
public static string GetArgumentName(int argIndex)
|
||||||
{
|
{
|
||||||
return $"{DefaultNames.ArgumentNamePrefix}{argIndex}";
|
return $"{DefaultNames.ArgumentNamePrefix}{argIndex}";
|
||||||
@@ -119,12 +113,12 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
{
|
{
|
||||||
case StorageKind.ConstantBuffer:
|
case StorageKind.ConstantBuffer:
|
||||||
case StorageKind.StorageBuffer:
|
case StorageKind.StorageBuffer:
|
||||||
if (!(operation.GetSource(0) is AstOperand bindingIndex) || bindingIndex.Type != OperandType.Constant)
|
if (operation.GetSource(0) is not AstOperand bindingIndex || bindingIndex.Type != OperandType.Constant)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"First input of {operation.Inst} with {operation.StorageKind} storage must be a constant operand.");
|
throw new InvalidOperationException($"First input of {operation.Inst} with {operation.StorageKind} storage must be a constant operand.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(operation.GetSource(1) is AstOperand fieldIndex) || fieldIndex.Type != OperandType.Constant)
|
if (operation.GetSource(1) is not AstOperand fieldIndex || fieldIndex.Type != OperandType.Constant)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"Second input of {operation.Inst} with {operation.StorageKind} storage must be a constant operand.");
|
throw new InvalidOperationException($"Second input of {operation.Inst} with {operation.StorageKind} storage must be a constant operand.");
|
||||||
}
|
}
|
||||||
@@ -138,7 +132,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
|
|
||||||
case StorageKind.LocalMemory:
|
case StorageKind.LocalMemory:
|
||||||
case StorageKind.SharedMemory:
|
case StorageKind.SharedMemory:
|
||||||
if (!(operation.GetSource(0) is AstOperand bindingId) || bindingId.Type != OperandType.Constant)
|
if (operation.GetSource(0) is not AstOperand { Type: OperandType.Constant } bindingId)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"First input of {operation.Inst} with {operation.StorageKind} storage must be a constant operand.");
|
throw new InvalidOperationException($"First input of {operation.Inst} with {operation.StorageKind} storage must be a constant operand.");
|
||||||
}
|
}
|
||||||
@@ -153,7 +147,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
case StorageKind.InputPerPatch:
|
case StorageKind.InputPerPatch:
|
||||||
case StorageKind.Output:
|
case StorageKind.Output:
|
||||||
case StorageKind.OutputPerPatch:
|
case StorageKind.OutputPerPatch:
|
||||||
if (!(operation.GetSource(0) is AstOperand varId) || varId.Type != OperandType.Constant)
|
if (operation.GetSource(0) is not AstOperand varId || varId.Type != OperandType.Constant)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"First input of {operation.Inst} with {operation.StorageKind} storage must be a constant operand.");
|
throw new InvalidOperationException($"First input of {operation.Inst} with {operation.StorageKind} storage must be a constant operand.");
|
||||||
}
|
}
|
||||||
@@ -166,7 +160,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
|
|
||||||
if (context.Config.HasPerLocationInputOrOutput(ioVariable, isOutput))
|
if (context.Config.HasPerLocationInputOrOutput(ioVariable, isOutput))
|
||||||
{
|
{
|
||||||
if (!(operation.GetSource(1) is AstOperand vecIndex) || vecIndex.Type != OperandType.Constant)
|
if (operation.GetSource(1) is not AstOperand vecIndex || vecIndex.Type != OperandType.Constant)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"Second input of {operation.Inst} with {operation.StorageKind} storage must be a constant operand.");
|
throw new InvalidOperationException($"Second input of {operation.Inst} with {operation.StorageKind} storage must be a constant operand.");
|
||||||
}
|
}
|
||||||
|
@@ -38,18 +38,24 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||||||
{
|
{
|
||||||
switch (dstType)
|
switch (dstType)
|
||||||
{
|
{
|
||||||
case AggregateType.Bool: return $"(floatBitsToInt({expr}) != 0)";
|
case AggregateType.Bool:
|
||||||
case AggregateType.S32: return $"floatBitsToInt({expr})";
|
return $"(floatBitsToInt({expr}) != 0)";
|
||||||
case AggregateType.U32: return $"floatBitsToUint({expr})";
|
case AggregateType.S32:
|
||||||
|
return $"floatBitsToInt({expr})";
|
||||||
|
case AggregateType.U32:
|
||||||
|
return $"floatBitsToUint({expr})";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (dstType == AggregateType.FP32)
|
else if (dstType == AggregateType.FP32)
|
||||||
{
|
{
|
||||||
switch (srcType)
|
switch (srcType)
|
||||||
{
|
{
|
||||||
case AggregateType.Bool: return $"intBitsToFloat({ReinterpretBoolToInt(expr, node, AggregateType.S32)})";
|
case AggregateType.Bool:
|
||||||
case AggregateType.S32: return $"intBitsToFloat({expr})";
|
return $"intBitsToFloat({ReinterpretBoolToInt(expr, node, AggregateType.S32)})";
|
||||||
case AggregateType.U32: return $"uintBitsToFloat({expr})";
|
case AggregateType.S32:
|
||||||
|
return $"intBitsToFloat({expr})";
|
||||||
|
case AggregateType.U32:
|
||||||
|
return $"uintBitsToFloat({expr})";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (srcType == AggregateType.Bool)
|
else if (srcType == AggregateType.Bool)
|
||||||
|
@@ -1,13 +1,14 @@
|
|||||||
using Ryujinx.Graphics.Shader.StructuredIr;
|
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||||
|
using Ryujinx.Graphics.Shader.StructuredIr;
|
||||||
using Ryujinx.Graphics.Shader.Translation;
|
using Ryujinx.Graphics.Shader.Translation;
|
||||||
using Spv.Generator;
|
using Spv.Generator;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using static Spv.Specification;
|
using static Spv.Specification;
|
||||||
|
using Instruction = Spv.Generator.Instruction;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
||||||
{
|
{
|
||||||
using IrConsts = IntermediateRepresentation.IrConsts;
|
|
||||||
using IrOperandType = IntermediateRepresentation.OperandType;
|
using IrOperandType = IntermediateRepresentation.OperandType;
|
||||||
|
|
||||||
partial class CodeGenContext : Module
|
partial class CodeGenContext : Module
|
||||||
@@ -36,15 +37,15 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
public Dictionary<IoDefinition, Instruction> OutputsPerPatch { get; } = new Dictionary<IoDefinition, Instruction>();
|
public Dictionary<IoDefinition, Instruction> OutputsPerPatch { get; } = new Dictionary<IoDefinition, Instruction>();
|
||||||
|
|
||||||
public StructuredFunction CurrentFunction { get; set; }
|
public StructuredFunction CurrentFunction { get; set; }
|
||||||
private readonly Dictionary<AstOperand, Instruction> _locals = new Dictionary<AstOperand, Instruction>();
|
private readonly Dictionary<AstOperand, Instruction> _locals = new();
|
||||||
private readonly Dictionary<int, Instruction[]> _localForArgs = new Dictionary<int, Instruction[]>();
|
private readonly Dictionary<int, Instruction[]> _localForArgs = new();
|
||||||
private readonly Dictionary<int, Instruction> _funcArgs = new Dictionary<int, Instruction>();
|
private readonly Dictionary<int, Instruction> _funcArgs = new();
|
||||||
private readonly Dictionary<int, (StructuredFunction, Instruction)> _functions = new Dictionary<int, (StructuredFunction, Instruction)>();
|
private readonly Dictionary<int, (StructuredFunction, Instruction)> _functions = new();
|
||||||
|
|
||||||
private class BlockState
|
private class BlockState
|
||||||
{
|
{
|
||||||
private int _entryCount;
|
private int _entryCount;
|
||||||
private readonly List<Instruction> _labels = new List<Instruction>();
|
private readonly List<Instruction> _labels = new();
|
||||||
|
|
||||||
public Instruction GetNextLabel(CodeGenContext context)
|
public Instruction GetNextLabel(CodeGenContext context)
|
||||||
{
|
{
|
||||||
@@ -67,7 +68,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly Dictionary<AstBlock, BlockState> _labels = new Dictionary<AstBlock, BlockState>();
|
private readonly Dictionary<AstBlock, BlockState> _labels = new();
|
||||||
|
|
||||||
public Dictionary<AstBlock, (Instruction, Instruction)> LoopTargets { get; set; }
|
public Dictionary<AstBlock, (Instruction, Instruction)> LoopTargets { get; set; }
|
||||||
|
|
||||||
@@ -98,7 +99,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
InputTopology.LinesAdjacency => 2,
|
InputTopology.LinesAdjacency => 2,
|
||||||
InputTopology.Triangles => 3,
|
InputTopology.Triangles => 3,
|
||||||
InputTopology.TrianglesAdjacency => 3,
|
InputTopology.TrianglesAdjacency => 3,
|
||||||
_ => throw new InvalidOperationException($"Invalid input topology \"{inPrimitive}\".")
|
_ => throw new InvalidOperationException($"Invalid input topology \"{inPrimitive}\"."),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,7 +223,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
IrOperandType.Constant => GetConstant(type, operand),
|
IrOperandType.Constant => GetConstant(type, operand),
|
||||||
IrOperandType.LocalVariable => GetLocal(type, operand),
|
IrOperandType.LocalVariable => GetLocal(type, operand),
|
||||||
IrOperandType.Undefined => GetUndefined(type),
|
IrOperandType.Undefined => GetUndefined(type),
|
||||||
_ => throw new ArgumentException($"Invalid operand type \"{operand.Type}\".")
|
_ => throw new ArgumentException($"Invalid operand type \"{operand.Type}\"."),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,7 +260,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
AggregateType.Bool => ConstantFalse(TypeBool()),
|
AggregateType.Bool => ConstantFalse(TypeBool()),
|
||||||
AggregateType.FP32 => Constant(TypeFP32(), 0f),
|
AggregateType.FP32 => Constant(TypeFP32(), 0f),
|
||||||
AggregateType.FP64 => Constant(TypeFP64(), 0d),
|
AggregateType.FP64 => Constant(TypeFP64(), 0d),
|
||||||
_ => Constant(GetType(type), 0)
|
_ => Constant(GetType(type), 0),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -272,7 +273,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
AggregateType.FP64 => Constant(TypeFP64(), (double)BitConverter.Int32BitsToSingle(operand.Value)),
|
AggregateType.FP64 => Constant(TypeFP64(), (double)BitConverter.Int32BitsToSingle(operand.Value)),
|
||||||
AggregateType.S32 => Constant(TypeS32(), operand.Value),
|
AggregateType.S32 => Constant(TypeS32(), operand.Value),
|
||||||
AggregateType.U32 => Constant(TypeU32(), (uint)operand.Value),
|
AggregateType.U32 => Constant(TypeU32(), (uint)operand.Value),
|
||||||
_ => throw new ArgumentException($"Invalid type \"{type}\".")
|
_ => throw new ArgumentException($"Invalid type \"{type}\"."),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,7 +329,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
AggregateType.Vector2 => 2,
|
AggregateType.Vector2 => 2,
|
||||||
AggregateType.Vector3 => 3,
|
AggregateType.Vector3 => 3,
|
||||||
AggregateType.Vector4 => 4,
|
AggregateType.Vector4 => 4,
|
||||||
_ => 1
|
_ => 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
return TypeVector(GetType(type & ~AggregateType.ElementCountMask), vectorLength);
|
return TypeVector(GetType(type & ~AggregateType.ElementCountMask), vectorLength);
|
||||||
@@ -342,7 +343,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
AggregateType.FP64 => TypeFP64(),
|
AggregateType.FP64 => TypeFP64(),
|
||||||
AggregateType.S32 => TypeS32(),
|
AggregateType.S32 => TypeS32(),
|
||||||
AggregateType.U32 => TypeU32(),
|
AggregateType.U32 => TypeU32(),
|
||||||
_ => throw new ArgumentException($"Invalid attribute type \"{type}\".")
|
_ => throw new ArgumentException($"Invalid attribute type \"{type}\"."),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,5 +1,4 @@
|
|||||||
using Ryujinx.Common;
|
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
|
||||||
using Ryujinx.Graphics.Shader.StructuredIr;
|
using Ryujinx.Graphics.Shader.StructuredIr;
|
||||||
using Ryujinx.Graphics.Shader.Translation;
|
using Ryujinx.Graphics.Shader.Translation;
|
||||||
using Spv.Generator;
|
using Spv.Generator;
|
||||||
@@ -14,7 +13,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
{
|
{
|
||||||
static class Declarations
|
static class Declarations
|
||||||
{
|
{
|
||||||
private static readonly string[] StagePrefixes = new string[] { "cp", "vp", "tcp", "tep", "gp", "fp" };
|
private static readonly string[] _stagePrefixes = { "cp", "vp", "tcp", "tep", "gp", "fp" };
|
||||||
|
|
||||||
public static void DeclareParameters(CodeGenContext context, StructuredFunction function)
|
public static void DeclareParameters(CodeGenContext context, StructuredFunction function)
|
||||||
{
|
{
|
||||||
@@ -107,7 +106,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
private static void DeclareBuffers(CodeGenContext context, IEnumerable<BufferDefinition> buffers, bool isBuffer)
|
private static void DeclareBuffers(CodeGenContext context, IEnumerable<BufferDefinition> buffers, bool isBuffer)
|
||||||
{
|
{
|
||||||
HashSet<SpvInstruction> decoratedTypes = new HashSet<SpvInstruction>();
|
HashSet<SpvInstruction> decoratedTypes = new();
|
||||||
|
|
||||||
foreach (BufferDefinition buffer in buffers)
|
foreach (BufferDefinition buffer in buffers)
|
||||||
{
|
{
|
||||||
@@ -199,7 +198,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
SamplerType.Texture3D => Dim.Dim3D,
|
SamplerType.Texture3D => Dim.Dim3D,
|
||||||
SamplerType.TextureCube => Dim.Cube,
|
SamplerType.TextureCube => Dim.Cube,
|
||||||
SamplerType.TextureBuffer => Dim.Buffer,
|
SamplerType.TextureBuffer => Dim.Buffer,
|
||||||
_ => throw new InvalidOperationException($"Invalid sampler type \"{descriptor.Type & SamplerType.Mask}\".")
|
_ => throw new InvalidOperationException($"Invalid sampler type \"{descriptor.Type & SamplerType.Mask}\"."),
|
||||||
};
|
};
|
||||||
|
|
||||||
var imageType = context.TypeImage(
|
var imageType = context.TypeImage(
|
||||||
@@ -282,7 +281,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
SamplerType.Texture3D => Dim.Dim3D,
|
SamplerType.Texture3D => Dim.Dim3D,
|
||||||
SamplerType.TextureCube => Dim.Cube,
|
SamplerType.TextureCube => Dim.Cube,
|
||||||
SamplerType.TextureBuffer => Dim.Buffer,
|
SamplerType.TextureBuffer => Dim.Buffer,
|
||||||
_ => throw new ArgumentException($"Invalid sampler type \"{type & SamplerType.Mask}\".")
|
_ => throw new ArgumentException($"Invalid sampler type \"{type & SamplerType.Mask}\"."),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -330,7 +329,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
TextureFormat.R10G10B10A2Unorm => ImageFormat.Rgb10A2,
|
TextureFormat.R10G10B10A2Unorm => ImageFormat.Rgb10A2,
|
||||||
TextureFormat.R10G10B10A2Uint => ImageFormat.Rgb10a2ui,
|
TextureFormat.R10G10B10A2Uint => ImageFormat.Rgb10a2ui,
|
||||||
TextureFormat.R11G11B10Float => ImageFormat.R11fG11fB10f,
|
TextureFormat.R11G11B10Float => ImageFormat.R11fG11fB10f,
|
||||||
_ => throw new ArgumentException($"Invalid texture format \"{format}\".")
|
_ => throw new ArgumentException($"Invalid texture format \"{format}\"."),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -352,7 +351,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
(_, AggregateType varType) = IoMap.GetSpirvBuiltIn(ioVariable);
|
(_, AggregateType varType) = IoMap.GetSpirvBuiltIn(ioVariable);
|
||||||
AggregateType elemType = varType & AggregateType.ElementTypeMask;
|
AggregateType elemType = varType & AggregateType.ElementTypeMask;
|
||||||
|
|
||||||
if (elemType == AggregateType.S32 || elemType == AggregateType.U32)
|
if (elemType is AggregateType.S32 or AggregateType.U32)
|
||||||
{
|
{
|
||||||
iq = PixelImap.Constant;
|
iq = PixelImap.Constant;
|
||||||
}
|
}
|
||||||
@@ -410,7 +409,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
2 => AggregateType.Vector2,
|
2 => AggregateType.Vector2,
|
||||||
3 => AggregateType.Vector3,
|
3 => AggregateType.Vector3,
|
||||||
4 => AggregateType.Vector4,
|
4 => AggregateType.Vector4,
|
||||||
_ => AggregateType.Invalid
|
_ => AggregateType.Invalid,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -420,7 +419,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
if (!isPerPatch && IoMap.IsPerVertex(ioVariable, context.Config.Stage, isOutput))
|
if (!isPerPatch && IoMap.IsPerVertex(ioVariable, context.Config.Stage, isOutput))
|
||||||
{
|
{
|
||||||
int arraySize = context.Config.Stage == ShaderStage.Geometry ? context.InputVertices : 32;
|
int arraySize = context.Config.Stage == ShaderStage.Geometry ? context.InputVertices : 32;
|
||||||
spvType = context.TypeArray(spvType, context.Constant(context.TypeU32(), (LiteralInteger)arraySize));
|
spvType = context.TypeArray(spvType, context.Constant(context.TypeU32(), arraySize));
|
||||||
|
|
||||||
if (context.Config.GpPassthrough && context.Config.GpuAccessor.QueryHostSupportsGeometryShaderPassthrough())
|
if (context.Config.GpPassthrough && context.Config.GpuAccessor.QueryHostSupportsGeometryShaderPassthrough())
|
||||||
{
|
{
|
||||||
@@ -542,7 +541,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
private static string GetStagePrefix(ShaderStage stage)
|
private static string GetStagePrefix(ShaderStage stage)
|
||||||
{
|
{
|
||||||
return StagePrefixes[(int)stage];
|
return _stagePrefixes[(int)stage];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -15,7 +15,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
ShaderStage.TessellationEvaluation => ExecutionModel.TessellationEvaluation,
|
ShaderStage.TessellationEvaluation => ExecutionModel.TessellationEvaluation,
|
||||||
ShaderStage.Geometry => ExecutionModel.Geometry,
|
ShaderStage.Geometry => ExecutionModel.Geometry,
|
||||||
ShaderStage.Fragment => ExecutionModel.Fragment,
|
ShaderStage.Fragment => ExecutionModel.Fragment,
|
||||||
_ => throw new ArgumentException($"Invalid shader stage \"{stage}\".")
|
_ => throw new ArgumentException($"Invalid shader stage \"{stage}\"."),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -21,12 +21,13 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
MemorySemanticsMask.UniformMemory |
|
MemorySemanticsMask.UniformMemory |
|
||||||
MemorySemanticsMask.AcquireRelease;
|
MemorySemanticsMask.AcquireRelease;
|
||||||
|
|
||||||
private static readonly Func<CodeGenContext, AstOperation, OperationResult>[] InstTable;
|
private static readonly Func<CodeGenContext, AstOperation, OperationResult>[] _instTable;
|
||||||
|
|
||||||
static Instructions()
|
static Instructions()
|
||||||
{
|
{
|
||||||
InstTable = new Func<CodeGenContext, AstOperation, OperationResult>[(int)Instruction.Count];
|
_instTable = new Func<CodeGenContext, AstOperation, OperationResult>[(int)Instruction.Count];
|
||||||
|
|
||||||
|
#pragma warning disable IDE0055 // Disable formatting
|
||||||
Add(Instruction.Absolute, GenerateAbsolute);
|
Add(Instruction.Absolute, GenerateAbsolute);
|
||||||
Add(Instruction.Add, GenerateAdd);
|
Add(Instruction.Add, GenerateAdd);
|
||||||
Add(Instruction.AtomicAdd, GenerateAtomicAdd);
|
Add(Instruction.AtomicAdd, GenerateAtomicAdd);
|
||||||
@@ -141,16 +142,17 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
Add(Instruction.VoteAll, GenerateVoteAll);
|
Add(Instruction.VoteAll, GenerateVoteAll);
|
||||||
Add(Instruction.VoteAllEqual, GenerateVoteAllEqual);
|
Add(Instruction.VoteAllEqual, GenerateVoteAllEqual);
|
||||||
Add(Instruction.VoteAny, GenerateVoteAny);
|
Add(Instruction.VoteAny, GenerateVoteAny);
|
||||||
|
#pragma warning restore IDE0055
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Add(Instruction inst, Func<CodeGenContext, AstOperation, OperationResult> handler)
|
private static void Add(Instruction inst, Func<CodeGenContext, AstOperation, OperationResult> handler)
|
||||||
{
|
{
|
||||||
InstTable[(int)(inst & Instruction.Mask)] = handler;
|
_instTable[(int)(inst & Instruction.Mask)] = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static OperationResult Generate(CodeGenContext context, AstOperation operation)
|
public static OperationResult Generate(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
var handler = InstTable[(int)(operation.Inst & Instruction.Mask)];
|
var handler = _instTable[(int)(operation.Inst & Instruction.Mask)];
|
||||||
if (handler != null)
|
if (handler != null)
|
||||||
{
|
{
|
||||||
return handler(context, operation);
|
return handler(context, operation);
|
||||||
@@ -305,7 +307,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
Debug.Assert(funcId.Type == OperandType.Constant);
|
Debug.Assert(funcId.Type == OperandType.Constant);
|
||||||
|
|
||||||
(var function, var spvFunc) = context.GetFunction(funcId.Value);
|
var (function, spvFunc) = context.GetFunction(funcId.Value);
|
||||||
|
|
||||||
var args = new SpvInstruction[operation.SourcesCount - 1];
|
var args = new SpvInstruction[operation.SourcesCount - 1];
|
||||||
var spvLocals = context.GetLocalForArgsPointers(funcId.Value);
|
var spvLocals = context.GetLocalForArgsPointers(funcId.Value);
|
||||||
@@ -625,11 +627,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
return context.Get(type, texOp.GetSource(srcIndex++));
|
return context.Get(type, texOp.GetSource(srcIndex++));
|
||||||
}
|
}
|
||||||
|
|
||||||
SpvInstruction index = null;
|
|
||||||
|
|
||||||
if (isIndexed)
|
if (isIndexed)
|
||||||
{
|
{
|
||||||
index = Src(AggregateType.S32);
|
Src(AggregateType.S32);
|
||||||
}
|
}
|
||||||
|
|
||||||
int coordsCount = texOp.Type.GetDimensions();
|
int coordsCount = texOp.Type.GetDimensions();
|
||||||
@@ -657,9 +657,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
SpvInstruction value = Src(componentType);
|
SpvInstruction value = Src(componentType);
|
||||||
|
|
||||||
(var imageType, var imageVariable) = context.Images[new TextureMeta(texOp.CbufSlot, texOp.Handle, texOp.Format)];
|
(SpvInstruction imageType, SpvInstruction imageVariable) = context.Images[new TextureMeta(texOp.CbufSlot, texOp.Handle, texOp.Format)];
|
||||||
|
|
||||||
var image = context.Load(imageType, imageVariable);
|
context.Load(imageType, imageVariable);
|
||||||
|
|
||||||
SpvInstruction resultType = context.GetType(componentType);
|
SpvInstruction resultType = context.GetType(componentType);
|
||||||
SpvInstruction imagePointerType = context.TypePointer(StorageClass.Image, resultType);
|
SpvInstruction imagePointerType = context.TypePointer(StorageClass.Image, resultType);
|
||||||
@@ -714,11 +714,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
return context.Get(type, texOp.GetSource(srcIndex++));
|
return context.Get(type, texOp.GetSource(srcIndex++));
|
||||||
}
|
}
|
||||||
|
|
||||||
SpvInstruction index = null;
|
|
||||||
|
|
||||||
if (isIndexed)
|
if (isIndexed)
|
||||||
{
|
{
|
||||||
index = Src(AggregateType.S32);
|
Src(AggregateType.S32);
|
||||||
}
|
}
|
||||||
|
|
||||||
int coordsCount = texOp.Type.GetDimensions();
|
int coordsCount = texOp.Type.GetDimensions();
|
||||||
@@ -744,7 +742,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
pCoords = Src(AggregateType.S32);
|
pCoords = Src(AggregateType.S32);
|
||||||
}
|
}
|
||||||
|
|
||||||
(var imageType, var imageVariable) = context.Images[new TextureMeta(texOp.CbufSlot, texOp.Handle, texOp.Format)];
|
var (imageType, imageVariable) = context.Images[new TextureMeta(texOp.CbufSlot, texOp.Handle, texOp.Format)];
|
||||||
|
|
||||||
var image = context.Load(imageType, imageVariable);
|
var image = context.Load(imageType, imageVariable);
|
||||||
var imageComponentType = context.GetType(componentType);
|
var imageComponentType = context.GetType(componentType);
|
||||||
@@ -778,11 +776,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
return context.Get(type, texOp.GetSource(srcIndex++));
|
return context.Get(type, texOp.GetSource(srcIndex++));
|
||||||
}
|
}
|
||||||
|
|
||||||
SpvInstruction index = null;
|
|
||||||
|
|
||||||
if (isIndexed)
|
if (isIndexed)
|
||||||
{
|
{
|
||||||
index = Src(AggregateType.S32);
|
Src(AggregateType.S32);
|
||||||
}
|
}
|
||||||
|
|
||||||
int coordsCount = texOp.Type.GetDimensions();
|
int coordsCount = texOp.Type.GetDimensions();
|
||||||
@@ -833,7 +829,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
var texel = context.CompositeConstruct(context.TypeVector(context.GetType(componentType), ComponentsCount), cElems);
|
var texel = context.CompositeConstruct(context.TypeVector(context.GetType(componentType), ComponentsCount), cElems);
|
||||||
|
|
||||||
(var imageType, var imageVariable) = context.Images[new TextureMeta(texOp.CbufSlot, texOp.Handle, texOp.Format)];
|
var (imageType, imageVariable) = context.Images[new TextureMeta(texOp.CbufSlot, texOp.Handle, texOp.Format)];
|
||||||
|
|
||||||
var image = context.Load(imageType, imageVariable);
|
var image = context.Load(imageType, imageVariable);
|
||||||
|
|
||||||
@@ -886,11 +882,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
return context.Get(type, texOp.GetSource(srcIndex++));
|
return context.Get(type, texOp.GetSource(srcIndex++));
|
||||||
}
|
}
|
||||||
|
|
||||||
SpvInstruction index = null;
|
|
||||||
|
|
||||||
if (isIndexed)
|
if (isIndexed)
|
||||||
{
|
{
|
||||||
index = Src(AggregateType.S32);
|
Src(AggregateType.S32);
|
||||||
}
|
}
|
||||||
|
|
||||||
int pCount = texOp.Type.GetDimensions();
|
int pCount = texOp.Type.GetDimensions();
|
||||||
@@ -916,7 +910,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
var meta = new TextureMeta(texOp.CbufSlot, texOp.Handle, texOp.Format);
|
var meta = new TextureMeta(texOp.CbufSlot, texOp.Handle, texOp.Format);
|
||||||
|
|
||||||
(_, var sampledImageType, var sampledImageVariable) = context.Samplers[meta];
|
var (_, sampledImageType, sampledImageVariable) = context.Samplers[meta];
|
||||||
|
|
||||||
var image = context.Load(sampledImageType, sampledImageVariable);
|
var image = context.Load(sampledImageType, sampledImageVariable);
|
||||||
|
|
||||||
@@ -973,7 +967,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
loopBlock = loopBlock.Parent;
|
loopBlock = loopBlock.Parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
(var loopTarget, var continueTarget) = context.LoopTargets[loopBlock];
|
(_, SpvInstruction continueTarget) = context.LoopTargets[loopBlock];
|
||||||
|
|
||||||
context.Branch(continueTarget);
|
context.Branch(continueTarget);
|
||||||
|
|
||||||
@@ -1307,11 +1301,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
return context.Get(type, texOp.GetSource(srcIndex++));
|
return context.Get(type, texOp.GetSource(srcIndex++));
|
||||||
}
|
}
|
||||||
|
|
||||||
SpvInstruction index = null;
|
|
||||||
|
|
||||||
if (isIndexed)
|
if (isIndexed)
|
||||||
{
|
{
|
||||||
index = Src(AggregateType.S32);
|
Src(AggregateType.S32);
|
||||||
}
|
}
|
||||||
|
|
||||||
int coordsCount = texOp.Type.GetDimensions();
|
int coordsCount = texOp.Type.GetDimensions();
|
||||||
@@ -1395,7 +1387,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
derivatives = new[]
|
derivatives = new[]
|
||||||
{
|
{
|
||||||
AssembleDerivativesVector(coordsCount), // dPdx
|
AssembleDerivativesVector(coordsCount), // dPdx
|
||||||
AssembleDerivativesVector(coordsCount) // dPdy
|
AssembleDerivativesVector(coordsCount), // dPdy
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1445,7 +1437,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
AssembleOffsetVector(coordsCount),
|
AssembleOffsetVector(coordsCount),
|
||||||
AssembleOffsetVector(coordsCount),
|
AssembleOffsetVector(coordsCount),
|
||||||
AssembleOffsetVector(coordsCount),
|
AssembleOffsetVector(coordsCount),
|
||||||
AssembleOffsetVector(coordsCount)
|
AssembleOffsetVector(coordsCount),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1521,7 +1513,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
var meta = new TextureMeta(texOp.CbufSlot, texOp.Handle, texOp.Format);
|
var meta = new TextureMeta(texOp.CbufSlot, texOp.Handle, texOp.Format);
|
||||||
|
|
||||||
(var imageType, var sampledImageType, var sampledImageVariable) = context.Samplers[meta];
|
var (imageType, sampledImageType, sampledImageVariable) = context.Samplers[meta];
|
||||||
|
|
||||||
var image = context.Load(sampledImageType, sampledImageVariable);
|
var image = context.Load(sampledImageType, sampledImageVariable);
|
||||||
|
|
||||||
@@ -1595,16 +1587,14 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
bool isIndexed = (texOp.Type & SamplerType.Indexed) != 0;
|
bool isIndexed = (texOp.Type & SamplerType.Indexed) != 0;
|
||||||
|
|
||||||
SpvInstruction index = null;
|
|
||||||
|
|
||||||
if (isIndexed)
|
if (isIndexed)
|
||||||
{
|
{
|
||||||
index = context.GetS32(texOp.GetSource(0));
|
context.GetS32(texOp.GetSource(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
var meta = new TextureMeta(texOp.CbufSlot, texOp.Handle, texOp.Format);
|
var meta = new TextureMeta(texOp.CbufSlot, texOp.Handle, texOp.Format);
|
||||||
|
|
||||||
(var imageType, var sampledImageType, var sampledImageVariable) = context.Samplers[meta];
|
(SpvInstruction imageType, SpvInstruction sampledImageType, SpvInstruction sampledImageVariable) = context.Samplers[meta];
|
||||||
|
|
||||||
var image = context.Load(sampledImageType, sampledImageVariable);
|
var image = context.Load(sampledImageType, sampledImageVariable);
|
||||||
image = context.Image(imageType, image);
|
image = context.Image(imageType, image);
|
||||||
@@ -1809,12 +1799,12 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
{
|
{
|
||||||
case StorageKind.ConstantBuffer:
|
case StorageKind.ConstantBuffer:
|
||||||
case StorageKind.StorageBuffer:
|
case StorageKind.StorageBuffer:
|
||||||
if (!(operation.GetSource(srcIndex++) is AstOperand bindingIndex) || bindingIndex.Type != OperandType.Constant)
|
if (operation.GetSource(srcIndex++) is not AstOperand bindingIndex || bindingIndex.Type != OperandType.Constant)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"First input of {operation.Inst} with {storageKind} storage must be a constant operand.");
|
throw new InvalidOperationException($"First input of {operation.Inst} with {storageKind} storage must be a constant operand.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(operation.GetSource(srcIndex) is AstOperand fieldIndex) || fieldIndex.Type != OperandType.Constant)
|
if (operation.GetSource(srcIndex) is not AstOperand fieldIndex || fieldIndex.Type != OperandType.Constant)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"Second input of {operation.Inst} with {storageKind} storage must be a constant operand.");
|
throw new InvalidOperationException($"Second input of {operation.Inst} with {storageKind} storage must be a constant operand.");
|
||||||
}
|
}
|
||||||
@@ -1833,7 +1823,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
case StorageKind.LocalMemory:
|
case StorageKind.LocalMemory:
|
||||||
case StorageKind.SharedMemory:
|
case StorageKind.SharedMemory:
|
||||||
if (!(operation.GetSource(srcIndex++) is AstOperand bindingId) || bindingId.Type != OperandType.Constant)
|
if (operation.GetSource(srcIndex++) is not AstOperand { Type: OperandType.Constant } bindingId)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"First input of {operation.Inst} with {storageKind} storage must be a constant operand.");
|
throw new InvalidOperationException($"First input of {operation.Inst} with {storageKind} storage must be a constant operand.");
|
||||||
}
|
}
|
||||||
@@ -1856,7 +1846,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
case StorageKind.InputPerPatch:
|
case StorageKind.InputPerPatch:
|
||||||
case StorageKind.Output:
|
case StorageKind.Output:
|
||||||
case StorageKind.OutputPerPatch:
|
case StorageKind.OutputPerPatch:
|
||||||
if (!(operation.GetSource(srcIndex++) is AstOperand varId) || varId.Type != OperandType.Constant)
|
if (operation.GetSource(srcIndex++) is not AstOperand varId || varId.Type != OperandType.Constant)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"First input of {operation.Inst} with {storageKind} storage must be a constant operand.");
|
throw new InvalidOperationException($"First input of {operation.Inst} with {storageKind} storage must be a constant operand.");
|
||||||
}
|
}
|
||||||
@@ -1869,7 +1859,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
if (context.Config.HasPerLocationInputOrOutput(ioVariable, isOutput))
|
if (context.Config.HasPerLocationInputOrOutput(ioVariable, isOutput))
|
||||||
{
|
{
|
||||||
if (!(operation.GetSource(srcIndex++) is AstOperand vecIndex) || vecIndex.Type != OperandType.Constant)
|
if (operation.GetSource(srcIndex++) is not AstOperand vecIndex || vecIndex.Type != OperandType.Constant)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"Second input of {operation.Inst} with {storageKind} storage must be a constant operand.");
|
throw new InvalidOperationException($"Second input of {operation.Inst} with {storageKind} storage must be a constant operand.");
|
||||||
}
|
}
|
||||||
@@ -1964,7 +1954,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
private static SpvInstruction GetScalarInput(CodeGenContext context, IoVariable ioVariable)
|
private static SpvInstruction GetScalarInput(CodeGenContext context, IoVariable ioVariable)
|
||||||
{
|
{
|
||||||
(_, var varType) = IoMap.GetSpirvBuiltIn(ioVariable);
|
var (_, varType) = IoMap.GetSpirvBuiltIn(ioVariable);
|
||||||
varType &= AggregateType.ElementTypeMask;
|
varType &= AggregateType.ElementTypeMask;
|
||||||
|
|
||||||
var ioDefinition = new IoDefinition(StorageKind.Input, ioVariable);
|
var ioDefinition = new IoDefinition(StorageKind.Input, ioVariable);
|
||||||
|
@@ -45,7 +45,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
IoVariable.VertexIndex => (BuiltIn.VertexIndex, AggregateType.S32),
|
IoVariable.VertexIndex => (BuiltIn.VertexIndex, AggregateType.S32),
|
||||||
IoVariable.ViewportIndex => (BuiltIn.ViewportIndex, AggregateType.S32),
|
IoVariable.ViewportIndex => (BuiltIn.ViewportIndex, AggregateType.S32),
|
||||||
IoVariable.ViewportMask => (BuiltIn.ViewportMaskNV, AggregateType.Array | AggregateType.S32),
|
IoVariable.ViewportMask => (BuiltIn.ViewportMaskNV, AggregateType.Array | AggregateType.S32),
|
||||||
_ => (default, AggregateType.Invalid)
|
_ => (default, AggregateType.Invalid),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
IoVariable.TessellationLevelOuter => 4,
|
IoVariable.TessellationLevelOuter => 4,
|
||||||
IoVariable.ViewportMask => 1,
|
IoVariable.ViewportMask => 1,
|
||||||
IoVariable.UserDefined => MaxAttributes,
|
IoVariable.UserDefined => MaxAttributes,
|
||||||
_ => 1
|
_ => 1,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,9 +75,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
case IoVariable.PointCoord:
|
case IoVariable.PointCoord:
|
||||||
case IoVariable.ViewportMask:
|
case IoVariable.ViewportMask:
|
||||||
return !isOutput &&
|
return !isOutput &&
|
||||||
(stage == ShaderStage.TessellationControl ||
|
stage is ShaderStage.TessellationControl or ShaderStage.TessellationEvaluation or ShaderStage.Geometry;
|
||||||
stage == ShaderStage.TessellationEvaluation ||
|
|
||||||
stage == ShaderStage.Geometry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@@ -5,7 +5,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
{
|
{
|
||||||
readonly struct OperationResult
|
readonly struct OperationResult
|
||||||
{
|
{
|
||||||
public static OperationResult Invalid => new OperationResult(AggregateType.Invalid, null);
|
public static OperationResult Invalid => new(AggregateType.Invalid, null);
|
||||||
|
|
||||||
public AggregateType Type { get; }
|
public AggregateType Type { get; }
|
||||||
public Instruction Value { get; }
|
public Instruction Value { get; }
|
||||||
|
@@ -17,15 +17,15 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
{
|
{
|
||||||
// Resource pools for Spirv generation. Note: Increase count when more threads are being used.
|
// Resource pools for Spirv generation. Note: Increase count when more threads are being used.
|
||||||
private const int GeneratorPoolCount = 1;
|
private const int GeneratorPoolCount = 1;
|
||||||
private static ObjectPool<SpvInstructionPool> InstructionPool;
|
private static readonly ObjectPool<SpvInstructionPool> _instructionPool;
|
||||||
private static ObjectPool<SpvLiteralIntegerPool> IntegerPool;
|
private static readonly ObjectPool<SpvLiteralIntegerPool> _integerPool;
|
||||||
private static object PoolLock;
|
private static readonly object _poolLock;
|
||||||
|
|
||||||
static SpirvGenerator()
|
static SpirvGenerator()
|
||||||
{
|
{
|
||||||
InstructionPool = new (() => new SpvInstructionPool(), GeneratorPoolCount);
|
_instructionPool = new(() => new SpvInstructionPool(), GeneratorPoolCount);
|
||||||
IntegerPool = new (() => new SpvLiteralIntegerPool(), GeneratorPoolCount);
|
_integerPool = new(() => new SpvLiteralIntegerPool(), GeneratorPoolCount);
|
||||||
PoolLock = new object();
|
_poolLock = new object();
|
||||||
}
|
}
|
||||||
|
|
||||||
private const HelperFunctionsMask NeedsInvocationIdMask =
|
private const HelperFunctionsMask NeedsInvocationIdMask =
|
||||||
@@ -40,13 +40,13 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
SpvInstructionPool instPool;
|
SpvInstructionPool instPool;
|
||||||
SpvLiteralIntegerPool integerPool;
|
SpvLiteralIntegerPool integerPool;
|
||||||
|
|
||||||
lock (PoolLock)
|
lock (_poolLock)
|
||||||
{
|
{
|
||||||
instPool = InstructionPool.Allocate();
|
instPool = _instructionPool.Allocate();
|
||||||
integerPool = IntegerPool.Allocate();
|
integerPool = _integerPool.Allocate();
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeGenContext context = new CodeGenContext(info, config, instPool, integerPool);
|
CodeGenContext context = new(info, config, instPool, integerPool);
|
||||||
|
|
||||||
context.AddCapability(Capability.GroupNonUniformBallot);
|
context.AddCapability(Capability.GroupNonUniformBallot);
|
||||||
context.AddCapability(Capability.GroupNonUniformShuffle);
|
context.AddCapability(Capability.GroupNonUniformShuffle);
|
||||||
@@ -133,10 +133,10 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
byte[] result = context.Generate();
|
byte[] result = context.Generate();
|
||||||
|
|
||||||
lock (PoolLock)
|
lock (_poolLock)
|
||||||
{
|
{
|
||||||
InstructionPool.Release(instPool);
|
_instructionPool.Release(instPool);
|
||||||
IntegerPool.Release(integerPool);
|
_integerPool.Release(integerPool);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -144,7 +144,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
private static void Generate(CodeGenContext context, StructuredProgramInfo info, int funcIndex)
|
private static void Generate(CodeGenContext context, StructuredProgramInfo info, int funcIndex)
|
||||||
{
|
{
|
||||||
(var function, var spvFunc) = context.GetFunction(funcIndex);
|
var (function, spvFunc) = context.GetFunction(funcIndex);
|
||||||
|
|
||||||
context.CurrentFunction = function;
|
context.CurrentFunction = function;
|
||||||
context.AddFunction(spvFunc);
|
context.AddFunction(spvFunc);
|
||||||
@@ -160,7 +160,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
Generate(context, function.MainBlock);
|
Generate(context, function.MainBlock);
|
||||||
|
|
||||||
// Functions must always end with a return.
|
// Functions must always end with a return.
|
||||||
if (!(function.MainBlock.Last is AstOperation operation) ||
|
if (function.MainBlock.Last is not AstOperation operation ||
|
||||||
(operation.Inst != Instruction.Return && operation.Inst != Instruction.Discard))
|
(operation.Inst != Instruction.Return && operation.Inst != Instruction.Discard))
|
||||||
{
|
{
|
||||||
context.Return();
|
context.Return();
|
||||||
@@ -232,7 +232,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
InputTopology.LinesAdjacency => ExecutionMode.InputLinesAdjacency,
|
InputTopology.LinesAdjacency => ExecutionMode.InputLinesAdjacency,
|
||||||
InputTopology.Triangles => ExecutionMode.Triangles,
|
InputTopology.Triangles => ExecutionMode.Triangles,
|
||||||
InputTopology.TrianglesAdjacency => ExecutionMode.InputTrianglesAdjacency,
|
InputTopology.TrianglesAdjacency => ExecutionMode.InputTrianglesAdjacency,
|
||||||
_ => throw new InvalidOperationException($"Invalid input topology \"{inputTopology}\".")
|
_ => throw new InvalidOperationException($"Invalid input topology \"{inputTopology}\"."),
|
||||||
});
|
});
|
||||||
|
|
||||||
context.AddExecutionMode(spvFunc, ExecutionMode.Invocations, (SpvLiteralInteger)context.Config.ThreadsPerInputPrimitive);
|
context.AddExecutionMode(spvFunc, ExecutionMode.Invocations, (SpvLiteralInteger)context.Config.ThreadsPerInputPrimitive);
|
||||||
@@ -242,7 +242,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
OutputTopology.PointList => ExecutionMode.OutputPoints,
|
OutputTopology.PointList => ExecutionMode.OutputPoints,
|
||||||
OutputTopology.LineStrip => ExecutionMode.OutputLineStrip,
|
OutputTopology.LineStrip => ExecutionMode.OutputLineStrip,
|
||||||
OutputTopology.TriangleStrip => ExecutionMode.OutputTriangleStrip,
|
OutputTopology.TriangleStrip => ExecutionMode.OutputTriangleStrip,
|
||||||
_ => throw new InvalidOperationException($"Invalid output topology \"{context.Config.OutputTopology}\".")
|
_ => throw new InvalidOperationException($"Invalid output topology \"{context.Config.OutputTopology}\"."),
|
||||||
});
|
});
|
||||||
|
|
||||||
int maxOutputVertices = context.Config.GpPassthrough ? context.InputVertices : context.Config.MaxOutputVertices;
|
int maxOutputVertices = context.Config.GpPassthrough ? context.InputVertices : context.Config.MaxOutputVertices;
|
||||||
@@ -294,7 +294,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
private static void Generate(CodeGenContext context, AstBlock block)
|
private static void Generate(CodeGenContext context, AstBlock block)
|
||||||
{
|
{
|
||||||
AstBlockVisitor visitor = new AstBlockVisitor(block);
|
AstBlockVisitor visitor = new(block);
|
||||||
|
|
||||||
var loopTargets = new Dictionary<AstBlock, (SpvInstruction, SpvInstruction)>();
|
var loopTargets = new Dictionary<AstBlock, (SpvInstruction, SpvInstruction)>();
|
||||||
|
|
||||||
@@ -346,7 +346,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
// if the condition is true.
|
// if the condition is true.
|
||||||
AstBlock mergeBlock = e.Block.Parent;
|
AstBlock mergeBlock = e.Block.Parent;
|
||||||
|
|
||||||
(var loopTarget, var continueTarget) = loopTargets[e.Block];
|
var (loopTarget, continueTarget) = loopTargets[e.Block];
|
||||||
|
|
||||||
context.Branch(continueTarget);
|
context.Branch(continueTarget);
|
||||||
context.AddLabel(continueTarget);
|
context.AddLabel(continueTarget);
|
||||||
|
@@ -148,7 +148,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||||||
{
|
{
|
||||||
if (OpCodes.Count != 0)
|
if (OpCodes.Count != 0)
|
||||||
{
|
{
|
||||||
return OpCodes[OpCodes.Count - 1];
|
return OpCodes[^1];
|
||||||
}
|
}
|
||||||
|
|
||||||
return default;
|
return default;
|
||||||
|
@@ -3,7 +3,6 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Shader.Decoders
|
namespace Ryujinx.Graphics.Shader.Decoders
|
||||||
@@ -12,8 +11,8 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||||||
{
|
{
|
||||||
public static DecodedProgram Decode(ShaderConfig config, ulong startAddress)
|
public static DecodedProgram Decode(ShaderConfig config, ulong startAddress)
|
||||||
{
|
{
|
||||||
Queue<DecodedFunction> functionsQueue = new Queue<DecodedFunction>();
|
Queue<DecodedFunction> functionsQueue = new();
|
||||||
Dictionary<ulong, DecodedFunction> functionsVisited = new Dictionary<ulong, DecodedFunction>();
|
Dictionary<ulong, DecodedFunction> functionsVisited = new();
|
||||||
|
|
||||||
DecodedFunction EnqueueFunction(ulong address)
|
DecodedFunction EnqueueFunction(ulong address)
|
||||||
{
|
{
|
||||||
@@ -30,9 +29,9 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||||||
|
|
||||||
while (functionsQueue.TryDequeue(out DecodedFunction currentFunction))
|
while (functionsQueue.TryDequeue(out DecodedFunction currentFunction))
|
||||||
{
|
{
|
||||||
List<Block> blocks = new List<Block>();
|
List<Block> blocks = new();
|
||||||
Queue<Block> workQueue = new Queue<Block>();
|
Queue<Block> workQueue = new();
|
||||||
Dictionary<ulong, Block> visited = new Dictionary<ulong, Block>();
|
Dictionary<ulong, Block> visited = new();
|
||||||
|
|
||||||
Block GetBlock(ulong blkAddress)
|
Block GetBlock(ulong blkAddress)
|
||||||
{
|
{
|
||||||
@@ -273,12 +272,12 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||||||
int offset;
|
int offset;
|
||||||
int count = 1;
|
int count = 1;
|
||||||
bool isStore = false;
|
bool isStore = false;
|
||||||
bool indexed = false;
|
bool indexed;
|
||||||
bool perPatch = false;
|
bool perPatch = false;
|
||||||
|
|
||||||
if (name == InstName.Ast)
|
if (name == InstName.Ast)
|
||||||
{
|
{
|
||||||
InstAst opAst = new InstAst(opCode);
|
InstAst opAst = new(opCode);
|
||||||
count = (int)opAst.AlSize + 1;
|
count = (int)opAst.AlSize + 1;
|
||||||
offset = opAst.Imm11;
|
offset = opAst.Imm11;
|
||||||
indexed = opAst.Phys;
|
indexed = opAst.Phys;
|
||||||
@@ -287,7 +286,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||||||
}
|
}
|
||||||
else if (name == InstName.Ald)
|
else if (name == InstName.Ald)
|
||||||
{
|
{
|
||||||
InstAld opAld = new InstAld(opCode);
|
InstAld opAld = new(opCode);
|
||||||
count = (int)opAld.AlSize + 1;
|
count = (int)opAld.AlSize + 1;
|
||||||
offset = opAld.Imm11;
|
offset = opAld.Imm11;
|
||||||
indexed = opAld.Phys;
|
indexed = opAld.Phys;
|
||||||
@@ -296,7 +295,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||||||
}
|
}
|
||||||
else /* if (name == InstName.Ipa) */
|
else /* if (name == InstName.Ipa) */
|
||||||
{
|
{
|
||||||
InstIpa opIpa = new InstIpa(opCode);
|
InstIpa opIpa = new(opCode);
|
||||||
offset = opIpa.Imm10;
|
offset = opIpa.Imm10;
|
||||||
indexed = opIpa.Idx;
|
indexed = opIpa.Idx;
|
||||||
}
|
}
|
||||||
@@ -370,7 +369,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||||||
|
|
||||||
private static bool IsUnconditional(ref InstOp op)
|
private static bool IsUnconditional(ref InstOp op)
|
||||||
{
|
{
|
||||||
InstConditional condOp = new InstConditional(op.RawOpCode);
|
InstConditional condOp = new(op.RawOpCode);
|
||||||
|
|
||||||
if ((op.Name == InstName.Bra || op.Name == InstName.Exit) && condOp.Ccc != Ccc.T)
|
if ((op.Name == InstName.Bra || op.Name == InstName.Exit) && condOp.Ccc != Ccc.T)
|
||||||
{
|
{
|
||||||
@@ -391,9 +390,9 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||||||
|
|
||||||
if (lastOp.Name == InstName.Brx && block.Successors.Count == (hasNext ? 1 : 0))
|
if (lastOp.Name == InstName.Brx && block.Successors.Count == (hasNext ? 1 : 0))
|
||||||
{
|
{
|
||||||
HashSet<ulong> visited = new HashSet<ulong>();
|
HashSet<ulong> visited = new();
|
||||||
|
|
||||||
InstBrx opBrx = new InstBrx(lastOp.RawOpCode);
|
InstBrx opBrx = new(lastOp.RawOpCode);
|
||||||
ulong baseOffset = lastOp.GetAbsoluteAddress();
|
ulong baseOffset = lastOp.GetAbsoluteAddress();
|
||||||
|
|
||||||
// An indirect branch could go anywhere,
|
// An indirect branch could go anywhere,
|
||||||
@@ -437,7 +436,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||||||
// On a successful match, "BaseOffset" is the offset in bytes where the jump offsets are
|
// On a successful match, "BaseOffset" is the offset in bytes where the jump offsets are
|
||||||
// located on the constant buffer, and "UpperBound" is the total number of offsets for the BRX, minus 1.
|
// located on the constant buffer, and "UpperBound" is the total number of offsets for the BRX, minus 1.
|
||||||
|
|
||||||
HashSet<Block> visited = new HashSet<Block>();
|
HashSet<Block> visited = new();
|
||||||
|
|
||||||
var ldcLocation = FindFirstRegWrite(visited, new BlockLocation(block, block.OpCodes.Count - 1), brxReg);
|
var ldcLocation = FindFirstRegWrite(visited, new BlockLocation(block, block.OpCodes.Count - 1), brxReg);
|
||||||
if (ldcLocation.Block == null || ldcLocation.Block.OpCodes[ldcLocation.Index].Name != InstName.Ldc)
|
if (ldcLocation.Block == null || ldcLocation.Block.OpCodes[ldcLocation.Index].Name != InstName.Ldc)
|
||||||
@@ -507,7 +506,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||||||
|
|
||||||
private static BlockLocation FindFirstRegWrite(HashSet<Block> visited, BlockLocation location, int regIndex)
|
private static BlockLocation FindFirstRegWrite(HashSet<Block> visited, BlockLocation location, int regIndex)
|
||||||
{
|
{
|
||||||
Queue<BlockLocation> toVisit = new Queue<BlockLocation>();
|
Queue<BlockLocation> toVisit = new();
|
||||||
toVisit.Enqueue(location);
|
toVisit.Enqueue(location);
|
||||||
visited.Add(location.Block);
|
visited.Add(location.Block);
|
||||||
|
|
||||||
@@ -554,10 +553,10 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||||||
{
|
{
|
||||||
Brk,
|
Brk,
|
||||||
Cont,
|
Cont,
|
||||||
Sync
|
Sync,
|
||||||
}
|
}
|
||||||
|
|
||||||
private struct PathBlockState
|
private readonly struct PathBlockState
|
||||||
{
|
{
|
||||||
public Block Block { get; }
|
public Block Block { get; }
|
||||||
|
|
||||||
@@ -565,13 +564,13 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||||||
{
|
{
|
||||||
None,
|
None,
|
||||||
PopPushOp,
|
PopPushOp,
|
||||||
PushBranchOp
|
PushBranchOp,
|
||||||
}
|
}
|
||||||
|
|
||||||
private RestoreType _restoreType;
|
private readonly RestoreType _restoreType;
|
||||||
|
|
||||||
private ulong _restoreValue;
|
private readonly ulong _restoreValue;
|
||||||
private MergeType _restoreMergeType;
|
private readonly MergeType _restoreMergeType;
|
||||||
|
|
||||||
public bool ReturningFromVisit => _restoreType != RestoreType.None;
|
public bool ReturningFromVisit => _restoreType != RestoreType.None;
|
||||||
|
|
||||||
@@ -622,9 +621,9 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||||||
|
|
||||||
Block target = blocks[pushOp.GetAbsoluteAddress()];
|
Block target = blocks[pushOp.GetAbsoluteAddress()];
|
||||||
|
|
||||||
Stack<PathBlockState> workQueue = new Stack<PathBlockState>();
|
Stack<PathBlockState> workQueue = new();
|
||||||
HashSet<Block> visited = new HashSet<Block>();
|
HashSet<Block> visited = new();
|
||||||
Stack<(ulong, MergeType)> branchStack = new Stack<(ulong, MergeType)>();
|
Stack<(ulong, MergeType)> branchStack = new();
|
||||||
|
|
||||||
void Push(PathBlockState pbs)
|
void Push(PathBlockState pbs)
|
||||||
{
|
{
|
||||||
@@ -759,7 +758,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||||||
{
|
{
|
||||||
InstName.Pbk => MergeType.Brk,
|
InstName.Pbk => MergeType.Brk,
|
||||||
InstName.Pcnt => MergeType.Cont,
|
InstName.Pcnt => MergeType.Cont,
|
||||||
_ => MergeType.Sync
|
_ => MergeType.Sync,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -769,7 +768,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||||||
{
|
{
|
||||||
InstName.Brk => MergeType.Brk,
|
InstName.Brk => MergeType.Brk,
|
||||||
InstName.Cont => MergeType.Cont,
|
InstName.Cont => MergeType.Cont,
|
||||||
_ => MergeType.Sync
|
_ => MergeType.Sync,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -26,6 +26,6 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||||||
Tex = 1 << 12,
|
Tex = 1 << 12,
|
||||||
TexB = 1 << 13,
|
TexB = 1 << 13,
|
||||||
Bra = 1 << 14,
|
Bra = 1 << 14,
|
||||||
NoPred = 1 << 15
|
NoPred = 1 << 15,
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -24,13 +24,14 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static TableEntry[] _opCodes;
|
private static readonly TableEntry[] _opCodes;
|
||||||
|
|
||||||
static InstTable()
|
static InstTable()
|
||||||
{
|
{
|
||||||
_opCodes = new TableEntry[1 << EncodingBits];
|
_opCodes = new TableEntry[1 << EncodingBits];
|
||||||
|
|
||||||
#region Instructions
|
#region Instructions
|
||||||
|
#pragma warning disable IDE0055 // Disable formatting
|
||||||
Add("1110111110100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Al2p, InstEmit.Al2p, InstProps.Rd | InstProps.Ra);
|
Add("1110111110100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Al2p, InstEmit.Al2p, InstProps.Rd | InstProps.Ra);
|
||||||
Add("1110111111011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Ald, InstEmit.Ald, InstProps.Rd | InstProps.Ra);
|
Add("1110111111011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Ald, InstEmit.Ald, InstProps.Rd | InstProps.Ra);
|
||||||
Add("1110111111110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Ast, InstEmit.Ast, InstProps.Ra | InstProps.Rb2 | InstProps.Rc);
|
Add("1110111111110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Ast, InstEmit.Ast, InstProps.Ra | InstProps.Rb2 | InstProps.Rc);
|
||||||
@@ -325,6 +326,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||||||
Add("0011011x00xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Xmad, InstEmit.XmadI, InstProps.Rd | InstProps.Ra | InstProps.Ib | InstProps.Rc);
|
Add("0011011x00xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Xmad, InstEmit.XmadI, InstProps.Rd | InstProps.Ra | InstProps.Ib | InstProps.Rc);
|
||||||
Add("0100111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Xmad, InstEmit.XmadC, InstProps.Rd | InstProps.Ra | InstProps.Rc);
|
Add("0100111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Xmad, InstEmit.XmadC, InstProps.Rd | InstProps.Ra | InstProps.Rc);
|
||||||
Add("010100010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Xmad, InstEmit.XmadRc, InstProps.Rd | InstProps.Ra | InstProps.Rc);
|
Add("010100010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Xmad, InstEmit.XmadRc, InstProps.Rd | InstProps.Ra | InstProps.Rc);
|
||||||
|
#pragma warning restore IDE0055
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -357,7 +359,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||||||
|
|
||||||
xMask = ~xMask;
|
xMask = ~xMask;
|
||||||
|
|
||||||
TableEntry entry = new TableEntry(name, emitter, props, xBits);
|
TableEntry entry = new(name, emitter, props, xBits);
|
||||||
|
|
||||||
for (int index = 0; index < (1 << xBits); index++)
|
for (int index = 0; index < (1 << xBits); index++)
|
||||||
{
|
{
|
||||||
|
@@ -6,7 +6,7 @@ namespace Ryujinx.Graphics.Shader
|
|||||||
Lines,
|
Lines,
|
||||||
LinesAdjacency,
|
LinesAdjacency,
|
||||||
Triangles,
|
Triangles,
|
||||||
TrianglesAdjacency
|
TrianglesAdjacency,
|
||||||
}
|
}
|
||||||
|
|
||||||
static class InputTopologyExtensions
|
static class InputTopologyExtensions
|
||||||
@@ -20,7 +20,7 @@ namespace Ryujinx.Graphics.Shader
|
|||||||
InputTopology.LinesAdjacency => "lines_adjacency",
|
InputTopology.LinesAdjacency => "lines_adjacency",
|
||||||
InputTopology.Triangles => "triangles",
|
InputTopology.Triangles => "triangles",
|
||||||
InputTopology.TrianglesAdjacency => "triangles_adjacency",
|
InputTopology.TrianglesAdjacency => "triangles_adjacency",
|
||||||
_ => "points"
|
_ => "points",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ namespace Ryujinx.Graphics.Shader
|
|||||||
InputTopology.LinesAdjacency => 2,
|
InputTopology.LinesAdjacency => 2,
|
||||||
InputTopology.Triangles or
|
InputTopology.Triangles or
|
||||||
InputTopology.TrianglesAdjacency => 3,
|
InputTopology.TrianglesAdjacency => 3,
|
||||||
_ => 1
|
_ => 1,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||||
using Ryujinx.Graphics.Shader.Translation;
|
using Ryujinx.Graphics.Shader.Translation;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Shader.Instructions
|
namespace Ryujinx.Graphics.Shader.Instructions
|
||||||
@@ -21,10 +20,10 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
Tessellation = TessellationControl | TessellationEvaluation,
|
Tessellation = TessellationControl | TessellationEvaluation,
|
||||||
VertexTessellationGeometry = Vertex | Tessellation | Geometry,
|
VertexTessellationGeometry = Vertex | Tessellation | Geometry,
|
||||||
TessellationGeometryFragment = Tessellation | Geometry | Fragment,
|
TessellationGeometryFragment = Tessellation | Geometry | Fragment,
|
||||||
AllGraphics = Vertex | Tessellation | Geometry | Fragment
|
AllGraphics = Vertex | Tessellation | Geometry | Fragment,
|
||||||
}
|
}
|
||||||
|
|
||||||
private struct AttributeEntry
|
private readonly struct AttributeEntry
|
||||||
{
|
{
|
||||||
public int BaseOffset { get; }
|
public int BaseOffset { get; }
|
||||||
public AggregateType Type { get; }
|
public AggregateType Type { get; }
|
||||||
@@ -344,7 +343,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
AggregateType.Vector2 => 2,
|
AggregateType.Vector2 => 2,
|
||||||
AggregateType.Vector3 => 3,
|
AggregateType.Vector3 => 3,
|
||||||
AggregateType.Vector4 => 4,
|
AggregateType.Vector4 => 4,
|
||||||
_ => 1
|
_ => 1,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -7,350 +7,350 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
public static void AtomCas(EmitterContext context)
|
public static void AtomCas(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstAtomCas op = context.GetOp<InstAtomCas>();
|
context.GetOp<InstAtomCas>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction AtomCas is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction AtomCas is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void AtomsCas(EmitterContext context)
|
public static void AtomsCas(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstAtomsCas op = context.GetOp<InstAtomsCas>();
|
context.GetOp<InstAtomsCas>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction AtomsCas is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction AtomsCas is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void B2r(EmitterContext context)
|
public static void B2r(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstB2r op = context.GetOp<InstB2r>();
|
context.GetOp<InstB2r>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction B2r is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction B2r is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Bpt(EmitterContext context)
|
public static void Bpt(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstBpt op = context.GetOp<InstBpt>();
|
context.GetOp<InstBpt>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction Bpt is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction Bpt is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Cctl(EmitterContext context)
|
public static void Cctl(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstCctl op = context.GetOp<InstCctl>();
|
context.GetOp<InstCctl>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction Cctl is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction Cctl is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Cctll(EmitterContext context)
|
public static void Cctll(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstCctll op = context.GetOp<InstCctll>();
|
context.GetOp<InstCctll>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction Cctll is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction Cctll is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Cctlt(EmitterContext context)
|
public static void Cctlt(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstCctlt op = context.GetOp<InstCctlt>();
|
context.GetOp<InstCctlt>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction Cctlt is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction Cctlt is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Cs2r(EmitterContext context)
|
public static void Cs2r(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstCs2r op = context.GetOp<InstCs2r>();
|
context.GetOp<InstCs2r>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction Cs2r is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction Cs2r is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void FchkR(EmitterContext context)
|
public static void FchkR(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstFchkR op = context.GetOp<InstFchkR>();
|
context.GetOp<InstFchkR>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction FchkR is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction FchkR is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void FchkI(EmitterContext context)
|
public static void FchkI(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstFchkI op = context.GetOp<InstFchkI>();
|
context.GetOp<InstFchkI>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction FchkI is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction FchkI is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void FchkC(EmitterContext context)
|
public static void FchkC(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstFchkC op = context.GetOp<InstFchkC>();
|
context.GetOp<InstFchkC>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction FchkC is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction FchkC is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Getcrsptr(EmitterContext context)
|
public static void Getcrsptr(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstGetcrsptr op = context.GetOp<InstGetcrsptr>();
|
context.GetOp<InstGetcrsptr>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction Getcrsptr is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction Getcrsptr is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Getlmembase(EmitterContext context)
|
public static void Getlmembase(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstGetlmembase op = context.GetOp<InstGetlmembase>();
|
context.GetOp<InstGetlmembase>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction Getlmembase is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction Getlmembase is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Ide(EmitterContext context)
|
public static void Ide(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstIde op = context.GetOp<InstIde>();
|
context.GetOp<InstIde>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction Ide is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction Ide is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void IdpR(EmitterContext context)
|
public static void IdpR(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstIdpR op = context.GetOp<InstIdpR>();
|
context.GetOp<InstIdpR>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction IdpR is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction IdpR is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void IdpC(EmitterContext context)
|
public static void IdpC(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstIdpC op = context.GetOp<InstIdpC>();
|
context.GetOp<InstIdpC>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction IdpC is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction IdpC is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ImadspR(EmitterContext context)
|
public static void ImadspR(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstImadspR op = context.GetOp<InstImadspR>();
|
context.GetOp<InstImadspR>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction ImadspR is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction ImadspR is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ImadspI(EmitterContext context)
|
public static void ImadspI(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstImadspI op = context.GetOp<InstImadspI>();
|
context.GetOp<InstImadspI>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction ImadspI is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction ImadspI is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ImadspC(EmitterContext context)
|
public static void ImadspC(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstImadspC op = context.GetOp<InstImadspC>();
|
context.GetOp<InstImadspC>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction ImadspC is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction ImadspC is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ImadspRc(EmitterContext context)
|
public static void ImadspRc(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstImadspRc op = context.GetOp<InstImadspRc>();
|
context.GetOp<InstImadspRc>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction ImadspRc is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction ImadspRc is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Jcal(EmitterContext context)
|
public static void Jcal(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstJcal op = context.GetOp<InstJcal>();
|
context.GetOp<InstJcal>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction Jcal is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction Jcal is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Jmp(EmitterContext context)
|
public static void Jmp(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstJmp op = context.GetOp<InstJmp>();
|
context.GetOp<InstJmp>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction Jmp is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction Jmp is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Jmx(EmitterContext context)
|
public static void Jmx(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstJmx op = context.GetOp<InstJmx>();
|
context.GetOp<InstJmx>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction Jmx is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction Jmx is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Ld(EmitterContext context)
|
public static void Ld(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstLd op = context.GetOp<InstLd>();
|
context.GetOp<InstLd>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction Ld is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction Ld is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Lepc(EmitterContext context)
|
public static void Lepc(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstLepc op = context.GetOp<InstLepc>();
|
context.GetOp<InstLepc>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction Lepc is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction Lepc is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Longjmp(EmitterContext context)
|
public static void Longjmp(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstLongjmp op = context.GetOp<InstLongjmp>();
|
context.GetOp<InstLongjmp>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction Longjmp is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction Longjmp is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Pexit(EmitterContext context)
|
public static void Pexit(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstPexit op = context.GetOp<InstPexit>();
|
context.GetOp<InstPexit>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction Pexit is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction Pexit is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Pixld(EmitterContext context)
|
public static void Pixld(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstPixld op = context.GetOp<InstPixld>();
|
context.GetOp<InstPixld>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction Pixld is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction Pixld is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Plongjmp(EmitterContext context)
|
public static void Plongjmp(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstPlongjmp op = context.GetOp<InstPlongjmp>();
|
context.GetOp<InstPlongjmp>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction Plongjmp is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction Plongjmp is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Pret(EmitterContext context)
|
public static void Pret(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstPret op = context.GetOp<InstPret>();
|
context.GetOp<InstPret>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction Pret is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction Pret is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void PrmtR(EmitterContext context)
|
public static void PrmtR(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstPrmtR op = context.GetOp<InstPrmtR>();
|
context.GetOp<InstPrmtR>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction PrmtR is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction PrmtR is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void PrmtI(EmitterContext context)
|
public static void PrmtI(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstPrmtI op = context.GetOp<InstPrmtI>();
|
context.GetOp<InstPrmtI>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction PrmtI is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction PrmtI is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void PrmtC(EmitterContext context)
|
public static void PrmtC(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstPrmtC op = context.GetOp<InstPrmtC>();
|
context.GetOp<InstPrmtC>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction PrmtC is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction PrmtC is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void PrmtRc(EmitterContext context)
|
public static void PrmtRc(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstPrmtRc op = context.GetOp<InstPrmtRc>();
|
context.GetOp<InstPrmtRc>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction PrmtRc is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction PrmtRc is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void R2b(EmitterContext context)
|
public static void R2b(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstR2b op = context.GetOp<InstR2b>();
|
context.GetOp<InstR2b>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction R2b is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction R2b is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Ram(EmitterContext context)
|
public static void Ram(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstRam op = context.GetOp<InstRam>();
|
context.GetOp<InstRam>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction Ram is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction Ram is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Rtt(EmitterContext context)
|
public static void Rtt(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstRtt op = context.GetOp<InstRtt>();
|
context.GetOp<InstRtt>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction Rtt is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction Rtt is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Sam(EmitterContext context)
|
public static void Sam(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstSam op = context.GetOp<InstSam>();
|
context.GetOp<InstSam>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction Sam is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction Sam is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Setcrsptr(EmitterContext context)
|
public static void Setcrsptr(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstSetcrsptr op = context.GetOp<InstSetcrsptr>();
|
context.GetOp<InstSetcrsptr>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction Setcrsptr is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction Setcrsptr is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Setlmembase(EmitterContext context)
|
public static void Setlmembase(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstSetlmembase op = context.GetOp<InstSetlmembase>();
|
context.GetOp<InstSetlmembase>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction Setlmembase is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction Setlmembase is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void St(EmitterContext context)
|
public static void St(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstSt op = context.GetOp<InstSt>();
|
context.GetOp<InstSt>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction St is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction St is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Stp(EmitterContext context)
|
public static void Stp(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstStp op = context.GetOp<InstStp>();
|
context.GetOp<InstStp>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction Stp is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction Stp is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Txa(EmitterContext context)
|
public static void Txa(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstTxa op = context.GetOp<InstTxa>();
|
context.GetOp<InstTxa>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction Txa is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction Txa is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Vabsdiff(EmitterContext context)
|
public static void Vabsdiff(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstVabsdiff op = context.GetOp<InstVabsdiff>();
|
context.GetOp<InstVabsdiff>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction Vabsdiff is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction Vabsdiff is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Vabsdiff4(EmitterContext context)
|
public static void Vabsdiff4(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstVabsdiff4 op = context.GetOp<InstVabsdiff4>();
|
context.GetOp<InstVabsdiff4>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction Vabsdiff4 is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction Vabsdiff4 is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Vadd(EmitterContext context)
|
public static void Vadd(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstVadd op = context.GetOp<InstVadd>();
|
context.GetOp<InstVadd>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction Vadd is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction Vadd is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Votevtg(EmitterContext context)
|
public static void Votevtg(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstVotevtg op = context.GetOp<InstVotevtg>();
|
context.GetOp<InstVotevtg>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction Votevtg is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction Votevtg is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Vset(EmitterContext context)
|
public static void Vset(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstVset op = context.GetOp<InstVset>();
|
context.GetOp<InstVset>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction Vset is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction Vset is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Vshl(EmitterContext context)
|
public static void Vshl(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstVshl op = context.GetOp<InstVshl>();
|
context.GetOp<InstVshl>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction Vshl is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction Vshl is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Vshr(EmitterContext context)
|
public static void Vshr(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstVshr op = context.GetOp<InstVshr>();
|
context.GetOp<InstVshr>();
|
||||||
|
|
||||||
context.Config.GpuAccessor.Log("Shader instruction Vshr is not implemented.");
|
context.Config.GpuAccessor.Log("Shader instruction Vshr is not implemented.");
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,6 @@ using Ryujinx.Graphics.Shader.Decoders;
|
|||||||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||||
using Ryujinx.Graphics.Shader.Translation;
|
using Ryujinx.Graphics.Shader.Translation;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
|
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
|
||||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||||
|
|
||||||
@@ -18,7 +17,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
IDstFmt.S16 => short.MinValue,
|
IDstFmt.S16 => short.MinValue,
|
||||||
IDstFmt.U32 => uint.MinValue,
|
IDstFmt.U32 => uint.MinValue,
|
||||||
IDstFmt.S32 => int.MinValue,
|
IDstFmt.S32 => int.MinValue,
|
||||||
_ => throw new ArgumentException($"The type \"{type}\" is not a supported integer type.")
|
_ => throw new ArgumentException($"The type \"{type}\" is not a supported integer type."),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,7 +29,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
IDstFmt.S16 => short.MaxValue,
|
IDstFmt.S16 => short.MaxValue,
|
||||||
IDstFmt.U32 => uint.MaxValue,
|
IDstFmt.U32 => uint.MaxValue,
|
||||||
IDstFmt.S32 => int.MaxValue,
|
IDstFmt.S32 => int.MaxValue,
|
||||||
_ => throw new ArgumentException($"The type \"{type}\" is not a supported integer type.")
|
_ => throw new ArgumentException($"The type \"{type}\" is not a supported integer type."),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,7 +43,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
ISrcDstFmt.S16 => short.MinValue,
|
ISrcDstFmt.S16 => short.MinValue,
|
||||||
ISrcDstFmt.U32 => uint.MinValue,
|
ISrcDstFmt.U32 => uint.MinValue,
|
||||||
ISrcDstFmt.S32 => int.MinValue,
|
ISrcDstFmt.S32 => int.MinValue,
|
||||||
_ => throw new ArgumentException($"The type \"{type}\" is not a supported integer type.")
|
_ => throw new ArgumentException($"The type \"{type}\" is not a supported integer type."),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +57,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
ISrcDstFmt.S16 => short.MaxValue,
|
ISrcDstFmt.S16 => short.MaxValue,
|
||||||
ISrcDstFmt.U32 => uint.MaxValue,
|
ISrcDstFmt.U32 => uint.MaxValue,
|
||||||
ISrcDstFmt.S32 => int.MaxValue,
|
ISrcDstFmt.S32 => int.MaxValue,
|
||||||
_ => throw new ArgumentException($"The type \"{type}\" is not a supported integer type.")
|
_ => throw new ArgumentException($"The type \"{type}\" is not a supported integer type."),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,7 +68,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
BoolOp.And => context.BitwiseAnd(input, pred),
|
BoolOp.And => context.BitwiseAnd(input, pred),
|
||||||
BoolOp.Or => context.BitwiseOr(input, pred),
|
BoolOp.Or => context.BitwiseOr(input, pred),
|
||||||
BoolOp.Xor => context.BitwiseExclusiveOr(input, pred),
|
BoolOp.Xor => context.BitwiseExclusiveOr(input, pred),
|
||||||
_ => input
|
_ => input,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,7 +88,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
VectorSelect.S8B3 => SignExtendTo32(context, context.ShiftRightU32(src, Const(24)), 8),
|
VectorSelect.S8B3 => SignExtendTo32(context, context.ShiftRightU32(src, Const(24)), 8),
|
||||||
VectorSelect.S16H0 => SignExtendTo32(context, context.ShiftRightU32(src, Const(0)), 16),
|
VectorSelect.S16H0 => SignExtendTo32(context, context.ShiftRightU32(src, Const(0)), 16),
|
||||||
VectorSelect.S16H1 => SignExtendTo32(context, context.ShiftRightU32(src, Const(16)), 16),
|
VectorSelect.S16H1 => SignExtendTo32(context, context.ShiftRightU32(src, Const(16)), 16),
|
||||||
_ => src
|
_ => src,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -33,7 +33,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
|
|
||||||
for (int index = 0; index < (int)op.AlSize + 1; index++)
|
for (int index = 0; index < (int)op.AlSize + 1; index++)
|
||||||
{
|
{
|
||||||
Register rd = new Register(op.Dest + index, RegisterType.Gpr);
|
Register rd = new(op.Dest + index, RegisterType.Gpr);
|
||||||
|
|
||||||
if (rd.IsRZ)
|
if (rd.IsRZ)
|
||||||
{
|
{
|
||||||
@@ -91,7 +91,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Register rd = new Register(op.SrcB + index, RegisterType.Gpr);
|
Register rd = new(op.SrcB + index, RegisterType.Gpr);
|
||||||
|
|
||||||
if (op.Phys)
|
if (op.Phys)
|
||||||
{
|
{
|
||||||
|
@@ -22,7 +22,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
|
|
||||||
public static void Depbar(EmitterContext context)
|
public static void Depbar(EmitterContext context)
|
||||||
{
|
{
|
||||||
|
#pragma warning disable IDE0059 // Remove unnecessary value assignment
|
||||||
InstDepbar op = context.GetOp<InstDepbar>();
|
InstDepbar op = context.GetOp<InstDepbar>();
|
||||||
|
#pragma warning restore IDE0059
|
||||||
|
|
||||||
// No operation.
|
// No operation.
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
using Ryujinx.Graphics.Shader.Decoders;
|
using Ryujinx.Graphics.Shader.Decoders;
|
||||||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||||
using Ryujinx.Graphics.Shader.Translation;
|
using Ryujinx.Graphics.Shader.Translation;
|
||||||
|
|
||||||
using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper;
|
using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper;
|
||||||
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
|
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
|
||||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||||
@@ -80,7 +79,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
Ccc.Oft => GetVF(),
|
Ccc.Oft => GetVF(),
|
||||||
Ccc.Rle => context.BitwiseOr(GetNF(), GetZF()),
|
Ccc.Rle => context.BitwiseOr(GetNF(), GetZF()),
|
||||||
Ccc.Rgt => context.BitwiseNot(context.BitwiseOr(GetNF(), GetZF())),
|
Ccc.Rgt => context.BitwiseNot(context.BitwiseOr(GetNF(), GetZF())),
|
||||||
_ => Const(defaultCond)
|
_ => Const(defaultCond),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,6 @@ using Ryujinx.Graphics.Shader.Decoders;
|
|||||||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||||
using Ryujinx.Graphics.Shader.Translation;
|
using Ryujinx.Graphics.Shader.Translation;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper;
|
using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper;
|
||||||
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
|
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
|
||||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||||
@@ -140,7 +139,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
IntegerRound.Floor => context.FPFloor(srcB, srcType.ToInstFPType()),
|
IntegerRound.Floor => context.FPFloor(srcB, srcType.ToInstFPType()),
|
||||||
IntegerRound.Ceil => context.FPCeiling(srcB, srcType.ToInstFPType()),
|
IntegerRound.Ceil => context.FPCeiling(srcB, srcType.ToInstFPType()),
|
||||||
IntegerRound.Trunc => context.FPTruncate(srcB, srcType.ToInstFPType()),
|
IntegerRound.Trunc => context.FPTruncate(srcB, srcType.ToInstFPType()),
|
||||||
_ => srcB
|
_ => srcB,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,7 +190,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
RoundMode2.Floor => context.FPFloor(srcB, fpType),
|
RoundMode2.Floor => context.FPFloor(srcB, fpType),
|
||||||
RoundMode2.Ceil => context.FPCeiling(srcB, fpType),
|
RoundMode2.Ceil => context.FPCeiling(srcB, fpType),
|
||||||
RoundMode2.Trunc => context.FPTruncate(srcB, fpType),
|
RoundMode2.Trunc => context.FPTruncate(srcB, fpType),
|
||||||
_ => srcB
|
_ => srcB,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!isSignedInt)
|
if (!isSignedInt)
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
using Ryujinx.Graphics.Shader.Decoders;
|
using Ryujinx.Graphics.Shader.Decoders;
|
||||||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||||
using Ryujinx.Graphics.Shader.Translation;
|
using Ryujinx.Graphics.Shader.Translation;
|
||||||
|
|
||||||
using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper;
|
using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper;
|
||||||
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
|
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
|
||||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||||
@@ -458,7 +457,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
MultiplyScale.M2 => ConstF(2f),
|
MultiplyScale.M2 => ConstF(2f),
|
||||||
MultiplyScale.M4 => ConstF(4f),
|
MultiplyScale.M4 => ConstF(4f),
|
||||||
MultiplyScale.M8 => ConstF(8f),
|
MultiplyScale.M8 => ConstF(8f),
|
||||||
_ => ConstF(1f) // Invalid, behave as if it had no scale.
|
_ => ConstF(1f), // Invalid, behave as if it had no scale.
|
||||||
};
|
};
|
||||||
|
|
||||||
if (scaleConst.AsFloat() == 1f)
|
if (scaleConst.AsFloat() == 1f)
|
||||||
|
@@ -2,7 +2,6 @@ using Ryujinx.Graphics.Shader.Decoders;
|
|||||||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||||
using Ryujinx.Graphics.Shader.Translation;
|
using Ryujinx.Graphics.Shader.Translation;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper;
|
using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper;
|
||||||
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
|
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
|
||||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||||
@@ -546,20 +545,16 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Instruction inst;
|
var inst = (cond & ~FComp.Nan) switch
|
||||||
|
|
||||||
switch (cond & ~FComp.Nan)
|
|
||||||
{
|
{
|
||||||
case FComp.Lt: inst = Instruction.CompareLess; break;
|
FComp.Lt => Instruction.CompareLess,
|
||||||
case FComp.Eq: inst = Instruction.CompareEqual; break;
|
FComp.Eq => Instruction.CompareEqual,
|
||||||
case FComp.Le: inst = Instruction.CompareLessOrEqual; break;
|
FComp.Le => Instruction.CompareLessOrEqual,
|
||||||
case FComp.Gt: inst = Instruction.CompareGreater; break;
|
FComp.Gt => Instruction.CompareGreater,
|
||||||
case FComp.Ne: inst = Instruction.CompareNotEqual; break;
|
FComp.Ne => Instruction.CompareNotEqual,
|
||||||
case FComp.Ge: inst = Instruction.CompareGreaterOrEqual; break;
|
FComp.Ge => Instruction.CompareGreaterOrEqual,
|
||||||
|
_ => throw new ArgumentException($"Unexpected condition \"{cond}\"."),
|
||||||
default: throw new ArgumentException($"Unexpected condition \"{cond}\".");
|
};
|
||||||
}
|
|
||||||
|
|
||||||
res = context.Add(inst | fpType, Local(), srcA, srcB);
|
res = context.Add(inst | fpType, Local(), srcA, srcB);
|
||||||
|
|
||||||
if ((cond & FComp.Nan) != 0)
|
if ((cond & FComp.Nan) != 0)
|
||||||
|
@@ -3,8 +3,6 @@ using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
|||||||
using Ryujinx.Graphics.Shader.Translation;
|
using Ryujinx.Graphics.Shader.Translation;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
|
|
||||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Shader.Instructions
|
namespace Ryujinx.Graphics.Shader.Instructions
|
||||||
@@ -13,14 +11,14 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
public static void Bra(EmitterContext context)
|
public static void Bra(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstBra op = context.GetOp<InstBra>();
|
context.GetOp<InstBra>();
|
||||||
|
|
||||||
EmitBranch(context, context.CurrBlock.Successors[^1].Address);
|
EmitBranch(context, context.CurrBlock.Successors[^1].Address);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Brk(EmitterContext context)
|
public static void Brk(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstBrk op = context.GetOp<InstBrk>();
|
context.GetOp<InstBrk>();
|
||||||
|
|
||||||
EmitBrkContSync(context);
|
EmitBrkContSync(context);
|
||||||
}
|
}
|
||||||
@@ -123,7 +121,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
|
|
||||||
public static void Cal(EmitterContext context)
|
public static void Cal(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstCal op = context.GetOp<InstCal>();
|
context.GetOp<InstCal>();
|
||||||
|
|
||||||
DecodedFunction function = context.Program.GetFunctionByAddress(context.CurrOp.GetAbsoluteAddress());
|
DecodedFunction function = context.Program.GetFunctionByAddress(context.CurrOp.GetAbsoluteAddress());
|
||||||
|
|
||||||
@@ -147,7 +145,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
|
|
||||||
public static void Cont(EmitterContext context)
|
public static void Cont(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstCont op = context.GetOp<InstCont>();
|
context.GetOp<InstCont>();
|
||||||
|
|
||||||
EmitBrkContSync(context);
|
EmitBrkContSync(context);
|
||||||
}
|
}
|
||||||
@@ -185,28 +183,28 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
|
|
||||||
public static void Kil(EmitterContext context)
|
public static void Kil(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstKil op = context.GetOp<InstKil>();
|
context.GetOp<InstKil>();
|
||||||
|
|
||||||
context.Discard();
|
context.Discard();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Pbk(EmitterContext context)
|
public static void Pbk(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstPbk op = context.GetOp<InstPbk>();
|
context.GetOp<InstPbk>();
|
||||||
|
|
||||||
EmitPbkPcntSsy(context);
|
EmitPbkPcntSsy(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Pcnt(EmitterContext context)
|
public static void Pcnt(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstPcnt op = context.GetOp<InstPcnt>();
|
context.GetOp<InstPcnt>();
|
||||||
|
|
||||||
EmitPbkPcntSsy(context);
|
EmitPbkPcntSsy(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Ret(EmitterContext context)
|
public static void Ret(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstRet op = context.GetOp<InstRet>();
|
context.GetOp<InstRet>();
|
||||||
|
|
||||||
if (context.IsNonMain)
|
if (context.IsNonMain)
|
||||||
{
|
{
|
||||||
@@ -220,14 +218,14 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
|
|
||||||
public static void Ssy(EmitterContext context)
|
public static void Ssy(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstSsy op = context.GetOp<InstSsy>();
|
context.GetOp<InstSsy>();
|
||||||
|
|
||||||
EmitPbkPcntSsy(context);
|
EmitPbkPcntSsy(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Sync(EmitterContext context)
|
public static void Sync(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstSync op = context.GetOp<InstSync>();
|
context.GetOp<InstSync>();
|
||||||
|
|
||||||
EmitBrkContSync(context);
|
EmitBrkContSync(context);
|
||||||
}
|
}
|
||||||
@@ -275,7 +273,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
private static void EmitBranch(EmitterContext context, ulong address)
|
private static void EmitBranch(EmitterContext context, ulong address)
|
||||||
{
|
{
|
||||||
InstOp op = context.CurrOp;
|
InstOp op = context.CurrOp;
|
||||||
InstConditional opCond = new InstConditional(op.RawOpCode);
|
InstConditional opCond = new(op.RawOpCode);
|
||||||
|
|
||||||
// If we're branching to the next instruction, then the branch
|
// If we're branching to the next instruction, then the branch
|
||||||
// is useless and we can ignore it.
|
// is useless and we can ignore it.
|
||||||
|
@@ -3,7 +3,6 @@ using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
|||||||
using Ryujinx.Graphics.Shader.Translation;
|
using Ryujinx.Graphics.Shader.Translation;
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Shader.Instructions
|
namespace Ryujinx.Graphics.Shader.Instructions
|
||||||
@@ -111,7 +110,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
return new Operand[]
|
return new Operand[]
|
||||||
{
|
{
|
||||||
ConstF((float)Unsafe.As<ushort, Half>(ref low)),
|
ConstF((float)Unsafe.As<ushort, Half>(ref low)),
|
||||||
ConstF((float)Unsafe.As<ushort, Half>(ref high))
|
ConstF((float)Unsafe.As<ushort, Half>(ref high)),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,7 +122,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
return new Operand[]
|
return new Operand[]
|
||||||
{
|
{
|
||||||
ConstF((float)Unsafe.As<ushort, Half>(ref low)),
|
ConstF((float)Unsafe.As<ushort, Half>(ref low)),
|
||||||
ConstF((float)Unsafe.As<ushort, Half>(ref high))
|
ConstF((float)Unsafe.As<ushort, Half>(ref high)),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,42 +138,37 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
|
|
||||||
public static Operand[] GetHalfUnpacked(EmitterContext context, Operand src, HalfSwizzle swizzle)
|
public static Operand[] GetHalfUnpacked(EmitterContext context, Operand src, HalfSwizzle swizzle)
|
||||||
{
|
{
|
||||||
switch (swizzle)
|
return swizzle switch
|
||||||
{
|
{
|
||||||
case HalfSwizzle.F16:
|
HalfSwizzle.F16 => new Operand[]
|
||||||
return new Operand[]
|
|
||||||
{
|
{
|
||||||
context.UnpackHalf2x16Low (src),
|
context.UnpackHalf2x16Low (src),
|
||||||
context.UnpackHalf2x16High(src)
|
context.UnpackHalf2x16High(src),
|
||||||
};
|
},
|
||||||
|
HalfSwizzle.F32 => new Operand[] { src, src },
|
||||||
case HalfSwizzle.F32: return new Operand[] { src, src };
|
HalfSwizzle.H0H0 => new Operand[]
|
||||||
|
|
||||||
case HalfSwizzle.H0H0:
|
|
||||||
return new Operand[]
|
|
||||||
{
|
{
|
||||||
context.UnpackHalf2x16Low(src),
|
context.UnpackHalf2x16Low(src),
|
||||||
context.UnpackHalf2x16Low(src)
|
context.UnpackHalf2x16Low(src),
|
||||||
};
|
},
|
||||||
|
HalfSwizzle.H1H1 => new Operand[]
|
||||||
case HalfSwizzle.H1H1:
|
|
||||||
return new Operand[]
|
|
||||||
{
|
{
|
||||||
context.UnpackHalf2x16High(src),
|
context.UnpackHalf2x16High(src),
|
||||||
context.UnpackHalf2x16High(src)
|
context.UnpackHalf2x16High(src),
|
||||||
|
},
|
||||||
|
_ => throw new ArgumentException($"Invalid swizzle \"{swizzle}\"."),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new ArgumentException($"Invalid swizzle \"{swizzle}\".");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Operand GetHalfPacked(EmitterContext context, OFmt swizzle, Operand[] results, int rd)
|
public static Operand GetHalfPacked(EmitterContext context, OFmt swizzle, Operand[] results, int rd)
|
||||||
{
|
{
|
||||||
switch (swizzle)
|
switch (swizzle)
|
||||||
{
|
{
|
||||||
case OFmt.F16: return context.PackHalf2x16(results[0], results[1]);
|
case OFmt.F16:
|
||||||
|
return context.PackHalf2x16(results[0], results[1]);
|
||||||
|
|
||||||
case OFmt.F32: return results[0];
|
case OFmt.F32:
|
||||||
|
return results[0];
|
||||||
|
|
||||||
case OFmt.MrgH0:
|
case OFmt.MrgH0:
|
||||||
{
|
{
|
||||||
|
@@ -510,7 +510,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
aLow = context.BitwiseNot(aLow);
|
aLow = context.BitwiseNot(aLow);
|
||||||
aHigh = context.BitwiseNot(aHigh);
|
aHigh = context.BitwiseNot(aHigh);
|
||||||
|
|
||||||
|
#pragma warning disable IDE0059 // Remove unnecessary value assignment
|
||||||
aLow = AddWithCarry(context, aLow, Const(1), out Operand aLowCOut);
|
aLow = AddWithCarry(context, aLow, Const(1), out Operand aLowCOut);
|
||||||
|
#pragma warning restore IDE0059
|
||||||
aHigh = context.IAdd(aHigh, aLowCOut);
|
aHigh = context.IAdd(aHigh, aLowCOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2,7 +2,6 @@ using Ryujinx.Graphics.Shader.Decoders;
|
|||||||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||||
using Ryujinx.Graphics.Shader.Translation;
|
using Ryujinx.Graphics.Shader.Translation;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper;
|
using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper;
|
||||||
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
|
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
|
||||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||||
@@ -220,7 +219,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
res = context.ISubtract(srcA, srcB);
|
res = context.ISubtract(srcA, srcB);
|
||||||
|
#pragma warning disable IDE0059 // Remove unnecessary value assignment
|
||||||
res = context.IAdd(res, context.BitwiseNot(GetCF()));
|
res = context.IAdd(res, context.BitwiseNot(GetCF()));
|
||||||
|
#pragma warning restore IDE0059
|
||||||
|
|
||||||
switch (cond)
|
switch (cond)
|
||||||
{
|
{
|
||||||
@@ -287,17 +288,25 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
IComp.Gt => Instruction.CompareGreaterU32,
|
IComp.Gt => Instruction.CompareGreaterU32,
|
||||||
IComp.Ne => Instruction.CompareNotEqual,
|
IComp.Ne => Instruction.CompareNotEqual,
|
||||||
IComp.Ge => Instruction.CompareGreaterOrEqualU32,
|
IComp.Ge => Instruction.CompareGreaterOrEqualU32,
|
||||||
_ => throw new InvalidOperationException($"Unexpected condition \"{cond}\".")
|
_ => throw new InvalidOperationException($"Unexpected condition \"{cond}\"."),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (isSigned)
|
if (isSigned)
|
||||||
{
|
{
|
||||||
switch (cond)
|
switch (cond)
|
||||||
{
|
{
|
||||||
case IComp.Lt: inst = Instruction.CompareLess; break;
|
case IComp.Lt:
|
||||||
case IComp.Le: inst = Instruction.CompareLessOrEqual; break;
|
inst = Instruction.CompareLess;
|
||||||
case IComp.Gt: inst = Instruction.CompareGreater; break;
|
break;
|
||||||
case IComp.Ge: inst = Instruction.CompareGreaterOrEqual; break;
|
case IComp.Le:
|
||||||
|
inst = Instruction.CompareLessOrEqual;
|
||||||
|
break;
|
||||||
|
case IComp.Gt:
|
||||||
|
inst = Instruction.CompareGreater;
|
||||||
|
break;
|
||||||
|
case IComp.Ge:
|
||||||
|
inst = Instruction.CompareGreaterOrEqual;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
using Ryujinx.Graphics.Shader.Decoders;
|
using Ryujinx.Graphics.Shader.Decoders;
|
||||||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||||
using Ryujinx.Graphics.Shader.Translation;
|
using Ryujinx.Graphics.Shader.Translation;
|
||||||
|
|
||||||
using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper;
|
using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper;
|
||||||
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
|
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
|
||||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||||
@@ -103,10 +102,10 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
|
|
||||||
Operand res = logicOp switch
|
Operand res = logicOp switch
|
||||||
{
|
{
|
||||||
LogicOp.And => res = context.BitwiseAnd(srcA, srcB),
|
LogicOp.And => context.BitwiseAnd(srcA, srcB),
|
||||||
LogicOp.Or => res = context.BitwiseOr(srcA, srcB),
|
LogicOp.Or => context.BitwiseOr(srcA, srcB),
|
||||||
LogicOp.Xor => res = context.BitwiseExclusiveOr(srcA, srcB),
|
LogicOp.Xor => context.BitwiseExclusiveOr(srcA, srcB),
|
||||||
_ => srcB
|
_ => srcB,
|
||||||
};
|
};
|
||||||
|
|
||||||
EmitLopPredWrite(context, res, predOp, destPred);
|
EmitLopPredWrite(context, res, predOp, destPred);
|
||||||
|
@@ -2,7 +2,6 @@ using Ryujinx.Graphics.Shader.Decoders;
|
|||||||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||||
using Ryujinx.Graphics.Shader.Translation;
|
using Ryujinx.Graphics.Shader.Translation;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
|
||||||
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
|
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
|
||||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||||
|
|
||||||
@@ -48,7 +47,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
AtomsSize.S32 => AtomSize.S32,
|
AtomsSize.S32 => AtomSize.S32,
|
||||||
AtomsSize.U64 => AtomSize.U64,
|
AtomsSize.U64 => AtomSize.U64,
|
||||||
AtomsSize.S64 => AtomSize.S64,
|
AtomsSize.S64 => AtomSize.S64,
|
||||||
_ => AtomSize.U32
|
_ => AtomSize.U32,
|
||||||
};
|
};
|
||||||
|
|
||||||
Operand id = Const(context.Config.ResourceManager.SharedMemoryId);
|
Operand id = Const(context.Config.ResourceManager.SharedMemoryId);
|
||||||
@@ -85,7 +84,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
|
|
||||||
for (int index = 0; index < count; index++)
|
for (int index = 0; index < count; index++)
|
||||||
{
|
{
|
||||||
Register dest = new Register(op.Dest + index, RegisterType.Gpr);
|
Register dest = new(op.Dest + index, RegisterType.Gpr);
|
||||||
|
|
||||||
if (dest.IsRZ)
|
if (dest.IsRZ)
|
||||||
{
|
{
|
||||||
@@ -309,14 +308,14 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
LsSize2.B64 => 2,
|
LsSize2.B64 => 2,
|
||||||
LsSize2.B128 => 4,
|
LsSize2.B128 => 4,
|
||||||
_ => 1
|
_ => 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
Operand baseOffset = context.Copy(srcA);
|
Operand baseOffset = context.Copy(srcA);
|
||||||
|
|
||||||
for (int index = 0; index < count; index++)
|
for (int index = 0; index < count; index++)
|
||||||
{
|
{
|
||||||
Register dest = new Register(rd + index, RegisterType.Gpr);
|
Register dest = new(rd + index, RegisterType.Gpr);
|
||||||
|
|
||||||
if (dest.IsRZ)
|
if (dest.IsRZ)
|
||||||
{
|
{
|
||||||
@@ -354,7 +353,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
|
|
||||||
for (int index = 0; index < count; index++)
|
for (int index = 0; index < count; index++)
|
||||||
{
|
{
|
||||||
Register dest = new Register(rd + index, RegisterType.Gpr);
|
Register dest = new(rd + index, RegisterType.Gpr);
|
||||||
|
|
||||||
if (dest.IsRZ)
|
if (dest.IsRZ)
|
||||||
{
|
{
|
||||||
@@ -390,7 +389,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
LsSize2.B64 => 2,
|
LsSize2.B64 => 2,
|
||||||
LsSize2.B128 => 4,
|
LsSize2.B128 => 4,
|
||||||
_ => 1
|
_ => 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
Operand baseOffset = context.Copy(srcA);
|
Operand baseOffset = context.Copy(srcA);
|
||||||
@@ -476,22 +475,18 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
LsSize.S8 => StorageKind.GlobalMemoryS8,
|
LsSize.S8 => StorageKind.GlobalMemoryS8,
|
||||||
LsSize.U16 => StorageKind.GlobalMemoryU16,
|
LsSize.U16 => StorageKind.GlobalMemoryU16,
|
||||||
LsSize.S16 => StorageKind.GlobalMemoryS16,
|
LsSize.S16 => StorageKind.GlobalMemoryS16,
|
||||||
_ => StorageKind.GlobalMemory
|
_ => StorageKind.GlobalMemory,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int GetVectorCount(LsSize size)
|
private static int GetVectorCount(LsSize size)
|
||||||
{
|
{
|
||||||
switch (size)
|
return size switch
|
||||||
{
|
{
|
||||||
case LsSize.B64:
|
LsSize.B64 => 2,
|
||||||
return 2;
|
LsSize.B128 or LsSize.UB128 => 4,
|
||||||
case LsSize.B128:
|
_ => 1,
|
||||||
case LsSize.UB128:
|
};
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static (Operand, Operand) Get40BitsAddress(
|
private static (Operand, Operand) Get40BitsAddress(
|
||||||
@@ -544,10 +539,18 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
|
|
||||||
switch (size)
|
switch (size)
|
||||||
{
|
{
|
||||||
case LsSize.U8: value = ZeroExtendTo32(context, value, 8); break;
|
case LsSize.U8:
|
||||||
case LsSize.U16: value = ZeroExtendTo32(context, value, 16); break;
|
value = ZeroExtendTo32(context, value, 8);
|
||||||
case LsSize.S8: value = SignExtendTo32(context, value, 8); break;
|
break;
|
||||||
case LsSize.S16: value = SignExtendTo32(context, value, 16); break;
|
case LsSize.U16:
|
||||||
|
value = ZeroExtendTo32(context, value, 16);
|
||||||
|
break;
|
||||||
|
case LsSize.S8:
|
||||||
|
value = SignExtendTo32(context, value, 8);
|
||||||
|
break;
|
||||||
|
case LsSize.S16:
|
||||||
|
value = SignExtendTo32(context, value, 16);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
|
@@ -7,7 +7,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
public static void Nop(EmitterContext context)
|
public static void Nop(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstNop op = context.GetOp<InstNop>();
|
context.GetOp<InstNop>();
|
||||||
|
|
||||||
// No operation.
|
// No operation.
|
||||||
}
|
}
|
||||||
|
@@ -4,7 +4,6 @@ using Ryujinx.Graphics.Shader.Translation;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
|
||||||
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
|
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
|
||||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||||
|
|
||||||
@@ -221,7 +220,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
|
|
||||||
Operand destOperand = dest != RegisterConsts.RegisterZeroIndex ? Register(dest, RegisterType.Gpr) : null;
|
Operand destOperand = dest != RegisterConsts.RegisterZeroIndex ? Register(dest, RegisterType.Gpr) : null;
|
||||||
|
|
||||||
List<Operand> sourcesList = new List<Operand>();
|
List<Operand> sourcesList = new();
|
||||||
|
|
||||||
if (isBindless)
|
if (isBindless)
|
||||||
{
|
{
|
||||||
@@ -325,7 +324,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
return context.Copy(Register(srcA++, RegisterType.Gpr));
|
return context.Copy(Register(srcA++, RegisterType.Gpr));
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Operand> sourcesList = new List<Operand>();
|
List<Operand> sourcesList = new();
|
||||||
|
|
||||||
if (isBindless)
|
if (isBindless)
|
||||||
{
|
{
|
||||||
@@ -445,10 +444,18 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
|
|
||||||
switch (size)
|
switch (size)
|
||||||
{
|
{
|
||||||
case SuSize.U8: context.Copy(dests[0], ZeroExtendTo32(context, dests[0], 8)); break;
|
case SuSize.U8:
|
||||||
case SuSize.U16: context.Copy(dests[0], ZeroExtendTo32(context, dests[0], 16)); break;
|
context.Copy(dests[0], ZeroExtendTo32(context, dests[0], 8));
|
||||||
case SuSize.S8: context.Copy(dests[0], SignExtendTo32(context, dests[0], 8)); break;
|
break;
|
||||||
case SuSize.S16: context.Copy(dests[0], SignExtendTo32(context, dests[0], 16)); break;
|
case SuSize.U16:
|
||||||
|
context.Copy(dests[0], ZeroExtendTo32(context, dests[0], 16));
|
||||||
|
break;
|
||||||
|
case SuSize.S8:
|
||||||
|
context.Copy(dests[0], SignExtendTo32(context, dests[0], 8));
|
||||||
|
break;
|
||||||
|
case SuSize.S16:
|
||||||
|
context.Copy(dests[0], SignExtendTo32(context, dests[0], 16));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -493,7 +500,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
return context.Copy(Register(srcB++, RegisterType.Gpr));
|
return context.Copy(Register(srcB++, RegisterType.Gpr));
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Operand> sourcesList = new List<Operand>();
|
List<Operand> sourcesList = new();
|
||||||
|
|
||||||
if (isBindless)
|
if (isBindless)
|
||||||
{
|
{
|
||||||
@@ -600,7 +607,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
return context.Copy(Register(srcB++, RegisterType.Gpr));
|
return context.Copy(Register(srcB++, RegisterType.Gpr));
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Operand> sourcesList = new List<Operand>();
|
List<Operand> sourcesList = new();
|
||||||
|
|
||||||
if (isBindless)
|
if (isBindless)
|
||||||
{
|
{
|
||||||
@@ -699,7 +706,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
SuatomSize.S64 => 3,
|
SuatomSize.S64 => 3,
|
||||||
SuatomSize.Sd32 => 2,
|
SuatomSize.Sd32 => 2,
|
||||||
SuatomSize.Sd64 => 3,
|
SuatomSize.Sd64 => 3,
|
||||||
_ => 2
|
_ => 2,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -715,7 +722,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
SuatomSize.S64 => TextureFormat.R32G32Uint,
|
SuatomSize.S64 => TextureFormat.R32G32Uint,
|
||||||
SuatomSize.Sd32 => TextureFormat.R32Uint,
|
SuatomSize.Sd32 => TextureFormat.R32Uint,
|
||||||
SuatomSize.Sd64 => TextureFormat.R32G32Uint,
|
SuatomSize.Sd64 => TextureFormat.R32G32Uint,
|
||||||
_ => TextureFormat.R32Uint
|
_ => TextureFormat.R32Uint,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -732,7 +739,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
SuatomOp.Or => TextureFlags.BitwiseOr,
|
SuatomOp.Or => TextureFlags.BitwiseOr,
|
||||||
SuatomOp.Xor => TextureFlags.BitwiseXor,
|
SuatomOp.Xor => TextureFlags.BitwiseXor,
|
||||||
SuatomOp.Exch => TextureFlags.Swap,
|
SuatomOp.Exch => TextureFlags.Swap,
|
||||||
_ => TextureFlags.Add
|
_ => TextureFlags.Add,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -743,7 +750,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
SuSize.B64 => 2,
|
SuSize.B64 => 2,
|
||||||
SuSize.B128 => 4,
|
SuSize.B128 => 4,
|
||||||
SuSize.UB128 => 4,
|
SuSize.UB128 => 4,
|
||||||
_ => 1
|
_ => 1,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -759,7 +766,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
SuSize.B64 => 3,
|
SuSize.B64 => 3,
|
||||||
SuSize.B128 => 4,
|
SuSize.B128 => 4,
|
||||||
SuSize.UB128 => 4,
|
SuSize.UB128 => 4,
|
||||||
_ => 2
|
_ => 2,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -775,7 +782,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
SuSize.B64 => TextureFormat.R32G32Uint,
|
SuSize.B64 => TextureFormat.R32G32Uint,
|
||||||
SuSize.B128 => TextureFormat.R32G32B32A32Uint,
|
SuSize.B128 => TextureFormat.R32G32B32A32Uint,
|
||||||
SuSize.UB128 => TextureFormat.R32G32B32A32Uint,
|
SuSize.UB128 => TextureFormat.R32G32B32A32Uint,
|
||||||
_ => TextureFormat.R32Uint
|
_ => TextureFormat.R32Uint,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -789,7 +796,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
SuDim._2d => SamplerType.Texture2D,
|
SuDim._2d => SamplerType.Texture2D,
|
||||||
SuDim._2dArray => SamplerType.Texture2D | SamplerType.Array,
|
SuDim._2dArray => SamplerType.Texture2D | SamplerType.Array,
|
||||||
SuDim._3d => SamplerType.Texture3D,
|
SuDim._3d => SamplerType.Texture3D,
|
||||||
_ => SamplerType.None
|
_ => SamplerType.None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -4,7 +4,6 @@ using Ryujinx.Graphics.Shader.Translation;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
|
||||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Shader.Instructions
|
namespace Ryujinx.Graphics.Shader.Instructions
|
||||||
@@ -14,7 +13,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
private static readonly int[,] _maskLut = new int[,]
|
private static readonly int[,] _maskLut = new int[,]
|
||||||
{
|
{
|
||||||
{ 0b0001, 0b0010, 0b0100, 0b1000, 0b0011, 0b1001, 0b1010, 0b1100 },
|
{ 0b0001, 0b0010, 0b0100, 0b1000, 0b0011, 0b1001, 0b1010, 0b1100 },
|
||||||
{ 0b0111, 0b1011, 0b1101, 0b1110, 0b1111, 0b0000, 0b0000, 0b0000 }
|
{ 0b0111, 0b1011, 0b1101, 0b1110, 0b1111, 0b0000, 0b0000, 0b0000 },
|
||||||
};
|
};
|
||||||
|
|
||||||
public const bool Sample1DAs2D = true;
|
public const bool Sample1DAs2D = true;
|
||||||
@@ -23,7 +22,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
Texs,
|
Texs,
|
||||||
Tlds,
|
Tlds,
|
||||||
Tld4s
|
Tld4s,
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Tex(EmitterContext context)
|
public static void Tex(EmitterContext context)
|
||||||
@@ -207,7 +206,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
|
|
||||||
Operand arrayIndex = isArray ? Ra() : null;
|
Operand arrayIndex = isArray ? Ra() : null;
|
||||||
|
|
||||||
List<Operand> sourcesList = new List<Operand>();
|
List<Operand> sourcesList = new();
|
||||||
|
|
||||||
if (isBindless)
|
if (isBindless)
|
||||||
{
|
{
|
||||||
@@ -353,7 +352,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Operand> sourcesList = new List<Operand>();
|
List<Operand> sourcesList = new();
|
||||||
|
|
||||||
Operand Ra()
|
Operand Ra()
|
||||||
{
|
{
|
||||||
@@ -722,7 +721,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
|
|
||||||
Operand arrayIndex = isArray ? Ra() : null;
|
Operand arrayIndex = isArray ? Ra() : null;
|
||||||
|
|
||||||
List<Operand> sourcesList = new List<Operand>();
|
List<Operand> sourcesList = new();
|
||||||
|
|
||||||
SamplerType type = ConvertSamplerType(dimensions);
|
SamplerType type = ConvertSamplerType(dimensions);
|
||||||
TextureFlags flags = TextureFlags.Gather;
|
TextureFlags flags = TextureFlags.Gather;
|
||||||
@@ -864,7 +863,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
|
|
||||||
TextureFlags flags = TextureFlags.None;
|
TextureFlags flags = TextureFlags.None;
|
||||||
|
|
||||||
List<Operand> sourcesList = new List<Operand>();
|
List<Operand> sourcesList = new();
|
||||||
|
|
||||||
if (isBindless)
|
if (isBindless)
|
||||||
{
|
{
|
||||||
@@ -996,7 +995,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
|
|
||||||
TextureFlags flags = TextureFlags.Derivatives;
|
TextureFlags flags = TextureFlags.Derivatives;
|
||||||
|
|
||||||
List<Operand> sourcesList = new List<Operand>();
|
List<Operand> sourcesList = new();
|
||||||
|
|
||||||
if (isBindless)
|
if (isBindless)
|
||||||
{
|
{
|
||||||
@@ -1126,7 +1125,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
return context.Copy(Register(srcA++, RegisterType.Gpr));
|
return context.Copy(Register(srcA++, RegisterType.Gpr));
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Operand> sourcesList = new List<Operand>();
|
List<Operand> sourcesList = new();
|
||||||
|
|
||||||
if (isBindless)
|
if (isBindless)
|
||||||
{
|
{
|
||||||
@@ -1195,7 +1194,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
TexDim.Array3d => SamplerType.Texture3D | SamplerType.Array,
|
TexDim.Array3d => SamplerType.Texture3D | SamplerType.Array,
|
||||||
TexDim.Cube => SamplerType.TextureCube,
|
TexDim.Cube => SamplerType.TextureCube,
|
||||||
TexDim.ArrayCube => SamplerType.TextureCube | SamplerType.Array,
|
TexDim.ArrayCube => SamplerType.TextureCube | SamplerType.Array,
|
||||||
_ => throw new ArgumentException($"Invalid texture dimensions \"{dimensions}\".")
|
_ => throw new ArgumentException($"Invalid texture dimensions \"{dimensions}\"."),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
using Ryujinx.Graphics.Shader.Decoders;
|
using Ryujinx.Graphics.Shader.Decoders;
|
||||||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||||
using Ryujinx.Graphics.Shader.Translation;
|
using Ryujinx.Graphics.Shader.Translation;
|
||||||
|
|
||||||
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
|
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
|
||||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||||
|
|
||||||
@@ -77,7 +76,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
VideoScale.Shr7 => 7,
|
VideoScale.Shr7 => 7,
|
||||||
VideoScale.Shr15 => 15,
|
VideoScale.Shr15 => 15,
|
||||||
_ => 0
|
_ => 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (shift != 0)
|
if (shift != 0)
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
using Ryujinx.Graphics.Shader.Decoders;
|
using Ryujinx.Graphics.Shader.Decoders;
|
||||||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||||
using Ryujinx.Graphics.Shader.Translation;
|
using Ryujinx.Graphics.Shader.Translation;
|
||||||
|
|
||||||
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
|
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
|
||||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||||
|
|
||||||
@@ -39,7 +38,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
ShflMode.Up => context.ShuffleUp(srcA, srcB, srcC),
|
ShflMode.Up => context.ShuffleUp(srcA, srcB, srcC),
|
||||||
ShflMode.Down => context.ShuffleDown(srcA, srcB, srcC),
|
ShflMode.Down => context.ShuffleDown(srcA, srcB, srcC),
|
||||||
ShflMode.Bfly => context.ShuffleXor(srcA, srcB, srcC),
|
ShflMode.Bfly => context.ShuffleXor(srcA, srcB, srcC),
|
||||||
_ => (null, null)
|
_ => (null, null),
|
||||||
};
|
};
|
||||||
|
|
||||||
context.Copy(GetDest(op.Dest), res);
|
context.Copy(GetDest(op.Dest), res);
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||||
using Ryujinx.Graphics.Shader.Translation;
|
using Ryujinx.Graphics.Shader.Translation;
|
||||||
|
|
||||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Shader.Instructions
|
namespace Ryujinx.Graphics.Shader.Instructions
|
||||||
@@ -98,6 +97,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
{
|
{
|
||||||
return imm switch
|
return imm switch
|
||||||
{
|
{
|
||||||
|
#pragma warning disable IDE0055 // Disable formatting
|
||||||
TruthTable.False => Const(0),
|
TruthTable.False => Const(0),
|
||||||
TruthTable.True => Const(-1),
|
TruthTable.True => Const(-1),
|
||||||
TruthTable.In => x,
|
TruthTable.In => x,
|
||||||
@@ -118,7 +118,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
TruthTable.AndXor => context.BitwiseExclusiveOr(x, context.BitwiseAnd(y, z)),
|
TruthTable.AndXor => context.BitwiseExclusiveOr(x, context.BitwiseAnd(y, z)),
|
||||||
TruthTable.OrXor => context.BitwiseExclusiveOr(x, context.BitwiseOr(y, z)),
|
TruthTable.OrXor => context.BitwiseExclusiveOr(x, context.BitwiseOr(y, z)),
|
||||||
TruthTable.Xor3 => context.BitwiseExclusiveOr(x, context.BitwiseExclusiveOr(y, z)),
|
TruthTable.Xor3 => context.BitwiseExclusiveOr(x, context.BitwiseExclusiveOr(y, z)),
|
||||||
_ => null
|
_ => null,
|
||||||
|
#pragma warning restore IDE0055
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -83,9 +83,9 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
|
|||||||
case Instruction.Discard:
|
case Instruction.Discard:
|
||||||
case Instruction.Return:
|
case Instruction.Return:
|
||||||
return true;
|
return true;
|
||||||
}
|
default:
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@@ -1,8 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
|
namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
|
||||||
{
|
{
|
||||||
[Flags]
|
[Flags]
|
||||||
|
[SuppressMessage("Design", "CA1069: Enums values should not be duplicated")]
|
||||||
enum Instruction
|
enum Instruction
|
||||||
{
|
{
|
||||||
Absolute = 1,
|
Absolute = 1,
|
||||||
@@ -130,7 +132,7 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
|
|||||||
FP32 = 1 << 16,
|
FP32 = 1 << 16,
|
||||||
FP64 = 1 << 17,
|
FP64 = 1 << 17,
|
||||||
|
|
||||||
Mask = 0xffff
|
Mask = 0xffff,
|
||||||
}
|
}
|
||||||
|
|
||||||
static class InstructionExtensions
|
static class InstructionExtensions
|
||||||
|
@@ -43,6 +43,6 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
|
|||||||
VertexId,
|
VertexId,
|
||||||
VertexIndex,
|
VertexIndex,
|
||||||
ViewportIndex,
|
ViewportIndex,
|
||||||
ViewportMask
|
ViewportMask,
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -8,6 +8,6 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
|
|||||||
Label,
|
Label,
|
||||||
LocalVariable,
|
LocalVariable,
|
||||||
Register,
|
Register,
|
||||||
Undefined
|
Undefined,
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -15,7 +15,7 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
|
|||||||
|
|
||||||
public int DestsCount => _dest != null ? 1 : 0;
|
public int DestsCount => _dest != null ? 1 : 0;
|
||||||
|
|
||||||
private HashSet<BasicBlock> _blocks;
|
private readonly HashSet<BasicBlock> _blocks;
|
||||||
|
|
||||||
private class PhiSource
|
private class PhiSource
|
||||||
{
|
{
|
||||||
@@ -29,7 +29,7 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<PhiSource> _sources;
|
private readonly List<PhiSource> _sources;
|
||||||
|
|
||||||
public int SourcesCount => _sources.Count;
|
public int SourcesCount => _sources.Count;
|
||||||
|
|
||||||
|
@@ -17,7 +17,7 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
|
|||||||
GlobalMemoryS8, // TODO: Remove this and store type as a field on the Operation class itself.
|
GlobalMemoryS8, // TODO: Remove this and store type as a field on the Operation class itself.
|
||||||
GlobalMemoryS16, // TODO: Remove this and store type as a field on the Operation class itself.
|
GlobalMemoryS16, // TODO: Remove this and store type as a field on the Operation class itself.
|
||||||
GlobalMemoryU8, // TODO: Remove this and store type as a field on the Operation class itself.
|
GlobalMemoryU8, // TODO: Remove this and store type as a field on the Operation class itself.
|
||||||
GlobalMemoryU16 // TODO: Remove this and store type as a field on the Operation class itself.
|
GlobalMemoryU16, // TODO: Remove this and store type as a field on the Operation class itself.
|
||||||
}
|
}
|
||||||
|
|
||||||
static class StorageKindExtensions
|
static class StorageKindExtensions
|
||||||
|
@@ -1,8 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
|
namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
|
||||||
{
|
{
|
||||||
[Flags]
|
[Flags]
|
||||||
|
[SuppressMessage("Design", "CA1069: Enums values should not be duplicated")]
|
||||||
enum TextureFlags
|
enum TextureFlags
|
||||||
{
|
{
|
||||||
None = 0,
|
None = 0,
|
||||||
@@ -27,6 +29,6 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
|
|||||||
BitwiseOr = 6 << 16,
|
BitwiseOr = 6 << 16,
|
||||||
BitwiseXor = 7 << 16,
|
BitwiseXor = 7 << 16,
|
||||||
Swap = 8 << 16,
|
Swap = 8 << 16,
|
||||||
CAS = 9 << 16
|
CAS = 9 << 16,
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -4,21 +4,20 @@ namespace Ryujinx.Graphics.Shader
|
|||||||
{
|
{
|
||||||
PointList = 1,
|
PointList = 1,
|
||||||
LineStrip = 6,
|
LineStrip = 6,
|
||||||
TriangleStrip = 7
|
TriangleStrip = 7,
|
||||||
}
|
}
|
||||||
|
|
||||||
static class OutputTopologyExtensions
|
static class OutputTopologyExtensions
|
||||||
{
|
{
|
||||||
public static string ToGlslString(this OutputTopology topology)
|
public static string ToGlslString(this OutputTopology topology)
|
||||||
{
|
{
|
||||||
switch (topology)
|
return topology switch
|
||||||
{
|
{
|
||||||
case OutputTopology.LineStrip: return "line_strip";
|
OutputTopology.LineStrip => "line_strip",
|
||||||
case OutputTopology.PointList: return "points";
|
OutputTopology.PointList => "points",
|
||||||
case OutputTopology.TriangleStrip: return "triangle_strip";
|
OutputTopology.TriangleStrip => "triangle_strip",
|
||||||
}
|
_ => "points",
|
||||||
|
};
|
||||||
return "points";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -18,7 +18,7 @@ namespace Ryujinx.Graphics.Shader
|
|||||||
Array = 1 << 8,
|
Array = 1 << 8,
|
||||||
Indexed = 1 << 9,
|
Indexed = 1 << 9,
|
||||||
Multisample = 1 << 10,
|
Multisample = 1 << 10,
|
||||||
Shadow = 1 << 11
|
Shadow = 1 << 11,
|
||||||
}
|
}
|
||||||
|
|
||||||
static class SamplerTypeExtensions
|
static class SamplerTypeExtensions
|
||||||
@@ -32,7 +32,7 @@ namespace Ryujinx.Graphics.Shader
|
|||||||
SamplerType.Texture2D => 2,
|
SamplerType.Texture2D => 2,
|
||||||
SamplerType.Texture3D => 3,
|
SamplerType.Texture3D => 3,
|
||||||
SamplerType.TextureCube => 3,
|
SamplerType.TextureCube => 3,
|
||||||
_ => throw new ArgumentException($"Invalid sampler type \"{type}\".")
|
_ => throw new ArgumentException($"Invalid sampler type \"{type}\"."),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ namespace Ryujinx.Graphics.Shader
|
|||||||
SamplerType.Texture2D => "sampler2D",
|
SamplerType.Texture2D => "sampler2D",
|
||||||
SamplerType.Texture3D => "sampler3D",
|
SamplerType.Texture3D => "sampler3D",
|
||||||
SamplerType.TextureCube => "samplerCube",
|
SamplerType.TextureCube => "samplerCube",
|
||||||
_ => throw new ArgumentException($"Invalid sampler type \"{type}\".")
|
_ => throw new ArgumentException($"Invalid sampler type \"{type}\"."),
|
||||||
};
|
};
|
||||||
|
|
||||||
if ((type & SamplerType.Multisample) != 0)
|
if ((type & SamplerType.Multisample) != 0)
|
||||||
@@ -75,7 +75,7 @@ namespace Ryujinx.Graphics.Shader
|
|||||||
SamplerType.Texture2D => "image2D",
|
SamplerType.Texture2D => "image2D",
|
||||||
SamplerType.Texture3D => "image3D",
|
SamplerType.Texture3D => "image3D",
|
||||||
SamplerType.TextureCube => "imageCube",
|
SamplerType.TextureCube => "imageCube",
|
||||||
_ => throw new ArgumentException($"Invalid sampler type \"{type}\".")
|
_ => throw new ArgumentException($"Invalid sampler type \"{type}\"."),
|
||||||
};
|
};
|
||||||
|
|
||||||
if ((type & SamplerType.Multisample) != 0)
|
if ((type & SamplerType.Multisample) != 0)
|
||||||
@@ -90,8 +90,12 @@ namespace Ryujinx.Graphics.Shader
|
|||||||
|
|
||||||
switch (componentType)
|
switch (componentType)
|
||||||
{
|
{
|
||||||
case AggregateType.U32: typeName = 'u' + typeName; break;
|
case AggregateType.U32:
|
||||||
case AggregateType.S32: typeName = 'i' + typeName; break;
|
typeName = 'u' + typeName;
|
||||||
|
break;
|
||||||
|
case AggregateType.S32:
|
||||||
|
typeName = 'i' + typeName;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return typeName;
|
return typeName;
|
||||||
|
@@ -3,6 +3,6 @@ namespace Ryujinx.Graphics.Shader
|
|||||||
public enum ShaderIdentification
|
public enum ShaderIdentification
|
||||||
{
|
{
|
||||||
None,
|
None,
|
||||||
GeometryLayerPassthrough
|
GeometryLayerPassthrough,
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -9,7 +9,7 @@ namespace Ryujinx.Graphics.Shader
|
|||||||
Geometry,
|
Geometry,
|
||||||
Fragment,
|
Fragment,
|
||||||
|
|
||||||
Count
|
Count,
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ShaderStageExtensions
|
public static class ShaderStageExtensions
|
||||||
|
@@ -29,7 +29,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private LinkedList<IAstNode> _nodes;
|
private readonly LinkedList<IAstNode> _nodes;
|
||||||
|
|
||||||
public IAstNode First => _nodes.First?.Value;
|
public IAstNode First => _nodes.First?.Value;
|
||||||
public IAstNode Last => _nodes.Last?.Value;
|
public IAstNode Last => _nodes.Last?.Value;
|
||||||
|
@@ -7,6 +7,6 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||||||
Else,
|
Else,
|
||||||
ElseIf,
|
ElseIf,
|
||||||
Main,
|
Main,
|
||||||
While
|
While,
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -49,9 +49,10 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||||||
|
|
||||||
public static AstOperand Local(AggregateType type)
|
public static AstOperand Local(AggregateType type)
|
||||||
{
|
{
|
||||||
AstOperand local = new AstOperand(OperandType.LocalVariable);
|
AstOperand local = new(OperandType.LocalVariable)
|
||||||
|
{
|
||||||
local.VarType = type;
|
VarType = type,
|
||||||
|
};
|
||||||
|
|
||||||
return local;
|
return local;
|
||||||
}
|
}
|
||||||
|
@@ -14,7 +14,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||||||
|
|
||||||
public int Index { get; }
|
public int Index { get; }
|
||||||
|
|
||||||
private IAstNode[] _sources;
|
private readonly IAstNode[] _sources;
|
||||||
|
|
||||||
public int SourcesCount => _sources.Length;
|
public int SourcesCount => _sources.Length;
|
||||||
|
|
||||||
@@ -77,9 +77,15 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||||||
|
|
||||||
switch (componentsCount)
|
switch (componentsCount)
|
||||||
{
|
{
|
||||||
case 2: type |= AggregateType.Vector2; break;
|
case 2:
|
||||||
case 3: type |= AggregateType.Vector3; break;
|
type |= AggregateType.Vector2;
|
||||||
case 4: type |= AggregateType.Vector4; break;
|
break;
|
||||||
|
case 3:
|
||||||
|
type |= AggregateType.Vector3;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
type |= AggregateType.Vector4;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return type;
|
return type;
|
||||||
|
@@ -17,7 +17,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||||||
// (this makes comparison with the disassembly easier).
|
// (this makes comparison with the disassembly easier).
|
||||||
if (!context.Config.Options.Flags.HasFlag(TranslationFlags.DebugMode))
|
if (!context.Config.Options.Flags.HasFlag(TranslationFlags.DebugMode))
|
||||||
{
|
{
|
||||||
AstBlockVisitor visitor = new AstBlockVisitor(mainBlock);
|
AstBlockVisitor visitor = new(mainBlock);
|
||||||
|
|
||||||
foreach (IAstNode node in visitor.Visit())
|
foreach (IAstNode node in visitor.Visit())
|
||||||
{
|
{
|
||||||
@@ -45,7 +45,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||||||
|
|
||||||
private static bool IsWorthPropagating(IAstNode source)
|
private static bool IsWorthPropagating(IAstNode source)
|
||||||
{
|
{
|
||||||
if (!(source is AstOperation srcOp))
|
if (source is not AstOperation srcOp)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -87,7 +87,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||||||
|
|
||||||
private static void RemoveEmptyBlocks(AstBlock mainBlock)
|
private static void RemoveEmptyBlocks(AstBlock mainBlock)
|
||||||
{
|
{
|
||||||
Queue<AstBlock> pending = new Queue<AstBlock>();
|
Queue<AstBlock> pending = new();
|
||||||
|
|
||||||
pending.Enqueue(mainBlock);
|
pending.Enqueue(mainBlock);
|
||||||
|
|
||||||
|
@@ -3,6 +3,6 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||||||
enum BufferLayout
|
enum BufferLayout
|
||||||
{
|
{
|
||||||
Std140,
|
Std140,
|
||||||
Std430
|
Std430,
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -1,7 +1,6 @@
|
|||||||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
using static Ryujinx.Graphics.Shader.StructuredIr.AstHelper;
|
using static Ryujinx.Graphics.Shader.StructuredIr.AstHelper;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Shader.StructuredIr
|
namespace Ryujinx.Graphics.Shader.StructuredIr
|
||||||
@@ -144,7 +143,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||||||
|
|
||||||
AstBlock[] path = BackwardsPath(block, ParentBlock(stmt.Label));
|
AstBlock[] path = BackwardsPath(block, ParentBlock(stmt.Label));
|
||||||
|
|
||||||
AstBlock loopFirstStmt = path[path.Length - 1];
|
AstBlock loopFirstStmt = path[^1];
|
||||||
|
|
||||||
if (loopFirstStmt.Type == AstBlockType.Else)
|
if (loopFirstStmt.Type == AstBlockType.Else)
|
||||||
{
|
{
|
||||||
@@ -265,7 +264,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||||||
else if (child.Type == AstBlockType.Else)
|
else if (child.Type == AstBlockType.Else)
|
||||||
{
|
{
|
||||||
// Modify the matching if condition to force the else to be entered by the goto.
|
// Modify the matching if condition to force the else to be entered by the goto.
|
||||||
if (!(Previous(child) is AstBlock ifBlock) || ifBlock.Type != AstBlockType.If)
|
if (Previous(child) is not AstBlock ifBlock || ifBlock.Type != AstBlockType.If)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("Found an else without a matching if.");
|
throw new InvalidOperationException("Found an else without a matching if.");
|
||||||
}
|
}
|
||||||
@@ -332,7 +331,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||||||
{
|
{
|
||||||
AstBlock block = ParentBlock(stmt.Goto);
|
AstBlock block = ParentBlock(stmt.Goto);
|
||||||
|
|
||||||
AstBlock newBlock = new AstBlock(AstBlockType.If, stmt.Condition);
|
AstBlock newBlock = new(AstBlockType.If, stmt.Condition);
|
||||||
|
|
||||||
block.AddAfter(stmt.Goto, newBlock);
|
block.AddAfter(stmt.Goto, newBlock);
|
||||||
|
|
||||||
@@ -367,7 +366,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||||||
return first as AstBlock;
|
return first as AstBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
AstBlock newBlock = new AstBlock(type, cond);
|
AstBlock newBlock = new(type, cond);
|
||||||
|
|
||||||
block.AddBefore(first, newBlock);
|
block.AddBefore(first, newBlock);
|
||||||
|
|
||||||
@@ -387,7 +386,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||||||
|
|
||||||
private static bool BlockMatches(IAstNode node, AstBlockType type, IAstNode cond)
|
private static bool BlockMatches(IAstNode node, AstBlockType type, IAstNode cond)
|
||||||
{
|
{
|
||||||
if (!(node is AstBlock block))
|
if (node is not AstBlock block)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -399,7 +398,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||||||
{
|
{
|
||||||
if (lCond is AstOperation lCondOp && lCondOp.Inst == Instruction.LogicalNot)
|
if (lCond is AstOperation lCondOp && lCondOp.Inst == Instruction.LogicalNot)
|
||||||
{
|
{
|
||||||
if (!(rCond is AstOperation rCondOp) || rCondOp.Inst != lCondOp.Inst)
|
if (rCond is not AstOperation rCondOp || rCondOp.Inst != lCondOp.Inst)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -418,7 +417,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||||||
return block.Parent;
|
return block.Parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!(node is AstBlock))
|
while (node is not AstBlock)
|
||||||
{
|
{
|
||||||
node = node.Parent;
|
node = node.Parent;
|
||||||
}
|
}
|
||||||
@@ -430,7 +429,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||||||
{
|
{
|
||||||
AstBlock block = bottom;
|
AstBlock block = bottom;
|
||||||
|
|
||||||
List<AstBlock> path = new List<AstBlock>();
|
List<AstBlock> path = new();
|
||||||
|
|
||||||
while (block != top)
|
while (block != top)
|
||||||
{
|
{
|
||||||
|
@@ -12,6 +12,6 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||||||
ShuffleUp = 1 << 6,
|
ShuffleUp = 1 << 6,
|
||||||
ShuffleXor = 1 << 7,
|
ShuffleXor = 1 << 7,
|
||||||
SwizzleAdd = 1 << 10,
|
SwizzleAdd = 1 << 10,
|
||||||
FSI = 1 << 11
|
FSI = 1 << 11,
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -19,12 +19,13 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static InstInfo[] _infoTbl;
|
private static readonly InstInfo[] _infoTbl;
|
||||||
|
|
||||||
static InstructionInfo()
|
static InstructionInfo()
|
||||||
{
|
{
|
||||||
_infoTbl = new InstInfo[(int)Instruction.Count];
|
_infoTbl = new InstInfo[(int)Instruction.Count];
|
||||||
|
|
||||||
|
#pragma warning disable IDE0055 // Disable formatting
|
||||||
// Inst Destination type Source 1 type Source 2 type Source 3 type Source 4 type
|
// Inst Destination type Source 1 type Source 2 type Source 3 type Source 4 type
|
||||||
Add(Instruction.AtomicAdd, AggregateType.U32, AggregateType.S32, AggregateType.S32, AggregateType.U32);
|
Add(Instruction.AtomicAdd, AggregateType.U32, AggregateType.S32, AggregateType.S32, AggregateType.U32);
|
||||||
Add(Instruction.AtomicAnd, AggregateType.U32, AggregateType.S32, AggregateType.S32, AggregateType.U32);
|
Add(Instruction.AtomicAnd, AggregateType.U32, AggregateType.S32, AggregateType.S32, AggregateType.U32);
|
||||||
@@ -130,6 +131,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||||||
Add(Instruction.VoteAll, AggregateType.Bool, AggregateType.Bool);
|
Add(Instruction.VoteAll, AggregateType.Bool, AggregateType.Bool);
|
||||||
Add(Instruction.VoteAllEqual, AggregateType.Bool, AggregateType.Bool);
|
Add(Instruction.VoteAllEqual, AggregateType.Bool, AggregateType.Bool);
|
||||||
Add(Instruction.VoteAny, AggregateType.Bool, AggregateType.Bool);
|
Add(Instruction.VoteAny, AggregateType.Bool, AggregateType.Bool);
|
||||||
|
#pragma warning restore IDE0055v
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Add(Instruction inst, AggregateType destType, params AggregateType[] srcTypes)
|
private static void Add(Instruction inst, AggregateType destType, params AggregateType[] srcTypes)
|
||||||
|
@@ -25,7 +25,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||||||
OperandType.Argument => AggregateType.S32,
|
OperandType.Argument => AggregateType.S32,
|
||||||
OperandType.Constant => AggregateType.S32,
|
OperandType.Constant => AggregateType.S32,
|
||||||
OperandType.Undefined => AggregateType.S32,
|
OperandType.Undefined => AggregateType.S32,
|
||||||
_ => throw new ArgumentException($"Invalid operand type \"{type}\".")
|
_ => throw new ArgumentException($"Invalid operand type \"{type}\"."),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -30,7 +30,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||||||
|
|
||||||
BasicBlock srcBlock = phi.GetBlock(index);
|
BasicBlock srcBlock = phi.GetBlock(index);
|
||||||
|
|
||||||
Operation copyOp = new Operation(Instruction.Copy, phi.Dest, src);
|
Operation copyOp = new(Instruction.Copy, phi.Dest, src);
|
||||||
|
|
||||||
srcBlock.Append(copyOp);
|
srcBlock.Append(copyOp);
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,7 @@ using Ryujinx.Graphics.Shader.Translation;
|
|||||||
|
|
||||||
namespace Ryujinx.Graphics.Shader.StructuredIr
|
namespace Ryujinx.Graphics.Shader.StructuredIr
|
||||||
{
|
{
|
||||||
struct StructureField
|
readonly struct StructureField
|
||||||
{
|
{
|
||||||
public AggregateType Type { get; }
|
public AggregateType Type { get; }
|
||||||
public string Name { get; }
|
public string Name { get; }
|
||||||
|
@@ -10,7 +10,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||||||
{
|
{
|
||||||
public static StructuredProgramInfo MakeStructuredProgram(IReadOnlyList<Function> functions, ShaderConfig config)
|
public static StructuredProgramInfo MakeStructuredProgram(IReadOnlyList<Function> functions, ShaderConfig config)
|
||||||
{
|
{
|
||||||
StructuredProgramContext context = new StructuredProgramContext(config);
|
StructuredProgramContext context = new(config);
|
||||||
|
|
||||||
for (int funcIndex = 0; funcIndex < functions.Count; funcIndex++)
|
for (int funcIndex = 0; funcIndex < functions.Count; funcIndex++)
|
||||||
{
|
{
|
||||||
@@ -79,7 +79,6 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||||||
{
|
{
|
||||||
IoVariable ioVariable = (IoVariable)operation.GetSource(0).Value;
|
IoVariable ioVariable = (IoVariable)operation.GetSource(0).Value;
|
||||||
bool isOutput = storageKind.IsOutput();
|
bool isOutput = storageKind.IsOutput();
|
||||||
bool perPatch = storageKind.IsPerPatch();
|
|
||||||
int location = 0;
|
int location = 0;
|
||||||
int component = 0;
|
int component = 0;
|
||||||
|
|
||||||
@@ -169,9 +168,15 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||||||
|
|
||||||
switch (componentsCount)
|
switch (componentsCount)
|
||||||
{
|
{
|
||||||
case 2: destType |= AggregateType.Vector2; break;
|
case 2:
|
||||||
case 3: destType |= AggregateType.Vector3; break;
|
destType |= AggregateType.Vector2;
|
||||||
case 4: destType |= AggregateType.Vector4; break;
|
break;
|
||||||
|
case 3:
|
||||||
|
destType |= AggregateType.Vector3;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
destType |= AggregateType.Vector4;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
AstOperand destVec = context.NewTemp(destType);
|
AstOperand destVec = context.NewTemp(destType);
|
||||||
@@ -181,7 +186,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||||||
for (int i = 0; i < operation.DestsCount; i++)
|
for (int i = 0; i < operation.DestsCount; i++)
|
||||||
{
|
{
|
||||||
AstOperand dest = context.GetOperand(operation.GetDest(i));
|
AstOperand dest = context.GetOperand(operation.GetDest(i));
|
||||||
AstOperand index = new AstOperand(OperandType.Constant, i);
|
AstOperand index = new(OperandType.Constant, i);
|
||||||
|
|
||||||
dest.VarType = destElemType;
|
dest.VarType = destElemType;
|
||||||
|
|
||||||
@@ -304,9 +309,9 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||||||
|
|
||||||
private static AggregateType GetVarTypeFromUses(Operand dest)
|
private static AggregateType GetVarTypeFromUses(Operand dest)
|
||||||
{
|
{
|
||||||
HashSet<Operand> visited = new HashSet<Operand>();
|
HashSet<Operand> visited = new();
|
||||||
|
|
||||||
Queue<Operand> pending = new Queue<Operand>();
|
Queue<Operand> pending = new();
|
||||||
|
|
||||||
bool Enqueue(Operand operand)
|
bool Enqueue(Operand operand)
|
||||||
{
|
{
|
||||||
@@ -385,7 +390,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||||||
{
|
{
|
||||||
Instruction.ImageLoad or
|
Instruction.ImageLoad or
|
||||||
Instruction.TextureSample => true,
|
Instruction.TextureSample => true,
|
||||||
_ => false
|
_ => false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -396,7 +401,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||||||
Instruction.Branch or
|
Instruction.Branch or
|
||||||
Instruction.BranchIfFalse or
|
Instruction.BranchIfFalse or
|
||||||
Instruction.BranchIfTrue => true,
|
Instruction.BranchIfTrue => true,
|
||||||
_ => false
|
_ => false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -408,7 +413,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||||||
Instruction.BitwiseExclusiveOr or
|
Instruction.BitwiseExclusiveOr or
|
||||||
Instruction.BitwiseNot or
|
Instruction.BitwiseNot or
|
||||||
Instruction.BitwiseOr => true,
|
Instruction.BitwiseOr => true,
|
||||||
_ => false
|
_ => false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -420,7 +425,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||||||
Instruction.BitwiseExclusiveOr => Instruction.LogicalExclusiveOr,
|
Instruction.BitwiseExclusiveOr => Instruction.LogicalExclusiveOr,
|
||||||
Instruction.BitwiseNot => Instruction.LogicalNot,
|
Instruction.BitwiseNot => Instruction.LogicalNot,
|
||||||
Instruction.BitwiseOr => Instruction.LogicalOr,
|
Instruction.BitwiseOr => Instruction.LogicalOr,
|
||||||
_ => throw new ArgumentException($"Unexpected instruction \"{inst}\".")
|
_ => throw new ArgumentException($"Unexpected instruction \"{inst}\"."),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3,7 +3,6 @@ using Ryujinx.Graphics.Shader.Translation;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
|
||||||
using static Ryujinx.Graphics.Shader.StructuredIr.AstHelper;
|
using static Ryujinx.Graphics.Shader.StructuredIr.AstHelper;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Shader.StructuredIr
|
namespace Ryujinx.Graphics.Shader.StructuredIr
|
||||||
@@ -184,11 +183,11 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||||||
|
|
||||||
AddNode(Assign(gotoTempAsg.Destination, cond));
|
AddNode(Assign(gotoTempAsg.Destination, cond));
|
||||||
|
|
||||||
AstOperation branch = new AstOperation(branchOp.Inst);
|
AstOperation branch = new(branchOp.Inst);
|
||||||
|
|
||||||
AddNode(branch);
|
AddNode(branch);
|
||||||
|
|
||||||
GotoStatement gotoStmt = new GotoStatement(branch, gotoTempAsg, isLoop);
|
GotoStatement gotoStmt = new(branch, gotoTempAsg, isLoop);
|
||||||
|
|
||||||
_gotos.Add(gotoStmt);
|
_gotos.Add(gotoStmt);
|
||||||
}
|
}
|
||||||
@@ -236,7 +235,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||||||
|
|
||||||
private void NewBlock(AstBlockType type, IAstNode cond, int endIndex)
|
private void NewBlock(AstBlockType type, IAstNode cond, int endIndex)
|
||||||
{
|
{
|
||||||
AstBlock childBlock = new AstBlock(type, cond);
|
AstBlock childBlock = new(type, cond);
|
||||||
|
|
||||||
AddNode(childBlock);
|
AddNode(childBlock);
|
||||||
|
|
||||||
@@ -316,7 +315,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
|||||||
new AstOperand(OperandType.Constant, binding),
|
new AstOperand(OperandType.Constant, binding),
|
||||||
new AstOperand(OperandType.Constant, 0),
|
new AstOperand(OperandType.Constant, 0),
|
||||||
new AstOperand(OperandType.Constant, vecIndex),
|
new AstOperand(OperandType.Constant, vecIndex),
|
||||||
new AstOperand(OperandType.Constant, elemIndex)
|
new AstOperand(OperandType.Constant, elemIndex),
|
||||||
};
|
};
|
||||||
|
|
||||||
return new AstOperation(Instruction.Load, StorageKind.ConstantBuffer, false, sources, sources.Length);
|
return new AstOperation(Instruction.Load, StorageKind.ConstantBuffer, false, sources, sources.Length);
|
||||||
|
@@ -20,22 +20,22 @@ namespace Ryujinx.Graphics.Shader
|
|||||||
FragmentIsBgra,
|
FragmentIsBgra,
|
||||||
ViewportInverse,
|
ViewportInverse,
|
||||||
FragmentRenderScaleCount,
|
FragmentRenderScaleCount,
|
||||||
RenderScale
|
RenderScale,
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct SupportBuffer
|
public struct SupportBuffer
|
||||||
{
|
{
|
||||||
internal const int Binding = 0;
|
internal const int Binding = 0;
|
||||||
|
|
||||||
public static int FieldSize;
|
public static readonly int FieldSize;
|
||||||
public static int RequiredSize;
|
public static readonly int RequiredSize;
|
||||||
|
|
||||||
public static int FragmentAlphaTestOffset;
|
public static readonly int FragmentAlphaTestOffset;
|
||||||
public static int FragmentIsBgraOffset;
|
public static readonly int FragmentIsBgraOffset;
|
||||||
public static int ViewportInverseOffset;
|
public static readonly int ViewportInverseOffset;
|
||||||
public static int FragmentRenderScaleCountOffset;
|
public static readonly int FragmentRenderScaleCountOffset;
|
||||||
public static int GraphicsRenderScaleOffset;
|
public static readonly int GraphicsRenderScaleOffset;
|
||||||
public static int ComputeRenderScaleOffset;
|
public static readonly int ComputeRenderScaleOffset;
|
||||||
|
|
||||||
public const int FragmentIsBgraCount = 8;
|
public const int FragmentIsBgraCount = 8;
|
||||||
// One for the render target, 64 for the textures, and 8 for the images.
|
// One for the render target, 64 for the textures, and 8 for the images.
|
||||||
@@ -51,7 +51,7 @@ namespace Ryujinx.Graphics.Shader
|
|||||||
FieldSize = Unsafe.SizeOf<Vector4<float>>();
|
FieldSize = Unsafe.SizeOf<Vector4<float>>();
|
||||||
RequiredSize = Unsafe.SizeOf<SupportBuffer>();
|
RequiredSize = Unsafe.SizeOf<SupportBuffer>();
|
||||||
|
|
||||||
SupportBuffer instance = new SupportBuffer();
|
SupportBuffer instance = new();
|
||||||
|
|
||||||
FragmentAlphaTestOffset = OffsetOf(ref instance, ref instance.FragmentAlphaTest);
|
FragmentAlphaTestOffset = OffsetOf(ref instance, ref instance.FragmentAlphaTest);
|
||||||
FragmentIsBgraOffset = OffsetOf(ref instance, ref instance.FragmentIsBgra);
|
FragmentIsBgraOffset = OffsetOf(ref instance, ref instance.FragmentIsBgra);
|
||||||
@@ -69,7 +69,7 @@ namespace Ryujinx.Graphics.Shader
|
|||||||
new StructureField(AggregateType.Array | AggregateType.U32, "s_is_bgra", FragmentIsBgraCount),
|
new StructureField(AggregateType.Array | AggregateType.U32, "s_is_bgra", FragmentIsBgraCount),
|
||||||
new StructureField(AggregateType.Vector4 | AggregateType.FP32, "s_viewport_inverse"),
|
new StructureField(AggregateType.Vector4 | AggregateType.FP32, "s_viewport_inverse"),
|
||||||
new StructureField(AggregateType.S32, "s_frag_scale_count"),
|
new StructureField(AggregateType.S32, "s_frag_scale_count"),
|
||||||
new StructureField(AggregateType.Array | AggregateType.FP32, "s_render_scale", RenderScaleMaxCount)
|
new StructureField(AggregateType.Array | AggregateType.FP32, "s_render_scale", RenderScaleMaxCount),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -4,7 +4,7 @@ namespace Ryujinx.Graphics.Shader
|
|||||||
{
|
{
|
||||||
Isolines = 0,
|
Isolines = 0,
|
||||||
Triangles = 1,
|
Triangles = 1,
|
||||||
Quads = 2
|
Quads = 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
static class TessPatchTypeExtensions
|
static class TessPatchTypeExtensions
|
||||||
@@ -15,7 +15,7 @@ namespace Ryujinx.Graphics.Shader
|
|||||||
{
|
{
|
||||||
TessPatchType.Isolines => "isolines",
|
TessPatchType.Isolines => "isolines",
|
||||||
TessPatchType.Quads => "quads",
|
TessPatchType.Quads => "quads",
|
||||||
_ => "triangles"
|
_ => "triangles",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -4,7 +4,7 @@ namespace Ryujinx.Graphics.Shader
|
|||||||
{
|
{
|
||||||
EqualSpacing = 0,
|
EqualSpacing = 0,
|
||||||
FractionalEventSpacing = 1,
|
FractionalEventSpacing = 1,
|
||||||
FractionalOddSpacing = 2
|
FractionalOddSpacing = 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
static class TessSpacingExtensions
|
static class TessSpacingExtensions
|
||||||
@@ -15,7 +15,7 @@ namespace Ryujinx.Graphics.Shader
|
|||||||
{
|
{
|
||||||
TessSpacing.FractionalEventSpacing => "fractional_even_spacing",
|
TessSpacing.FractionalEventSpacing => "fractional_even_spacing",
|
||||||
TessSpacing.FractionalOddSpacing => "fractional_odd_spacing",
|
TessSpacing.FractionalOddSpacing => "fractional_odd_spacing",
|
||||||
_ => "equal_spacing"
|
_ => "equal_spacing",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -43,7 +43,7 @@ namespace Ryujinx.Graphics.Shader
|
|||||||
R32G32B32A32Sint,
|
R32G32B32A32Sint,
|
||||||
R10G10B10A2Unorm,
|
R10G10B10A2Unorm,
|
||||||
R10G10B10A2Uint,
|
R10G10B10A2Uint,
|
||||||
R11G11B10Float
|
R11G11B10Float,
|
||||||
}
|
}
|
||||||
|
|
||||||
static class TextureFormatExtensions
|
static class TextureFormatExtensions
|
||||||
@@ -52,6 +52,7 @@ namespace Ryujinx.Graphics.Shader
|
|||||||
{
|
{
|
||||||
return format switch
|
return format switch
|
||||||
{
|
{
|
||||||
|
#pragma warning disable IDE0055 // Disable formatting
|
||||||
TextureFormat.R8Unorm => "r8",
|
TextureFormat.R8Unorm => "r8",
|
||||||
TextureFormat.R8Snorm => "r8_snorm",
|
TextureFormat.R8Snorm => "r8_snorm",
|
||||||
TextureFormat.R8Uint => "r8ui",
|
TextureFormat.R8Uint => "r8ui",
|
||||||
@@ -91,7 +92,8 @@ namespace Ryujinx.Graphics.Shader
|
|||||||
TextureFormat.R10G10B10A2Unorm => "rgb10_a2",
|
TextureFormat.R10G10B10A2Unorm => "rgb10_a2",
|
||||||
TextureFormat.R10G10B10A2Uint => "rgb10_a2ui",
|
TextureFormat.R10G10B10A2Uint => "rgb10_a2ui",
|
||||||
TextureFormat.R11G11B10Float => "r11f_g11f_b10f",
|
TextureFormat.R11G11B10Float => "r11f_g11f_b10f",
|
||||||
_ => string.Empty
|
_ => string.Empty,
|
||||||
|
#pragma warning restore IDE0055
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -8,7 +8,7 @@ namespace Ryujinx.Graphics.Shader
|
|||||||
CombinedSampler = 0, // Must be 0.
|
CombinedSampler = 0, // Must be 0.
|
||||||
SeparateSamplerHandle = 1,
|
SeparateSamplerHandle = 1,
|
||||||
SeparateSamplerId = 2,
|
SeparateSamplerId = 2,
|
||||||
SeparateConstantSamplerHandle = 3
|
SeparateConstantSamplerHandle = 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TextureHandle
|
public static class TextureHandle
|
||||||
|
@@ -14,6 +14,6 @@ namespace Ryujinx.Graphics.Shader
|
|||||||
ResScaleUnsupported = 1 << 0,
|
ResScaleUnsupported = 1 << 0,
|
||||||
NeedsScaleValue = 1 << 1,
|
NeedsScaleValue = 1 << 1,
|
||||||
ImageStore = 1 << 2,
|
ImageStore = 1 << 2,
|
||||||
ImageCoherent = 1 << 3
|
ImageCoherent = 1 << 3,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Shader.Translation
|
namespace Ryujinx.Graphics.Shader.Translation
|
||||||
{
|
{
|
||||||
[Flags]
|
[Flags]
|
||||||
|
[SuppressMessage("Design", "CA1069: Enums values should not be duplicated")]
|
||||||
enum AggregateType
|
enum AggregateType
|
||||||
{
|
{
|
||||||
Invalid,
|
Invalid,
|
||||||
@@ -23,7 +25,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
Vector3 = 2 << ElementCountShift,
|
Vector3 = 2 << ElementCountShift,
|
||||||
Vector4 = 3 << ElementCountShift,
|
Vector4 = 3 << ElementCountShift,
|
||||||
|
|
||||||
Array = 1 << 10
|
Array = 1 << 10,
|
||||||
}
|
}
|
||||||
|
|
||||||
static class AggregateTypeExtensions
|
static class AggregateTypeExtensions
|
||||||
@@ -37,7 +39,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
AggregateType.S32 or
|
AggregateType.S32 or
|
||||||
AggregateType.U32 => 4,
|
AggregateType.U32 => 4,
|
||||||
AggregateType.FP64 => 8,
|
AggregateType.FP64 => 8,
|
||||||
_ => 0
|
_ => 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
switch (type & AggregateType.ElementCountMask)
|
switch (type & AggregateType.ElementCountMask)
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user