Compare commits
8 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
4965681e06 | ||
|
3868a00206 | ||
|
933e5144a9 | ||
|
73a42c85c4 | ||
|
39ba11054b | ||
|
c250e3392c | ||
|
e56b069081 | ||
|
204c031fef |
@@ -21,6 +21,10 @@
|
|||||||
<img src="https://github.com/Ryujinx/Ryujinx/actions/workflows/release.yml/badge.svg"
|
<img src="https://github.com/Ryujinx/Ryujinx/actions/workflows/release.yml/badge.svg"
|
||||||
alt="">
|
alt="">
|
||||||
</a>
|
</a>
|
||||||
|
<a href="https://crwd.in/ryujinx">
|
||||||
|
<img src="https://badges.crowdin.net/ryujinx/localized.svg"
|
||||||
|
alt="">
|
||||||
|
</a>
|
||||||
<a href="https://discord.com/invite/VkQYXAZ">
|
<a href="https://discord.com/invite/VkQYXAZ">
|
||||||
<img src="https://img.shields.io/discord/410208534861447168?color=5865F2&label=Ryujinx&logo=discord&logoColor=white"
|
<img src="https://img.shields.io/discord/410208534861447168?color=5865F2&label=Ryujinx&logo=discord&logoColor=white"
|
||||||
alt="Discord">
|
alt="Discord">
|
||||||
@@ -48,6 +52,8 @@ See our [Setup & Configuration Guide](https://github.com/Ryujinx/Ryujinx/wiki/Ry
|
|||||||
For our Local Wireless and LAN builds, see our [Multiplayer: Local Play/Local Wireless Guide
|
For our Local Wireless and LAN builds, see our [Multiplayer: Local Play/Local Wireless Guide
|
||||||
](https://github.com/Ryujinx/Ryujinx/wiki/Multiplayer-(LDN-Local-Wireless)-Guide).
|
](https://github.com/Ryujinx/Ryujinx/wiki/Multiplayer-(LDN-Local-Wireless)-Guide).
|
||||||
|
|
||||||
|
Avalonia UI comes with translations for various languages. See [Crowdin](https://crwd.in/ryujinx) for more information.
|
||||||
|
|
||||||
## Latest build
|
## Latest build
|
||||||
|
|
||||||
These builds are compiled automatically for each commit on the master branch. While we strive to ensure optimal stability and performance prior to pushing an update, our automated builds **may be unstable or completely broken.**
|
These builds are compiled automatically for each commit on the master branch. While we strive to ensure optimal stability and performance prior to pushing an update, our automated builds **may be unstable or completely broken.**
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
using ARMeilleure.Translation.PTC;
|
using ARMeilleure.Translation.PTC;
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
|
using Avalonia.Threading;
|
||||||
using Ryujinx.Ava.Ui.Windows;
|
using Ryujinx.Ava.Ui.Windows;
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
@@ -8,6 +9,7 @@ using Ryujinx.Common.Logging;
|
|||||||
using Ryujinx.Common.System;
|
using Ryujinx.Common.System;
|
||||||
using Ryujinx.Common.SystemInfo;
|
using Ryujinx.Common.SystemInfo;
|
||||||
using Ryujinx.Modules;
|
using Ryujinx.Modules;
|
||||||
|
using Ryujinx.SDL2.Common;
|
||||||
using Ryujinx.Ui.Common;
|
using Ryujinx.Ui.Common;
|
||||||
using Ryujinx.Ui.Common.Configuration;
|
using Ryujinx.Ui.Common.Configuration;
|
||||||
using Ryujinx.Ui.Common.Helper;
|
using Ryujinx.Ui.Common.Helper;
|
||||||
@@ -94,6 +96,9 @@ namespace Ryujinx.Ava
|
|||||||
// Initialize Discord integration.
|
// Initialize Discord integration.
|
||||||
DiscordIntegrationModule.Initialize();
|
DiscordIntegrationModule.Initialize();
|
||||||
|
|
||||||
|
// Initialize SDL2 driver
|
||||||
|
SDL2Driver.MainThreadDispatcher = action => Dispatcher.UIThread.InvokeAsync(action, DispatcherPriority.Input);
|
||||||
|
|
||||||
ReloadConfig();
|
ReloadConfig();
|
||||||
|
|
||||||
ForceDpiAware.Windows();
|
ForceDpiAware.Windows();
|
||||||
@@ -219,4 +224,4 @@ namespace Ryujinx.Ava
|
|||||||
Logger.Shutdown();
|
Logger.Shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -28,9 +28,39 @@ namespace Ryujinx.Common.SystemInfo
|
|||||||
|
|
||||||
CpuName = $"{cpuName} ; {LogicalCoreCount} logical";
|
CpuName = $"{cpuName} ; {LogicalCoreCount} logical";
|
||||||
RamTotal = totalRAM;
|
RamTotal = totalRAM;
|
||||||
|
RamAvailable = GetVMInfoAvailableMemory();
|
||||||
}
|
}
|
||||||
|
|
||||||
[DllImport("libSystem.dylib", CharSet = CharSet.Ansi, SetLastError = true)]
|
static ulong GetVMInfoAvailableMemory()
|
||||||
|
{
|
||||||
|
var port = mach_host_self();
|
||||||
|
|
||||||
|
uint pageSize = 0;
|
||||||
|
var result = host_page_size(port, ref pageSize);
|
||||||
|
|
||||||
|
if (result != 0)
|
||||||
|
{
|
||||||
|
Logger.Error?.Print(LogClass.Application, $"Failed to query Available RAM. host_page_size() error = {result}");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int flavor = 4; // HOST_VM_INFO64
|
||||||
|
uint count = (uint)(Marshal.SizeOf<VMStatistics64>() / sizeof(int)); // HOST_VM_INFO64_COUNT
|
||||||
|
VMStatistics64 stats = new();
|
||||||
|
result = host_statistics64(port, flavor, ref stats, ref count);
|
||||||
|
|
||||||
|
if (result != 0)
|
||||||
|
{
|
||||||
|
Logger.Error?.Print(LogClass.Application, $"Failed to query Available RAM. host_statistics64() error = {result}");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (ulong)(stats.FreeCount + stats.InactiveCount) * pageSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
private const string SystemLibraryName = "libSystem.dylib";
|
||||||
|
|
||||||
|
[DllImport(SystemLibraryName, CharSet = CharSet.Ansi, SetLastError = true)]
|
||||||
private static extern int sysctlbyname(string name, IntPtr oldValue, ref ulong oldSize, IntPtr newValue, ulong newValueSize);
|
private static extern int sysctlbyname(string name, IntPtr oldValue, ref ulong oldSize, IntPtr newValue, ulong newValueSize);
|
||||||
|
|
||||||
private static int sysctlbyname(string name, IntPtr oldValue, ref ulong oldSize)
|
private static int sysctlbyname(string name, IntPtr oldValue, ref ulong oldSize)
|
||||||
@@ -85,5 +115,43 @@ namespace Ryujinx.Common.SystemInfo
|
|||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[DllImport(SystemLibraryName, CharSet = CharSet.Ansi, SetLastError = true)]
|
||||||
|
private static extern uint mach_host_self();
|
||||||
|
|
||||||
|
[DllImport(SystemLibraryName, CharSet = CharSet.Ansi, SetLastError = true)]
|
||||||
|
private static extern int host_page_size(uint host, ref uint out_page_size);
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 8)]
|
||||||
|
struct VMStatistics64
|
||||||
|
{
|
||||||
|
public uint FreeCount;
|
||||||
|
public uint ActiveCount;
|
||||||
|
public uint InactiveCount;
|
||||||
|
public uint WireCount;
|
||||||
|
public ulong ZeroFillCount;
|
||||||
|
public ulong Reactivations;
|
||||||
|
public ulong Pageins;
|
||||||
|
public ulong Pageouts;
|
||||||
|
public ulong Faults;
|
||||||
|
public ulong CowFaults;
|
||||||
|
public ulong Lookups;
|
||||||
|
public ulong Hits;
|
||||||
|
public ulong Purges;
|
||||||
|
public uint PurgeableCount;
|
||||||
|
public uint SpeculativeCount;
|
||||||
|
public ulong Decompressions;
|
||||||
|
public ulong Compressions;
|
||||||
|
public ulong Swapins;
|
||||||
|
public ulong Swapouts;
|
||||||
|
public uint CompressorPageCount;
|
||||||
|
public uint ThrottledCount;
|
||||||
|
public uint ExternalPageCount;
|
||||||
|
public uint InternalPageCount;
|
||||||
|
public ulong TotalUncompressedPagesInCompressor;
|
||||||
|
}
|
||||||
|
|
||||||
|
[DllImport(SystemLibraryName, CharSet = CharSet.Ansi, SetLastError = true)]
|
||||||
|
private static extern int host_statistics64(uint host_priv, int host_flavor, ref VMStatistics64 host_info64_out, ref uint host_info64_outCnt);
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -202,57 +202,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
|||||||
_channel.BufferManager.SetComputeUniformBuffer(cb.Slot, cbDescriptor.PackAddress(), (uint)cbDescriptor.Size);
|
_channel.BufferManager.SetComputeUniformBuffer(cb.Slot, cbDescriptor.PackAddress(), (uint)cbDescriptor.Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
_channel.BufferManager.SetComputeStorageBufferBindings(info.SBuffers);
|
_channel.BufferManager.SetComputeBufferBindings(cs.Bindings);
|
||||||
_channel.BufferManager.SetComputeUniformBufferBindings(info.CBuffers);
|
|
||||||
|
|
||||||
int maxTextureBinding = -1;
|
_channel.TextureManager.SetComputeBindings(cs.Bindings);
|
||||||
int maxImageBinding = -1;
|
|
||||||
|
|
||||||
TextureBindingInfo[] textureBindings = _channel.TextureManager.RentComputeTextureBindings(info.Textures.Count);
|
|
||||||
|
|
||||||
for (int index = 0; index < info.Textures.Count; index++)
|
|
||||||
{
|
|
||||||
var descriptor = info.Textures[index];
|
|
||||||
|
|
||||||
Target target = ShaderTexture.GetTarget(descriptor.Type);
|
|
||||||
|
|
||||||
textureBindings[index] = new TextureBindingInfo(
|
|
||||||
target,
|
|
||||||
descriptor.Binding,
|
|
||||||
descriptor.CbufSlot,
|
|
||||||
descriptor.HandleIndex,
|
|
||||||
descriptor.Flags);
|
|
||||||
|
|
||||||
if (descriptor.Binding > maxTextureBinding)
|
|
||||||
{
|
|
||||||
maxTextureBinding = descriptor.Binding;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TextureBindingInfo[] imageBindings = _channel.TextureManager.RentComputeImageBindings(info.Images.Count);
|
|
||||||
|
|
||||||
for (int index = 0; index < info.Images.Count; index++)
|
|
||||||
{
|
|
||||||
var descriptor = info.Images[index];
|
|
||||||
|
|
||||||
Target target = ShaderTexture.GetTarget(descriptor.Type);
|
|
||||||
Format format = ShaderTexture.GetFormat(descriptor.Format);
|
|
||||||
|
|
||||||
imageBindings[index] = new TextureBindingInfo(
|
|
||||||
target,
|
|
||||||
format,
|
|
||||||
descriptor.Binding,
|
|
||||||
descriptor.CbufSlot,
|
|
||||||
descriptor.HandleIndex,
|
|
||||||
descriptor.Flags);
|
|
||||||
|
|
||||||
if (descriptor.Binding > maxImageBinding)
|
|
||||||
{
|
|
||||||
maxImageBinding = descriptor.Binding;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_channel.TextureManager.SetComputeMaxBindings(maxTextureBinding, maxImageBinding);
|
|
||||||
|
|
||||||
// Should never return false for mismatching spec state, since the shader was fetched above.
|
// Should never return false for mismatching spec state, since the shader was fetched above.
|
||||||
_channel.TextureManager.CommitComputeBindings(cs.SpecializationState);
|
_channel.TextureManager.CommitComputeBindings(cs.SpecializationState);
|
||||||
|
@@ -1257,88 +1257,24 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|||||||
UpdateUserClipState();
|
UpdateUserClipState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateShaderBindings(gs.Bindings);
|
||||||
|
|
||||||
for (int stageIndex = 0; stageIndex < Constants.ShaderStages; stageIndex++)
|
for (int stageIndex = 0; stageIndex < Constants.ShaderStages; stageIndex++)
|
||||||
{
|
{
|
||||||
UpdateStageBindings(stageIndex, gs.Shaders[stageIndex + 1]?.Info);
|
_currentProgramInfo[stageIndex] = gs.Shaders[stageIndex + 1]?.Info;
|
||||||
}
|
}
|
||||||
|
|
||||||
_context.Renderer.Pipeline.SetProgram(gs.HostProgram);
|
_context.Renderer.Pipeline.SetProgram(gs.HostProgram);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Updates bindings consumed by the shader stage on the texture and buffer managers.
|
/// Updates bindings consumed by the shader on the texture and buffer managers.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="stage">Shader stage to have the bindings updated</param>
|
/// <param name="bindings">Bindings for the active shader</param>
|
||||||
/// <param name="info">Shader stage bindings info</param>
|
private void UpdateShaderBindings(CachedShaderBindings bindings)
|
||||||
private void UpdateStageBindings(int stage, ShaderProgramInfo info)
|
|
||||||
{
|
{
|
||||||
_currentProgramInfo[stage] = info;
|
_channel.TextureManager.SetGraphicsBindings(bindings);
|
||||||
|
_channel.BufferManager.SetGraphicsBufferBindings(bindings);
|
||||||
if (info == null)
|
|
||||||
{
|
|
||||||
_channel.TextureManager.RentGraphicsTextureBindings(stage, 0);
|
|
||||||
_channel.TextureManager.RentGraphicsImageBindings(stage, 0);
|
|
||||||
_channel.BufferManager.SetGraphicsStorageBufferBindings(stage, null);
|
|
||||||
_channel.BufferManager.SetGraphicsUniformBufferBindings(stage, null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int maxTextureBinding = -1;
|
|
||||||
int maxImageBinding = -1;
|
|
||||||
|
|
||||||
Span<TextureBindingInfo> textureBindings = _channel.TextureManager.RentGraphicsTextureBindings(stage, info.Textures.Count);
|
|
||||||
|
|
||||||
if (info.UsesRtLayer)
|
|
||||||
{
|
|
||||||
_vtgWritesRtLayer = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int index = 0; index < info.Textures.Count; index++)
|
|
||||||
{
|
|
||||||
var descriptor = info.Textures[index];
|
|
||||||
|
|
||||||
Target target = ShaderTexture.GetTarget(descriptor.Type);
|
|
||||||
|
|
||||||
textureBindings[index] = new TextureBindingInfo(
|
|
||||||
target,
|
|
||||||
descriptor.Binding,
|
|
||||||
descriptor.CbufSlot,
|
|
||||||
descriptor.HandleIndex,
|
|
||||||
descriptor.Flags);
|
|
||||||
|
|
||||||
if (descriptor.Binding > maxTextureBinding)
|
|
||||||
{
|
|
||||||
maxTextureBinding = descriptor.Binding;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TextureBindingInfo[] imageBindings = _channel.TextureManager.RentGraphicsImageBindings(stage, info.Images.Count);
|
|
||||||
|
|
||||||
for (int index = 0; index < info.Images.Count; index++)
|
|
||||||
{
|
|
||||||
var descriptor = info.Images[index];
|
|
||||||
|
|
||||||
Target target = ShaderTexture.GetTarget(descriptor.Type);
|
|
||||||
Format format = ShaderTexture.GetFormat(descriptor.Format);
|
|
||||||
|
|
||||||
imageBindings[index] = new TextureBindingInfo(
|
|
||||||
target,
|
|
||||||
format,
|
|
||||||
descriptor.Binding,
|
|
||||||
descriptor.CbufSlot,
|
|
||||||
descriptor.HandleIndex,
|
|
||||||
descriptor.Flags);
|
|
||||||
|
|
||||||
if (descriptor.Binding > maxImageBinding)
|
|
||||||
{
|
|
||||||
maxImageBinding = descriptor.Binding;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_channel.TextureManager.SetGraphicsMaxBindings(maxTextureBinding, maxImageBinding);
|
|
||||||
|
|
||||||
_channel.BufferManager.SetGraphicsStorageBufferBindings(stage, info.SBuffers);
|
|
||||||
_channel.BufferManager.SetGraphicsUniformBufferBindings(stage, info.CBuffers);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@@ -37,8 +37,8 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
private TexturePool _cachedTexturePool;
|
private TexturePool _cachedTexturePool;
|
||||||
private SamplerPool _cachedSamplerPool;
|
private SamplerPool _cachedSamplerPool;
|
||||||
|
|
||||||
private readonly TextureBindingInfo[][] _textureBindings;
|
private TextureBindingInfo[][] _textureBindings;
|
||||||
private readonly TextureBindingInfo[][] _imageBindings;
|
private TextureBindingInfo[][] _imageBindings;
|
||||||
|
|
||||||
private struct TextureState
|
private struct TextureState
|
||||||
{
|
{
|
||||||
@@ -56,9 +56,6 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
private TextureState[] _textureState;
|
private TextureState[] _textureState;
|
||||||
private TextureState[] _imageState;
|
private TextureState[] _imageState;
|
||||||
|
|
||||||
private int[] _textureBindingsCount;
|
|
||||||
private int[] _imageBindingsCount;
|
|
||||||
|
|
||||||
private int _texturePoolSequence;
|
private int _texturePoolSequence;
|
||||||
private int _samplerPoolSequence;
|
private int _samplerPoolSequence;
|
||||||
|
|
||||||
@@ -101,9 +98,6 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
_textureState = new TextureState[InitialTextureStateSize];
|
_textureState = new TextureState[InitialTextureStateSize];
|
||||||
_imageState = new TextureState[InitialImageStateSize];
|
_imageState = new TextureState[InitialImageStateSize];
|
||||||
|
|
||||||
_textureBindingsCount = new int[stages];
|
|
||||||
_imageBindingsCount = new int[stages];
|
|
||||||
|
|
||||||
for (int stage = 0; stage < stages; stage++)
|
for (int stage = 0; stage < stages; stage++)
|
||||||
{
|
{
|
||||||
_textureBindings[stage] = new TextureBindingInfo[InitialTextureStateSize];
|
_textureBindings[stage] = new TextureBindingInfo[InitialTextureStateSize];
|
||||||
@@ -112,39 +106,15 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Rents the texture bindings array for a given stage, so that they can be modified.
|
/// Sets the texture and image bindings.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="stage">Shader stage number, or 0 for compute shaders</param>
|
/// <param name="bindings">Bindings for the active shader</param>
|
||||||
/// <param name="count">The number of bindings needed</param>
|
public void SetBindings(CachedShaderBindings bindings)
|
||||||
/// <returns>The texture bindings array</returns>
|
|
||||||
public TextureBindingInfo[] RentTextureBindings(int stage, int count)
|
|
||||||
{
|
{
|
||||||
if (count > _textureBindings[stage].Length)
|
_textureBindings = bindings.TextureBindings;
|
||||||
{
|
_imageBindings = bindings.ImageBindings;
|
||||||
Array.Resize(ref _textureBindings[stage], count);
|
|
||||||
}
|
|
||||||
|
|
||||||
_textureBindingsCount[stage] = count;
|
SetMaxBindings(bindings.MaxTextureBinding, bindings.MaxImageBinding);
|
||||||
|
|
||||||
return _textureBindings[stage];
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Rents the image bindings array for a given stage, so that they can be modified.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="stage">Shader stage number, or 0 for compute shaders</param>
|
|
||||||
/// <param name="count">The number of bindings needed</param>
|
|
||||||
/// <returns>The image bindings array</returns>
|
|
||||||
public TextureBindingInfo[] RentImageBindings(int stage, int count)
|
|
||||||
{
|
|
||||||
if (count > _imageBindings[stage].Length)
|
|
||||||
{
|
|
||||||
Array.Resize(ref _imageBindings[stage], count);
|
|
||||||
}
|
|
||||||
|
|
||||||
_imageBindingsCount[stage] = count;
|
|
||||||
|
|
||||||
return _imageBindings[stage];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -257,7 +227,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
|
|
||||||
case ShaderStage.Vertex:
|
case ShaderStage.Vertex:
|
||||||
int fragmentIndex = (int)ShaderStage.Fragment - 1;
|
int fragmentIndex = (int)ShaderStage.Fragment - 1;
|
||||||
index += _textureBindingsCount[fragmentIndex] + _imageBindingsCount[fragmentIndex];
|
index += _textureBindings[fragmentIndex].Length + _imageBindings[fragmentIndex].Length;
|
||||||
|
|
||||||
result = texture.ScaleFactor;
|
result = texture.ScaleFactor;
|
||||||
break;
|
break;
|
||||||
@@ -284,7 +254,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private bool VertexRequiresScale()
|
private bool VertexRequiresScale()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < _textureBindingsCount[0]; i++)
|
for (int i = 0; i < _textureBindings[0].Length; i++)
|
||||||
{
|
{
|
||||||
if ((_textureBindings[0][i].Flags & TextureUsageFlags.NeedsScaleValue) != 0)
|
if ((_textureBindings[0][i].Flags & TextureUsageFlags.NeedsScaleValue) != 0)
|
||||||
{
|
{
|
||||||
@@ -292,7 +262,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < _imageBindingsCount[0]; i++)
|
for (int i = 0; i < _imageBindings[0].Length; i++)
|
||||||
{
|
{
|
||||||
if ((_imageBindings[0][i].Flags & TextureUsageFlags.NeedsScaleValue) != 0)
|
if ((_imageBindings[0][i].Flags & TextureUsageFlags.NeedsScaleValue) != 0)
|
||||||
{
|
{
|
||||||
@@ -309,10 +279,10 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
private void CommitRenderScale()
|
private void CommitRenderScale()
|
||||||
{
|
{
|
||||||
// Stage 0 total: Compute or Vertex.
|
// Stage 0 total: Compute or Vertex.
|
||||||
int total = _textureBindingsCount[0] + _imageBindingsCount[0];
|
int total = _textureBindings[0].Length + _imageBindings[0].Length;
|
||||||
|
|
||||||
int fragmentIndex = (int)ShaderStage.Fragment - 1;
|
int fragmentIndex = (int)ShaderStage.Fragment - 1;
|
||||||
int fragmentTotal = _isCompute ? 0 : (_textureBindingsCount[fragmentIndex] + _imageBindingsCount[fragmentIndex]);
|
int fragmentTotal = _isCompute ? 0 : (_textureBindings[fragmentIndex].Length + _imageBindings[fragmentIndex].Length);
|
||||||
|
|
||||||
if (total != 0 && fragmentTotal != _lastFragmentTotal && VertexRequiresScale())
|
if (total != 0 && fragmentTotal != _lastFragmentTotal && VertexRequiresScale())
|
||||||
{
|
{
|
||||||
@@ -481,7 +451,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
bool poolModified,
|
bool poolModified,
|
||||||
ShaderSpecializationState specState)
|
ShaderSpecializationState specState)
|
||||||
{
|
{
|
||||||
int textureCount = _textureBindingsCount[stageIndex];
|
int textureCount = _textureBindings[stageIndex].Length;
|
||||||
if (textureCount == 0)
|
if (textureCount == 0)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
@@ -609,7 +579,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
/// <returns>True if all bound images match the current shader specialiation state, false otherwise</returns>
|
/// <returns>True if all bound images match the current shader specialiation state, false otherwise</returns>
|
||||||
private bool CommitImageBindings(TexturePool pool, ShaderStage stage, int stageIndex, bool poolModified, ShaderSpecializationState specState)
|
private bool CommitImageBindings(TexturePool pool, ShaderStage stage, int stageIndex, bool poolModified, ShaderSpecializationState specState)
|
||||||
{
|
{
|
||||||
int imageCount = _imageBindingsCount[stageIndex];
|
int imageCount = _imageBindings[stageIndex].Length;
|
||||||
if (imageCount == 0)
|
if (imageCount == 0)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
@@ -622,7 +592,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Scales for images appear after the texture ones.
|
// Scales for images appear after the texture ones.
|
||||||
int baseScaleIndex = _textureBindingsCount[stageIndex];
|
int baseScaleIndex = _textureBindings[stageIndex].Length;
|
||||||
|
|
||||||
int cachedTextureBufferIndex = -1;
|
int cachedTextureBufferIndex = -1;
|
||||||
int cachedSamplerBufferIndex = -1;
|
int cachedSamplerBufferIndex = -1;
|
||||||
|
@@ -57,45 +57,21 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Rents the texture bindings array of the compute pipeline.
|
/// Sets the texture and image bindings for the compute pipeline.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="count">The number of bindings needed</param>
|
/// <param name="bindings">Bindings for the active shader</param>
|
||||||
/// <returns>The texture bindings array</returns>
|
public void SetComputeBindings(CachedShaderBindings bindings)
|
||||||
public TextureBindingInfo[] RentComputeTextureBindings(int count)
|
|
||||||
{
|
{
|
||||||
return _cpBindingsManager.RentTextureBindings(0, count);
|
_cpBindingsManager.SetBindings(bindings);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Rents the texture bindings array for a given stage on the graphics pipeline.
|
/// Sets the texture and image bindings for the graphics pipeline.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="stage">The index of the shader stage to bind the textures</param>
|
/// <param name="bindings">Bindings for the active shader</param>
|
||||||
/// <param name="count">The number of bindings needed</param>
|
public void SetGraphicsBindings(CachedShaderBindings bindings)
|
||||||
/// <returns>The texture bindings array</returns>
|
|
||||||
public TextureBindingInfo[] RentGraphicsTextureBindings(int stage, int count)
|
|
||||||
{
|
{
|
||||||
return _gpBindingsManager.RentTextureBindings(stage, count);
|
_gpBindingsManager.SetBindings(bindings);
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Rents the image bindings array of the compute pipeline.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="count">The number of bindings needed</param>
|
|
||||||
/// <returns>The image bindings array</returns>
|
|
||||||
public TextureBindingInfo[] RentComputeImageBindings(int count)
|
|
||||||
{
|
|
||||||
return _cpBindingsManager.RentImageBindings(0, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Rents the image bindings array for a given stage on the graphics pipeline.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="stage">The index of the shader stage to bind the images</param>
|
|
||||||
/// <param name="count">The number of bindings needed</param>
|
|
||||||
/// <returns>The image bindings array</returns>
|
|
||||||
public TextureBindingInfo[] RentGraphicsImageBindings(int stage, int count)
|
|
||||||
{
|
|
||||||
return _gpBindingsManager.RentImageBindings(stage, count);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -107,16 +83,6 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
_cpBindingsManager.SetTextureBufferIndex(index);
|
_cpBindingsManager.SetTextureBufferIndex(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sets the max binding indexes on the compute pipeline.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="maxTextureBinding">The maximum texture binding</param>
|
|
||||||
/// <param name="maxImageBinding">The maximum image binding</param>
|
|
||||||
public void SetComputeMaxBindings(int maxTextureBinding, int maxImageBinding)
|
|
||||||
{
|
|
||||||
_cpBindingsManager.SetMaxBindings(maxTextureBinding, maxImageBinding);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets the texture constant buffer index on the graphics pipeline.
|
/// Sets the texture constant buffer index on the graphics pipeline.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -126,16 +92,6 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
_gpBindingsManager.SetTextureBufferIndex(index);
|
_gpBindingsManager.SetTextureBufferIndex(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sets the max binding indexes on the graphics pipeline.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="maxTextureBinding">The maximum texture binding</param>
|
|
||||||
/// <param name="maxImageBinding">The maximum image binding</param>
|
|
||||||
public void SetGraphicsMaxBindings(int maxTextureBinding, int maxImageBinding)
|
|
||||||
{
|
|
||||||
_gpBindingsManager.SetMaxBindings(maxTextureBinding, maxImageBinding);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets the current sampler pool on the compute pipeline.
|
/// Sets the current sampler pool on the compute pipeline.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.Gpu.Image;
|
using Ryujinx.Graphics.Gpu.Image;
|
||||||
|
using Ryujinx.Graphics.Gpu.Shader;
|
||||||
using Ryujinx.Graphics.Shader;
|
using Ryujinx.Graphics.Shader;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Gpu.Memory
|
namespace Ryujinx.Graphics.Gpu.Memory
|
||||||
@@ -34,7 +34,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Shader buffer binding information.
|
/// Shader buffer binding information.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public BufferDescriptor[] Bindings { get; }
|
public BufferDescriptor[] Bindings { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Buffer regions.
|
/// Buffer regions.
|
||||||
@@ -78,7 +78,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||||||
/// Sets shader buffer binding information.
|
/// Sets shader buffer binding information.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="descriptors">Buffer binding information</param>
|
/// <param name="descriptors">Buffer binding information</param>
|
||||||
public void SetBindings(ReadOnlyCollection<BufferDescriptor> descriptors)
|
public void SetBindings(BufferDescriptor[] descriptors)
|
||||||
{
|
{
|
||||||
if (descriptors == null)
|
if (descriptors == null)
|
||||||
{
|
{
|
||||||
@@ -86,8 +86,10 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
descriptors.CopyTo(Bindings, 0);
|
if ((Count = descriptors.Length) != 0)
|
||||||
Count = descriptors.Count;
|
{
|
||||||
|
Bindings = descriptors;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -320,41 +322,26 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets the binding points for the storage buffers bound on the compute pipeline.
|
/// Sets the binding points for the storage buffers bound on the compute pipeline.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="descriptors">Buffer descriptors with the binding point values</param>
|
/// <param name="bindings">Bindings for the active shader</param>
|
||||||
public void SetComputeStorageBufferBindings(ReadOnlyCollection<BufferDescriptor> descriptors)
|
public void SetComputeBufferBindings(CachedShaderBindings bindings)
|
||||||
{
|
{
|
||||||
_cpStorageBuffers.SetBindings(descriptors);
|
_cpStorageBuffers.SetBindings(bindings.StorageBufferBindings[0]);
|
||||||
|
_cpUniformBuffers.SetBindings(bindings.ConstantBufferBindings[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets the binding points for the storage buffers bound on the graphics pipeline.
|
/// Sets the binding points for the storage buffers bound on the graphics pipeline.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="stage">Index of the shader stage</param>
|
/// <param name="bindings">Bindings for the active shader</param>
|
||||||
/// <param name="descriptors">Buffer descriptors with the binding point values</param>
|
public void SetGraphicsBufferBindings(CachedShaderBindings bindings)
|
||||||
public void SetGraphicsStorageBufferBindings(int stage, ReadOnlyCollection<BufferDescriptor> descriptors)
|
|
||||||
{
|
{
|
||||||
_gpStorageBuffers[stage].SetBindings(descriptors);
|
for (int i = 0; i < Constants.ShaderStages; i++)
|
||||||
|
{
|
||||||
|
_gpStorageBuffers[i].SetBindings(bindings.StorageBufferBindings[i]);
|
||||||
|
_gpUniformBuffers[i].SetBindings(bindings.ConstantBufferBindings[i]);
|
||||||
|
}
|
||||||
|
|
||||||
_gpStorageBuffersDirty = true;
|
_gpStorageBuffersDirty = true;
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sets the binding points for the uniform buffers bound on the compute pipeline.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="descriptors">Buffer descriptors with the binding point values</param>
|
|
||||||
public void SetComputeUniformBufferBindings(ReadOnlyCollection<BufferDescriptor> descriptors)
|
|
||||||
{
|
|
||||||
_cpUniformBuffers.SetBindings(descriptors);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sets the enabled uniform buffers mask on the graphics pipeline.
|
|
||||||
/// Each bit set on the mask indicates that the respective buffer index is enabled.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="stage">Index of the shader stage</param>
|
|
||||||
/// <param name="descriptors">Buffer descriptors with the binding point values</param>
|
|
||||||
public void SetGraphicsUniformBufferBindings(int stage, ReadOnlyCollection<BufferDescriptor> descriptors)
|
|
||||||
{
|
|
||||||
_gpUniformBuffers[stage].SetBindings(descriptors);
|
|
||||||
_gpUniformBuffersDirty = true;
|
_gpUniformBuffersDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
103
Ryujinx.Graphics.Gpu/Shader/CachedShaderBindings.cs
Normal file
103
Ryujinx.Graphics.Gpu/Shader/CachedShaderBindings.cs
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
using Ryujinx.Graphics.GAL;
|
||||||
|
using Ryujinx.Graphics.Gpu.Engine;
|
||||||
|
using Ryujinx.Graphics.Gpu.Image;
|
||||||
|
using Ryujinx.Graphics.Shader;
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A collection of shader bindings ready for insertion into the buffer and texture managers.
|
||||||
|
/// </summary>
|
||||||
|
internal class CachedShaderBindings
|
||||||
|
{
|
||||||
|
public TextureBindingInfo[][] TextureBindings { get; }
|
||||||
|
public TextureBindingInfo[][] ImageBindings { get; }
|
||||||
|
public BufferDescriptor[][] ConstantBufferBindings { get; }
|
||||||
|
public BufferDescriptor[][] StorageBufferBindings { get; }
|
||||||
|
|
||||||
|
public int MaxTextureBinding { get; }
|
||||||
|
public int MaxImageBinding { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a new cached shader bindings collection.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="isCompute">Whether the shader is for compute</param>
|
||||||
|
/// <param name="stages">The stages used by the shader</param>
|
||||||
|
public CachedShaderBindings(bool isCompute, CachedShaderStage[] stages)
|
||||||
|
{
|
||||||
|
int stageCount = isCompute ? 1 : Constants.ShaderStages;
|
||||||
|
|
||||||
|
TextureBindings = new TextureBindingInfo[stageCount][];
|
||||||
|
ImageBindings = new TextureBindingInfo[stageCount][];
|
||||||
|
ConstantBufferBindings = new BufferDescriptor[stageCount][];
|
||||||
|
StorageBufferBindings = new BufferDescriptor[stageCount][];
|
||||||
|
|
||||||
|
int maxTextureBinding = -1;
|
||||||
|
int maxImageBinding = -1;
|
||||||
|
int offset = isCompute ? 0 : 1;
|
||||||
|
|
||||||
|
for (int i = 0; i < stageCount; i++)
|
||||||
|
{
|
||||||
|
CachedShaderStage stage = stages[i + offset];
|
||||||
|
|
||||||
|
if (stage == null)
|
||||||
|
{
|
||||||
|
TextureBindings[i] = Array.Empty<TextureBindingInfo>();
|
||||||
|
ImageBindings[i] = Array.Empty<TextureBindingInfo>();
|
||||||
|
ConstantBufferBindings[i] = Array.Empty<BufferDescriptor>();
|
||||||
|
StorageBufferBindings[i] = Array.Empty<BufferDescriptor>();
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
TextureBindings[i] = stage.Info.Textures.Select(descriptor =>
|
||||||
|
{
|
||||||
|
Target target = ShaderTexture.GetTarget(descriptor.Type);
|
||||||
|
|
||||||
|
var result = new TextureBindingInfo(
|
||||||
|
target,
|
||||||
|
descriptor.Binding,
|
||||||
|
descriptor.CbufSlot,
|
||||||
|
descriptor.HandleIndex,
|
||||||
|
descriptor.Flags);
|
||||||
|
|
||||||
|
if (descriptor.Binding > maxTextureBinding)
|
||||||
|
{
|
||||||
|
maxTextureBinding = descriptor.Binding;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}).ToArray();
|
||||||
|
|
||||||
|
ImageBindings[i] = stage.Info.Images.Select(descriptor =>
|
||||||
|
{
|
||||||
|
Target target = ShaderTexture.GetTarget(descriptor.Type);
|
||||||
|
Format format = ShaderTexture.GetFormat(descriptor.Format);
|
||||||
|
|
||||||
|
var result = new TextureBindingInfo(
|
||||||
|
target,
|
||||||
|
format,
|
||||||
|
descriptor.Binding,
|
||||||
|
descriptor.CbufSlot,
|
||||||
|
descriptor.HandleIndex,
|
||||||
|
descriptor.Flags);
|
||||||
|
|
||||||
|
if (descriptor.Binding > maxImageBinding)
|
||||||
|
{
|
||||||
|
maxImageBinding = descriptor.Binding;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}).ToArray();
|
||||||
|
|
||||||
|
ConstantBufferBindings[i] = stage.Info.CBuffers.ToArray();
|
||||||
|
StorageBufferBindings[i] = stage.Info.SBuffers.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
MaxTextureBinding = maxTextureBinding;
|
||||||
|
MaxImageBinding = maxImageBinding;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -24,6 +24,11 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public CachedShaderStage[] Shaders { get; }
|
public CachedShaderStage[] Shaders { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Cached shader bindings, ready for placing into the bindings manager.
|
||||||
|
/// </summary>
|
||||||
|
public CachedShaderBindings Bindings { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new instance of the shader bundle.
|
/// Creates a new instance of the shader bundle.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -37,6 +42,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
Shaders = shaders;
|
Shaders = shaders;
|
||||||
|
|
||||||
SpecializationState.Prepare(shaders);
|
SpecializationState.Prepare(shaders);
|
||||||
|
Bindings = new CachedShaderBindings(shaders.Length == 1, shaders);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@@ -11,9 +11,10 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
Unknown
|
Unknown
|
||||||
}
|
}
|
||||||
|
|
||||||
static class VendorUtils
|
static partial class VendorUtils
|
||||||
{
|
{
|
||||||
public static Regex AmdGcnRegex = new Regex(@"Radeon (((HD|R(5|7|9|X)) )?((M?[2-6]\d{2}(\D|$))|([7-8]\d{3}(\D|$))|Fury|Nano))|(Pro Duo)");
|
[GeneratedRegex("Radeon (((HD|R(5|7|9|X)) )?((M?[2-6]\\d{2}(\\D|$))|([7-8]\\d{3}(\\D|$))|Fury|Nano))|(Pro Duo)")]
|
||||||
|
public static partial Regex AmdGcnRegex();
|
||||||
|
|
||||||
public static Vendor FromId(uint id)
|
public static Vendor FromId(uint id)
|
||||||
{
|
{
|
||||||
|
@@ -471,7 +471,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
GpuRenderer = Marshal.PtrToStringAnsi((IntPtr)properties.DeviceName);
|
GpuRenderer = Marshal.PtrToStringAnsi((IntPtr)properties.DeviceName);
|
||||||
GpuVersion = $"Vulkan v{ParseStandardVulkanVersion(properties.ApiVersion)}, Driver v{ParseDriverVersion(ref properties)}";
|
GpuVersion = $"Vulkan v{ParseStandardVulkanVersion(properties.ApiVersion)}, Driver v{ParseDriverVersion(ref properties)}";
|
||||||
|
|
||||||
IsAmdGcn = Vendor == Vendor.Amd && VendorUtils.AmdGcnRegex.IsMatch(GpuRenderer);
|
IsAmdGcn = Vendor == Vendor.Amd && VendorUtils.AmdGcnRegex().IsMatch(GpuRenderer);
|
||||||
|
|
||||||
Logger.Notice.Print(LogClass.Gpu, $"{GpuVendor} {GpuRenderer} ({GpuVersion})");
|
Logger.Notice.Print(LogClass.Gpu, $"{GpuVendor} {GpuRenderer} ({GpuVersion})");
|
||||||
}
|
}
|
||||||
|
@@ -18,7 +18,7 @@ using System.Text.RegularExpressions;
|
|||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Applets.Error
|
namespace Ryujinx.HLE.HOS.Applets.Error
|
||||||
{
|
{
|
||||||
internal class ErrorApplet : IApplet
|
internal partial class ErrorApplet : IApplet
|
||||||
{
|
{
|
||||||
private const long ErrorMessageBinaryTitleId = 0x0100000000000801;
|
private const long ErrorMessageBinaryTitleId = 0x0100000000000801;
|
||||||
|
|
||||||
@@ -30,6 +30,9 @@ namespace Ryujinx.HLE.HOS.Applets.Error
|
|||||||
|
|
||||||
public event EventHandler AppletStateChanged;
|
public event EventHandler AppletStateChanged;
|
||||||
|
|
||||||
|
[GeneratedRegex(@"[^\u0000\u0009\u000A\u000D\u0020-\uFFFF]..")]
|
||||||
|
private static partial Regex CleanTextRegex();
|
||||||
|
|
||||||
public ErrorApplet(Horizon horizon)
|
public ErrorApplet(Horizon horizon)
|
||||||
{
|
{
|
||||||
_horizon = horizon;
|
_horizon = horizon;
|
||||||
@@ -101,7 +104,7 @@ namespace Ryujinx.HLE.HOS.Applets.Error
|
|||||||
|
|
||||||
private static string CleanText(string value)
|
private static string CleanText(string value)
|
||||||
{
|
{
|
||||||
return Regex.Replace(value, @"[^\u0000\u0009\u000A\u000D\u0020-\uFFFF]..", "").Replace("\0", "");
|
return CleanTextRegex().Replace(value, "").Replace("\0", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetMessageText(uint module, uint description, string key)
|
private string GetMessageText(uint module, uint description, string key)
|
||||||
|
@@ -2,18 +2,30 @@
|
|||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres.Proxy
|
namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres.Proxy
|
||||||
{
|
{
|
||||||
static class DnsBlacklist
|
static partial class DnsBlacklist
|
||||||
{
|
{
|
||||||
const RegexOptions RegexOpts = RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture | RegexOptions.Compiled;
|
const RegexOptions RegexOpts = RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture;
|
||||||
|
|
||||||
private static readonly Regex[] BlockedHosts = new Regex[]
|
[GeneratedRegex(@"^(.*)\-lp1\.(n|s)\.n\.srv\.nintendo\.net$", RegexOpts)]
|
||||||
{
|
private static partial Regex BlockedHost1();
|
||||||
new Regex(@"^(.*)\-lp1\.(n|s)\.n\.srv\.nintendo\.net$", RegexOpts),
|
[GeneratedRegex(@"^(.*)\-lp1\.lp1\.t\.npln\.srv\.nintendo\.net$", RegexOpts)]
|
||||||
new Regex(@"^(.*)\-lp1\.lp1\.t\.npln\.srv\.nintendo\.net$", RegexOpts),
|
private static partial Regex BlockedHost2();
|
||||||
new Regex(@"^(.*)\-lp1\.(znc|p)\.srv\.nintendo\.net$", RegexOpts),
|
[GeneratedRegex(@"^(.*)\-lp1\.(znc|p)\.srv\.nintendo\.net$", RegexOpts)]
|
||||||
new Regex(@"^(.*)\-sb\-api\.accounts\.nintendo\.com$", RegexOpts),
|
private static partial Regex BlockedHost3();
|
||||||
new Regex(@"^(.*)\-sb\.accounts\.nintendo\.com$", RegexOpts),
|
[GeneratedRegex(@"^(.*)\-sb\-api\.accounts\.nintendo\.com$", RegexOpts)]
|
||||||
new Regex(@"^accounts\.nintendo\.com$", RegexOpts)
|
private static partial Regex BlockedHost4();
|
||||||
|
[GeneratedRegex(@"^(.*)\-sb\.accounts\.nintendo\.com$", RegexOpts)]
|
||||||
|
private static partial Regex BlockedHost5();
|
||||||
|
[GeneratedRegex(@"^accounts\.nintendo\.com$", RegexOpts)]
|
||||||
|
private static partial Regex BlockedHost6();
|
||||||
|
|
||||||
|
private static readonly Regex[] BlockedHosts = {
|
||||||
|
BlockedHost1(),
|
||||||
|
BlockedHost2(),
|
||||||
|
BlockedHost3(),
|
||||||
|
BlockedHost4(),
|
||||||
|
BlockedHost5(),
|
||||||
|
BlockedHost6()
|
||||||
};
|
};
|
||||||
|
|
||||||
public static bool IsHostBlocked(string host)
|
public static bool IsHostBlocked(string host)
|
||||||
|
@@ -9,7 +9,7 @@ using System.Text.RegularExpressions;
|
|||||||
|
|
||||||
namespace Ryujinx.HLE.Loaders.Executables
|
namespace Ryujinx.HLE.Loaders.Executables
|
||||||
{
|
{
|
||||||
class NsoExecutable : IExecutable
|
partial class NsoExecutable : IExecutable
|
||||||
{
|
{
|
||||||
public byte[] Program { get; }
|
public byte[] Program { get; }
|
||||||
public Span<byte> Text => Program.AsSpan((int)TextOffset, (int)TextSize);
|
public Span<byte> Text => Program.AsSpan((int)TextOffset, (int)TextSize);
|
||||||
@@ -29,6 +29,13 @@ namespace Ryujinx.HLE.Loaders.Executables
|
|||||||
public string Name;
|
public string Name;
|
||||||
public Array32<byte> BuildId;
|
public Array32<byte> BuildId;
|
||||||
|
|
||||||
|
[GeneratedRegex(@"[a-z]:[\\/][ -~]{5,}\.nss", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)]
|
||||||
|
private static partial Regex ModuleRegex();
|
||||||
|
[GeneratedRegex(@"sdk_version: ([0-9.]*)")]
|
||||||
|
private static partial Regex FsSdkRegex();
|
||||||
|
[GeneratedRegex(@"SDK MW[ -~]*")]
|
||||||
|
private static partial Regex SdkMwRegex();
|
||||||
|
|
||||||
public NsoExecutable(IStorage inStorage, string name = null)
|
public NsoExecutable(IStorage inStorage, string name = null)
|
||||||
{
|
{
|
||||||
NsoReader reader = new NsoReader();
|
NsoReader reader = new NsoReader();
|
||||||
@@ -83,7 +90,7 @@ namespace Ryujinx.HLE.Loaders.Executables
|
|||||||
|
|
||||||
if (string.IsNullOrEmpty(modulePath))
|
if (string.IsNullOrEmpty(modulePath))
|
||||||
{
|
{
|
||||||
Match moduleMatch = Regex.Match(rawTextBuffer, @"[a-z]:[\\/][ -~]{5,}\.nss", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled);
|
Match moduleMatch = ModuleRegex().Match(rawTextBuffer);
|
||||||
if (moduleMatch.Success)
|
if (moduleMatch.Success)
|
||||||
{
|
{
|
||||||
modulePath = moduleMatch.Value;
|
modulePath = moduleMatch.Value;
|
||||||
@@ -92,13 +99,13 @@ namespace Ryujinx.HLE.Loaders.Executables
|
|||||||
|
|
||||||
stringBuilder.AppendLine($" Module: {modulePath}");
|
stringBuilder.AppendLine($" Module: {modulePath}");
|
||||||
|
|
||||||
Match fsSdkMatch = Regex.Match(rawTextBuffer, @"sdk_version: ([0-9.]*)", RegexOptions.Compiled);
|
Match fsSdkMatch = FsSdkRegex().Match(rawTextBuffer);
|
||||||
if (fsSdkMatch.Success)
|
if (fsSdkMatch.Success)
|
||||||
{
|
{
|
||||||
stringBuilder.AppendLine($" FS SDK Version: {fsSdkMatch.Value.Replace("sdk_version: ", "")}");
|
stringBuilder.AppendLine($" FS SDK Version: {fsSdkMatch.Value.Replace("sdk_version: ", "")}");
|
||||||
}
|
}
|
||||||
|
|
||||||
MatchCollection sdkMwMatches = Regex.Matches(rawTextBuffer, @"SDK MW[ -~]*", RegexOptions.Compiled);
|
MatchCollection sdkMwMatches = SdkMwRegex().Matches(rawTextBuffer);
|
||||||
if (sdkMwMatches.Count != 0)
|
if (sdkMwMatches.Count != 0)
|
||||||
{
|
{
|
||||||
string libHeader = " SDK Libraries: ";
|
string libHeader = " SDK Libraries: ";
|
||||||
|
@@ -638,16 +638,7 @@ namespace Ryujinx.Headless.SDL2
|
|||||||
|
|
||||||
Translator.IsReadyForTranslation.Reset();
|
Translator.IsReadyForTranslation.Reset();
|
||||||
|
|
||||||
Thread windowThread = new Thread(() =>
|
ExecutionEntrypoint();
|
||||||
{
|
|
||||||
ExecutionEntrypoint();
|
|
||||||
})
|
|
||||||
{
|
|
||||||
Name = "GUI.WindowThread"
|
|
||||||
};
|
|
||||||
|
|
||||||
windowThread.Start();
|
|
||||||
windowThread.Join();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@@ -168,14 +168,6 @@ namespace Ryujinx.Headless.SDL2
|
|||||||
|
|
||||||
public void Render()
|
public void Render()
|
||||||
{
|
{
|
||||||
InitializeWindowRenderer();
|
|
||||||
|
|
||||||
Device.Gpu.Renderer.Initialize(_glLogLevel);
|
|
||||||
|
|
||||||
InitializeRenderer();
|
|
||||||
|
|
||||||
_gpuVendorName = GetGpuVendorName();
|
|
||||||
|
|
||||||
Device.Gpu.Renderer.RunLoop(() =>
|
Device.Gpu.Renderer.RunLoop(() =>
|
||||||
{
|
{
|
||||||
Device.Gpu.SetGpuThread();
|
Device.Gpu.SetGpuThread();
|
||||||
@@ -323,6 +315,14 @@ namespace Ryujinx.Headless.SDL2
|
|||||||
|
|
||||||
InitializeWindow();
|
InitializeWindow();
|
||||||
|
|
||||||
|
InitializeWindowRenderer();
|
||||||
|
|
||||||
|
Device.Gpu.Renderer.Initialize(_glLogLevel);
|
||||||
|
|
||||||
|
InitializeRenderer();
|
||||||
|
|
||||||
|
_gpuVendorName = GetGpuVendorName();
|
||||||
|
|
||||||
Thread renderLoopThread = new Thread(Render)
|
Thread renderLoopThread = new Thread(Render)
|
||||||
{
|
{
|
||||||
Name = "GUI.RenderLoop"
|
Name = "GUI.RenderLoop"
|
||||||
|
@@ -28,6 +28,8 @@ namespace Ryujinx.SDL2.Common
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Action<Action> MainThreadDispatcher { get; set; }
|
||||||
|
|
||||||
private const uint SdlInitFlags = SDL_INIT_EVENTS | SDL_INIT_GAMECONTROLLER | SDL_INIT_JOYSTICK | SDL_INIT_AUDIO | SDL_INIT_VIDEO;
|
private const uint SdlInitFlags = SDL_INIT_EVENTS | SDL_INIT_GAMECONTROLLER | SDL_INIT_JOYSTICK | SDL_INIT_AUDIO | SDL_INIT_VIDEO;
|
||||||
|
|
||||||
private bool _isRunning;
|
private bool _isRunning;
|
||||||
@@ -154,10 +156,13 @@ namespace Ryujinx.SDL2.Common
|
|||||||
|
|
||||||
while (_isRunning)
|
while (_isRunning)
|
||||||
{
|
{
|
||||||
while (SDL_PollEvent(out SDL_Event evnt) != 0)
|
MainThreadDispatcher?.Invoke(() =>
|
||||||
{
|
{
|
||||||
HandleSDLEvent(ref evnt);
|
while (SDL_PollEvent(out SDL_Event evnt) != 0)
|
||||||
}
|
{
|
||||||
|
HandleSDLEvent(ref evnt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
waitHandle.Wait(WaitTimeMs);
|
waitHandle.Wait(WaitTimeMs);
|
||||||
}
|
}
|
||||||
|
@@ -7,6 +7,7 @@ using Ryujinx.Common.Logging;
|
|||||||
using Ryujinx.Common.System;
|
using Ryujinx.Common.System;
|
||||||
using Ryujinx.Common.SystemInfo;
|
using Ryujinx.Common.SystemInfo;
|
||||||
using Ryujinx.Modules;
|
using Ryujinx.Modules;
|
||||||
|
using Ryujinx.SDL2.Common;
|
||||||
using Ryujinx.Ui;
|
using Ryujinx.Ui;
|
||||||
using Ryujinx.Ui.Common;
|
using Ryujinx.Ui.Common;
|
||||||
using Ryujinx.Ui.Common.Configuration;
|
using Ryujinx.Ui.Common.Configuration;
|
||||||
@@ -111,6 +112,15 @@ namespace Ryujinx
|
|||||||
// Initialize Discord integration.
|
// Initialize Discord integration.
|
||||||
DiscordIntegrationModule.Initialize();
|
DiscordIntegrationModule.Initialize();
|
||||||
|
|
||||||
|
// Initialize SDL2 driver
|
||||||
|
SDL2Driver.MainThreadDispatcher = action =>
|
||||||
|
{
|
||||||
|
Gtk.Application.Invoke(delegate
|
||||||
|
{
|
||||||
|
action();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// Sets ImageSharp Jpeg Encoder Quality.
|
// Sets ImageSharp Jpeg Encoder Quality.
|
||||||
SixLabors.ImageSharp.Configuration.Default.ImageFormatsManager.SetEncoder(JpegFormat.Instance, new JpegEncoder()
|
SixLabors.ImageSharp.Configuration.Default.ImageFormatsManager.SetEncoder(JpegFormat.Instance, new JpegEncoder()
|
||||||
{
|
{
|
||||||
|
3
crowdin.yml
Normal file
3
crowdin.yml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
files:
|
||||||
|
- source: /**/Assets/Locales/en_US.json
|
||||||
|
translation: /**/Assets/Locales/%locale_with_underscore%.json
|
Reference in New Issue
Block a user