Compare commits

...

8 Commits

Author SHA1 Message Date
TSRBerry
79a1314ee4 [Ryujinx.Cpu] Address dotnet-format issues (#5365)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0060 warnings

* Silence dotnet format IDE0052 warnings

* Silence dotnet format IDE0059 warnings

* Address or silence dotnet format IDE1006 warnings

* Address dotnet format CA1816 warnings

* Address most dotnet format whitespace warnings

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Add comments to disabled warnings

* Remove a few unused parameters

* Adjust namespaces

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Start working on disabled warnings

* Fix and silence a few dotnet-format warnings again

* Address a few disabled IDE0060 warnings

* Silence IDE0060 in .editorconfig

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* Address review feedback

* Remove redundant unsafe modifiers

* Fix build issues

* Add GC.SuppressFinalize() call

* Add trailing commas and fix naming rule violations

* Remove unused members and assignments
2023-07-01 02:18:52 +00:00
TSRBerry
e9848339dd [Ryujinx.Tests] Address dotnet-format issues (#5389)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Fix new dotnet-format issues after rebase

* Address review comments

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Format if-blocks correctly

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* cpu tests: Disable CA2211 for CodeBaseAddress and DataBaseAddress

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* Apply suggestions from code review

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* First dotnet format pass

* Fix naming rule violations

* Remove naming rule violation exceptions

* Fix comment style

* Use targeted new

* Remove redundant code

* Remove comment alignment

* Remove naming rule exceptions

* Add trailing commas

* Use nameof expression

* Reformat to add remaining trailing commas

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
2023-07-01 02:14:34 +00:00
TSRBerry
6e28a4dd13 [Ryujinx.Ui.Common] Address dotnet-format issues (#5392)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Silence dotnet format IDE0060 warnings

* Address dotnet format CA1401 warnings

* dotnet-format fixes after rebase

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Another rebase, another dotnet format run

* Run dotnet format style after rebase

* Add comments to disabled warnings

* Remove a few unused parameters

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Address IDE0251 warnings

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* Small optimizations

* Remove alignment

* Apply formatting

* Fix build issues

* Final pass for dotnet format

* Add trailing commas

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Add trailing commas

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
2023-06-29 02:39:22 +02:00
TSRBerry
7c989f88bd [Ryujinx.Graphics.GAL] Address dotnet-format issues (#5366)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0052 warnings

* Address dotnet format CA1816 warnings

* Address or silence dotnet format CA1069 warnings

* Address remaining dotnet format analyzer warnings

* Address review comments

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Revert formatting changes for while and for-loops

* Another rebase, another dotnet format run

* Run dotnet format whitespace after rebase

* Run dotnet format style after rebase

* Run dotnet format analyzers after rebase

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Disable 'prefer switch expression' rule

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Start working on disabled warnings

* Address IDE0251 warnings

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* First dotnet format pass

* Address review feedback

* Add trailing commas

* Remove SuppressMessage for IDE0066

* Make explicit Equals implementation implicit
2023-06-28 20:20:10 +02:00
Ac_K
16fa983704 macOS: Fix warning in some shell scripts (#5398)
* macOS: Fix warning in some shell scripts

In a way to continue the cleaning of the project, there are some warnings which can be easily fixed.

* Try to fix CI

* Fix APP_ARGUMENTS

* Addresses feedback
2023-06-28 19:09:48 +02:00
TSRBerry
40daca5684 [Ryujinx.Headless.SDL2] Address dotnet-format issues (#5379)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Address or silence dotnet format CA1806 and a few CA1854 warnings

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* First dotnet format pass

* Add trailing commas

* Fix naming and formatting issues
2023-06-28 19:03:27 +02:00
TSRBerry
981e0c082d [Spv.Generator] Address dotnet-format issues (#5394)
* dotnet format style --severity info

Some changes were manually reverted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0052 warnings

* Address or silence dotnet format IDE1006 warnings

* Address or silence dotnet format CA1069 warnings

* Address review comments

* Address most dotnet format whitespace warnings

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Address IDE0251 warnings

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* Rename Operand.cs to IOperand.cs

* Update src/Spv.Generator/Module.cs

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Remove NotNullWhen attribute and use conditional access to avoid NRE

* Fix duplicated enum values

* Remove unread member

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
2023-06-28 18:54:20 +02:00
TSRBerry
cebfa54467 [Ryujinx.Graphics.Texture] Address dotnet-format issues (#5375)
* dotnet format style --severity info

Some changes were manually reverted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0060 warnings

* Silence dotnet format IDE0059 warnings

* Address or silence dotnet format CA2208 warnings

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Format if-blocks correctly

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Address IDE0251 warnings

* Silence IDE0060 in .editorconfig

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* First dotnet format pass

* Apply suggestions from code review

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Address review feedback

* Update src/Ryujinx.Graphics.Texture/Astc/AstcDecoder.cs

Co-authored-by: Ac_K <Acoustik666@gmail.com>

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
2023-06-28 18:46:18 +02:00
345 changed files with 5349 additions and 4805 deletions

View File

@@ -35,12 +35,12 @@ EXECUTABLE_SUB_PATH=Contents/MacOS/Ryujinx
rm -rf "$TEMP_DIRECTORY" rm -rf "$TEMP_DIRECTORY"
mkdir -p "$TEMP_DIRECTORY" mkdir -p "$TEMP_DIRECTORY"
DOTNET_COMMON_ARGS="-p:DebugType=embedded -p:Version=$VERSION -p:SourceRevisionId=$SOURCE_REVISION_ID --self-contained true $EXTRA_ARGS" DOTNET_COMMON_ARGS=(-p:DebugType=embedded -p:Version="$VERSION" -p:SourceRevisionId="$SOURCE_REVISION_ID" --self-contained true $EXTRA_ARGS)
dotnet restore dotnet restore
dotnet build -c $CONFIGURATION src/Ryujinx.Ava dotnet build -c "$CONFIGURATION" src/Ryujinx.Ava
dotnet publish -c $CONFIGURATION -r osx-arm64 -o "$TEMP_DIRECTORY/publish_arm64" $DOTNET_COMMON_ARGS src/Ryujinx.Ava dotnet publish -c "$CONFIGURATION" -r osx-arm64 -o "$TEMP_DIRECTORY/publish_arm64" "${DOTNET_COMMON_ARGS[@]}" src/Ryujinx.Ava
dotnet publish -c $CONFIGURATION -r osx-x64 -o "$TEMP_DIRECTORY/publish_x64" $DOTNET_COMMON_ARGS src/Ryujinx.Ava dotnet publish -c "$CONFIGURATION" -r osx-x64 -o "$TEMP_DIRECTORY/publish_x64" "${DOTNET_COMMON_ARGS[@]}" src/Ryujinx.Ava
# Get rid of the support library for ARMeilleure for x64 (that's only for arm64) # Get rid of the support library for ARMeilleure for x64 (that's only for arm64)
rm -rf "$TEMP_DIRECTORY/publish_x64/libarmeilleure-jitsupport.dylib" rm -rf "$TEMP_DIRECTORY/publish_x64/libarmeilleure-jitsupport.dylib"
@@ -104,10 +104,10 @@ fi
echo "Creating archive" echo "Creating archive"
pushd "$OUTPUT_DIRECTORY" pushd "$OUTPUT_DIRECTORY"
tar --exclude "Ryujinx.app/Contents/MacOS/Ryujinx" -cvf $RELEASE_TAR_FILE_NAME Ryujinx.app 1> /dev/null tar --exclude "Ryujinx.app/Contents/MacOS/Ryujinx" -cvf "$RELEASE_TAR_FILE_NAME" Ryujinx.app 1> /dev/null
python3 "$BASE_DIR/distribution/misc/add_tar_exec.py" $RELEASE_TAR_FILE_NAME "Ryujinx.app/Contents/MacOS/Ryujinx" "Ryujinx.app/Contents/MacOS/Ryujinx" python3 "$BASE_DIR/distribution/misc/add_tar_exec.py" "$RELEASE_TAR_FILE_NAME" "Ryujinx.app/Contents/MacOS/Ryujinx" "Ryujinx.app/Contents/MacOS/Ryujinx"
gzip -9 < $RELEASE_TAR_FILE_NAME > $RELEASE_TAR_FILE_NAME.gz gzip -9 < "$RELEASE_TAR_FILE_NAME" > "$RELEASE_TAR_FILE_NAME.gz"
rm $RELEASE_TAR_FILE_NAME rm "$RELEASE_TAR_FILE_NAME"
popd popd
echo "Done" echo "Done"

View File

@@ -5,7 +5,7 @@ set -e
INSTALL_DIRECTORY=$1 INSTALL_DIRECTORY=$1
NEW_APP_DIRECTORY=$2 NEW_APP_DIRECTORY=$2
APP_PID=$3 APP_PID=$3
APP_ARGUMENTS="${@:4}" APP_ARGUMENTS=("${@:4}")
error_handler() { error_handler() {
local lineno="$1" local lineno="$1"
@@ -33,7 +33,7 @@ trap 'error_handler ${LINENO}' ERR
attempt=0 attempt=0
while true; do while true; do
if lsof -p $APP_PID +r 1 &>/dev/null || ps -p "$APP_PID" &>/dev/null; then if lsof -p "$APP_PID" +r 1 &>/dev/null || ps -p "$APP_PID" &>/dev/null; then
if [ "$attempt" -eq 4 ]; then if [ "$attempt" -eq 4 ]; then
exit 1 exit 1
fi fi
@@ -53,5 +53,5 @@ mv "$NEW_APP_DIRECTORY" "$INSTALL_DIRECTORY"
if [ "$#" -le 3 ]; then if [ "$#" -le 3 ]; then
open -a "$INSTALL_DIRECTORY" open -a "$INSTALL_DIRECTORY"
else else
open -a "$INSTALL_DIRECTORY" --args "$APP_ARGUMENTS" open -a "$INSTALL_DIRECTORY" --args "${APP_ARGUMENTS[@]}"
fi fi

View File

@@ -32,6 +32,7 @@ using Ryujinx.HLE.HOS.Services.Account.Acc;
using Ryujinx.HLE.HOS.SystemState; using Ryujinx.HLE.HOS.SystemState;
using Ryujinx.Input; using Ryujinx.Input;
using Ryujinx.Input.HLE; using Ryujinx.Input.HLE;
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;
@@ -692,7 +693,7 @@ namespace Ryujinx.Ava
DiscordIntegrationModule.SwitchToPlayingState(Device.Processes.ActiveApplication.ProgramIdText, Device.Processes.ActiveApplication.Name); DiscordIntegrationModule.SwitchToPlayingState(Device.Processes.ActiveApplication.ProgramIdText, Device.Processes.ActiveApplication.Name);
_viewModel.ApplicationLibrary.LoadAndSaveMetaData(Device.Processes.ActiveApplication.ProgramIdText, appMetadata => ApplicationLibrary.LoadAndSaveMetaData(Device.Processes.ActiveApplication.ProgramIdText, appMetadata =>
{ {
appMetadata.LastPlayed = DateTime.UtcNow; appMetadata.LastPlayed = DateTime.UtcNow;
}); });

View File

@@ -42,7 +42,7 @@ namespace Ryujinx.Ava.UI.Controls
{ {
viewModel.SelectedApplication.Favorite = !viewModel.SelectedApplication.Favorite; viewModel.SelectedApplication.Favorite = !viewModel.SelectedApplication.Favorite;
viewModel.ApplicationLibrary.LoadAndSaveMetaData(viewModel.SelectedApplication.TitleId, appMetadata => ApplicationLibrary.LoadAndSaveMetaData(viewModel.SelectedApplication.TitleId, appMetadata =>
{ {
appMetadata.Favorite = viewModel.SelectedApplication.Favorite; appMetadata.Favorite = viewModel.SelectedApplication.Favorite;
}); });

View File

@@ -3,6 +3,7 @@ using LibHac.Ncm;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.UI.Windows; using Ryujinx.Ava.UI.Windows;
using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.FileSystem;
using Ryujinx.Ui.App.Common;
using System; using System;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
@@ -74,7 +75,7 @@ namespace Ryujinx.Ava.UI.Models
} }
else else
{ {
var appMetadata = MainWindow.MainWindowViewModel.ApplicationLibrary.LoadAndSaveMetaData(TitleIdString); var appMetadata = ApplicationLibrary.LoadAndSaveMetaData(TitleIdString);
Title = appMetadata.Title ?? TitleIdString; Title = appMetadata.Title ?? TitleIdString;
} }

View File

@@ -239,28 +239,28 @@ namespace Ryujinx.Ava.UI.Renderer
IPlatformHandle CreateMacOS() IPlatformHandle CreateMacOS()
{ {
// Create a new CAMetalLayer. // Create a new CAMetalLayer.
IntPtr layerClass = ObjectiveC.objc_getClass("CAMetalLayer"); ObjectiveC.Object layerObject = new("CAMetalLayer");
IntPtr metalLayer = ObjectiveC.IntPtr_objc_msgSend(layerClass, "alloc"); ObjectiveC.Object metalLayer = layerObject.GetFromMessage("alloc");
ObjectiveC.objc_msgSend(metalLayer, "init"); metalLayer.SendMessage("init");
// Create a child NSView to render into. // Create a child NSView to render into.
IntPtr nsViewClass = ObjectiveC.objc_getClass("NSView"); ObjectiveC.Object nsViewObject = new("NSView");
IntPtr child = ObjectiveC.IntPtr_objc_msgSend(nsViewClass, "alloc"); ObjectiveC.Object child = nsViewObject.GetFromMessage("alloc");
ObjectiveC.objc_msgSend(child, "init", new ObjectiveC.NSRect(0, 0, 0, 0)); child.SendMessage("init", new ObjectiveC.NSRect(0, 0, 0, 0));
// Make its renderer our metal layer. // Make its renderer our metal layer.
ObjectiveC.objc_msgSend(child, "setWantsLayer:", 1); child.SendMessage("setWantsLayer:", 1);
ObjectiveC.objc_msgSend(child, "setLayer:", metalLayer); child.SendMessage("setLayer:", metalLayer);
ObjectiveC.objc_msgSend(metalLayer, "setContentsScale:", Program.DesktopScaleFactor); metalLayer.SendMessage("setContentsScale:", Program.DesktopScaleFactor);
// Ensure the scale factor is up to date. // Ensure the scale factor is up to date.
_updateBoundsCallback = rect => _updateBoundsCallback = rect =>
{ {
ObjectiveC.objc_msgSend(metalLayer, "setContentsScale:", Program.DesktopScaleFactor); metalLayer.SendMessage("setContentsScale:", Program.DesktopScaleFactor);
}; };
IntPtr nsView = child; IntPtr nsView = child.ObjPtr;
MetalLayer = metalLayer; MetalLayer = metalLayer.ObjPtr;
NsView = nsView; NsView = nsView;
return new PlatformHandle(nsView, "NSView"); return new PlatformHandle(nsView, "NSView");

View File

@@ -7,15 +7,13 @@ namespace Ryujinx.Cpu
{ {
public class AddressSpace : IDisposable public class AddressSpace : IDisposable
{ {
private const ulong PageSize = 0x1000;
private const int DefaultBlockAlignment = 1 << 20; private const int DefaultBlockAlignment = 1 << 20;
private enum MappingType : byte private enum MappingType : byte
{ {
None, None,
Private, Private,
Shared Shared,
} }
private class Mapping : IntrusiveRedBlackTreeNode<Mapping>, IComparable<Mapping> private class Mapping : IntrusiveRedBlackTreeNode<Mapping>, IComparable<Mapping>
@@ -37,7 +35,7 @@ namespace Ryujinx.Cpu
ulong leftSize = splitAddress - Address; ulong leftSize = splitAddress - Address;
ulong rightSize = EndAddress - splitAddress; ulong rightSize = EndAddress - splitAddress;
Mapping left = new Mapping(Address, leftSize, Type); Mapping left = new(Address, leftSize, Type);
Address = splitAddress; Address = splitAddress;
Size = rightSize; Size = rightSize;
@@ -93,7 +91,7 @@ namespace Ryujinx.Cpu
(var leftAllocation, PrivateAllocation) = PrivateAllocation.Split(leftSize); (var leftAllocation, PrivateAllocation) = PrivateAllocation.Split(leftSize);
PrivateMapping left = new PrivateMapping(Address, leftSize, leftAllocation); PrivateMapping left = new(Address, leftSize, leftAllocation);
Address = splitAddress; Address = splitAddress;
Size = rightSize; Size = rightSize;
@@ -181,7 +179,7 @@ namespace Ryujinx.Cpu
{ {
addressSpace = null; addressSpace = null;
MemoryAllocationFlags asFlags = MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible; const MemoryAllocationFlags asFlags = MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible;
ulong minAddressSpaceSize = Math.Min(asSize, 1UL << 36); ulong minAddressSpaceSize = Math.Min(asSize, 1UL << 36);
@@ -391,8 +389,6 @@ namespace Ryujinx.Cpu
ulong vaAligned = BitUtils.AlignDown(va, alignment); ulong vaAligned = BitUtils.AlignDown(va, alignment);
ulong endAddressAligned = BitUtils.AlignUp(endAddress, alignment); ulong endAddressAligned = BitUtils.AlignUp(endAddress, alignment);
ulong sizeAligned = endAddressAligned - vaAligned;
PrivateMapping map = _privateTree.GetNode(new PrivateMapping(va, 1UL, default)); PrivateMapping map = _privateTree.GetNode(new PrivateMapping(va, 1UL, default));
for (; map != null; map = map.Successor) for (; map != null; map = map.Successor)
@@ -436,8 +432,6 @@ namespace Ryujinx.Cpu
return; return;
} }
ulong alignedSize = endAddressAligned - vaAligned;
PrivateMapping map = _privateTree.GetNode(new PrivateMapping(va, 1UL, default)); PrivateMapping map = _privateTree.GetNode(new PrivateMapping(va, 1UL, default));
for (; map != null; map = map.Successor) for (; map != null; map = map.Successor)
@@ -495,9 +489,11 @@ namespace Ryujinx.Cpu
public void Dispose() public void Dispose()
{ {
GC.SuppressFinalize(this);
_privateMemoryAllocator?.Dispose(); _privateMemoryAllocator?.Dispose();
Base.Dispose(); Base.Dispose();
Mirror.Dispose(); Mirror.Dispose();
} }
} }
} }

View File

@@ -42,6 +42,6 @@ namespace Ryujinx.Cpu.AppleHv.Arm
WatchpointSameEl = 0b110101, WatchpointSameEl = 0b110101,
BkptAarch32 = 0b111000, BkptAarch32 = 0b111000,
VectorCatchAarch32 = 0b111010, VectorCatchAarch32 = 0b111010,
BrkAarch64 = 0b111100 BrkAarch64 = 0b111100,
} }
} }

View File

@@ -4,7 +4,7 @@ namespace Ryujinx.Cpu.AppleHv
{ {
public class DummyDiskCacheLoadState : IDiskCacheLoadState public class DummyDiskCacheLoadState : IDiskCacheLoadState
{ {
#pragma warning disable CS0067 #pragma warning disable CS0067 // The event is never used
/// <inheritdoc/> /// <inheritdoc/>
public event Action<LoadState, int, int> StateChanged; public event Action<LoadState, int, int> StateChanged;
#pragma warning restore CS0067 #pragma warning restore CS0067
@@ -14,4 +14,4 @@ namespace Ryujinx.Cpu.AppleHv
{ {
} }
} }
} }

View File

@@ -18,18 +18,16 @@ namespace Ryujinx.Cpu.AppleHv
private const ulong AllocationGranule = 1UL << 14; private const ulong AllocationGranule = 1UL << 14;
private readonly ulong _asBase; private readonly ulong _asBase;
private readonly ulong _asSize;
private readonly ulong _backingSize; private readonly ulong _backingSize;
private readonly HvAddressSpaceRange _userRange; private readonly HvAddressSpaceRange _userRange;
private readonly HvAddressSpaceRange _kernelRange; private readonly HvAddressSpaceRange _kernelRange;
private MemoryBlock _kernelCodeBlock; private readonly MemoryBlock _kernelCodeBlock;
public HvAddressSpace(MemoryBlock backingMemory, ulong asSize) public HvAddressSpace(MemoryBlock backingMemory, ulong asSize)
{ {
(_asBase, var ipaAllocator) = HvVm.CreateAddressSpace(backingMemory); (_asBase, var ipaAllocator) = HvVm.CreateAddressSpace(backingMemory);
_asSize = asSize;
_backingSize = backingMemory.Size; _backingSize = backingMemory.Size;
_userRange = new HvAddressSpaceRange(ipaAllocator); _userRange = new HvAddressSpaceRange(ipaAllocator);
@@ -58,20 +56,20 @@ namespace Ryujinx.Cpu.AppleHv
_kernelCodeBlock.Write(KernelRegionEretOffset, 0xD69F03E0u); // ERET _kernelCodeBlock.Write(KernelRegionEretOffset, 0xD69F03E0u); // ERET
ulong kernelCodePa = ipaAllocator.Allocate(AllocationGranule); ulong kernelCodePa = ipaAllocator.Allocate(AllocationGranule);
HvApi.hv_vm_map((ulong)_kernelCodeBlock.Pointer, kernelCodePa, AllocationGranule, hv_memory_flags_t.HV_MEMORY_READ | hv_memory_flags_t.HV_MEMORY_EXEC).ThrowOnError(); HvApi.hv_vm_map((ulong)_kernelCodeBlock.Pointer, kernelCodePa, AllocationGranule, HvMemoryFlags.Read | HvMemoryFlags.Exec).ThrowOnError();
_kernelRange.Map(KernelRegionCodeOffset, kernelCodePa, KernelRegionCodeSize, ApFlags.UserNoneKernelReadExecute); _kernelRange.Map(KernelRegionCodeOffset, kernelCodePa, KernelRegionCodeSize, ApFlags.UserNoneKernelReadExecute);
} }
public void InitializeMmu(ulong vcpu) public void InitializeMmu(ulong vcpu)
{ {
HvApi.hv_vcpu_set_sys_reg(vcpu, hv_sys_reg_t.HV_SYS_REG_VBAR_EL1, KernelRegionBase + KernelRegionCodeOffset); HvApi.hv_vcpu_set_sys_reg(vcpu, HvSysReg.VBAR_EL1, KernelRegionBase + KernelRegionCodeOffset);
HvApi.hv_vcpu_set_sys_reg(vcpu, hv_sys_reg_t.HV_SYS_REG_TTBR0_EL1, _userRange.GetIpaBase()); HvApi.hv_vcpu_set_sys_reg(vcpu, HvSysReg.TTBR0_EL1, _userRange.GetIpaBase());
HvApi.hv_vcpu_set_sys_reg(vcpu, hv_sys_reg_t.HV_SYS_REG_TTBR1_EL1, _kernelRange.GetIpaBase()); HvApi.hv_vcpu_set_sys_reg(vcpu, HvSysReg.TTBR1_EL1, _kernelRange.GetIpaBase());
HvApi.hv_vcpu_set_sys_reg(vcpu, hv_sys_reg_t.HV_SYS_REG_MAIR_EL1, 0xffUL); HvApi.hv_vcpu_set_sys_reg(vcpu, HvSysReg.MAIR_EL1, 0xffUL);
HvApi.hv_vcpu_set_sys_reg(vcpu, hv_sys_reg_t.HV_SYS_REG_TCR_EL1, 0x00000011B5193519UL); HvApi.hv_vcpu_set_sys_reg(vcpu, HvSysReg.TCR_EL1, 0x00000011B5193519UL);
HvApi.hv_vcpu_set_sys_reg(vcpu, hv_sys_reg_t.HV_SYS_REG_SCTLR_EL1, 0x0000000034D5D925UL); HvApi.hv_vcpu_set_sys_reg(vcpu, HvSysReg.SCTLR_EL1, 0x0000000034D5D925UL);
} }
public bool GetAndClearUserTlbInvalidationPending() public bool GetAndClearUserTlbInvalidationPending()
@@ -115,7 +113,7 @@ namespace Ryujinx.Cpu.AppleHv
MemoryPermission.ReadAndWrite => ApFlags.UserReadWriteKernelReadWrite, MemoryPermission.ReadAndWrite => ApFlags.UserReadWriteKernelReadWrite,
MemoryPermission.ReadAndExecute => ApFlags.UserReadExecuteKernelRead, MemoryPermission.ReadAndExecute => ApFlags.UserReadExecuteKernelRead,
MemoryPermission.ReadWriteExecute => ApFlags.UserReadWriteExecuteKernelReadWrite, MemoryPermission.ReadWriteExecute => ApFlags.UserReadWriteExecuteKernelReadWrite,
_ => throw new ArgumentException($"Permission \"{permission}\" is invalid.") _ => throw new ArgumentException($"Permission \"{permission}\" is invalid."),
}; };
} }
@@ -126,4 +124,4 @@ namespace Ryujinx.Cpu.AppleHv
HvVm.DestroyAddressSpace(_asBase, _backingSize); HvVm.DestroyAddressSpace(_asBase, _backingSize);
} }
} }
} }

