Compare commits
11 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
0684b00b3c | ||
|
02b5c7ea89 | ||
|
801b71a128 | ||
|
12c5f6ee89 | ||
|
79a1314ee4 | ||
|
e9848339dd | ||
|
6e28a4dd13 | ||
|
7c989f88bd | ||
|
16fa983704 | ||
|
40daca5684 | ||
|
981e0c082d |
@@ -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"
|
@@ -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
|
@@ -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;
|
||||||
});
|
});
|
||||||
|
@@ -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;
|
||||||
});
|
});
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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");
|
||||||
|
@@ -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,6 +489,8 @@ namespace Ryujinx.Cpu
|
|||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
|
||||||
_privateMemoryAllocator?.Dispose();
|
_privateMemoryAllocator?.Dispose();
|
||||||
Base.Dispose();
|
Base.Dispose();
|
||||||
Mirror.Dispose();
|
Mirror.Dispose();
|
||||||
|
@@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -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
|
||||||
|
@@ -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."),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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();
|
||||||
|
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -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)
|
||||||
{
|
{
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
@@ -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; }
|
||||||
|
@@ -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()
|
||||||
|
@@ -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;
|
||||||
|
@@ -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);
|
||||||
|
|
||||||
|
@@ -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);
|
||||||
|
@@ -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)
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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();
|
||||||
|
|
||||||
|
@@ -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);
|
||||||
|
@@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
||||||
|
@@ -7,6 +7,6 @@ namespace Ryujinx.Cpu
|
|||||||
{
|
{
|
||||||
Unloaded,
|
Unloaded,
|
||||||
Loading,
|
Loading,
|
||||||
Loaded
|
Loaded,
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -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)
|
||||||
|
@@ -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,8 +41,8 @@ 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);
|
byte value = memory.Read<byte>(position + (ulong)offs);
|
||||||
@@ -60,4 +59,3 @@ namespace Ryujinx.Cpu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
@@ -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);
|
||||||
}
|
}
|
||||||
|
@@ -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; }
|
||||||
|
@@ -9,6 +9,6 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
Clamp,
|
Clamp,
|
||||||
MirrorClampToEdge,
|
MirrorClampToEdge,
|
||||||
MirrorClampToBorder,
|
MirrorClampToBorder,
|
||||||
MirrorClamp
|
MirrorClamp,
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -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; }
|
||||||
|
@@ -47,6 +47,6 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
HslHue,
|
HslHue,
|
||||||
HslSaturation,
|
HslSaturation,
|
||||||
HslColor,
|
HslColor,
|
||||||
HslLuminosity
|
HslLuminosity,
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -4,6 +4,6 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
{
|
{
|
||||||
Uncorrelated,
|
Uncorrelated,
|
||||||
Disjoint,
|
Disjoint,
|
||||||
Conjoint
|
Conjoint,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -7,6 +7,6 @@
|
|||||||
SmaaLow,
|
SmaaLow,
|
||||||
SmaaMedium,
|
SmaaMedium,
|
||||||
SmaaHigh,
|
SmaaHigh,
|
||||||
SmaaUltra
|
SmaaUltra,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -36,7 +36,7 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@@ -12,6 +12,6 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
MinimumGl = 0x8007,
|
MinimumGl = 0x8007,
|
||||||
MaximumGl = 0x8008,
|
MaximumGl = 0x8008,
|
||||||
SubtractGl = 0x800a,
|
SubtractGl = 0x800a,
|
||||||
ReverseSubtractGl = 0x800b
|
ReverseSubtractGl = 0x800b,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3,6 +3,6 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
public enum BufferAccess
|
public enum BufferAccess
|
||||||
{
|
{
|
||||||
Default,
|
Default,
|
||||||
FlushPersistent
|
FlushPersistent,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,7 @@ 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;
|
||||||
|
|
||||||
|
@@ -3,6 +3,6 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
public enum CompareMode
|
public enum CompareMode
|
||||||
{
|
{
|
||||||
None,
|
None,
|
||||||
CompareRToTexture
|
CompareRToTexture,
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -4,6 +4,6 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
{
|
{
|
||||||
SamplesPassed,
|
SamplesPassed,
|
||||||
PrimitivesGenerated,
|
PrimitivesGenerated,
|
||||||
TransformFeedbackPrimitivesWritten
|
TransformFeedbackPrimitivesWritten,
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -3,6 +3,6 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
public enum DepthMode
|
public enum DepthMode
|
||||||
{
|
{
|
||||||
MinusOneToOne,
|
MinusOneToOne,
|
||||||
ZeroToOne
|
ZeroToOne,
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -3,6 +3,6 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
public enum DepthStencilMode
|
public enum DepthStencilMode
|
||||||
{
|
{
|
||||||
Depth,
|
Depth,
|
||||||
Stencil
|
Stencil,
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -4,6 +4,6 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
{
|
{
|
||||||
Front = 0x404,
|
Front = 0x404,
|
||||||
Back = 0x405,
|
Back = 0x405,
|
||||||
FrontAndBack = 0x408
|
FrontAndBack = 0x408,
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -146,7 +146,7 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
B5G5R5A1Unorm,
|
B5G5R5A1Unorm,
|
||||||
A1B5G5R5Unorm,
|
A1B5G5R5Unorm,
|
||||||
B8G8R8A8Unorm,
|
B8G8R8A8Unorm,
|
||||||
B8G8R8A8Srgb
|
B8G8R8A8Srgb,
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class FormatExtensions
|
public static class FormatExtensions
|
||||||
|
@@ -3,6 +3,6 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
public enum FrontFace
|
public enum FrontFace
|
||||||
{
|
{
|
||||||
Clockwise = 0x900,
|
Clockwise = 0x900,
|
||||||
CounterClockwise = 0x901
|
CounterClockwise = 0x901,
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -1,5 +1,4 @@
|
|||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.GAL
|
namespace Ryujinx.Graphics.GAL
|
||||||
{
|
{
|
||||||
|
@@ -4,6 +4,6 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
{
|
{
|
||||||
UByte,
|
UByte,
|
||||||
UShort,
|
UShort,
|
||||||
UInt
|
UInt,
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -17,6 +17,6 @@
|
|||||||
CopyInverted = 0x150C,
|
CopyInverted = 0x150C,
|
||||||
OrInverted = 0x150D,
|
OrInverted = 0x150D,
|
||||||
Nand = 0x150E,
|
Nand = 0x150E,
|
||||||
Set = 0x150F
|
Set = 0x150F,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3,6 +3,6 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
public enum MagFilter
|
public enum MagFilter
|
||||||
{
|
{
|
||||||
Nearest = 1,
|
Nearest = 1,
|
||||||
Linear
|
Linear,
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -7,6 +7,6 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
NearestMipmapNearest,
|
NearestMipmapNearest,
|
||||||
LinearMipmapNearest,
|
LinearMipmapNearest,
|
||||||
NearestMipmapLinear,
|
NearestMipmapLinear,
|
||||||
LinearMipmapLinear
|
LinearMipmapLinear,
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -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()
|
||||||
{
|
{
|
||||||
@@ -62,11 +62,9 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
|||||||
// 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;
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -100,6 +100,6 @@
|
|||||||
TextureBarrierTiled,
|
TextureBarrierTiled,
|
||||||
TryHostConditionalRendering,
|
TryHostConditionalRendering,
|
||||||
TryHostConditionalRenderingFlush,
|
TryHostConditionalRenderingFlush,
|
||||||
UpdateRenderScale
|
UpdateRenderScale,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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)
|
||||||
{
|
{
|
||||||
|
@@ -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)
|
||||||
|
@@ -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)
|
||||||
|
@@ -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;
|
||||||
|
@@ -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;
|
||||||
|
@@ -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;
|
||||||
|
@@ -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;
|
||||||
|
@@ -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;
|
||||||
|
@@ -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)
|
||||||
{
|
{
|
||||||
|
@@ -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;
|
||||||
|
@@ -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)
|
||||||
|
@@ -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)
|
||||||
|
@@ -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;
|
||||||
|
@@ -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;
|
||||||
|
@@ -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;
|
||||||
|
@@ -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)
|
||||||
|
@@ -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;
|
||||||
|
@@ -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)
|
||||||
|
@@ -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;
|
||||||
|
@@ -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;
|
||||||
|
@@ -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)
|
||||||
{
|
{
|
||||||
|
@@ -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)
|
||||||
{
|
{
|
||||||
|
@@ -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;
|
||||||
|
@@ -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)
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
@@ -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)
|
||||||
|
@@ -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;
|
||||||
|
@@ -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;
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
struct CreateHostBufferCommand : IGALCommand, IGALCommand<CreateHostBufferCommand>
|
struct CreateHostBufferCommand : IGALCommand, IGALCommand<CreateHostBufferCommand>
|
||||||
{
|
{
|
||||||
public CommandType CommandType => CommandType.CreateHostBuffer;
|
public readonly CommandType CommandType => CommandType.CreateHostBuffer;
|
||||||
private BufferHandle _threadedHandle;
|
private BufferHandle _threadedHandle;
|
||||||
private nint _pointer;
|
private nint _pointer;
|
||||||
private int _size;
|
private int _size;
|
||||||
|
@@ -5,7 +5,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer
|
|||||||
{
|
{
|
||||||
struct CreateProgramCommand : IGALCommand, IGALCommand<CreateProgramCommand>
|
struct CreateProgramCommand : IGALCommand, IGALCommand<CreateProgramCommand>
|
||||||
{
|
{
|
||||||
public CommandType CommandType => CommandType.CreateProgram;
|
public readonly CommandType CommandType => CommandType.CreateProgram;
|
||||||
private TableRef<IProgramRequest> _request;
|
private TableRef<IProgramRequest> _request;
|
||||||
|
|
||||||
public void Set(TableRef<IProgramRequest> request)
|
public void Set(TableRef<IProgramRequest> request)
|
||||||
|
@@ -5,7 +5,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer
|
|||||||
{
|
{
|
||||||
struct CreateSamplerCommand : IGALCommand, IGALCommand<CreateSamplerCommand>
|
struct CreateSamplerCommand : IGALCommand, IGALCommand<CreateSamplerCommand>
|
||||||
{
|
{
|
||||||
public CommandType CommandType => CommandType.CreateSampler;
|
public readonly CommandType CommandType => CommandType.CreateSampler;
|
||||||
private TableRef<ThreadedSampler> _sampler;
|
private TableRef<ThreadedSampler> _sampler;
|
||||||
private SamplerCreateInfo _info;
|
private SamplerCreateInfo _info;
|
||||||
|
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
struct CreateSyncCommand : IGALCommand, IGALCommand<CreateSyncCommand>
|
struct CreateSyncCommand : IGALCommand, IGALCommand<CreateSyncCommand>
|
||||||
{
|
{
|
||||||
public CommandType CommandType => CommandType.CreateSync;
|
public readonly CommandType CommandType => CommandType.CreateSync;
|
||||||
private ulong _id;
|
private ulong _id;
|
||||||
private bool _strict;
|
private bool _strict;
|
||||||
|
|
||||||
|
@@ -5,7 +5,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer
|
|||||||
{
|
{
|
||||||
struct CreateTextureCommand : IGALCommand, IGALCommand<CreateTextureCommand>
|
struct CreateTextureCommand : IGALCommand, IGALCommand<CreateTextureCommand>
|
||||||
{
|
{
|
||||||
public CommandType CommandType => CommandType.CreateTexture;
|
public readonly CommandType CommandType => CommandType.CreateTexture;
|
||||||
private TableRef<ThreadedTexture> _texture;
|
private TableRef<ThreadedTexture> _texture;
|
||||||
private TextureCreateInfo _info;
|
private TextureCreateInfo _info;
|
||||||
private float _scale;
|
private float _scale;
|
||||||
|
@@ -4,7 +4,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer
|
|||||||
{
|
{
|
||||||
struct GetCapabilitiesCommand : IGALCommand, IGALCommand<GetCapabilitiesCommand>
|
struct GetCapabilitiesCommand : IGALCommand, IGALCommand<GetCapabilitiesCommand>
|
||||||
{
|
{
|
||||||
public CommandType CommandType => CommandType.GetCapabilities;
|
public readonly CommandType CommandType => CommandType.GetCapabilities;
|
||||||
private TableRef<ResultBox<Capabilities>> _result;
|
private TableRef<ResultBox<Capabilities>> _result;
|
||||||
|
|
||||||
public void Set(TableRef<ResultBox<Capabilities>> result)
|
public void Set(TableRef<ResultBox<Capabilities>> result)
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
struct PreFrameCommand : IGALCommand, IGALCommand<PreFrameCommand>
|
struct PreFrameCommand : IGALCommand, IGALCommand<PreFrameCommand>
|
||||||
{
|
{
|
||||||
public CommandType CommandType => CommandType.PreFrame;
|
public readonly CommandType CommandType => CommandType.PreFrame;
|
||||||
|
|
||||||
public static void Run(ref PreFrameCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
public static void Run(ref PreFrameCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||||
{
|
{
|
||||||
|
@@ -6,7 +6,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer
|
|||||||
{
|
{
|
||||||
struct ReportCounterCommand : IGALCommand, IGALCommand<ReportCounterCommand>
|
struct ReportCounterCommand : IGALCommand, IGALCommand<ReportCounterCommand>
|
||||||
{
|
{
|
||||||
public CommandType CommandType => CommandType.ReportCounter;
|
public readonly CommandType CommandType => CommandType.ReportCounter;
|
||||||
private TableRef<ThreadedCounterEvent> _event;
|
private TableRef<ThreadedCounterEvent> _event;
|
||||||
private CounterType _type;
|
private CounterType _type;
|
||||||
private TableRef<EventHandler<ulong>> _resultHandler;
|
private TableRef<EventHandler<ulong>> _resultHandler;
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
struct ResetCounterCommand : IGALCommand, IGALCommand<ResetCounterCommand>
|
struct ResetCounterCommand : IGALCommand, IGALCommand<ResetCounterCommand>
|
||||||
{
|
{
|
||||||
public CommandType CommandType => CommandType.ResetCounter;
|
public readonly CommandType CommandType => CommandType.ResetCounter;
|
||||||
private CounterType _type;
|
private CounterType _type;
|
||||||
|
|
||||||
public void Set(CounterType type)
|
public void Set(CounterType type)
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
struct UpdateCountersCommand : IGALCommand, IGALCommand<UpdateCountersCommand>
|
struct UpdateCountersCommand : IGALCommand, IGALCommand<UpdateCountersCommand>
|
||||||
{
|
{
|
||||||
public CommandType CommandType => CommandType.UpdateCounters;
|
public readonly CommandType CommandType => CommandType.UpdateCounters;
|
||||||
|
|
||||||
public static void Run(ref UpdateCountersCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
public static void Run(ref UpdateCountersCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||||
{
|
{
|
||||||
|
@@ -5,7 +5,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Sampler
|
|||||||
{
|
{
|
||||||
struct SamplerDisposeCommand : IGALCommand, IGALCommand<SamplerDisposeCommand>
|
struct SamplerDisposeCommand : IGALCommand, IGALCommand<SamplerDisposeCommand>
|
||||||
{
|
{
|
||||||
public CommandType CommandType => CommandType.SamplerDispose;
|
public readonly CommandType CommandType => CommandType.SamplerDispose;
|
||||||
private TableRef<ThreadedSampler> _sampler;
|
private TableRef<ThreadedSampler> _sampler;
|
||||||
|
|
||||||
public void Set(TableRef<ThreadedSampler> sampler)
|
public void Set(TableRef<ThreadedSampler> sampler)
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
struct SetAlphaTestCommand : IGALCommand, IGALCommand<SetAlphaTestCommand>
|
struct SetAlphaTestCommand : IGALCommand, IGALCommand<SetAlphaTestCommand>
|
||||||
{
|
{
|
||||||
public CommandType CommandType => CommandType.SetAlphaTest;
|
public readonly CommandType CommandType => CommandType.SetAlphaTest;
|
||||||
private bool _enable;
|
private bool _enable;
|
||||||
private float _reference;
|
private float _reference;
|
||||||
private CompareOp _op;
|
private CompareOp _op;
|
||||||
|
@@ -2,7 +2,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
|||||||
{
|
{
|
||||||
struct SetBlendStateAdvancedCommand : IGALCommand, IGALCommand<SetBlendStateAdvancedCommand>
|
struct SetBlendStateAdvancedCommand : IGALCommand, IGALCommand<SetBlendStateAdvancedCommand>
|
||||||
{
|
{
|
||||||
public CommandType CommandType => CommandType.SetBlendStateAdvanced;
|
public readonly CommandType CommandType => CommandType.SetBlendStateAdvanced;
|
||||||
private AdvancedBlendDescriptor _blend;
|
private AdvancedBlendDescriptor _blend;
|
||||||
|
|
||||||
public void Set(AdvancedBlendDescriptor blend)
|
public void Set(AdvancedBlendDescriptor blend)
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
struct SetBlendStateCommand : IGALCommand, IGALCommand<SetBlendStateCommand>
|
struct SetBlendStateCommand : IGALCommand, IGALCommand<SetBlendStateCommand>
|
||||||
{
|
{
|
||||||
public CommandType CommandType => CommandType.SetBlendState;
|
public readonly CommandType CommandType => CommandType.SetBlendState;
|
||||||
private int _index;
|
private int _index;
|
||||||
private BlendDescriptor _blend;
|
private BlendDescriptor _blend;
|
||||||
|
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
struct SetDepthBiasCommand : IGALCommand, IGALCommand<SetDepthBiasCommand>
|
struct SetDepthBiasCommand : IGALCommand, IGALCommand<SetDepthBiasCommand>
|
||||||
{
|
{
|
||||||
public CommandType CommandType => CommandType.SetDepthBias;
|
public readonly CommandType CommandType => CommandType.SetDepthBias;
|
||||||
private PolygonModeMask _enables;
|
private PolygonModeMask _enables;
|
||||||
private float _factor;
|
private float _factor;
|
||||||
private float _units;
|
private float _units;
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
struct SetDepthClampCommand : IGALCommand, IGALCommand<SetDepthClampCommand>
|
struct SetDepthClampCommand : IGALCommand, IGALCommand<SetDepthClampCommand>
|
||||||
{
|
{
|
||||||
public CommandType CommandType => CommandType.SetDepthClamp;
|
public readonly CommandType CommandType => CommandType.SetDepthClamp;
|
||||||
private bool _clamp;
|
private bool _clamp;
|
||||||
|
|
||||||
public void Set(bool clamp)
|
public void Set(bool clamp)
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user