Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
b994dafe7a | ||
|
54421760c3 | ||
|
88a0e720cb | ||
|
53cc9e0561 | ||
|
7defc59b9d |
@@ -58,7 +58,6 @@ namespace ARMeilleure.CodeGen.Linking
|
||||
/// <param name="a">First instance</param>
|
||||
/// <param name="b">Second instance</param>
|
||||
/// <returns><see langword="true"/> if not equal; otherwise <see langword="false"/></returns>
|
||||
/// <inheritdoc/>
|
||||
public static bool operator !=(Symbol a, Symbol b)
|
||||
{
|
||||
return !(a == b);
|
||||
|
@@ -206,7 +206,7 @@ namespace ARMeilleure.Common
|
||||
/// <typeparam name="T">Type of elements</typeparam>
|
||||
/// <param name="length">Number of elements</param>
|
||||
/// <param name="fill">Fill value</param>
|
||||
/// <param name="leaf"><see langword="true"/> if leaf; otherwise <see langword=""="false"/></param>
|
||||
/// <param name="leaf"><see langword="true"/> if leaf; otherwise <see langword="false"/></param>
|
||||
/// <returns>Allocated block</returns>
|
||||
private IntPtr Allocate<T>(int length, T fill, bool leaf) where T : unmanaged
|
||||
{
|
||||
|
@@ -9,6 +9,9 @@ namespace ARMeilleure.Common
|
||||
class Counter<T> : IDisposable where T : unmanaged
|
||||
{
|
||||
private bool _disposed;
|
||||
/// <summary>
|
||||
/// Index in the <see cref="EntryTable{T}"/>
|
||||
/// </summary>
|
||||
private readonly int _index;
|
||||
private readonly EntryTable<T> _countTable;
|
||||
|
||||
@@ -17,7 +20,6 @@ namespace ARMeilleure.Common
|
||||
/// <see cref="EntryTable{T}"/> instance and index.
|
||||
/// </summary>
|
||||
/// <param name="countTable"><see cref="EntryTable{T}"/> instance</param>
|
||||
/// <param name="index">Index in the <see cref="EntryTable{T}"/></param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="countTable"/> is <see langword="null"/></exception>
|
||||
/// <exception cref="ArgumentException"><typeparamref name="T"/> is unsupported</exception>
|
||||
public Counter(EntryTable<T> countTable)
|
||||
@@ -68,7 +70,7 @@ namespace ARMeilleure.Common
|
||||
/// <summary>
|
||||
/// Releases all unmanaged and optionally managed resources used by the <see cref="Counter{T}"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="disposing"><see langword="true"/> to dispose managed resources also; otherwise just unmanaged resouces</param>
|
||||
/// <param name="disposing"><see langword="true"/> to dispose managed resources also; otherwise just unmanaged resources</param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!_disposed)
|
||||
|
@@ -344,7 +344,7 @@ namespace ARMeilleure.Translation
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the value from the dictionary after searching for it with <paramref name="key">.
|
||||
/// Removes the value from the dictionary after searching for it with <paramref name="key"/>.
|
||||
/// </summary>
|
||||
/// <param name="key">Key to search for</param>
|
||||
/// <returns>Number of deleted values</returns>
|
||||
|
@@ -52,8 +52,8 @@
|
||||
"GameListContextMenuOpenModsDirectory": "Open Mods Directory",
|
||||
"GameListContextMenuOpenModsDirectoryToolTip": "Opens the directory which contains Application's Mods",
|
||||
"GameListContextMenuCacheManagement": "Cache Management",
|
||||
"GameListContextMenuCacheManagementPurgePptc": "Purge PPTC Cache",
|
||||
"GameListContextMenuCacheManagementPurgePptcToolTip": "Deletes Application's PPTC cache",
|
||||
"GameListContextMenuCacheManagementPurgePptc": "Queue PPTC Rebuild",
|
||||
"GameListContextMenuCacheManagementPurgePptcToolTip": "Trigger PPTC to rebuild at boot time on the next game launch",
|
||||
"GameListContextMenuCacheManagementPurgeShaderCache": "Purge Shader Cache",
|
||||
"GameListContextMenuCacheManagementPurgeShaderCacheToolTip": "Deletes Application's shader cache",
|
||||
"GameListContextMenuCacheManagementOpenPptcDirectory": "Open PPTC Directory",
|
||||
@@ -350,7 +350,7 @@
|
||||
"DialogProfileDeleteProfileTitle": "Deleting Profile",
|
||||
"DialogProfileDeleteProfileMessage": "This action is irreversible, are you sure you want to continue?",
|
||||
"DialogWarning": "Warning",
|
||||
"DialogPPTCDeletionMessage": "You are about to delete the PPTC cache for :\n\n{0}\n\nAre you sure you want to proceed?",
|
||||
"DialogPPTCDeletionMessage": "You are about to queue a PPTC rebuild on the next boot of:\n\n{0}\n\nAre you sure you want to proceed?",
|
||||
"DialogPPTCDeletionErrorMessage": "Error purging PPTC cache at {0}: {1}",
|
||||
"DialogShaderDeletionMessage": "You are about to delete the Shader cache for :\n\n{0}\n\nAre you sure you want to proceed?",
|
||||
"DialogShaderDeletionErrorMessage": "Error purging Shader cache at {0}: {1}",
|
||||
|
@@ -49,6 +49,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
|
||||
private float _previousVolumeLevel;
|
||||
private float _volume;
|
||||
private bool _isVulkanAvailable = true;
|
||||
private bool _directoryChanged = false;
|
||||
private List<string> _gpuIds = new List<string>();
|
||||
private KeyboardHotkeys _keyboardHotkeys;
|
||||
private int _graphicsBackendIndex;
|
||||
@@ -112,6 +113,17 @@ namespace Ryujinx.Ava.Ui.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public bool DirectoryChanged
|
||||
{
|
||||
get => _directoryChanged;
|
||||
set
|
||||
{
|
||||
_directoryChanged = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool EnableDiscordIntegration { get; set; }
|
||||
public bool CheckUpdatesOnStart { get; set; }
|
||||
public bool ShowConfirmExit { get; set; }
|
||||
@@ -397,10 +409,14 @@ namespace Ryujinx.Ava.Ui.ViewModels
|
||||
|
||||
public async Task SaveSettings()
|
||||
{
|
||||
List<string> gameDirs = new List<string>(GameDirectories);
|
||||
|
||||
ConfigurationState config = ConfigurationState.Instance;
|
||||
|
||||
if (_directoryChanged)
|
||||
{
|
||||
List<string> gameDirs = new List<string>(GameDirectories);
|
||||
config.Ui.GameDirs.Value = gameDirs;
|
||||
}
|
||||
|
||||
if (_validTzRegions.Contains(TimeZone))
|
||||
{
|
||||
config.System.TimeZone.Value = TimeZone;
|
||||
@@ -465,7 +481,6 @@ namespace Ryujinx.Ava.Ui.ViewModels
|
||||
|
||||
config.System.SystemTimeOffset.Value = systemTimeOffset.Seconds;
|
||||
config.Graphics.ShadersDumpPath.Value = ShaderDumpPath;
|
||||
config.Ui.GameDirs.Value = gameDirs;
|
||||
config.System.FsGlobalAccessLogMode.Value = FsGlobalAccessLogMode;
|
||||
config.System.MemoryManagerMode.Value = (MemoryManagerMode)MemoryMode;
|
||||
|
||||
|
@@ -162,6 +162,7 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
if (!string.IsNullOrWhiteSpace(path) && Directory.Exists(path) && !ViewModel.GameDirectories.Contains(path))
|
||||
{
|
||||
ViewModel.GameDirectories.Add(path);
|
||||
ViewModel.DirectoryChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -170,6 +171,7 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
if (!string.IsNullOrWhiteSpace(path))
|
||||
{
|
||||
ViewModel.GameDirectories.Add(path);
|
||||
ViewModel.DirectoryChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -181,6 +183,7 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
foreach (string path in selected)
|
||||
{
|
||||
ViewModel.GameDirectories.Remove(path);
|
||||
ViewModel.DirectoryChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,10 +235,12 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
|
||||
ControllerSettings?.SaveCurrentProfile();
|
||||
|
||||
if (Owner is MainWindow window)
|
||||
if (Owner is MainWindow window && ViewModel.DirectoryChanged)
|
||||
{
|
||||
window.ViewModel.LoadApplications();
|
||||
}
|
||||
|
||||
ViewModel.DirectoryChanged = false;
|
||||
}
|
||||
|
||||
protected override void OnClosed(EventArgs e)
|
||||
|
@@ -1317,10 +1317,12 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
|
||||
for (int location = 0; location < attributeTypes.Length; location++)
|
||||
{
|
||||
attributeTypes[location] = vertexAttribState[location].UnpackType() switch
|
||||
VertexAttribType type = vertexAttribState[location].UnpackType();
|
||||
|
||||
attributeTypes[location] = type switch
|
||||
{
|
||||
3 => AttributeType.Sint,
|
||||
4 => AttributeType.Uint,
|
||||
VertexAttribType.Sint => AttributeType.Sint,
|
||||
VertexAttribType.Uint => AttributeType.Uint,
|
||||
_ => AttributeType.Float
|
||||
};
|
||||
}
|
||||
|
@@ -267,6 +267,41 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
#pragma warning restore CS0649
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Vertex attribute vector and component size.
|
||||
/// </summary>
|
||||
enum VertexAttribSize
|
||||
{
|
||||
Size32x4 = 1,
|
||||
Size32x3 = 2,
|
||||
Size16x4 = 3,
|
||||
Size32x2 = 4,
|
||||
Size16x3 = 5,
|
||||
Size8x4 = 0xa,
|
||||
Size16x2 = 0xf,
|
||||
Size32 = 0x12,
|
||||
Size8x3 = 0x13,
|
||||
Size8x2 = 0x18,
|
||||
Size16 = 0x1b,
|
||||
Size8 = 0x1d,
|
||||
Rgb10A2 = 0x30,
|
||||
Rg11B10 = 0x31
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Vertex attribute component type.
|
||||
/// </summary>
|
||||
enum VertexAttribType
|
||||
{
|
||||
Snorm = 1,
|
||||
Unorm = 2,
|
||||
Sint = 3,
|
||||
Uint = 4,
|
||||
Uscaled = 5,
|
||||
Sscaled = 6,
|
||||
Float = 7
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Vertex buffer attribute state.
|
||||
/// </summary>
|
||||
@@ -312,13 +347,22 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
return Attribute & 0x3fe00000;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// Unpacks the Maxwell attribute size.
|
||||
/// </summary>
|
||||
/// <returns>Attribute size</returns>
|
||||
public VertexAttribSize UnpackSize()
|
||||
{
|
||||
return (VertexAttribSize)((Attribute >> 21) & 0x3f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unpacks the Maxwell attribute component type.
|
||||
/// </summary>
|
||||
/// <returns>Attribute component type</returns>
|
||||
public uint UnpackType()
|
||||
public VertexAttribType UnpackType()
|
||||
{
|
||||
return (Attribute >> 27) & 7;
|
||||
return (VertexAttribType)((Attribute >> 27) & 7);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -82,7 +82,7 @@ namespace Ryujinx.Graphics.Gpu
|
||||
/// <summary>
|
||||
/// Host hardware capabilities.
|
||||
/// </summary>
|
||||
internal Capabilities Capabilities { get; private set; }
|
||||
internal Capabilities Capabilities;
|
||||
|
||||
/// <summary>
|
||||
/// Event for signalling shader cache loading progress.
|
||||
|
@@ -573,9 +573,9 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
||||
RecompileGraphicsFromGuestCode(guestShaders, specState, programIndex);
|
||||
}
|
||||
}
|
||||
catch (DiskCacheLoadException diskCacheLoadException)
|
||||
catch (Exception exception)
|
||||
{
|
||||
Logger.Error?.Print(LogClass.Gpu, $"Error translating guest shader. {diskCacheLoadException.Message}");
|
||||
Logger.Error?.Print(LogClass.Gpu, $"Error translating guest shader. {exception.Message}");
|
||||
|
||||
ErrorCount++;
|
||||
SignalCompiled();
|
||||
|
@@ -27,7 +27,6 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||
_stageIndex = stageIndex;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public int QueryBindingConstantBuffer(int index)
|
||||
{
|
||||
if (_context.Capabilities.Api == TargetApi.Vulkan)
|
||||
@@ -41,7 +40,6 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public int QueryBindingStorageBuffer(int index)
|
||||
{
|
||||
if (_context.Capabilities.Api == TargetApi.Vulkan)
|
||||
@@ -54,7 +52,6 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public int QueryBindingTexture(int index, bool isBuffer)
|
||||
{
|
||||
if (_context.Capabilities.Api == TargetApi.Vulkan)
|
||||
@@ -72,7 +69,6 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public int QueryBindingImage(int index, bool isBuffer)
|
||||
{
|
||||
if (_context.Capabilities.Api == TargetApi.Vulkan)
|
||||
@@ -116,37 +112,26 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool QueryHostHasFrontFacingBug() => _context.Capabilities.HasFrontFacingBug;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool QueryHostHasVectorIndexingBug() => _context.Capabilities.HasVectorIndexingBug;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public int QueryHostStorageBufferOffsetAlignment() => _context.Capabilities.StorageBufferOffsetAlignment;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool QueryHostSupportsBgraFormat() => _context.Capabilities.SupportsBgraFormat;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool QueryHostSupportsFragmentShaderInterlock() => _context.Capabilities.SupportsFragmentShaderInterlock;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool QueryHostSupportsFragmentShaderOrderingIntel() => _context.Capabilities.SupportsFragmentShaderOrderingIntel;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool QueryHostSupportsGeometryShaderPassthrough() => _context.Capabilities.SupportsGeometryShaderPassthrough;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool QueryHostSupportsImageLoadFormatted() => _context.Capabilities.SupportsImageLoadFormatted;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool QueryHostSupportsNonConstantTextureOffset() => _context.Capabilities.SupportsNonConstantTextureOffset;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool QueryHostSupportsShaderBallot() => _context.Capabilities.SupportsShaderBallot;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool QueryHostSupportsTextureShadowLod() => _context.Capabilities.SupportsTextureShadowLod;
|
||||
|
||||
/// <summary>
|
||||
|
@@ -1,9 +1,12 @@
|
||||
using Ryujinx.Graphics.Shader.StructuredIr;
|
||||
using Ryujinx.Graphics.Shader.Translation;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Shader
|
||||
{
|
||||
public enum AttributeType : byte
|
||||
{
|
||||
// Generic types.
|
||||
Float,
|
||||
Sint,
|
||||
Uint
|
||||
@@ -11,18 +14,7 @@ namespace Ryujinx.Graphics.Shader
|
||||
|
||||
static class AttributeTypeExtensions
|
||||
{
|
||||
public static string GetScalarType(this AttributeType type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
AttributeType.Float => "float",
|
||||
AttributeType.Sint => "int",
|
||||
AttributeType.Uint => "uint",
|
||||
_ => throw new ArgumentException($"Invalid attribute type \"{type}\".")
|
||||
};
|
||||
}
|
||||
|
||||
public static string GetVec4Type(this AttributeType type)
|
||||
public static string ToVec4Type(this AttributeType type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
@@ -32,5 +24,27 @@ namespace Ryujinx.Graphics.Shader
|
||||
_ => throw new ArgumentException($"Invalid attribute type \"{type}\".")
|
||||
};
|
||||
}
|
||||
|
||||
public static VariableType ToVariableType(this AttributeType type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
AttributeType.Float => VariableType.F32,
|
||||
AttributeType.Sint => VariableType.S32,
|
||||
AttributeType.Uint => VariableType.U32,
|
||||
_ => throw new ArgumentException($"Invalid attribute type \"{type}\".")
|
||||
};
|
||||
}
|
||||
|
||||
public static AggregateType ToAggregateType(this AttributeType type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
AttributeType.Float => AggregateType.FP32,
|
||||
AttributeType.Sint => AggregateType.S32,
|
||||
AttributeType.Uint => AggregateType.U32,
|
||||
_ => throw new ArgumentException($"Invalid attribute type \"{type}\".")
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@@ -553,11 +553,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
||||
|
||||
if (context.Config.Stage == ShaderStage.Vertex)
|
||||
{
|
||||
type = context.Config.GpuAccessor.QueryAttributeType(attr).GetVec4Type();
|
||||
type = context.Config.GpuAccessor.QueryAttributeType(attr).ToVec4Type();
|
||||
}
|
||||
else
|
||||
{
|
||||
type = AttributeType.Float.GetVec4Type();
|
||||
type = AttributeType.Float.ToVec4Type();
|
||||
}
|
||||
|
||||
context.AppendLine($"layout ({pass}location = {attr}) {iq}in {type} {name}{suffix};");
|
||||
|
@@ -454,12 +454,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
||||
|
||||
AttributeType type = context.Config.GpuAccessor.QueryAttributeType(location);
|
||||
|
||||
return type switch
|
||||
{
|
||||
AttributeType.Sint => VariableType.S32,
|
||||
AttributeType.Uint => VariableType.U32,
|
||||
_ => VariableType.F32
|
||||
};
|
||||
return type.ToVariableType();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -93,12 +93,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||
|
||||
if (config.Stage == ShaderStage.Vertex && !isOutAttr)
|
||||
{
|
||||
elemType = config.GpuAccessor.QueryAttributeType(location) switch
|
||||
{
|
||||
AttributeType.Sint => AggregateType.S32,
|
||||
AttributeType.Uint => AggregateType.U32,
|
||||
_ => AggregateType.FP32
|
||||
};
|
||||
elemType = config.GpuAccessor.QueryAttributeType(location).ToAggregateType();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@@ -8,7 +8,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
class FormatCapabilities
|
||||
{
|
||||
private readonly FormatFeatureFlags[] _table;
|
||||
private readonly FormatFeatureFlags[] _bufferTable;
|
||||
private readonly FormatFeatureFlags[] _optimalTable;
|
||||
|
||||
private readonly Vk _api;
|
||||
private readonly PhysicalDevice _physicalDevice;
|
||||
@@ -17,14 +18,18 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
_api = api;
|
||||
_physicalDevice = physicalDevice;
|
||||
_table = new FormatFeatureFlags[Enum.GetNames(typeof(GAL.Format)).Length];
|
||||
|
||||
int totalFormats = Enum.GetNames(typeof(GAL.Format)).Length;
|
||||
|
||||
_bufferTable = new FormatFeatureFlags[totalFormats];
|
||||
_optimalTable = new FormatFeatureFlags[totalFormats];
|
||||
}
|
||||
|
||||
public bool FormatsSupports(FormatFeatureFlags flags, params GAL.Format[] formats)
|
||||
public bool BufferFormatsSupport(FormatFeatureFlags flags, params GAL.Format[] formats)
|
||||
{
|
||||
foreach (GAL.Format format in formats)
|
||||
{
|
||||
if (!FormatSupports(flags, format))
|
||||
if (!BufferFormatSupports(flags, format))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -33,15 +38,42 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool FormatSupports(FormatFeatureFlags flags, GAL.Format format)
|
||||
public bool OptimalFormatsSupport(FormatFeatureFlags flags, params GAL.Format[] formats)
|
||||
{
|
||||
var formatFeatureFlags = _table[(int)format];
|
||||
foreach (GAL.Format format in formats)
|
||||
{
|
||||
if (!OptimalFormatSupports(flags, format))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool BufferFormatSupports(FormatFeatureFlags flags, GAL.Format format)
|
||||
{
|
||||
var formatFeatureFlags = _bufferTable[(int)format];
|
||||
|
||||
if (formatFeatureFlags == 0)
|
||||
{
|
||||
_api.GetPhysicalDeviceFormatProperties(_physicalDevice, FormatTable.GetFormat(format), out var fp);
|
||||
formatFeatureFlags = fp.BufferFeatures;
|
||||
_bufferTable[(int)format] = formatFeatureFlags;
|
||||
}
|
||||
|
||||
return (formatFeatureFlags & flags) == flags;
|
||||
}
|
||||
|
||||
public bool OptimalFormatSupports(FormatFeatureFlags flags, GAL.Format format)
|
||||
{
|
||||
var formatFeatureFlags = _optimalTable[(int)format];
|
||||
|
||||
if (formatFeatureFlags == 0)
|
||||
{
|
||||
_api.GetPhysicalDeviceFormatProperties(_physicalDevice, FormatTable.GetFormat(format), out var fp);
|
||||
formatFeatureFlags = fp.OptimalTilingFeatures;
|
||||
_table[(int)format] = formatFeatureFlags;
|
||||
_optimalTable[(int)format] = formatFeatureFlags;
|
||||
}
|
||||
|
||||
return (formatFeatureFlags & flags) == flags;
|
||||
@@ -69,7 +101,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
requiredFeatures |= FormatFeatureFlags.FormatFeatureStorageImageBit;
|
||||
}
|
||||
|
||||
if (!FormatSupports(requiredFeatures, srcFormat) || (IsD24S8(srcFormat) && VulkanConfiguration.ForceD24S8Unsupported))
|
||||
if (!OptimalFormatSupports(requiredFeatures, srcFormat) || (IsD24S8(srcFormat) && VulkanConfiguration.ForceD24S8Unsupported))
|
||||
{
|
||||
// The format is not supported. Can we convert it to a higher precision format?
|
||||
if (IsD24S8(srcFormat))
|
||||
@@ -85,9 +117,44 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return format;
|
||||
}
|
||||
|
||||
public VkFormat ConvertToVertexVkFormat(GAL.Format srcFormat)
|
||||
{
|
||||
var format = FormatTable.GetFormat(srcFormat);
|
||||
|
||||
if (!BufferFormatSupports(FormatFeatureFlags.FormatFeatureVertexBufferBit, srcFormat) ||
|
||||
(IsRGB16IntFloat(srcFormat) && VulkanConfiguration.ForceRGB16IntFloatUnsupported))
|
||||
{
|
||||
// The format is not supported. Can we convert it to an alternative format?
|
||||
switch (srcFormat)
|
||||
{
|
||||
case GAL.Format.R16G16B16Float:
|
||||
format = VkFormat.R16G16B16A16Sfloat;
|
||||
break;
|
||||
case GAL.Format.R16G16B16Sint:
|
||||
format = VkFormat.R16G16B16A16Sint;
|
||||
break;
|
||||
case GAL.Format.R16G16B16Uint:
|
||||
format = VkFormat.R16G16B16A16Uint;
|
||||
break;
|
||||
default:
|
||||
Logger.Error?.Print(LogClass.Gpu, $"Format {srcFormat} is not supported by the host.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return format;
|
||||
}
|
||||
|
||||
public static bool IsD24S8(GAL.Format format)
|
||||
{
|
||||
return format == GAL.Format.D24UnormS8Uint || format == GAL.Format.S8UintD24Unorm;
|
||||
}
|
||||
|
||||
private static bool IsRGB16IntFloat(GAL.Format format)
|
||||
{
|
||||
return format == GAL.Format.R16G16B16Float ||
|
||||
format == GAL.Format.R16G16B16Sint ||
|
||||
format == GAL.Format.R16G16B16Uint;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -730,6 +730,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
public void SetVertexAttribs(ReadOnlySpan<VertexAttribDescriptor> vertexAttribs)
|
||||
{
|
||||
var formatCapabilities = Gd.FormatCapabilities;
|
||||
|
||||
int count = Math.Min(Constants.MaxVertexAttributes, vertexAttribs.Length);
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
@@ -740,7 +742,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_newState.Internal.VertexAttributeDescriptions[i] = new VertexInputAttributeDescription(
|
||||
(uint)i,
|
||||
(uint)bufferIndex,
|
||||
FormatTable.GetFormat(attribute.Format),
|
||||
formatCapabilities.ConvertToVertexVkFormat(attribute.Format),
|
||||
(uint)attribute.Offset);
|
||||
}
|
||||
|
||||
|
@@ -211,7 +211,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
pipeline.Internal.VertexAttributeDescriptions[i] = new VertexInputAttributeDescription(
|
||||
(uint)i,
|
||||
(uint)bufferIndex,
|
||||
FormatTable.GetFormat(attribute.Format),
|
||||
gd.FormatCapabilities.ConvertToVertexVkFormat(attribute.Format),
|
||||
(uint)attribute.Offset);
|
||||
}
|
||||
|
||||
|
@@ -451,8 +451,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
return;
|
||||
}
|
||||
else if (_gd.FormatCapabilities.FormatSupports(FormatFeatureFlags.FormatFeatureBlitSrcBit, srcFormat) &&
|
||||
_gd.FormatCapabilities.FormatSupports(FormatFeatureFlags.FormatFeatureBlitDstBit, dstFormat))
|
||||
else if (_gd.FormatCapabilities.OptimalFormatSupports(FormatFeatureFlags.FormatFeatureBlitSrcBit, srcFormat) &&
|
||||
_gd.FormatCapabilities.OptimalFormatSupports(FormatFeatureFlags.FormatFeatureBlitDstBit, dstFormat))
|
||||
{
|
||||
TextureCopy.Blit(
|
||||
_gd.Api,
|
||||
@@ -761,8 +761,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
private bool SupportsBlitFromD32FS8ToD32FAndS8()
|
||||
{
|
||||
var formatFeatureFlags = FormatFeatureFlags.FormatFeatureBlitSrcBit | FormatFeatureFlags.FormatFeatureBlitDstBit;
|
||||
return _gd.FormatCapabilities.FormatSupports(formatFeatureFlags, GAL.Format.D32Float) &&
|
||||
_gd.FormatCapabilities.FormatSupports(formatFeatureFlags, GAL.Format.S8Uint);
|
||||
return _gd.FormatCapabilities.OptimalFormatSupports(formatFeatureFlags, GAL.Format.D32Float) &&
|
||||
_gd.FormatCapabilities.OptimalFormatSupports(formatFeatureFlags, GAL.Format.S8Uint);
|
||||
}
|
||||
|
||||
public TextureView GetView(GAL.Format format)
|
||||
|
@@ -7,5 +7,6 @@
|
||||
public const bool UsePushDescriptors = false;
|
||||
|
||||
public const bool ForceD24S8Unsupported = false;
|
||||
public const bool ForceRGB16IntFloatUnsupported = false;
|
||||
}
|
||||
}
|
||||
|
@@ -377,7 +377,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
FormatFeatureFlags.FormatFeatureTransferSrcBit |
|
||||
FormatFeatureFlags.FormatFeatureTransferDstBit;
|
||||
|
||||
bool supportsBc123CompressionFormat = FormatCapabilities.FormatsSupports(compressedFormatFeatureFlags,
|
||||
bool supportsBc123CompressionFormat = FormatCapabilities.OptimalFormatsSupport(compressedFormatFeatureFlags,
|
||||
GAL.Format.Bc1RgbaSrgb,
|
||||
GAL.Format.Bc1RgbaUnorm,
|
||||
GAL.Format.Bc2Srgb,
|
||||
@@ -385,13 +385,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
GAL.Format.Bc3Srgb,
|
||||
GAL.Format.Bc3Unorm);
|
||||
|
||||
bool supportsBc45CompressionFormat = FormatCapabilities.FormatsSupports(compressedFormatFeatureFlags,
|
||||
bool supportsBc45CompressionFormat = FormatCapabilities.OptimalFormatsSupport(compressedFormatFeatureFlags,
|
||||
GAL.Format.Bc4Snorm,
|
||||
GAL.Format.Bc4Unorm,
|
||||
GAL.Format.Bc5Snorm,
|
||||
GAL.Format.Bc5Unorm);
|
||||
|
||||
bool supportsBc67CompressionFormat = FormatCapabilities.FormatsSupports(compressedFormatFeatureFlags,
|
||||
bool supportsBc67CompressionFormat = FormatCapabilities.OptimalFormatsSupport(compressedFormatFeatureFlags,
|
||||
GAL.Format.Bc6HSfloat,
|
||||
GAL.Format.Bc6HUfloat,
|
||||
GAL.Format.Bc7Srgb,
|
||||
|
@@ -154,9 +154,9 @@ namespace Ryujinx.Ui.Widgets
|
||||
//
|
||||
// _purgePtcCacheMenuItem
|
||||
//
|
||||
_purgePtcCacheMenuItem = new MenuItem("Purge PPTC Cache")
|
||||
_purgePtcCacheMenuItem = new MenuItem("Queue PPTC Rebuild")
|
||||
{
|
||||
TooltipText = "Delete the Application's PPTC cache."
|
||||
TooltipText = "Trigger PPTC to rebuild at boot time on the next game launch."
|
||||
};
|
||||
_purgePtcCacheMenuItem.Activated += PurgePtcCache_Clicked;
|
||||
|
||||
|
@@ -522,7 +522,7 @@ namespace Ryujinx.Ui.Widgets
|
||||
DirectoryInfo mainDir = new DirectoryInfo(System.IO.Path.Combine(AppDataManager.GamesDirPath, _titleIdText, "cache", "cpu", "0"));
|
||||
DirectoryInfo backupDir = new DirectoryInfo(System.IO.Path.Combine(AppDataManager.GamesDirPath, _titleIdText, "cache", "cpu", "1"));
|
||||
|
||||
MessageDialog warningDialog = GtkDialog.CreateConfirmationDialog("Warning", $"You are about to delete the PPTC cache for :\n\n<b>{_titleName}</b>\n\nAre you sure you want to proceed?");
|
||||
MessageDialog warningDialog = GtkDialog.CreateConfirmationDialog("Warning", $"You are about to queue a PPTC rebuild on the next boot of:\n\n<b>{_titleName}</b>\n\nAre you sure you want to proceed?");
|
||||
|
||||
List<FileInfo> cacheFiles = new List<FileInfo>();
|
||||
|
||||
|
@@ -34,6 +34,7 @@ namespace Ryujinx.Ui.Windows
|
||||
|
||||
private long _systemTimeOffset;
|
||||
private float _previousVolumeLevel;
|
||||
private bool _directoryChanged = false;
|
||||
|
||||
#pragma warning disable CS0649, IDE0044
|
||||
[GUI] CheckButton _traceLogToggle;
|
||||
@@ -501,14 +502,22 @@ namespace Ryujinx.Ui.Windows
|
||||
|
||||
private void SaveSettings()
|
||||
{
|
||||
List<string> gameDirs = new List<string>();
|
||||
|
||||
_gameDirsBoxStore.GetIterFirst(out TreeIter treeIter);
|
||||
for (int i = 0; i < _gameDirsBoxStore.IterNChildren(); i++)
|
||||
if (_directoryChanged)
|
||||
{
|
||||
gameDirs.Add((string)_gameDirsBoxStore.GetValue(treeIter, 0));
|
||||
List<string> gameDirs = new List<string>();
|
||||
|
||||
_gameDirsBoxStore.IterNext(ref treeIter);
|
||||
_gameDirsBoxStore.GetIterFirst(out TreeIter treeIter);
|
||||
|
||||
for (int i = 0; i < _gameDirsBoxStore.IterNChildren(); i++)
|
||||
{
|
||||
gameDirs.Add((string)_gameDirsBoxStore.GetValue(treeIter, 0));
|
||||
|
||||
_gameDirsBoxStore.IterNext(ref treeIter);
|
||||
}
|
||||
|
||||
ConfigurationState.Instance.Ui.GameDirs.Value = gameDirs;
|
||||
|
||||
_directoryChanged = false;
|
||||
}
|
||||
|
||||
if (!float.TryParse(_resScaleText.Buffer.Text, out float resScaleCustom) || resScaleCustom <= 0.0f)
|
||||
@@ -571,7 +580,6 @@ namespace Ryujinx.Ui.Windows
|
||||
ConfigurationState.Instance.System.SystemTimeOffset.Value = _systemTimeOffset;
|
||||
ConfigurationState.Instance.Ui.CustomThemePath.Value = _custThemePath.Buffer.Text;
|
||||
ConfigurationState.Instance.Graphics.ShadersDumpPath.Value = _graphicsShadersDumpPath.Buffer.Text;
|
||||
ConfigurationState.Instance.Ui.GameDirs.Value = gameDirs;
|
||||
ConfigurationState.Instance.System.FsGlobalAccessLogMode.Value = (int)_fsLogSpinAdjustment.Value;
|
||||
ConfigurationState.Instance.Graphics.MaxAnisotropy.Value = float.Parse(_anisotropy.ActiveId, CultureInfo.InvariantCulture);
|
||||
ConfigurationState.Instance.Graphics.AspectRatio.Value = Enum.Parse<AspectRatio>(_aspectRatio.ActiveId);
|
||||
@@ -655,27 +663,27 @@ namespace Ryujinx.Ui.Windows
|
||||
|
||||
if (fileChooser.Run() == (int)ResponseType.Accept)
|
||||
{
|
||||
_directoryChanged = false;
|
||||
foreach (string directory in fileChooser.Filenames)
|
||||
{
|
||||
bool directoryAdded = false;
|
||||
|
||||
if (_gameDirsBoxStore.GetIterFirst(out TreeIter treeIter))
|
||||
{
|
||||
do
|
||||
{
|
||||
if (directory.Equals((string)_gameDirsBoxStore.GetValue(treeIter, 0)))
|
||||
{
|
||||
directoryAdded = true;
|
||||
break;
|
||||
}
|
||||
} while(_gameDirsBoxStore.IterNext(ref treeIter));
|
||||
}
|
||||
|
||||
if (!directoryAdded)
|
||||
if (!_directoryChanged)
|
||||
{
|
||||
_gameDirsBoxStore.AppendValues(directory);
|
||||
}
|
||||
}
|
||||
|
||||
_directoryChanged = true;
|
||||
}
|
||||
|
||||
fileChooser.Dispose();
|
||||
@@ -693,6 +701,8 @@ namespace Ryujinx.Ui.Windows
|
||||
if (selection.GetSelected(out TreeIter treeIter))
|
||||
{
|
||||
_gameDirsBoxStore.Remove(ref treeIter);
|
||||
|
||||
_directoryChanged = true;
|
||||
}
|
||||
|
||||
((ToggleButton)sender).SetStateFlags(StateFlags.Normal, true);
|
||||
|
Reference in New Issue
Block a user