View File

@@ -34,7 +34,7 @@ namespace Ryujinx.Cpu.AppleHv
ulong size = (ulong)count * sizeof(ulong); ulong size = (ulong)count * sizeof(ulong);
Allocation = blockAllocator.Allocate(size, PageSize); Allocation = blockAllocator.Allocate(size, PageSize);
AsSpan().Fill(0UL); AsSpan().Clear();
if (hasNext) if (hasNext)
{ {
@@ -42,7 +42,7 @@ namespace Ryujinx.Cpu.AppleHv
} }
} }
public unsafe Span<ulong> AsSpan() public Span<ulong> AsSpan()
{ {
return MemoryMarshal.Cast<byte, ulong>(Allocation.Memory.GetSpan(Allocation.Offset, (int)Allocation.Size)); return MemoryMarshal.Cast<byte, ulong>(Allocation.Memory.GetSpan(Allocation.Offset, (int)Allocation.Size));
} }
@@ -52,12 +52,10 @@ namespace Ryujinx.Cpu.AppleHv
private int _tlbInvalidationPending; private int _tlbInvalidationPending;
private readonly HvIpaAllocator _ipaAllocator;
private readonly HvMemoryBlockAllocator _blockAllocator; private readonly HvMemoryBlockAllocator _blockAllocator;
public HvAddressSpaceRange(HvIpaAllocator ipaAllocator) public HvAddressSpaceRange(HvIpaAllocator ipaAllocator)
{ {
_ipaAllocator = ipaAllocator;
_blockAllocator = new HvMemoryBlockAllocator(ipaAllocator, (int)AllocationGranule); _blockAllocator = new HvMemoryBlockAllocator(ipaAllocator, (int)AllocationGranule);
} }
@@ -129,7 +127,7 @@ namespace Ryujinx.Cpu.AppleHv
ulong endVa = (va + size + PageMask) & ~((ulong)PageMask); ulong endVa = (va + size + PageMask) & ~((ulong)PageMask);
va &= ~((ulong)PageMask); va &= ~((ulong)PageMask);
(ulong blockSize, int blockShift) = GetBlockSizeAndShift(depth); (ulong blockSize, _) = GetBlockSizeAndShift(depth);
while (va < endVa) while (va < endVa)
{ {
@@ -138,7 +136,7 @@ namespace Ryujinx.Cpu.AppleHv
int l = (int)(va >> (PageBits + (2 - depth) * LevelBits)) & LevelMask; int l = (int)(va >> (PageBits + (2 - depth) * LevelBits)) & LevelMask;
PtLevel nextTable = level.Next != null ? level.Next[l] : null; PtLevel nextTable = level.Next?[l];
if (nextTable != null) if (nextTable != null)
{ {
@@ -190,7 +188,7 @@ namespace Ryujinx.Cpu.AppleHv
ulong endVa = (va + size + PageSize - 1) & ~((ulong)PageSize - 1); ulong endVa = (va + size + PageSize - 1) & ~((ulong)PageSize - 1);
va &= ~((ulong)PageSize - 1); va &= ~((ulong)PageSize - 1);
(ulong blockSize, int blockShift) = GetBlockSizeAndShift(depth); (ulong blockSize, _) = GetBlockSizeAndShift(depth);
while (va < endVa) while (va < endVa)
{ {
@@ -204,7 +202,7 @@ namespace Ryujinx.Cpu.AppleHv
// First check if the region is mapped. // First check if the region is mapped.
if ((pte & 3) != 0) if ((pte & 3) != 0)
{ {
PtLevel nextTable = level.Next != null ? level.Next[l] : null; PtLevel nextTable = level.Next?[l];
if (nextTable != null) if (nextTable != null)
{ {
@@ -240,10 +238,10 @@ namespace Ryujinx.Cpu.AppleHv
pte &= ~3UL; pte &= ~3UL;
pte |= (depth == 2 ? 3UL : 1UL); pte |= (depth == 2 ? 3UL : 1UL);
PtLevel level = new PtLevel(_blockAllocator, LevelCount, depth < 2); PtLevel level = new(_blockAllocator, LevelCount, depth < 2);
Span<ulong> currentLevel = level.AsSpan(); Span<ulong> currentLevel = level.AsSpan();
(ulong blockSize, int blockShift) = GetBlockSizeAndShift(depth); (_, int blockShift) = GetBlockSizeAndShift(depth);
// Fill in the blocks. // Fill in the blocks.
for (int i = 0; i < LevelCount; i++) for (int i = 0; i < LevelCount; i++)
@@ -334,7 +332,7 @@ namespace Ryujinx.Cpu.AppleHv
if ((currentTable[index] & 1) == 0) if ((currentTable[index] & 1) == 0)
{ {
PtLevel nextLevel = new PtLevel(_blockAllocator, LevelCount, hasNext); PtLevel nextLevel = new(_blockAllocator, LevelCount, hasNext);
currentTable[index] = (nextLevel.Address & ~(ulong)PageMask) | 3UL; currentTable[index] = (nextLevel.Address & ~(ulong)PageMask) | 3UL;
level.Next[index] = nextLevel; level.Next[index] = nextLevel;
@@ -347,7 +345,7 @@ namespace Ryujinx.Cpu.AppleHv
} }
} }
private void WriteBlock(PtLevel level, int index, int depth, ulong pa, ulong attr) private static void WriteBlock(PtLevel level, int index, int depth, ulong pa, ulong attr)
{ {
Span<ulong> currentTable = level.AsSpan(); Span<ulong> currentTable = level.AsSpan();
@@ -367,4 +365,4 @@ namespace Ryujinx.Cpu.AppleHv
_blockAllocator.Dispose(); _blockAllocator.Dispose();
} }
} }
} }

View File

@@ -1,245 +1,244 @@
using ARMeilleure.State;
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace Ryujinx.Cpu.AppleHv namespace Ryujinx.Cpu.AppleHv
{ {
struct hv_vcpu_exit_exception_t struct HvVcpuExitException
{ {
#pragma warning disable CS0649 #pragma warning disable CS0649 // Field is never assigned to
public ulong syndrome; public ulong Syndrome;
public ulong virtual_address; public ulong VirtualAddress;
public ulong physical_address; public ulong PhysicalAddress;
#pragma warning restore CS0649 #pragma warning restore CS0649
} }
struct hv_vcpu_exit_t struct HvVcpuExit
{ {
#pragma warning disable CS0649 #pragma warning disable CS0649 // Field is never assigned to
public uint reason; public uint Reason;
public hv_vcpu_exit_exception_t exception; public HvVcpuExitException Exception;
#pragma warning restore CS0649 #pragma warning restore CS0649
} }
enum hv_reg_t : uint enum HvReg : uint
{ {
HV_REG_X0, X0,
HV_REG_X1, X1,
HV_REG_X2, X2,
HV_REG_X3, X3,
HV_REG_X4, X4,
HV_REG_X5, X5,
HV_REG_X6, X6,
HV_REG_X7, X7,
HV_REG_X8, X8,
HV_REG_X9, X9,
HV_REG_X10, X10,
HV_REG_X11, X11,
HV_REG_X12, X12,
HV_REG_X13, X13,
HV_REG_X14, X14,
HV_REG_X15, X15,
HV_REG_X16, X16,
HV_REG_X17, X17,
HV_REG_X18, X18,
HV_REG_X19, X19,
HV_REG_X20, X20,
HV_REG_X21, X21,
HV_REG_X22, X22,
HV_REG_X23, X23,
HV_REG_X24, X24,
HV_REG_X25, X25,
HV_REG_X26, X26,
HV_REG_X27, X27,
HV_REG_X28, X28,
HV_REG_X29, X29,
HV_REG_FP = HV_REG_X29, FP = X29,
HV_REG_X30, X30,
HV_REG_LR = HV_REG_X30, LR = X30,
HV_REG_PC, PC,
HV_REG_FPCR, FPCR,
HV_REG_FPSR, FPSR,
HV_REG_CPSR, CPSR,
} }
enum hv_simd_fp_reg_t : uint enum HvSimdFPReg : uint
{ {
HV_SIMD_FP_REG_Q0, Q0,
HV_SIMD_FP_REG_Q1, Q1,
HV_SIMD_FP_REG_Q2, Q2,
HV_SIMD_FP_REG_Q3, Q3,
HV_SIMD_FP_REG_Q4, Q4,
HV_SIMD_FP_REG_Q5, Q5,
HV_SIMD_FP_REG_Q6, Q6,
HV_SIMD_FP_REG_Q7, Q7,
HV_SIMD_FP_REG_Q8, Q8,
HV_SIMD_FP_REG_Q9, Q9,
HV_SIMD_FP_REG_Q10, Q10,
HV_SIMD_FP_REG_Q11, Q11,
HV_SIMD_FP_REG_Q12, Q12,
HV_SIMD_FP_REG_Q13, Q13,
HV_SIMD_FP_REG_Q14, Q14,
HV_SIMD_FP_REG_Q15, Q15,
HV_SIMD_FP_REG_Q16, Q16,
HV_SIMD_FP_REG_Q17, Q17,
HV_SIMD_FP_REG_Q18, Q18,
HV_SIMD_FP_REG_Q19, Q19,
HV_SIMD_FP_REG_Q20, Q20,
HV_SIMD_FP_REG_Q21, Q21,
HV_SIMD_FP_REG_Q22, Q22,
HV_SIMD_FP_REG_Q23, Q23,
HV_SIMD_FP_REG_Q24, Q24,
HV_SIMD_FP_REG_Q25, Q25,
HV_SIMD_FP_REG_Q26, Q26,
HV_SIMD_FP_REG_Q27, Q27,
HV_SIMD_FP_REG_Q28, Q28,
HV_SIMD_FP_REG_Q29, Q29,
HV_SIMD_FP_REG_Q30, Q30,
HV_SIMD_FP_REG_Q31, Q31,
} }
enum hv_sys_reg_t : ushort enum HvSysReg : ushort
{ {
HV_SYS_REG_DBGBVR0_EL1 = 0x8004, DBGBVR0_EL1 = 0x8004,
HV_SYS_REG_DBGBCR0_EL1 = 0x8005, DBGBCR0_EL1 = 0x8005,
HV_SYS_REG_DBGWVR0_EL1 = 0x8006, DBGWVR0_EL1 = 0x8006,
HV_SYS_REG_DBGWCR0_EL1 = 0x8007, DBGWCR0_EL1 = 0x8007,
HV_SYS_REG_DBGBVR1_EL1 = 0x800c, DBGBVR1_EL1 = 0x800c,
HV_SYS_REG_DBGBCR1_EL1 = 0x800d, DBGBCR1_EL1 = 0x800d,
HV_SYS_REG_DBGWVR1_EL1 = 0x800e, DBGWVR1_EL1 = 0x800e,
HV_SYS_REG_DBGWCR1_EL1 = 0x800f, DBGWCR1_EL1 = 0x800f,
HV_SYS_REG_MDCCINT_EL1 = 0x8010, MDCCINT_EL1 = 0x8010,
HV_SYS_REG_MDSCR_EL1 = 0x8012, MDSCR_EL1 = 0x8012,
HV_SYS_REG_DBGBVR2_EL1 = 0x8014, DBGBVR2_EL1 = 0x8014,
HV_SYS_REG_DBGBCR2_EL1 = 0x8015, DBGBCR2_EL1 = 0x8015,
HV_SYS_REG_DBGWVR2_EL1 = 0x8016, DBGWVR2_EL1 = 0x8016,
HV_SYS_REG_DBGWCR2_EL1 = 0x8017, DBGWCR2_EL1 = 0x8017,
HV_SYS_REG_DBGBVR3_EL1 = 0x801c, DBGBVR3_EL1 = 0x801c,
HV_SYS_REG_DBGBCR3_EL1 = 0x801d, DBGBCR3_EL1 = 0x801d,
HV_SYS_REG_DBGWVR3_EL1 = 0x801e, DBGWVR3_EL1 = 0x801e,
HV_SYS_REG_DBGWCR3_EL1 = 0x801f, DBGWCR3_EL1 = 0x801f,
HV_SYS_REG_DBGBVR4_EL1 = 0x8024, DBGBVR4_EL1 = 0x8024,
HV_SYS_REG_DBGBCR4_EL1 = 0x8025, DBGBCR4_EL1 = 0x8025,
HV_SYS_REG_DBGWVR4_EL1 = 0x8026, DBGWVR4_EL1 = 0x8026,
HV_SYS_REG_DBGWCR4_EL1 = 0x8027, DBGWCR4_EL1 = 0x8027,
HV_SYS_REG_DBGBVR5_EL1 = 0x802c, DBGBVR5_EL1 = 0x802c,
HV_SYS_REG_DBGBCR5_EL1 = 0x802d, DBGBCR5_EL1 = 0x802d,
HV_SYS_REG_DBGWVR5_EL1 = 0x802e, DBGWVR5_EL1 = 0x802e,
HV_SYS_REG_DBGWCR5_EL1 = 0x802f, DBGWCR5_EL1 = 0x802f,
HV_SYS_REG_DBGBVR6_EL1 = 0x8034, DBGBVR6_EL1 = 0x8034,
HV_SYS_REG_DBGBCR6_EL1 = 0x8035, DBGBCR6_EL1 = 0x8035,
HV_SYS_REG_DBGWVR6_EL1 = 0x8036, DBGWVR6_EL1 = 0x8036,
HV_SYS_REG_DBGWCR6_EL1 = 0x8037, DBGWCR6_EL1 = 0x8037,
HV_SYS_REG_DBGBVR7_EL1 = 0x803c, DBGBVR7_EL1 = 0x803c,
HV_SYS_REG_DBGBCR7_EL1 = 0x803d, DBGBCR7_EL1 = 0x803d,
HV_SYS_REG_DBGWVR7_EL1 = 0x803e, DBGWVR7_EL1 = 0x803e,
HV_SYS_REG_DBGWCR7_EL1 = 0x803f, DBGWCR7_EL1 = 0x803f,
HV_SYS_REG_DBGBVR8_EL1 = 0x8044, DBGBVR8_EL1 = 0x8044,
HV_SYS_REG_DBGBCR8_EL1 = 0x8045, DBGBCR8_EL1 = 0x8045,
HV_SYS_REG_DBGWVR8_EL1 = 0x8046, DBGWVR8_EL1 = 0x8046,
HV_SYS_REG_DBGWCR8_EL1 = 0x8047, DBGWCR8_EL1 = 0x8047,
HV_SYS_REG_DBGBVR9_EL1 = 0x804c, DBGBVR9_EL1 = 0x804c,
HV_SYS_REG_DBGBCR9_EL1 = 0x804d, DBGBCR9_EL1 = 0x804d,
HV_SYS_REG_DBGWVR9_EL1 = 0x804e, DBGWVR9_EL1 = 0x804e,
HV_SYS_REG_DBGWCR9_EL1 = 0x804f, DBGWCR9_EL1 = 0x804f,
HV_SYS_REG_DBGBVR10_EL1 = 0x8054, DBGBVR10_EL1 = 0x8054,
HV_SYS_REG_DBGBCR10_EL1 = 0x8055, DBGBCR10_EL1 = 0x8055,
HV_SYS_REG_DBGWVR10_EL1 = 0x8056, DBGWVR10_EL1 = 0x8056,
HV_SYS_REG_DBGWCR10_EL1 = 0x8057, DBGWCR10_EL1 = 0x8057,
HV_SYS_REG_DBGBVR11_EL1 = 0x805c, DBGBVR11_EL1 = 0x805c,
HV_SYS_REG_DBGBCR11_EL1 = 0x805d, DBGBCR11_EL1 = 0x805d,
HV_SYS_REG_DBGWVR11_EL1 = 0x805e, DBGWVR11_EL1 = 0x805e,
HV_SYS_REG_DBGWCR11_EL1 = 0x805f, DBGWCR11_EL1 = 0x805f,
HV_SYS_REG_DBGBVR12_EL1 = 0x8064, DBGBVR12_EL1 = 0x8064,
HV_SYS_REG_DBGBCR12_EL1 = 0x8065, DBGBCR12_EL1 = 0x8065,
HV_SYS_REG_DBGWVR12_EL1 = 0x8066, DBGWVR12_EL1 = 0x8066,
HV_SYS_REG_DBGWCR12_EL1 = 0x8067, DBGWCR12_EL1 = 0x8067,
HV_SYS_REG_DBGBVR13_EL1 = 0x806c, DBGBVR13_EL1 = 0x806c,
HV_SYS_REG_DBGBCR13_EL1 = 0x806d, DBGBCR13_EL1 = 0x806d,
HV_SYS_REG_DBGWVR13_EL1 = 0x806e, DBGWVR13_EL1 = 0x806e,
HV_SYS_REG_DBGWCR13_EL1 = 0x806f, DBGWCR13_EL1 = 0x806f,
HV_SYS_REG_DBGBVR14_EL1 = 0x8074, DBGBVR14_EL1 = 0x8074,
HV_SYS_REG_DBGBCR14_EL1 = 0x8075, DBGBCR14_EL1 = 0x8075,
HV_SYS_REG_DBGWVR14_EL1 = 0x8076, DBGWVR14_EL1 = 0x8076,
HV_SYS_REG_DBGWCR14_EL1 = 0x8077, DBGWCR14_EL1 = 0x8077,
HV_SYS_REG_DBGBVR15_EL1 = 0x807c, DBGBVR15_EL1 = 0x807c,
HV_SYS_REG_DBGBCR15_EL1 = 0x807d, DBGBCR15_EL1 = 0x807d,
HV_SYS_REG_DBGWVR15_EL1 = 0x807e, DBGWVR15_EL1 = 0x807e,
HV_SYS_REG_DBGWCR15_EL1 = 0x807f, DBGWCR15_EL1 = 0x807f,
HV_SYS_REG_MIDR_EL1 = 0xc000, MIDR_EL1 = 0xc000,
HV_SYS_REG_MPIDR_EL1 = 0xc005, MPIDR_EL1 = 0xc005,
HV_SYS_REG_ID_AA64PFR0_EL1 = 0xc020, ID_AA64PFR0_EL1 = 0xc020,
HV_SYS_REG_ID_AA64PFR1_EL1 = 0xc021, ID_AA64PFR1_EL1 = 0xc021,
HV_SYS_REG_ID_AA64DFR0_EL1 = 0xc028, ID_AA64DFR0_EL1 = 0xc028,
HV_SYS_REG_ID_AA64DFR1_EL1 = 0xc029, ID_AA64DFR1_EL1 = 0xc029,
HV_SYS_REG_ID_AA64ISAR0_EL1 = 0xc030, ID_AA64ISAR0_EL1 = 0xc030,
HV_SYS_REG_ID_AA64ISAR1_EL1 = 0xc031, ID_AA64ISAR1_EL1 = 0xc031,
HV_SYS_REG_ID_AA64MMFR0_EL1 = 0xc038, ID_AA64MMFR0_EL1 = 0xc038,
HV_SYS_REG_ID_AA64MMFR1_EL1 = 0xc039, ID_AA64MMFR1_EL1 = 0xc039,
HV_SYS_REG_ID_AA64MMFR2_EL1 = 0xc03a, ID_AA64MMFR2_EL1 = 0xc03a,
HV_SYS_REG_SCTLR_EL1 = 0xc080, SCTLR_EL1 = 0xc080,
HV_SYS_REG_CPACR_EL1 = 0xc082, CPACR_EL1 = 0xc082,
HV_SYS_REG_TTBR0_EL1 = 0xc100, TTBR0_EL1 = 0xc100,
HV_SYS_REG_TTBR1_EL1 = 0xc101, TTBR1_EL1 = 0xc101,
HV_SYS_REG_TCR_EL1 = 0xc102, TCR_EL1 = 0xc102,
HV_SYS_REG_APIAKEYLO_EL1 = 0xc108, APIAKEYLO_EL1 = 0xc108,
HV_SYS_REG_APIAKEYHI_EL1 = 0xc109, APIAKEYHI_EL1 = 0xc109,
HV_SYS_REG_APIBKEYLO_EL1 = 0xc10a, APIBKEYLO_EL1 = 0xc10a,
HV_SYS_REG_APIBKEYHI_EL1 = 0xc10b, APIBKEYHI_EL1 = 0xc10b,
HV_SYS_REG_APDAKEYLO_EL1 = 0xc110, APDAKEYLO_EL1 = 0xc110,
HV_SYS_REG_APDAKEYHI_EL1 = 0xc111, APDAKEYHI_EL1 = 0xc111,
HV_SYS_REG_APDBKEYLO_EL1 = 0xc112, APDBKEYLO_EL1 = 0xc112,
HV_SYS_REG_APDBKEYHI_EL1 = 0xc113, APDBKEYHI_EL1 = 0xc113,
HV_SYS_REG_APGAKEYLO_EL1 = 0xc118, APGAKEYLO_EL1 = 0xc118,
HV_SYS_REG_APGAKEYHI_EL1 = 0xc119, APGAKEYHI_EL1 = 0xc119,
HV_SYS_REG_SPSR_EL1 = 0xc200, SPSR_EL1 = 0xc200,
HV_SYS_REG_ELR_EL1 = 0xc201, ELR_EL1 = 0xc201,
HV_SYS_REG_SP_EL0 = 0xc208, SP_EL0 = 0xc208,
HV_SYS_REG_AFSR0_EL1 = 0xc288, AFSR0_EL1 = 0xc288,
HV_SYS_REG_AFSR1_EL1 = 0xc289, AFSR1_EL1 = 0xc289,
HV_SYS_REG_ESR_EL1 = 0xc290, ESR_EL1 = 0xc290,
HV_SYS_REG_FAR_EL1 = 0xc300, FAR_EL1 = 0xc300,
HV_SYS_REG_PAR_EL1 = 0xc3a0, PAR_EL1 = 0xc3a0,
HV_SYS_REG_MAIR_EL1 = 0xc510, MAIR_EL1 = 0xc510,
HV_SYS_REG_AMAIR_EL1 = 0xc518, AMAIR_EL1 = 0xc518,
HV_SYS_REG_VBAR_EL1 = 0xc600, VBAR_EL1 = 0xc600,
HV_SYS_REG_CONTEXTIDR_EL1 = 0xc681, CONTEXTIDR_EL1 = 0xc681,
HV_SYS_REG_TPIDR_EL1 = 0xc684, TPIDR_EL1 = 0xc684,
HV_SYS_REG_CNTKCTL_EL1 = 0xc708, CNTKCTL_EL1 = 0xc708,
HV_SYS_REG_CSSELR_EL1 = 0xd000, CSSELR_EL1 = 0xd000,
HV_SYS_REG_TPIDR_EL0 = 0xde82, TPIDR_EL0 = 0xde82,
HV_SYS_REG_TPIDRRO_EL0 = 0xde83, TPIDRRO_EL0 = 0xde83,
HV_SYS_REG_CNTV_CTL_EL0 = 0xdf19, CNTV_CTL_EL0 = 0xdf19,
HV_SYS_REG_CNTV_CVAL_EL0 = 0xdf1a, CNTV_CVAL_EL0 = 0xdf1a,
HV_SYS_REG_SP_EL1 = 0xe208, SP_EL1 = 0xe208,
} }
enum hv_memory_flags_t : ulong enum HvMemoryFlags : ulong
{ {
HV_MEMORY_READ = 1UL << 0, Read = 1UL << 0,
HV_MEMORY_WRITE = 1UL << 1, Write = 1UL << 1,
HV_MEMORY_EXEC = 1UL << 2 Exec = 1UL << 2,
} }
enum hv_result_t : uint enum HvResult : uint
{ {
HV_SUCCESS = 0, Success = 0,
HV_ERROR = 0xfae94001, Error = 0xfae94001,
HV_BUSY = 0xfae94002, Busy = 0xfae94002,
HV_BAD_ARGUMENT = 0xfae94003, BadArgument = 0xfae94003,
HV_NO_RESOURCES = 0xfae94005, NoResources = 0xfae94005,
HV_NO_DEVICE = 0xfae94006, NoDevice = 0xfae94006,
HV_DENIED = 0xfae94007, Denied = 0xfae94007,
HV_UNSUPPORTED = 0xfae9400f Unsupported = 0xfae9400f,
} }
enum hv_interrupt_type_t : uint enum HvInterruptType : uint
{ {
HV_INTERRUPT_TYPE_IRQ, IRQ,
HV_INTERRUPT_TYPE_FIQ FIQ,
} }
struct hv_simd_fp_uchar16_t struct HvSimdFPUchar16
{ {
public ulong Low; public ulong Low;
public ulong High; public ulong High;
@@ -247,9 +246,9 @@ namespace Ryujinx.Cpu.AppleHv
static class HvResultExtensions static class HvResultExtensions
{ {
public static void ThrowOnError(this hv_result_t result) public static void ThrowOnError(this HvResult result)
{ {
if (result != hv_result_t.HV_SUCCESS) if (result != HvResult.Success)
{ {
throw new Exception($"Unexpected result \"{result}\"."); throw new Exception($"Unexpected result \"{result}\".");
} }
@@ -261,60 +260,60 @@ namespace Ryujinx.Cpu.AppleHv
public const string LibraryName = "/System/Library/Frameworks/Hypervisor.framework/Hypervisor"; public const string LibraryName = "/System/Library/Frameworks/Hypervisor.framework/Hypervisor";
[LibraryImport(LibraryName, SetLastError = true)] [LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vm_get_max_vcpu_count(out uint max_vcpu_count); public static partial HvResult hv_vm_get_max_vcpu_count(out uint max_vcpu_count);
[LibraryImport(LibraryName, SetLastError = true)] [LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vm_create(IntPtr config); public static partial HvResult hv_vm_create(IntPtr config);
[LibraryImport(LibraryName, SetLastError = true)] [LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vm_destroy(); public static partial HvResult hv_vm_destroy();
[LibraryImport(LibraryName, SetLastError = true)] [LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vm_map(ulong addr, ulong ipa, ulong size, hv_memory_flags_t flags); public static partial HvResult hv_vm_map(ulong addr, ulong ipa, ulong size, HvMemoryFlags flags);
[LibraryImport(LibraryName, SetLastError = true)] [LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vm_unmap(ulong ipa, ulong size); public static partial HvResult hv_vm_unmap(ulong ipa, ulong size);
[LibraryImport(LibraryName, SetLastError = true)] [LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vm_protect(ulong ipa, ulong size, hv_memory_flags_t flags); public static partial HvResult hv_vm_protect(ulong ipa, ulong size, HvMemoryFlags flags);
[LibraryImport(LibraryName, SetLastError = true)] [LibraryImport(LibraryName, SetLastError = true)]
public unsafe static partial hv_result_t hv_vcpu_create(out ulong vcpu, ref hv_vcpu_exit_t* exit, IntPtr config); public unsafe static partial HvResult hv_vcpu_create(out ulong vcpu, ref HvVcpuExit* exit, IntPtr config);
[LibraryImport(LibraryName, SetLastError = true)] [LibraryImport(LibraryName, SetLastError = true)]
public unsafe static partial hv_result_t hv_vcpu_destroy(ulong vcpu); public unsafe static partial HvResult hv_vcpu_destroy(ulong vcpu);
[LibraryImport(LibraryName, SetLastError = true)] [LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_run(ulong vcpu); public static partial HvResult hv_vcpu_run(ulong vcpu);
[LibraryImport(LibraryName, SetLastError = true)] [LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpus_exit(ref ulong vcpus, uint vcpu_count); public static partial HvResult hv_vcpus_exit(ref ulong vcpus, uint vcpu_count);
[LibraryImport(LibraryName, SetLastError = true)] [LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_set_vtimer_mask(ulong vcpu, [MarshalAs(UnmanagedType.Bool)] bool vtimer_is_masked); public static partial HvResult hv_vcpu_set_vtimer_mask(ulong vcpu, [MarshalAs(UnmanagedType.Bool)] bool vtimer_is_masked);
[LibraryImport(LibraryName, SetLastError = true)] [LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_get_reg(ulong vcpu, hv_reg_t reg, out ulong value); public static partial HvResult hv_vcpu_get_reg(ulong vcpu, HvReg reg, out ulong value);
[LibraryImport(LibraryName, SetLastError = true)] [LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_set_reg(ulong vcpu, hv_reg_t reg, ulong value); public static partial HvResult hv_vcpu_set_reg(ulong vcpu, HvReg reg, ulong value);
[LibraryImport(LibraryName, SetLastError = true)] [LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_get_simd_fp_reg(ulong vcpu, hv_simd_fp_reg_t reg, out hv_simd_fp_uchar16_t value); public static partial HvResult hv_vcpu_get_simd_fp_reg(ulong vcpu, HvSimdFPReg reg, out HvSimdFPUchar16 value);
[LibraryImport(LibraryName, SetLastError = true)] [LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_set_simd_fp_reg(ulong vcpu, hv_simd_fp_reg_t reg, hv_simd_fp_uchar16_t value); // DO NOT USE DIRECTLY! public static partial HvResult hv_vcpu_set_simd_fp_reg(ulong vcpu, HvSimdFPReg reg, HvSimdFPUchar16 value); // DO NOT USE DIRECTLY!
[LibraryImport(LibraryName, SetLastError = true)] [LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_get_sys_reg(ulong vcpu, hv_sys_reg_t reg, out ulong value); public static partial HvResult hv_vcpu_get_sys_reg(ulong vcpu, HvSysReg reg, out ulong value);
[LibraryImport(LibraryName, SetLastError = true)] [LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_set_sys_reg(ulong vcpu, hv_sys_reg_t reg, ulong value); public static partial HvResult hv_vcpu_set_sys_reg(ulong vcpu, HvSysReg reg, ulong value);
[LibraryImport(LibraryName, SetLastError = true)] [LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_get_pending_interrupt(ulong vcpu, hv_interrupt_type_t type, [MarshalAs(UnmanagedType.Bool)] out bool pending); public static partial HvResult hv_vcpu_get_pending_interrupt(ulong vcpu, HvInterruptType type, [MarshalAs(UnmanagedType.Bool)] out bool pending);
[LibraryImport(LibraryName, SetLastError = true)] [LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_set_pending_interrupt(ulong vcpu, hv_interrupt_type_t type, [MarshalAs(UnmanagedType.Bool)] bool pending); public static partial HvResult hv_vcpu_set_pending_interrupt(ulong vcpu, HvInterruptType type, [MarshalAs(UnmanagedType.Bool)] bool pending);
} }
} }

View File

@@ -1,5 +1,4 @@
using ARMeilleure.Memory; using ARMeilleure.Memory;
using System;
namespace Ryujinx.Cpu.AppleHv namespace Ryujinx.Cpu.AppleHv
{ {
@@ -14,10 +13,6 @@ namespace Ryujinx.Cpu.AppleHv
_memoryManager = (HvMemoryManager)memory; _memoryManager = (HvMemoryManager)memory;
} }
private void UnmapHandler(ulong address, ulong size)
{
}
/// <inheritdoc/> /// <inheritdoc/>
public IExecutionContext CreateExecutionContext(ExceptionCallbacks exceptionCallbacks) public IExecutionContext CreateExecutionContext(ExceptionCallbacks exceptionCallbacks)
{ {
@@ -44,4 +39,4 @@ namespace Ryujinx.Cpu.AppleHv
{ {
} }
} }
} }

View File

@@ -17,4 +17,4 @@ namespace Ryujinx.Cpu.AppleHv
return new HvCpuContext(_tickSource, memoryManager, for64Bit); return new HvCpuContext(_tickSource, memoryManager, for64Bit);
} }
} }
} }

View File

@@ -125,17 +125,17 @@ namespace Ryujinx.Cpu.AppleHv
{ {
HvVcpu vcpu = HvVcpuPool.Instance.Create(memoryManager.AddressSpace, _shadowContext, SwapContext); HvVcpu vcpu = HvVcpuPool.Instance.Create(memoryManager.AddressSpace, _shadowContext, SwapContext);
HvApi.hv_vcpu_set_reg(vcpu.Handle, hv_reg_t.HV_REG_PC, address).ThrowOnError(); HvApi.hv_vcpu_set_reg(vcpu.Handle, HvReg.PC, address).ThrowOnError();
while (Running) while (Running)
{ {
HvApi.hv_vcpu_run(vcpu.Handle).ThrowOnError(); HvApi.hv_vcpu_run(vcpu.Handle).ThrowOnError();
uint reason = vcpu.ExitInfo->reason; uint reason = vcpu.ExitInfo->Reason;
if (reason == 1) if (reason == 1)
{ {
uint hvEsr = (uint)vcpu.ExitInfo->exception.syndrome; uint hvEsr = (uint)vcpu.ExitInfo->Exception.Syndrome;
ExceptionClass hvEc = (ExceptionClass)(hvEsr >> 26); ExceptionClass hvEc = (ExceptionClass)(hvEsr >> 26);
if (hvEc != ExceptionClass.HvcAarch64) if (hvEc != ExceptionClass.HvcAarch64)
@@ -144,7 +144,7 @@ namespace Ryujinx.Cpu.AppleHv
} }
address = SynchronousException(memoryManager, ref vcpu); address = SynchronousException(memoryManager, ref vcpu);
HvApi.hv_vcpu_set_reg(vcpu.Handle, hv_reg_t.HV_REG_PC, address).ThrowOnError(); HvApi.hv_vcpu_set_reg(vcpu.Handle, HvReg.PC, address).ThrowOnError();
} }
else if (reason == 0) else if (reason == 0)
{ {
@@ -168,8 +168,8 @@ namespace Ryujinx.Cpu.AppleHv
{ {
ulong vcpuHandle = vcpu.Handle; ulong vcpuHandle = vcpu.Handle;
HvApi.hv_vcpu_get_sys_reg(vcpuHandle, hv_sys_reg_t.HV_SYS_REG_ELR_EL1, out ulong elr).ThrowOnError(); HvApi.hv_vcpu_get_sys_reg(vcpuHandle, HvSysReg.ELR_EL1, out ulong elr).ThrowOnError();
HvApi.hv_vcpu_get_sys_reg(vcpuHandle, hv_sys_reg_t.HV_SYS_REG_ESR_EL1, out ulong esr).ThrowOnError(); HvApi.hv_vcpu_get_sys_reg(vcpuHandle, HvSysReg.ESR_EL1, out ulong esr).ThrowOnError();
ExceptionClass ec = (ExceptionClass)((uint)esr >> 26); ExceptionClass ec = (ExceptionClass)((uint)esr >> 26);
@@ -180,7 +180,7 @@ namespace Ryujinx.Cpu.AppleHv
break; break;
case ExceptionClass.TrappedMsrMrsSystem: case ExceptionClass.TrappedMsrMrsSystem:
InstructionTrap((uint)esr); InstructionTrap((uint)esr);
HvApi.hv_vcpu_set_sys_reg(vcpuHandle, hv_sys_reg_t.HV_SYS_REG_ELR_EL1, elr + 4UL).ThrowOnError(); HvApi.hv_vcpu_set_sys_reg(vcpuHandle, HvSysReg.ELR_EL1, elr + 4UL).ThrowOnError();
break; break;
case ExceptionClass.SvcAarch64: case ExceptionClass.SvcAarch64:
ReturnToPool(vcpu); ReturnToPool(vcpu);
@@ -204,7 +204,7 @@ namespace Ryujinx.Cpu.AppleHv
} }
} }
private void DataAbort(MemoryTracking tracking, ulong vcpu, uint esr) private static void DataAbort(MemoryTracking tracking, ulong vcpu, uint esr)
{ {
bool write = (esr & (1u << 6)) != 0; bool write = (esr & (1u << 6)) != 0;
bool farValid = (esr & (1u << 10)) == 0; bool farValid = (esr & (1u << 10)) == 0;
@@ -212,7 +212,7 @@ namespace Ryujinx.Cpu.AppleHv
if (farValid) if (farValid)
{ {
HvApi.hv_vcpu_get_sys_reg(vcpu, hv_sys_reg_t.HV_SYS_REG_FAR_EL1, out ulong far).ThrowOnError(); HvApi.hv_vcpu_get_sys_reg(vcpu, HvSysReg.FAR_EL1, out ulong far).ThrowOnError();
ulong size = 1UL << accessSizeLog2; ulong size = 1UL << accessSizeLog2;
@@ -281,4 +281,4 @@ namespace Ryujinx.Cpu.AppleHv
{ {
} }
} }
} }

View File

@@ -2,7 +2,7 @@ using ARMeilleure.State;
namespace Ryujinx.Cpu.AppleHv namespace Ryujinx.Cpu.AppleHv
{ {
unsafe class HvExecutionContextShadow : IHvExecutionContext class HvExecutionContextShadow : IHvExecutionContext
{ {
public ulong Pc { get; set; } public ulong Pc { get; set; }
public ulong ElrEl1 { get; set; } public ulong ElrEl1 { get; set; }
@@ -56,4 +56,4 @@ namespace Ryujinx.Cpu.AppleHv
return false; return false;
} }
} }
} }

View File

@@ -8,10 +8,10 @@ namespace Ryujinx.Cpu.AppleHv
{ {
class HvExecutionContextVcpu : IHvExecutionContext class HvExecutionContextVcpu : IHvExecutionContext
{ {
private static MemoryBlock _setSimdFpRegFuncMem; private static readonly MemoryBlock _setSimdFpRegFuncMem;
private delegate hv_result_t SetSimdFpReg(ulong vcpu, hv_simd_fp_reg_t reg, in V128 value, IntPtr funcPtr); private delegate HvResult SetSimdFpReg(ulong vcpu, HvSimdFPReg reg, in V128 value, IntPtr funcPtr);
private static SetSimdFpReg _setSimdFpReg; private static readonly SetSimdFpReg _setSimdFpReg;
private static IntPtr _setSimdFpRegNativePtr; private static readonly IntPtr _setSimdFpRegNativePtr;
static HvExecutionContextVcpu() static HvExecutionContextVcpu()
{ {
@@ -34,12 +34,12 @@ namespace Ryujinx.Cpu.AppleHv
{ {
get get
{ {
HvApi.hv_vcpu_get_reg(_vcpu, hv_reg_t.HV_REG_PC, out ulong pc).ThrowOnError(); HvApi.hv_vcpu_get_reg(_vcpu, HvReg.PC, out ulong pc).ThrowOnError();
return pc; return pc;
} }
set set
{ {
HvApi.hv_vcpu_set_reg(_vcpu, hv_reg_t.HV_REG_PC, value).ThrowOnError(); HvApi.hv_vcpu_set_reg(_vcpu, HvReg.PC, value).ThrowOnError();
} }
} }
@@ -47,12 +47,12 @@ namespace Ryujinx.Cpu.AppleHv
{ {
get get
{ {
HvApi.hv_vcpu_get_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_ELR_EL1, out ulong elr).ThrowOnError(); HvApi.hv_vcpu_get_sys_reg(_vcpu, HvSysReg.ELR_EL1, out ulong elr).ThrowOnError();
return elr; return elr;
} }
set set
{ {
HvApi.hv_vcpu_set_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_ELR_EL1, value).ThrowOnError(); HvApi.hv_vcpu_set_sys_reg(_vcpu, HvSysReg.ELR_EL1, value).ThrowOnError();
} }
} }
@@ -60,12 +60,12 @@ namespace Ryujinx.Cpu.AppleHv
{ {
get get
{ {
HvApi.hv_vcpu_get_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_ESR_EL1, out ulong esr).ThrowOnError(); HvApi.hv_vcpu_get_sys_reg(_vcpu, HvSysReg.ESR_EL1, out ulong esr).ThrowOnError();
return esr; return esr;
} }
set set
{ {
HvApi.hv_vcpu_set_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_ESR_EL1, value).ThrowOnError(); HvApi.hv_vcpu_set_sys_reg(_vcpu, HvSysReg.ESR_EL1, value).ThrowOnError();
} }
} }
@@ -73,12 +73,12 @@ namespace Ryujinx.Cpu.AppleHv
{ {
get get
{ {
HvApi.hv_vcpu_get_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_TPIDR_EL0, out ulong tpidrEl0).ThrowOnError(); HvApi.hv_vcpu_get_sys_reg(_vcpu, HvSysReg.TPIDR_EL0, out ulong tpidrEl0).ThrowOnError();
return (long)tpidrEl0; return (long)tpidrEl0;
} }
set set
{ {
HvApi.hv_vcpu_set_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_TPIDR_EL0, (ulong)value).ThrowOnError(); HvApi.hv_vcpu_set_sys_reg(_vcpu, HvSysReg.TPIDR_EL0, (ulong)value).ThrowOnError();
} }
} }
@@ -86,12 +86,12 @@ namespace Ryujinx.Cpu.AppleHv
{ {
get get
{ {
HvApi.hv_vcpu_get_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_TPIDRRO_EL0, out ulong tpidrroEl0).ThrowOnError(); HvApi.hv_vcpu_get_sys_reg(_vcpu, HvSysReg.TPIDRRO_EL0, out ulong tpidrroEl0).ThrowOnError();
return (long)tpidrroEl0; return (long)tpidrroEl0;
} }
set set
{ {
HvApi.hv_vcpu_set_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_TPIDRRO_EL0, (ulong)value).ThrowOnError(); HvApi.hv_vcpu_set_sys_reg(_vcpu, HvSysReg.TPIDRRO_EL0, (ulong)value).ThrowOnError();
} }
} }
@@ -99,12 +99,12 @@ namespace Ryujinx.Cpu.AppleHv
{ {
get get
{ {
HvApi.hv_vcpu_get_reg(_vcpu, hv_reg_t.HV_REG_CPSR, out ulong cpsr).ThrowOnError(); HvApi.hv_vcpu_get_reg(_vcpu, HvReg.CPSR, out ulong cpsr).ThrowOnError();
return (uint)cpsr; return (uint)cpsr;
} }
set set
{ {
HvApi.hv_vcpu_set_reg(_vcpu, hv_reg_t.HV_REG_CPSR, (ulong)value).ThrowOnError(); HvApi.hv_vcpu_set_reg(_vcpu, HvReg.CPSR, (ulong)value).ThrowOnError();
} }
} }
@@ -112,12 +112,12 @@ namespace Ryujinx.Cpu.AppleHv
{ {
get get
{ {
HvApi.hv_vcpu_get_reg(_vcpu, hv_reg_t.HV_REG_FPCR, out ulong fpcr).ThrowOnError(); HvApi.hv_vcpu_get_reg(_vcpu, HvReg.FPCR, out ulong fpcr).ThrowOnError();
return (uint)fpcr; return (uint)fpcr;
} }
set set
{ {
HvApi.hv_vcpu_set_reg(_vcpu, hv_reg_t.HV_REG_FPCR, (ulong)value).ThrowOnError(); HvApi.hv_vcpu_set_reg(_vcpu, HvReg.FPCR, (ulong)value).ThrowOnError();
} }
} }
@@ -125,16 +125,16 @@ namespace Ryujinx.Cpu.AppleHv
{ {
get get
{ {
HvApi.hv_vcpu_get_reg(_vcpu, hv_reg_t.HV_REG_FPSR, out ulong fpsr).ThrowOnError(); HvApi.hv_vcpu_get_reg(_vcpu, HvReg.FPSR, out ulong fpsr).ThrowOnError();
return (uint)fpsr; return (uint)fpsr;
} }
set set
{ {
HvApi.hv_vcpu_set_reg(_vcpu, hv_reg_t.HV_REG_FPSR, (ulong)value).ThrowOnError(); HvApi.hv_vcpu_set_reg(_vcpu, HvReg.FPSR, (ulong)value).ThrowOnError();
} }
} }
private ulong _vcpu; private readonly ulong _vcpu;
private int _interruptRequested; private int _interruptRequested;
public HvExecutionContextVcpu(ulong vcpu) public HvExecutionContextVcpu(ulong vcpu)
@@ -146,12 +146,12 @@ namespace Ryujinx.Cpu.AppleHv
{ {
if (index == 31) if (index == 31)
{ {
HvApi.hv_vcpu_get_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_SP_EL0, out ulong value).ThrowOnError(); HvApi.hv_vcpu_get_sys_reg(_vcpu, HvSysReg.SP_EL0, out ulong value).ThrowOnError();
return value; return value;
} }
else else
{ {
HvApi.hv_vcpu_get_reg(_vcpu, hv_reg_t.HV_REG_X0 + (uint)index, out ulong value).ThrowOnError(); HvApi.hv_vcpu_get_reg(_vcpu, HvReg.X0 + (uint)index, out ulong value).ThrowOnError();
return value; return value;
} }
} }
@@ -160,23 +160,23 @@ namespace Ryujinx.Cpu.AppleHv
{ {
if (index == 31) if (index == 31)
{ {
HvApi.hv_vcpu_set_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_SP_EL0, value).ThrowOnError(); HvApi.hv_vcpu_set_sys_reg(_vcpu, HvSysReg.SP_EL0, value).ThrowOnError();
} }
else else
{ {
HvApi.hv_vcpu_set_reg(_vcpu, hv_reg_t.HV_REG_X0 + (uint)index, value).ThrowOnError(); HvApi.hv_vcpu_set_reg(_vcpu, HvReg.X0 + (uint)index, value).ThrowOnError();
} }
} }
public V128 GetV(int index) public V128 GetV(int index)
{ {
HvApi.hv_vcpu_get_simd_fp_reg(_vcpu, hv_simd_fp_reg_t.HV_SIMD_FP_REG_Q0 + (uint)index, out hv_simd_fp_uchar16_t value).ThrowOnError(); HvApi.hv_vcpu_get_simd_fp_reg(_vcpu, HvSimdFPReg.Q0 + (uint)index, out HvSimdFPUchar16 value).ThrowOnError();
return new V128(value.Low, value.High); return new V128(value.Low, value.High);
} }
public void SetV(int index, V128 value) public void SetV(int index, V128 value)
{ {
_setSimdFpReg(_vcpu, hv_simd_fp_reg_t.HV_SIMD_FP_REG_Q0 + (uint)index, value, _setSimdFpRegNativePtr).ThrowOnError(); _setSimdFpReg(_vcpu, HvSimdFPReg.Q0 + (uint)index, value, _setSimdFpRegNativePtr).ThrowOnError();
} }
public void RequestInterrupt() public void RequestInterrupt()
@@ -193,4 +193,4 @@ namespace Ryujinx.Cpu.AppleHv
return Interlocked.Exchange(ref _interruptRequested, 0) != 0; return Interlocked.Exchange(ref _interruptRequested, 0) != 0;
} }
} }
} }

View File

@@ -31,4 +31,4 @@ namespace Ryujinx.Cpu.AppleHv
_block.Free(offset, size); _block.Free(offset, size);
} }
} }
} }

View File

@@ -3,7 +3,7 @@ using System;
namespace Ryujinx.Cpu.AppleHv namespace Ryujinx.Cpu.AppleHv
{ {
struct HvMemoryBlockAllocation : IDisposable readonly struct HvMemoryBlockAllocation : IDisposable
{ {
private readonly HvMemoryBlockAllocator _owner; private readonly HvMemoryBlockAllocator _owner;
private readonly HvMemoryBlockAllocator.Block _block; private readonly HvMemoryBlockAllocator.Block _block;

View File

@@ -1,12 +1,9 @@
using Ryujinx.Memory; using Ryujinx.Memory;
using System.Collections.Generic;
namespace Ryujinx.Cpu.AppleHv namespace Ryujinx.Cpu.AppleHv
{ {
class HvMemoryBlockAllocator : PrivateMemoryAllocatorImpl<HvMemoryBlockAllocator.Block> class HvMemoryBlockAllocator : PrivateMemoryAllocatorImpl<HvMemoryBlockAllocator.Block>
{ {
private const ulong InvalidOffset = ulong.MaxValue;
public class Block : PrivateMemoryAllocator.Block public class Block : PrivateMemoryAllocator.Block
{ {
private readonly HvIpaAllocator _ipaAllocator; private readonly HvIpaAllocator _ipaAllocator;
@@ -21,7 +18,7 @@ namespace Ryujinx.Cpu.AppleHv
Ipa = ipaAllocator.Allocate(size); Ipa = ipaAllocator.Allocate(size);
} }
HvApi.hv_vm_map((ulong)Memory.Pointer, Ipa, size, hv_memory_flags_t.HV_MEMORY_READ | hv_memory_flags_t.HV_MEMORY_WRITE).ThrowOnError(); HvApi.hv_vm_map((ulong)Memory.Pointer, Ipa, size, HvMemoryFlags.Read | HvMemoryFlags.Write).ThrowOnError();
} }
public override void Destroy() public override void Destroy()
@@ -44,7 +41,7 @@ namespace Ryujinx.Cpu.AppleHv
_ipaAllocator = ipaAllocator; _ipaAllocator = ipaAllocator;
} }
public unsafe HvMemoryBlockAllocation Allocate(ulong size, ulong alignment) public HvMemoryBlockAllocation Allocate(ulong size, ulong alignment)
{ {
var allocation = Allocate(size, alignment, CreateBlock); var allocation = Allocate(size, alignment, CreateBlock);

View File

@@ -32,7 +32,7 @@ namespace Ryujinx.Cpu.AppleHv
MappedReplicated = 0x5555555555555555, MappedReplicated = 0x5555555555555555,
WriteTrackedReplicated = 0xaaaaaaaaaaaaaaaa, WriteTrackedReplicated = 0xaaaaaaaaaaaaaaaa,
ReadWriteTrackedReplicated = ulong.MaxValue ReadWriteTrackedReplicated = ulong.MaxValue,
} }
private readonly InvalidAccessHandler _invalidAccessHandler; private readonly InvalidAccessHandler _invalidAccessHandler;
@@ -126,6 +126,7 @@ namespace Ryujinx.Cpu.AppleHv
} }
} }
#pragma warning disable IDE0051 // Remove unused private member
/// <summary> /// <summary>
/// Ensures the combination of virtual address and size is part of the addressable space and fully mapped. /// Ensures the combination of virtual address and size is part of the addressable space and fully mapped.
/// </summary> /// </summary>
@@ -138,6 +139,7 @@ namespace Ryujinx.Cpu.AppleHv
throw new InvalidMemoryRegionException($"Not mapped: va=0x{va:X16}, size=0x{size:X16}"); throw new InvalidMemoryRegionException($"Not mapped: va=0x{va:X16}, size=0x{size:X16}");
} }
} }
#pragma warning restore IDE0051
/// <inheritdoc/> /// <inheritdoc/>
public void Map(ulong va, ulong pa, ulong size, MemoryMapFlags flags) public void Map(ulong va, ulong pa, ulong size, MemoryMapFlags flags)
@@ -306,7 +308,7 @@ namespace Ryujinx.Cpu.AppleHv
size = Math.Min(data.Length, PageSize - (int)(va & PageMask)); size = Math.Min(data.Length, PageSize - (int)(va & PageMask));
data.Slice(0, size).CopyTo(_backingMemory.GetSpan(pa, size)); data[..size].CopyTo(_backingMemory.GetSpan(pa, size));
offset += size; offset += size;
} }
@@ -428,7 +430,7 @@ namespace Ryujinx.Cpu.AppleHv
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private void GetPageBlockRange(ulong pageStart, ulong pageEnd, out ulong startMask, out ulong endMask, out int pageIndex, out int pageEndIndex) private static void GetPageBlockRange(ulong pageStart, ulong pageEnd, out ulong startMask, out ulong endMask, out int pageIndex, out int pageEndIndex)
{ {
startMask = ulong.MaxValue << ((int)(pageStart & 31) << 1); startMask = ulong.MaxValue << ((int)(pageStart & 31) << 1);
endMask = ulong.MaxValue >> (64 - ((int)(pageEnd & 31) << 1)); endMask = ulong.MaxValue >> (64 - ((int)(pageEnd & 31) << 1));
@@ -606,7 +608,7 @@ namespace Ryujinx.Cpu.AppleHv
size = Math.Min(data.Length, PageSize - (int)(va & PageMask)); size = Math.Min(data.Length, PageSize - (int)(va & PageMask));
_backingMemory.GetSpan(pa, size).CopyTo(data.Slice(0, size)); _backingMemory.GetSpan(pa, size).CopyTo(data[..size]);
offset += size; offset += size;
} }
@@ -723,7 +725,7 @@ namespace Ryujinx.Cpu.AppleHv
/// <param name="startVa">The virtual address of the beginning of the first page</param> /// <param name="startVa">The virtual address of the beginning of the first page</param>
/// <remarks>This function does not differentiate between allocated and unallocated pages.</remarks> /// <remarks>This function does not differentiate between allocated and unallocated pages.</remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private int GetPagesCount(ulong va, ulong size, out ulong startVa) private static int GetPagesCount(ulong va, ulong size, out ulong startVa)
{ {
// WARNING: Always check if ulong does not overflow during the operations. // WARNING: Always check if ulong does not overflow during the operations.
startVa = va & ~(ulong)PageMask; startVa = va & ~(ulong)PageMask;
@@ -814,7 +816,7 @@ namespace Ryujinx.Cpu.AppleHv
{ {
MemoryPermission.None => MemoryPermission.ReadAndWrite, MemoryPermission.None => MemoryPermission.ReadAndWrite,
MemoryPermission.Write => MemoryPermission.Read, MemoryPermission.Write => MemoryPermission.Read,
_ => MemoryPermission.None _ => MemoryPermission.None,
}; };
_addressSpace.ReprotectUser(va, size, protection); _addressSpace.ReprotectUser(va, size, protection);
@@ -943,4 +945,4 @@ namespace Ryujinx.Cpu.AppleHv
private static void ThrowInvalidMemoryRegionException(string message) => throw new InvalidMemoryRegionException(message); private static void ThrowInvalidMemoryRegionException(string message) => throw new InvalidMemoryRegionException(message);
} }
} }

