Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
358a781639 | ||
|
45ce540b9b | ||
|
96bf7f8522 |
@@ -113,6 +113,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
Add(X86Instruction.Divps, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f5e, InstructionFlags.Vex));
|
Add(X86Instruction.Divps, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f5e, InstructionFlags.Vex));
|
||||||
Add(X86Instruction.Divsd, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f5e, InstructionFlags.Vex | InstructionFlags.PrefixF2));
|
Add(X86Instruction.Divsd, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f5e, InstructionFlags.Vex | InstructionFlags.PrefixF2));
|
||||||
Add(X86Instruction.Divss, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f5e, InstructionFlags.Vex | InstructionFlags.PrefixF3));
|
Add(X86Instruction.Divss, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f5e, InstructionFlags.Vex | InstructionFlags.PrefixF3));
|
||||||
|
Add(X86Instruction.Gf2p8affineqb, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x000f3ace, InstructionFlags.Prefix66));
|
||||||
Add(X86Instruction.Haddpd, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f7c, InstructionFlags.Vex | InstructionFlags.Prefix66));
|
Add(X86Instruction.Haddpd, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f7c, InstructionFlags.Vex | InstructionFlags.Prefix66));
|
||||||
Add(X86Instruction.Haddps, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f7c, InstructionFlags.Vex | InstructionFlags.PrefixF2));
|
Add(X86Instruction.Haddps, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f7c, InstructionFlags.Vex | InstructionFlags.PrefixF2));
|
||||||
Add(X86Instruction.Idiv, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x070000f7, InstructionFlags.None));
|
Add(X86Instruction.Idiv, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x070000f7, InstructionFlags.None));
|
||||||
|
@@ -20,8 +20,9 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
if (maxNum >= 7)
|
if (maxNum >= 7)
|
||||||
{
|
{
|
||||||
(_, int ebx7, _, _) = X86Base.CpuId(0x00000007, 0x00000000);
|
(_, int ebx7, int ecx7, _) = X86Base.CpuId(0x00000007, 0x00000000);
|
||||||
FeatureInfo7Ebx = (FeatureFlags7Ebx)ebx7;
|
FeatureInfo7Ebx = (FeatureFlags7Ebx)ebx7;
|
||||||
|
FeatureInfo7Ecx = (FeatureFlags7Ecx)ecx7;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,9 +55,16 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
Sha = 1 << 29
|
Sha = 1 << 29
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
public enum FeatureFlags7Ecx
|
||||||
|
{
|
||||||
|
Gfni = 1 << 8,
|
||||||
|
}
|
||||||
|
|
||||||
public static FeatureFlags1Edx FeatureInfo1Edx { get; }
|
public static FeatureFlags1Edx FeatureInfo1Edx { get; }
|
||||||
public static FeatureFlags1Ecx FeatureInfo1Ecx { get; }
|
public static FeatureFlags1Ecx FeatureInfo1Ecx { get; }
|
||||||
public static FeatureFlags7Ebx FeatureInfo7Ebx { get; } = 0;
|
public static FeatureFlags7Ebx FeatureInfo7Ebx { get; } = 0;
|
||||||
|
public static FeatureFlags7Ecx FeatureInfo7Ecx { get; } = 0;
|
||||||
|
|
||||||
public static bool SupportsSse => FeatureInfo1Edx.HasFlag(FeatureFlags1Edx.Sse);
|
public static bool SupportsSse => FeatureInfo1Edx.HasFlag(FeatureFlags1Edx.Sse);
|
||||||
public static bool SupportsSse2 => FeatureInfo1Edx.HasFlag(FeatureFlags1Edx.Sse2);
|
public static bool SupportsSse2 => FeatureInfo1Edx.HasFlag(FeatureFlags1Edx.Sse2);
|
||||||
@@ -72,6 +80,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
public static bool SupportsAvx2 => FeatureInfo7Ebx.HasFlag(FeatureFlags7Ebx.Avx2) && SupportsAvx;
|
public static bool SupportsAvx2 => FeatureInfo7Ebx.HasFlag(FeatureFlags7Ebx.Avx2) && SupportsAvx;
|
||||||
public static bool SupportsF16c => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.F16c);
|
public static bool SupportsF16c => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.F16c);
|
||||||
public static bool SupportsSha => FeatureInfo7Ebx.HasFlag(FeatureFlags7Ebx.Sha);
|
public static bool SupportsSha => FeatureInfo7Ebx.HasFlag(FeatureFlags7Ebx.Sha);
|
||||||
|
public static bool SupportsGfni => FeatureInfo7Ecx.HasFlag(FeatureFlags7Ecx.Gfni);
|
||||||
|
|
||||||
public static bool ForceLegacySse { get; set; }
|
public static bool ForceLegacySse { get; set; }
|
||||||
|
|
||||||
|
@@ -58,6 +58,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
Add(Intrinsic.X86Divps, new IntrinsicInfo(X86Instruction.Divps, IntrinsicType.Binary));
|
Add(Intrinsic.X86Divps, new IntrinsicInfo(X86Instruction.Divps, IntrinsicType.Binary));
|
||||||
Add(Intrinsic.X86Divsd, new IntrinsicInfo(X86Instruction.Divsd, IntrinsicType.Binary));
|
Add(Intrinsic.X86Divsd, new IntrinsicInfo(X86Instruction.Divsd, IntrinsicType.Binary));
|
||||||
Add(Intrinsic.X86Divss, new IntrinsicInfo(X86Instruction.Divss, IntrinsicType.Binary));
|
Add(Intrinsic.X86Divss, new IntrinsicInfo(X86Instruction.Divss, IntrinsicType.Binary));
|
||||||
|
Add(Intrinsic.X86Gf2p8affineqb, new IntrinsicInfo(X86Instruction.Gf2p8affineqb, IntrinsicType.TernaryImm));
|
||||||
Add(Intrinsic.X86Haddpd, new IntrinsicInfo(X86Instruction.Haddpd, IntrinsicType.Binary));
|
Add(Intrinsic.X86Haddpd, new IntrinsicInfo(X86Instruction.Haddpd, IntrinsicType.Binary));
|
||||||
Add(Intrinsic.X86Haddps, new IntrinsicInfo(X86Instruction.Haddps, IntrinsicType.Binary));
|
Add(Intrinsic.X86Haddps, new IntrinsicInfo(X86Instruction.Haddps, IntrinsicType.Binary));
|
||||||
Add(Intrinsic.X86Insertps, new IntrinsicInfo(X86Instruction.Insertps, IntrinsicType.TernaryImm));
|
Add(Intrinsic.X86Insertps, new IntrinsicInfo(X86Instruction.Insertps, IntrinsicType.TernaryImm));
|
||||||
|
@@ -54,6 +54,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
Divps,
|
Divps,
|
||||||
Divsd,
|
Divsd,
|
||||||
Divss,
|
Divss,
|
||||||
|
Gf2p8affineqb,
|
||||||
Haddpd,
|
Haddpd,
|
||||||
Haddps,
|
Haddps,
|
||||||
Idiv,
|
Idiv,
|
||||||
|
@@ -243,6 +243,21 @@ namespace ARMeilleure.Instructions
|
|||||||
throw new ArgumentException($"Invalid rounding mode \"{roundMode}\".");
|
throw new ArgumentException($"Invalid rounding mode \"{roundMode}\".");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ulong X86GetGf2p8LogicalShiftLeft(int shift)
|
||||||
|
{
|
||||||
|
ulong identity =
|
||||||
|
(0b00000001UL << 56) |
|
||||||
|
(0b00000010UL << 48) |
|
||||||
|
(0b00000100UL << 40) |
|
||||||
|
(0b00001000UL << 32) |
|
||||||
|
(0b00010000UL << 24) |
|
||||||
|
(0b00100000UL << 16) |
|
||||||
|
(0b01000000UL << 8) |
|
||||||
|
(0b10000000UL << 0);
|
||||||
|
|
||||||
|
return shift >= 0 ? identity >> (shift * 8) : identity << (-shift * 8);
|
||||||
|
}
|
||||||
|
|
||||||
public static Operand EmitCountSetBits8(ArmEmitterContext context, Operand op) // "size" is 8 (SIMD&FP Inst.).
|
public static Operand EmitCountSetBits8(ArmEmitterContext context, Operand op) // "size" is 8 (SIMD&FP Inst.).
|
||||||
{
|
{
|
||||||
Debug.Assert(op.Type == OperandType.I32 || op.Type == OperandType.I64);
|
Debug.Assert(op.Type == OperandType.I32 || op.Type == OperandType.I64);
|
||||||
|
@@ -336,8 +336,32 @@ namespace ARMeilleure.Instructions
|
|||||||
{
|
{
|
||||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||||
|
|
||||||
Operand res = context.VectorZero();
|
if (Optimizations.UseGfni)
|
||||||
|
{
|
||||||
|
const long bitMatrix =
|
||||||
|
(0b10000000L << 56) |
|
||||||
|
(0b01000000L << 48) |
|
||||||
|
(0b00100000L << 40) |
|
||||||
|
(0b00010000L << 32) |
|
||||||
|
(0b00001000L << 24) |
|
||||||
|
(0b00000100L << 16) |
|
||||||
|
(0b00000010L << 8) |
|
||||||
|
(0b00000001L << 0);
|
||||||
|
|
||||||
|
Operand vBitMatrix = X86GetAllElements(context, bitMatrix);
|
||||||
|
|
||||||
|
Operand res = context.AddIntrinsic(Intrinsic.X86Gf2p8affineqb, GetVec(op.Rn), vBitMatrix, Const(0));
|
||||||
|
|
||||||
|
if (op.RegisterSize == RegisterSize.Simd64)
|
||||||
|
{
|
||||||
|
res = context.VectorZeroUpper64(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
context.Copy(GetVec(op.Rd), res);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Operand res = context.VectorZero();
|
||||||
int elems = op.RegisterSize == RegisterSize.Simd128 ? 16 : 8;
|
int elems = op.RegisterSize == RegisterSize.Simd128 ? 16 : 8;
|
||||||
|
|
||||||
for (int index = 0; index < elems; index++)
|
for (int index = 0; index < elems; index++)
|
||||||
@@ -351,6 +375,7 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
context.Copy(GetVec(op.Rd), res);
|
context.Copy(GetVec(op.Rd), res);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Operand EmitReverseBits8Op(ArmEmitterContext context, Operand op)
|
private static Operand EmitReverseBits8Op(ArmEmitterContext context, Operand op)
|
||||||
{
|
{
|
||||||
|
@@ -88,8 +88,35 @@ namespace ARMeilleure.Instructions
|
|||||||
OpCodeSimdShImm op = (OpCodeSimdShImm)context.CurrOp;
|
OpCodeSimdShImm op = (OpCodeSimdShImm)context.CurrOp;
|
||||||
|
|
||||||
int shift = GetImmShl(op);
|
int shift = GetImmShl(op);
|
||||||
|
int eSize = 8 << op.Size;
|
||||||
|
|
||||||
if (Optimizations.UseSse2 && op.Size > 0)
|
if (shift >= eSize)
|
||||||
|
{
|
||||||
|
if ((op.RegisterSize == RegisterSize.Simd64))
|
||||||
|
{
|
||||||
|
Operand res = context.VectorZeroUpper64(GetVec(op.Rd));
|
||||||
|
|
||||||
|
context.Copy(GetVec(op.Rd), res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (Optimizations.UseGfni && op.Size == 0)
|
||||||
|
{
|
||||||
|
Operand n = GetVec(op.Rn);
|
||||||
|
|
||||||
|
ulong bitMatrix = X86GetGf2p8LogicalShiftLeft(shift);
|
||||||
|
|
||||||
|
Operand vBitMatrix = X86GetElements(context, bitMatrix, bitMatrix);
|
||||||
|
|
||||||
|
Operand res = context.AddIntrinsic(Intrinsic.X86Gf2p8affineqb, n, vBitMatrix, Const(0));
|
||||||
|
|
||||||
|
if (op.RegisterSize == RegisterSize.Simd64)
|
||||||
|
{
|
||||||
|
res = context.VectorZeroUpper64(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
context.Copy(GetVec(op.Rd), res);
|
||||||
|
}
|
||||||
|
else if (Optimizations.UseSse2 && op.Size > 0)
|
||||||
{
|
{
|
||||||
Operand n = GetVec(op.Rn);
|
Operand n = GetVec(op.Rn);
|
||||||
|
|
||||||
@@ -396,10 +423,40 @@ namespace ARMeilleure.Instructions
|
|||||||
{
|
{
|
||||||
OpCodeSimdShImm op = (OpCodeSimdShImm)context.CurrOp;
|
OpCodeSimdShImm op = (OpCodeSimdShImm)context.CurrOp;
|
||||||
|
|
||||||
if (Optimizations.UseSse2 && op.Size > 0 && op.Size < 3)
|
|
||||||
{
|
|
||||||
int shift = GetImmShr(op);
|
int shift = GetImmShr(op);
|
||||||
|
|
||||||
|
if (Optimizations.UseGfni && op.Size == 0)
|
||||||
|
{
|
||||||
|
Operand n = GetVec(op.Rn);
|
||||||
|
|
||||||
|
ulong bitMatrix;
|
||||||
|
|
||||||
|
if (shift < 8)
|
||||||
|
{
|
||||||
|
bitMatrix = X86GetGf2p8LogicalShiftLeft(-shift);
|
||||||
|
|
||||||
|
// Extend sign-bit
|
||||||
|
bitMatrix |= 0x8080808080808080UL >> (64 - shift * 8);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Replicate sign-bit into all bits
|
||||||
|
bitMatrix = 0x8080808080808080UL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Operand vBitMatrix = X86GetElements(context, bitMatrix, bitMatrix);
|
||||||
|
|
||||||
|
Operand res = context.AddIntrinsic(Intrinsic.X86Gf2p8affineqb, n, vBitMatrix, Const(0));
|
||||||
|
|
||||||
|
if (op.RegisterSize == RegisterSize.Simd64)
|
||||||
|
{
|
||||||
|
res = context.VectorZeroUpper64(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
context.Copy(GetVec(op.Rd), res);
|
||||||
|
}
|
||||||
|
else if (Optimizations.UseSse2 && op.Size > 0 && op.Size < 3)
|
||||||
|
{
|
||||||
Operand n = GetVec(op.Rn);
|
Operand n = GetVec(op.Rn);
|
||||||
|
|
||||||
Intrinsic sraInst = X86PsraInstruction[op.Size];
|
Intrinsic sraInst = X86PsraInstruction[op.Size];
|
||||||
@@ -929,10 +986,44 @@ namespace ARMeilleure.Instructions
|
|||||||
OpCodeSimdShImm op = (OpCodeSimdShImm)context.CurrOp;
|
OpCodeSimdShImm op = (OpCodeSimdShImm)context.CurrOp;
|
||||||
|
|
||||||
int shift = GetImmShl(op);
|
int shift = GetImmShl(op);
|
||||||
|
int eSize = 8 << op.Size;
|
||||||
|
|
||||||
ulong mask = shift != 0 ? ulong.MaxValue >> (64 - shift) : 0UL;
|
ulong mask = shift != 0 ? ulong.MaxValue >> (64 - shift) : 0UL;
|
||||||
|
|
||||||
if (Optimizations.UseSse2 && op.Size > 0)
|
if (shift >= eSize)
|
||||||
|
{
|
||||||
|
if ((op.RegisterSize == RegisterSize.Simd64) || scalar)
|
||||||
|
{
|
||||||
|
Operand res = context.VectorZeroUpper64(GetVec(op.Rd));
|
||||||
|
|
||||||
|
context.Copy(GetVec(op.Rd), res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (Optimizations.UseGfni && op.Size == 0)
|
||||||
|
{
|
||||||
|
Operand d = GetVec(op.Rd);
|
||||||
|
Operand n = GetVec(op.Rn);
|
||||||
|
|
||||||
|
ulong bitMatrix = X86GetGf2p8LogicalShiftLeft(shift);
|
||||||
|
|
||||||
|
Operand vBitMatrix = X86GetElements(context, bitMatrix, bitMatrix);
|
||||||
|
|
||||||
|
Operand nShifted = context.AddIntrinsic(Intrinsic.X86Gf2p8affineqb, n, vBitMatrix, Const(0));
|
||||||
|
|
||||||
|
Operand dMask = X86GetAllElements(context, (long)mask * _masks_SliSri[op.Size]);
|
||||||
|
|
||||||
|
Operand dMasked = context.AddIntrinsic(Intrinsic.X86Pand, d, dMask);
|
||||||
|
|
||||||
|
Operand res = context.AddIntrinsic(Intrinsic.X86Por, nShifted, dMasked);
|
||||||
|
|
||||||
|
if ((op.RegisterSize == RegisterSize.Simd64) || scalar)
|
||||||
|
{
|
||||||
|
res = context.VectorZeroUpper64(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
context.Copy(d, res);
|
||||||
|
}
|
||||||
|
else if (Optimizations.UseSse2 && op.Size > 0)
|
||||||
{
|
{
|
||||||
Operand d = GetVec(op.Rd);
|
Operand d = GetVec(op.Rd);
|
||||||
Operand n = GetVec(op.Rn);
|
Operand n = GetVec(op.Rn);
|
||||||
@@ -988,7 +1079,40 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
ulong mask = (ulong.MaxValue << (eSize - shift)) & (ulong.MaxValue >> (64 - eSize));
|
ulong mask = (ulong.MaxValue << (eSize - shift)) & (ulong.MaxValue >> (64 - eSize));
|
||||||
|
|
||||||
if (Optimizations.UseSse2 && op.Size > 0)
|
if (shift >= eSize)
|
||||||
|
{
|
||||||
|
if ((op.RegisterSize == RegisterSize.Simd64) || scalar)
|
||||||
|
{
|
||||||
|
Operand res = context.VectorZeroUpper64(GetVec(op.Rd));
|
||||||
|
|
||||||
|
context.Copy(GetVec(op.Rd), res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (Optimizations.UseGfni && op.Size == 0)
|
||||||
|
{
|
||||||
|
Operand d = GetVec(op.Rd);
|
||||||
|
Operand n = GetVec(op.Rn);
|
||||||
|
|
||||||
|
ulong bitMatrix = X86GetGf2p8LogicalShiftLeft(-shift);
|
||||||
|
|
||||||
|
Operand vBitMatrix = X86GetElements(context, bitMatrix, bitMatrix);
|
||||||
|
|
||||||
|
Operand nShifted = context.AddIntrinsic(Intrinsic.X86Gf2p8affineqb, n, vBitMatrix, Const(0));
|
||||||
|
|
||||||
|
Operand dMask = X86GetAllElements(context, (long)mask * _masks_SliSri[op.Size]);
|
||||||
|
|
||||||
|
Operand dMasked = context.AddIntrinsic(Intrinsic.X86Pand, d, dMask);
|
||||||
|
|
||||||
|
Operand res = context.AddIntrinsic(Intrinsic.X86Por, nShifted, dMasked);
|
||||||
|
|
||||||
|
if ((op.RegisterSize == RegisterSize.Simd64) || scalar)
|
||||||
|
{
|
||||||
|
res = context.VectorZeroUpper64(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
context.Copy(d, res);
|
||||||
|
}
|
||||||
|
else if (Optimizations.UseSse2 && op.Size > 0)
|
||||||
{
|
{
|
||||||
Operand d = GetVec(op.Rd);
|
Operand d = GetVec(op.Rd);
|
||||||
Operand n = GetVec(op.Rn);
|
Operand n = GetVec(op.Rn);
|
||||||
|
@@ -47,6 +47,7 @@ namespace ARMeilleure.IntermediateRepresentation
|
|||||||
X86Divps,
|
X86Divps,
|
||||||
X86Divsd,
|
X86Divsd,
|
||||||
X86Divss,
|
X86Divss,
|
||||||
|
X86Gf2p8affineqb,
|
||||||
X86Haddpd,
|
X86Haddpd,
|
||||||
X86Haddps,
|
X86Haddps,
|
||||||
X86Insertps,
|
X86Insertps,
|
||||||
|
@@ -22,6 +22,7 @@ namespace ARMeilleure
|
|||||||
public static bool UseAesniIfAvailable { get; set; } = true;
|
public static bool UseAesniIfAvailable { get; set; } = true;
|
||||||
public static bool UsePclmulqdqIfAvailable { get; set; } = true;
|
public static bool UsePclmulqdqIfAvailable { get; set; } = true;
|
||||||
public static bool UseShaIfAvailable { get; set; } = true;
|
public static bool UseShaIfAvailable { get; set; } = true;
|
||||||
|
public static bool UseGfniIfAvailable { get; set; } = true;
|
||||||
|
|
||||||
public static bool ForceLegacySse
|
public static bool ForceLegacySse
|
||||||
{
|
{
|
||||||
@@ -42,5 +43,6 @@ namespace ARMeilleure
|
|||||||
internal static bool UseAesni => UseAesniIfAvailable && HardwareCapabilities.SupportsAesni;
|
internal static bool UseAesni => UseAesniIfAvailable && HardwareCapabilities.SupportsAesni;
|
||||||
internal static bool UsePclmulqdq => UsePclmulqdqIfAvailable && HardwareCapabilities.SupportsPclmulqdq;
|
internal static bool UsePclmulqdq => UsePclmulqdqIfAvailable && HardwareCapabilities.SupportsPclmulqdq;
|
||||||
internal static bool UseSha => UseShaIfAvailable && HardwareCapabilities.SupportsSha;
|
internal static bool UseSha => UseShaIfAvailable && HardwareCapabilities.SupportsSha;
|
||||||
|
internal static bool UseGfni => UseGfniIfAvailable && HardwareCapabilities.SupportsGfni;
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -27,7 +27,7 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
private const string OuterHeaderMagicString = "PTCohd\0\0";
|
private const string OuterHeaderMagicString = "PTCohd\0\0";
|
||||||
private const string InnerHeaderMagicString = "PTCihd\0\0";
|
private const string InnerHeaderMagicString = "PTCihd\0\0";
|
||||||
|
|
||||||
private const uint InternalVersion = 3703; //! To be incremented manually for each change to the ARMeilleure project.
|
private const uint InternalVersion = 3710; //! To be incremented manually for each change to the ARMeilleure project.
|
||||||
|
|
||||||
private const string ActualDir = "0";
|
private const string ActualDir = "0";
|
||||||
private const string BackupDir = "1";
|
private const string BackupDir = "1";
|
||||||
@@ -951,7 +951,8 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
return new FeatureInfo(
|
return new FeatureInfo(
|
||||||
(uint)HardwareCapabilities.FeatureInfo1Ecx,
|
(uint)HardwareCapabilities.FeatureInfo1Ecx,
|
||||||
(uint)HardwareCapabilities.FeatureInfo1Edx,
|
(uint)HardwareCapabilities.FeatureInfo1Edx,
|
||||||
(uint)HardwareCapabilities.FeatureInfo7Ebx);
|
(uint)HardwareCapabilities.FeatureInfo7Ebx,
|
||||||
|
(uint)HardwareCapabilities.FeatureInfo7Ecx);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte GetMemoryManagerMode()
|
private static byte GetMemoryManagerMode()
|
||||||
@@ -971,7 +972,7 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
return osPlatform;
|
return osPlatform;
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 54*/)]
|
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 58*/)]
|
||||||
private struct OuterHeader
|
private struct OuterHeader
|
||||||
{
|
{
|
||||||
public ulong Magic;
|
public ulong Magic;
|
||||||
@@ -1002,8 +1003,8 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 12*/)]
|
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 16*/)]
|
||||||
private record struct FeatureInfo(uint FeatureInfo0, uint FeatureInfo1, uint FeatureInfo2);
|
private record struct FeatureInfo(uint FeatureInfo0, uint FeatureInfo1, uint FeatureInfo2, uint FeatureInfo3);
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 128*/)]
|
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 128*/)]
|
||||||
private struct InnerHeader
|
private struct InnerHeader
|
||||||
|
@@ -58,6 +58,8 @@ namespace Ryujinx.Ava
|
|||||||
private const float MaxResolutionScale = 4.0f; // Max resolution hotkeys can scale to before wrapping.
|
private const float MaxResolutionScale = 4.0f; // Max resolution hotkeys can scale to before wrapping.
|
||||||
private const int TargetFps = 60;
|
private const int TargetFps = 60;
|
||||||
|
|
||||||
|
private const float VolumeDelta = 0.05f;
|
||||||
|
|
||||||
private static readonly Cursor InvisibleCursor = new Cursor(StandardCursorType.None);
|
private static readonly Cursor InvisibleCursor = new Cursor(StandardCursorType.None);
|
||||||
|
|
||||||
private readonly long _ticksPerFrame;
|
private readonly long _ticksPerFrame;
|
||||||
@@ -73,6 +75,7 @@ namespace Ryujinx.Ava
|
|||||||
private bool _isStopped;
|
private bool _isStopped;
|
||||||
private bool _isActive;
|
private bool _isActive;
|
||||||
private long _lastCursorMoveTime;
|
private long _lastCursorMoveTime;
|
||||||
|
private float _newVolume;
|
||||||
private long _ticks = 0;
|
private long _ticks = 0;
|
||||||
|
|
||||||
private KeyboardHotkeyState _prevHotkeyState;
|
private KeyboardHotkeyState _prevHotkeyState;
|
||||||
@@ -1003,6 +1006,18 @@ namespace Ryujinx.Ava
|
|||||||
GraphicsConfig.ResScale =
|
GraphicsConfig.ResScale =
|
||||||
(MaxResolutionScale + GraphicsConfig.ResScale - 2) % MaxResolutionScale + 1;
|
(MaxResolutionScale + GraphicsConfig.ResScale - 2) % MaxResolutionScale + 1;
|
||||||
break;
|
break;
|
||||||
|
case KeyboardHotkeyState.VolumeUp:
|
||||||
|
_newVolume = MathF.Round((Device.GetVolume() + VolumeDelta), 2);
|
||||||
|
Device.SetVolume(_newVolume);
|
||||||
|
|
||||||
|
_parent.ViewModel.Volume = Device.GetVolume();
|
||||||
|
break;
|
||||||
|
case KeyboardHotkeyState.VolumeDown:
|
||||||
|
_newVolume = MathF.Round((Device.GetVolume() - VolumeDelta), 2);
|
||||||
|
Device.SetVolume(_newVolume);
|
||||||
|
|
||||||
|
_parent.ViewModel.Volume = Device.GetVolume();
|
||||||
|
break;
|
||||||
case KeyboardHotkeyState.None:
|
case KeyboardHotkeyState.None:
|
||||||
(_keyboardInterface as AvaloniaKeyboard).Clear();
|
(_keyboardInterface as AvaloniaKeyboard).Clear();
|
||||||
break;
|
break;
|
||||||
@@ -1068,6 +1083,14 @@ namespace Ryujinx.Ava
|
|||||||
{
|
{
|
||||||
state = KeyboardHotkeyState.ResScaleDown;
|
state = KeyboardHotkeyState.ResScaleDown;
|
||||||
}
|
}
|
||||||
|
else if (_keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.VolumeUp))
|
||||||
|
{
|
||||||
|
state = KeyboardHotkeyState.VolumeUp;
|
||||||
|
}
|
||||||
|
else if (_keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.VolumeDown))
|
||||||
|
{
|
||||||
|
state = KeyboardHotkeyState.VolumeDown;
|
||||||
|
}
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
@@ -589,5 +589,7 @@
|
|||||||
"SettingsAppRequiredRestartMessage": "Ryujinx Restart Required",
|
"SettingsAppRequiredRestartMessage": "Ryujinx Restart Required",
|
||||||
"SettingsGpuBackendRestartMessage": "Graphics Backend or Gpu settings have been modified. This will require a restart to be applied",
|
"SettingsGpuBackendRestartMessage": "Graphics Backend or Gpu settings have been modified. This will require a restart to be applied",
|
||||||
"SettingsGpuBackendRestartSubMessage": "Do you want to restart now?",
|
"SettingsGpuBackendRestartSubMessage": "Do you want to restart now?",
|
||||||
|
"SettingsTabHotkeysVolumeUpHotkey": "Increase Volume:",
|
||||||
|
"SettingsTabHotkeysVolumeDownHotkey": "Decrease Volume:",
|
||||||
"VolumeShort": "Vol"
|
"VolumeShort": "Vol"
|
||||||
}
|
}
|
||||||
|
@@ -9,6 +9,8 @@
|
|||||||
Pause,
|
Pause,
|
||||||
ToggleMute,
|
ToggleMute,
|
||||||
ResScaleUp,
|
ResScaleUp,
|
||||||
ResScaleDown
|
ResScaleDown,
|
||||||
|
VolumeUp,
|
||||||
|
VolumeDown
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -257,6 +257,22 @@
|
|||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
<StackPanel Margin="10,0,0,0" Orientation="Horizontal">
|
||||||
|
<TextBlock VerticalAlignment="Center" Text="{locale:Locale SettingsTabHotkeysVolumeUpHotkey}" Width="230" />
|
||||||
|
<ToggleButton Width="90" Height="27" Checked="Button_Checked" Unchecked="Button_Unchecked">
|
||||||
|
<TextBlock
|
||||||
|
Text="{Binding KeyboardHotkeys.VolumeUp, Mode=TwoWay, Converter={StaticResource Key}}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
</ToggleButton>
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel Margin="10,0,0,0" Orientation="Horizontal">
|
||||||
|
<TextBlock VerticalAlignment="Center" Text="{locale:Locale SettingsTabHotkeysVolumeDownHotkey}" Width="230" />
|
||||||
|
<ToggleButton Width="90" Height="27" Checked="Button_Checked" Unchecked="Button_Unchecked">
|
||||||
|
<TextBlock
|
||||||
|
Text="{Binding KeyboardHotkeys.VolumeDown, Mode=TwoWay, Converter={StaticResource Key}}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
</ToggleButton>
|
||||||
|
</StackPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Border>
|
</Border>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
|
@@ -9,5 +9,7 @@
|
|||||||
public Key ToggleMute { get; set; }
|
public Key ToggleMute { get; set; }
|
||||||
public Key ResScaleUp { get; set; }
|
public Key ResScaleUp { get; set; }
|
||||||
public Key ResScaleDown { get; set; }
|
public Key ResScaleDown { get; set; }
|
||||||
|
public Key VolumeUp { get; set; }
|
||||||
|
public Key VolumeDown { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -9,17 +9,19 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Ryujinx.Graphics.Vulkan
|
namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
class Shader
|
class Shader : IDisposable
|
||||||
{
|
{
|
||||||
// The shaderc.net dependency's Options constructor and dispose are not thread safe.
|
// The shaderc.net dependency's Options constructor and dispose are not thread safe.
|
||||||
// Take this lock when using them.
|
// Take this lock when using them.
|
||||||
private static object _shaderOptionsLock = new object();
|
private static object _shaderOptionsLock = new object();
|
||||||
|
|
||||||
|
private static readonly IntPtr _ptrMainEntryPointName = Marshal.StringToHGlobalAnsi("main");
|
||||||
|
|
||||||
private readonly Vk _api;
|
private readonly Vk _api;
|
||||||
private readonly Device _device;
|
private readonly Device _device;
|
||||||
private readonly ShaderStageFlags _stage;
|
private readonly ShaderStageFlags _stage;
|
||||||
|
|
||||||
private IntPtr _entryPointName;
|
private bool _disposed;
|
||||||
private ShaderModule _module;
|
private ShaderModule _module;
|
||||||
|
|
||||||
public ShaderStageFlags StageFlags => _stage;
|
public ShaderStageFlags StageFlags => _stage;
|
||||||
@@ -39,7 +41,6 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
CompileStatus = ProgramLinkStatus.Incomplete;
|
CompileStatus = ProgramLinkStatus.Incomplete;
|
||||||
|
|
||||||
_stage = shaderSource.Stage.Convert();
|
_stage = shaderSource.Stage.Convert();
|
||||||
_entryPointName = Marshal.StringToHGlobalAnsi("main");
|
|
||||||
|
|
||||||
CompileTask = Task.Run(() =>
|
CompileTask = Task.Run(() =>
|
||||||
{
|
{
|
||||||
@@ -145,7 +146,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
SType = StructureType.PipelineShaderStageCreateInfo,
|
SType = StructureType.PipelineShaderStageCreateInfo,
|
||||||
Stage = _stage,
|
Stage = _stage,
|
||||||
Module = _module,
|
Module = _module,
|
||||||
PName = (byte*)_entryPointName
|
PName = (byte*)_ptrMainEntryPointName
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,11 +157,10 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public unsafe void Dispose()
|
public unsafe void Dispose()
|
||||||
{
|
{
|
||||||
if (_entryPointName != IntPtr.Zero)
|
if (!_disposed)
|
||||||
{
|
{
|
||||||
_api.DestroyShaderModule(_device, _module, null);
|
_api.DestroyShaderModule(_device, _module, null);
|
||||||
Marshal.FreeHGlobal(_entryPointName);
|
_disposed = true;
|
||||||
_entryPointName = IntPtr.Zero;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -124,7 +124,7 @@ namespace Ryujinx.HLE
|
|||||||
|
|
||||||
public void SetVolume(float volume)
|
public void SetVolume(float volume)
|
||||||
{
|
{
|
||||||
System.SetVolume(volume);
|
System.SetVolume(Math.Clamp(volume, 0, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
public float GetVolume()
|
public float GetVolume()
|
||||||
|
@@ -14,7 +14,7 @@ namespace Ryujinx.Ui.Common.Configuration
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The current version of the file format
|
/// The current version of the file format
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const int CurrentVersion = 40;
|
public const int CurrentVersion = 41;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Version of the configuration file format
|
/// Version of the configuration file format
|
||||||
|
@@ -677,7 +677,9 @@ namespace Ryujinx.Ui.Common.Configuration
|
|||||||
ShowUi = Key.F4,
|
ShowUi = Key.F4,
|
||||||
Pause = Key.F5,
|
Pause = Key.F5,
|
||||||
ResScaleUp = Key.Unbound,
|
ResScaleUp = Key.Unbound,
|
||||||
ResScaleDown = Key.Unbound
|
ResScaleDown = Key.Unbound,
|
||||||
|
VolumeUp = Key.Unbound,
|
||||||
|
VolumeDown = Key.Unbound
|
||||||
};
|
};
|
||||||
Hid.InputConfig.Value = new List<InputConfig>
|
Hid.InputConfig.Value = new List<InputConfig>
|
||||||
{
|
{
|
||||||
@@ -1156,6 +1158,24 @@ namespace Ryujinx.Ui.Common.Configuration
|
|||||||
configurationFileUpdated = true;
|
configurationFileUpdated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 41)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 41.");
|
||||||
|
|
||||||
|
configurationFileFormat.Hotkeys = new KeyboardHotkeys
|
||||||
|
{
|
||||||
|
ToggleVsync = configurationFileFormat.Hotkeys.ToggleVsync,
|
||||||
|
Screenshot = configurationFileFormat.Hotkeys.Screenshot,
|
||||||
|
ShowUi = configurationFileFormat.Hotkeys.ShowUi,
|
||||||
|
Pause = configurationFileFormat.Hotkeys.Pause,
|
||||||
|
ToggleMute = configurationFileFormat.Hotkeys.ToggleMute,
|
||||||
|
ResScaleUp = configurationFileFormat.Hotkeys.ResScaleUp,
|
||||||
|
ResScaleDown = configurationFileFormat.Hotkeys.ResScaleDown,
|
||||||
|
VolumeUp = Key.Unbound,
|
||||||
|
VolumeDown = Key.Unbound
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
Logger.EnableFileLog.Value = configurationFileFormat.EnableFileLog;
|
Logger.EnableFileLog.Value = configurationFileFormat.EnableFileLog;
|
||||||
Graphics.ResScale.Value = configurationFileFormat.ResScale;
|
Graphics.ResScale.Value = configurationFileFormat.ResScale;
|
||||||
Graphics.ResScaleCustom.Value = configurationFileFormat.ResScaleCustom;
|
Graphics.ResScaleCustom.Value = configurationFileFormat.ResScaleCustom;
|
||||||
|
@@ -35,6 +35,7 @@ namespace Ryujinx.Ui
|
|||||||
private const int SwitchPanelHeight = 720;
|
private const int SwitchPanelHeight = 720;
|
||||||
private const int TargetFps = 60;
|
private const int TargetFps = 60;
|
||||||
private const float MaxResolutionScale = 4.0f; // Max resolution hotkeys can scale to before wrapping.
|
private const float MaxResolutionScale = 4.0f; // Max resolution hotkeys can scale to before wrapping.
|
||||||
|
private const float VolumeDelta = 0.05f;
|
||||||
|
|
||||||
public ManualResetEvent WaitEvent { get; set; }
|
public ManualResetEvent WaitEvent { get; set; }
|
||||||
public NpadManager NpadManager { get; }
|
public NpadManager NpadManager { get; }
|
||||||
@@ -57,6 +58,7 @@ namespace Ryujinx.Ui
|
|||||||
private readonly long _ticksPerFrame;
|
private readonly long _ticksPerFrame;
|
||||||
|
|
||||||
private long _ticks = 0;
|
private long _ticks = 0;
|
||||||
|
private float _newVolume;
|
||||||
|
|
||||||
private readonly Stopwatch _chrono;
|
private readonly Stopwatch _chrono;
|
||||||
|
|
||||||
@@ -643,6 +645,20 @@ namespace Ryujinx.Ui
|
|||||||
(MaxResolutionScale + GraphicsConfig.ResScale - 2) % MaxResolutionScale + 1;
|
(MaxResolutionScale + GraphicsConfig.ResScale - 2) % MaxResolutionScale + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (currentHotkeyState.HasFlag(KeyboardHotkeyState.VolumeUp) &&
|
||||||
|
!_prevHotkeyState.HasFlag(KeyboardHotkeyState.VolumeUp))
|
||||||
|
{
|
||||||
|
_newVolume = MathF.Round((Device.GetVolume() + VolumeDelta), 2);
|
||||||
|
Device.SetVolume(_newVolume);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentHotkeyState.HasFlag(KeyboardHotkeyState.VolumeDown) &&
|
||||||
|
!_prevHotkeyState.HasFlag(KeyboardHotkeyState.VolumeDown))
|
||||||
|
{
|
||||||
|
_newVolume = MathF.Round((Device.GetVolume() - VolumeDelta), 2);
|
||||||
|
Device.SetVolume(_newVolume);
|
||||||
|
}
|
||||||
|
|
||||||
_prevHotkeyState = currentHotkeyState;
|
_prevHotkeyState = currentHotkeyState;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -675,7 +691,9 @@ namespace Ryujinx.Ui
|
|||||||
Pause = 1 << 3,
|
Pause = 1 << 3,
|
||||||
ToggleMute = 1 << 4,
|
ToggleMute = 1 << 4,
|
||||||
ResScaleUp = 1 << 5,
|
ResScaleUp = 1 << 5,
|
||||||
ResScaleDown = 1 << 6
|
ResScaleDown = 1 << 6,
|
||||||
|
VolumeUp = 1 << 7,
|
||||||
|
VolumeDown = 1 << 8
|
||||||
}
|
}
|
||||||
|
|
||||||
private KeyboardHotkeyState GetHotkeyState()
|
private KeyboardHotkeyState GetHotkeyState()
|
||||||
@@ -717,6 +735,16 @@ namespace Ryujinx.Ui
|
|||||||
state |= KeyboardHotkeyState.ResScaleDown;
|
state |= KeyboardHotkeyState.ResScaleDown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.VolumeUp))
|
||||||
|
{
|
||||||
|
state |= KeyboardHotkeyState.VolumeUp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.VolumeDown))
|
||||||
|
{
|
||||||
|
state |= KeyboardHotkeyState.VolumeDown;
|
||||||
|
}
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user