Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
296c4a3d01 | ||
|
e7cf4e6eaf | ||
|
a1a4771ac1 | ||
|
2fd819613f | ||
|
ad6ff6ce99 | ||
|
dc30d94852 | ||
|
4f293f8cbe | ||
|
32a1cd83fd | ||
|
e3d0ccf8d5 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -170,3 +170,6 @@ launchSettings.json
|
|||||||
|
|
||||||
# NetCore Publishing Profiles
|
# NetCore Publishing Profiles
|
||||||
PublishProfiles/
|
PublishProfiles/
|
||||||
|
|
||||||
|
# Glade backup files
|
||||||
|
*.glade~
|
||||||
|
@@ -16,4 +16,10 @@
|
|||||||
</ContentWithTargetPath>
|
</ContentWithTargetPath>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
|
||||||
|
<_Parameter1>Ryujinx.Tests</_Parameter1>
|
||||||
|
</AssemblyAttribute>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@@ -1,5 +1,4 @@
|
|||||||
using ARMeilleure.IntermediateRepresentation;
|
using ARMeilleure.IntermediateRepresentation;
|
||||||
using System;
|
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
|
||||||
namespace ARMeilleure.CodeGen.Arm64
|
namespace ARMeilleure.CodeGen.Arm64
|
||||||
@@ -32,9 +31,12 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
public static bool TryEncodeBitMask(Operand operand, out int immN, out int immS, out int immR)
|
public static bool TryEncodeBitMask(Operand operand, out int immN, out int immS, out int immR)
|
||||||
{
|
{
|
||||||
ulong value = operand.Value;
|
return TryEncodeBitMask(operand.Type, operand.Value, out immN, out immS, out immR);
|
||||||
|
}
|
||||||
|
|
||||||
if (operand.Type == OperandType.I32)
|
public static bool TryEncodeBitMask(OperandType type, ulong value, out int immN, out int immS, out int immR)
|
||||||
|
{
|
||||||
|
if (type == OperandType.I32)
|
||||||
{
|
{
|
||||||
value |= value << 32;
|
value |= value << 32;
|
||||||
}
|
}
|
||||||
@@ -50,7 +52,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
// Any value AND all ones will be equal itself, so it's effectively a no-op.
|
// Any value AND all ones will be equal itself, so it's effectively a no-op.
|
||||||
// Any value OR all ones will be equal all ones, so one can just use MOV.
|
// Any value OR all ones will be equal all ones, so one can just use MOV.
|
||||||
// Any value XOR all ones will be equal its inverse, so one can just use MVN.
|
// Any value XOR all ones will be equal its inverse, so one can just use MVN.
|
||||||
if (value == ulong.MaxValue)
|
if (value == 0 || value == ulong.MaxValue)
|
||||||
{
|
{
|
||||||
immN = 0;
|
immN = 0;
|
||||||
immS = 0;
|
immS = 0;
|
||||||
@@ -59,79 +61,18 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bitLength = CountSequence(value);
|
// Normalize value, rotating it such that the LSB is 1: Ensures we get a complete element that has not
|
||||||
|
// been cut-in-half across the word boundary.
|
||||||
|
int rotation = BitOperations.TrailingZeroCount(value & (value + 1));
|
||||||
|
ulong rotatedValue = ulong.RotateRight(value, rotation);
|
||||||
|
|
||||||
if ((value >> bitLength) != 0)
|
// Now that we have a complete element in the LSB with the LSB = 1, determine size and number of ones
|
||||||
{
|
// in element.
|
||||||
bitLength += CountSequence(value >> bitLength);
|
int elementSize = BitOperations.TrailingZeroCount(rotatedValue & (rotatedValue + 1));
|
||||||
}
|
int onesInElement = BitOperations.TrailingZeroCount(~rotatedValue);
|
||||||
|
|
||||||
int bitLengthLog2 = BitOperations.Log2((uint)bitLength);
|
// Check the value is repeating; also ensures element size is a power of two.
|
||||||
int bitLengthPow2 = 1 << bitLengthLog2;
|
if (ulong.RotateRight(value, elementSize) != value)
|
||||||
|
|
||||||
if (bitLengthPow2 < bitLength)
|
|
||||||
{
|
|
||||||
bitLengthLog2++;
|
|
||||||
bitLengthPow2 <<= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int selectedESize = 64;
|
|
||||||
int repetitions = 1;
|
|
||||||
int onesCount = BitOperations.PopCount(value);
|
|
||||||
|
|
||||||
if (bitLengthPow2 < 64 && (value >> bitLengthPow2) != 0)
|
|
||||||
{
|
|
||||||
for (int eSizeLog2 = bitLengthLog2; eSizeLog2 < 6; eSizeLog2++)
|
|
||||||
{
|
|
||||||
bool match = true;
|
|
||||||
int eSize = 1 << eSizeLog2;
|
|
||||||
ulong mask = (1UL << eSize) - 1;
|
|
||||||
ulong eValue = value & mask;
|
|
||||||
|
|
||||||
for (int e = 1; e < 64 / eSize; e++)
|
|
||||||
{
|
|
||||||
if (((value >> (e * eSize)) & mask) != eValue)
|
|
||||||
{
|
|
||||||
match = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (match)
|
|
||||||
{
|
|
||||||
selectedESize = eSize;
|
|
||||||
repetitions = 64 / eSize;
|
|
||||||
onesCount = BitOperations.PopCount(eValue);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find rotation. We have two cases, one where the highest bit is 0
|
|
||||||
// and one where it is 1.
|
|
||||||
// If it's 1, we just need to count the number of 1 bits on the MSB to find the right rotation.
|
|
||||||
// If it's 0, we just need to count the number of 0 bits on the LSB to find the left rotation,
|
|
||||||
// then we can convert it to the right rotation shift by subtracting the value from the element size.
|
|
||||||
int rotation;
|
|
||||||
long vHigh = (long)(value << (64 - selectedESize));
|
|
||||||
if (vHigh < 0)
|
|
||||||
{
|
|
||||||
rotation = BitOperations.LeadingZeroCount(~(ulong)vHigh);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rotation = (selectedESize - BitOperations.TrailingZeroCount(value)) & (selectedESize - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reconstruct value and see if it matches. If not, we can't encode.
|
|
||||||
ulong reconstructed = onesCount == 64 ? ulong.MaxValue : RotateRight((1UL << onesCount) - 1, rotation, selectedESize);
|
|
||||||
|
|
||||||
for (int bit = 32; bit >= selectedESize; bit >>= 1)
|
|
||||||
{
|
|
||||||
reconstructed |= reconstructed << bit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reconstructed != value || onesCount == 0)
|
|
||||||
{
|
{
|
||||||
immN = 0;
|
immN = 0;
|
||||||
immS = 0;
|
immS = 0;
|
||||||
@@ -140,34 +81,11 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
immR = rotation;
|
immN = (elementSize >> 6) & 1;
|
||||||
|
immS = (((~elementSize + 1) << 1) | (onesInElement - 1)) & 0x3f;
|
||||||
// immN indicates that there are no repetitions.
|
immR = (elementSize - rotation) & (elementSize - 1);
|
||||||
// The MSB of immS indicates the amount of repetitions, and the LSB the number of bits set.
|
|
||||||
if (repetitions == 1)
|
|
||||||
{
|
|
||||||
immN = 1;
|
|
||||||
immS = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
immN = 0;
|
|
||||||
immS = (0xf80 >> BitOperations.Log2((uint)repetitions)) & 0x3f;
|
|
||||||
}
|
|
||||||
|
|
||||||
immS |= onesCount - 1;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int CountSequence(ulong value)
|
|
||||||
{
|
|
||||||
return BitOperations.TrailingZeroCount(value) + BitOperations.TrailingZeroCount(~value);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ulong RotateRight(ulong bits, int shift, int size)
|
|
||||||
{
|
|
||||||
return (bits >> shift) | ((bits << (size - shift)) & (size == 64 ? ulong.MaxValue : (1UL << size) - 1));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -1303,7 +1303,15 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
|
|
||||||
private static void GenerateConstantCopy(CodeGenContext context, Operand dest, ulong value)
|
private static void GenerateConstantCopy(CodeGenContext context, Operand dest, ulong value)
|
||||||
{
|
{
|
||||||
if (value != 0)
|
if (value == 0)
|
||||||
|
{
|
||||||
|
context.Assembler.Mov(dest, Register(ZrRegister, dest.Type));
|
||||||
|
}
|
||||||
|
else if (CodeGenCommon.TryEncodeBitMask(dest.Type, value, out _, out _, out _))
|
||||||
|
{
|
||||||
|
context.Assembler.Orr(dest, Register(ZrRegister, dest.Type), Const(dest.Type, (long)value));
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
int hw = 0;
|
int hw = 0;
|
||||||
bool first = true;
|
bool first = true;
|
||||||
@@ -1328,10 +1336,6 @@ namespace ARMeilleure.CodeGen.Arm64
|
|||||||
value >>= 16;
|
value >>= 16;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
context.Assembler.Mov(dest, Register(ZrRegister, dest.Type));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void GenerateAtomicCas(
|
private static void GenerateAtomicCas(
|
||||||
|
@@ -48,9 +48,21 @@ namespace ARMeilleure.CodeGen
|
|||||||
/// <returns>A delegate of type <typeparamref name="T"/> pointing to the mapped function</returns>
|
/// <returns>A delegate of type <typeparamref name="T"/> pointing to the mapped function</returns>
|
||||||
public T Map<T>()
|
public T Map<T>()
|
||||||
{
|
{
|
||||||
IntPtr codePtr = JitCache.Map(this);
|
return MapWithPointer<T>(out _);
|
||||||
|
}
|
||||||
|
|
||||||
return Marshal.GetDelegateForFunctionPointer<T>(codePtr);
|
/// <summary>
|
||||||
|
/// Maps the <see cref="CompiledFunction"/> onto the <see cref="JitCache"/> and returns a delegate of type
|
||||||
|
/// <typeparamref name="T"/> pointing to the mapped function.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">Type of delegate</typeparam>
|
||||||
|
/// <param name="codePointer">Pointer to the function code in memory</param>
|
||||||
|
/// <returns>A delegate of type <typeparamref name="T"/> pointing to the mapped function</returns>
|
||||||
|
public T MapWithPointer<T>(out IntPtr codePointer)
|
||||||
|
{
|
||||||
|
codePointer = JitCache.Map(this);
|
||||||
|
|
||||||
|
return Marshal.GetDelegateForFunctionPointer<T>(codePointer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -191,7 +191,7 @@ namespace ARMeilleure.Instructions
|
|||||||
{
|
{
|
||||||
TranslatedFunction function = Context.Translator.GetOrTranslate(address, GetContext().ExecutionMode);
|
TranslatedFunction function = Context.Translator.GetOrTranslate(address, GetContext().ExecutionMode);
|
||||||
|
|
||||||
return (ulong)function.FuncPtr.ToInt64();
|
return (ulong)function.FuncPointer.ToInt64();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void InvalidateCacheLine(ulong address)
|
public static void InvalidateCacheLine(ulong address)
|
||||||
|
@@ -29,7 +29,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 = 4272; //! To be incremented manually for each change to the ARMeilleure project.
|
private const uint InternalVersion = 4328; //! 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";
|
||||||
@@ -745,9 +745,9 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
bool highCq)
|
bool highCq)
|
||||||
{
|
{
|
||||||
var cFunc = new CompiledFunction(code, unwindInfo, RelocInfo.Empty);
|
var cFunc = new CompiledFunction(code, unwindInfo, RelocInfo.Empty);
|
||||||
var gFunc = cFunc.Map<GuestFunction>();
|
var gFunc = cFunc.MapWithPointer<GuestFunction>(out IntPtr gFuncPointer);
|
||||||
|
|
||||||
return new TranslatedFunction(gFunc, callCounter, guestSize, highCq);
|
return new TranslatedFunction(gFunc, gFuncPointer, callCounter, guestSize, highCq);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateInfo(InfoEntry infoEntry)
|
private void UpdateInfo(InfoEntry infoEntry)
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
using ARMeilleure.Common;
|
using ARMeilleure.Common;
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace ARMeilleure.Translation
|
namespace ARMeilleure.Translation
|
||||||
{
|
{
|
||||||
@@ -8,18 +7,18 @@ namespace ARMeilleure.Translation
|
|||||||
{
|
{
|
||||||
private readonly GuestFunction _func; // Ensure that this delegate will not be garbage collected.
|
private readonly GuestFunction _func; // Ensure that this delegate will not be garbage collected.
|
||||||
|
|
||||||
|
public IntPtr FuncPointer { get; }
|
||||||
public Counter<uint> CallCounter { get; }
|
public Counter<uint> CallCounter { get; }
|
||||||
public ulong GuestSize { get; }
|
public ulong GuestSize { get; }
|
||||||
public bool HighCq { get; }
|
public bool HighCq { get; }
|
||||||
public IntPtr FuncPtr { get; }
|
|
||||||
|
|
||||||
public TranslatedFunction(GuestFunction func, Counter<uint> callCounter, ulong guestSize, bool highCq)
|
public TranslatedFunction(GuestFunction func, IntPtr funcPointer, Counter<uint> callCounter, ulong guestSize, bool highCq)
|
||||||
{
|
{
|
||||||
_func = func;
|
_func = func;
|
||||||
|
FuncPointer = funcPointer;
|
||||||
CallCounter = callCounter;
|
CallCounter = callCounter;
|
||||||
GuestSize = guestSize;
|
GuestSize = guestSize;
|
||||||
HighCq = highCq;
|
HighCq = highCq;
|
||||||
FuncPtr = Marshal.GetFunctionPointerForDelegate(func);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ulong Execute(State.ExecutionContext context)
|
public ulong Execute(State.ExecutionContext context)
|
||||||
|
@@ -211,7 +211,7 @@ namespace ARMeilleure.Translation
|
|||||||
|
|
||||||
if (oldFunc != func)
|
if (oldFunc != func)
|
||||||
{
|
{
|
||||||
JitCache.Unmap(func.FuncPtr);
|
JitCache.Unmap(func.FuncPointer);
|
||||||
func = oldFunc;
|
func = oldFunc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,7 +230,7 @@ namespace ARMeilleure.Translation
|
|||||||
{
|
{
|
||||||
if (FunctionTable.IsValid(guestAddress) && (Optimizations.AllowLcqInFunctionTable || func.HighCq))
|
if (FunctionTable.IsValid(guestAddress) && (Optimizations.AllowLcqInFunctionTable || func.HighCq))
|
||||||
{
|
{
|
||||||
Volatile.Write(ref FunctionTable.GetValue(guestAddress), (ulong)func.FuncPtr);
|
Volatile.Write(ref FunctionTable.GetValue(guestAddress), (ulong)func.FuncPointer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,11 +292,11 @@ namespace ARMeilleure.Translation
|
|||||||
_ptc.WriteCompiledFunction(address, funcSize, hash, highCq, compiledFunc);
|
_ptc.WriteCompiledFunction(address, funcSize, hash, highCq, compiledFunc);
|
||||||
}
|
}
|
||||||
|
|
||||||
GuestFunction func = compiledFunc.Map<GuestFunction>();
|
GuestFunction func = compiledFunc.MapWithPointer<GuestFunction>(out IntPtr funcPointer);
|
||||||
|
|
||||||
Allocators.ResetAll();
|
Allocators.ResetAll();
|
||||||
|
|
||||||
return new TranslatedFunction(func, counter, funcSize, highCq);
|
return new TranslatedFunction(func, funcPointer, counter, funcSize, highCq);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BackgroundTranslate()
|
private void BackgroundTranslate()
|
||||||
@@ -537,7 +537,7 @@ namespace ARMeilleure.Translation
|
|||||||
|
|
||||||
foreach (var func in functions)
|
foreach (var func in functions)
|
||||||
{
|
{
|
||||||
JitCache.Unmap(func.FuncPtr);
|
JitCache.Unmap(func.FuncPointer);
|
||||||
|
|
||||||
func.CallCounter?.Dispose();
|
func.CallCounter?.Dispose();
|
||||||
}
|
}
|
||||||
@@ -546,7 +546,7 @@ namespace ARMeilleure.Translation
|
|||||||
|
|
||||||
while (_oldFuncs.TryDequeue(out var kv))
|
while (_oldFuncs.TryDequeue(out var kv))
|
||||||
{
|
{
|
||||||
JitCache.Unmap(kv.Value.FuncPtr);
|
JitCache.Unmap(kv.Value.FuncPointer);
|
||||||
|
|
||||||
kv.Value.CallCounter?.Dispose();
|
kv.Value.CallCounter?.Dispose();
|
||||||
}
|
}
|
||||||
|
@@ -26,6 +26,9 @@
|
|||||||
"MenuBarToolsInstallFirmware": "Install Firmware",
|
"MenuBarToolsInstallFirmware": "Install Firmware",
|
||||||
"MenuBarFileToolsInstallFirmwareFromFile": "Install a firmware from XCI or ZIP",
|
"MenuBarFileToolsInstallFirmwareFromFile": "Install a firmware from XCI or ZIP",
|
||||||
"MenuBarFileToolsInstallFirmwareFromDirectory": "Install a firmware from a directory",
|
"MenuBarFileToolsInstallFirmwareFromDirectory": "Install a firmware from a directory",
|
||||||
|
"MenuBarToolsManageFileTypes": "Manage file types",
|
||||||
|
"MenuBarToolsInstallFileTypes": "Install file types",
|
||||||
|
"MenuBarToolsUninstallFileTypes": "Uninstall file types",
|
||||||
"MenuBarHelp": "Help",
|
"MenuBarHelp": "Help",
|
||||||
"MenuBarHelpCheckForUpdates": "Check for Updates",
|
"MenuBarHelpCheckForUpdates": "Check for Updates",
|
||||||
"MenuBarHelpAbout": "About",
|
"MenuBarHelpAbout": "About",
|
||||||
@@ -339,6 +342,10 @@
|
|||||||
"DialogFirmwareInstallEmbeddedSuccessMessage": "No installed firmware was found but Ryujinx was able to install firmware {0} from the provided game.\\nThe emulator will now start.",
|
"DialogFirmwareInstallEmbeddedSuccessMessage": "No installed firmware was found but Ryujinx was able to install firmware {0} from the provided game.\\nThe emulator will now start.",
|
||||||
"DialogFirmwareNoFirmwareInstalledMessage": "No Firmware Installed",
|
"DialogFirmwareNoFirmwareInstalledMessage": "No Firmware Installed",
|
||||||
"DialogFirmwareInstalledMessage": "Firmware {0} was installed",
|
"DialogFirmwareInstalledMessage": "Firmware {0} was installed",
|
||||||
|
"DialogInstallFileTypesSuccessMessage": "Successfully installed file types!",
|
||||||
|
"DialogInstallFileTypesErrorMessage": "Failed to install file types.",
|
||||||
|
"DialogUninstallFileTypesSuccessMessage": "Successfully uninstalled file types!",
|
||||||
|
"DialogUninstallFileTypesErrorMessage": "Failed to uninstall file types.",
|
||||||
"DialogOpenSettingsWindowLabel": "Open Settings Window",
|
"DialogOpenSettingsWindowLabel": "Open Settings Window",
|
||||||
"DialogControllerAppletTitle": "Controller Applet",
|
"DialogControllerAppletTitle": "Controller Applet",
|
||||||
"DialogMessageDialogErrorExceptionMessage": "Error displaying Message Dialog: {0}",
|
"DialogMessageDialogErrorExceptionMessage": "Error displaying Message Dialog: {0}",
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Input;
|
using Avalonia.Input;
|
||||||
|
using Avalonia.Interactivity;
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.Input;
|
using Ryujinx.Input;
|
||||||
using System;
|
using System;
|
||||||
@@ -30,6 +31,7 @@ namespace Ryujinx.Ava.Input
|
|||||||
_control.KeyDown += OnKeyPress;
|
_control.KeyDown += OnKeyPress;
|
||||||
_control.KeyUp += OnKeyRelease;
|
_control.KeyUp += OnKeyRelease;
|
||||||
_control.TextInput += Control_TextInput;
|
_control.TextInput += Control_TextInput;
|
||||||
|
_control.AddHandler(InputElement.TextInputEvent, Control_LastChanceTextInput, RoutingStrategies.Bubble);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Control_TextInput(object sender, TextInputEventArgs e)
|
private void Control_TextInput(object sender, TextInputEventArgs e)
|
||||||
@@ -37,6 +39,12 @@ namespace Ryujinx.Ava.Input
|
|||||||
TextInput?.Invoke(this, e.Text);
|
TextInput?.Invoke(this, e.Text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Control_LastChanceTextInput(object sender, TextInputEventArgs e)
|
||||||
|
{
|
||||||
|
// Swallow event
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
|
||||||
public event Action<string> OnGamepadConnected
|
public event Action<string> OnGamepadConnected
|
||||||
{
|
{
|
||||||
add { }
|
add { }
|
||||||
|
@@ -14,10 +14,8 @@ using Ryujinx.Ui.Common;
|
|||||||
using Ryujinx.Ui.Common.Configuration;
|
using Ryujinx.Ui.Common.Configuration;
|
||||||
using Ryujinx.Ui.Common.Helper;
|
using Ryujinx.Ui.Common.Helper;
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Runtime.Versioning;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Ryujinx.Ava
|
namespace Ryujinx.Ava
|
||||||
@@ -35,48 +33,6 @@ namespace Ryujinx.Ava
|
|||||||
|
|
||||||
private const uint MB_ICONWARNING = 0x30;
|
private const uint MB_ICONWARNING = 0x30;
|
||||||
|
|
||||||
[SupportedOSPlatform("linux")]
|
|
||||||
static void RegisterMimeTypes()
|
|
||||||
{
|
|
||||||
if (ReleaseInformation.IsFlatHubBuild())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
string mimeDbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".local", "share", "mime");
|
|
||||||
|
|
||||||
if (!File.Exists(Path.Combine(mimeDbPath, "packages", "Ryujinx.xml")))
|
|
||||||
{
|
|
||||||
string mimeTypesFile = Path.Combine(ReleaseInformation.GetBaseApplicationDirectory(), "mime", "Ryujinx.xml");
|
|
||||||
using Process mimeProcess = new();
|
|
||||||
|
|
||||||
mimeProcess.StartInfo.FileName = "xdg-mime";
|
|
||||||
mimeProcess.StartInfo.Arguments = $"install --novendor --mode user {mimeTypesFile}";
|
|
||||||
|
|
||||||
mimeProcess.Start();
|
|
||||||
mimeProcess.WaitForExit();
|
|
||||||
|
|
||||||
if (mimeProcess.ExitCode != 0)
|
|
||||||
{
|
|
||||||
Logger.Error?.PrintMsg(LogClass.Application, $"Unable to install mime types. Make sure xdg-utils is installed. Process exited with code: {mimeProcess.ExitCode}");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
using Process updateMimeProcess = new();
|
|
||||||
|
|
||||||
updateMimeProcess.StartInfo.FileName = "update-mime-database";
|
|
||||||
updateMimeProcess.StartInfo.Arguments = mimeDbPath;
|
|
||||||
|
|
||||||
updateMimeProcess.Start();
|
|
||||||
updateMimeProcess.WaitForExit();
|
|
||||||
|
|
||||||
if (updateMimeProcess.ExitCode != 0)
|
|
||||||
{
|
|
||||||
Logger.Error?.PrintMsg(LogClass.Application, $"Could not update local mime database. Process exited with code: {updateMimeProcess.ExitCode}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
Version = ReleaseInformation.GetVersion();
|
Version = ReleaseInformation.GetVersion();
|
||||||
@@ -139,12 +95,6 @@ namespace Ryujinx.Ava
|
|||||||
// Initialize the logger system.
|
// Initialize the logger system.
|
||||||
LoggerModule.Initialize();
|
LoggerModule.Initialize();
|
||||||
|
|
||||||
// Register mime types on linux.
|
|
||||||
if (OperatingSystem.IsLinux())
|
|
||||||
{
|
|
||||||
RegisterMimeTypes();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize Discord integration.
|
// Initialize Discord integration.
|
||||||
DiscordIntegrationModule.Initialize();
|
DiscordIntegrationModule.Initialize();
|
||||||
|
|
||||||
|
@@ -683,6 +683,11 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
get => ConsoleHelper.SetConsoleWindowStateSupported;
|
get => ConsoleHelper.SetConsoleWindowStateSupported;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool ManageFileTypesVisible
|
||||||
|
{
|
||||||
|
get => FileAssociationHelper.IsTypeAssociationSupported;
|
||||||
|
}
|
||||||
|
|
||||||
public ObservableCollection<ApplicationData> Applications
|
public ObservableCollection<ApplicationData> Applications
|
||||||
{
|
{
|
||||||
get => _applications;
|
get => _applications;
|
||||||
|
@@ -77,8 +77,7 @@
|
|||||||
</MenuItem.Icon>
|
</MenuItem.Icon>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<Separator />
|
<Separator />
|
||||||
<MenuItem Name="ChangeLanguageMenuItem" Header="{locale:Locale MenuBarOptionsChangeLanguage}">
|
<MenuItem Name="ChangeLanguageMenuItem" Header="{locale:Locale MenuBarOptionsChangeLanguage}" />
|
||||||
</MenuItem>
|
|
||||||
<Separator />
|
<Separator />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Click="OpenSettings"
|
Click="OpenSettings"
|
||||||
@@ -141,6 +140,10 @@
|
|||||||
<MenuItem Command="{ReflectionBinding InstallFirmwareFromFile}" Header="{locale:Locale MenuBarFileToolsInstallFirmwareFromFile}" />
|
<MenuItem Command="{ReflectionBinding InstallFirmwareFromFile}" Header="{locale:Locale MenuBarFileToolsInstallFirmwareFromFile}" />
|
||||||
<MenuItem Command="{ReflectionBinding InstallFirmwareFromFolder}" Header="{locale:Locale MenuBarFileToolsInstallFirmwareFromDirectory}" />
|
<MenuItem Command="{ReflectionBinding InstallFirmwareFromFolder}" Header="{locale:Locale MenuBarFileToolsInstallFirmwareFromDirectory}" />
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
<MenuItem Header="{locale:Locale MenuBarToolsManageFileTypes}" IsVisible="{Binding ManageFileTypesVisible}">
|
||||||
|
<MenuItem Header="{locale:Locale MenuBarToolsInstallFileTypes}" Click="InstallFileTypes_Click"/>
|
||||||
|
<MenuItem Header="{locale:Locale MenuBarToolsUninstallFileTypes}" Click="UninstallFileTypes_Click"/>
|
||||||
|
</MenuItem>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem VerticalAlignment="Center" Header="{locale:Locale MenuBarHelp}">
|
<MenuItem VerticalAlignment="Center" Header="{locale:Locale MenuBarHelp}">
|
||||||
<MenuItem
|
<MenuItem
|
||||||
|
@@ -3,6 +3,7 @@ using Avalonia.Controls;
|
|||||||
using Avalonia.Interactivity;
|
using Avalonia.Interactivity;
|
||||||
using LibHac.FsSystem;
|
using LibHac.FsSystem;
|
||||||
using LibHac.Ncm;
|
using LibHac.Ncm;
|
||||||
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.Ava.UI.Helpers;
|
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;
|
||||||
@@ -10,6 +11,7 @@ using Ryujinx.Common;
|
|||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using Ryujinx.HLE.HOS;
|
using Ryujinx.HLE.HOS;
|
||||||
using Ryujinx.Modules;
|
using Ryujinx.Modules;
|
||||||
|
using Ryujinx.Ui.Common.Helper;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@@ -163,6 +165,32 @@ namespace Ryujinx.Ava.UI.Views.Main
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async void InstallFileTypes_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (FileAssociationHelper.Install())
|
||||||
|
{
|
||||||
|
await ContentDialogHelper.CreateInfoDialog(LocaleManager.Instance[LocaleKeys.DialogInstallFileTypesSuccessMessage],
|
||||||
|
string.Empty, LocaleManager.Instance[LocaleKeys.InputDialogOk], string.Empty, string.Empty);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogInstallFileTypesErrorMessage]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void UninstallFileTypes_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (FileAssociationHelper.Uninstall())
|
||||||
|
{
|
||||||
|
await ContentDialogHelper.CreateInfoDialog(LocaleManager.Instance[LocaleKeys.DialogUninstallFileTypesSuccessMessage],
|
||||||
|
string.Empty, LocaleManager.Instance[LocaleKeys.InputDialogOk], string.Empty, string.Empty);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogUninstallFileTypesErrorMessage]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async void CheckForUpdates(object sender, RoutedEventArgs e)
|
public async void CheckForUpdates(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
if (Updater.CanUpdate(true))
|
if (Updater.CanUpdate(true))
|
||||||
|
@@ -349,6 +349,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (srcTexture.Info.Samples > 1 || dstTexture.Info.Samples > 1)
|
||||||
|
{
|
||||||
|
srcTexture.PropagateScale(dstTexture);
|
||||||
|
}
|
||||||
|
|
||||||
float scale = srcTexture.ScaleFactor;
|
float scale = srcTexture.ScaleFactor;
|
||||||
float dstScale = dstTexture.ScaleFactor;
|
float dstScale = dstTexture.ScaleFactor;
|
||||||
|
|
||||||
|
@@ -25,6 +25,12 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
// This method uses much more memory so we want to avoid it if possible.
|
// This method uses much more memory so we want to avoid it if possible.
|
||||||
private const int ByteComparisonSwitchThreshold = 4;
|
private const int ByteComparisonSwitchThreshold = 4;
|
||||||
|
|
||||||
|
// Tuning for blacklisting textures from scaling when their data is updated from CPU.
|
||||||
|
// Each write adds the weight, each GPU modification subtracts 1.
|
||||||
|
// Exceeding the threshold blacklists the texture.
|
||||||
|
private const int ScaledSetWeight = 10;
|
||||||
|
private const int ScaledSetThreshold = 30;
|
||||||
|
|
||||||
private const int MinLevelsForForceAnisotropy = 5;
|
private const int MinLevelsForForceAnisotropy = 5;
|
||||||
|
|
||||||
private struct TexturePoolOwner
|
private struct TexturePoolOwner
|
||||||
@@ -122,6 +128,8 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
private Target _arrayViewTarget;
|
private Target _arrayViewTarget;
|
||||||
|
|
||||||
private ITexture _flushHostTexture;
|
private ITexture _flushHostTexture;
|
||||||
|
private ITexture _setHostTexture;
|
||||||
|
private int _scaledSetScore;
|
||||||
|
|
||||||
private Texture _viewStorage;
|
private Texture _viewStorage;
|
||||||
|
|
||||||
@@ -518,6 +526,25 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Registers when a texture has had its data set after being scaled, and
|
||||||
|
/// determines if it should be blacklisted from scaling to improve performance.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>True if setting data for a scaled texture is allowed, false if the texture has been blacklisted</returns>
|
||||||
|
private bool AllowScaledSetData()
|
||||||
|
{
|
||||||
|
_scaledSetScore += ScaledSetWeight;
|
||||||
|
|
||||||
|
if (_scaledSetScore >= ScaledSetThreshold)
|
||||||
|
{
|
||||||
|
BlacklistScale();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Blacklists this texture from being scaled. Resets its scale to 1 if needed.
|
/// Blacklists this texture from being scaled. Resets its scale to 1 if needed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -554,9 +581,10 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
/// Copy the host texture to a scaled one. If a texture is not provided, create it with the given scale.
|
/// Copy the host texture to a scaled one. If a texture is not provided, create it with the given scale.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="scale">Scale factor</param>
|
/// <param name="scale">Scale factor</param>
|
||||||
|
/// <param name="copy">True if the data should be copied to the texture, false otherwise</param>
|
||||||
/// <param name="storage">Texture to use instead of creating one</param>
|
/// <param name="storage">Texture to use instead of creating one</param>
|
||||||
/// <returns>A host texture containing a scaled version of this texture</returns>
|
/// <returns>A host texture containing a scaled version of this texture</returns>
|
||||||
private ITexture GetScaledHostTexture(float scale, ITexture storage = null)
|
private ITexture GetScaledHostTexture(float scale, bool copy, ITexture storage = null)
|
||||||
{
|
{
|
||||||
if (storage == null)
|
if (storage == null)
|
||||||
{
|
{
|
||||||
@@ -564,7 +592,10 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
storage = _context.Renderer.CreateTexture(createInfo, scale);
|
storage = _context.Renderer.CreateTexture(createInfo, scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (copy)
|
||||||
|
{
|
||||||
HostTexture.CopyTo(storage, new Extents2D(0, 0, HostTexture.Width, HostTexture.Height), new Extents2D(0, 0, storage.Width, storage.Height), true);
|
HostTexture.CopyTo(storage, new Extents2D(0, 0, HostTexture.Width, HostTexture.Height), new Extents2D(0, 0, storage.Width, storage.Height), true);
|
||||||
|
}
|
||||||
|
|
||||||
return storage;
|
return storage;
|
||||||
}
|
}
|
||||||
@@ -595,7 +626,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
|
|
||||||
ScaleFactor = scale;
|
ScaleFactor = scale;
|
||||||
|
|
||||||
ITexture newStorage = GetScaledHostTexture(ScaleFactor);
|
ITexture newStorage = GetScaledHostTexture(ScaleFactor, true);
|
||||||
|
|
||||||
Logger.Debug?.Print(LogClass.Gpu, $" Copy performed: {HostTexture.Width}x{HostTexture.Height} to {newStorage.Width}x{newStorage.Height}");
|
Logger.Debug?.Print(LogClass.Gpu, $" Copy performed: {HostTexture.Width}x{HostTexture.Height} to {newStorage.Width}x{newStorage.Height}");
|
||||||
|
|
||||||
@@ -692,11 +723,6 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void SynchronizeFull()
|
public void SynchronizeFull()
|
||||||
{
|
{
|
||||||
if (_hasData)
|
|
||||||
{
|
|
||||||
BlacklistScale();
|
|
||||||
}
|
|
||||||
|
|
||||||
ReadOnlySpan<byte> data = _physicalMemory.GetSpan(Range);
|
ReadOnlySpan<byte> data = _physicalMemory.GetSpan(Range);
|
||||||
|
|
||||||
// If the host does not support ASTC compression, we need to do the decompression.
|
// If the host does not support ASTC compression, we need to do the decompression.
|
||||||
@@ -723,7 +749,19 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
|
|
||||||
SpanOrArray<byte> result = ConvertToHostCompatibleFormat(data);
|
SpanOrArray<byte> result = ConvertToHostCompatibleFormat(data);
|
||||||
|
|
||||||
|
if (ScaleFactor != 1f && AllowScaledSetData())
|
||||||
|
{
|
||||||
|
// If needed, create a texture to load from 1x scale.
|
||||||
|
ITexture texture = _setHostTexture = GetScaledHostTexture(1f, false, _setHostTexture);
|
||||||
|
|
||||||
|
texture.SetData(result);
|
||||||
|
|
||||||
|
texture.CopyTo(HostTexture, new Extents2D(0, 0, texture.Width, texture.Height), new Extents2D(0, 0, HostTexture.Width, HostTexture.Height), true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
HostTexture.SetData(result);
|
HostTexture.SetData(result);
|
||||||
|
}
|
||||||
|
|
||||||
_hasData = true;
|
_hasData = true;
|
||||||
}
|
}
|
||||||
@@ -1056,7 +1094,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
if (ScaleFactor != 1f)
|
if (ScaleFactor != 1f)
|
||||||
{
|
{
|
||||||
// If needed, create a texture to flush back to host at 1x scale.
|
// If needed, create a texture to flush back to host at 1x scale.
|
||||||
texture = _flushHostTexture = GetScaledHostTexture(1f, _flushHostTexture);
|
texture = _flushHostTexture = GetScaledHostTexture(1f, true, _flushHostTexture);
|
||||||
}
|
}
|
||||||
|
|
||||||
return texture;
|
return texture;
|
||||||
@@ -1456,6 +1494,8 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void SignalModified()
|
public void SignalModified()
|
||||||
{
|
{
|
||||||
|
_scaledSetScore = Math.Max(0, _scaledSetScore - 1);
|
||||||
|
|
||||||
if (_modifiedStale || Group.HasCopyDependencies)
|
if (_modifiedStale || Group.HasCopyDependencies)
|
||||||
{
|
{
|
||||||
_modifiedStale = false;
|
_modifiedStale = false;
|
||||||
@@ -1472,6 +1512,11 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
/// <param name="bound">True if the texture has been bound, false if it has been unbound</param>
|
/// <param name="bound">True if the texture has been bound, false if it has been unbound</param>
|
||||||
public void SignalModifying(bool bound)
|
public void SignalModifying(bool bound)
|
||||||
{
|
{
|
||||||
|
if (bound)
|
||||||
|
{
|
||||||
|
_scaledSetScore = Math.Max(0, _scaledSetScore - 1);
|
||||||
|
}
|
||||||
|
|
||||||
if (_modifiedStale || Group.HasCopyDependencies)
|
if (_modifiedStale || Group.HasCopyDependencies)
|
||||||
{
|
{
|
||||||
_modifiedStale = false;
|
_modifiedStale = false;
|
||||||
@@ -1685,6 +1730,9 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
|
|
||||||
_flushHostTexture?.Release();
|
_flushHostTexture?.Release();
|
||||||
_flushHostTexture = null;
|
_flushHostTexture = null;
|
||||||
|
|
||||||
|
_setHostTexture?.Release();
|
||||||
|
_setHostTexture = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@@ -112,7 +112,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
/// <returns>True if eligible</returns>
|
/// <returns>True if eligible</returns>
|
||||||
private static TextureScaleMode IsUpscaleCompatible(TextureInfo info, bool withUpscale)
|
private static TextureScaleMode IsUpscaleCompatible(TextureInfo info, bool withUpscale)
|
||||||
{
|
{
|
||||||
if ((info.Target == Target.Texture2D || info.Target == Target.Texture2DArray) && !info.FormatInfo.IsCompressed)
|
if ((info.Target == Target.Texture2D || info.Target == Target.Texture2DArray || info.Target == Target.Texture2DMultisample) && !info.FormatInfo.IsCompressed)
|
||||||
{
|
{
|
||||||
return UpscaleSafeMode(info) ? (withUpscale ? TextureScaleMode.Scaled : TextureScaleMode.Eligible) : TextureScaleMode.Undesired;
|
return UpscaleSafeMode(info) ? (withUpscale ? TextureScaleMode.Scaled : TextureScaleMode.Eligible) : TextureScaleMode.Undesired;
|
||||||
}
|
}
|
||||||
|
@@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
|||||||
private const ushort FileFormatVersionMajor = 1;
|
private const ushort FileFormatVersionMajor = 1;
|
||||||
private const ushort FileFormatVersionMinor = 2;
|
private const ushort FileFormatVersionMinor = 2;
|
||||||
private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
|
private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
|
||||||
private const uint CodeGenVersion = 4318;
|
private const uint CodeGenVersion = 4336;
|
||||||
|
|
||||||
private const string SharedTocFileName = "shared.toc";
|
private const string SharedTocFileName = "shared.toc";
|
||||||
private const string SharedDataFileName = "shared.data";
|
private const string SharedDataFileName = "shared.data";
|
||||||
|
@@ -261,17 +261,17 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
|
|
||||||
private static OperationResult GenerateBitfieldExtractS32(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateBitfieldExtractS32(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
return GenerateTernaryS32(context, operation, context.Delegates.BitFieldSExtract);
|
return GenerateBitfieldExtractS32(context, operation, context.Delegates.BitFieldSExtract);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OperationResult GenerateBitfieldExtractU32(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateBitfieldExtractU32(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
return GenerateTernaryS32(context, operation, context.Delegates.BitFieldUExtract);
|
return GenerateTernaryU32(context, operation, context.Delegates.BitFieldUExtract);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OperationResult GenerateBitfieldInsert(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateBitfieldInsert(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
return GenerateQuaternaryS32(context, operation, context.Delegates.BitFieldInsert);
|
return GenerateBitfieldInsert(context, operation, context.Delegates.BitFieldInsert);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OperationResult GenerateBitfieldReverse(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateBitfieldReverse(CodeGenContext context, AstOperation operation)
|
||||||
@@ -2290,22 +2290,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OperationResult GenerateTernaryS32(
|
|
||||||
CodeGenContext context,
|
|
||||||
AstOperation operation,
|
|
||||||
Func<SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction> emitS)
|
|
||||||
{
|
|
||||||
var src1 = operation.GetSource(0);
|
|
||||||
var src2 = operation.GetSource(1);
|
|
||||||
var src3 = operation.GetSource(2);
|
|
||||||
|
|
||||||
return new OperationResult(AggregateType.S32, emitS(
|
|
||||||
context.TypeS32(),
|
|
||||||
context.GetS32(src1),
|
|
||||||
context.GetS32(src2),
|
|
||||||
context.GetS32(src3)));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static OperationResult GenerateTernaryU32(
|
private static OperationResult GenerateTernaryU32(
|
||||||
CodeGenContext context,
|
CodeGenContext context,
|
||||||
AstOperation operation,
|
AstOperation operation,
|
||||||
@@ -2322,7 +2306,23 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
context.GetU32(src3)));
|
context.GetU32(src3)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OperationResult GenerateQuaternaryS32(
|
private static OperationResult GenerateBitfieldExtractS32(
|
||||||
|
CodeGenContext context,
|
||||||
|
AstOperation operation,
|
||||||
|
Func<SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction> emitS)
|
||||||
|
{
|
||||||
|
var src1 = operation.GetSource(0);
|
||||||
|
var src2 = operation.GetSource(1);
|
||||||
|
var src3 = operation.GetSource(2);
|
||||||
|
|
||||||
|
return new OperationResult(AggregateType.S32, emitS(
|
||||||
|
context.TypeS32(),
|
||||||
|
context.GetS32(src1),
|
||||||
|
context.GetU32(src2),
|
||||||
|
context.GetU32(src3)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static OperationResult GenerateBitfieldInsert(
|
||||||
CodeGenContext context,
|
CodeGenContext context,
|
||||||
AstOperation operation,
|
AstOperation operation,
|
||||||
Func<SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction> emitS)
|
Func<SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction, SpvInstruction> emitS)
|
||||||
@@ -2332,12 +2332,12 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
var src3 = operation.GetSource(2);
|
var src3 = operation.GetSource(2);
|
||||||
var src4 = operation.GetSource(3);
|
var src4 = operation.GetSource(3);
|
||||||
|
|
||||||
return new OperationResult(AggregateType.S32, emitS(
|
return new OperationResult(AggregateType.U32, emitS(
|
||||||
context.TypeS32(),
|
context.TypeU32(),
|
||||||
context.GetS32(src1),
|
context.GetU32(src1),
|
||||||
context.GetS32(src2),
|
context.GetU32(src2),
|
||||||
context.GetS32(src3),
|
context.GetU32(src3),
|
||||||
context.GetS32(src4)));
|
context.GetU32(src4)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Vulkan
|
namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
@@ -16,6 +17,10 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
private bool _hasPendingQuery;
|
private bool _hasPendingQuery;
|
||||||
private int _queryCount;
|
private int _queryCount;
|
||||||
|
|
||||||
|
private int[] _queryCountHistory = new int[3];
|
||||||
|
private int _queryCountHistoryIndex;
|
||||||
|
private int _remainingQueries;
|
||||||
|
|
||||||
public void RegisterFlush(ulong drawCount)
|
public void RegisterFlush(ulong drawCount)
|
||||||
{
|
{
|
||||||
_lastFlush = Stopwatch.GetTimestamp();
|
_lastFlush = Stopwatch.GetTimestamp();
|
||||||
@@ -27,6 +32,9 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
public bool RegisterPendingQuery()
|
public bool RegisterPendingQuery()
|
||||||
{
|
{
|
||||||
_hasPendingQuery = true;
|
_hasPendingQuery = true;
|
||||||
|
_remainingQueries--;
|
||||||
|
|
||||||
|
_queryCountHistory[_queryCountHistoryIndex]++;
|
||||||
|
|
||||||
// Interrupt render passes to flush queries, so that early results arrive sooner.
|
// Interrupt render passes to flush queries, so that early results arrive sooner.
|
||||||
if (++_queryCount == InitialQueryCountForFlush)
|
if (++_queryCount == InitialQueryCountForFlush)
|
||||||
@@ -37,6 +45,21 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int GetRemainingQueries()
|
||||||
|
{
|
||||||
|
if (_remainingQueries <= 0)
|
||||||
|
{
|
||||||
|
_remainingQueries = 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_queryCount < InitialQueryCountForFlush)
|
||||||
|
{
|
||||||
|
return Math.Min(InitialQueryCountForFlush - _queryCount, _remainingQueries);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _remainingQueries;
|
||||||
|
}
|
||||||
|
|
||||||
public bool ShouldFlushQuery()
|
public bool ShouldFlushQuery()
|
||||||
{
|
{
|
||||||
return _hasPendingQuery;
|
return _hasPendingQuery;
|
||||||
@@ -69,5 +92,14 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
return now > _lastFlush + flushTimeout;
|
return now > _lastFlush + flushTimeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Present()
|
||||||
|
{
|
||||||
|
_queryCountHistoryIndex = (_queryCountHistoryIndex + 1) % 3;
|
||||||
|
|
||||||
|
_remainingQueries = _queryCountHistory.Max() + 10;
|
||||||
|
|
||||||
|
_queryCountHistory[_queryCountHistoryIndex] = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -14,6 +14,12 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
MemoryPropertyFlags.HostCoherentBit |
|
MemoryPropertyFlags.HostCoherentBit |
|
||||||
MemoryPropertyFlags.HostCachedBit;
|
MemoryPropertyFlags.HostCachedBit;
|
||||||
|
|
||||||
|
// Some drivers don't expose a "HostCached" memory type,
|
||||||
|
// so we need those alternative flags for the allocation to succeed there.
|
||||||
|
private const MemoryPropertyFlags DefaultBufferMemoryAltFlags =
|
||||||
|
MemoryPropertyFlags.HostVisibleBit |
|
||||||
|
MemoryPropertyFlags.HostCoherentBit;
|
||||||
|
|
||||||
private const MemoryPropertyFlags DeviceLocalBufferMemoryFlags =
|
private const MemoryPropertyFlags DeviceLocalBufferMemoryFlags =
|
||||||
MemoryPropertyFlags.DeviceLocalBit;
|
MemoryPropertyFlags.DeviceLocalBit;
|
||||||
|
|
||||||
@@ -94,9 +100,21 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
gd.Api.CreateBuffer(_device, in bufferCreateInfo, null, out var buffer).ThrowOnError();
|
gd.Api.CreateBuffer(_device, in bufferCreateInfo, null, out var buffer).ThrowOnError();
|
||||||
gd.Api.GetBufferMemoryRequirements(_device, buffer, out var requirements);
|
gd.Api.GetBufferMemoryRequirements(_device, buffer, out var requirements);
|
||||||
|
|
||||||
var allocateFlags = deviceLocal ? DeviceLocalBufferMemoryFlags : DefaultBufferMemoryFlags;
|
MemoryPropertyFlags allocateFlags;
|
||||||
|
MemoryPropertyFlags allocateFlagsAlt;
|
||||||
|
|
||||||
var allocation = gd.MemoryAllocator.AllocateDeviceMemory(_physicalDevice, requirements, allocateFlags);
|
if (deviceLocal)
|
||||||
|
{
|
||||||
|
allocateFlags = DeviceLocalBufferMemoryFlags;
|
||||||
|
allocateFlagsAlt = DeviceLocalBufferMemoryFlags;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
allocateFlags = DefaultBufferMemoryFlags;
|
||||||
|
allocateFlagsAlt = DefaultBufferMemoryAltFlags;
|
||||||
|
}
|
||||||
|
|
||||||
|
var allocation = gd.MemoryAllocator.AllocateDeviceMemory(_physicalDevice, requirements, allocateFlags, allocateFlagsAlt);
|
||||||
|
|
||||||
if (allocation.Memory.Handle == 0UL)
|
if (allocation.Memory.Handle == 0UL)
|
||||||
{
|
{
|
||||||
|
@@ -23,7 +23,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
public int[] AttachmentIndices { get; }
|
public int[] AttachmentIndices { get; }
|
||||||
|
|
||||||
public int AttachmentsCount { get; }
|
public int AttachmentsCount { get; }
|
||||||
public int MaxColorAttachmentIndex { get; }
|
public int MaxColorAttachmentIndex => AttachmentIndices.Length > 0 ? AttachmentIndices[AttachmentIndices.Length - 1] : -1;
|
||||||
public bool HasDepthStencil { get; }
|
public bool HasDepthStencil { get; }
|
||||||
public int ColorAttachmentsCount => AttachmentsCount - (HasDepthStencil ? 1 : 0);
|
public int ColorAttachmentsCount => AttachmentsCount - (HasDepthStencil ? 1 : 0);
|
||||||
|
|
||||||
@@ -66,8 +66,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
AttachmentSamples = new uint[count];
|
AttachmentSamples = new uint[count];
|
||||||
AttachmentFormats = new VkFormat[count];
|
AttachmentFormats = new VkFormat[count];
|
||||||
AttachmentIndices = new int[count];
|
AttachmentIndices = new int[colorsCount];
|
||||||
MaxColorAttachmentIndex = colors.Length - 1;
|
|
||||||
|
|
||||||
uint width = uint.MaxValue;
|
uint width = uint.MaxValue;
|
||||||
uint height = uint.MaxValue;
|
uint height = uint.MaxValue;
|
||||||
|
@@ -28,10 +28,11 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
public readonly bool SupportsExtendedDynamicState;
|
public readonly bool SupportsExtendedDynamicState;
|
||||||
public readonly bool SupportsMultiView;
|
public readonly bool SupportsMultiView;
|
||||||
public readonly bool SupportsNullDescriptors;
|
public readonly bool SupportsNullDescriptors;
|
||||||
public readonly bool SupportsPreciseOcclusionQueries;
|
|
||||||
public readonly bool SupportsPushDescriptors;
|
public readonly bool SupportsPushDescriptors;
|
||||||
public readonly bool SupportsTransformFeedback;
|
public readonly bool SupportsTransformFeedback;
|
||||||
public readonly bool SupportsTransformFeedbackQueries;
|
public readonly bool SupportsTransformFeedbackQueries;
|
||||||
|
public readonly bool SupportsPreciseOcclusionQueries;
|
||||||
|
public readonly bool SupportsPipelineStatisticsQuery;
|
||||||
public readonly bool SupportsGeometryShader;
|
public readonly bool SupportsGeometryShader;
|
||||||
public readonly uint MinSubgroupSize;
|
public readonly uint MinSubgroupSize;
|
||||||
public readonly uint MaxSubgroupSize;
|
public readonly uint MaxSubgroupSize;
|
||||||
@@ -55,6 +56,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
bool supportsTransformFeedback,
|
bool supportsTransformFeedback,
|
||||||
bool supportsTransformFeedbackQueries,
|
bool supportsTransformFeedbackQueries,
|
||||||
bool supportsPreciseOcclusionQueries,
|
bool supportsPreciseOcclusionQueries,
|
||||||
|
bool supportsPipelineStatisticsQuery,
|
||||||
bool supportsGeometryShader,
|
bool supportsGeometryShader,
|
||||||
uint minSubgroupSize,
|
uint minSubgroupSize,
|
||||||
uint maxSubgroupSize,
|
uint maxSubgroupSize,
|
||||||
@@ -77,6 +79,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
SupportsTransformFeedback = supportsTransformFeedback;
|
SupportsTransformFeedback = supportsTransformFeedback;
|
||||||
SupportsTransformFeedbackQueries = supportsTransformFeedbackQueries;
|
SupportsTransformFeedbackQueries = supportsTransformFeedbackQueries;
|
||||||
SupportsPreciseOcclusionQueries = supportsPreciseOcclusionQueries;
|
SupportsPreciseOcclusionQueries = supportsPreciseOcclusionQueries;
|
||||||
|
SupportsPipelineStatisticsQuery = supportsPipelineStatisticsQuery;
|
||||||
SupportsGeometryShader = supportsGeometryShader;
|
SupportsGeometryShader = supportsGeometryShader;
|
||||||
MinSubgroupSize = minSubgroupSize;
|
MinSubgroupSize = minSubgroupSize;
|
||||||
MaxSubgroupSize = maxSubgroupSize;
|
MaxSubgroupSize = maxSubgroupSize;
|
||||||
|
@@ -27,7 +27,16 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
MemoryRequirements requirements,
|
MemoryRequirements requirements,
|
||||||
MemoryPropertyFlags flags = 0)
|
MemoryPropertyFlags flags = 0)
|
||||||
{
|
{
|
||||||
int memoryTypeIndex = FindSuitableMemoryTypeIndex(_api, physicalDevice, requirements.MemoryTypeBits, flags);
|
return AllocateDeviceMemory(physicalDevice, requirements, flags, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MemoryAllocation AllocateDeviceMemory(
|
||||||
|
PhysicalDevice physicalDevice,
|
||||||
|
MemoryRequirements requirements,
|
||||||
|
MemoryPropertyFlags flags,
|
||||||
|
MemoryPropertyFlags alternativeFlags)
|
||||||
|
{
|
||||||
|
int memoryTypeIndex = FindSuitableMemoryTypeIndex(_api, physicalDevice, requirements.MemoryTypeBits, flags, alternativeFlags);
|
||||||
if (memoryTypeIndex < 0)
|
if (memoryTypeIndex < 0)
|
||||||
{
|
{
|
||||||
return default;
|
return default;
|
||||||
@@ -56,21 +65,35 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
return newBl.Allocate(size, alignment, map);
|
return newBl.Allocate(size, alignment, map);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int FindSuitableMemoryTypeIndex(Vk api, PhysicalDevice physicalDevice, uint memoryTypeBits, MemoryPropertyFlags flags)
|
private static int FindSuitableMemoryTypeIndex(
|
||||||
|
Vk api,
|
||||||
|
PhysicalDevice physicalDevice,
|
||||||
|
uint memoryTypeBits,
|
||||||
|
MemoryPropertyFlags flags,
|
||||||
|
MemoryPropertyFlags alternativeFlags)
|
||||||
{
|
{
|
||||||
|
int bestCandidateIndex = -1;
|
||||||
|
|
||||||
api.GetPhysicalDeviceMemoryProperties(physicalDevice, out var properties);
|
api.GetPhysicalDeviceMemoryProperties(physicalDevice, out var properties);
|
||||||
|
|
||||||
for (int i = 0; i < properties.MemoryTypeCount; i++)
|
for (int i = 0; i < properties.MemoryTypeCount; i++)
|
||||||
{
|
{
|
||||||
var type = properties.MemoryTypes[i];
|
var type = properties.MemoryTypes[i];
|
||||||
|
|
||||||
if ((memoryTypeBits & (1 << i)) != 0 && type.PropertyFlags.HasFlag(flags))
|
if ((memoryTypeBits & (1 << i)) != 0)
|
||||||
|
{
|
||||||
|
if (type.PropertyFlags.HasFlag(flags))
|
||||||
{
|
{
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
else if (type.PropertyFlags.HasFlag(alternativeFlags))
|
||||||
|
{
|
||||||
|
bestCandidateIndex = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return bestCandidateIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
@@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
protected readonly Device Device;
|
protected readonly Device Device;
|
||||||
public readonly PipelineCache PipelineCache;
|
public readonly PipelineCache PipelineCache;
|
||||||
|
|
||||||
protected readonly AutoFlushCounter AutoFlush;
|
public readonly AutoFlushCounter AutoFlush;
|
||||||
|
|
||||||
protected PipelineDynamicState DynamicState;
|
protected PipelineDynamicState DynamicState;
|
||||||
private PipelineState _newState;
|
private PipelineState _newState;
|
||||||
@@ -1344,8 +1344,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
var dstAttachmentFormats = _newState.Internal.AttachmentFormats.AsSpan();
|
var dstAttachmentFormats = _newState.Internal.AttachmentFormats.AsSpan();
|
||||||
FramebufferParams.AttachmentFormats.CopyTo(dstAttachmentFormats);
|
FramebufferParams.AttachmentFormats.CopyTo(dstAttachmentFormats);
|
||||||
|
|
||||||
int maxAttachmentIndex = FramebufferParams.MaxColorAttachmentIndex + (FramebufferParams.HasDepthStencil ? 1 : 0);
|
for (int i = FramebufferParams.AttachmentFormats.Length; i < dstAttachmentFormats.Length; i++)
|
||||||
for (int i = FramebufferParams.AttachmentFormats.Length; i <= maxAttachmentIndex; i++)
|
|
||||||
{
|
{
|
||||||
dstAttachmentFormats[i] = 0;
|
dstAttachmentFormats[i] = 0;
|
||||||
}
|
}
|
||||||
@@ -1376,8 +1375,6 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
for (int i = 0; i < FramebufferParams.AttachmentsCount; i++)
|
for (int i = 0; i < FramebufferParams.AttachmentsCount; i++)
|
||||||
{
|
{
|
||||||
int bindIndex = FramebufferParams.AttachmentIndices[i];
|
|
||||||
|
|
||||||
attachmentDescs[i] = new AttachmentDescription(
|
attachmentDescs[i] = new AttachmentDescription(
|
||||||
0,
|
0,
|
||||||
FramebufferParams.AttachmentFormats[i],
|
FramebufferParams.AttachmentFormats[i],
|
||||||
|
@@ -27,14 +27,11 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
int attachmentCount = 0;
|
int attachmentCount = 0;
|
||||||
int colorCount = 0;
|
int colorCount = 0;
|
||||||
int maxColorAttachmentIndex = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < state.AttachmentEnable.Length; i++)
|
for (int i = 0; i < state.AttachmentEnable.Length; i++)
|
||||||
{
|
{
|
||||||
if (state.AttachmentEnable[i])
|
if (state.AttachmentEnable[i])
|
||||||
{
|
{
|
||||||
maxColorAttachmentIndex = i;
|
|
||||||
|
|
||||||
attachmentFormats[attachmentCount] = gd.FormatCapabilities.ConvertToVkFormat(state.AttachmentFormats[i]);
|
attachmentFormats[attachmentCount] = gd.FormatCapabilities.ConvertToVkFormat(state.AttachmentFormats[i]);
|
||||||
|
|
||||||
attachmentIndices[attachmentCount++] = i;
|
attachmentIndices[attachmentCount++] = i;
|
||||||
@@ -270,7 +267,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
// NOTE: Viewports, Scissors are dynamic.
|
// NOTE: Viewports, Scissors are dynamic.
|
||||||
|
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < Constants.MaxRenderTargets; i++)
|
||||||
{
|
{
|
||||||
var blend = state.BlendDescriptors[i];
|
var blend = state.BlendDescriptors[i];
|
||||||
|
|
||||||
@@ -293,21 +290,24 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int maxAttachmentIndex = 0;
|
int attachmentCount = 0;
|
||||||
for (int i = 0; i < 8; i++)
|
int maxColorAttachmentIndex = -1;
|
||||||
|
|
||||||
|
for (int i = 0; i < Constants.MaxRenderTargets; i++)
|
||||||
{
|
{
|
||||||
if (state.AttachmentEnable[i])
|
if (state.AttachmentEnable[i])
|
||||||
{
|
{
|
||||||
pipeline.Internal.AttachmentFormats[maxAttachmentIndex++] = gd.FormatCapabilities.ConvertToVkFormat(state.AttachmentFormats[i]);
|
pipeline.Internal.AttachmentFormats[attachmentCount++] = gd.FormatCapabilities.ConvertToVkFormat(state.AttachmentFormats[i]);
|
||||||
|
maxColorAttachmentIndex = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.DepthStencilEnable)
|
if (state.DepthStencilEnable)
|
||||||
{
|
{
|
||||||
pipeline.Internal.AttachmentFormats[maxAttachmentIndex++] = gd.FormatCapabilities.ConvertToVkFormat(state.DepthStencilFormat);
|
pipeline.Internal.AttachmentFormats[attachmentCount++] = gd.FormatCapabilities.ConvertToVkFormat(state.DepthStencilFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
pipeline.ColorBlendAttachmentStateCount = 8;
|
pipeline.ColorBlendAttachmentStateCount = (uint)(maxColorAttachmentIndex + 1);
|
||||||
pipeline.VertexAttributeDescriptionsCount = (uint)Math.Min(Constants.MaxVertexAttributes, state.VertexAttribCount);
|
pipeline.VertexAttributeDescriptionsCount = (uint)Math.Min(Constants.MaxVertexAttributes, state.VertexAttribCount);
|
||||||
|
|
||||||
return pipeline;
|
return pipeline;
|
||||||
|
@@ -14,7 +14,6 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
private CounterQueueEvent _activeConditionalRender;
|
private CounterQueueEvent _activeConditionalRender;
|
||||||
|
|
||||||
private readonly List<BufferedQuery> _pendingQueryCopies;
|
private readonly List<BufferedQuery> _pendingQueryCopies;
|
||||||
private readonly List<BufferedQuery> _pendingQueryResets;
|
|
||||||
|
|
||||||
private ulong _byteWeight;
|
private ulong _byteWeight;
|
||||||
|
|
||||||
@@ -22,7 +21,6 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
_activeQueries = new List<QueryPool>();
|
_activeQueries = new List<QueryPool>();
|
||||||
_pendingQueryCopies = new();
|
_pendingQueryCopies = new();
|
||||||
_pendingQueryResets = new List<BufferedQuery>();
|
|
||||||
|
|
||||||
CommandBuffer = (Cbs = gd.CommandBufferPool.Rent()).CommandBuffer;
|
CommandBuffer = (Cbs = gd.CommandBufferPool.Rent()).CommandBuffer;
|
||||||
}
|
}
|
||||||
@@ -34,16 +32,6 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
query.PoolCopy(Cbs);
|
query.PoolCopy(Cbs);
|
||||||
}
|
}
|
||||||
|
|
||||||
lock (_pendingQueryResets)
|
|
||||||
{
|
|
||||||
foreach (var query in _pendingQueryResets)
|
|
||||||
{
|
|
||||||
query.PoolReset(CommandBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
_pendingQueryResets.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
_pendingQueryCopies.Clear();
|
_pendingQueryCopies.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,10 +226,12 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
Gd.Api.CmdBeginQuery(CommandBuffer, queryPool, 0, Gd.Capabilities.SupportsPreciseOcclusionQueries ? QueryControlFlags.PreciseBit : 0);
|
Gd.Api.CmdBeginQuery(CommandBuffer, queryPool, 0, Gd.Capabilities.SupportsPreciseOcclusionQueries ? QueryControlFlags.PreciseBit : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Gd.ResetCounterPool();
|
||||||
|
|
||||||
Restore();
|
Restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void BeginQuery(BufferedQuery query, QueryPool pool, bool needsReset)
|
public void BeginQuery(BufferedQuery query, QueryPool pool, bool needsReset, bool fromSamplePool)
|
||||||
{
|
{
|
||||||
if (needsReset)
|
if (needsReset)
|
||||||
{
|
{
|
||||||
@@ -249,9 +239,11 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
Gd.Api.CmdResetQueryPool(CommandBuffer, pool, 0, 1);
|
Gd.Api.CmdResetQueryPool(CommandBuffer, pool, 0, 1);
|
||||||
|
|
||||||
lock (_pendingQueryResets)
|
if (fromSamplePool)
|
||||||
{
|
{
|
||||||
_pendingQueryResets.Remove(query); // Might be present on here.
|
// Try reset some additional queries in advance.
|
||||||
|
|
||||||
|
Gd.ResetFutureCounters(CommandBuffer, AutoFlush.GetRemainingQueries());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,14 +259,6 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
_activeQueries.Remove(pool);
|
_activeQueries.Remove(pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ResetQuery(BufferedQuery query)
|
|
||||||
{
|
|
||||||
lock (_pendingQueryResets)
|
|
||||||
{
|
|
||||||
_pendingQueryResets.Add(query);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CopyQueryResults(BufferedQuery query)
|
public void CopyQueryResults(BufferedQuery query)
|
||||||
{
|
{
|
||||||
_pendingQueryCopies.Add(query);
|
_pendingQueryCopies.Add(query);
|
||||||
|
@@ -18,7 +18,6 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
|||||||
private readonly PipelineFull _pipeline;
|
private readonly PipelineFull _pipeline;
|
||||||
|
|
||||||
private QueryPool _queryPool;
|
private QueryPool _queryPool;
|
||||||
private bool _isReset;
|
|
||||||
|
|
||||||
private readonly BufferHolder _buffer;
|
private readonly BufferHolder _buffer;
|
||||||
private readonly IntPtr _bufferMap;
|
private readonly IntPtr _bufferMap;
|
||||||
@@ -27,6 +26,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
|||||||
private bool _isSupported;
|
private bool _isSupported;
|
||||||
|
|
||||||
private long _defaultValue;
|
private long _defaultValue;
|
||||||
|
private int? _resetSequence;
|
||||||
|
|
||||||
public unsafe BufferedQuery(VulkanRenderer gd, Device device, PipelineFull pipeline, CounterType type, bool result32Bit)
|
public unsafe BufferedQuery(VulkanRenderer gd, Device device, PipelineFull pipeline, CounterType type, bool result32Bit)
|
||||||
{
|
{
|
||||||
@@ -67,8 +67,8 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
|||||||
return type switch
|
return type switch
|
||||||
{
|
{
|
||||||
CounterType.SamplesPassed => true,
|
CounterType.SamplesPassed => true,
|
||||||
|
CounterType.PrimitivesGenerated => gd.Capabilities.SupportsPipelineStatisticsQuery,
|
||||||
CounterType.TransformFeedbackPrimitivesWritten => gd.Capabilities.SupportsTransformFeedbackQueries,
|
CounterType.TransformFeedbackPrimitivesWritten => gd.Capabilities.SupportsTransformFeedbackQueries,
|
||||||
CounterType.PrimitivesGenerated => gd.Capabilities.SupportsGeometryShader,
|
|
||||||
_ => false
|
_ => false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -92,16 +92,17 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
|||||||
public void Reset()
|
public void Reset()
|
||||||
{
|
{
|
||||||
End(false);
|
End(false);
|
||||||
Begin();
|
Begin(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Begin()
|
public void Begin(int? resetSequence)
|
||||||
{
|
{
|
||||||
if (_isSupported)
|
if (_isSupported)
|
||||||
{
|
{
|
||||||
_pipeline.BeginQuery(this, _queryPool, !_isReset);
|
bool needsReset = resetSequence == null || _resetSequence == null || resetSequence.Value != _resetSequence.Value;
|
||||||
|
_pipeline.BeginQuery(this, _queryPool, needsReset, _type == CounterType.SamplesPassed && resetSequence != null);
|
||||||
}
|
}
|
||||||
_isReset = false;
|
_resetSequence = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe void End(bool withResult)
|
public unsafe void End(bool withResult)
|
||||||
@@ -162,13 +163,14 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PoolReset(CommandBuffer cmd)
|
public void PoolReset(CommandBuffer cmd, int resetSequence)
|
||||||
{
|
{
|
||||||
if (_isSupported)
|
if (_isSupported)
|
||||||
{
|
{
|
||||||
_api.CmdResetQueryPool(cmd, _queryPool, 0, 1);
|
_api.CmdResetQueryPool(cmd, _queryPool, 0, 1);
|
||||||
}
|
}
|
||||||
_isReset = true;
|
|
||||||
|
_resetSequence = resetSequence;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PoolCopy(CommandBufferScoped cbs)
|
public void PoolCopy(CommandBufferScoped cbs)
|
||||||
|
@@ -3,6 +3,7 @@ using Silk.NET.Vulkan;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Vulkan.Queries
|
namespace Ryujinx.Graphics.Vulkan.Queries
|
||||||
{
|
{
|
||||||
@@ -32,6 +33,8 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
|||||||
|
|
||||||
private Thread _consumerThread;
|
private Thread _consumerThread;
|
||||||
|
|
||||||
|
public int ResetSequence { get; private set; }
|
||||||
|
|
||||||
internal CounterQueue(VulkanRenderer gd, Device device, PipelineFull pipeline, CounterType type)
|
internal CounterQueue(VulkanRenderer gd, Device device, PipelineFull pipeline, CounterType type)
|
||||||
{
|
{
|
||||||
_gd = gd;
|
_gd = gd;
|
||||||
@@ -53,6 +56,24 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
|||||||
_consumerThread.Start();
|
_consumerThread.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ResetCounterPool()
|
||||||
|
{
|
||||||
|
ResetSequence++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ResetFutureCounters(CommandBuffer cmd, int count)
|
||||||
|
{
|
||||||
|
// Pre-emptively reset queries to avoid render pass splitting.
|
||||||
|
lock (_queryPool)
|
||||||
|
{
|
||||||
|
count = Math.Min(count, _queryPool.Count);
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
_queryPool.ElementAt(i).PoolReset(cmd, ResetSequence);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void EventConsumer()
|
private void EventConsumer()
|
||||||
{
|
{
|
||||||
while (!Disposed)
|
while (!Disposed)
|
||||||
@@ -106,7 +127,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
|||||||
{
|
{
|
||||||
lock (_lock)
|
lock (_lock)
|
||||||
{
|
{
|
||||||
_pipeline.ResetQuery(query);
|
// The query will be reset when it dequeues.
|
||||||
_queryPool.Enqueue(query);
|
_queryPool.Enqueue(query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -34,7 +34,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
|||||||
|
|
||||||
DrawIndex = drawIndex;
|
DrawIndex = drawIndex;
|
||||||
|
|
||||||
_counter.Begin();
|
_counter.Begin(_queue.ResetSequence);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Auto<DisposableBuffer> GetBuffer()
|
public Auto<DisposableBuffer> GetBuffer()
|
||||||
|
@@ -24,6 +24,19 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ResetCounterPool()
|
||||||
|
{
|
||||||
|
foreach (var queue in _counterQueues)
|
||||||
|
{
|
||||||
|
queue.ResetCounterPool();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ResetFutureCounters(CommandBuffer cmd, int count)
|
||||||
|
{
|
||||||
|
_counterQueues[(int)CounterType.SamplesPassed].ResetFutureCounters(cmd, count);
|
||||||
|
}
|
||||||
|
|
||||||
public CounterQueueEvent QueueReport(CounterType type, EventHandler<ulong> resultHandler, bool hostReserved)
|
public CounterQueueEvent QueueReport(CounterType type, EventHandler<ulong> resultHandler, bool hostReserved)
|
||||||
{
|
{
|
||||||
return _counterQueues[(int)type].QueueReport(resultHandler, _pipeline.DrawCount, hostReserved);
|
return _counterQueues[(int)type].QueueReport(resultHandler, _pipeline.DrawCount, hostReserved);
|
||||||
|
@@ -9,6 +9,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
Intel,
|
Intel,
|
||||||
Nvidia,
|
Nvidia,
|
||||||
ARM,
|
ARM,
|
||||||
|
Broadcom,
|
||||||
Qualcomm,
|
Qualcomm,
|
||||||
Apple,
|
Apple,
|
||||||
Unknown
|
Unknown
|
||||||
@@ -28,6 +29,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
0x106B => Vendor.Apple,
|
0x106B => Vendor.Apple,
|
||||||
0x10DE => Vendor.Nvidia,
|
0x10DE => Vendor.Nvidia,
|
||||||
0x13B5 => Vendor.ARM,
|
0x13B5 => Vendor.ARM,
|
||||||
|
0x14E4 => Vendor.Broadcom,
|
||||||
0x8086 => Vendor.Intel,
|
0x8086 => Vendor.Intel,
|
||||||
0x5143 => Vendor.Qualcomm,
|
0x5143 => Vendor.Qualcomm,
|
||||||
_ => Vendor.Unknown
|
_ => Vendor.Unknown
|
||||||
@@ -43,6 +45,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
0x106B => "Apple",
|
0x106B => "Apple",
|
||||||
0x10DE => "NVIDIA",
|
0x10DE => "NVIDIA",
|
||||||
0x13B5 => "ARM",
|
0x13B5 => "ARM",
|
||||||
|
0x14E4 => "Broadcom",
|
||||||
0x1AE0 => "Google",
|
0x1AE0 => "Google",
|
||||||
0x5143 => "Qualcomm",
|
0x5143 => "Qualcomm",
|
||||||
0x8086 => "Intel",
|
0x8086 => "Intel",
|
||||||
|
@@ -162,7 +162,6 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
if (messageSeverity.HasFlag(DebugUtilsMessageSeverityFlagsEXT.ErrorBitExt))
|
if (messageSeverity.HasFlag(DebugUtilsMessageSeverityFlagsEXT.ErrorBitExt))
|
||||||
{
|
{
|
||||||
Logger.Error?.Print(LogClass.Gpu, msg);
|
Logger.Error?.Print(LogClass.Gpu, msg);
|
||||||
//throw new Exception(msg);
|
|
||||||
}
|
}
|
||||||
else if (messageSeverity.HasFlag(DebugUtilsMessageSeverityFlagsEXT.WarningBitExt))
|
else if (messageSeverity.HasFlag(DebugUtilsMessageSeverityFlagsEXT.WarningBitExt))
|
||||||
{
|
{
|
||||||
@@ -379,14 +378,34 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
SType = StructureType.PhysicalDeviceFeatures2
|
SType = StructureType.PhysicalDeviceFeatures2
|
||||||
};
|
};
|
||||||
|
|
||||||
PhysicalDeviceCustomBorderColorFeaturesEXT featuresCustomBorderColorSupported = new PhysicalDeviceCustomBorderColorFeaturesEXT()
|
PhysicalDeviceVulkan11Features supportedFeaturesVk11 = new PhysicalDeviceVulkan11Features()
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceCustomBorderColorFeaturesExt
|
SType = StructureType.PhysicalDeviceVulkan11Features,
|
||||||
|
PNext = features2.PNext
|
||||||
|
};
|
||||||
|
|
||||||
|
features2.PNext = &supportedFeaturesVk11;
|
||||||
|
|
||||||
|
PhysicalDeviceCustomBorderColorFeaturesEXT supportedFeaturesCustomBorderColor = new PhysicalDeviceCustomBorderColorFeaturesEXT()
|
||||||
|
{
|
||||||
|
SType = StructureType.PhysicalDeviceCustomBorderColorFeaturesExt,
|
||||||
|
PNext = features2.PNext
|
||||||
};
|
};
|
||||||
|
|
||||||
if (supportedExtensions.Contains("VK_EXT_custom_border_color"))
|
if (supportedExtensions.Contains("VK_EXT_custom_border_color"))
|
||||||
{
|
{
|
||||||
features2.PNext = &featuresCustomBorderColorSupported;
|
features2.PNext = &supportedFeaturesCustomBorderColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
PhysicalDeviceTransformFeedbackFeaturesEXT supportedFeaturesTransformFeedback = new PhysicalDeviceTransformFeedbackFeaturesEXT()
|
||||||
|
{
|
||||||
|
SType = StructureType.PhysicalDeviceTransformFeedbackFeaturesExt,
|
||||||
|
PNext = features2.PNext
|
||||||
|
};
|
||||||
|
|
||||||
|
if (supportedExtensions.Contains(ExtTransformFeedback.ExtensionName))
|
||||||
|
{
|
||||||
|
features2.PNext = &supportedFeaturesTransformFeedback;
|
||||||
}
|
}
|
||||||
|
|
||||||
PhysicalDeviceRobustness2FeaturesEXT supportedFeaturesRobustness2 = new PhysicalDeviceRobustness2FeaturesEXT()
|
PhysicalDeviceRobustness2FeaturesEXT supportedFeaturesRobustness2 = new PhysicalDeviceRobustness2FeaturesEXT()
|
||||||
@@ -408,42 +427,49 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
var features = new PhysicalDeviceFeatures()
|
var features = new PhysicalDeviceFeatures()
|
||||||
{
|
{
|
||||||
DepthBiasClamp = true,
|
DepthBiasClamp = true,
|
||||||
DepthClamp = true,
|
DepthClamp = supportedFeatures.DepthClamp,
|
||||||
DualSrcBlend = true,
|
DualSrcBlend = supportedFeatures.DualSrcBlend,
|
||||||
FragmentStoresAndAtomics = true,
|
FragmentStoresAndAtomics = true,
|
||||||
GeometryShader = supportedFeatures.GeometryShader,
|
GeometryShader = supportedFeatures.GeometryShader,
|
||||||
ImageCubeArray = true,
|
ImageCubeArray = true,
|
||||||
IndependentBlend = true,
|
IndependentBlend = true,
|
||||||
LogicOp = supportedFeatures.LogicOp,
|
LogicOp = supportedFeatures.LogicOp,
|
||||||
MultiViewport = true,
|
|
||||||
OcclusionQueryPrecise = supportedFeatures.OcclusionQueryPrecise,
|
OcclusionQueryPrecise = supportedFeatures.OcclusionQueryPrecise,
|
||||||
|
MultiViewport = supportedFeatures.MultiViewport,
|
||||||
PipelineStatisticsQuery = supportedFeatures.PipelineStatisticsQuery,
|
PipelineStatisticsQuery = supportedFeatures.PipelineStatisticsQuery,
|
||||||
SamplerAnisotropy = true,
|
SamplerAnisotropy = true,
|
||||||
ShaderClipDistance = true,
|
ShaderClipDistance = true,
|
||||||
ShaderFloat64 = supportedFeatures.ShaderFloat64,
|
ShaderFloat64 = supportedFeatures.ShaderFloat64,
|
||||||
ShaderImageGatherExtended = true,
|
ShaderImageGatherExtended = supportedFeatures.ShaderImageGatherExtended,
|
||||||
ShaderStorageImageMultisample = supportedFeatures.ShaderStorageImageMultisample,
|
ShaderStorageImageMultisample = supportedFeatures.ShaderStorageImageMultisample,
|
||||||
// ShaderStorageImageReadWithoutFormat = true,
|
// ShaderStorageImageReadWithoutFormat = true,
|
||||||
// ShaderStorageImageWriteWithoutFormat = true,
|
// ShaderStorageImageWriteWithoutFormat = true,
|
||||||
TessellationShader = true,
|
TessellationShader = supportedFeatures.TessellationShader,
|
||||||
VertexPipelineStoresAndAtomics = true,
|
VertexPipelineStoresAndAtomics = true,
|
||||||
RobustBufferAccess = useRobustBufferAccess
|
RobustBufferAccess = useRobustBufferAccess
|
||||||
};
|
};
|
||||||
|
|
||||||
void* pExtendedFeatures = null;
|
void* pExtendedFeatures = null;
|
||||||
|
|
||||||
var featuresTransformFeedback = new PhysicalDeviceTransformFeedbackFeaturesEXT()
|
PhysicalDeviceTransformFeedbackFeaturesEXT featuresTransformFeedback;
|
||||||
|
|
||||||
|
if (supportedExtensions.Contains(ExtTransformFeedback.ExtensionName))
|
||||||
|
{
|
||||||
|
featuresTransformFeedback = new PhysicalDeviceTransformFeedbackFeaturesEXT()
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceTransformFeedbackFeaturesExt,
|
SType = StructureType.PhysicalDeviceTransformFeedbackFeaturesExt,
|
||||||
PNext = pExtendedFeatures,
|
PNext = pExtendedFeatures,
|
||||||
TransformFeedback = true
|
TransformFeedback = supportedFeaturesTransformFeedback.TransformFeedback
|
||||||
};
|
};
|
||||||
|
|
||||||
pExtendedFeatures = &featuresTransformFeedback;
|
pExtendedFeatures = &featuresTransformFeedback;
|
||||||
|
}
|
||||||
|
|
||||||
|
PhysicalDeviceRobustness2FeaturesEXT featuresRobustness2;
|
||||||
|
|
||||||
if (supportedExtensions.Contains("VK_EXT_robustness2"))
|
if (supportedExtensions.Contains("VK_EXT_robustness2"))
|
||||||
{
|
{
|
||||||
var featuresRobustness2 = new PhysicalDeviceRobustness2FeaturesEXT()
|
featuresRobustness2 = new PhysicalDeviceRobustness2FeaturesEXT()
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceRobustness2FeaturesExt,
|
SType = StructureType.PhysicalDeviceRobustness2FeaturesExt,
|
||||||
PNext = pExtendedFeatures,
|
PNext = pExtendedFeatures,
|
||||||
@@ -466,7 +492,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceVulkan11Features,
|
SType = StructureType.PhysicalDeviceVulkan11Features,
|
||||||
PNext = pExtendedFeatures,
|
PNext = pExtendedFeatures,
|
||||||
ShaderDrawParameters = true
|
ShaderDrawParameters = supportedFeaturesVk11.ShaderDrawParameters
|
||||||
};
|
};
|
||||||
|
|
||||||
pExtendedFeatures = &featuresVk11;
|
pExtendedFeatures = &featuresVk11;
|
||||||
@@ -527,8 +553,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
PhysicalDeviceCustomBorderColorFeaturesEXT featuresCustomBorderColor;
|
PhysicalDeviceCustomBorderColorFeaturesEXT featuresCustomBorderColor;
|
||||||
|
|
||||||
if (supportedExtensions.Contains("VK_EXT_custom_border_color") &&
|
if (supportedExtensions.Contains("VK_EXT_custom_border_color") &&
|
||||||
featuresCustomBorderColorSupported.CustomBorderColors &&
|
supportedFeaturesCustomBorderColor.CustomBorderColors &&
|
||||||
featuresCustomBorderColorSupported.CustomBorderColorWithoutFormat)
|
supportedFeaturesCustomBorderColor.CustomBorderColorWithoutFormat)
|
||||||
{
|
{
|
||||||
featuresCustomBorderColor = new PhysicalDeviceCustomBorderColorFeaturesEXT()
|
featuresCustomBorderColor = new PhysicalDeviceCustomBorderColorFeaturesEXT()
|
||||||
{
|
{
|
||||||
|
@@ -271,6 +271,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
supportsTransformFeedback,
|
supportsTransformFeedback,
|
||||||
propertiesTransformFeedback.TransformFeedbackQueries,
|
propertiesTransformFeedback.TransformFeedbackQueries,
|
||||||
features2.Features.OcclusionQueryPrecise,
|
features2.Features.OcclusionQueryPrecise,
|
||||||
|
supportedFeatures.PipelineStatisticsQuery,
|
||||||
supportedFeatures.GeometryShader,
|
supportedFeatures.GeometryShader,
|
||||||
propertiesSubgroupSizeControl.MinSubgroupSize,
|
propertiesSubgroupSizeControl.MinSubgroupSize,
|
||||||
propertiesSubgroupSizeControl.MaxSubgroupSize,
|
propertiesSubgroupSizeControl.MaxSubgroupSize,
|
||||||
@@ -589,9 +590,13 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
Vendor = VendorUtils.FromId(properties.VendorID);
|
Vendor = VendorUtils.FromId(properties.VendorID);
|
||||||
|
|
||||||
IsAmdWindows = Vendor == Vendor.Amd && RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
IsAmdWindows = Vendor == Vendor.Amd && OperatingSystem.IsWindows();
|
||||||
IsIntelWindows = Vendor == Vendor.Intel && RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
IsIntelWindows = Vendor == Vendor.Intel && OperatingSystem.IsWindows();
|
||||||
IsTBDR = IsMoltenVk || Vendor == Vendor.Qualcomm || Vendor == Vendor.ARM || Vendor == Vendor.ImgTec;
|
IsTBDR = IsMoltenVk ||
|
||||||
|
Vendor == Vendor.Qualcomm ||
|
||||||
|
Vendor == Vendor.ARM ||
|
||||||
|
Vendor == Vendor.Broadcom ||
|
||||||
|
Vendor == Vendor.ImgTec;
|
||||||
|
|
||||||
GpuVendor = vendorName;
|
GpuVendor = vendorName;
|
||||||
GpuRenderer = Marshal.PtrToStringAnsi((IntPtr)properties.DeviceName);
|
GpuRenderer = Marshal.PtrToStringAnsi((IntPtr)properties.DeviceName);
|
||||||
@@ -679,6 +684,16 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
_counters.Update();
|
_counters.Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ResetCounterPool()
|
||||||
|
{
|
||||||
|
_counters.ResetCounterPool();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ResetFutureCounters(CommandBuffer cmd, int count)
|
||||||
|
{
|
||||||
|
_counters?.ResetFutureCounters(cmd, count);
|
||||||
|
}
|
||||||
|
|
||||||
public void BackgroundContextAction(Action action, bool alwaysBackground = false)
|
public void BackgroundContextAction(Action action, bool alwaysBackground = false)
|
||||||
{
|
{
|
||||||
action();
|
action();
|
||||||
|
@@ -120,7 +120,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
ImageSharingMode = SharingMode.Exclusive,
|
ImageSharingMode = SharingMode.Exclusive,
|
||||||
ImageArrayLayers = 1,
|
ImageArrayLayers = 1,
|
||||||
PreTransform = capabilities.CurrentTransform,
|
PreTransform = capabilities.CurrentTransform,
|
||||||
CompositeAlpha = CompositeAlphaFlagsKHR.OpaqueBitKhr,
|
CompositeAlpha = ChooseCompositeAlpha(capabilities.SupportedCompositeAlpha),
|
||||||
PresentMode = ChooseSwapPresentMode(presentModes, _vsyncEnabled),
|
PresentMode = ChooseSwapPresentMode(presentModes, _vsyncEnabled),
|
||||||
Clipped = true
|
Clipped = true
|
||||||
};
|
};
|
||||||
@@ -188,6 +188,22 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
return availableFormats[0];
|
return availableFormats[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static CompositeAlphaFlagsKHR ChooseCompositeAlpha(CompositeAlphaFlagsKHR supportedFlags)
|
||||||
|
{
|
||||||
|
if (supportedFlags.HasFlag(CompositeAlphaFlagsKHR.OpaqueBitKhr))
|
||||||
|
{
|
||||||
|
return CompositeAlphaFlagsKHR.OpaqueBitKhr;
|
||||||
|
}
|
||||||
|
else if (supportedFlags.HasFlag(CompositeAlphaFlagsKHR.PreMultipliedBitKhr))
|
||||||
|
{
|
||||||
|
return CompositeAlphaFlagsKHR.PreMultipliedBitKhr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return CompositeAlphaFlagsKHR.InheritBitKhr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static PresentModeKHR ChooseSwapPresentMode(PresentModeKHR[] availablePresentModes, bool vsyncEnabled)
|
private static PresentModeKHR ChooseSwapPresentMode(PresentModeKHR[] availablePresentModes, bool vsyncEnabled)
|
||||||
{
|
{
|
||||||
if (!vsyncEnabled && availablePresentModes.Contains(PresentModeKHR.ImmediateKhr))
|
if (!vsyncEnabled && availablePresentModes.Contains(PresentModeKHR.ImmediateKhr))
|
||||||
@@ -198,10 +214,6 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
return PresentModeKHR.MailboxKhr;
|
return PresentModeKHR.MailboxKhr;
|
||||||
}
|
}
|
||||||
else if (availablePresentModes.Contains(PresentModeKHR.FifoKhr))
|
|
||||||
{
|
|
||||||
return PresentModeKHR.FifoKhr;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return PresentModeKHR.FifoKhr;
|
return PresentModeKHR.FifoKhr;
|
||||||
@@ -225,6 +237,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public unsafe override void Present(ITexture texture, ImageCrop crop, Action swapBuffersCallback)
|
public unsafe override void Present(ITexture texture, ImageCrop crop, Action swapBuffersCallback)
|
||||||
{
|
{
|
||||||
|
_gd.PipelineInternal.AutoFlush.Present();
|
||||||
|
|
||||||
uint nextImage = 0;
|
uint nextImage = 0;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
|
46
Ryujinx.Tests/Cpu/Arm64CodeGenCommonTests.cs
Normal file
46
Ryujinx.Tests/Cpu/Arm64CodeGenCommonTests.cs
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
using ARMeilleure.CodeGen.Arm64;
|
||||||
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
namespace Ryujinx.Tests.Cpu
|
||||||
|
{
|
||||||
|
public class Arm64CodeGenCommonTests
|
||||||
|
{
|
||||||
|
public struct TestCase
|
||||||
|
{
|
||||||
|
public ulong Value;
|
||||||
|
public bool Valid;
|
||||||
|
public int ImmN;
|
||||||
|
public int ImmS;
|
||||||
|
public int ImmR;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly TestCase[] TestCases =
|
||||||
|
{
|
||||||
|
new() { Value = 0, Valid = false, ImmN = 0, ImmS = 0, ImmR = 0 },
|
||||||
|
new() { Value = 0x970977f35f848714, Valid = false, ImmN = 0, ImmS = 0, ImmR = 0 },
|
||||||
|
new() { Value = 0xffffffffffffffff, Valid = false, ImmN = 0, ImmS = 0, ImmR = 0 },
|
||||||
|
new() { Value = 0x5555555555555555, Valid = true, ImmN = 0, ImmS = 0x3c, ImmR = 0 },
|
||||||
|
new() { Value = 0xaaaaaaaaaaaaaaaa, Valid = true, ImmN = 0, ImmS = 0x3c, ImmR = 1 },
|
||||||
|
new() { Value = 0x6666666666666666, Valid = true, ImmN = 0, ImmS = 0x39, ImmR = 3 },
|
||||||
|
new() { Value = 0x1c1c1c1c1c1c1c1c, Valid = true, ImmN = 0, ImmS = 0x32, ImmR = 6 },
|
||||||
|
new() { Value = 0x0f0f0f0f0f0f0f0f, Valid = true, ImmN = 0, ImmS = 0x33, ImmR = 0 },
|
||||||
|
new() { Value = 0xf1f1f1f1f1f1f1f1, Valid = true, ImmN = 0, ImmS = 0x34, ImmR = 4 },
|
||||||
|
new() { Value = 0xe7e7e7e7e7e7e7e7, Valid = true, ImmN = 0, ImmS = 0x35, ImmR = 3 },
|
||||||
|
new() { Value = 0xc001c001c001c001, Valid = true, ImmN = 0, ImmS = 0x22, ImmR = 2 },
|
||||||
|
new() { Value = 0x0000038000000380, Valid = true, ImmN = 0, ImmS = 0x02, ImmR = 25 },
|
||||||
|
new() { Value = 0xffff8fffffff8fff, Valid = true, ImmN = 0, ImmS = 0x1c, ImmR = 17 },
|
||||||
|
new() { Value = 0x000000000ffff800, Valid = true, ImmN = 1, ImmS = 0x10, ImmR = 53 },
|
||||||
|
};
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void BitImmTests([ValueSource(nameof(TestCases))] TestCase test)
|
||||||
|
{
|
||||||
|
bool valid = CodeGenCommon.TryEncodeBitMask(test.Value, out int immN, out int immS, out int immR);
|
||||||
|
|
||||||
|
Assert.That(valid, Is.EqualTo(test.Valid));
|
||||||
|
Assert.That(immN, Is.EqualTo(test.ImmN));
|
||||||
|
Assert.That(immS, Is.EqualTo(test.ImmS));
|
||||||
|
Assert.That(immR, Is.EqualTo(test.ImmR));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -340,7 +340,7 @@ namespace Ryujinx.Ui.Common.Configuration
|
|||||||
{
|
{
|
||||||
configurationFileFormat = JsonHelper.DeserializeFromFile<ConfigurationFileFormat>(path);
|
configurationFileFormat = JsonHelper.DeserializeFromFile<ConfigurationFileFormat>(path);
|
||||||
|
|
||||||
return true;
|
return configurationFileFormat.Version != 0;
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
|
198
Ryujinx.Ui.Common/Helper/FileAssociationHelper.cs
Normal file
198
Ryujinx.Ui.Common/Helper/FileAssociationHelper.cs
Normal file
@@ -0,0 +1,198 @@
|
|||||||
|
using Microsoft.Win32;
|
||||||
|
using Ryujinx.Common;
|
||||||
|
using Ryujinx.Common.Logging;
|
||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Runtime.Versioning;
|
||||||
|
|
||||||
|
namespace Ryujinx.Ui.Common.Helper
|
||||||
|
{
|
||||||
|
public static partial class FileAssociationHelper
|
||||||
|
{
|
||||||
|
private static string[] _fileExtensions = new string[] { ".nca", ".nro", ".nso", ".nsp", ".xci" };
|
||||||
|
|
||||||
|
[SupportedOSPlatform("linux")]
|
||||||
|
private static string _mimeDbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".local", "share", "mime");
|
||||||
|
|
||||||
|
private const int SHCNE_ASSOCCHANGED = 0x8000000;
|
||||||
|
private const int SHCNF_FLUSH = 0x1000;
|
||||||
|
|
||||||
|
[LibraryImport("shell32.dll", SetLastError = true)]
|
||||||
|
public static partial void SHChangeNotify(uint wEventId, uint uFlags, IntPtr dwItem1, IntPtr dwItem2);
|
||||||
|
|
||||||
|
public static bool IsTypeAssociationSupported => (OperatingSystem.IsLinux() || OperatingSystem.IsWindows()) && !ReleaseInformation.IsFlatHubBuild();
|
||||||
|
|
||||||
|
[SupportedOSPlatform("linux")]
|
||||||
|
private static bool AreMimeTypesRegisteredLinux() => File.Exists(Path.Combine(_mimeDbPath, "packages", "Ryujinx.xml"));
|
||||||
|
|
||||||
|
[SupportedOSPlatform("linux")]
|
||||||
|
private static bool InstallLinuxMimeTypes(bool uninstall = false)
|
||||||
|
{
|
||||||
|
string installKeyword = uninstall ? "uninstall" : "install";
|
||||||
|
|
||||||
|
if (!AreMimeTypesRegisteredLinux())
|
||||||
|
{
|
||||||
|
string mimeTypesFile = Path.Combine(ReleaseInformation.GetBaseApplicationDirectory(), "mime", "Ryujinx.xml");
|
||||||
|
string additionalArgs = !uninstall ? "--novendor" : "";
|
||||||
|
|
||||||
|
using Process mimeProcess = new();
|
||||||
|
|
||||||
|
mimeProcess.StartInfo.FileName = "xdg-mime";
|
||||||
|
mimeProcess.StartInfo.Arguments = $"{installKeyword} {additionalArgs} --mode user {mimeTypesFile}";
|
||||||
|
|
||||||
|
mimeProcess.Start();
|
||||||
|
mimeProcess.WaitForExit();
|
||||||
|
|
||||||
|
if (mimeProcess.ExitCode != 0)
|
||||||
|
{
|
||||||
|
Logger.Error?.PrintMsg(LogClass.Application, $"Unable to {installKeyword} mime types. Make sure xdg-utils is installed. Process exited with code: {mimeProcess.ExitCode}");
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
using Process updateMimeProcess = new();
|
||||||
|
|
||||||
|
updateMimeProcess.StartInfo.FileName = "update-mime-database";
|
||||||
|
updateMimeProcess.StartInfo.Arguments = _mimeDbPath;
|
||||||
|
|
||||||
|
updateMimeProcess.Start();
|
||||||
|
updateMimeProcess.WaitForExit();
|
||||||
|
|
||||||
|
if (updateMimeProcess.ExitCode != 0)
|
||||||
|
{
|
||||||
|
Logger.Error?.PrintMsg(LogClass.Application, $"Could not update local mime database. Process exited with code: {updateMimeProcess.ExitCode}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
[SupportedOSPlatform("windows")]
|
||||||
|
private static bool AreMimeTypesRegisteredWindows()
|
||||||
|
{
|
||||||
|
static bool CheckRegistering(string ext)
|
||||||
|
{
|
||||||
|
RegistryKey key = Registry.CurrentUser.OpenSubKey(@$"Software\Classes\{ext}");
|
||||||
|
|
||||||
|
if (key is null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
key.OpenSubKey(@"shell\open\command");
|
||||||
|
|
||||||
|
string keyValue = (string)key.GetValue("");
|
||||||
|
|
||||||
|
return keyValue is not null && (keyValue.Contains("Ryujinx") || keyValue.Contains(AppDomain.CurrentDomain.FriendlyName));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool registered = false;
|
||||||
|
|
||||||
|
foreach (string ext in _fileExtensions)
|
||||||
|
{
|
||||||
|
registered |= CheckRegistering(ext);
|
||||||
|
}
|
||||||
|
|
||||||
|
return registered;
|
||||||
|
}
|
||||||
|
|
||||||
|
[SupportedOSPlatform("windows")]
|
||||||
|
private static bool InstallWindowsMimeTypes(bool uninstall = false)
|
||||||
|
{
|
||||||
|
static bool RegisterExtension(string ext, bool uninstall = false)
|
||||||
|
{
|
||||||
|
string keyString = @$"Software\Classes\{ext}";
|
||||||
|
|
||||||
|
if (uninstall)
|
||||||
|
{
|
||||||
|
if (!AreMimeTypesRegisteredWindows())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Registry.CurrentUser.DeleteSubKeyTree(keyString);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RegistryKey key = Registry.CurrentUser.CreateSubKey(keyString);
|
||||||
|
if (key is null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
key.CreateSubKey(@"shell\open\command");
|
||||||
|
|
||||||
|
key.SetValue("", $"\"{Environment.ProcessPath}\" \"%1\"");
|
||||||
|
key.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notify Explorer the file association has been changed.
|
||||||
|
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_FLUSH, IntPtr.Zero, IntPtr.Zero);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool registered = false;
|
||||||
|
|
||||||
|
foreach (string ext in _fileExtensions)
|
||||||
|
{
|
||||||
|
registered |= RegisterExtension(ext, uninstall);
|
||||||
|
}
|
||||||
|
|
||||||
|
return registered;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool AreMimeTypesRegistered()
|
||||||
|
{
|
||||||
|
if (OperatingSystem.IsLinux())
|
||||||
|
{
|
||||||
|
return AreMimeTypesRegisteredLinux();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OperatingSystem.IsWindows())
|
||||||
|
{
|
||||||
|
return AreMimeTypesRegisteredWindows();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Add macOS support.
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool Install()
|
||||||
|
{
|
||||||
|
if (OperatingSystem.IsLinux())
|
||||||
|
{
|
||||||
|
return InstallLinuxMimeTypes();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OperatingSystem.IsWindows())
|
||||||
|
{
|
||||||
|
return InstallWindowsMimeTypes();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Add macOS support.
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool Uninstall()
|
||||||
|
{
|
||||||
|
if (OperatingSystem.IsLinux())
|
||||||
|
{
|
||||||
|
return InstallLinuxMimeTypes(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OperatingSystem.IsWindows())
|
||||||
|
{
|
||||||
|
return InstallWindowsMimeTypes(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Add macOS support.
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -18,7 +18,6 @@ using System.Collections.Generic;
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Runtime.Versioning;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Ryujinx
|
namespace Ryujinx
|
||||||
@@ -73,48 +72,6 @@ namespace Ryujinx
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[SupportedOSPlatform("linux")]
|
|
||||||
static void RegisterMimeTypes()
|
|
||||||
{
|
|
||||||
if (ReleaseInformation.IsFlatHubBuild())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
string mimeDbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".local", "share", "mime");
|
|
||||||
|
|
||||||
if (!File.Exists(Path.Combine(mimeDbPath, "packages", "Ryujinx.xml")))
|
|
||||||
{
|
|
||||||
string mimeTypesFile = Path.Combine(ReleaseInformation.GetBaseApplicationDirectory(), "mime", "Ryujinx.xml");
|
|
||||||
using Process mimeProcess = new();
|
|
||||||
|
|
||||||
mimeProcess.StartInfo.FileName = "xdg-mime";
|
|
||||||
mimeProcess.StartInfo.Arguments = $"install --novendor --mode user {mimeTypesFile}";
|
|
||||||
|
|
||||||
mimeProcess.Start();
|
|
||||||
mimeProcess.WaitForExit();
|
|
||||||
|
|
||||||
if (mimeProcess.ExitCode != 0)
|
|
||||||
{
|
|
||||||
Logger.Error?.PrintMsg(LogClass.Application, $"Unable to install mime types. Make sure xdg-utils is installed. Process exited with code: {mimeProcess.ExitCode}");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
using Process updateMimeProcess = new();
|
|
||||||
|
|
||||||
updateMimeProcess.StartInfo.FileName = "update-mime-database";
|
|
||||||
updateMimeProcess.StartInfo.Arguments = mimeDbPath;
|
|
||||||
|
|
||||||
updateMimeProcess.Start();
|
|
||||||
updateMimeProcess.WaitForExit();
|
|
||||||
|
|
||||||
if (updateMimeProcess.ExitCode != 0)
|
|
||||||
{
|
|
||||||
Logger.Error?.PrintMsg(LogClass.Application, $"Could not update local mime database. Process exited with code: {updateMimeProcess.ExitCode}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void Main(string[] args)
|
static void Main(string[] args)
|
||||||
{
|
{
|
||||||
Version = ReleaseInformation.GetVersion();
|
Version = ReleaseInformation.GetVersion();
|
||||||
@@ -189,12 +146,6 @@ namespace Ryujinx
|
|||||||
// Initialize the logger system.
|
// Initialize the logger system.
|
||||||
LoggerModule.Initialize();
|
LoggerModule.Initialize();
|
||||||
|
|
||||||
// Register mime types on linux.
|
|
||||||
if (OperatingSystem.IsLinux())
|
|
||||||
{
|
|
||||||
RegisterMimeTypes();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize Discord integration.
|
// Initialize Discord integration.
|
||||||
DiscordIntegrationModule.Initialize();
|
DiscordIntegrationModule.Initialize();
|
||||||
|
|
||||||
|
@@ -44,7 +44,6 @@ using System.IO;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
using GUI = Gtk.Builder.ObjectAttribute;
|
using GUI = Gtk.Builder.ObjectAttribute;
|
||||||
using ShaderCacheLoadingState = Ryujinx.Graphics.Gpu.Shader.ShaderCacheState;
|
using ShaderCacheLoadingState = Ryujinx.Graphics.Gpu.Shader.ShaderCacheState;
|
||||||
|
|
||||||
@@ -109,6 +108,7 @@ namespace Ryujinx.Ui
|
|||||||
[GUI] CheckMenuItem _favToggle;
|
[GUI] CheckMenuItem _favToggle;
|
||||||
[GUI] MenuItem _firmwareInstallDirectory;
|
[GUI] MenuItem _firmwareInstallDirectory;
|
||||||
[GUI] MenuItem _firmwareInstallFile;
|
[GUI] MenuItem _firmwareInstallFile;
|
||||||
|
[GUI] MenuItem _fileTypesSubMenu;
|
||||||
[GUI] Label _fifoStatus;
|
[GUI] Label _fifoStatus;
|
||||||
[GUI] CheckMenuItem _iconToggle;
|
[GUI] CheckMenuItem _iconToggle;
|
||||||
[GUI] CheckMenuItem _developerToggle;
|
[GUI] CheckMenuItem _developerToggle;
|
||||||
@@ -220,6 +220,8 @@ namespace Ryujinx.Ui
|
|||||||
_pauseEmulation.Sensitive = false;
|
_pauseEmulation.Sensitive = false;
|
||||||
_resumeEmulation.Sensitive = false;
|
_resumeEmulation.Sensitive = false;
|
||||||
|
|
||||||
|
_fileTypesSubMenu.Visible = FileAssociationHelper.IsTypeAssociationSupported;
|
||||||
|
|
||||||
if (ConfigurationState.Instance.Ui.GuiColumns.FavColumn) _favToggle.Active = true;
|
if (ConfigurationState.Instance.Ui.GuiColumns.FavColumn) _favToggle.Active = true;
|
||||||
if (ConfigurationState.Instance.Ui.GuiColumns.IconColumn) _iconToggle.Active = true;
|
if (ConfigurationState.Instance.Ui.GuiColumns.IconColumn) _iconToggle.Active = true;
|
||||||
if (ConfigurationState.Instance.Ui.GuiColumns.AppColumn) _appToggle.Active = true;
|
if (ConfigurationState.Instance.Ui.GuiColumns.AppColumn) _appToggle.Active = true;
|
||||||
@@ -1500,6 +1502,30 @@ namespace Ryujinx.Ui
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void InstallFileTypes_Pressed(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (FileAssociationHelper.Install())
|
||||||
|
{
|
||||||
|
GtkDialog.CreateInfoDialog("Install file types", "File types successfully installed!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GtkDialog.CreateErrorDialog("Failed to install file types.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UninstallFileTypes_Pressed(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (FileAssociationHelper.Uninstall())
|
||||||
|
{
|
||||||
|
GtkDialog.CreateInfoDialog("Uninstall file types", "File types successfully uninstalled!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GtkDialog.CreateErrorDialog("Failed to uninstall file types.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void HandleRelaunch()
|
private void HandleRelaunch()
|
||||||
{
|
{
|
||||||
if (_userChannelPersistence.PreviousIndex != -1 && _userChannelPersistence.ShouldRestart)
|
if (_userChannelPersistence.PreviousIndex != -1 && _userChannelPersistence.ShouldRestart)
|
||||||
|
@@ -1,67 +1,67 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!-- Generated with glade 3.21.0 -->
|
<!-- Generated with glade 3.40.0 -->
|
||||||
<interface>
|
<interface>
|
||||||
<requires lib="gtk+" version="3.20"/>
|
<requires lib="gtk+" version="3.20"/>
|
||||||
<object class="GtkApplicationWindow" id="_mainWin">
|
<object class="GtkApplicationWindow" id="_mainWin">
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="title" translatable="yes">Ryujinx</property>
|
<property name="title" translatable="yes">Ryujinx</property>
|
||||||
<property name="window_position">center</property>
|
<property name="window-position">center</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox" id="_box">
|
<object class="GtkBox" id="_box">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="orientation">vertical</property>
|
<property name="orientation">vertical</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuBar" id="_menuBar">
|
<object class="GtkMenuBar" id="_menuBar">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuItem" id="_fileMenu">
|
<object class="GtkMenuItem" id="_fileMenu">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="label" translatable="yes">File</property>
|
<property name="label" translatable="yes">File</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
<child type="submenu">
|
<child type="submenu">
|
||||||
<object class="GtkMenu">
|
<object class="GtkMenu">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuItem" id="_loadApplicationFile">
|
<object class="GtkMenuItem" id="_loadApplicationFile">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="tooltip_text" translatable="yes">Open a file explorer to choose a Switch compatible file to load</property>
|
<property name="tooltip-text" translatable="yes">Open a file explorer to choose a Switch compatible file to load</property>
|
||||||
<property name="label" translatable="yes">Load Application from File</property>
|
<property name="label" translatable="yes">Load Application from File</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
<signal name="activate" handler="Load_Application_File" swapped="no"/>
|
<signal name="activate" handler="Load_Application_File" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuItem" id="_loadApplicationFolder">
|
<object class="GtkMenuItem" id="_loadApplicationFolder">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="tooltip_text" translatable="yes">Open a file explorer to choose a Switch compatible, unpacked application to load</property>
|
<property name="tooltip-text" translatable="yes">Open a file explorer to choose a Switch compatible, unpacked application to load</property>
|
||||||
<property name="label" translatable="yes">Load Unpacked Game</property>
|
<property name="label" translatable="yes">Load Unpacked Game</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
<signal name="activate" handler="Load_Application_Folder" swapped="no"/>
|
<signal name="activate" handler="Load_Application_Folder" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuItem" id="_appletMenu">
|
<object class="GtkMenuItem" id="_appletMenu">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="label" translatable="yes">Load Applet</property>
|
<property name="label" translatable="yes">Load Applet</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
<child type="submenu">
|
<child type="submenu">
|
||||||
<object class="GtkMenu">
|
<object class="GtkMenu">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuItem" id="LoadMiiEditApplet">
|
<object class="GtkMenuItem" id="LoadMiiEditApplet">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="tooltip_text" translatable="yes">Open Mii Editor Applet in Standalone mode</property>
|
<property name="tooltip-text" translatable="yes">Open Mii Editor Applet in Standalone mode</property>
|
||||||
<property name="label" translatable="yes">Mii Editor</property>
|
<property name="label" translatable="yes">Mii Editor</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
<signal name="activate" handler="Load_Mii_Edit_Applet" swapped="no"/>
|
<signal name="activate" handler="Load_Mii_Edit_Applet" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
@@ -72,42 +72,42 @@
|
|||||||
<child>
|
<child>
|
||||||
<object class="GtkSeparatorMenuItem">
|
<object class="GtkSeparatorMenuItem">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuItem" id="OpenRyuFolder">
|
<object class="GtkMenuItem" id="OpenRyuFolder">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="tooltip_text" translatable="yes">Open Ryujinx filesystem folder</property>
|
<property name="tooltip-text" translatable="yes">Open Ryujinx filesystem folder</property>
|
||||||
<property name="label" translatable="yes">Open Ryujinx Folder</property>
|
<property name="label" translatable="yes">Open Ryujinx Folder</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
<signal name="activate" handler="Open_Ryu_Folder" swapped="no"/>
|
<signal name="activate" handler="Open_Ryu_Folder" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuItem" id="OpenLogsFolder">
|
<object class="GtkMenuItem" id="OpenLogsFolder">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="tooltip_text" translatable="yes">Opens the folder where logs are written to.</property>
|
<property name="tooltip-text" translatable="yes">Opens the folder where logs are written to.</property>
|
||||||
<property name="label" translatable="yes">Open Logs Folder</property>
|
<property name="label" translatable="yes">Open Logs Folder</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
<signal name="activate" handler="OpenLogsFolder_Pressed" swapped="no"/>
|
<signal name="activate" handler="OpenLogsFolder_Pressed" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkSeparatorMenuItem">
|
<object class="GtkSeparatorMenuItem">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuItem" id="ExitMenuItem">
|
<object class="GtkMenuItem" id="ExitMenuItem">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="tooltip_text" translatable="yes">Exit Ryujinx</property>
|
<property name="tooltip-text" translatable="yes">Exit Ryujinx</property>
|
||||||
<property name="label" translatable="yes">Exit</property>
|
<property name="label" translatable="yes">Exit</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
<signal name="activate" handler="Exit_Pressed" swapped="no"/>
|
<signal name="activate" handler="Exit_Pressed" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
@@ -118,144 +118,144 @@
|
|||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuItem" id="_optionMenu">
|
<object class="GtkMenuItem" id="_optionMenu">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="label" translatable="yes">Options</property>
|
<property name="label" translatable="yes">Options</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
<child type="submenu">
|
<child type="submenu">
|
||||||
<object class="GtkMenu">
|
<object class="GtkMenu">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuItem" id="_fullScreen">
|
<object class="GtkMenuItem" id="_fullScreen">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="label" translatable="yes">Enter Fullscreen</property>
|
<property name="label" translatable="yes">Enter Fullscreen</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkCheckMenuItem" id="_startFullScreen">
|
<object class="GtkCheckMenuItem" id="_startFullScreen">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="label" translatable="yes">Start Games in Fullscreen Mode</property>
|
<property name="label" translatable="yes">Start Games in Fullscreen Mode</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
<signal name="toggled" handler="StartFullScreen_Toggled" swapped="no"/>
|
<signal name="toggled" handler="StartFullScreen_Toggled" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkCheckMenuItem" id="_showConsole">
|
<object class="GtkCheckMenuItem" id="_showConsole">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="label" translatable="yes">Show Log Console</property>
|
<property name="label" translatable="yes">Show Log Console</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
<signal name="toggled" handler="ShowConsole_Toggled" swapped="no"/>
|
<signal name="toggled" handler="ShowConsole_Toggled" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkSeparatorMenuItem">
|
<object class="GtkSeparatorMenuItem">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuItem" id="GUIColumns">
|
<object class="GtkMenuItem" id="GUIColumns">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="tooltip_text" translatable="yes">Select which GUI columns to enable</property>
|
<property name="tooltip-text" translatable="yes">Select which GUI columns to enable</property>
|
||||||
<property name="label" translatable="yes">Enable GUI Columns</property>
|
<property name="label" translatable="yes">Enable GUI Columns</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
<child type="submenu">
|
<child type="submenu">
|
||||||
<object class="GtkMenu">
|
<object class="GtkMenu">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkCheckMenuItem" id="_favToggle">
|
<object class="GtkCheckMenuItem" id="_favToggle">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="tooltip_text" translatable="yes">Enable or Disable Favorite Games Column in the game list</property>
|
<property name="tooltip-text" translatable="yes">Enable or Disable Favorite Games Column in the game list</property>
|
||||||
<property name="label" translatable="yes">Enable Favorite Games Column</property>
|
<property name="label" translatable="yes">Enable Favorite Games Column</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkCheckMenuItem" id="_iconToggle">
|
<object class="GtkCheckMenuItem" id="_iconToggle">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="tooltip_text" translatable="yes">Enable or Disable Icon Column in the game list</property>
|
<property name="tooltip-text" translatable="yes">Enable or Disable Icon Column in the game list</property>
|
||||||
<property name="label" translatable="yes">Enable Icon Column</property>
|
<property name="label" translatable="yes">Enable Icon Column</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkCheckMenuItem" id="_appToggle">
|
<object class="GtkCheckMenuItem" id="_appToggle">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="tooltip_text" translatable="yes">Enable or Disable Title Name/ID Column in the game list</property>
|
<property name="tooltip-text" translatable="yes">Enable or Disable Title Name/ID Column in the game list</property>
|
||||||
<property name="label" translatable="yes">Enable Title Name/ID Column</property>
|
<property name="label" translatable="yes">Enable Title Name/ID Column</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkCheckMenuItem" id="_developerToggle">
|
<object class="GtkCheckMenuItem" id="_developerToggle">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="tooltip_text" translatable="yes">Enable or Disable Developer Column in the game list</property>
|
<property name="tooltip-text" translatable="yes">Enable or Disable Developer Column in the game list</property>
|
||||||
<property name="label" translatable="yes">Enable Developer Column</property>
|
<property name="label" translatable="yes">Enable Developer Column</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkCheckMenuItem" id="_versionToggle">
|
<object class="GtkCheckMenuItem" id="_versionToggle">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="tooltip_text" translatable="yes">Enable or Disable Version Column in the game list</property>
|
<property name="tooltip-text" translatable="yes">Enable or Disable Version Column in the game list</property>
|
||||||
<property name="label" translatable="yes">Enable Version Column</property>
|
<property name="label" translatable="yes">Enable Version Column</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkCheckMenuItem" id="_timePlayedToggle">
|
<object class="GtkCheckMenuItem" id="_timePlayedToggle">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="tooltip_text" translatable="yes">Enable or Disable Time Played Column in the game list</property>
|
<property name="tooltip-text" translatable="yes">Enable or Disable Time Played Column in the game list</property>
|
||||||
<property name="label" translatable="yes">Enable Time Played Column</property>
|
<property name="label" translatable="yes">Enable Time Played Column</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkCheckMenuItem" id="_lastPlayedToggle">
|
<object class="GtkCheckMenuItem" id="_lastPlayedToggle">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="tooltip_text" translatable="yes">Enable or Disable Last Played Column in the game list</property>
|
<property name="tooltip-text" translatable="yes">Enable or Disable Last Played Column in the game list</property>
|
||||||
<property name="label" translatable="yes">Enable Last Played Column</property>
|
<property name="label" translatable="yes">Enable Last Played Column</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkCheckMenuItem" id="_fileExtToggle">
|
<object class="GtkCheckMenuItem" id="_fileExtToggle">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="tooltip_text" translatable="yes">Enable or Disable file extension column in the game list</property>
|
<property name="tooltip-text" translatable="yes">Enable or Disable file extension column in the game list</property>
|
||||||
<property name="label" translatable="yes">Enable File Ext Column</property>
|
<property name="label" translatable="yes">Enable File Ext Column</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkCheckMenuItem" id="_fileSizeToggle">
|
<object class="GtkCheckMenuItem" id="_fileSizeToggle">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="tooltip_text" translatable="yes">Enable or Disable File Size Column in the game list</property>
|
<property name="tooltip-text" translatable="yes">Enable or Disable File Size Column in the game list</property>
|
||||||
<property name="label" translatable="yes">Enable File Size Column</property>
|
<property name="label" translatable="yes">Enable File Size Column</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkCheckMenuItem" id="_pathToggle">
|
<object class="GtkCheckMenuItem" id="_pathToggle">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="tooltip_text" translatable="yes">Enable or Disable Path Column in the game list</property>
|
<property name="tooltip-text" translatable="yes">Enable or Disable Path Column in the game list</property>
|
||||||
<property name="label" translatable="yes">Enable Path Column</property>
|
<property name="label" translatable="yes">Enable Path Column</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
@@ -265,26 +265,26 @@
|
|||||||
<child>
|
<child>
|
||||||
<object class="GtkSeparatorMenuItem">
|
<object class="GtkSeparatorMenuItem">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuItem" id="SettingsMenu">
|
<object class="GtkMenuItem" id="SettingsMenu">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="tooltip_text" translatable="yes">Open settings window</property>
|
<property name="tooltip-text" translatable="yes">Open settings window</property>
|
||||||
<property name="label" translatable="yes">Settings</property>
|
<property name="label" translatable="yes">Settings</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
<signal name="activate" handler="Settings_Pressed" swapped="no"/>
|
<signal name="activate" handler="Settings_Pressed" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuItem" id="_manageUserProfiles">
|
<object class="GtkMenuItem" id="_manageUserProfiles">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="tooltip_text" translatable="yes">Open User Profiles Manager window</property>
|
<property name="tooltip-text" translatable="yes">Open User Profiles Manager window</property>
|
||||||
<property name="label" translatable="yes">Manage User Profiles</property>
|
<property name="label" translatable="yes">Manage User Profiles</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
<signal name="activate" handler="ManageUserProfiles_Pressed" swapped="no"/>
|
<signal name="activate" handler="ManageUserProfiles_Pressed" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
@@ -295,74 +295,74 @@
|
|||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuItem" id="_actionMenu">
|
<object class="GtkMenuItem" id="_actionMenu">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="label" translatable="yes">Actions</property>
|
<property name="label" translatable="yes">Actions</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
<child type="submenu">
|
<child type="submenu">
|
||||||
<object class="GtkMenu">
|
<object class="GtkMenu">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuItem" id="_pauseEmulation">
|
<object class="GtkMenuItem" id="_pauseEmulation">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="tooltip_text" translatable="yes">Pause emulation</property>
|
<property name="tooltip-text" translatable="yes">Pause emulation</property>
|
||||||
<property name="label" translatable="yes">Pause Emulation</property>
|
<property name="label" translatable="yes">Pause Emulation</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
<signal name="activate" handler="PauseEmulation_Pressed" swapped="no"/>
|
<signal name="activate" handler="PauseEmulation_Pressed" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuItem" id="_resumeEmulation">
|
<object class="GtkMenuItem" id="_resumeEmulation">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="tooltip_text" translatable="yes">Resume emulation</property>
|
<property name="tooltip-text" translatable="yes">Resume emulation</property>
|
||||||
<property name="label" translatable="yes">Resume Emulation</property>
|
<property name="label" translatable="yes">Resume Emulation</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
<signal name="activate" handler="ResumeEmulation_Pressed" swapped="no"/>
|
<signal name="activate" handler="ResumeEmulation_Pressed" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuItem" id="_stopEmulation">
|
<object class="GtkMenuItem" id="_stopEmulation">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="tooltip_text" translatable="yes">Stop emulation of the current game and return to game selection</property>
|
<property name="tooltip-text" translatable="yes">Stop emulation of the current game and return to game selection</property>
|
||||||
<property name="label" translatable="yes">Stop Emulation</property>
|
<property name="label" translatable="yes">Stop Emulation</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
<signal name="activate" handler="StopEmulation_Pressed" swapped="no"/>
|
<signal name="activate" handler="StopEmulation_Pressed" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkSeparatorMenuItem">
|
<object class="GtkSeparatorMenuItem">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuItem" id="_simulateWakeUpMessage">
|
<object class="GtkMenuItem" id="_simulateWakeUpMessage">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="tooltip_text" translatable="yes">Simulate a Wake-up Message</property>
|
<property name="tooltip-text" translatable="yes">Simulate a Wake-up Message</property>
|
||||||
<property name="label" translatable="yes">Simulate Wake-up Message</property>
|
<property name="label" translatable="yes">Simulate Wake-up Message</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
<signal name="activate" handler="Simulate_WakeUp_Message_Pressed" swapped="no"/>
|
<signal name="activate" handler="Simulate_WakeUp_Message_Pressed" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuItem" id="_scanAmiibo">
|
<object class="GtkMenuItem" id="_scanAmiibo">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="tooltip_text" translatable="yes">Scan an Amiibo</property>
|
<property name="tooltip-text" translatable="yes">Scan an Amiibo</property>
|
||||||
<property name="label" translatable="yes">Scan an Amiibo</property>
|
<property name="label" translatable="yes">Scan an Amiibo</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
<signal name="activate" handler="Scan_Amiibo" swapped="no"/>
|
<signal name="activate" handler="Scan_Amiibo" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuItem" id="_takeScreenshot">
|
<object class="GtkMenuItem" id="_takeScreenshot">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="tooltip_text" translatable="yes">Take a screenshot</property>
|
<property name="tooltip-text" translatable="yes">Take a screenshot</property>
|
||||||
<property name="label" translatable="yes">Take Screenshot</property>
|
<property name="label" translatable="yes">Take Screenshot</property>
|
||||||
<signal name="activate" handler="Take_Screenshot" swapped="no"/>
|
<signal name="activate" handler="Take_Screenshot" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
@@ -370,16 +370,16 @@
|
|||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuItem" id="_hideUi">
|
<object class="GtkMenuItem" id="_hideUi">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="label" translatable="yes">Hide UI (SHOWUIKEY to show)</property>
|
<property name="label" translatable="yes">Hide UI (SHOWUIKEY to show)</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
<signal name="activate" handler="HideUi_Pressed" swapped="no"/>
|
<signal name="activate" handler="HideUi_Pressed" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuItem" id="_manageCheats">
|
<object class="GtkMenuItem" id="_manageCheats">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="label" translatable="yes">Manage Cheats</property>
|
<property name="label" translatable="yes">Manage Cheats</property>
|
||||||
<signal name="activate" handler="ManageCheats_Pressed" swapped="no"/>
|
<signal name="activate" handler="ManageCheats_Pressed" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
@@ -391,38 +391,38 @@
|
|||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuItem" id="_toolsMenu">
|
<object class="GtkMenuItem" id="_toolsMenu">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="label" translatable="yes">Tools</property>
|
<property name="label" translatable="yes">Tools</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
<child type="submenu">
|
<child type="submenu">
|
||||||
<object class="GtkMenu">
|
<object class="GtkMenu">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuItem" id="FirmwareSubMenu">
|
<object class="GtkMenuItem" id="FirmwareSubMenu">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="label" translatable="yes">Install Firmware</property>
|
<property name="label" translatable="yes">Install Firmware</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
<child type="submenu">
|
<child type="submenu">
|
||||||
<object class="GtkMenu">
|
<object class="GtkMenu">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuItem" id="_firmwareInstallFile">
|
<object class="GtkMenuItem" id="_firmwareInstallFile">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="label" translatable="yes">Install a firmware from XCI or ZIP</property>
|
<property name="label" translatable="yes">Install a firmware from XCI or ZIP</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
<signal name="activate" handler="Installer_File_Pressed" swapped="no"/>
|
<signal name="activate" handler="Installer_File_Pressed" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuItem" id="_firmwareInstallDirectory">
|
<object class="GtkMenuItem" id="_firmwareInstallDirectory">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="label" translatable="yes">Install a firmware from a directory</property>
|
<property name="label" translatable="yes">Install a firmware from a directory</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
<signal name="activate" handler="Installer_Directory_Pressed" swapped="no"/>
|
<signal name="activate" handler="Installer_Directory_Pressed" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
@@ -430,6 +430,36 @@
|
|||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem" id="_fileTypesSubMenu">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Manage file types</property>
|
||||||
|
<property name="use-underline">True</property>
|
||||||
|
<child type="submenu">
|
||||||
|
<object class="GtkMenu">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem" id="_installFileTypes">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Install file types</property>
|
||||||
|
<signal name="activate" handler="InstallFileTypes_Pressed" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem" id="_uninstallFileTypes">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Uninstall file types</property>
|
||||||
|
<signal name="activate" handler="UninstallFileTypes_Pressed" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
@@ -437,36 +467,36 @@
|
|||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuItem" id="HelpMenu">
|
<object class="GtkMenuItem" id="HelpMenu">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="label" translatable="yes">Help</property>
|
<property name="label" translatable="yes">Help</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
<child type="submenu">
|
<child type="submenu">
|
||||||
<object class="GtkMenu">
|
<object class="GtkMenu">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuItem" id="UpdateMenuItem">
|
<object class="GtkMenuItem" id="UpdateMenuItem">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="tooltip_text" translatable="yes">Check for updates to Ryujinx</property>
|
<property name="tooltip-text" translatable="yes">Check for updates to Ryujinx</property>
|
||||||
<property name="label" translatable="yes">Check for Updates</property>
|
<property name="label" translatable="yes">Check for Updates</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
<signal name="activate" handler="Update_Pressed" swapped="no"/>
|
<signal name="activate" handler="Update_Pressed" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkSeparatorMenuItem">
|
<object class="GtkSeparatorMenuItem">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuItem" id="About">
|
<object class="GtkMenuItem" id="About">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="tooltip_text" translatable="yes">Open about window</property>
|
<property name="tooltip-text" translatable="yes">Open about window</property>
|
||||||
<property name="label" translatable="yes">About</property>
|
<property name="label" translatable="yes">About</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
<signal name="activate" handler="About_Pressed" swapped="no"/>
|
<signal name="activate" handler="About_Pressed" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
@@ -484,24 +514,24 @@
|
|||||||
<child>
|
<child>
|
||||||
<object class="GtkBox" id="_mainBox">
|
<object class="GtkBox" id="_mainBox">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="orientation">vertical</property>
|
<property name="orientation">vertical</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox" id="_viewBox">
|
<object class="GtkBox" id="_viewBox">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="orientation">vertical</property>
|
<property name="orientation">vertical</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkScrolledWindow" id="_gameTableWindow">
|
<object class="GtkScrolledWindow" id="_gameTableWindow">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can-focus">True</property>
|
||||||
<property name="shadow_type">in</property>
|
<property name="shadow-type">in</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkTreeView" id="_gameTable">
|
<object class="GtkTreeView" id="_gameTable">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can-focus">True</property>
|
||||||
<property name="reorderable">True</property>
|
<property name="reorderable">True</property>
|
||||||
<property name="hover_selection">True</property>
|
<property name="hover-selection">True</property>
|
||||||
<signal name="row-activated" handler="Row_Activated" swapped="no"/>
|
<signal name="row-activated" handler="Row_Activated" swapped="no"/>
|
||||||
<child internal-child="selection">
|
<child internal-child="selection">
|
||||||
<object class="GtkTreeSelection" id="_gameTableSelection"/>
|
<object class="GtkTreeSelection" id="_gameTableSelection"/>
|
||||||
@@ -524,24 +554,24 @@
|
|||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox" id="_footerBox">
|
<object class="GtkBox" id="_footerBox">
|
||||||
<property name="height_request">19</property>
|
<property name="height-request">19</property>
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox" id="_listStatusBox">
|
<object class="GtkBox" id="_listStatusBox">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkEventBox">
|
<object class="GtkEventBox">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="margin_left">5</property>
|
<property name="margin-left">5</property>
|
||||||
<signal name="button-release-event" handler="RefreshList_Pressed" swapped="no"/>
|
<signal name="button-release-event" handler="RefreshList_Pressed" swapped="no"/>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
<property name="name">RefreshList</property>
|
<property name="name">RefreshList</property>
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="stock">gtk-refresh</property>
|
<property name="stock">gtk-refresh</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
@@ -555,11 +585,11 @@
|
|||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel" id="_progressLabel">
|
<object class="GtkLabel" id="_progressLabel">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="margin_left">10</property>
|
<property name="margin-left">10</property>
|
||||||
<property name="margin_right">5</property>
|
<property name="margin-right">5</property>
|
||||||
<property name="margin_top">2</property>
|
<property name="margin-top">2</property>
|
||||||
<property name="margin_bottom">2</property>
|
<property name="margin-bottom">2</property>
|
||||||
<property name="label" translatable="yes">0/0 Games Loaded</property>
|
<property name="label" translatable="yes">0/0 Games Loaded</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
@@ -570,13 +600,13 @@
|
|||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkProgressBar" id="_progressBar">
|
<object class="GtkProgressBar" id="_progressBar">
|
||||||
<property name="width_request">200</property>
|
<property name="width-request">200</property>
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
<property name="margin_left">10</property>
|
<property name="margin-left">10</property>
|
||||||
<property name="margin_right">5</property>
|
<property name="margin-right">5</property>
|
||||||
<property name="margin_bottom">6</property>
|
<property name="margin-bottom">6</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">True</property>
|
<property name="expand">True</property>
|
||||||
@@ -594,19 +624,19 @@
|
|||||||
<child>
|
<child>
|
||||||
<object class="GtkBox" id="_statusBar">
|
<object class="GtkBox" id="_statusBar">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkEventBox">
|
<object class="GtkEventBox">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<signal name="button-release-event" handler="VSyncStatus_Clicked" swapped="no"/>
|
<signal name="button-release-event" handler="VSyncStatus_Clicked" swapped="no"/>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel" id="_vSyncStatus">
|
<object class="GtkLabel" id="_vSyncStatus">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
<property name="margin_left">5</property>
|
<property name="margin-left">5</property>
|
||||||
<property name="margin_right">5</property>
|
<property name="margin-right">5</property>
|
||||||
<property name="label" translatable="yes">VSync</property>
|
<property name="label" translatable="yes">VSync</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
@@ -620,7 +650,7 @@
|
|||||||
<child>
|
<child>
|
||||||
<object class="GtkSeparator">
|
<object class="GtkSeparator">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
@@ -631,15 +661,15 @@
|
|||||||
<child>
|
<child>
|
||||||
<object class="GtkEventBox">
|
<object class="GtkEventBox">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<signal name="button-release-event" handler="DockedMode_Clicked" swapped="no"/>
|
<signal name="button-release-event" handler="DockedMode_Clicked" swapped="no"/>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel" id="_dockedMode">
|
<object class="GtkLabel" id="_dockedMode">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
<property name="margin_left">5</property>
|
<property name="margin-left">5</property>
|
||||||
<property name="margin_right">5</property>
|
<property name="margin-right">5</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
@@ -652,7 +682,7 @@
|
|||||||
<child>
|
<child>
|
||||||
<object class="GtkSeparator">
|
<object class="GtkSeparator">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
@@ -663,15 +693,15 @@
|
|||||||
<child>
|
<child>
|
||||||
<object class="GtkEventBox">
|
<object class="GtkEventBox">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<signal name="button-release-event" handler="VolumeStatus_Clicked" swapped="no"/>
|
<signal name="button-release-event" handler="VolumeStatus_Clicked" swapped="no"/>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel" id="_volumeStatus">
|
<object class="GtkLabel" id="_volumeStatus">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
<property name="margin_left">5</property>
|
<property name="margin-left">5</property>
|
||||||
<property name="margin_right">5</property>
|
<property name="margin-right">5</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
@@ -684,7 +714,7 @@
|
|||||||
<child>
|
<child>
|
||||||
<object class="GtkSeparator">
|
<object class="GtkSeparator">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
@@ -695,15 +725,15 @@
|
|||||||
<child>
|
<child>
|
||||||
<object class="GtkEventBox">
|
<object class="GtkEventBox">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<signal name="button-release-event" handler="AspectRatio_Clicked" swapped="no"/>
|
<signal name="button-release-event" handler="AspectRatio_Clicked" swapped="no"/>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel" id="_aspectRatio">
|
<object class="GtkLabel" id="_aspectRatio">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
<property name="margin_left">5</property>
|
<property name="margin-left">5</property>
|
||||||
<property name="margin_right">5</property>
|
<property name="margin-right">5</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
@@ -716,7 +746,7 @@
|
|||||||
<child>
|
<child>
|
||||||
<object class="GtkSeparator">
|
<object class="GtkSeparator">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
@@ -727,10 +757,10 @@
|
|||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel" id="_gameStatus">
|
<object class="GtkLabel" id="_gameStatus">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
<property name="margin_left">5</property>
|
<property name="margin-left">5</property>
|
||||||
<property name="margin_right">5</property>
|
<property name="margin-right">5</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
@@ -741,7 +771,7 @@
|
|||||||
<child>
|
<child>
|
||||||
<object class="GtkSeparator">
|
<object class="GtkSeparator">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
@@ -752,10 +782,10 @@
|
|||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel" id="_fifoStatus">
|
<object class="GtkLabel" id="_fifoStatus">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
<property name="margin_left">5</property>
|
<property name="margin-left">5</property>
|
||||||
<property name="margin_right">5</property>
|
<property name="margin-right">5</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
@@ -766,7 +796,7 @@
|
|||||||
<child>
|
<child>
|
||||||
<object class="GtkSeparator">
|
<object class="GtkSeparator">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
@@ -777,10 +807,10 @@
|
|||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel" id="_gpuBackend">
|
<object class="GtkLabel" id="_gpuBackend">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
<property name="margin_left">5</property>
|
<property name="margin-left">5</property>
|
||||||
<property name="margin_right">5</property>
|
<property name="margin-right">5</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
@@ -791,7 +821,7 @@
|
|||||||
<child>
|
<child>
|
||||||
<object class="GtkSeparator">
|
<object class="GtkSeparator">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
@@ -802,10 +832,10 @@
|
|||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel" id="_gpuName">
|
<object class="GtkLabel" id="_gpuName">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
<property name="margin_left">5</property>
|
<property name="margin-left">5</property>
|
||||||
<property name="margin_right">5</property>
|
<property name="margin-right">5</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">True</property>
|
<property name="expand">True</property>
|
||||||
@@ -823,12 +853,12 @@
|
|||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="margin_left">5</property>
|
<property name="margin-left">5</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel">
|
<object class="GtkLabel">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="label" translatable="yes">System Version</property>
|
<property name="label" translatable="yes">System Version</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
@@ -839,16 +869,16 @@
|
|||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel" id="_firmwareVersionLabel">
|
<object class="GtkLabel" id="_firmwareVersionLabel">
|
||||||
<property name="width_request">50</property>
|
<property name="width-request">50</property>
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="margin_left">5</property>
|
<property name="margin-left">5</property>
|
||||||
<property name="margin_right">5</property>
|
<property name="margin-right">5</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
<property name="fill">True</property>
|
<property name="fill">True</property>
|
||||||
<property name="pack_type">end</property>
|
<property name="pack-type">end</property>
|
||||||
<property name="position">1</property>
|
<property name="position">1</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
@@ -856,15 +886,15 @@
|
|||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
<property name="fill">True</property>
|
<property name="fill">True</property>
|
||||||
<property name="pack_type">end</property>
|
<property name="pack-type">end</property>
|
||||||
<property name="position">4</property>
|
<property name="position">4</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel" id="_loadingStatusLabel">
|
<object class="GtkLabel" id="_loadingStatusLabel">
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="margin_left">5</property>
|
<property name="margin-left">5</property>
|
||||||
<property name="margin_right">5</property>
|
<property name="margin-right">5</property>
|
||||||
<property name="label" translatable="yes">0/0 </property>
|
<property name="label" translatable="yes">0/0 </property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
@@ -875,11 +905,11 @@
|
|||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkProgressBar" id="_loadingStatusBar">
|
<object class="GtkProgressBar" id="_loadingStatusBar">
|
||||||
<property name="width_request">200</property>
|
<property name="width-request">200</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="margin_left">5</property>
|
<property name="margin-left">5</property>
|
||||||
<property name="margin_right">5</property>
|
<property name="margin-right">5</property>
|
||||||
<property name="margin_bottom">6</property>
|
<property name="margin-bottom">6</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
@@ -903,8 +933,5 @@
|
|||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child type="titlebar">
|
|
||||||
<placeholder/>
|
|
||||||
</child>
|
|
||||||
</object>
|
</object>
|
||||||
</interface>
|
</interface>
|
||||||
|
Reference in New Issue
Block a user