View File

@@ -3,14 +3,14 @@ namespace Ryujinx.Cpu.AppleHv
unsafe class HvVcpu unsafe class HvVcpu
{ {
public readonly ulong Handle; public readonly ulong Handle;
public readonly hv_vcpu_exit_t* ExitInfo; public readonly HvVcpuExit* ExitInfo;
public readonly IHvExecutionContext ShadowContext; public readonly IHvExecutionContext ShadowContext;
public readonly IHvExecutionContext NativeContext; public readonly IHvExecutionContext NativeContext;
public readonly bool IsEphemeral; public readonly bool IsEphemeral;
public HvVcpu( public HvVcpu(
ulong handle, ulong handle,
hv_vcpu_exit_t* exitInfo, HvVcpuExit* exitInfo,
IHvExecutionContext shadowContext, IHvExecutionContext shadowContext,
IHvExecutionContext nativeContext, IHvExecutionContext nativeContext,
bool isEphemeral) bool isEphemeral)
@@ -22,4 +22,4 @@ namespace Ryujinx.Cpu.AppleHv
IsEphemeral = isEphemeral; IsEphemeral = isEphemeral;
} }
} }
} }

View File

@@ -17,10 +17,10 @@ namespace Ryujinx.Cpu.AppleHv
private const int MaxActiveVcpus = 4; private const int MaxActiveVcpus = 4;
public static readonly HvVcpuPool Instance = new HvVcpuPool(); public static readonly HvVcpuPool Instance = new();
private int _totalVcpus; private int _totalVcpus;
private int _maxVcpus; private readonly int _maxVcpus;
public HvVcpuPool() public HvVcpuPool()
{ {
@@ -69,17 +69,17 @@ namespace Ryujinx.Cpu.AppleHv
bool isEphemeral = newCount > _maxVcpus - MaxActiveVcpus; bool isEphemeral = newCount > _maxVcpus - MaxActiveVcpus;
// Create VCPU. // Create VCPU.
hv_vcpu_exit_t* exitInfo = null; HvVcpuExit* exitInfo = null;
HvApi.hv_vcpu_create(out ulong vcpuHandle, ref exitInfo, IntPtr.Zero).ThrowOnError(); HvApi.hv_vcpu_create(out ulong vcpuHandle, ref exitInfo, IntPtr.Zero).ThrowOnError();
// Enable FP and SIMD instructions. // Enable FP and SIMD instructions.
HvApi.hv_vcpu_set_sys_reg(vcpuHandle, hv_sys_reg_t.HV_SYS_REG_CPACR_EL1, 0b11 << 20).ThrowOnError(); HvApi.hv_vcpu_set_sys_reg(vcpuHandle, HvSysReg.CPACR_EL1, 0b11 << 20).ThrowOnError();
addressSpace.InitializeMmu(vcpuHandle); addressSpace.InitializeMmu(vcpuHandle);
HvExecutionContextVcpu nativeContext = new HvExecutionContextVcpu(vcpuHandle); HvExecutionContextVcpu nativeContext = new(vcpuHandle);
HvVcpu vcpu = new HvVcpu(vcpuHandle, exitInfo, shadowContext, nativeContext, isEphemeral); HvVcpu vcpu = new(vcpuHandle, exitInfo, shadowContext, nativeContext, isEphemeral);
return vcpu; return vcpu;
} }
@@ -100,4 +100,4 @@ namespace Ryujinx.Cpu.AppleHv
Interlocked.Decrement(ref _totalVcpus); Interlocked.Decrement(ref _totalVcpus);
} }
} }
} }

