Compare commits

..

11 Commits

Author SHA1 Message Date
9367e3c35d ava: Fix Open Applet menu enabled (#5206)
Currently, the `Open Applet` menu is still enabled when a guest is running, which is wrong. This is not fixed by refreshing the property binding on `IsEnabled`.
2023-06-03 11:03:34 +02:00
52cf141874 Armeilleure: Fix support for Windows on ARM64 (#5202)
* Armeilleure: Fix support for Windows on ARM64

Tested on Windows DevKit 2023.

* Address gdkchan's comments
2023-06-03 10:23:51 +02:00
8a352df3c6 Allow BGRA images on Vulkan (#5203) 2023-06-03 03:43:00 +00:00
c545c59851 ava: Fix exit dialog while guest is running. (#5207)
* ava: Fix exit dialog while guest is running.

There is currently an issue while a game runs, the content dialog creation method check if `IsGameRunning` is true to show the popup.
But the condition here is wrong (`window` is null) so it throw a NullException silently in `Dispatcher.UIThread`.
This is now fixed by using the right casting.

* improve condition

* Fix spacing
2023-06-03 03:37:00 +00:00
96ea4e8c8e nuget: bump Microsoft.NET.Test.Sdk from 17.6.0 to 17.6.1 (#5192)
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.6.0 to 17.6.1.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md)
- [Commits](https://github.com/microsoft/vstest/compare/v17.6.0...v17.6.1)

---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-01 21:03:00 +02:00
b8f48bcf64 UI: Fix empty homebrew icon (#5189)
* UI: Fix empty homebrew icon

We currently don't check the icon size when we read it from the homebrew data. That could cause issues at UI side since the buffer isn't null but empty. Extra check have been added UI side too.
(I cleaned up some files during my research too)

Fixes #5188

* Remove additional check

* Remove unused using
2023-06-01 18:24:00 +02:00
6966211e07 Give Library header DockPanel explicit height (#5160) 2023-06-01 17:40:44 +02:00
57524a4c8a Add issue template for missing shader instructions (#5048)
* Add issue template for missing shader instructions

* fixup! Add issue template for missing shader instructions

* Update .github/ISSUE_TEMPLATE/missing_shader_instruction.yml

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
2023-06-01 17:32:38 +02:00
f4539c49d8 [Logger] Add print with stacktrace method (#5129)
* Add print with stacktrace method

* Adjust logging namespaces

* Add static keyword to DynamicObjectFormatter
2023-06-01 13:47:53 +00:00
12c62fdbc2 nuget: bump DynamicData from 7.13.8 to 7.14.2 (#5148)
Bumps [DynamicData](https://github.com/reactiveui/DynamicData) from 7.13.8 to 7.14.2.
- [Release notes](https://github.com/reactiveui/DynamicData/releases)
- [Changelog](https://github.com/reactivemarbles/DynamicData/blob/main/ReleaseNotes.md)
- [Commits](https://github.com/reactiveui/DynamicData/compare/7.13.8...7.14.2)

---
updated-dependencies:
- dependency-name: DynamicData
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-01 13:35:04 +00:00
e3c6be5e29 Only run one workflow for a PR at a time (#5137) 2023-06-01 09:42:49 +02:00
29 changed files with 141 additions and 96 deletions

View File

@ -0,0 +1,19 @@
name: Missing Shader Instruction
description: Shader Instruction is missing in Ryujinx.
title: "[GPU]"
labels: [gpu, not-implemented]
body:
- type: textarea
id: instruction
attributes:
label: Shader instruction
description: What shader instruction is missing?
validations:
required: true
- type: textarea
id: required
attributes:
label: Required by
description: Add links to the [compatibility list page(s)](https://github.com/Ryujinx/Ryujinx-Games-List/issues) of the game(s) that require this instruction.
validations:
required: true

View File

@ -18,6 +18,10 @@ on:
- '*.yml' - '*.yml'
- 'README.md' - 'README.md'
concurrency:
group: pr-checks-${{ github.event.number }}
cancel-in-progress: true
env: env:
POWERSHELL_TELEMETRY_OPTOUT: 1 POWERSHELL_TELEMETRY_OPTOUT: 1
DOTNET_CLI_TELEMETRY_OPTOUT: 1 DOTNET_CLI_TELEMETRY_OPTOUT: 1

View File

@ -13,7 +13,7 @@
<PackageVersion Include="CommandLineParser" Version="2.9.1" /> <PackageVersion Include="CommandLineParser" Version="2.9.1" />
<PackageVersion Include="Concentus" Version="1.1.7" /> <PackageVersion Include="Concentus" Version="1.1.7" />
<PackageVersion Include="DiscordRichPresence" Version="1.1.3.18" /> <PackageVersion Include="DiscordRichPresence" Version="1.1.3.18" />
<PackageVersion Include="DynamicData" Version="7.13.8" /> <PackageVersion Include="DynamicData" Version="7.14.2" />
<PackageVersion Include="FluentAvaloniaUI" Version="1.4.5" /> <PackageVersion Include="FluentAvaloniaUI" Version="1.4.5" />
<PackageVersion Include="GtkSharp.Dependencies" Version="1.1.1" /> <PackageVersion Include="GtkSharp.Dependencies" Version="1.1.1" />
<PackageVersion Include="GtkSharp.Dependencies.osx" Version="0.0.5" /> <PackageVersion Include="GtkSharp.Dependencies.osx" Version="0.0.5" />
@ -21,7 +21,7 @@
<PackageVersion Include="LibHac" Version="0.18.0" /> <PackageVersion Include="LibHac" Version="0.18.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" /> <PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.5.0" /> <PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.5.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.6.0" /> <PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.6.1" />
<PackageVersion Include="Microsoft.IO.RecyclableMemoryStream" Version="2.3.2" /> <PackageVersion Include="Microsoft.IO.RecyclableMemoryStream" Version="2.3.2" />
<PackageVersion Include="MsgPack.Cli" Version="1.0.1" /> <PackageVersion Include="MsgPack.Cli" Version="1.0.1" />
<PackageVersion Include="NUnit" Version="3.13.3" /> <PackageVersion Include="NUnit" Version="3.13.3" />

View File

@ -6,10 +6,11 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Runtime.Versioning;
namespace ARMeilleure.Translation.Cache namespace ARMeilleure.Translation.Cache
{ {
static class JitCache static partial class JitCache
{ {
private const int PageSize = 4 * 1024; private const int PageSize = 4 * 1024;
private const int PageMask = PageSize - 1; private const int PageMask = PageSize - 1;
@ -27,6 +28,10 @@ namespace ARMeilleure.Translation.Cache
private static readonly object _lock = new object(); private static readonly object _lock = new object();
private static bool _initialized; private static bool _initialized;
[SupportedOSPlatform("windows")]
[LibraryImport("kernel32.dll", SetLastError = true)]
public static partial IntPtr FlushInstructionCache(IntPtr hProcess, IntPtr lpAddress, UIntPtr dwSize);
public static void Initialize(IJitMemoryAllocator allocator) public static void Initialize(IJitMemoryAllocator allocator)
{ {
if (_initialized) return; if (_initialized) return;
@ -36,7 +41,11 @@ namespace ARMeilleure.Translation.Cache
if (_initialized) return; if (_initialized) return;
_jitRegion = new ReservedRegion(allocator, CacheSize); _jitRegion = new ReservedRegion(allocator, CacheSize);
_jitCacheInvalidator = new JitCacheInvalidation(allocator);
if (!OperatingSystem.IsWindows() && !OperatingSystem.IsMacOS())
{
_jitCacheInvalidator = new JitCacheInvalidation(allocator);
}
_cacheAllocator = new CacheMemoryAllocator(CacheSize); _cacheAllocator = new CacheMemoryAllocator(CacheSize);
@ -77,7 +86,14 @@ namespace ARMeilleure.Translation.Cache
Marshal.Copy(code, 0, funcPtr, code.Length); Marshal.Copy(code, 0, funcPtr, code.Length);
ReprotectAsExecutable(funcOffset, code.Length); ReprotectAsExecutable(funcOffset, code.Length);
_jitCacheInvalidator.Invalidate(funcPtr, (ulong)code.Length); if (OperatingSystem.IsWindows() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
{
FlushInstructionCache(Process.GetCurrentProcess().Handle, funcPtr, (UIntPtr)code.Length);
}
else
{
_jitCacheInvalidator?.Invalidate(funcPtr, (ulong)code.Length);
}
} }
Add(funcOffset, code.Length, func.UnwindInfo); Add(funcOffset, code.Length, func.UnwindInfo);

View File

@ -47,8 +47,8 @@ namespace ARMeilleure.Translation.Cache
public JitCacheInvalidation(IJitMemoryAllocator allocator) public JitCacheInvalidation(IJitMemoryAllocator allocator)
{ {
// On macOS, a different path is used to write to the JIT cache, which does the invalidation. // On macOS and Windows, a different path is used to write to the JIT cache, which does the invalidation.
if (!OperatingSystem.IsMacOS() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64) if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
{ {
ulong size = (ulong)_invalidationCode.Length * sizeof(int); ulong size = (ulong)_invalidationCode.Length * sizeof(int);
ulong mask = (ulong)ReservedRegion.DefaultGranularity - 1; ulong mask = (ulong)ReservedRegion.DefaultGranularity - 1;

View File

@ -21,6 +21,7 @@ namespace Ryujinx.Ava.UI.Helpers
if (value is byte[] buffer && targetType == typeof(IImage)) if (value is byte[] buffer && targetType == typeof(IImage))
{ {
MemoryStream mem = new(buffer); MemoryStream mem = new(buffer);
return new Bitmap(mem); return new Bitmap(mem);
} }

View File

@ -318,7 +318,7 @@ namespace Ryujinx.Ava.UI.Helpers
Window parent = GetMainWindow(); Window parent = GetMainWindow();
if (parent is { IsActive: true } and MainWindow window && window.ViewModel.IsGameRunning) if (parent != null && parent.IsActive && (parent as MainWindow).ViewModel.IsGameRunning)
{ {
contentDialogOverlayWindow = new() contentDialogOverlayWindow = new()
{ {

View File

@ -257,6 +257,7 @@ namespace Ryujinx.Ava.UI.ViewModels
OnPropertyChanged(); OnPropertyChanged();
OnPropertyChanged(nameof(EnableNonGameRunningControls)); OnPropertyChanged(nameof(EnableNonGameRunningControls));
OnPropertyChanged(nameof(IsAppletMenuActive));
OnPropertyChanged(nameof(StatusBarVisible)); OnPropertyChanged(nameof(StatusBarVisible));
OnPropertyChanged(nameof(ShowFirmwareStatus)); OnPropertyChanged(nameof(ShowFirmwareStatus));
} }

View File

@ -9,9 +9,7 @@ using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.UI.Windows; using Ryujinx.Ava.UI.Windows;
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Utilities; using Ryujinx.Common.Utilities;
using Ryujinx.HLE.HOS;
using Ryujinx.Modules; using Ryujinx.Modules;
using Ryujinx.Ui.App.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;

View File

@ -16,6 +16,7 @@
</Design.DataContext> </Design.DataContext>
<DockPanel <DockPanel
Margin="0,0,0,5" Margin="0,0,0,5"
Height="35"
HorizontalAlignment="Stretch"> HorizontalAlignment="Stretch">
<Button <Button
Width="40" Width="40"

View File

@ -519,14 +519,14 @@ namespace Ryujinx.Ava.UI.Windows
private void ConfirmExit() private void ConfirmExit()
{ {
Dispatcher.UIThread.InvokeAsync(async () => Dispatcher.UIThread.InvokeAsync(async () =>
{ {
ViewModel.IsClosing = await ContentDialogHelper.CreateExitDialog(); ViewModel.IsClosing = await ContentDialogHelper.CreateExitDialog();
if (ViewModel.IsClosing) if (ViewModel.IsClosing)
{ {
Close(); Close();
} }
}); });
} }
public async void LoadApplications() public async void LoadApplications()

View File

@ -1,6 +1,7 @@
using System.Text; using System.Diagnostics;
using System.Text;
namespace Ryujinx.Common.Logging namespace Ryujinx.Common.Logging.Formatters
{ {
internal class DefaultLogFormatter : ILogFormatter internal class DefaultLogFormatter : ILogFormatter
{ {
@ -27,6 +28,14 @@ namespace Ryujinx.Common.Logging
if (args.Data is not null) if (args.Data is not null)
{ {
if (args.Data is StackTrace trace)
{
sb.Append('\n');
sb.Append(trace);
return sb.ToString();
}
sb.Append(' '); sb.Append(' ');
DynamicObjectFormatter.Format(sb, args.Data); DynamicObjectFormatter.Format(sb, args.Data);
} }
@ -39,4 +48,4 @@ namespace Ryujinx.Common.Logging
} }
} }
} }
} }

View File

@ -3,9 +3,9 @@ using System;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
namespace Ryujinx.Common.Logging namespace Ryujinx.Common.Logging.Formatters
{ {
internal class DynamicObjectFormatter internal static class DynamicObjectFormatter
{ {
private static readonly ObjectPool<StringBuilder> StringBuilderPool = SharedPools.Default<StringBuilder>(); private static readonly ObjectPool<StringBuilder> StringBuilderPool = SharedPools.Default<StringBuilder>();
@ -17,7 +17,7 @@ namespace Ryujinx.Common.Logging
} }
StringBuilder sb = StringBuilderPool.Allocate(); StringBuilder sb = StringBuilderPool.Allocate();
try try
{ {
Format(sb, dynamicObject); Format(sb, dynamicObject);

View File

@ -1,7 +1,7 @@
namespace Ryujinx.Common.Logging namespace Ryujinx.Common.Logging.Formatters
{ {
interface ILogFormatter interface ILogFormatter
{ {
string Format(LogEventArgs args); string Format(LogEventArgs args);
} }
} }

View File

@ -1,4 +1,5 @@
using System; using Ryujinx.Common.Logging.Formatters;
using System;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace Ryujinx.Common.Logging namespace Ryujinx.Common.Logging

View File

@ -1,3 +1,4 @@
using Ryujinx.Common.Logging.Targets;
using Ryujinx.Common.SystemInterop; using Ryujinx.Common.SystemInterop;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -55,6 +56,16 @@ namespace Ryujinx.Common.Logging
} }
} }
[StackTraceHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PrintStack(LogClass logClass, string message, [CallerMemberName] string caller = "")
{
if (m_EnabledClasses[(int)logClass])
{
Updated?.Invoke(null, new LogEventArgs(Level, m_Time.Elapsed, Thread.CurrentThread.Name, FormatMessage(logClass, caller, message), new StackTrace(true)));
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PrintStub(LogClass logClass, string message = "", [CallerMemberName] string caller = "") public void PrintStub(LogClass logClass, string message = "", [CallerMemberName] string caller = "")
{ {
@ -122,7 +133,7 @@ namespace Ryujinx.Common.Logging
AsyncLogTargetOverflowAction.Discard)); AsyncLogTargetOverflowAction.Discard));
Notice = new Log(LogLevel.Notice); Notice = new Log(LogLevel.Notice);
// Enable important log levels before configuration is loaded // Enable important log levels before configuration is loaded
Error = new Log(LogLevel.Error); Error = new Log(LogLevel.Error);
Warning = new Log(LogLevel.Warning); Warning = new Log(LogLevel.Warning);
@ -221,4 +232,4 @@ namespace Ryujinx.Common.Logging
m_EnabledClasses[(int)logClass] = enabled; m_EnabledClasses[(int)logClass] = enabled;
} }
} }
} }

View File

@ -2,7 +2,7 @@
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Threading; using System.Threading;
namespace Ryujinx.Common.Logging namespace Ryujinx.Common.Logging.Targets
{ {
public enum AsyncLogTargetOverflowAction public enum AsyncLogTargetOverflowAction
{ {

View File

@ -1,6 +1,7 @@
using System; using Ryujinx.Common.Logging.Formatters;
using System;
namespace Ryujinx.Common.Logging namespace Ryujinx.Common.Logging.Targets
{ {
public class ConsoleLogTarget : ILogTarget public class ConsoleLogTarget : ILogTarget
{ {
@ -38,4 +39,4 @@ namespace Ryujinx.Common.Logging
Console.ResetColor(); Console.ResetColor();
} }
} }
} }

View File

@ -1,8 +1,9 @@
using System; using Ryujinx.Common.Logging.Formatters;
using System;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
namespace Ryujinx.Common.Logging namespace Ryujinx.Common.Logging.Targets
{ {
public class FileLogTarget : ILogTarget public class FileLogTarget : ILogTarget
{ {

View File

@ -1,6 +1,6 @@
using System; using System;
namespace Ryujinx.Common.Logging namespace Ryujinx.Common.Logging.Targets
{ {
public interface ILogTarget : IDisposable public interface ILogTarget : IDisposable
{ {

View File

@ -1,7 +1,7 @@
using Ryujinx.Common.Utilities; using Ryujinx.Common.Utilities;
using System.IO; using System.IO;
namespace Ryujinx.Common.Logging namespace Ryujinx.Common.Logging.Targets
{ {
public class JsonLogTarget : ILogTarget public class JsonLogTarget : ILogTarget
{ {

View File

@ -383,6 +383,7 @@ namespace Ryujinx.Graphics.GAL
case Format.R10G10B10A2Unorm: case Format.R10G10B10A2Unorm:
case Format.R10G10B10A2Uint: case Format.R10G10B10A2Uint:
case Format.R11G11B10Float: case Format.R11G11B10Float:
case Format.B8G8R8A8Unorm:
return true; return true;
} }

View File

@ -96,8 +96,6 @@ namespace Ryujinx.Graphics.Vulkan.Effects
{ {
var originalInfo = view.Info; var originalInfo = view.Info;
var swapRB = originalInfo.Format.IsBgr() && originalInfo.SwizzleR == SwizzleComponent.Red;
var info = new TextureCreateInfo( var info = new TextureCreateInfo(
width, width,
height, height,
@ -110,9 +108,9 @@ namespace Ryujinx.Graphics.Vulkan.Effects
originalInfo.Format, originalInfo.Format,
originalInfo.DepthStencilMode, originalInfo.DepthStencilMode,
originalInfo.Target, originalInfo.Target,
swapRB ? originalInfo.SwizzleB : originalInfo.SwizzleR, originalInfo.SwizzleR,
originalInfo.SwizzleG, originalInfo.SwizzleG,
swapRB ? originalInfo.SwizzleR : originalInfo.SwizzleB, originalInfo.SwizzleB,
originalInfo.SwizzleA); originalInfo.SwizzleA);
_intermediaryTexture?.Dispose(); _intermediaryTexture?.Dispose();
_intermediaryTexture = _renderer.CreateTexture(info, view.ScaleFactor) as TextureView; _intermediaryTexture = _renderer.CreateTexture(info, view.ScaleFactor) as TextureView;
@ -155,7 +153,7 @@ namespace Ryujinx.Graphics.Vulkan.Effects
var bufferRanges = new BufferRange(bufferHandle, 0, rangeSize); var bufferRanges = new BufferRange(bufferHandle, 0, rangeSize);
_pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(2, bufferRanges) }); _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(2, bufferRanges) });
_pipeline.SetImage(0, _intermediaryTexture, GAL.Format.R8G8B8A8Unorm); _pipeline.SetImage(0, _intermediaryTexture, FormatTable.ConvertRgba8SrgbToUnorm(view.Info.Format));
_pipeline.DispatchCompute(dispatchX, dispatchY, 1); _pipeline.DispatchCompute(dispatchX, dispatchY, 1);
_pipeline.ComputeBarrier(); _pipeline.ComputeBarrier();

View File

@ -56,28 +56,7 @@ namespace Ryujinx.Graphics.Vulkan.Effects
if (_texture == null || _texture.Width != view.Width || _texture.Height != view.Height) if (_texture == null || _texture.Width != view.Width || _texture.Height != view.Height)
{ {
_texture?.Dispose(); _texture?.Dispose();
_texture = _renderer.CreateTexture(view.Info, view.ScaleFactor) as TextureView;
var info = view.Info;
if (view.Info.Format.IsBgr())
{
info = new TextureCreateInfo(info.Width,
info.Height,
info.Depth,
info.Levels,
info.Samples,
info.BlockWidth,
info.BlockHeight,
info.BytesPerPixel,
info.Format,
info.DepthStencilMode,
info.Target,
info.SwizzleB,
info.SwizzleG,
info.SwizzleR,
info.SwizzleA);
}
_texture = _renderer.CreateTexture(info, view.ScaleFactor) as TextureView;
} }
_pipeline.SetCommandBuffer(cbs); _pipeline.SetCommandBuffer(cbs);
@ -96,7 +75,7 @@ namespace Ryujinx.Graphics.Vulkan.Effects
var dispatchX = BitUtils.DivRoundUp(view.Width, IPostProcessingEffect.LocalGroupSize); var dispatchX = BitUtils.DivRoundUp(view.Width, IPostProcessingEffect.LocalGroupSize);
var dispatchY = BitUtils.DivRoundUp(view.Height, IPostProcessingEffect.LocalGroupSize); var dispatchY = BitUtils.DivRoundUp(view.Height, IPostProcessingEffect.LocalGroupSize);
_pipeline.SetImage(0, _texture, GAL.Format.R8G8B8A8Unorm); _pipeline.SetImage(0, _texture, FormatTable.ConvertRgba8SrgbToUnorm(view.Info.Format));
_pipeline.DispatchCompute(dispatchX, dispatchY, 1); _pipeline.DispatchCompute(dispatchX, dispatchY, 1);
_renderer.BufferManager.Delete(bufferHandle); _renderer.BufferManager.Delete(bufferHandle);

View File

@ -4,7 +4,6 @@ using Ryujinx.Graphics.Shader;
using Ryujinx.Graphics.Shader.Translation; using Ryujinx.Graphics.Shader.Translation;
using Silk.NET.Vulkan; using Silk.NET.Vulkan;
using System; using System;
using Format = Ryujinx.Graphics.GAL.Format;
namespace Ryujinx.Graphics.Vulkan.Effects namespace Ryujinx.Graphics.Vulkan.Effects
{ {
@ -149,7 +148,7 @@ namespace Ryujinx.Graphics.Vulkan.Effects
1, 1,
1, 1,
1, 1,
Format.R8G8Unorm, GAL.Format.R8G8Unorm,
DepthStencilMode.Depth, DepthStencilMode.Depth,
Target.Texture2D, Target.Texture2D,
SwizzleComponent.Red, SwizzleComponent.Red,
@ -165,7 +164,7 @@ namespace Ryujinx.Graphics.Vulkan.Effects
1, 1,
1, 1,
1, 1,
Format.R8Unorm, GAL.Format.R8Unorm,
DepthStencilMode.Depth, DepthStencilMode.Depth,
Target.Texture2D, Target.Texture2D,
SwizzleComponent.Red, SwizzleComponent.Red,
@ -192,30 +191,9 @@ namespace Ryujinx.Graphics.Vulkan.Effects
_edgeOutputTexture?.Dispose(); _edgeOutputTexture?.Dispose();
_blendOutputTexture?.Dispose(); _blendOutputTexture?.Dispose();
var info = view.Info; _outputTexture = _renderer.CreateTexture(view.Info, view.ScaleFactor) as TextureView;
_edgeOutputTexture = _renderer.CreateTexture(view.Info, view.ScaleFactor) as TextureView;
if (view.Info.Format.IsBgr()) _blendOutputTexture = _renderer.CreateTexture(view.Info, view.ScaleFactor) as TextureView;
{
info = new TextureCreateInfo(info.Width,
info.Height,
info.Depth,
info.Levels,
info.Samples,
info.BlockWidth,
info.BlockHeight,
info.BytesPerPixel,
info.Format,
info.DepthStencilMode,
info.Target,
info.SwizzleB,
info.SwizzleG,
info.SwizzleR,
info.SwizzleA);
}
_outputTexture = _renderer.CreateTexture(info, view.ScaleFactor) as TextureView;
_edgeOutputTexture = _renderer.CreateTexture(info, view.ScaleFactor) as TextureView;
_blendOutputTexture = _renderer.CreateTexture(info, view.ScaleFactor) as TextureView;
} }
_pipeline.SetCommandBuffer(cbs); _pipeline.SetCommandBuffer(cbs);
@ -240,7 +218,7 @@ namespace Ryujinx.Graphics.Vulkan.Effects
_renderer.BufferManager.SetData(bufferHandle, 0, resolutionBuffer); _renderer.BufferManager.SetData(bufferHandle, 0, resolutionBuffer);
var bufferRanges = new BufferRange(bufferHandle, 0, rangeSize); var bufferRanges = new BufferRange(bufferHandle, 0, rangeSize);
_pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(2, bufferRanges) }); _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(2, bufferRanges) });
_pipeline.SetImage(0, _edgeOutputTexture, GAL.Format.R8G8B8A8Unorm); _pipeline.SetImage(0, _edgeOutputTexture, FormatTable.ConvertRgba8SrgbToUnorm(view.Info.Format));
_pipeline.DispatchCompute(dispatchX, dispatchY, 1); _pipeline.DispatchCompute(dispatchX, dispatchY, 1);
_pipeline.ComputeBarrier(); _pipeline.ComputeBarrier();
@ -250,7 +228,7 @@ namespace Ryujinx.Graphics.Vulkan.Effects
_pipeline.SetTextureAndSampler(ShaderStage.Compute, 1, _edgeOutputTexture, _samplerLinear); _pipeline.SetTextureAndSampler(ShaderStage.Compute, 1, _edgeOutputTexture, _samplerLinear);
_pipeline.SetTextureAndSampler(ShaderStage.Compute, 3, _areaTexture, _samplerLinear); _pipeline.SetTextureAndSampler(ShaderStage.Compute, 3, _areaTexture, _samplerLinear);
_pipeline.SetTextureAndSampler(ShaderStage.Compute, 4, _searchTexture, _samplerLinear); _pipeline.SetTextureAndSampler(ShaderStage.Compute, 4, _searchTexture, _samplerLinear);
_pipeline.SetImage(0, _blendOutputTexture, GAL.Format.R8G8B8A8Unorm); _pipeline.SetImage(0, _blendOutputTexture, FormatTable.ConvertRgba8SrgbToUnorm(view.Info.Format));
_pipeline.DispatchCompute(dispatchX, dispatchY, 1); _pipeline.DispatchCompute(dispatchX, dispatchY, 1);
_pipeline.ComputeBarrier(); _pipeline.ComputeBarrier();
@ -259,7 +237,7 @@ namespace Ryujinx.Graphics.Vulkan.Effects
_pipeline.Specialize(_specConstants); _pipeline.Specialize(_specConstants);
_pipeline.SetTextureAndSampler(ShaderStage.Compute, 3, _blendOutputTexture, _samplerLinear); _pipeline.SetTextureAndSampler(ShaderStage.Compute, 3, _blendOutputTexture, _samplerLinear);
_pipeline.SetTextureAndSampler(ShaderStage.Compute, 1, view, _samplerLinear); _pipeline.SetTextureAndSampler(ShaderStage.Compute, 1, view, _samplerLinear);
_pipeline.SetImage(0, _outputTexture, GAL.Format.R8G8B8A8Unorm); _pipeline.SetImage(0, _outputTexture, FormatTable.ConvertRgba8SrgbToUnorm(view.Info.Format));
_pipeline.DispatchCompute(dispatchX, dispatchY, 1); _pipeline.DispatchCompute(dispatchX, dispatchY, 1);
_pipeline.ComputeBarrier(); _pipeline.ComputeBarrier();

View File

@ -169,6 +169,16 @@ namespace Ryujinx.Graphics.Vulkan
return _table[(int)format]; return _table[(int)format];
} }
public static Format ConvertRgba8SrgbToUnorm(Format format)
{
return format switch
{
Format.R8G8B8A8Srgb => Format.R8G8B8A8Unorm,
Format.B8G8R8A8Srgb => Format.B8G8R8A8Unorm,
_ => format
};
}
public static int GetAttributeFormatSize(VkFormat format) public static int GetAttributeFormatSize(VkFormat format)
{ {
switch (format) switch (format)

View File

@ -9,6 +9,7 @@ using Ryujinx.Common.Configuration.Hid.Controller;
using Ryujinx.Common.Configuration.Hid.Controller.Motion; using Ryujinx.Common.Configuration.Hid.Controller.Motion;
using Ryujinx.Common.Configuration.Hid.Keyboard; using Ryujinx.Common.Configuration.Hid.Keyboard;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Common.Logging.Targets;
using Ryujinx.Common.SystemInterop; using Ryujinx.Common.SystemInterop;
using Ryujinx.Common.Utilities; using Ryujinx.Common.Utilities;
using Ryujinx.Cpu; using Ryujinx.Cpu;

View File

@ -343,7 +343,14 @@ namespace Ryujinx.Ui.App.Common
ulong nacpSize = reader.ReadUInt64(); ulong nacpSize = reader.ReadUInt64();
// Reads and stores game icon as byte array // Reads and stores game icon as byte array
applicationIcon = Read(assetOffset + iconOffset, (int)iconSize); if (iconSize > 0)
{
applicationIcon = Read(assetOffset + iconOffset, (int)iconSize);
}
else
{
applicationIcon = _nroIcon;
}
// Read the NACP data // Read the NACP data
Read(assetOffset + (int)nacpOffset, (int)nacpSize).AsSpan().CopyTo(controlHolder.ByteSpan); Read(assetOffset + (int)nacpOffset, (int)nacpSize).AsSpan().CopyTo(controlHolder.ByteSpan);
@ -666,7 +673,14 @@ namespace Ryujinx.Ui.App.Common
long iconSize = BitConverter.ToInt64(iconSectionInfo, 8); long iconSize = BitConverter.ToInt64(iconSectionInfo, 8);
// Reads and stores game icon as byte array // Reads and stores game icon as byte array
applicationIcon = Read(assetOffset + iconOffset, (int)iconSize); if (iconSize > 0)
{
applicationIcon = Read(assetOffset + iconOffset, (int)iconSize);
}
else
{
applicationIcon = _nroIcon;
}
} }
else else
{ {

View File

@ -1,5 +1,6 @@
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Common.Logging.Targets;
using System; using System;
namespace Ryujinx.Ui.Common.Configuration namespace Ryujinx.Ui.Common.Configuration