Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
eebc39228d | ||
|
9daf029f35 | ||
|
51a27032f0 | ||
|
a6a67a2b7a |
@@ -10,6 +10,7 @@ using Ryujinx.Ava.Ui.Windows;
|
||||
using Ryujinx.Common;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Ui.Common.Configuration;
|
||||
using Ryujinx.Ui.Common.Helper;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
@@ -64,8 +65,7 @@ namespace Ryujinx.Ava
|
||||
if (result == UserResult.Yes)
|
||||
{
|
||||
var path = Process.GetCurrentProcess().MainModule.FileName;
|
||||
var info = new ProcessStartInfo() { FileName = path, UseShellExecute = false };
|
||||
var proc = Process.Start(info);
|
||||
var proc = Process.Start(path, CommandLineState.Arguments);
|
||||
desktop.Shutdown();
|
||||
Environment.Exit(0);
|
||||
}
|
||||
|
@@ -13,6 +13,7 @@ using Ryujinx.Common.SystemInfo;
|
||||
using Ryujinx.Modules;
|
||||
using Ryujinx.Ui.Common;
|
||||
using Ryujinx.Ui.Common.Configuration;
|
||||
using Ryujinx.Ui.Common.Helper;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
@@ -26,7 +27,6 @@ namespace Ryujinx.Ava
|
||||
public static double ActualScaleFactor { get; set; }
|
||||
public static string Version { get; private set; }
|
||||
public static string ConfigurationPath { get; private set; }
|
||||
public static string CommandLineProfile { get; set; }
|
||||
public static bool PreviewerDetached { get; private set; }
|
||||
|
||||
public static RenderTimer RenderTimer { get; private set; }
|
||||
@@ -87,46 +87,8 @@ namespace Ryujinx.Ava
|
||||
|
||||
private static void Initialize(string[] args)
|
||||
{
|
||||
// Parse Arguments.
|
||||
string launchPathArg = null;
|
||||
string baseDirPathArg = null;
|
||||
bool startFullscreenArg = false;
|
||||
|
||||
for (int i = 0; i < args.Length; ++i)
|
||||
{
|
||||
string arg = args[i];
|
||||
|
||||
if (arg == "-r" || arg == "--root-data-dir")
|
||||
{
|
||||
if (i + 1 >= args.Length)
|
||||
{
|
||||
Logger.Error?.Print(LogClass.Application, $"Invalid option '{arg}'");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
baseDirPathArg = args[++i];
|
||||
}
|
||||
else if (arg == "-p" || arg == "--profile")
|
||||
{
|
||||
if (i + 1 >= args.Length)
|
||||
{
|
||||
Logger.Error?.Print(LogClass.Application, $"Invalid option '{arg}'");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
CommandLineProfile = args[++i];
|
||||
}
|
||||
else if (arg == "-f" || arg == "--fullscreen")
|
||||
{
|
||||
startFullscreenArg = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
launchPathArg = arg;
|
||||
}
|
||||
}
|
||||
// Parse arguments
|
||||
CommandLineState.ParseArguments(args);
|
||||
|
||||
// Delete backup files after updating.
|
||||
Task.Run(Updater.CleanupUpdate);
|
||||
@@ -138,7 +100,7 @@ namespace Ryujinx.Ava
|
||||
AppDomain.CurrentDomain.ProcessExit += (object sender, EventArgs e) => Exit();
|
||||
|
||||
// Setup base data directory.
|
||||
AppDataManager.Initialize(baseDirPathArg);
|
||||
AppDataManager.Initialize(CommandLineState.BaseDirPathArg);
|
||||
|
||||
// Initialize the configuration.
|
||||
ConfigurationState.Initialize();
|
||||
@@ -173,9 +135,9 @@ namespace Ryujinx.Ava
|
||||
}
|
||||
}
|
||||
|
||||
if (launchPathArg != null)
|
||||
if (CommandLineState.LaunchPathArg != null)
|
||||
{
|
||||
MainWindow.DeferLoadApplication(launchPathArg, startFullscreenArg);
|
||||
MainWindow.DeferLoadApplication(CommandLineState.LaunchPathArg, CommandLineState.StartFullscreenArg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,6 +177,19 @@ namespace Ryujinx.Ava
|
||||
Logger.Warning?.PrintMsg(LogClass.Application, $"Failed to load config! Loading the default config instead.\nFailed config location {ConfigurationPath}");
|
||||
}
|
||||
}
|
||||
|
||||
// Check if graphics backend was overridden
|
||||
if (CommandLineState.OverrideGraphicsBackend != null)
|
||||
{
|
||||
if (CommandLineState.OverrideGraphicsBackend.ToLower() == "opengl")
|
||||
{
|
||||
ConfigurationState.Instance.Graphics.GraphicsBackend.Value = GraphicsBackend.OpenGl;
|
||||
}
|
||||
else if (CommandLineState.OverrideGraphicsBackend.ToLower() == "vulkan")
|
||||
{
|
||||
ConfigurationState.Instance.Graphics.GraphicsBackend.Value = GraphicsBackend.Vulkan;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void PrintSystemInfo()
|
||||
|
@@ -21,14 +21,10 @@ using Ryujinx.HLE.HOS.Services.Time.TimeZone;
|
||||
using Ryujinx.Input;
|
||||
using Ryujinx.Ui.Common.Configuration;
|
||||
using Ryujinx.Ui.Common.Configuration.System;
|
||||
using Silk.NET.Vulkan;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading.Tasks;
|
||||
using TimeZone = Ryujinx.Ava.Ui.Models.TimeZone;
|
||||
|
||||
namespace Ryujinx.Ava.Ui.ViewModels
|
||||
|
@@ -23,6 +23,7 @@ using Ryujinx.Modules;
|
||||
using Ryujinx.Ui.App.Common;
|
||||
using Ryujinx.Ui.Common;
|
||||
using Ryujinx.Ui.Common.Configuration;
|
||||
using Ryujinx.Ui.Common.Helper;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
@@ -432,7 +433,7 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
// Consider removing this at some point in the future when we don't need to worry about old saves.
|
||||
VirtualFileSystem.FixExtraData(LibHacHorizonManager.RyujinxClient);
|
||||
|
||||
AccountManager = new AccountManager(LibHacHorizonManager.RyujinxClient, Program.CommandLineProfile);
|
||||
AccountManager = new AccountManager(LibHacHorizonManager.RyujinxClient, CommandLineState.Profile);
|
||||
|
||||
VirtualFileSystem.ReloadKeySet();
|
||||
|
||||
|
@@ -708,11 +708,12 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
else
|
||||
{
|
||||
bool dataMatches = _currentData != null && data.SequenceEqual(_currentData);
|
||||
_currentData = data.ToArray();
|
||||
if (dataMatches)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_currentData = data.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
||||
private const ushort FileFormatVersionMajor = 1;
|
||||
private const ushort FileFormatVersionMinor = 2;
|
||||
private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
|
||||
private const uint CodeGenVersion = 3807;
|
||||
private const uint CodeGenVersion = 3831;
|
||||
|
||||
private const string SharedTocFileName = "shared.toc";
|
||||
private const string SharedDataFileName = "shared.data";
|
||||
|
@@ -34,5 +34,11 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
||||
GL.ActiveTexture(TextureUnit.Texture0 + unit);
|
||||
GL.BindTexture(target, Handle);
|
||||
}
|
||||
|
||||
public static void ClearBinding(int unit)
|
||||
{
|
||||
GL.ActiveTexture(TextureUnit.Texture0 + unit);
|
||||
GL.BindTextureUnit(unit, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -919,6 +919,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||
|
||||
if (texture == null)
|
||||
{
|
||||
GL.BindImageTexture(binding, 0, 0, true, 0, TextureAccess.ReadWrite, SizedInternalFormat.Rgba8);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1275,6 +1276,10 @@ namespace Ryujinx.Graphics.OpenGL
|
||||
((TextureBase)texture).Bind(binding);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TextureBase.ClearBinding(binding);
|
||||
}
|
||||
|
||||
Sampler glSampler = (Sampler)sampler;
|
||||
|
||||
|
@@ -10,12 +10,12 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
||||
|
||||
public StructuredFunction CurrentFunction { get; set; }
|
||||
|
||||
public StructuredProgramInfo Info { get; }
|
||||
|
||||
public ShaderConfig Config { get; }
|
||||
|
||||
public OperandManager OperandManager { get; }
|
||||
|
||||
private readonly StructuredProgramInfo _info;
|
||||
|
||||
private readonly StringBuilder _sb;
|
||||
|
||||
private int _level;
|
||||
@@ -24,7 +24,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
||||
|
||||
public CodeGenContext(StructuredProgramInfo info, ShaderConfig config)
|
||||
{
|
||||
_info = info;
|
||||
Info = info;
|
||||
Config = config;
|
||||
|
||||
OperandManager = new OperandManager();
|
||||
@@ -72,19 +72,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
||||
|
||||
public StructuredFunction GetFunction(int id)
|
||||
{
|
||||
return _info.Functions[id];
|
||||
}
|
||||
|
||||
public TransformFeedbackOutput GetTransformFeedbackOutput(int location, int component)
|
||||
{
|
||||
int index = (AttributeConsts.UserAttributeBase / 4) + location * 4 + component;
|
||||
return _info.TransformFeedbackOutputs[index];
|
||||
}
|
||||
|
||||
public TransformFeedbackOutput GetTransformFeedbackOutput(int location)
|
||||
{
|
||||
int index = location / 4;
|
||||
return _info.TransformFeedbackOutputs[index];
|
||||
return Info.Functions[id];
|
||||
}
|
||||
|
||||
private void UpdateIndentation()
|
||||
|
@@ -210,7 +210,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
||||
|
||||
if (context.Config.TransformFeedbackEnabled && context.Config.LastInVertexPipeline)
|
||||
{
|
||||
var tfOutput = context.GetTransformFeedbackOutput(AttributeConsts.PositionX);
|
||||
var tfOutput = context.Info.GetTransformFeedbackOutput(AttributeConsts.PositionX);
|
||||
if (tfOutput.Valid)
|
||||
{
|
||||
context.AppendLine($"layout (xfb_buffer = {tfOutput.Buffer}, xfb_offset = {tfOutput.Offset}, xfb_stride = {tfOutput.Stride}) out gl_PerVertex");
|
||||
@@ -603,6 +603,31 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
||||
string name = $"{DefaultNames.OAttributePrefix}{attr}{suffix}";
|
||||
|
||||
if (context.Config.TransformFeedbackEnabled && context.Config.LastInVertexPipeline)
|
||||
{
|
||||
int attrOffset = AttributeConsts.UserAttributeBase + attr * 16;
|
||||
int components = context.Config.LastInPipeline ? context.Info.GetTransformFeedbackOutputComponents(attrOffset) : 1;
|
||||
|
||||
if (components > 1)
|
||||
{
|
||||
string type = components switch
|
||||
{
|
||||
2 => "vec2",
|
||||
3 => "vec3",
|
||||
4 => "vec4",
|
||||
_ => "float"
|
||||
};
|
||||
|
||||
string xfb = string.Empty;
|
||||
|
||||
var tfOutput = context.Info.GetTransformFeedbackOutput(attrOffset);
|
||||
if (tfOutput.Valid)
|
||||
{
|
||||
xfb = $", xfb_buffer = {tfOutput.Buffer}, xfb_offset = {tfOutput.Offset}, xfb_stride = {tfOutput.Stride}";
|
||||
}
|
||||
|
||||
context.AppendLine($"layout (location = {attr}{xfb}) out {type} {name};");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int c = 0; c < 4; c++)
|
||||
{
|
||||
@@ -610,7 +635,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
||||
|
||||
string xfb = string.Empty;
|
||||
|
||||
var tfOutput = context.GetTransformFeedbackOutput(attr, c);
|
||||
var tfOutput = context.Info.GetTransformFeedbackOutput(attrOffset + c * 4);
|
||||
if (tfOutput.Valid)
|
||||
{
|
||||
xfb = $", xfb_buffer = {tfOutput.Buffer}, xfb_offset = {tfOutput.Offset}, xfb_stride = {tfOutput.Stride}";
|
||||
@@ -619,6 +644,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
||||
context.AppendLine($"layout (location = {attr}, component = {c}{xfb}) out float {name}_{swzMask};");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
context.AppendLine($"layout (location = {attr}) out vec4 {name};");
|
||||
|
@@ -134,7 +134,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
||||
if (assignment.Destination is AstOperand operand && operand.Type.IsAttribute())
|
||||
{
|
||||
bool perPatch = operand.Type == OperandType.AttributePerPatch;
|
||||
dest = OperandManager.GetOutAttributeName(operand.Value, context.Config, perPatch);
|
||||
dest = OperandManager.GetOutAttributeName(context, operand.Value, perPatch);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
||||
}
|
||||
else if (node is AstOperand operand)
|
||||
{
|
||||
return context.OperandManager.GetExpression(operand, context.Config);
|
||||
return context.OperandManager.GetExpression(context, operand);
|
||||
}
|
||||
|
||||
throw new ArgumentException($"Invalid node type \"{node?.GetType().Name ?? "null"}\".");
|
||||
|
@@ -205,7 +205,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
||||
if (src2 is AstOperand operand && operand.Type == OperandType.Constant)
|
||||
{
|
||||
int attrOffset = baseAttr.Value + (operand.Value << 2);
|
||||
return OperandManager.GetAttributeName(attrOffset, context.Config, perPatch: false, isOutAttr: false, indexExpr);
|
||||
return OperandManager.GetAttributeName(context, attrOffset, perPatch: false, isOutAttr: false, indexExpr);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -332,7 +332,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
||||
if (src2 is AstOperand operand && operand.Type == OperandType.Constant)
|
||||
{
|
||||
int attrOffset = baseAttr.Value + (operand.Value << 2);
|
||||
attrName = OperandManager.GetAttributeName(attrOffset, context.Config, perPatch: false, isOutAttr: true);
|
||||
attrName = OperandManager.GetAttributeName(context, attrOffset, perPatch: false, isOutAttr: true);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@@ -48,6 +48,10 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
||||
{ AttributeConsts.TessCoordY, new BuiltInAttribute("gl_TessCoord.y", VariableType.F32) },
|
||||
{ AttributeConsts.InstanceId, new BuiltInAttribute("gl_InstanceID", VariableType.S32) },
|
||||
{ AttributeConsts.VertexId, new BuiltInAttribute("gl_VertexID", VariableType.S32) },
|
||||
{ AttributeConsts.BaseInstance, new BuiltInAttribute("gl_BaseInstance", VariableType.S32) },
|
||||
{ AttributeConsts.BaseVertex, new BuiltInAttribute("gl_BaseVertex", VariableType.S32) },
|
||||
{ AttributeConsts.InstanceIndex, new BuiltInAttribute("gl_InstanceIndex", VariableType.S32) },
|
||||
{ AttributeConsts.VertexIndex, new BuiltInAttribute("gl_VertexIndex", VariableType.S32) },
|
||||
{ AttributeConsts.FrontFacing, new BuiltInAttribute("gl_FrontFacing", VariableType.Bool) },
|
||||
|
||||
// Special.
|
||||
@@ -99,15 +103,15 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
||||
return name;
|
||||
}
|
||||
|
||||
public string GetExpression(AstOperand operand, ShaderConfig config)
|
||||
public string GetExpression(CodeGenContext context, AstOperand operand)
|
||||
{
|
||||
return operand.Type switch
|
||||
{
|
||||
OperandType.Argument => GetArgumentName(operand.Value),
|
||||
OperandType.Attribute => GetAttributeName(operand.Value, config, perPatch: false),
|
||||
OperandType.AttributePerPatch => GetAttributeName(operand.Value, config, perPatch: true),
|
||||
OperandType.Attribute => GetAttributeName(context, operand.Value, perPatch: false),
|
||||
OperandType.AttributePerPatch => GetAttributeName(context, operand.Value, perPatch: true),
|
||||
OperandType.Constant => NumberFormatter.FormatInt(operand.Value),
|
||||
OperandType.ConstantBuffer => GetConstantBufferName(operand, config),
|
||||
OperandType.ConstantBuffer => GetConstantBufferName(operand, context.Config),
|
||||
OperandType.LocalVariable => _locals[operand],
|
||||
OperandType.Undefined => DefaultNames.UndefinedName,
|
||||
_ => throw new ArgumentException($"Invalid operand type \"{operand.Type}\".")
|
||||
@@ -149,13 +153,15 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
||||
return GetVec4Indexed(GetUbName(stage, slotExpr) + $"[{offsetExpr} >> 2]", offsetExpr + " & 3", indexElement);
|
||||
}
|
||||
|
||||
public static string GetOutAttributeName(int value, ShaderConfig config, bool perPatch)
|
||||
public static string GetOutAttributeName(CodeGenContext context, int value, bool perPatch)
|
||||
{
|
||||
return GetAttributeName(value, config, perPatch, isOutAttr: true);
|
||||
return GetAttributeName(context, value, perPatch, isOutAttr: true);
|
||||
}
|
||||
|
||||
public static string GetAttributeName(int value, ShaderConfig config, bool perPatch, bool isOutAttr = false, string indexExpr = "0")
|
||||
public static string GetAttributeName(CodeGenContext context, int value, bool perPatch, bool isOutAttr = false, string indexExpr = "0")
|
||||
{
|
||||
ShaderConfig config = context.Config;
|
||||
|
||||
if ((value & AttributeConsts.LoadOutputMask) != 0)
|
||||
{
|
||||
isOutAttr = true;
|
||||
@@ -188,6 +194,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
||||
}
|
||||
else if (value >= AttributeConsts.UserAttributeBase && value < AttributeConsts.UserAttributeEnd)
|
||||
{
|
||||
int attrOffset = value;
|
||||
value -= AttributeConsts.UserAttributeBase;
|
||||
|
||||
string prefix = isOutAttr
|
||||
@@ -211,14 +218,15 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
||||
((config.LastInVertexPipeline && isOutAttr) ||
|
||||
(config.Stage == ShaderStage.Fragment && !isOutAttr)))
|
||||
{
|
||||
string name = $"{prefix}{(value >> 4)}_{swzMask}";
|
||||
int components = config.LastInPipeline ? context.Info.GetTransformFeedbackOutputComponents(attrOffset) : 1;
|
||||
string name = components > 1 ? $"{prefix}{(value >> 4)}" : $"{prefix}{(value >> 4)}_{swzMask}";
|
||||
|
||||
if (AttributeInfo.IsArrayAttributeGlsl(config.Stage, isOutAttr))
|
||||
{
|
||||
name += isOutAttr ? "[gl_InvocationID]" : $"[{indexExpr}]";
|
||||
}
|
||||
|
||||
return name;
|
||||
return components > 1 ? name + '.' + swzMask : name;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@@ -17,7 +17,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
||||
private const uint SpirvVersionRevision = 0;
|
||||
private const uint SpirvVersionPacked = (SpirvVersionMajor << 16) | (SpirvVersionMinor << 8) | SpirvVersionRevision;
|
||||
|
||||
private readonly StructuredProgramInfo _info;
|
||||
public StructuredProgramInfo Info { get; }
|
||||
|
||||
public ShaderConfig Config { get; }
|
||||
|
||||
@@ -85,7 +85,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
||||
GeneratorPool<Instruction> instPool,
|
||||
GeneratorPool<LiteralInteger> integerPool) : base(SpirvVersionPacked, instPool, integerPool)
|
||||
{
|
||||
_info = info;
|
||||
Info = info;
|
||||
Config = config;
|
||||
|
||||
if (config.Stage == ShaderStage.Geometry)
|
||||
@@ -317,6 +317,18 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
||||
{
|
||||
attrOffset = attr;
|
||||
type = elemType;
|
||||
|
||||
if (Config.LastInPipeline && isOutAttr)
|
||||
{
|
||||
int components = Info.GetTransformFeedbackOutputComponents(attr);
|
||||
|
||||
if (components > 1)
|
||||
{
|
||||
attrOffset &= ~0xf;
|
||||
type = AggregateType.Vector | AggregateType.FP32;
|
||||
attrInfo = new AttributeInfo(attrOffset, (attr - attrOffset) / 4, components, type, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ioVariable = isOutAttr ? Outputs[attrOffset] : Inputs[attrOffset];
|
||||
@@ -536,18 +548,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
||||
return _functions[funcIndex];
|
||||
}
|
||||
|
||||
public TransformFeedbackOutput GetTransformFeedbackOutput(int location, int component)
|
||||
{
|
||||
int index = (AttributeConsts.UserAttributeBase / 4) + location * 4 + component;
|
||||
return _info.TransformFeedbackOutputs[index];
|
||||
}
|
||||
|
||||
public TransformFeedbackOutput GetTransformFeedbackOutput(int location)
|
||||
{
|
||||
int index = location / 4;
|
||||
return _info.TransformFeedbackOutputs[index];
|
||||
}
|
||||
|
||||
public Instruction GetType(AggregateType type, int length = 1)
|
||||
{
|
||||
if (type.HasFlag(AggregateType.Array))
|
||||
|
@@ -440,12 +440,23 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
||||
{
|
||||
PixelImap iq = PixelImap.Unused;
|
||||
|
||||
if (context.Config.Stage == ShaderStage.Fragment &&
|
||||
attr >= AttributeConsts.UserAttributeBase &&
|
||||
attr < AttributeConsts.UserAttributeEnd)
|
||||
if (context.Config.Stage == ShaderStage.Fragment)
|
||||
{
|
||||
if (attr >= AttributeConsts.UserAttributeBase && attr < AttributeConsts.UserAttributeEnd)
|
||||
{
|
||||
iq = context.Config.ImapTypes[(attr - AttributeConsts.UserAttributeBase) / 16].GetFirstUsedType();
|
||||
}
|
||||
else
|
||||
{
|
||||
AttributeInfo attrInfo = AttributeInfo.From(context.Config, attr, isOutAttr: false);
|
||||
AggregateType elemType = attrInfo.Type & AggregateType.ElementTypeMask;
|
||||
|
||||
if (attrInfo.IsBuiltin && (elemType == AggregateType.S32 || elemType == AggregateType.U32))
|
||||
{
|
||||
iq = PixelImap.Constant;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DeclareInputOrOutput(context, attr, perPatch, isOutAttr: false, iq);
|
||||
}
|
||||
@@ -516,7 +527,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
||||
((isOutAttr && context.Config.LastInVertexPipeline) ||
|
||||
(!isOutAttr && context.Config.Stage == ShaderStage.Fragment)))
|
||||
{
|
||||
DeclareInputOrOutput(context, attr, (attr >> 2) & 3, isOutAttr, iq);
|
||||
DeclareTransformFeedbackInputOrOutput(context, attr, isOutAttr, iq);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -572,7 +583,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
||||
|
||||
if (context.Config.TransformFeedbackEnabled && context.Config.LastInVertexPipeline && isOutAttr)
|
||||
{
|
||||
var tfOutput = context.GetTransformFeedbackOutput(attrInfo.BaseValue);
|
||||
var tfOutput = context.Info.GetTransformFeedbackOutput(attrInfo.BaseValue);
|
||||
if (tfOutput.Valid)
|
||||
{
|
||||
context.Decorate(spvVar, Decoration.XfbBuffer, (LiteralInteger)tfOutput.Buffer);
|
||||
@@ -595,15 +606,22 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
||||
|
||||
context.Decorate(spvVar, Decoration.Location, (LiteralInteger)location);
|
||||
|
||||
if (!isOutAttr)
|
||||
{
|
||||
if (!perPatch &&
|
||||
if (!isOutAttr &&
|
||||
!perPatch &&
|
||||
(context.Config.PassthroughAttributes & (1 << location)) != 0 &&
|
||||
context.Config.GpuAccessor.QueryHostSupportsGeometryShaderPassthrough())
|
||||
{
|
||||
context.Decorate(spvVar, Decoration.PassthroughNV);
|
||||
}
|
||||
}
|
||||
else if (attr >= AttributeConsts.FragmentOutputColorBase && attr < AttributeConsts.FragmentOutputColorEnd)
|
||||
{
|
||||
int location = (attr - AttributeConsts.FragmentOutputColorBase) / 16;
|
||||
context.Decorate(spvVar, Decoration.Location, (LiteralInteger)location);
|
||||
}
|
||||
|
||||
if (!isOutAttr)
|
||||
{
|
||||
switch (iq)
|
||||
{
|
||||
case PixelImap.Constant:
|
||||
@@ -614,29 +632,40 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (attr >= AttributeConsts.FragmentOutputColorBase && attr < AttributeConsts.FragmentOutputColorEnd)
|
||||
{
|
||||
int location = (attr - AttributeConsts.FragmentOutputColorBase) / 16;
|
||||
context.Decorate(spvVar, Decoration.Location, (LiteralInteger)location);
|
||||
}
|
||||
|
||||
context.AddGlobalVariable(spvVar);
|
||||
dict.Add(attrInfo.BaseValue, spvVar);
|
||||
}
|
||||
|
||||
private static void DeclareInputOrOutput(CodeGenContext context, int attr, int component, bool isOutAttr, PixelImap iq = PixelImap.Unused)
|
||||
private static void DeclareTransformFeedbackInputOrOutput(CodeGenContext context, int attr, bool isOutAttr, PixelImap iq = PixelImap.Unused)
|
||||
{
|
||||
var dict = isOutAttr ? context.Outputs : context.Inputs;
|
||||
var attrInfo = AttributeInfo.From(context.Config, attr, isOutAttr);
|
||||
|
||||
bool hasComponent = true;
|
||||
int component = (attr >> 2) & 3;
|
||||
int components = 1;
|
||||
var type = attrInfo.Type & AggregateType.ElementTypeMask;
|
||||
|
||||
if (context.Config.LastInPipeline && isOutAttr)
|
||||
{
|
||||
components = context.Info.GetTransformFeedbackOutputComponents(attr);
|
||||
|
||||
if (components > 1)
|
||||
{
|
||||
attr &= ~0xf;
|
||||
type = AggregateType.Vector | AggregateType.FP32;
|
||||
hasComponent = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (dict.ContainsKey(attr))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var storageClass = isOutAttr ? StorageClass.Output : StorageClass.Input;
|
||||
var attrType = context.GetType(attrInfo.Type & AggregateType.ElementTypeMask);
|
||||
var attrType = context.GetType(type, components);
|
||||
|
||||
if (AttributeInfo.IsArrayAttributeSpirv(context.Config.Stage, isOutAttr) && (!attrInfo.IsBuiltin || AttributeInfo.IsArrayBuiltIn(attr)))
|
||||
{
|
||||
@@ -656,11 +685,15 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
||||
int location = (attr - AttributeConsts.UserAttributeBase) / 16;
|
||||
|
||||
context.Decorate(spvVar, Decoration.Location, (LiteralInteger)location);
|
||||
|
||||
if (hasComponent)
|
||||
{
|
||||
context.Decorate(spvVar, Decoration.Component, (LiteralInteger)component);
|
||||
}
|
||||
|
||||
if (isOutAttr)
|
||||
{
|
||||
var tfOutput = context.GetTransformFeedbackOutput(location, component);
|
||||
var tfOutput = context.Info.GetTransformFeedbackOutput(attr);
|
||||
if (tfOutput.Valid)
|
||||
{
|
||||
context.Decorate(spvVar, Decoration.XfbBuffer, (LiteralInteger)tfOutput.Buffer);
|
||||
@@ -704,8 +737,12 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
||||
AttributeConsts.ClipDistance0 => BuiltIn.ClipDistance,
|
||||
AttributeConsts.PointCoordX => BuiltIn.PointCoord,
|
||||
AttributeConsts.TessCoordX => BuiltIn.TessCoord,
|
||||
AttributeConsts.InstanceId => BuiltIn.InstanceId, // FIXME: Invalid
|
||||
AttributeConsts.VertexId => BuiltIn.VertexId, // FIXME: Invalid
|
||||
AttributeConsts.InstanceId => BuiltIn.InstanceId,
|
||||
AttributeConsts.VertexId => BuiltIn.VertexId,
|
||||
AttributeConsts.BaseInstance => BuiltIn.BaseInstance,
|
||||
AttributeConsts.BaseVertex => BuiltIn.BaseVertex,
|
||||
AttributeConsts.InstanceIndex => BuiltIn.InstanceIndex,
|
||||
AttributeConsts.VertexIndex => BuiltIn.VertexIndex,
|
||||
AttributeConsts.FrontFacing => BuiltIn.FrontFacing,
|
||||
AttributeConsts.FragmentOutputDepth => BuiltIn.FragDepth,
|
||||
AttributeConsts.ThreadKill => BuiltIn.HelperInvocation,
|
||||
|
@@ -62,11 +62,19 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
||||
context.AddCapability(Capability.TransformFeedback);
|
||||
}
|
||||
|
||||
if (config.Stage == ShaderStage.Fragment && context.Config.GpuAccessor.QueryHostSupportsFragmentShaderInterlock())
|
||||
if (config.Stage == ShaderStage.Fragment)
|
||||
{
|
||||
if (context.Info.Inputs.Contains(AttributeConsts.Layer))
|
||||
{
|
||||
context.AddCapability(Capability.Geometry);
|
||||
}
|
||||
|
||||
if (context.Config.GpuAccessor.QueryHostSupportsFragmentShaderInterlock())
|
||||
{
|
||||
context.AddCapability(Capability.FragmentShaderPixelInterlockEXT);
|
||||
context.AddExtension("SPV_EXT_fragment_shader_interlock");
|
||||
}
|
||||
}
|
||||
else if (config.Stage == ShaderStage.Geometry)
|
||||
{
|
||||
context.AddCapability(Capability.Geometry);
|
||||
|
@@ -51,7 +51,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||
offset |= AttributeConsts.LoadOutputMask;
|
||||
}
|
||||
|
||||
Operand src = op.P ? AttributePerPatch(offset) : Attribute(offset);
|
||||
Operand src = op.P ? AttributePerPatch(offset) : CreateInputAttribute(context, offset);
|
||||
|
||||
context.Copy(Register(rd), src);
|
||||
}
|
||||
@@ -312,5 +312,22 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||
|
||||
return attr;
|
||||
}
|
||||
|
||||
private static Operand CreateInputAttribute(EmitterContext context, int attr)
|
||||
{
|
||||
if (context.Config.Options.TargetApi == TargetApi.Vulkan)
|
||||
{
|
||||
if (attr == AttributeConsts.InstanceId)
|
||||
{
|
||||
return context.ISubtract(Attribute(AttributeConsts.InstanceIndex), Attribute(AttributeConsts.BaseInstance));
|
||||
}
|
||||
else if (attr == AttributeConsts.VertexId)
|
||||
{
|
||||
return Attribute(AttributeConsts.VertexIndex);
|
||||
}
|
||||
}
|
||||
|
||||
return Attribute(attr);
|
||||
}
|
||||
}
|
||||
}
|
@@ -71,12 +71,12 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
||||
var locations = config.GpuAccessor.QueryTransformFeedbackVaryingLocations(tfbIndex);
|
||||
var stride = config.GpuAccessor.QueryTransformFeedbackStride(tfbIndex);
|
||||
|
||||
for (int j = 0; j < locations.Length; j++)
|
||||
for (int i = 0; i < locations.Length; i++)
|
||||
{
|
||||
byte location = locations[j];
|
||||
byte location = locations[i];
|
||||
if (location < 0xc0)
|
||||
{
|
||||
context.Info.TransformFeedbackOutputs[location] = new TransformFeedbackOutput(tfbIndex, j * 4, stride);
|
||||
context.Info.TransformFeedbackOutputs[location] = new TransformFeedbackOutput(tfbIndex, i * 4, stride);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -42,5 +42,40 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
||||
|
||||
TransformFeedbackOutputs = new TransformFeedbackOutput[0xc0];
|
||||
}
|
||||
|
||||
public TransformFeedbackOutput GetTransformFeedbackOutput(int attr)
|
||||
{
|
||||
int index = attr / 4;
|
||||
return TransformFeedbackOutputs[index];
|
||||
}
|
||||
|
||||
public int GetTransformFeedbackOutputComponents(int attr)
|
||||
{
|
||||
int index = attr / 4;
|
||||
int baseIndex = index & ~3;
|
||||
|
||||
int count = 1;
|
||||
|
||||
for (; count < 4; count++)
|
||||
{
|
||||
ref var prev = ref TransformFeedbackOutputs[baseIndex + count - 1];
|
||||
ref var curr = ref TransformFeedbackOutputs[baseIndex + count];
|
||||
|
||||
int prevOffset = prev.Offset;
|
||||
int currOffset = curr.Offset;
|
||||
|
||||
if (!prev.Valid || !curr.Valid || prevOffset + 4 != currOffset)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (baseIndex + count <= index)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
}
|
||||
}
|
@@ -95,5 +95,10 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||
public const int LtMask = 0x2000040;
|
||||
|
||||
public const int ThreadKill = 0x2000044;
|
||||
|
||||
public const int BaseInstance = 0x2000050;
|
||||
public const int BaseVertex = 0x2000054;
|
||||
public const int InstanceIndex = 0x2000058;
|
||||
public const int VertexIndex = 0x200005c;
|
||||
}
|
||||
}
|
@@ -27,6 +27,10 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||
{ AttributeConsts.TessCoordY, new AttributeInfo(AttributeConsts.TessCoordX, 1, 3, AggregateType.Vector | AggregateType.FP32) },
|
||||
{ AttributeConsts.InstanceId, new AttributeInfo(AttributeConsts.InstanceId, 0, 1, AggregateType.S32) },
|
||||
{ AttributeConsts.VertexId, new AttributeInfo(AttributeConsts.VertexId, 0, 1, AggregateType.S32) },
|
||||
{ AttributeConsts.BaseInstance, new AttributeInfo(AttributeConsts.BaseInstance, 0, 1, AggregateType.S32) },
|
||||
{ AttributeConsts.BaseVertex, new AttributeInfo(AttributeConsts.BaseVertex, 0, 1, AggregateType.S32) },
|
||||
{ AttributeConsts.InstanceIndex, new AttributeInfo(AttributeConsts.InstanceIndex, 0, 1, AggregateType.S32) },
|
||||
{ AttributeConsts.VertexIndex, new AttributeInfo(AttributeConsts.VertexIndex, 0, 1, AggregateType.S32) },
|
||||
{ AttributeConsts.FrontFacing, new AttributeInfo(AttributeConsts.FrontFacing, 0, 1, AggregateType.Bool) },
|
||||
|
||||
// Special.
|
||||
|
@@ -17,6 +17,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||
public ShaderStage Stage { get; }
|
||||
|
||||
public bool GpPassthrough { get; }
|
||||
public bool LastInPipeline { get; private set; }
|
||||
public bool LastInVertexPipeline { get; private set; }
|
||||
|
||||
public int ThreadsPerInputPrimitive { get; }
|
||||
@@ -143,6 +144,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||
OmapSampleMask = header.OmapSampleMask;
|
||||
OmapDepth = header.OmapDepth;
|
||||
TransformFeedbackEnabled = gpuAccessor.QueryTransformFeedbackEnabled();
|
||||
LastInPipeline = true;
|
||||
LastInVertexPipeline = header.Stage < ShaderStage.Fragment;
|
||||
}
|
||||
|
||||
@@ -306,6 +308,8 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||
config._perPatchAttributeLocations = locationsMap;
|
||||
}
|
||||
|
||||
LastInPipeline = false;
|
||||
|
||||
// We don't consider geometry shaders using the geometry shader passthrough feature
|
||||
// as being the last because when this feature is used, it can't actually modify any of the outputs,
|
||||
// so the stage that comes before it is the last one that can do modifications.
|
||||
|
@@ -138,11 +138,6 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
public void SetImage(int binding, ITexture image, GAL.Format imageFormat)
|
||||
{
|
||||
if (image == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (image is TextureBuffer imageBuffer)
|
||||
{
|
||||
_bufferImageRefs[binding] = imageBuffer;
|
||||
@@ -152,6 +147,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
_imageRefs[binding] = view.GetView(imageFormat).GetIdentityImageView();
|
||||
}
|
||||
else
|
||||
{
|
||||
_imageRefs[binding] = null;
|
||||
_bufferImageRefs[binding] = null;
|
||||
_bufferImageFormats[binding] = default;
|
||||
}
|
||||
|
||||
SignalDirty(DirtyFlags.Image);
|
||||
}
|
||||
@@ -215,24 +216,23 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
public void SetTextureAndSampler(CommandBufferScoped cbs, ShaderStage stage, int binding, ITexture texture, ISampler sampler)
|
||||
{
|
||||
if (texture == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (texture is TextureBuffer textureBuffer)
|
||||
{
|
||||
_bufferTextureRefs[binding] = textureBuffer;
|
||||
}
|
||||
else
|
||||
else if (texture is TextureView view)
|
||||
{
|
||||
TextureView view = (TextureView)texture;
|
||||
|
||||
view.Storage.InsertBarrier(cbs, AccessFlags.AccessShaderReadBit, stage.ConvertToPipelineStageFlags());
|
||||
|
||||
_textureRefs[binding] = view.GetImageView();
|
||||
_samplerRefs[binding] = ((SamplerHolder)sampler)?.GetSampler();
|
||||
}
|
||||
else
|
||||
{
|
||||
_textureRefs[binding] = null;
|
||||
_samplerRefs[binding] = null;
|
||||
_bufferTextureRefs[binding] = null;
|
||||
}
|
||||
|
||||
SignalDirty(DirtyFlags.Texture);
|
||||
}
|
||||
|
@@ -81,232 +81,208 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
set => Internal.Id5 = (Internal.Id5 & 0xFFFFFFFF) | ((ulong)(uint)BitConverter.SingleToInt32Bits(value) << 32);
|
||||
}
|
||||
|
||||
public float BlendConstantR
|
||||
{
|
||||
get => BitConverter.Int32BitsToSingle((int)((Internal.Id6 >> 0) & 0xFFFFFFFF));
|
||||
set => Internal.Id6 = (Internal.Id6 & 0xFFFFFFFF00000000) | ((ulong)(uint)BitConverter.SingleToInt32Bits(value) << 0);
|
||||
}
|
||||
|
||||
public float BlendConstantG
|
||||
{
|
||||
get => BitConverter.Int32BitsToSingle((int)((Internal.Id6 >> 32) & 0xFFFFFFFF));
|
||||
set => Internal.Id6 = (Internal.Id6 & 0xFFFFFFFF) | ((ulong)(uint)BitConverter.SingleToInt32Bits(value) << 32);
|
||||
}
|
||||
|
||||
public float BlendConstantB
|
||||
{
|
||||
get => BitConverter.Int32BitsToSingle((int)((Internal.Id7 >> 0) & 0xFFFFFFFF));
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFFF00000000) | ((ulong)(uint)BitConverter.SingleToInt32Bits(value) << 0);
|
||||
}
|
||||
|
||||
public float BlendConstantA
|
||||
{
|
||||
get => BitConverter.Int32BitsToSingle((int)((Internal.Id7 >> 32) & 0xFFFFFFFF));
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFFF) | ((ulong)(uint)BitConverter.SingleToInt32Bits(value) << 32);
|
||||
}
|
||||
|
||||
public PolygonMode PolygonMode
|
||||
{
|
||||
get => (PolygonMode)((Internal.Id8 >> 0) & 0x3FFFFFFF);
|
||||
set => Internal.Id8 = (Internal.Id8 & 0xFFFFFFFFC0000000) | ((ulong)value << 0);
|
||||
get => (PolygonMode)((Internal.Id6 >> 0) & 0x3FFFFFFF);
|
||||
set => Internal.Id6 = (Internal.Id6 & 0xFFFFFFFFC0000000) | ((ulong)value << 0);
|
||||
}
|
||||
|
||||
public uint StagesCount
|
||||
{
|
||||
get => (byte)((Internal.Id8 >> 30) & 0xFF);
|
||||
set => Internal.Id8 = (Internal.Id8 & 0xFFFFFFC03FFFFFFF) | ((ulong)value << 30);
|
||||
get => (byte)((Internal.Id6 >> 30) & 0xFF);
|
||||
set => Internal.Id6 = (Internal.Id6 & 0xFFFFFFC03FFFFFFF) | ((ulong)value << 30);
|
||||
}
|
||||
|
||||
public uint VertexAttributeDescriptionsCount
|
||||
{
|
||||
get => (byte)((Internal.Id8 >> 38) & 0xFF);
|
||||
set => Internal.Id8 = (Internal.Id8 & 0xFFFFC03FFFFFFFFF) | ((ulong)value << 38);
|
||||
get => (byte)((Internal.Id6 >> 38) & 0xFF);
|
||||
set => Internal.Id6 = (Internal.Id6 & 0xFFFFC03FFFFFFFFF) | ((ulong)value << 38);
|
||||
}
|
||||
|
||||
public uint VertexBindingDescriptionsCount
|
||||
{
|
||||
get => (byte)((Internal.Id8 >> 46) & 0xFF);
|
||||
set => Internal.Id8 = (Internal.Id8 & 0xFFC03FFFFFFFFFFF) | ((ulong)value << 46);
|
||||
get => (byte)((Internal.Id6 >> 46) & 0xFF);
|
||||
set => Internal.Id6 = (Internal.Id6 & 0xFFC03FFFFFFFFFFF) | ((ulong)value << 46);
|
||||
}
|
||||
|
||||
public uint ViewportsCount
|
||||
{
|
||||
get => (byte)((Internal.Id8 >> 54) & 0xFF);
|
||||
set => Internal.Id8 = (Internal.Id8 & 0xC03FFFFFFFFFFFFF) | ((ulong)value << 54);
|
||||
get => (byte)((Internal.Id6 >> 54) & 0xFF);
|
||||
set => Internal.Id6 = (Internal.Id6 & 0xC03FFFFFFFFFFFFF) | ((ulong)value << 54);
|
||||
}
|
||||
|
||||
public uint ScissorsCount
|
||||
{
|
||||
get => (byte)((Internal.Id9 >> 0) & 0xFF);
|
||||
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFFFFF00) | ((ulong)value << 0);
|
||||
get => (byte)((Internal.Id7 >> 0) & 0xFF);
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFFFFFFFFF00) | ((ulong)value << 0);
|
||||
}
|
||||
|
||||
public uint ColorBlendAttachmentStateCount
|
||||
{
|
||||
get => (byte)((Internal.Id9 >> 8) & 0xFF);
|
||||
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFFF00FF) | ((ulong)value << 8);
|
||||
get => (byte)((Internal.Id7 >> 8) & 0xFF);
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFFFFFFF00FF) | ((ulong)value << 8);
|
||||
}
|
||||
|
||||
public PrimitiveTopology Topology
|
||||
{
|
||||
get => (PrimitiveTopology)((Internal.Id9 >> 16) & 0xF);
|
||||
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFF0FFFF) | ((ulong)value << 16);
|
||||
get => (PrimitiveTopology)((Internal.Id7 >> 16) & 0xF);
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFFFFFF0FFFF) | ((ulong)value << 16);
|
||||
}
|
||||
|
||||
public LogicOp LogicOp
|
||||
{
|
||||
get => (LogicOp)((Internal.Id9 >> 20) & 0xF);
|
||||
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFF0FFFFF) | ((ulong)value << 20);
|
||||
get => (LogicOp)((Internal.Id7 >> 20) & 0xF);
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFFFFF0FFFFF) | ((ulong)value << 20);
|
||||
}
|
||||
|
||||
public CompareOp DepthCompareOp
|
||||
{
|
||||
get => (CompareOp)((Internal.Id9 >> 24) & 0x7);
|
||||
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFF8FFFFFF) | ((ulong)value << 24);
|
||||
get => (CompareOp)((Internal.Id7 >> 24) & 0x7);
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFFFF8FFFFFF) | ((ulong)value << 24);
|
||||
}
|
||||
|
||||
public StencilOp StencilFrontFailOp
|
||||
{
|
||||
get => (StencilOp)((Internal.Id9 >> 27) & 0x7);
|
||||
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFC7FFFFFF) | ((ulong)value << 27);
|
||||
get => (StencilOp)((Internal.Id7 >> 27) & 0x7);
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFFFC7FFFFFF) | ((ulong)value << 27);
|
||||
}
|
||||
|
||||
public StencilOp StencilFrontPassOp
|
||||
{
|
||||
get => (StencilOp)((Internal.Id9 >> 30) & 0x7);
|
||||
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFE3FFFFFFF) | ((ulong)value << 30);
|
||||
get => (StencilOp)((Internal.Id7 >> 30) & 0x7);
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFFE3FFFFFFF) | ((ulong)value << 30);
|
||||
}
|
||||
|
||||
public StencilOp StencilFrontDepthFailOp
|
||||
{
|
||||
get => (StencilOp)((Internal.Id9 >> 33) & 0x7);
|
||||
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFF1FFFFFFFF) | ((ulong)value << 33);
|
||||
get => (StencilOp)((Internal.Id7 >> 33) & 0x7);
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFF1FFFFFFFF) | ((ulong)value << 33);
|
||||
}
|
||||
|
||||
public CompareOp StencilFrontCompareOp
|
||||
{
|
||||
get => (CompareOp)((Internal.Id9 >> 36) & 0x7);
|
||||
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFF8FFFFFFFFF) | ((ulong)value << 36);
|
||||
get => (CompareOp)((Internal.Id7 >> 36) & 0x7);
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFF8FFFFFFFFF) | ((ulong)value << 36);
|
||||
}
|
||||
|
||||
public StencilOp StencilBackFailOp
|
||||
{
|
||||
get => (StencilOp)((Internal.Id9 >> 39) & 0x7);
|
||||
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFC7FFFFFFFFF) | ((ulong)value << 39);
|
||||
get => (StencilOp)((Internal.Id7 >> 39) & 0x7);
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFC7FFFFFFFFF) | ((ulong)value << 39);
|
||||
}
|
||||
|
||||
public StencilOp StencilBackPassOp
|
||||
{
|
||||
get => (StencilOp)((Internal.Id9 >> 42) & 0x7);
|
||||
set => Internal.Id9 = (Internal.Id9 & 0xFFFFE3FFFFFFFFFF) | ((ulong)value << 42);
|
||||
get => (StencilOp)((Internal.Id7 >> 42) & 0x7);
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFFE3FFFFFFFFFF) | ((ulong)value << 42);
|
||||
}
|
||||
|
||||
public StencilOp StencilBackDepthFailOp
|
||||
{
|
||||
get => (StencilOp)((Internal.Id9 >> 45) & 0x7);
|
||||
set => Internal.Id9 = (Internal.Id9 & 0xFFFF1FFFFFFFFFFF) | ((ulong)value << 45);
|
||||
get => (StencilOp)((Internal.Id7 >> 45) & 0x7);
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFF1FFFFFFFFFFF) | ((ulong)value << 45);
|
||||
}
|
||||
|
||||
public CompareOp StencilBackCompareOp
|
||||
{
|
||||
get => (CompareOp)((Internal.Id9 >> 48) & 0x7);
|
||||
set => Internal.Id9 = (Internal.Id9 & 0xFFF8FFFFFFFFFFFF) | ((ulong)value << 48);
|
||||
get => (CompareOp)((Internal.Id7 >> 48) & 0x7);
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFFF8FFFFFFFFFFFF) | ((ulong)value << 48);
|
||||
}
|
||||
|
||||
public CullModeFlags CullMode
|
||||
{
|
||||
get => (CullModeFlags)((Internal.Id9 >> 51) & 0x3);
|
||||
set => Internal.Id9 = (Internal.Id9 & 0xFFE7FFFFFFFFFFFF) | ((ulong)value << 51);
|
||||
get => (CullModeFlags)((Internal.Id7 >> 51) & 0x3);
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFFE7FFFFFFFFFFFF) | ((ulong)value << 51);
|
||||
}
|
||||
|
||||
public bool PrimitiveRestartEnable
|
||||
{
|
||||
get => ((Internal.Id9 >> 53) & 0x1) != 0UL;
|
||||
set => Internal.Id9 = (Internal.Id9 & 0xFFDFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 53);
|
||||
get => ((Internal.Id7 >> 53) & 0x1) != 0UL;
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFFDFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 53);
|
||||
}
|
||||
|
||||
public bool DepthClampEnable
|
||||
{
|
||||
get => ((Internal.Id9 >> 54) & 0x1) != 0UL;
|
||||
set => Internal.Id9 = (Internal.Id9 & 0xFFBFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 54);
|
||||
get => ((Internal.Id7 >> 54) & 0x1) != 0UL;
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFFBFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 54);
|
||||
}
|
||||
|
||||
public bool RasterizerDiscardEnable
|
||||
{
|
||||
get => ((Internal.Id9 >> 55) & 0x1) != 0UL;
|
||||
set => Internal.Id9 = (Internal.Id9 & 0xFF7FFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 55);
|
||||
get => ((Internal.Id7 >> 55) & 0x1) != 0UL;
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFF7FFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 55);
|
||||
}
|
||||
|
||||
public FrontFace FrontFace
|
||||
{
|
||||
get => (FrontFace)((Internal.Id9 >> 56) & 0x1);
|
||||
set => Internal.Id9 = (Internal.Id9 & 0xFEFFFFFFFFFFFFFF) | ((ulong)value << 56);
|
||||
get => (FrontFace)((Internal.Id7 >> 56) & 0x1);
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFEFFFFFFFFFFFFFF) | ((ulong)value << 56);
|
||||
}
|
||||
|
||||
public bool DepthBiasEnable
|
||||
{
|
||||
get => ((Internal.Id9 >> 57) & 0x1) != 0UL;
|
||||
set => Internal.Id9 = (Internal.Id9 & 0xFDFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 57);
|
||||
get => ((Internal.Id7 >> 57) & 0x1) != 0UL;
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFDFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 57);
|
||||
}
|
||||
|
||||
public bool DepthTestEnable
|
||||
{
|
||||
get => ((Internal.Id9 >> 58) & 0x1) != 0UL;
|
||||
set => Internal.Id9 = (Internal.Id9 & 0xFBFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 58);
|
||||
get => ((Internal.Id7 >> 58) & 0x1) != 0UL;
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFBFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 58);
|
||||
}
|
||||
|
||||
public bool DepthWriteEnable
|
||||
{
|
||||
get => ((Internal.Id9 >> 59) & 0x1) != 0UL;
|
||||
set => Internal.Id9 = (Internal.Id9 & 0xF7FFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 59);
|
||||
get => ((Internal.Id7 >> 59) & 0x1) != 0UL;
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xF7FFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 59);
|
||||
}
|
||||
|
||||
public bool DepthBoundsTestEnable
|
||||
{
|
||||
get => ((Internal.Id9 >> 60) & 0x1) != 0UL;
|
||||
set => Internal.Id9 = (Internal.Id9 & 0xEFFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 60);
|
||||
get => ((Internal.Id7 >> 60) & 0x1) != 0UL;
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xEFFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 60);
|
||||
}
|
||||
|
||||
public bool StencilTestEnable
|
||||
{
|
||||
get => ((Internal.Id9 >> 61) & 0x1) != 0UL;
|
||||
set => Internal.Id9 = (Internal.Id9 & 0xDFFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 61);
|
||||
get => ((Internal.Id7 >> 61) & 0x1) != 0UL;
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xDFFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 61);
|
||||
}
|
||||
|
||||
public bool LogicOpEnable
|
||||
{
|
||||
get => ((Internal.Id9 >> 62) & 0x1) != 0UL;
|
||||
set => Internal.Id9 = (Internal.Id9 & 0xBFFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 62);
|
||||
get => ((Internal.Id7 >> 62) & 0x1) != 0UL;
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xBFFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 62);
|
||||
}
|
||||
|
||||
public bool HasDepthStencil
|
||||
{
|
||||
get => ((Internal.Id9 >> 63) & 0x1) != 0UL;
|
||||
set => Internal.Id9 = (Internal.Id9 & 0x7FFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 63);
|
||||
get => ((Internal.Id7 >> 63) & 0x1) != 0UL;
|
||||
set => Internal.Id7 = (Internal.Id7 & 0x7FFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 63);
|
||||
}
|
||||
|
||||
public uint PatchControlPoints
|
||||
{
|
||||
get => (uint)((Internal.Id10 >> 0) & 0xFFFFFFFF);
|
||||
set => Internal.Id10 = (Internal.Id10 & 0xFFFFFFFF00000000) | ((ulong)value << 0);
|
||||
get => (uint)((Internal.Id8 >> 0) & 0xFFFFFFFF);
|
||||
set => Internal.Id8 = (Internal.Id8 & 0xFFFFFFFF00000000) | ((ulong)value << 0);
|
||||
}
|
||||
|
||||
public uint SamplesCount
|
||||
{
|
||||
get => (uint)((Internal.Id10 >> 32) & 0xFFFFFFFF);
|
||||
set => Internal.Id10 = (Internal.Id10 & 0xFFFFFFFF) | ((ulong)value << 32);
|
||||
get => (uint)((Internal.Id8 >> 32) & 0xFFFFFFFF);
|
||||
set => Internal.Id8 = (Internal.Id8 & 0xFFFFFFFF) | ((ulong)value << 32);
|
||||
}
|
||||
|
||||
public bool AlphaToCoverageEnable
|
||||
{
|
||||
get => ((Internal.Id11 >> 0) & 0x1) != 0UL;
|
||||
set => Internal.Id11 = (Internal.Id11 & 0xFFFFFFFFFFFFFFFE) | ((value ? 1UL : 0UL) << 0);
|
||||
get => ((Internal.Id9 >> 0) & 0x1) != 0UL;
|
||||
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFFFFFFE) | ((value ? 1UL : 0UL) << 0);
|
||||
}
|
||||
|
||||
public bool AlphaToOneEnable
|
||||
{
|
||||
get => ((Internal.Id11 >> 1) & 0x1) != 0UL;
|
||||
set => Internal.Id11 = (Internal.Id11 & 0xFFFFFFFFFFFFFFFD) | ((value ? 1UL : 0UL) << 1);
|
||||
get => ((Internal.Id9 >> 1) & 0x1) != 0UL;
|
||||
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFFFFFFD) | ((value ? 1UL : 0UL) << 1);
|
||||
}
|
||||
|
||||
public NativeArray<PipelineShaderStageCreateInfo> Stages;
|
||||
@@ -510,11 +486,6 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
PAttachments = pColorBlendAttachmentState
|
||||
};
|
||||
|
||||
colorBlendState.BlendConstants[0] = BlendConstantR;
|
||||
colorBlendState.BlendConstants[1] = BlendConstantG;
|
||||
colorBlendState.BlendConstants[2] = BlendConstantB;
|
||||
colorBlendState.BlendConstants[3] = BlendConstantA;
|
||||
|
||||
bool supportsExtDynamicState = gd.Capabilities.SupportsExtendedDynamicState;
|
||||
int dynamicStatesCount = supportsExtDynamicState ? 9 : 8;
|
||||
|
||||
|
@@ -21,15 +21,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
public ulong Id8;
|
||||
public ulong Id9;
|
||||
public ulong Id10;
|
||||
public ulong Id11;
|
||||
|
||||
private uint VertexAttributeDescriptionsCount => (byte)((Id8 >> 38) & 0xFF);
|
||||
private uint VertexBindingDescriptionsCount => (byte)((Id8 >> 46) & 0xFF);
|
||||
private uint ViewportsCount => (byte)((Id8 >> 54) & 0xFF);
|
||||
private uint ScissorsCount => (byte)((Id9 >> 0) & 0xFF);
|
||||
private uint ColorBlendAttachmentStateCount => (byte)((Id9 >> 8) & 0xFF);
|
||||
private bool HasDepthStencil => ((Id9 >> 63) & 0x1) != 0UL;
|
||||
private uint VertexAttributeDescriptionsCount => (byte)((Id6 >> 38) & 0xFF);
|
||||
private uint VertexBindingDescriptionsCount => (byte)((Id6 >> 46) & 0xFF);
|
||||
private uint ViewportsCount => (byte)((Id6 >> 54) & 0xFF);
|
||||
private uint ScissorsCount => (byte)((Id7 >> 0) & 0xFF);
|
||||
private uint ColorBlendAttachmentStateCount => (byte)((Id7 >> 8) & 0xFF);
|
||||
private bool HasDepthStencil => ((Id7 >> 63) & 0x1) != 0UL;
|
||||
|
||||
public Array32<VertexInputAttributeDescription> VertexAttributeDescriptions;
|
||||
public Array33<VertexInputBindingDescription> VertexBindingDescriptions;
|
||||
@@ -47,7 +45,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
if (!Unsafe.As<ulong, Vector256<byte>>(ref Id0).Equals(Unsafe.As<ulong, Vector256<byte>>(ref other.Id0)) ||
|
||||
!Unsafe.As<ulong, Vector256<byte>>(ref Id4).Equals(Unsafe.As<ulong, Vector256<byte>>(ref other.Id4)) ||
|
||||
!Unsafe.As<ulong, Vector256<byte>>(ref Id8).Equals(Unsafe.As<ulong, Vector256<byte>>(ref other.Id8)))
|
||||
!Unsafe.As<ulong, Vector128<byte>>(ref Id8).Equals(Unsafe.As<ulong, Vector128<byte>>(ref other.Id8)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -91,9 +89,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
Id6 * 23 ^
|
||||
Id7 * 23 ^
|
||||
Id8 * 23 ^
|
||||
Id9 * 23 ^
|
||||
Id10 * 23 ^
|
||||
Id11 * 23;
|
||||
Id9 * 23;
|
||||
|
||||
for (int i = 0; i < (int)VertexAttributeDescriptionsCount; i++)
|
||||
{
|
||||
|
81
Ryujinx.Ui.Common/Helper/CommandLineState.cs
Normal file
81
Ryujinx.Ui.Common/Helper/CommandLineState.cs
Normal file
@@ -0,0 +1,81 @@
|
||||
using Ryujinx.Common.Logging;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Ryujinx.Ui.Common.Helper
|
||||
{
|
||||
public static class CommandLineState
|
||||
{
|
||||
public static string[] Arguments { get; private set; }
|
||||
|
||||
public static string OverrideGraphicsBackend { get; private set; }
|
||||
public static string BaseDirPathArg { get; private set; }
|
||||
public static string Profile { get; private set; }
|
||||
public static string LaunchPathArg { get; private set; }
|
||||
public static bool StartFullscreenArg { get; private set; }
|
||||
|
||||
public static void ParseArguments(string[] args)
|
||||
{
|
||||
List<string> arguments = new();
|
||||
|
||||
// Parse Arguments.
|
||||
for (int i = 0; i < args.Length; ++i)
|
||||
{
|
||||
string arg = args[i];
|
||||
|
||||
switch (arg)
|
||||
{
|
||||
case "-r":
|
||||
case "--root-data-dir":
|
||||
if (i + 1 >= args.Length)
|
||||
{
|
||||
Logger.Error?.Print(LogClass.Application, $"Invalid option '{arg}'");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
BaseDirPathArg = args[++i];
|
||||
|
||||
arguments.Add(arg);
|
||||
arguments.Add(args[i]);
|
||||
break;
|
||||
case "-p":
|
||||
case "--profile":
|
||||
if (i + 1 >= args.Length)
|
||||
{
|
||||
Logger.Error?.Print(LogClass.Application, $"Invalid option '{arg}'");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
Profile = args[++i];
|
||||
|
||||
arguments.Add(arg);
|
||||
arguments.Add(args[i]);
|
||||
break;
|
||||
case "-f":
|
||||
case "--fullscreen":
|
||||
StartFullscreenArg = true;
|
||||
|
||||
arguments.Add(arg);
|
||||
break;
|
||||
case "-g":
|
||||
case "--graphics-backend":
|
||||
if (i + 1 >= args.Length)
|
||||
{
|
||||
Logger.Error?.Print(LogClass.Application, $"Invalid option '{arg}'");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
OverrideGraphicsBackend = args[++i];
|
||||
break;
|
||||
default:
|
||||
LaunchPathArg = arg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Arguments = arguments.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
@@ -2,9 +2,9 @@ using Gdk;
|
||||
using Gtk;
|
||||
using Ryujinx.Ui;
|
||||
using Ryujinx.Ui.Common.Configuration;
|
||||
using Ryujinx.Ui.Common.Helper;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Ryujinx.Modules
|
||||
@@ -48,9 +48,8 @@ namespace Ryujinx.Modules
|
||||
{
|
||||
string ryuName = OperatingSystem.IsWindows() ? "Ryujinx.exe" : "Ryujinx";
|
||||
string ryuExe = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ryuName);
|
||||
var ryuArg = Environment.GetCommandLineArgs().AsEnumerable().Skip(1);
|
||||
|
||||
Process.Start(ryuExe, ryuArg);
|
||||
Process.Start(ryuExe, CommandLineState.Arguments);
|
||||
|
||||
Environment.Exit(0);
|
||||
}
|
||||
|
@@ -6,10 +6,11 @@ using Ryujinx.Common.GraphicsDriver;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Common.System;
|
||||
using Ryujinx.Common.SystemInfo;
|
||||
using Ryujinx.Ui.Common.Configuration;
|
||||
using Ryujinx.Modules;
|
||||
using Ryujinx.Ui;
|
||||
using Ryujinx.Ui.Common;
|
||||
using Ryujinx.Ui.Common.Configuration;
|
||||
using Ryujinx.Ui.Common.Helper;
|
||||
using Ryujinx.Ui.Widgets;
|
||||
using SixLabors.ImageSharp.Formats.Jpeg;
|
||||
using System;
|
||||
@@ -28,8 +29,6 @@ namespace Ryujinx
|
||||
|
||||
public static string ConfigurationPath { get; set; }
|
||||
|
||||
public static string CommandLineProfile { get; set; }
|
||||
|
||||
[DllImport("libX11")]
|
||||
private extern static int XInitThreads();
|
||||
|
||||
@@ -47,46 +46,13 @@ namespace Ryujinx
|
||||
MessageBoxA(IntPtr.Zero, "You are running an outdated version of Windows.\n\nStarting on June 1st 2022, Ryujinx will only support Windows 10 1803 and newer.\n", $"Ryujinx {Version}", MB_ICONWARNING);
|
||||
}
|
||||
|
||||
// Parse Arguments.
|
||||
string launchPathArg = null;
|
||||
string baseDirPathArg = null;
|
||||
bool startFullscreenArg = false;
|
||||
// Parse arguments
|
||||
CommandLineState.ParseArguments(args);
|
||||
|
||||
for (int i = 0; i < args.Length; ++i)
|
||||
{
|
||||
string arg = args[i];
|
||||
|
||||
if (arg == "-r" || arg == "--root-data-dir")
|
||||
{
|
||||
if (i + 1 >= args.Length)
|
||||
{
|
||||
Logger.Error?.Print(LogClass.Application, $"Invalid option '{arg}'");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
baseDirPathArg = args[++i];
|
||||
}
|
||||
else if (arg == "-p" || arg == "--profile")
|
||||
{
|
||||
if (i + 1 >= args.Length)
|
||||
{
|
||||
Logger.Error?.Print(LogClass.Application, $"Invalid option '{arg}'");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
CommandLineProfile = args[++i];
|
||||
}
|
||||
else if (arg == "-f" || arg == "--fullscreen")
|
||||
{
|
||||
startFullscreenArg = true;
|
||||
}
|
||||
else if (launchPathArg == null)
|
||||
{
|
||||
launchPathArg = arg;
|
||||
}
|
||||
}
|
||||
// Hook unhandled exception and process exit events.
|
||||
GLib.ExceptionManager.UnhandledException += (GLib.UnhandledExceptionArgs e) => ProcessUnhandledException(e.ExceptionObject as Exception, e.IsTerminating);
|
||||
AppDomain.CurrentDomain.UnhandledException += (object sender, UnhandledExceptionEventArgs e) => ProcessUnhandledException(e.ExceptionObject as Exception, e.IsTerminating);
|
||||
AppDomain.CurrentDomain.ProcessExit += (object sender, EventArgs e) => Exit();
|
||||
|
||||
// Make process DPI aware for proper window sizing on high-res screens.
|
||||
ForceDpiAware.Windows();
|
||||
@@ -95,8 +61,6 @@ namespace Ryujinx
|
||||
// Delete backup files after updating.
|
||||
Task.Run(Updater.CleanupUpdate);
|
||||
|
||||
Console.Title = $"Ryujinx Console {Version}";
|
||||
|
||||
// NOTE: GTK3 doesn't init X11 in a multi threaded way.
|
||||
// This ends up causing race condition and abort of XCB when a context is created by SPB (even if SPB do call XInitThreads).
|
||||
if (OperatingSystem.IsLinux())
|
||||
@@ -107,13 +71,8 @@ namespace Ryujinx
|
||||
string systemPath = Environment.GetEnvironmentVariable("Path", EnvironmentVariableTarget.Machine);
|
||||
Environment.SetEnvironmentVariable("Path", $"{Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin")};{systemPath}");
|
||||
|
||||
// Hook unhandled exception and process exit events.
|
||||
GLib.ExceptionManager.UnhandledException += (GLib.UnhandledExceptionArgs e) => ProcessUnhandledException(e.ExceptionObject as Exception, e.IsTerminating);
|
||||
AppDomain.CurrentDomain.UnhandledException += (object sender, UnhandledExceptionEventArgs e) => ProcessUnhandledException(e.ExceptionObject as Exception, e.IsTerminating);
|
||||
AppDomain.CurrentDomain.ProcessExit += (object sender, EventArgs e) => Exit();
|
||||
|
||||
// Setup base data directory.
|
||||
AppDataManager.Initialize(baseDirPathArg);
|
||||
AppDataManager.Initialize(CommandLineState.BaseDirPathArg);
|
||||
|
||||
// Initialize the configuration.
|
||||
ConfigurationState.Initialize();
|
||||
@@ -173,6 +132,21 @@ namespace Ryujinx
|
||||
}
|
||||
}
|
||||
|
||||
// Check if graphics backend was overridden
|
||||
if (CommandLineState.OverrideGraphicsBackend != null)
|
||||
{
|
||||
if (CommandLineState.OverrideGraphicsBackend.ToLower() == "opengl")
|
||||
{
|
||||
ConfigurationState.Instance.Graphics.GraphicsBackend.Value = GraphicsBackend.OpenGl;
|
||||
showVulkanPrompt = false;
|
||||
}
|
||||
else if (CommandLineState.OverrideGraphicsBackend.ToLower() == "vulkan")
|
||||
{
|
||||
ConfigurationState.Instance.Graphics.GraphicsBackend.Value = GraphicsBackend.Vulkan;
|
||||
showVulkanPrompt = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Logging system information.
|
||||
PrintSystemInfo();
|
||||
|
||||
@@ -195,9 +169,9 @@ namespace Ryujinx
|
||||
MainWindow mainWindow = new MainWindow();
|
||||
mainWindow.Show();
|
||||
|
||||
if (launchPathArg != null)
|
||||
if (CommandLineState.LaunchPathArg != null)
|
||||
{
|
||||
mainWindow.LoadApplication(launchPathArg, startFullscreenArg);
|
||||
mainWindow.LoadApplication(CommandLineState.LaunchPathArg, CommandLineState.StartFullscreenArg);
|
||||
}
|
||||
|
||||
if (ConfigurationState.Instance.CheckUpdatesOnStart.Value && Updater.CanUpdate(false))
|
||||
|
@@ -179,7 +179,7 @@ namespace Ryujinx.Ui
|
||||
VirtualFileSystem.FixExtraData(_libHacHorizonManager.RyujinxClient);
|
||||
|
||||
_contentManager = new ContentManager(_virtualFileSystem);
|
||||
_accountManager = new AccountManager(_libHacHorizonManager.RyujinxClient, Program.CommandLineProfile);
|
||||
_accountManager = new AccountManager(_libHacHorizonManager.RyujinxClient, CommandLineState.Profile);
|
||||
_userChannelPersistence = new UserChannelPersistence();
|
||||
|
||||
// Instantiate GUI objects.
|
||||
|
Reference in New Issue
Block a user