View File

@@ -10,7 +10,7 @@ namespace Ryujinx.Cpu.AppleHv
private static int _addressSpaces; private static int _addressSpaces;
private static HvIpaAllocator _ipaAllocator; private static HvIpaAllocator _ipaAllocator;
private static object _lock = new object(); private static readonly object _lock = new();
public static (ulong, HvIpaAllocator) CreateAddressSpace(MemoryBlock block) public static (ulong, HvIpaAllocator) CreateAddressSpace(MemoryBlock block)
{ {
@@ -36,7 +36,7 @@ namespace Ryujinx.Cpu.AppleHv
baseAddress = ipaAllocator.Allocate(block.Size, AsIpaAlignment); baseAddress = ipaAllocator.Allocate(block.Size, AsIpaAlignment);
} }
var rwx = hv_memory_flags_t.HV_MEMORY_READ | hv_memory_flags_t.HV_MEMORY_WRITE | hv_memory_flags_t.HV_MEMORY_EXEC; var rwx = HvMemoryFlags.Read | HvMemoryFlags.Write | HvMemoryFlags.Exec;
HvApi.hv_vm_map((ulong)block.Pointer, baseAddress, block.Size, rwx).ThrowOnError(); HvApi.hv_vm_map((ulong)block.Pointer, baseAddress, block.Size, rwx).ThrowOnError();
@@ -65,4 +65,4 @@ namespace Ryujinx.Cpu.AppleHv
} }
} }
} }
} }

View File

@@ -43,4 +43,4 @@ namespace Ryujinx.Cpu.AppleHv
void RequestInterrupt(); void RequestInterrupt();
bool GetAndClearInterruptRequested(); bool GetAndClearInterruptRequested();
} }
} }

View File

@@ -23,7 +23,7 @@ namespace Ryujinx.Cpu.Jit
PtcLoadingState.Start => LoadState.Unloaded, PtcLoadingState.Start => LoadState.Unloaded,
PtcLoadingState.Loading => LoadState.Loading, PtcLoadingState.Loading => LoadState.Loading,
PtcLoadingState.Loaded => LoadState.Loaded, PtcLoadingState.Loaded => LoadState.Loaded,
_ => throw new ArgumentException($"Invalid load state \"{newState}\".") _ => throw new ArgumentException($"Invalid load state \"{newState}\"."),
}; };
StateChanged?.Invoke(state, current, total); StateChanged?.Invoke(state, current, total);
@@ -35,4 +35,4 @@ namespace Ryujinx.Cpu.Jit
_loadState.Continue(); _loadState.Continue();
} }
} }
} }

View File

@@ -17,4 +17,4 @@ namespace Ryujinx.Cpu.Jit
return new JitCpuContext(_tickSource, memoryManager, for64Bit); return new JitCpuContext(_tickSource, memoryManager, for64Bit);
} }
} }
} }

View File

@@ -120,4 +120,4 @@ namespace Ryujinx.Cpu.Jit
_impl.Dispose(); _impl.Dispose();
} }
} }
} }

View File

@@ -19,6 +19,10 @@ namespace Ryujinx.Cpu.Jit
public void MapAsRx(ulong offset, ulong size) => _impl.Reprotect(offset, size, MemoryPermission.ReadAndExecute); public void MapAsRx(ulong offset, ulong size) => _impl.Reprotect(offset, size, MemoryPermission.ReadAndExecute);
public void MapAsRwx(ulong offset, ulong size) => _impl.Reprotect(offset, size, MemoryPermission.ReadWriteExecute); public void MapAsRwx(ulong offset, ulong size) => _impl.Reprotect(offset, size, MemoryPermission.ReadWriteExecute);
public void Dispose() => _impl.Dispose(); public void Dispose()
{
GC.SuppressFinalize(this);
_impl.Dispose();
}
} }
} }

View File

@@ -84,7 +84,6 @@ namespace Ryujinx.Cpu.Jit
ulong remainingSize = size; ulong remainingSize = size;
ulong oVa = va; ulong oVa = va;
ulong oPa = pa;
while (remainingSize != 0) while (remainingSize != 0)
{ {
_pageTable.Write((va / PageSize) * PteSize, PaToPte(pa)); _pageTable.Write((va / PageSize) * PteSize, PaToPte(pa));
@@ -246,7 +245,7 @@ namespace Ryujinx.Cpu.Jit
size = Math.Min(data.Length, PageSize - (int)(va & PageMask)); size = Math.Min(data.Length, PageSize - (int)(va & PageMask));
data.Slice(0, size).CopyTo(_backingMemory.GetSpan(pa, size)); data[..size].CopyTo(_backingMemory.GetSpan(pa, size));
offset += size; offset += size;
} }
@@ -298,7 +297,7 @@ namespace Ryujinx.Cpu.Jit
} }
/// <inheritdoc/> /// <inheritdoc/>
public unsafe WritableRegion GetWritableRegion(ulong va, int size, bool tracked = false) public WritableRegion GetWritableRegion(ulong va, int size, bool tracked = false)
{ {
if (size == 0) if (size == 0)
{ {
@@ -345,7 +344,7 @@ namespace Ryujinx.Cpu.Jit
/// <param name="startVa">The virtual address of the beginning of the first page</param> /// <param name="startVa">The virtual address of the beginning of the first page</param>
/// <remarks>This function does not differentiate between allocated and unallocated pages.</remarks> /// <remarks>This function does not differentiate between allocated and unallocated pages.</remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private int GetPagesCount(ulong va, uint size, out ulong startVa) private static int GetPagesCount(ulong va, uint size, out ulong startVa)
{ {
// WARNING: Always check if ulong does not overflow during the operations. // WARNING: Always check if ulong does not overflow during the operations.
startVa = va & ~(ulong)PageMask; startVa = va & ~(ulong)PageMask;
@@ -482,7 +481,7 @@ namespace Ryujinx.Cpu.Jit
size = Math.Min(data.Length, PageSize - (int)(va & PageMask)); size = Math.Min(data.Length, PageSize - (int)(va & PageMask));
_backingMemory.GetSpan(pa, size).CopyTo(data.Slice(0, size)); _backingMemory.GetSpan(pa, size).CopyTo(data[..size]);
offset += size; offset += size;
} }
@@ -576,6 +575,7 @@ namespace Ryujinx.Cpu.Jit
} }
} }
#pragma warning disable IDE0051 // Remove unused private member
private ulong GetPhysicalAddress(ulong va) private ulong GetPhysicalAddress(ulong va)
{ {
// We return -1L if the virtual address is invalid or unmapped. // We return -1L if the virtual address is invalid or unmapped.
@@ -586,6 +586,7 @@ namespace Ryujinx.Cpu.Jit
return GetPhysicalAddressInternal(va); return GetPhysicalAddressInternal(va);
} }
#pragma warning restore IDE0051
private ulong GetPhysicalAddressInternal(ulong va) private ulong GetPhysicalAddressInternal(ulong va)
{ {
@@ -604,7 +605,7 @@ namespace Ryujinx.Cpu.Jit
{ {
MemoryPermission.None => 0L, MemoryPermission.None => 0L,
MemoryPermission.Write => 2L << PointerTagBit, MemoryPermission.Write => 2L << PointerTagBit,
_ => 3L << PointerTagBit _ => 3L << PointerTagBit,
}; };
int pages = GetPagesCount(va, (uint)size, out va); int pages = GetPagesCount(va, (uint)size, out va);
@@ -698,6 +699,8 @@ namespace Ryujinx.Cpu.Jit
/// </summary> /// </summary>
protected override void Destroy() => _pageTable.Dispose(); protected override void Destroy() => _pageTable.Dispose();
private void ThrowInvalidMemoryRegionException(string message) => throw new InvalidMemoryRegionException(message); #pragma warning disable IDE0051 // Remove unused private member
private static void ThrowInvalidMemoryRegionException(string message) => throw new InvalidMemoryRegionException(message);
#pragma warning restore IDE0051
} }
} }

View File

@@ -31,7 +31,7 @@ namespace Ryujinx.Cpu.Jit
MappedReplicated = 0x5555555555555555, MappedReplicated = 0x5555555555555555,
WriteTrackedReplicated = 0xaaaaaaaaaaaaaaaa, WriteTrackedReplicated = 0xaaaaaaaaaaaaaaaa,
ReadWriteTrackedReplicated = ulong.MaxValue ReadWriteTrackedReplicated = ulong.MaxValue,
} }
private readonly InvalidAccessHandler _invalidAccessHandler; private readonly InvalidAccessHandler _invalidAccessHandler;
@@ -404,7 +404,7 @@ namespace Ryujinx.Cpu.Jit
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private void GetPageBlockRange(ulong pageStart, ulong pageEnd, out ulong startMask, out ulong endMask, out int pageIndex, out int pageEndIndex) private static void GetPageBlockRange(ulong pageStart, ulong pageEnd, out ulong startMask, out ulong endMask, out int pageIndex, out int pageEndIndex)
{ {
startMask = ulong.MaxValue << ((int)(pageStart & 31) << 1); startMask = ulong.MaxValue << ((int)(pageStart & 31) << 1);
endMask = ulong.MaxValue >> (64 - ((int)(pageEnd & 31) << 1)); endMask = ulong.MaxValue >> (64 - ((int)(pageEnd & 31) << 1));
@@ -606,7 +606,7 @@ namespace Ryujinx.Cpu.Jit
/// <param name="startVa">The virtual address of the beginning of the first page</param> /// <param name="startVa">The virtual address of the beginning of the first page</param>
/// <remarks>This function does not differentiate between allocated and unallocated pages.</remarks> /// <remarks>This function does not differentiate between allocated and unallocated pages.</remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private int GetPagesCount(ulong va, ulong size, out ulong startVa) private static int GetPagesCount(ulong va, ulong size, out ulong startVa)
{ {
// WARNING: Always check if ulong does not overflow during the operations. // WARNING: Always check if ulong does not overflow during the operations.
startVa = va & ~(ulong)PageMask; startVa = va & ~(ulong)PageMask;
@@ -697,7 +697,7 @@ namespace Ryujinx.Cpu.Jit
{ {
MemoryPermission.None => MemoryPermission.ReadAndWrite, MemoryPermission.None => MemoryPermission.ReadAndWrite,
MemoryPermission.Write => MemoryPermission.Read, MemoryPermission.Write => MemoryPermission.Read,
_ => MemoryPermission.None _ => MemoryPermission.None,
}; };
_addressSpace.Base.Reprotect(va, size, protection, false); _addressSpace.Base.Reprotect(va, size, protection, false);

View File

@@ -7,6 +7,6 @@ namespace Ryujinx.Cpu
{ {
Unloaded, Unloaded,
Loading, Loading,
Loaded Loaded,
} }
} }

View File

@@ -10,7 +10,6 @@ namespace Ryujinx.Cpu
{ {
private delegate bool TrackingEventDelegate(ulong address, ulong size, bool write); private delegate bool TrackingEventDelegate(ulong address, ulong size, bool write);
private readonly MemoryTracking _tracking;
private readonly TrackingEventDelegate _trackingEvent; private readonly TrackingEventDelegate _trackingEvent;
private readonly ulong _baseAddress; private readonly ulong _baseAddress;
@@ -18,12 +17,10 @@ namespace Ryujinx.Cpu
public MemoryEhMeilleure(MemoryBlock addressSpace, MemoryBlock addressSpaceMirror, MemoryTracking tracking) public MemoryEhMeilleure(MemoryBlock addressSpace, MemoryBlock addressSpaceMirror, MemoryTracking tracking)
{ {
_tracking = tracking;
_baseAddress = (ulong)addressSpace.Pointer; _baseAddress = (ulong)addressSpace.Pointer;
ulong endAddress = _baseAddress + addressSpace.Size; ulong endAddress = _baseAddress + addressSpace.Size;
_trackingEvent = new TrackingEventDelegate(tracking.VirtualMemoryEvent); _trackingEvent = tracking.VirtualMemoryEvent;
bool added = NativeSignalHandler.AddTrackedRegion((nuint)_baseAddress, (nuint)endAddress, Marshal.GetFunctionPointerForDelegate(_trackingEvent)); bool added = NativeSignalHandler.AddTrackedRegion((nuint)_baseAddress, (nuint)endAddress, Marshal.GetFunctionPointerForDelegate(_trackingEvent));
if (!added) if (!added)
@@ -51,6 +48,8 @@ namespace Ryujinx.Cpu
public void Dispose() public void Dispose()
{ {
GC.SuppressFinalize(this);
NativeSignalHandler.RemoveTrackedRegion((nuint)_baseAddress); NativeSignalHandler.RemoveTrackedRegion((nuint)_baseAddress);
if (_mirrorAddress != 0) if (_mirrorAddress != 0)

View File

@@ -2,7 +2,6 @@
using Ryujinx.Common.Memory; using Ryujinx.Common.Memory;
using Ryujinx.Memory; using Ryujinx.Memory;
using System; using System;
using System.IO;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
@@ -26,12 +25,12 @@ namespace Ryujinx.Cpu
} }
} }
public unsafe static T Read<T>(IVirtualMemoryManager memory, ulong position) where T : unmanaged public static T Read<T>(IVirtualMemoryManager memory, ulong position) where T : unmanaged
{ {
return MemoryMarshal.Cast<byte, T>(memory.GetSpan(position, Unsafe.SizeOf<T>()))[0]; return MemoryMarshal.Cast<byte, T>(memory.GetSpan(position, Unsafe.SizeOf<T>()))[0];
} }
public unsafe static ulong Write<T>(IVirtualMemoryManager memory, ulong position, T value) where T : unmanaged public static ulong Write<T>(IVirtualMemoryManager memory, ulong position, T value) where T : unmanaged
{ {
ReadOnlySpan<byte> data = MemoryMarshal.Cast<T, byte>(MemoryMarshal.CreateReadOnlySpan(ref value, 1)); ReadOnlySpan<byte> data = MemoryMarshal.Cast<T, byte>(MemoryMarshal.CreateReadOnlySpan(ref value, 1));
@@ -42,22 +41,21 @@ namespace Ryujinx.Cpu
public static string ReadAsciiString(IVirtualMemoryManager memory, ulong position, long maxSize = -1) public static string ReadAsciiString(IVirtualMemoryManager memory, ulong position, long maxSize = -1)
{ {
using (RecyclableMemoryStream ms = MemoryStreamManager.Shared.GetStream()) using RecyclableMemoryStream ms = MemoryStreamManager.Shared.GetStream();
for (long offs = 0; offs < maxSize || maxSize == -1; offs++)
{ {
for (long offs = 0; offs < maxSize || maxSize == -1; offs++) byte value = memory.Read<byte>(position + (ulong)offs);
if (value == 0)
{ {
byte value = memory.Read<byte>(position + (ulong)offs); break;
if (value == 0)
{
break;
}
ms.WriteByte(value);
} }
return Encoding.ASCII.GetString(ms.GetReadOnlySequence()); ms.WriteByte(value);
} }
return Encoding.ASCII.GetString(ms.GetReadOnlySequence());
} }
} }
} }

View File

@@ -3,7 +3,7 @@ using System;
namespace Ryujinx.Cpu namespace Ryujinx.Cpu
{ {
struct PrivateMemoryAllocation : IDisposable readonly struct PrivateMemoryAllocation : IDisposable
{ {
private readonly PrivateMemoryAllocator _owner; private readonly PrivateMemoryAllocator _owner;
private readonly PrivateMemoryAllocator.Block _block; private readonly PrivateMemoryAllocator.Block _block;
@@ -27,8 +27,8 @@ namespace Ryujinx.Cpu
public (PrivateMemoryAllocation, PrivateMemoryAllocation) Split(ulong splitOffset) public (PrivateMemoryAllocation, PrivateMemoryAllocation) Split(ulong splitOffset)
{ {
PrivateMemoryAllocation left = new PrivateMemoryAllocation(_owner, _block, Offset, splitOffset); PrivateMemoryAllocation left = new(_owner, _block, Offset, splitOffset);
PrivateMemoryAllocation right = new PrivateMemoryAllocation(_owner, _block, Offset + splitOffset, Size - splitOffset); PrivateMemoryAllocation right = new(_owner, _block, Offset + splitOffset, Size - splitOffset);
return (left, right); return (left, right);
} }

View File

@@ -15,7 +15,7 @@ namespace Ryujinx.Cpu
public MemoryBlock Memory { get; private set; } public MemoryBlock Memory { get; private set; }
public ulong Size { get; } public ulong Size { get; }
private struct Range : IComparable<Range> private readonly struct Range : IComparable<Range>
{ {
public ulong Offset { get; } public ulong Offset { get; }
public ulong Size { get; } public ulong Size { get; }
@@ -40,7 +40,7 @@ namespace Ryujinx.Cpu
Size = size; Size = size;
_freeRanges = new List<Range> _freeRanges = new List<Range>
{ {
new Range(0, size) new Range(0, size),
}; };
} }
@@ -164,7 +164,7 @@ namespace Ryujinx.Cpu
{ {
private const ulong InvalidOffset = ulong.MaxValue; private const ulong InvalidOffset = ulong.MaxValue;
public struct Allocation public readonly struct Allocation
{ {
public T Block { get; } public T Block { get; }
public ulong Offset { get; } public ulong Offset { get; }
@@ -265,4 +265,4 @@ namespace Ryujinx.Cpu
_blocks.Clear(); _blocks.Clear();
} }
} }
} }

View File

@@ -42,4 +42,4 @@ namespace Ryujinx.Cpu
_tickCounter.Start(); _tickCounter.Start();
} }
} }
} }

View File

@@ -9,6 +9,6 @@ namespace Ryujinx.Graphics.GAL
Clamp, Clamp,
MirrorClampToEdge, MirrorClampToEdge,
MirrorClampToBorder, MirrorClampToBorder,
MirrorClamp MirrorClamp,
} }
} }

View File

@@ -1,6 +1,6 @@
namespace Ryujinx.Graphics.GAL namespace Ryujinx.Graphics.GAL
{ {
public struct AdvancedBlendDescriptor public readonly struct AdvancedBlendDescriptor
{ {
public AdvancedBlendOp Op { get; } public AdvancedBlendOp Op { get; }
public AdvancedBlendOverlap Overlap { get; } public AdvancedBlendOverlap Overlap { get; }

View File

@@ -47,6 +47,6 @@ namespace Ryujinx.Graphics.GAL
HslHue, HslHue,
HslSaturation, HslSaturation,
HslColor, HslColor,
HslLuminosity HslLuminosity,
} }
} }

View File

@@ -4,6 +4,6 @@ namespace Ryujinx.Graphics.GAL
{ {
Uncorrelated, Uncorrelated,
Disjoint, Disjoint,
Conjoint Conjoint,
} }
} }

View File

@@ -7,6 +7,6 @@
SmaaLow, SmaaLow,
SmaaMedium, SmaaMedium,
SmaaHigh, SmaaHigh,
SmaaUltra SmaaUltra,
} }
} }

View File

@@ -4,30 +4,30 @@ namespace Ryujinx.Graphics.GAL
{ {
public bool Enable { get; } public bool Enable { get; }
public ColorF BlendConstant { get; } public ColorF BlendConstant { get; }
public BlendOp ColorOp { get; } public BlendOp ColorOp { get; }
public BlendFactor ColorSrcFactor { get; } public BlendFactor ColorSrcFactor { get; }
public BlendFactor ColorDstFactor { get; } public BlendFactor ColorDstFactor { get; }
public BlendOp AlphaOp { get; } public BlendOp AlphaOp { get; }
public BlendFactor AlphaSrcFactor { get; } public BlendFactor AlphaSrcFactor { get; }
public BlendFactor AlphaDstFactor { get; } public BlendFactor AlphaDstFactor { get; }
public BlendDescriptor( public BlendDescriptor(
bool enable, bool enable,
ColorF blendConstant, ColorF blendConstant,
BlendOp colorOp, BlendOp colorOp,
BlendFactor colorSrcFactor, BlendFactor colorSrcFactor,
BlendFactor colorDstFactor, BlendFactor colorDstFactor,
BlendOp alphaOp, BlendOp alphaOp,
BlendFactor alphaSrcFactor, BlendFactor alphaSrcFactor,
BlendFactor alphaDstFactor) BlendFactor alphaDstFactor)
{ {
Enable = enable; Enable = enable;
BlendConstant = blendConstant; BlendConstant = blendConstant;
ColorOp = colorOp; ColorOp = colorOp;
ColorSrcFactor = colorSrcFactor; ColorSrcFactor = colorSrcFactor;
ColorDstFactor = colorDstFactor; ColorDstFactor = colorDstFactor;
AlphaOp = alphaOp; AlphaOp = alphaOp;
AlphaSrcFactor = alphaSrcFactor; AlphaSrcFactor = alphaSrcFactor;
AlphaDstFactor = alphaDstFactor; AlphaDstFactor = alphaDstFactor;
} }

View File

@@ -22,21 +22,21 @@ namespace Ryujinx.Graphics.GAL
ConstantAlpha, ConstantAlpha,
OneMinusConstantAlpha, OneMinusConstantAlpha,
ZeroGl = 0x4000, ZeroGl = 0x4000,
OneGl = 0x4001, OneGl = 0x4001,
SrcColorGl = 0x4300, SrcColorGl = 0x4300,
OneMinusSrcColorGl = 0x4301, OneMinusSrcColorGl = 0x4301,
SrcAlphaGl = 0x4302, SrcAlphaGl = 0x4302,
OneMinusSrcAlphaGl = 0x4303, OneMinusSrcAlphaGl = 0x4303,
DstAlphaGl = 0x4304, DstAlphaGl = 0x4304,
OneMinusDstAlphaGl = 0x4305, OneMinusDstAlphaGl = 0x4305,
DstColorGl = 0x4306, DstColorGl = 0x4306,
OneMinusDstColorGl = 0x4307, OneMinusDstColorGl = 0x4307,
SrcAlphaSaturateGl = 0x4308, SrcAlphaSaturateGl = 0x4308,
Src1ColorGl = 0xc900, Src1ColorGl = 0xc900,
OneMinusSrc1ColorGl = 0xc901, OneMinusSrc1ColorGl = 0xc901,
Src1AlphaGl = 0xc902, Src1AlphaGl = 0xc902,
OneMinusSrc1AlphaGl = 0xc903 OneMinusSrc1AlphaGl = 0xc903,
} }
public static class BlendFactorExtensions public static class BlendFactorExtensions
@@ -54,9 +54,9 @@ namespace Ryujinx.Graphics.GAL
case BlendFactor.OneMinusSrc1Alpha: case BlendFactor.OneMinusSrc1Alpha:
case BlendFactor.OneMinusSrc1AlphaGl: case BlendFactor.OneMinusSrc1AlphaGl:
return true; return true;
default:
return false;
} }
return false;
} }
} }
} }

View File

@@ -8,10 +8,10 @@ namespace Ryujinx.Graphics.GAL
Minimum, Minimum,
Maximum, Maximum,
AddGl = 0x8006, AddGl = 0x8006,
MinimumGl = 0x8007, MinimumGl = 0x8007,
MaximumGl = 0x8008, MaximumGl = 0x8008,
SubtractGl = 0x800a, SubtractGl = 0x800a,
ReverseSubtractGl = 0x800b ReverseSubtractGl = 0x800b,
} }
} }

View File

@@ -3,6 +3,6 @@ namespace Ryujinx.Graphics.GAL
public enum BufferAccess public enum BufferAccess
{ {
Default, Default,
FlushPersistent FlushPersistent,
} }
} }

View File

@@ -11,4 +11,4 @@
Range = range; Range = range;
} }
} }
} }

View File

@@ -7,7 +7,7 @@ namespace Ryujinx.Graphics.GAL
{ {
private readonly ulong _value; private readonly ulong _value;
public static BufferHandle Null => new BufferHandle(0); public static BufferHandle Null => new(0);
private BufferHandle(ulong value) => _value = value; private BufferHandle(ulong value) => _value = value;
} }

View File

@@ -2,20 +2,20 @@ namespace Ryujinx.Graphics.GAL
{ {
public readonly struct BufferRange public readonly struct BufferRange
{ {
private static readonly BufferRange _empty = new BufferRange(BufferHandle.Null, 0, 0); private static readonly BufferRange _empty = new(BufferHandle.Null, 0, 0);
public static BufferRange Empty => _empty; public static BufferRange Empty => _empty;
public BufferHandle Handle { get; } public BufferHandle Handle { get; }
public int Offset { get; } public int Offset { get; }
public int Size { get; } public int Size { get; }
public BufferRange(BufferHandle handle, int offset, int size) public BufferRange(BufferHandle handle, int offset, int size)
{ {
Handle = handle; Handle = handle;
Offset = offset; Offset = offset;
Size = size; Size = size;
} }
} }
} }

View File

@@ -149,4 +149,4 @@ namespace Ryujinx.Graphics.GAL
GatherBiasPrecision = gatherBiasPrecision; GatherBiasPrecision = gatherBiasPrecision;
} }
} }
} }

View File

@@ -3,6 +3,6 @@ namespace Ryujinx.Graphics.GAL
public enum CompareMode public enum CompareMode
{ {
None, None,
CompareRToTexture CompareRToTexture,
} }
} }

View File

@@ -11,13 +11,13 @@ namespace Ryujinx.Graphics.GAL
GreaterOrEqual, GreaterOrEqual,
Always, Always,
NeverGl = 0x200, NeverGl = 0x200,
LessGl = 0x201, LessGl = 0x201,
EqualGl = 0x202, EqualGl = 0x202,
LessOrEqualGl = 0x203, LessOrEqualGl = 0x203,
GreaterGl = 0x204, GreaterGl = 0x204,
NotEqualGl = 0x205, NotEqualGl = 0x205,
GreaterOrEqualGl = 0x206, GreaterOrEqualGl = 0x206,
AlwaysGl = 0x207, AlwaysGl = 0x207,
} }
} }

View File

@@ -4,6 +4,6 @@ namespace Ryujinx.Graphics.GAL
{ {
SamplesPassed, SamplesPassed,
PrimitivesGenerated, PrimitivesGenerated,
TransformFeedbackPrimitivesWritten TransformFeedbackPrimitivesWritten,
} }
} }

View File

@@ -3,6 +3,6 @@ namespace Ryujinx.Graphics.GAL
public enum DepthMode public enum DepthMode
{ {
MinusOneToOne, MinusOneToOne,
ZeroToOne ZeroToOne,
} }
} }

View File

@@ -3,6 +3,6 @@ namespace Ryujinx.Graphics.GAL
public enum DepthStencilMode public enum DepthStencilMode
{ {
Depth, Depth,
Stencil Stencil,
} }
} }

View File

@@ -2,19 +2,19 @@ namespace Ryujinx.Graphics.GAL
{ {
public readonly struct DepthTestDescriptor public readonly struct DepthTestDescriptor
{ {
public bool TestEnable { get; } public bool TestEnable { get; }
public bool WriteEnable { get; } public bool WriteEnable { get; }
public CompareOp Func { get; } public CompareOp Func { get; }
public DepthTestDescriptor( public DepthTestDescriptor(
bool testEnable, bool testEnable,
bool writeEnable, bool writeEnable,
CompareOp func) CompareOp func)
{ {
TestEnable = testEnable; TestEnable = testEnable;
WriteEnable = writeEnable; WriteEnable = writeEnable;
Func = func; Func = func;
} }
} }
} }

View File

@@ -15,4 +15,4 @@ namespace Ryujinx.Graphics.GAL
IsDiscrete = isDiscrete; IsDiscrete = isDiscrete;
} }
} }
} }

View File

@@ -20,12 +20,12 @@ namespace Ryujinx.Graphics.GAL
public Extents2D Reduce(int level) public Extents2D Reduce(int level)
{ {
int div = 1 << level; int div = 1 << level;
return new Extents2D( return new Extents2D(
X1 >> level, X1 >> level,
Y1 >> level, Y1 >> level,
BitUtils.DivRoundUp(X2, div), BitUtils.DivRoundUp(X2, div),
BitUtils.DivRoundUp(Y2, div)); BitUtils.DivRoundUp(Y2, div));
} }
} }
} }

View File

@@ -15,4 +15,4 @@ namespace Ryujinx.Graphics.GAL
Y2 = y2; Y2 = y2;
} }
} }
} }

View File

@@ -2,8 +2,8 @@ namespace Ryujinx.Graphics.GAL
{ {
public enum Face public enum Face
{ {
Front = 0x404, Front = 0x404,
Back = 0x405, Back = 0x405,
FrontAndBack = 0x408 FrontAndBack = 0x408,
} }
} }

View File

@@ -146,7 +146,7 @@ namespace Ryujinx.Graphics.GAL
B5G5R5A1Unorm, B5G5R5A1Unorm,
A1B5G5R5Unorm, A1B5G5R5Unorm,
B8G8R8A8Unorm, B8G8R8A8Unorm,
B8G8R8A8Srgb B8G8R8A8Srgb,
} }
public static class FormatExtensions public static class FormatExtensions
@@ -665,4 +665,4 @@ namespace Ryujinx.Graphics.GAL
return format.IsUint() || format.IsSint(); return format.IsUint() || format.IsSint();
} }
} }
} }

View File

@@ -2,7 +2,7 @@ namespace Ryujinx.Graphics.GAL
{ {
public enum FrontFace public enum FrontFace
{ {
Clockwise = 0x900, Clockwise = 0x900,
CounterClockwise = 0x901 CounterClockwise = 0x901,
} }
} }

View File

@@ -3,4 +3,4 @@ using System;
namespace Ryujinx.Graphics.GAL namespace Ryujinx.Graphics.GAL
{ {
public interface ISampler : IDisposable { } public interface ISampler : IDisposable { }
} }

View File

@@ -1,5 +1,4 @@
using Ryujinx.Common.Memory; using Ryujinx.Common.Memory;
using System;
namespace Ryujinx.Graphics.GAL namespace Ryujinx.Graphics.GAL
{ {
@@ -25,4 +24,4 @@ namespace Ryujinx.Graphics.GAL
void SetStorage(BufferRange buffer); void SetStorage(BufferRange buffer);
void Release(); void Release();
} }
} }

View File

@@ -2,36 +2,36 @@ namespace Ryujinx.Graphics.GAL
{ {
public readonly struct ImageCrop public readonly struct ImageCrop
{ {
public int Left { get; } public int Left { get; }
public int Right { get; } public int Right { get; }
public int Top { get; } public int Top { get; }
public int Bottom { get; } public int Bottom { get; }
public bool FlipX { get; } public bool FlipX { get; }
public bool FlipY { get; } public bool FlipY { get; }
public bool IsStretched { get; } public bool IsStretched { get; }
public float AspectRatioX { get; } public float AspectRatioX { get; }
public float AspectRatioY { get; } public float AspectRatioY { get; }
public ImageCrop( public ImageCrop(
int left, int left,
int right, int right,
int top, int top,
int bottom, int bottom,
bool flipX, bool flipX,
bool flipY, bool flipY,
bool isStretched, bool isStretched,
float aspectRatioX, float aspectRatioX,
float aspectRatioY) float aspectRatioY)
{ {
Left = left; Left = left;
Right = right; Right = right;
Top = top; Top = top;
Bottom = bottom; Bottom = bottom;
FlipX = flipX; FlipX = flipX;
FlipY = flipY; FlipY = flipY;
IsStretched = isStretched; IsStretched = isStretched;
AspectRatioX = aspectRatioX; AspectRatioX = aspectRatioX;
AspectRatioY = aspectRatioY; AspectRatioY = aspectRatioY;
} }
} }
} }

View File

@@ -4,6 +4,6 @@ namespace Ryujinx.Graphics.GAL
{ {
UByte, UByte,
UShort, UShort,
UInt UInt,
} }
} }

View File

@@ -17,6 +17,6 @@
CopyInverted = 0x150C, CopyInverted = 0x150C,
OrInverted = 0x150D, OrInverted = 0x150D,
Nand = 0x150E, Nand = 0x150E,
Set = 0x150F Set = 0x150F,
} }
} }

View File

@@ -3,6 +3,6 @@ namespace Ryujinx.Graphics.GAL
public enum MagFilter public enum MagFilter
{ {
Nearest = 1, Nearest = 1,
Linear Linear,
} }
} }

View File

@@ -7,6 +7,6 @@ namespace Ryujinx.Graphics.GAL
NearestMipmapNearest, NearestMipmapNearest,
LinearMipmapNearest, LinearMipmapNearest,
NearestMipmapLinear, NearestMipmapLinear,
LinearMipmapLinear LinearMipmapLinear,
} }
} }

View File

@@ -15,9 +15,9 @@ namespace Ryujinx.Graphics.GAL.Multithreading
{ {
private ulong _bufferHandle = 0; private ulong _bufferHandle = 0;
private Dictionary<BufferHandle, BufferHandle> _bufferMap = new Dictionary<BufferHandle, BufferHandle>(); private readonly Dictionary<BufferHandle, BufferHandle> _bufferMap = new();
private HashSet<BufferHandle> _inFlight = new HashSet<BufferHandle>(); private readonly HashSet<BufferHandle> _inFlight = new();
private AutoResetEvent _inFlightChanged = new AutoResetEvent(false); private readonly AutoResetEvent _inFlightChanged = new(false);
internal BufferHandle CreateBufferHandle() internal BufferHandle CreateBufferHandle()
{ {
@@ -59,14 +59,12 @@ namespace Ryujinx.Graphics.GAL.Multithreading
internal BufferHandle MapBuffer(BufferHandle handle) internal BufferHandle MapBuffer(BufferHandle handle)
{ {
// Maps a threaded buffer to a backend one. // Maps a threaded buffer to a backend one.
// Threaded buffers are returned on creation as the buffer // Threaded buffers are returned on creation as the buffer
// isn't actually created until the queue runs the command. // isn't actually created until the queue runs the command.
BufferHandle result;
lock (_bufferMap) lock (_bufferMap)
{ {
if (!_bufferMap.TryGetValue(handle, out result)) if (!_bufferMap.TryGetValue(handle, out BufferHandle result))
{ {
result = BufferHandle.Null; result = BufferHandle.Null;
} }
@@ -79,11 +77,10 @@ namespace Ryujinx.Graphics.GAL.Multithreading
{ {
// Blocks until the handle is available. // Blocks until the handle is available.
BufferHandle result;
lock (_bufferMap) lock (_bufferMap)
{ {
if (_bufferMap.TryGetValue(handle, out result)) if (_bufferMap.TryGetValue(handle, out BufferHandle result))
{ {
return result; return result;
} }
@@ -128,9 +125,8 @@ namespace Ryujinx.Graphics.GAL.Multithreading
for (int i = 0; i < ranges.Length; i++) for (int i = 0; i < ranges.Length; i++)
{ {
ref BufferRange range = ref ranges[i]; ref BufferRange range = ref ranges[i];
BufferHandle result;
if (!_bufferMap.TryGetValue(range.Handle, out result)) if (!_bufferMap.TryGetValue(range.Handle, out BufferHandle result))
{ {
result = BufferHandle.Null; result = BufferHandle.Null;
} }
@@ -152,9 +148,8 @@ namespace Ryujinx.Graphics.GAL.Multithreading
{ {
ref BufferAssignment assignment = ref ranges[i]; ref BufferAssignment assignment = ref ranges[i];
BufferRange range = assignment.Range; BufferRange range = assignment.Range;
BufferHandle result;
if (!_bufferMap.TryGetValue(range.Handle, out result)) if (!_bufferMap.TryGetValue(range.Handle, out BufferHandle result))
{ {
result = BufferHandle.Null; result = BufferHandle.Null;
} }
@@ -175,9 +170,8 @@ namespace Ryujinx.Graphics.GAL.Multithreading
for (int i = 0; i < ranges.Length; i++) for (int i = 0; i < ranges.Length; i++)
{ {
BufferRange range = ranges[i].Buffer; BufferRange range = ranges[i].Buffer;
BufferHandle result;
if (!_bufferMap.TryGetValue(range.Handle, out result)) if (!_bufferMap.TryGetValue(range.Handle, out BufferHandle result))
{ {
result = BufferHandle.Null; result = BufferHandle.Null;
} }

View File

@@ -17,8 +17,8 @@ namespace Ryujinx.Graphics.GAL.Multithreading
{ {
private delegate void CommandDelegate(Span<byte> memory, ThreadedRenderer threaded, IRenderer renderer); private delegate void CommandDelegate(Span<byte> memory, ThreadedRenderer threaded, IRenderer renderer);
private static int _totalCommands = (int)Enum.GetValues<CommandType>().Max() + 1; private static readonly int _totalCommands = (int)Enum.GetValues<CommandType>().Max() + 1;
private static CommandDelegate[] _lookup = new CommandDelegate[_totalCommands]; private static readonly CommandDelegate[] _lookup = new CommandDelegate[_totalCommands];
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private static ref T GetCommand<T>(Span<byte> memory) private static ref T GetCommand<T>(Span<byte> memory)
@@ -146,7 +146,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void RunCommand(Span<byte> memory, ThreadedRenderer threaded, IRenderer renderer) public static void RunCommand(Span<byte> memory, ThreadedRenderer threaded, IRenderer renderer)
{ {
_lookup[memory[memory.Length - 1]](memory, threaded, renderer); _lookup[memory[^1]](memory, threaded, renderer);
} }
} }
} }

View File

@@ -100,6 +100,6 @@
TextureBarrierTiled, TextureBarrierTiled,
TryHostConditionalRendering, TryHostConditionalRendering,
TryHostConditionalRenderingFlush, TryHostConditionalRenderingFlush,
UpdateRenderScale UpdateRenderScale,
} }
} }

View File

@@ -2,7 +2,7 @@
{ {
struct BarrierCommand : IGALCommand, IGALCommand<BarrierCommand> struct BarrierCommand : IGALCommand, IGALCommand<BarrierCommand>
{ {
public CommandType CommandType => CommandType.Barrier; public readonly CommandType CommandType => CommandType.Barrier;
public static void Run(ref BarrierCommand command, ThreadedRenderer threaded, IRenderer renderer) public static void Run(ref BarrierCommand command, ThreadedRenderer threaded, IRenderer renderer)
{ {

View File

@@ -2,7 +2,7 @@
{ {
struct BeginTransformFeedbackCommand : IGALCommand, IGALCommand<BeginTransformFeedbackCommand> struct BeginTransformFeedbackCommand : IGALCommand, IGALCommand<BeginTransformFeedbackCommand>
{ {
public CommandType CommandType => CommandType.BeginTransformFeedback; public readonly CommandType CommandType => CommandType.BeginTransformFeedback;
private PrimitiveTopology _topology; private PrimitiveTopology _topology;
public void Set(PrimitiveTopology topology) public void Set(PrimitiveTopology topology)

View File

@@ -2,7 +2,7 @@
{ {
struct BufferDisposeCommand : IGALCommand, IGALCommand<BufferDisposeCommand> struct BufferDisposeCommand : IGALCommand, IGALCommand<BufferDisposeCommand>
{ {
public CommandType CommandType => CommandType.BufferDispose; public readonly CommandType CommandType => CommandType.BufferDispose;
private BufferHandle _buffer; private BufferHandle _buffer;
public void Set(BufferHandle buffer) public void Set(BufferHandle buffer)

View File

@@ -1,11 +1,10 @@
using Ryujinx.Graphics.GAL.Multithreading.Model; using Ryujinx.Graphics.GAL.Multithreading.Model;
using System;
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Buffer namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Buffer
{ {
struct BufferGetDataCommand : IGALCommand, IGALCommand<BufferGetDataCommand> struct BufferGetDataCommand : IGALCommand, IGALCommand<BufferGetDataCommand>
{ {
public CommandType CommandType => CommandType.BufferGetData; public readonly CommandType CommandType => CommandType.BufferGetData;
private BufferHandle _buffer; private BufferHandle _buffer;
private int _offset; private int _offset;
private int _size; private int _size;

View File

@@ -5,7 +5,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Buffer
{ {
struct BufferSetDataCommand : IGALCommand, IGALCommand<BufferSetDataCommand> struct BufferSetDataCommand : IGALCommand, IGALCommand<BufferSetDataCommand>
{ {
public CommandType CommandType => CommandType.BufferSetData; public readonly CommandType CommandType => CommandType.BufferSetData;
private BufferHandle _buffer; private BufferHandle _buffer;
private int _offset; private int _offset;
private SpanRef<byte> _data; private SpanRef<byte> _data;

View File

@@ -2,7 +2,7 @@
{ {
struct ClearBufferCommand : IGALCommand, IGALCommand<ClearBufferCommand> struct ClearBufferCommand : IGALCommand, IGALCommand<ClearBufferCommand>
{ {
public CommandType CommandType => CommandType.ClearBuffer; public readonly CommandType CommandType => CommandType.ClearBuffer;
private BufferHandle _destination; private BufferHandle _destination;
private int _offset; private int _offset;
private int _size; private int _size;

View File

@@ -2,7 +2,7 @@
{ {
struct ClearRenderTargetColorCommand : IGALCommand, IGALCommand<ClearRenderTargetColorCommand> struct ClearRenderTargetColorCommand : IGALCommand, IGALCommand<ClearRenderTargetColorCommand>
{ {
public CommandType CommandType => CommandType.ClearRenderTargetColor; public readonly CommandType CommandType => CommandType.ClearRenderTargetColor;
private int _index; private int _index;
private int _layer; private int _layer;
private int _layerCount; private int _layerCount;

View File

@@ -2,7 +2,7 @@
{ {
struct ClearRenderTargetDepthStencilCommand : IGALCommand, IGALCommand<ClearRenderTargetDepthStencilCommand> struct ClearRenderTargetDepthStencilCommand : IGALCommand, IGALCommand<ClearRenderTargetDepthStencilCommand>
{ {
public CommandType CommandType => CommandType.ClearRenderTargetDepthStencil; public readonly CommandType CommandType => CommandType.ClearRenderTargetDepthStencil;
private int _layer; private int _layer;
private int _layerCount; private int _layerCount;
private float _depthValue; private float _depthValue;

View File

@@ -2,7 +2,7 @@
{ {
struct CommandBufferBarrierCommand : IGALCommand, IGALCommand<CommandBufferBarrierCommand> struct CommandBufferBarrierCommand : IGALCommand, IGALCommand<CommandBufferBarrierCommand>
{ {
public CommandType CommandType => CommandType.CommandBufferBarrier; public readonly CommandType CommandType => CommandType.CommandBufferBarrier;
public static void Run(ref CommandBufferBarrierCommand command, ThreadedRenderer threaded, IRenderer renderer) public static void Run(ref CommandBufferBarrierCommand command, ThreadedRenderer threaded, IRenderer renderer)
{ {

View File

@@ -2,7 +2,7 @@
{ {
struct CopyBufferCommand : IGALCommand, IGALCommand<CopyBufferCommand> struct CopyBufferCommand : IGALCommand, IGALCommand<CopyBufferCommand>
{ {
public CommandType CommandType => CommandType.CopyBuffer; public readonly CommandType CommandType => CommandType.CopyBuffer;
private BufferHandle _source; private BufferHandle _source;
private BufferHandle _destination; private BufferHandle _destination;
private int _srcOffset; private int _srcOffset;

View File

@@ -5,7 +5,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands.CounterEvent
{ {
struct CounterEventDisposeCommand : IGALCommand, IGALCommand<CounterEventDisposeCommand> struct CounterEventDisposeCommand : IGALCommand, IGALCommand<CounterEventDisposeCommand>
{ {
public CommandType CommandType => CommandType.CounterEventDispose; public readonly CommandType CommandType => CommandType.CounterEventDispose;
private TableRef<ThreadedCounterEvent> _event; private TableRef<ThreadedCounterEvent> _event;
public void Set(TableRef<ThreadedCounterEvent> evt) public void Set(TableRef<ThreadedCounterEvent> evt)

View File

@@ -5,7 +5,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands.CounterEvent
{ {
struct CounterEventFlushCommand : IGALCommand, IGALCommand<CounterEventFlushCommand> struct CounterEventFlushCommand : IGALCommand, IGALCommand<CounterEventFlushCommand>
{ {
public CommandType CommandType => CommandType.CounterEventFlush; public readonly CommandType CommandType => CommandType.CounterEventFlush;
private TableRef<ThreadedCounterEvent> _event; private TableRef<ThreadedCounterEvent> _event;
public void Set(TableRef<ThreadedCounterEvent> evt) public void Set(TableRef<ThreadedCounterEvent> evt)

View File

@@ -2,7 +2,7 @@
{ {
struct DispatchComputeCommand : IGALCommand, IGALCommand<DispatchComputeCommand> struct DispatchComputeCommand : IGALCommand, IGALCommand<DispatchComputeCommand>
{ {
public CommandType CommandType => CommandType.DispatchCompute; public readonly CommandType CommandType => CommandType.DispatchCompute;
private int _groupsX; private int _groupsX;
private int _groupsY; private int _groupsY;
private int _groupsZ; private int _groupsZ;

View File

@@ -2,7 +2,7 @@
{ {
struct DrawIndexedCommand : IGALCommand, IGALCommand<DrawIndexedCommand> struct DrawIndexedCommand : IGALCommand, IGALCommand<DrawIndexedCommand>
{ {
public CommandType CommandType => CommandType.DrawIndexed; public readonly CommandType CommandType => CommandType.DrawIndexed;
private int _indexCount; private int _indexCount;
private int _instanceCount; private int _instanceCount;
private int _firstIndex; private int _firstIndex;

View File

@@ -2,7 +2,7 @@
{ {
struct DrawCommand : IGALCommand, IGALCommand<DrawCommand> struct DrawCommand : IGALCommand, IGALCommand<DrawCommand>
{ {
public CommandType CommandType => CommandType.Draw; public readonly CommandType CommandType => CommandType.Draw;
private int _vertexCount; private int _vertexCount;
private int _instanceCount; private int _instanceCount;
private int _firstVertex; private int _firstVertex;

View File

@@ -2,7 +2,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands
{ {
struct DrawIndexedIndirectCommand : IGALCommand, IGALCommand<DrawIndexedIndirectCommand> struct DrawIndexedIndirectCommand : IGALCommand, IGALCommand<DrawIndexedIndirectCommand>
{ {
public CommandType CommandType => CommandType.DrawIndexedIndirect; public readonly CommandType CommandType => CommandType.DrawIndexedIndirect;
private BufferRange _indirectBuffer; private BufferRange _indirectBuffer;
public void Set(BufferRange indirectBuffer) public void Set(BufferRange indirectBuffer)

View File

@@ -2,7 +2,7 @@
{ {
struct DrawIndexedIndirectCountCommand : IGALCommand, IGALCommand<DrawIndexedIndirectCountCommand> struct DrawIndexedIndirectCountCommand : IGALCommand, IGALCommand<DrawIndexedIndirectCountCommand>
{ {
public CommandType CommandType => CommandType.DrawIndexedIndirectCount; public readonly CommandType CommandType => CommandType.DrawIndexedIndirectCount;
private BufferRange _indirectBuffer; private BufferRange _indirectBuffer;
private BufferRange _parameterBuffer; private BufferRange _parameterBuffer;
private int _maxDrawCount; private int _maxDrawCount;

View File

@@ -2,7 +2,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands
{ {
struct DrawIndirectCommand : IGALCommand, IGALCommand<DrawIndirectCommand> struct DrawIndirectCommand : IGALCommand, IGALCommand<DrawIndirectCommand>
{ {
public CommandType CommandType => CommandType.DrawIndirect; public readonly CommandType CommandType => CommandType.DrawIndirect;
private BufferRange _indirectBuffer; private BufferRange _indirectBuffer;
public void Set(BufferRange indirectBuffer) public void Set(BufferRange indirectBuffer)

View File

@@ -2,7 +2,7 @@
{ {
struct DrawIndirectCountCommand : IGALCommand, IGALCommand<DrawIndirectCountCommand> struct DrawIndirectCountCommand : IGALCommand, IGALCommand<DrawIndirectCountCommand>
{ {
public CommandType CommandType => CommandType.DrawIndirectCount; public readonly CommandType CommandType => CommandType.DrawIndirectCount;
private BufferRange _indirectBuffer; private BufferRange _indirectBuffer;
private BufferRange _parameterBuffer; private BufferRange _parameterBuffer;
private int _maxDrawCount; private int _maxDrawCount;

View File

@@ -5,7 +5,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands
{ {
struct DrawTextureCommand : IGALCommand, IGALCommand<DrawTextureCommand> struct DrawTextureCommand : IGALCommand, IGALCommand<DrawTextureCommand>
{ {
public CommandType CommandType => CommandType.DrawTexture; public readonly CommandType CommandType => CommandType.DrawTexture;
private TableRef<ITexture> _texture; private TableRef<ITexture> _texture;
private TableRef<ISampler> _sampler; private TableRef<ISampler> _sampler;
private Extents2DF _srcRegion; private Extents2DF _srcRegion;

View File

@@ -2,7 +2,7 @@
{ {
struct EndHostConditionalRenderingCommand : IGALCommand, IGALCommand<EndHostConditionalRenderingCommand> struct EndHostConditionalRenderingCommand : IGALCommand, IGALCommand<EndHostConditionalRenderingCommand>
{ {
public CommandType CommandType => CommandType.EndHostConditionalRendering; public readonly CommandType CommandType => CommandType.EndHostConditionalRendering;
public static void Run(ref EndHostConditionalRenderingCommand command, ThreadedRenderer threaded, IRenderer renderer) public static void Run(ref EndHostConditionalRenderingCommand command, ThreadedRenderer threaded, IRenderer renderer)
{ {

View File

@@ -2,7 +2,7 @@
{ {
struct EndTransformFeedbackCommand : IGALCommand, IGALCommand<EndTransformFeedbackCommand> struct EndTransformFeedbackCommand : IGALCommand, IGALCommand<EndTransformFeedbackCommand>
{ {
public CommandType CommandType => CommandType.EndTransformFeedback; public readonly CommandType CommandType => CommandType.EndTransformFeedback;
public static void Run(ref EndTransformFeedbackCommand command, ThreadedRenderer threaded, IRenderer renderer) public static void Run(ref EndTransformFeedbackCommand command, ThreadedRenderer threaded, IRenderer renderer)
{ {

View File

@@ -5,7 +5,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Program
{ {
struct ProgramCheckLinkCommand : IGALCommand, IGALCommand<ProgramCheckLinkCommand> struct ProgramCheckLinkCommand : IGALCommand, IGALCommand<ProgramCheckLinkCommand>
{ {
public CommandType CommandType => CommandType.ProgramCheckLink; public readonly CommandType CommandType => CommandType.ProgramCheckLink;
private TableRef<ThreadedProgram> _program; private TableRef<ThreadedProgram> _program;
private bool _blocking; private bool _blocking;
private TableRef<ResultBox<ProgramLinkStatus>> _result; private TableRef<ResultBox<ProgramLinkStatus>> _result;

View File

@@ -5,7 +5,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Program
{ {
struct ProgramDisposeCommand : IGALCommand, IGALCommand<ProgramDisposeCommand> struct ProgramDisposeCommand : IGALCommand, IGALCommand<ProgramDisposeCommand>
{ {
public CommandType CommandType => CommandType.ProgramDispose; public readonly CommandType CommandType => CommandType.ProgramDispose;
private TableRef<ThreadedProgram> _program; private TableRef<ThreadedProgram> _program;
public void Set(TableRef<ThreadedProgram> program) public void Set(TableRef<ThreadedProgram> program)

View File

@@ -5,7 +5,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Program
{ {
struct ProgramGetBinaryCommand : IGALCommand, IGALCommand<ProgramGetBinaryCommand> struct ProgramGetBinaryCommand : IGALCommand, IGALCommand<ProgramGetBinaryCommand>
{ {
public CommandType CommandType => CommandType.ProgramGetBinary; public readonly CommandType CommandType => CommandType.ProgramGetBinary;
private TableRef<ThreadedProgram> _program; private TableRef<ThreadedProgram> _program;
private TableRef<ResultBox<byte[]>> _result; private TableRef<ResultBox<byte[]>> _result;

View File

@@ -5,7 +5,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer
{ {
struct ActionCommand : IGALCommand, IGALCommand<ActionCommand> struct ActionCommand : IGALCommand, IGALCommand<ActionCommand>
{ {
public CommandType CommandType => CommandType.Action; public readonly CommandType CommandType => CommandType.Action;
private TableRef<Action> _action; private TableRef<Action> _action;
public void Set(TableRef<Action> action) public void Set(TableRef<Action> action)

View File

@@ -2,7 +2,7 @@
{ {
struct CreateBufferAccessCommand : IGALCommand, IGALCommand<CreateBufferAccessCommand> struct CreateBufferAccessCommand : IGALCommand, IGALCommand<CreateBufferAccessCommand>
{ {
public CommandType CommandType => CommandType.CreateBufferAccess; public readonly CommandType CommandType => CommandType.CreateBufferAccess;
private BufferHandle _threadedHandle; private BufferHandle _threadedHandle;
private int _size; private int _size;
private BufferAccess _access; private BufferAccess _access;

View File

@@ -2,7 +2,7 @@
{ {
struct CreateBufferCommand : IGALCommand, IGALCommand<CreateBufferCommand> struct CreateBufferCommand : IGALCommand, IGALCommand<CreateBufferCommand>
{ {
public CommandType CommandType => CommandType.CreateBuffer; public readonly CommandType CommandType => CommandType.CreateBuffer;
private BufferHandle _threadedHandle; private BufferHandle _threadedHandle;
private int _size; private int _size;
private BufferHandle _storageHint; private BufferHandle _storageHint;

Some files were not shown because too many files have changed in this diff Show More