Compare commits
8 Commits
Author | SHA1 | Date | |
---|---|---|---|
e3b36db71c | |||
ba0171d054 | |||
d1146a5af2 | |||
79408b68c3 | |||
d461d4f68b | |||
b45d30acf8 | |||
df70442c46 | |||
e2ffa5a125 |
@ -130,11 +130,6 @@ namespace ARMeilleure.Instructions
|
||||
bool ordered = (accType & AccessType.Ordered) != 0;
|
||||
bool exclusive = (accType & AccessType.Exclusive) != 0;
|
||||
|
||||
if (ordered)
|
||||
{
|
||||
EmitBarrier(context);
|
||||
}
|
||||
|
||||
Operand address = context.Copy(GetIntOrSP(context, op.Rn));
|
||||
|
||||
Operand t = GetIntOrZR(context, op.Rt);
|
||||
@ -163,6 +158,11 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
EmitStoreExclusive(context, address, t, exclusive, op.Size, op.Rs, a32: false);
|
||||
}
|
||||
|
||||
if (ordered)
|
||||
{
|
||||
EmitBarrier(context);
|
||||
}
|
||||
}
|
||||
|
||||
private static void EmitBarrier(ArmEmitterContext context)
|
||||
|
@ -146,13 +146,13 @@ namespace ARMeilleure.Instructions
|
||||
var exclusive = (accType & AccessType.Exclusive) != 0;
|
||||
var ordered = (accType & AccessType.Ordered) != 0;
|
||||
|
||||
if (ordered)
|
||||
{
|
||||
EmitBarrier(context);
|
||||
}
|
||||
|
||||
if ((accType & AccessType.Load) != 0)
|
||||
{
|
||||
if (ordered)
|
||||
{
|
||||
EmitBarrier(context);
|
||||
}
|
||||
|
||||
if (size == DWordSizeLog2)
|
||||
{
|
||||
// Keep loads atomic - make the call to get the whole region and then decompose it into parts
|
||||
@ -219,6 +219,11 @@ namespace ARMeilleure.Instructions
|
||||
Operand value = context.ZeroExtend32(OperandType.I64, GetIntA32(context, op.Rt));
|
||||
EmitStoreExclusive(context, address, value, exclusive, size, op.Rd, a32: true);
|
||||
}
|
||||
|
||||
if (ordered)
|
||||
{
|
||||
EmitBarrier(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ namespace ARMeilleure.Translation.PTC
|
||||
private const string OuterHeaderMagicString = "PTCohd\0\0";
|
||||
private const string InnerHeaderMagicString = "PTCihd\0\0";
|
||||
|
||||
private const uint InternalVersion = 3179; //! To be incremented manually for each change to the ARMeilleure project.
|
||||
private const uint InternalVersion = 3193; //! To be incremented manually for each change to the ARMeilleure project.
|
||||
|
||||
private const string ActualDir = "0";
|
||||
private const string BackupDir = "1";
|
||||
|
@ -47,6 +47,7 @@ namespace Ryujinx.Common.Logging
|
||||
ServiceNim,
|
||||
ServiceNs,
|
||||
ServiceNsd,
|
||||
ServiceNtc,
|
||||
ServiceNv,
|
||||
ServiceOlsc,
|
||||
ServicePctl,
|
||||
|
@ -1,7 +1,7 @@
|
||||
using Ryujinx.Common;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Graphics.Device;
|
||||
using Ryujinx.Graphics.Gpu.Engine.Threed;
|
||||
using Ryujinx.Graphics.Gpu.Memory;
|
||||
using Ryujinx.Graphics.Texture;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@ -330,11 +330,95 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
||||
{
|
||||
// TODO: Implement remap functionality.
|
||||
// Buffer to buffer copy.
|
||||
memoryManager.Physical.BufferCache.CopyBuffer(memoryManager, srcGpuVa, dstGpuVa, size);
|
||||
|
||||
bool srcIsPitchKind = memoryManager.GetKind(srcGpuVa).IsPitch();
|
||||
bool dstIsPitchKind = memoryManager.GetKind(dstGpuVa).IsPitch();
|
||||
|
||||
if (!srcIsPitchKind && dstIsPitchKind)
|
||||
{
|
||||
CopyGobBlockLinearToLinear(memoryManager, srcGpuVa, dstGpuVa, size);
|
||||
}
|
||||
else if (srcIsPitchKind && !dstIsPitchKind)
|
||||
{
|
||||
CopyGobLinearToBlockLinear(memoryManager, srcGpuVa, dstGpuVa, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
memoryManager.Physical.BufferCache.CopyBuffer(memoryManager, srcGpuVa, dstGpuVa, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies block linear data with block linear GOBs to a block linear destination with linear GOBs.
|
||||
/// </summary>
|
||||
/// <param name="memoryManager">GPU memory manager</param>
|
||||
/// <param name="srcGpuVa">Source GPU virtual address</param>
|
||||
/// <param name="dstGpuVa">Destination GPU virtual address</param>
|
||||
/// <param name="size">Size in bytes of the copy</param>
|
||||
private static void CopyGobBlockLinearToLinear(MemoryManager memoryManager, ulong srcGpuVa, ulong dstGpuVa, ulong size)
|
||||
{
|
||||
if (((srcGpuVa | dstGpuVa | size) & 0xf) == 0)
|
||||
{
|
||||
for (ulong offset = 0; offset < size; offset += 16)
|
||||
{
|
||||
Vector128<byte> data = memoryManager.Read<Vector128<byte>>(ConvertGobLinearToBlockLinearAddress(srcGpuVa + offset), true);
|
||||
memoryManager.Write(dstGpuVa + offset, data);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (ulong offset = 0; offset < size; offset++)
|
||||
{
|
||||
byte data = memoryManager.Read<byte>(ConvertGobLinearToBlockLinearAddress(srcGpuVa + offset), true);
|
||||
memoryManager.Write(dstGpuVa + offset, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies block linear data with linear GOBs to a block linear destination with block linear GOBs.
|
||||
/// </summary>
|
||||
/// <param name="memoryManager">GPU memory manager</param>
|
||||
/// <param name="srcGpuVa">Source GPU virtual address</param>
|
||||
/// <param name="dstGpuVa">Destination GPU virtual address</param>
|
||||
/// <param name="size">Size in bytes of the copy</param>
|
||||
private static void CopyGobLinearToBlockLinear(MemoryManager memoryManager, ulong srcGpuVa, ulong dstGpuVa, ulong size)
|
||||
{
|
||||
if (((srcGpuVa | dstGpuVa | size) & 0xf) == 0)
|
||||
{
|
||||
for (ulong offset = 0; offset < size; offset += 16)
|
||||
{
|
||||
Vector128<byte> data = memoryManager.Read<Vector128<byte>>(srcGpuVa + offset, true);
|
||||
memoryManager.Write(ConvertGobLinearToBlockLinearAddress(dstGpuVa + offset), data);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (ulong offset = 0; offset < size; offset++)
|
||||
{
|
||||
byte data = memoryManager.Read<byte>(srcGpuVa + offset, true);
|
||||
memoryManager.Write(ConvertGobLinearToBlockLinearAddress(dstGpuVa + offset), data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the GOB block linear address from a linear address.
|
||||
/// </summary>
|
||||
/// <param name="address">Linear address</param>
|
||||
/// <returns>Block linear address</returns>
|
||||
private static ulong ConvertGobLinearToBlockLinearAddress(ulong address)
|
||||
{
|
||||
// y2 y1 y0 x5 x4 x3 x2 x1 x0 -> x5 y2 y1 x4 y0 x3 x2 x1 x0
|
||||
return (address & ~0x1f0UL) |
|
||||
((address & 0x40) >> 2) |
|
||||
((address & 0x10) << 1) |
|
||||
((address & 0x180) >> 1) |
|
||||
((address & 0x20) << 3);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs a buffer to buffer, or buffer to texture copy, then optionally releases a semaphore.
|
||||
/// </summary>
|
||||
|
@ -7,7 +7,6 @@ using Ryujinx.Graphics.Gpu.Engine.Types;
|
||||
using Ryujinx.Graphics.Gpu.Image;
|
||||
using Ryujinx.Graphics.Gpu.Memory;
|
||||
using Ryujinx.Graphics.Texture;
|
||||
using Ryujinx.Memory;
|
||||
using Ryujinx.Memory.Range;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
@ -264,7 +264,8 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// <param name="pa">CPU virtual address to map into</param>
|
||||
/// <param name="va">GPU virtual address to be mapped</param>
|
||||
/// <param name="size">Size in bytes of the mapping</param>
|
||||
public void Map(ulong pa, ulong va, ulong size)
|
||||
/// <param name="kind">Kind of the resource located at the mapping</param>
|
||||
public void Map(ulong pa, ulong va, ulong size, PteKind kind)
|
||||
{
|
||||
lock (_pageTable)
|
||||
{
|
||||
@ -272,7 +273,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
|
||||
for (ulong offset = 0; offset < size; offset += PageSize)
|
||||
{
|
||||
SetPte(va + offset, pa + offset);
|
||||
SetPte(va + offset, PackPte(pa + offset, kind));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -462,14 +463,37 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
return PteUnmapped;
|
||||
}
|
||||
|
||||
ulong baseAddress = GetPte(va);
|
||||
ulong pte = GetPte(va);
|
||||
|
||||
if (baseAddress == PteUnmapped)
|
||||
if (pte == PteUnmapped)
|
||||
{
|
||||
return PteUnmapped;
|
||||
}
|
||||
|
||||
return baseAddress + (va & PageMask);
|
||||
return UnpackPaFromPte(pte) + (va & PageMask);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the kind of a given memory page.
|
||||
/// This might indicate the type of resource that can be allocated on the page, and also texture tiling.
|
||||
/// </summary>
|
||||
/// <param name="va">GPU virtual address</param>
|
||||
/// <returns>Kind of the memory page</returns>
|
||||
public PteKind GetKind(ulong va)
|
||||
{
|
||||
if (!ValidateAddress(va))
|
||||
{
|
||||
return PteKind.Invalid;
|
||||
}
|
||||
|
||||
ulong pte = GetPte(va);
|
||||
|
||||
if (pte == PteUnmapped)
|
||||
{
|
||||
return PteKind.Invalid;
|
||||
}
|
||||
|
||||
return UnpackKindFromPte(pte);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -512,5 +536,36 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
|
||||
_pageTable[l0][l1] = pte;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a page table entry from a physical address and kind.
|
||||
/// </summary>
|
||||
/// <param name="pa">Physical address</param>
|
||||
/// <param name="kind">Kind</param>
|
||||
/// <returns>Page table entry</returns>
|
||||
private static ulong PackPte(ulong pa, PteKind kind)
|
||||
{
|
||||
return pa | ((ulong)kind << 56);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unpacks kind from a page table entry.
|
||||
/// </summary>
|
||||
/// <param name="pte">Page table entry</param>
|
||||
/// <returns>Kind</returns>
|
||||
private static PteKind UnpackKindFromPte(ulong pte)
|
||||
{
|
||||
return (PteKind)(pte >> 56);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unpacks physical address from a page table entry.
|
||||
/// </summary>
|
||||
/// <param name="pte">Page table entry</param>
|
||||
/// <returns>Physical address</returns>
|
||||
private static ulong UnpackPaFromPte(ulong pte)
|
||||
{
|
||||
return pte & 0xffffffffffffffUL;
|
||||
}
|
||||
}
|
||||
}
|
268
Ryujinx.Graphics.Gpu/Memory/PteKind.cs
Normal file
268
Ryujinx.Graphics.Gpu/Memory/PteKind.cs
Normal file
@ -0,0 +1,268 @@
|
||||
namespace Ryujinx.Graphics.Gpu.Memory
|
||||
{
|
||||
/// <summary>
|
||||
/// Kind of the resource at the given memory mapping.
|
||||
/// </summary>
|
||||
public enum PteKind : byte
|
||||
{
|
||||
Invalid = 0xff,
|
||||
Pitch = 0x00,
|
||||
Z16 = 0x01,
|
||||
Z162C = 0x02,
|
||||
Z16MS22C = 0x03,
|
||||
Z16MS42C = 0x04,
|
||||
Z16MS82C = 0x05,
|
||||
Z16MS162C = 0x06,
|
||||
Z162Z = 0x07,
|
||||
Z16MS22Z = 0x08,
|
||||
Z16MS42Z = 0x09,
|
||||
Z16MS82Z = 0x0a,
|
||||
Z16MS162Z = 0x0b,
|
||||
Z162CZ = 0x36,
|
||||
Z16MS22CZ = 0x37,
|
||||
Z16MS42CZ = 0x38,
|
||||
Z16MS82CZ = 0x39,
|
||||
Z16MS162CZ = 0x5f,
|
||||
Z164CZ = 0x0c,
|
||||
Z16MS24CZ = 0x0d,
|
||||
Z16MS44CZ = 0x0e,
|
||||
Z16MS84CZ = 0x0f,
|
||||
Z16MS164CZ = 0x10,
|
||||
S8Z24 = 0x11,
|
||||
S8Z241Z = 0x12,
|
||||
S8Z24MS21Z = 0x13,
|
||||
S8Z24MS41Z = 0x14,
|
||||
S8Z24MS81Z = 0x15,
|
||||
S8Z24MS161Z = 0x16,
|
||||
S8Z242CZ = 0x17,
|
||||
S8Z24MS22CZ = 0x18,
|
||||
S8Z24MS42CZ = 0x19,
|
||||
S8Z24MS82CZ = 0x1a,
|
||||
S8Z24MS162CZ = 0x1b,
|
||||
S8Z242CS = 0x1c,
|
||||
S8Z24MS22CS = 0x1d,
|
||||
S8Z24MS42CS = 0x1e,
|
||||
S8Z24MS82CS = 0x1f,
|
||||
S8Z24MS162CS = 0x20,
|
||||
S8Z244CSZV = 0x21,
|
||||
S8Z24MS24CSZV = 0x22,
|
||||
S8Z24MS44CSZV = 0x23,
|
||||
S8Z24MS84CSZV = 0x24,
|
||||
S8Z24MS164CSZV = 0x25,
|
||||
V8Z24MS4VC12 = 0x26,
|
||||
V8Z24MS4VC4 = 0x27,
|
||||
V8Z24MS8VC8 = 0x28,
|
||||
V8Z24MS8VC24 = 0x29,
|
||||
V8Z24MS4VC121ZV = 0x2e,
|
||||
V8Z24MS4VC41ZV = 0x2f,
|
||||
V8Z24MS8VC81ZV = 0x30,
|
||||
V8Z24MS8VC241ZV = 0x31,
|
||||
V8Z24MS4VC122CS = 0x32,
|
||||
V8Z24MS4VC42CS = 0x33,
|
||||
V8Z24MS8VC82CS = 0x34,
|
||||
V8Z24MS8VC242CS = 0x35,
|
||||
V8Z24MS4VC122CZV = 0x3a,
|
||||
V8Z24MS4VC42CZV = 0x3b,
|
||||
V8Z24MS8VC82CZV = 0x3c,
|
||||
V8Z24MS8VC242CZV = 0x3d,
|
||||
V8Z24MS4VC122ZV = 0x3e,
|
||||
V8Z24MS4VC42ZV = 0x3f,
|
||||
V8Z24MS8VC82ZV = 0x40,
|
||||
V8Z24MS8VC242ZV = 0x41,
|
||||
V8Z24MS4VC124CSZV = 0x42,
|
||||
V8Z24MS4VC44CSZV = 0x43,
|
||||
V8Z24MS8VC84CSZV = 0x44,
|
||||
V8Z24MS8VC244CSZV = 0x45,
|
||||
Z24S8 = 0x46,
|
||||
Z24S81Z = 0x47,
|
||||
Z24S8MS21Z = 0x48,
|
||||
Z24S8MS41Z = 0x49,
|
||||
Z24S8MS81Z = 0x4a,
|
||||
Z24S8MS161Z = 0x4b,
|
||||
Z24S82CS = 0x4c,
|
||||
Z24S8MS22CS = 0x4d,
|
||||
Z24S8MS42CS = 0x4e,
|
||||
Z24S8MS82CS = 0x4f,
|
||||
Z24S8MS162CS = 0x50,
|
||||
Z24S82CZ = 0x51,
|
||||
Z24S8MS22CZ = 0x52,
|
||||
Z24S8MS42CZ = 0x53,
|
||||
Z24S8MS82CZ = 0x54,
|
||||
Z24S8MS162CZ = 0x55,
|
||||
Z24S84CSZV = 0x56,
|
||||
Z24S8MS24CSZV = 0x57,
|
||||
Z24S8MS44CSZV = 0x58,
|
||||
Z24S8MS84CSZV = 0x59,
|
||||
Z24S8MS164CSZV = 0x5a,
|
||||
Z24V8MS4VC12 = 0x5b,
|
||||
Z24V8MS4VC4 = 0x5c,
|
||||
Z24V8MS8VC8 = 0x5d,
|
||||
Z24V8MS8VC24 = 0x5e,
|
||||
YUVB8C12Y = 0x60,
|
||||
YUVB8C22Y = 0x61,
|
||||
YUVB10C12Y = 0x62,
|
||||
YUVB10C22Y = 0x6b,
|
||||
YUVB12C12Y = 0x6c,
|
||||
YUVB12C22Y = 0x6d,
|
||||
Z24V8MS4VC121ZV = 0x63,
|
||||
Z24V8MS4VC41ZV = 0x64,
|
||||
Z24V8MS8VC81ZV = 0x65,
|
||||
Z24V8MS8VC241ZV = 0x66,
|
||||
Z24V8MS4VC122CS = 0x67,
|
||||
Z24V8MS4VC42CS = 0x68,
|
||||
Z24V8MS8VC82CS = 0x69,
|
||||
Z24V8MS8VC242CS = 0x6a,
|
||||
Z24V8MS4VC122CZV = 0x6f,
|
||||
Z24V8MS4VC42CZV = 0x70,
|
||||
Z24V8MS8VC82CZV = 0x71,
|
||||
Z24V8MS8VC242CZV = 0x72,
|
||||
Z24V8MS4VC122ZV = 0x73,
|
||||
Z24V8MS4VC42ZV = 0x74,
|
||||
Z24V8MS8VC82ZV = 0x75,
|
||||
Z24V8MS8VC242ZV = 0x76,
|
||||
Z24V8MS4VC124CSZV = 0x77,
|
||||
Z24V8MS4VC44CSZV = 0x78,
|
||||
Z24V8MS8VC84CSZV = 0x79,
|
||||
Z24V8MS8VC244CSZV = 0x7a,
|
||||
ZF32 = 0x7b,
|
||||
ZF321Z = 0x7c,
|
||||
ZF32MS21Z = 0x7d,
|
||||
ZF32MS41Z = 0x7e,
|
||||
ZF32MS81Z = 0x7f,
|
||||
ZF32MS161Z = 0x80,
|
||||
ZF322CS = 0x81,
|
||||
ZF32MS22CS = 0x82,
|
||||
ZF32MS42CS = 0x83,
|
||||
ZF32MS82CS = 0x84,
|
||||
ZF32MS162CS = 0x85,
|
||||
ZF322CZ = 0x86,
|
||||
ZF32MS22CZ = 0x87,
|
||||
ZF32MS42CZ = 0x88,
|
||||
ZF32MS82CZ = 0x89,
|
||||
ZF32MS162CZ = 0x8a,
|
||||
X8Z24X16V8S8MS4VC12 = 0x8b,
|
||||
X8Z24X16V8S8MS4VC4 = 0x8c,
|
||||
X8Z24X16V8S8MS8VC8 = 0x8d,
|
||||
X8Z24X16V8S8MS8VC24 = 0x8e,
|
||||
X8Z24X16V8S8MS4VC121CS = 0x8f,
|
||||
X8Z24X16V8S8MS4VC41CS = 0x90,
|
||||
X8Z24X16V8S8MS8VC81CS = 0x91,
|
||||
X8Z24X16V8S8MS8VC241CS = 0x92,
|
||||
X8Z24X16V8S8MS4VC121ZV = 0x97,
|
||||
X8Z24X16V8S8MS4VC41ZV = 0x98,
|
||||
X8Z24X16V8S8MS8VC81ZV = 0x99,
|
||||
X8Z24X16V8S8MS8VC241ZV = 0x9a,
|
||||
X8Z24X16V8S8MS4VC121CZV = 0x9b,
|
||||
X8Z24X16V8S8MS4VC41CZV = 0x9c,
|
||||
X8Z24X16V8S8MS8VC81CZV = 0x9d,
|
||||
X8Z24X16V8S8MS8VC241CZV = 0x9e,
|
||||
X8Z24X16V8S8MS4VC122CS = 0x9f,
|
||||
X8Z24X16V8S8MS4VC42CS = 0xa0,
|
||||
X8Z24X16V8S8MS8VC82CS = 0xa1,
|
||||
X8Z24X16V8S8MS8VC242CS = 0xa2,
|
||||
X8Z24X16V8S8MS4VC122CSZV = 0xa3,
|
||||
X8Z24X16V8S8MS4VC42CSZV = 0xa4,
|
||||
X8Z24X16V8S8MS8VC82CSZV = 0xa5,
|
||||
X8Z24X16V8S8MS8VC242CSZV = 0xa6,
|
||||
ZF32X16V8S8MS4VC12 = 0xa7,
|
||||
ZF32X16V8S8MS4VC4 = 0xa8,
|
||||
ZF32X16V8S8MS8VC8 = 0xa9,
|
||||
ZF32X16V8S8MS8VC24 = 0xaa,
|
||||
ZF32X16V8S8MS4VC121CS = 0xab,
|
||||
ZF32X16V8S8MS4VC41CS = 0xac,
|
||||
ZF32X16V8S8MS8VC81CS = 0xad,
|
||||
ZF32X16V8S8MS8VC241CS = 0xae,
|
||||
ZF32X16V8S8MS4VC121ZV = 0xb3,
|
||||
ZF32X16V8S8MS4VC41ZV = 0xb4,
|
||||
ZF32X16V8S8MS8VC81ZV = 0xb5,
|
||||
ZF32X16V8S8MS8VC241ZV = 0xb6,
|
||||
ZF32X16V8S8MS4VC121CZV = 0xb7,
|
||||
ZF32X16V8S8MS4VC41CZV = 0xb8,
|
||||
ZF32X16V8S8MS8VC81CZV = 0xb9,
|
||||
ZF32X16V8S8MS8VC241CZV = 0xba,
|
||||
ZF32X16V8S8MS4VC122CS = 0xbb,
|
||||
ZF32X16V8S8MS4VC42CS = 0xbc,
|
||||
ZF32X16V8S8MS8VC82CS = 0xbd,
|
||||
ZF32X16V8S8MS8VC242CS = 0xbe,
|
||||
ZF32X16V8S8MS4VC122CSZV = 0xbf,
|
||||
ZF32X16V8S8MS4VC42CSZV = 0xc0,
|
||||
ZF32X16V8S8MS8VC82CSZV = 0xc1,
|
||||
ZF32X16V8S8MS8VC242CSZV = 0xc2,
|
||||
ZF32X24S8 = 0xc3,
|
||||
ZF32X24S81CS = 0xc4,
|
||||
ZF32X24S8MS21CS = 0xc5,
|
||||
ZF32X24S8MS41CS = 0xc6,
|
||||
ZF32X24S8MS81CS = 0xc7,
|
||||
ZF32X24S8MS161CS = 0xc8,
|
||||
ZF32X24S82CSZV = 0xce,
|
||||
ZF32X24S8MS22CSZV = 0xcf,
|
||||
ZF32X24S8MS42CSZV = 0xd0,
|
||||
ZF32X24S8MS82CSZV = 0xd1,
|
||||
ZF32X24S8MS162CSZV = 0xd2,
|
||||
ZF32X24S82CS = 0xd3,
|
||||
ZF32X24S8MS22CS = 0xd4,
|
||||
ZF32X24S8MS42CS = 0xd5,
|
||||
ZF32X24S8MS82CS = 0xd6,
|
||||
ZF32X24S8MS162CS = 0xd7,
|
||||
S8 = 0x2a,
|
||||
S82S = 0x2b,
|
||||
Generic16Bx2 = 0xfe,
|
||||
C322C = 0xd8,
|
||||
C322CBR = 0xd9,
|
||||
C322CBA = 0xda,
|
||||
C322CRA = 0xdb,
|
||||
C322BRA = 0xdc,
|
||||
C32MS22C = 0xdd,
|
||||
C32MS22CBR = 0xde,
|
||||
C32MS24CBRA = 0xcc,
|
||||
C32MS42C = 0xdf,
|
||||
C32MS42CBR = 0xe0,
|
||||
C32MS42CBA = 0xe1,
|
||||
C32MS42CRA = 0xe2,
|
||||
C32MS42BRA = 0xe3,
|
||||
C32MS44CBRA = 0x2c,
|
||||
C32MS8MS162C = 0xe4,
|
||||
C32MS8MS162CRA = 0xe5,
|
||||
C642C = 0xe6,
|
||||
C642CBR = 0xe7,
|
||||
C642CBA = 0xe8,
|
||||
C642CRA = 0xe9,
|
||||
C642BRA = 0xea,
|
||||
C64MS22C = 0xeb,
|
||||
C64MS22CBR = 0xec,
|
||||
C64MS24CBRA = 0xcd,
|
||||
C64MS42C = 0xed,
|
||||
C64MS42CBR = 0xee,
|
||||
C64MS42CBA = 0xef,
|
||||
C64MS42CRA = 0xf0,
|
||||
C64MS42BRA = 0xf1,
|
||||
C64MS44CBRA = 0x2d,
|
||||
C64MS8MS162C = 0xf2,
|
||||
C64MS8MS162CRA = 0xf3,
|
||||
C1282C = 0xf4,
|
||||
C1282CR = 0xf5,
|
||||
C128MS22C = 0xf6,
|
||||
C128MS22CR = 0xf7,
|
||||
C128MS42C = 0xf8,
|
||||
C128MS42CR = 0xf9,
|
||||
C128MS8MS162C = 0xfa,
|
||||
C128MS8MS162CR = 0xfb,
|
||||
X8C24 = 0xfc,
|
||||
PitchNoSwizzle = 0xfd,
|
||||
SmSkedMessage = 0xca,
|
||||
SmHostMessage = 0xcb
|
||||
}
|
||||
|
||||
static class PteKindExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Checks if the kind is pitch.
|
||||
/// </summary>
|
||||
/// <param name="kind">Kind to check</param>
|
||||
/// <returns>True if pitch, false otherwise</returns>
|
||||
public static bool IsPitch(this PteKind kind)
|
||||
{
|
||||
return kind == PteKind.Pitch || kind == PteKind.PitchNoSwizzle;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
namespace Ryujinx.Graphics.Gpu.Memory
|
||||
{
|
||||
/// <summary>
|
||||
/// Name of a GPU resource.
|
||||
/// </summary>
|
||||
public enum ResourceName
|
||||
{
|
||||
Buffer,
|
||||
Texture,
|
||||
TexturePool,
|
||||
SamplerPool
|
||||
}
|
||||
}
|
@ -16,7 +16,7 @@ namespace Ryujinx.Graphics.Nvdec.Image
|
||||
int width = surface.Width;
|
||||
int height = surface.Height;
|
||||
int stride = surface.Stride;
|
||||
|
||||
|
||||
ReadOnlySpan<byte> luma = gmm.DeviceGetSpan(lumaOffset, GetBlockLinearSize(width, height, 1));
|
||||
|
||||
ReadLuma(surface.YPlane.AsSpan(), luma, stride, width, height);
|
||||
|
@ -612,7 +612,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||
_program?.Bind();
|
||||
_unit0Sampler?.Bind(0);
|
||||
|
||||
GL.ViewportArray(0, 1, _viewportArray);
|
||||
RestoreViewport0();
|
||||
|
||||
Enable(EnableCap.CullFace, _cullEnable);
|
||||
Enable(EnableCap.StencilTest, _stencilTestEnable);
|
||||
@ -1478,6 +1478,11 @@ namespace Ryujinx.Graphics.OpenGL
|
||||
_currentComponentMasks |= componentMaskAtIndex;
|
||||
}
|
||||
|
||||
public void RestoreClipControl()
|
||||
{
|
||||
GL.ClipControl(_clipOrigin, _clipDepthMode);
|
||||
}
|
||||
|
||||
public void RestoreScissor0Enable()
|
||||
{
|
||||
if ((_scissorEnables & 1u) != 0)
|
||||
@ -1494,6 +1499,14 @@ namespace Ryujinx.Graphics.OpenGL
|
||||
}
|
||||
}
|
||||
|
||||
public void RestoreViewport0()
|
||||
{
|
||||
if (_viewportArray.Length > 0)
|
||||
{
|
||||
GL.ViewportArray(0, 1, _viewportArray);
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryHostConditionalRendering(ICounterEvent value, ulong compare, bool isEqual)
|
||||
{
|
||||
if (value is CounterQueueEvent)
|
||||
|
@ -27,11 +27,12 @@ namespace Ryujinx.Graphics.OpenGL
|
||||
{
|
||||
GL.Disable(EnableCap.FramebufferSrgb);
|
||||
|
||||
CopyTextureToFrameBufferRGB(0, GetCopyFramebufferHandleLazy(), (TextureView)texture, crop);
|
||||
CopyTextureToFrameBufferRGB(0, GetCopyFramebufferHandleLazy(), (TextureView)texture, crop, swapBuffersCallback);
|
||||
|
||||
GL.Enable(EnableCap.FramebufferSrgb);
|
||||
|
||||
swapBuffersCallback();
|
||||
// Restore unpack alignment to 4, as performance overlays such as RTSS may change this to load their resources.
|
||||
GL.PixelStore(PixelStoreParameter.UnpackAlignment, 4);
|
||||
}
|
||||
|
||||
public void SetSize(int width, int height)
|
||||
@ -40,7 +41,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||
_height = height;
|
||||
}
|
||||
|
||||
private void CopyTextureToFrameBufferRGB(int drawFramebuffer, int readFramebuffer, TextureView view, ImageCrop crop)
|
||||
private void CopyTextureToFrameBufferRGB(int drawFramebuffer, int readFramebuffer, TextureView view, ImageCrop crop, Action swapBuffersCallback)
|
||||
{
|
||||
(int oldDrawFramebufferHandle, int oldReadFramebufferHandle) = ((Pipeline)_renderer.Pipeline).GetBoundFramebuffers();
|
||||
|
||||
@ -139,11 +140,20 @@ namespace Ryujinx.Graphics.OpenGL
|
||||
((Pipeline)_renderer.Pipeline).RestoreComponentMask(i);
|
||||
}
|
||||
|
||||
// Set clip control, viewport and the framebuffer to the output to placate overlays and OBS capture.
|
||||
GL.ClipControl(ClipOrigin.LowerLeft, ClipDepthMode.NegativeOneToOne);
|
||||
GL.Viewport(0, 0, _width, _height);
|
||||
GL.BindFramebuffer(FramebufferTarget.Framebuffer, drawFramebuffer);
|
||||
|
||||
swapBuffersCallback();
|
||||
|
||||
GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, oldReadFramebufferHandle);
|
||||
GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, oldDrawFramebufferHandle);
|
||||
|
||||
((Pipeline)_renderer.Pipeline).RestoreClipControl();
|
||||
((Pipeline)_renderer.Pipeline).RestoreScissor0Enable();
|
||||
((Pipeline)_renderer.Pipeline).RestoreRasterizerDiscard();
|
||||
((Pipeline)_renderer.Pipeline).RestoreViewport0();
|
||||
|
||||
if (viewConverted != view)
|
||||
{
|
||||
|
@ -1,19 +0,0 @@
|
||||
namespace Ryujinx.HLE.FileSystem.Content
|
||||
{
|
||||
static class ContentPath
|
||||
{
|
||||
public const string SystemContent = "@SystemContent";
|
||||
public const string UserContent = "@UserContent";
|
||||
public const string SdCardContent = "@SdCardContent";
|
||||
public const string SdCard = "@SdCard";
|
||||
public const string CalibFile = "@CalibFile";
|
||||
public const string Safe = "@Safe";
|
||||
public const string User = "@User";
|
||||
public const string System = "@System";
|
||||
public const string Host = "@Host";
|
||||
public const string GamecardApp = "@GcApp";
|
||||
public const string GamecardContents = "@GcS00000001";
|
||||
public const string GamecardUpdate = "@upp";
|
||||
public const string RegisteredUpdate = "@RegUpdate";
|
||||
}
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
using static Ryujinx.HLE.FileSystem.VirtualFileSystem;
|
||||
|
||||
namespace Ryujinx.HLE.FileSystem.Content
|
||||
{
|
||||
internal static class LocationHelper
|
||||
{
|
||||
public static string GetRealPath(VirtualFileSystem fileSystem, string switchContentPath)
|
||||
{
|
||||
string basePath = fileSystem.GetBasePath();
|
||||
|
||||
switch (switchContentPath)
|
||||
{
|
||||
case ContentPath.SystemContent:
|
||||
return Path.Combine(basePath, SystemNandPath, "Contents");
|
||||
case ContentPath.UserContent:
|
||||
return Path.Combine(basePath, UserNandPath, "Contents");
|
||||
case ContentPath.SdCardContent:
|
||||
return Path.Combine(fileSystem.GetSdCardPath(), "Nintendo", "Contents");
|
||||
case ContentPath.System:
|
||||
return Path.Combine(basePath, SystemNandPath);
|
||||
case ContentPath.User:
|
||||
return Path.Combine(basePath, UserNandPath);
|
||||
default:
|
||||
throw new NotSupportedException($"Content Path `{switchContentPath}` is not supported.");
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetContentPath(ContentStorageId contentStorageId)
|
||||
{
|
||||
switch (contentStorageId)
|
||||
{
|
||||
case ContentStorageId.NandSystem:
|
||||
return ContentPath.SystemContent;
|
||||
case ContentStorageId.NandUser:
|
||||
return ContentPath.UserContent;
|
||||
case ContentStorageId.SdCard:
|
||||
return ContentPath.SdCardContent;
|
||||
default:
|
||||
throw new NotSupportedException($"Content Storage `{contentStorageId}` is not supported.");
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetContentRoot(StorageId storageId)
|
||||
{
|
||||
switch (storageId)
|
||||
{
|
||||
case StorageId.NandSystem:
|
||||
return ContentPath.SystemContent;
|
||||
case StorageId.NandUser:
|
||||
return ContentPath.UserContent;
|
||||
case StorageId.SdCard:
|
||||
return ContentPath.SdCardContent;
|
||||
default:
|
||||
throw new NotSupportedException($"Storage Id `{storageId}` is not supported.");
|
||||
}
|
||||
}
|
||||
|
||||
public static StorageId GetStorageId(string contentPathString)
|
||||
{
|
||||
string cleanedPath = contentPathString.Split(':')[0];
|
||||
|
||||
switch (cleanedPath)
|
||||
{
|
||||
case ContentPath.SystemContent:
|
||||
case ContentPath.System:
|
||||
return StorageId.NandSystem;
|
||||
|
||||
case ContentPath.UserContent:
|
||||
case ContentPath.User:
|
||||
return StorageId.NandUser;
|
||||
|
||||
case ContentPath.SdCardContent:
|
||||
return StorageId.SdCard;
|
||||
|
||||
case ContentPath.Host:
|
||||
return StorageId.Host;
|
||||
|
||||
case ContentPath.GamecardApp:
|
||||
case ContentPath.GamecardContents:
|
||||
case ContentPath.GamecardUpdate:
|
||||
return StorageId.GameCard;
|
||||
|
||||
default:
|
||||
return StorageId.None;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
namespace Ryujinx.HLE.FileSystem.Content
|
||||
{
|
||||
public enum ContentStorageId
|
||||
{
|
||||
NandSystem,
|
||||
NandUser,
|
||||
SdCard
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
namespace Ryujinx.HLE.FileSystem.Content
|
||||
{
|
||||
enum TitleType
|
||||
{
|
||||
SystemPrograms = 0x01,
|
||||
SystemDataArchive = 0x02,
|
||||
SystemUpdate = 0x03,
|
||||
FirmwarePackageA = 0x04,
|
||||
FirmwarePackageB = 0x05,
|
||||
RegularApplication = 0x80,
|
||||
Update = 0x81,
|
||||
AddOnContent = 0x82,
|
||||
DeltaTitle = 0x83
|
||||
}
|
||||
}
|
@ -20,7 +20,7 @@ using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using Path = System.IO.Path;
|
||||
|
||||
namespace Ryujinx.HLE.FileSystem.Content
|
||||
namespace Ryujinx.HLE.FileSystem
|
||||
{
|
||||
public class ContentManager
|
||||
{
|
||||
@ -110,8 +110,8 @@ namespace Ryujinx.HLE.FileSystem.Content
|
||||
|
||||
try
|
||||
{
|
||||
contentPathString = LocationHelper.GetContentRoot(storageId);
|
||||
contentDirectory = LocationHelper.GetRealPath(_virtualFileSystem, contentPathString);
|
||||
contentPathString = ContentPath.GetContentPath(storageId);
|
||||
contentDirectory = ContentPath.GetRealPath(_virtualFileSystem, contentPathString);
|
||||
registeredDirectory = Path.Combine(contentDirectory, "registered");
|
||||
}
|
||||
catch (NotSupportedException)
|
||||
@ -367,8 +367,7 @@ namespace Ryujinx.HLE.FileSystem.Content
|
||||
{
|
||||
LocationEntry locationEntry = GetLocation(titleId, contentType, storageId);
|
||||
|
||||
return locationEntry.ContentPath != null ?
|
||||
LocationHelper.GetStorageId(locationEntry.ContentPath) : StorageId.None;
|
||||
return locationEntry.ContentPath != null ? ContentPath.GetStorageId(locationEntry.ContentPath) : StorageId.None;
|
||||
}
|
||||
}
|
||||
|
||||
@ -493,8 +492,8 @@ namespace Ryujinx.HLE.FileSystem.Content
|
||||
|
||||
public void InstallFirmware(string firmwareSource)
|
||||
{
|
||||
string contentPathString = LocationHelper.GetContentRoot(StorageId.NandSystem);
|
||||
string contentDirectory = LocationHelper.GetRealPath(_virtualFileSystem, contentPathString);
|
||||
string contentPathString = ContentPath.GetContentPath(StorageId.BuiltInSystem);
|
||||
string contentDirectory = ContentPath.GetRealPath(_virtualFileSystem, contentPathString);
|
||||
string registeredDirectory = Path.Combine(contentDirectory, "registered");
|
||||
string temporaryDirectory = Path.Combine(contentDirectory, "temp");
|
||||
|
||||
@ -998,9 +997,9 @@ namespace Ryujinx.HLE.FileSystem.Content
|
||||
|
||||
foreach (var entry in updateNcas)
|
||||
{
|
||||
foreach (var nca in entry.Value)
|
||||
foreach (var (type, path) in entry.Value)
|
||||
{
|
||||
extraNcas += nca.path + Environment.NewLine;
|
||||
extraNcas += path + Environment.NewLine;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1019,7 +1018,7 @@ namespace Ryujinx.HLE.FileSystem.Content
|
||||
|
||||
lock (_lock)
|
||||
{
|
||||
var locationEnties = _locationEntries[StorageId.NandSystem];
|
||||
var locationEnties = _locationEntries[StorageId.BuiltInSystem];
|
||||
|
||||
foreach (var entry in locationEnties)
|
||||
{
|
82
Ryujinx.HLE/FileSystem/ContentPath.cs
Normal file
82
Ryujinx.HLE/FileSystem/ContentPath.cs
Normal file
@ -0,0 +1,82 @@
|
||||
using LibHac.Fs;
|
||||
using LibHac.Ncm;
|
||||
using Ryujinx.Common.Configuration;
|
||||
using System;
|
||||
|
||||
using static Ryujinx.HLE.FileSystem.VirtualFileSystem;
|
||||
using Path = System.IO.Path;
|
||||
|
||||
namespace Ryujinx.HLE.FileSystem
|
||||
{
|
||||
internal static class ContentPath
|
||||
{
|
||||
public const string SystemContent = "@SystemContent";
|
||||
public const string UserContent = "@UserContent";
|
||||
public const string SdCardContent = "@SdCardContent";
|
||||
public const string SdCard = "@Sdcard";
|
||||
public const string CalibFile = "@CalibFile";
|
||||
public const string Safe = "@Safe";
|
||||
public const string User = "@User";
|
||||
public const string System = "@System";
|
||||
public const string Host = "@Host";
|
||||
public const string GamecardApp = "@GcApp";
|
||||
public const string GamecardContents = "@GcS00000001";
|
||||
public const string GamecardUpdate = "@upp";
|
||||
public const string RegisteredUpdate = "@RegUpdate";
|
||||
|
||||
public const string Nintendo = "Nintendo";
|
||||
public const string Contents = "Contents";
|
||||
|
||||
public static string GetRealPath(VirtualFileSystem fileSystem, string switchContentPath)
|
||||
{
|
||||
return switchContentPath switch
|
||||
{
|
||||
SystemContent => Path.Combine(AppDataManager.BaseDirPath, SystemNandPath, Contents),
|
||||
UserContent => Path.Combine(AppDataManager.BaseDirPath, UserNandPath, Contents),
|
||||
SdCardContent => Path.Combine(fileSystem.GetSdCardPath(), Nintendo, Contents),
|
||||
System => Path.Combine(AppDataManager.BaseDirPath, SystemNandPath),
|
||||
User => Path.Combine(AppDataManager.BaseDirPath, UserNandPath),
|
||||
_ => throw new NotSupportedException($"Content Path \"`{switchContentPath}`\" is not supported.")
|
||||
};
|
||||
}
|
||||
|
||||
public static string GetContentPath(ContentStorageId contentStorageId)
|
||||
{
|
||||
return contentStorageId switch
|
||||
{
|
||||
ContentStorageId.System => SystemContent,
|
||||
ContentStorageId.User => UserContent,
|
||||
ContentStorageId.SdCard => SdCardContent,
|
||||
_ => throw new NotSupportedException($"Content Storage Id \"`{contentStorageId}`\" is not supported.")
|
||||
};
|
||||
}
|
||||
|
||||
public static string GetContentPath(StorageId storageId)
|
||||
{
|
||||
return storageId switch
|
||||
{
|
||||
StorageId.BuiltInSystem => SystemContent,
|
||||
StorageId.BuiltInUser => UserContent,
|
||||
StorageId.SdCard => SdCardContent,
|
||||
_ => throw new NotSupportedException($"Storage Id \"`{storageId}`\" is not supported.")
|
||||
};
|
||||
}
|
||||
|
||||
public static StorageId GetStorageId(string contentPathString)
|
||||
{
|
||||
return contentPathString.Split(':')[0] switch
|
||||
{
|
||||
SystemContent or
|
||||
System => StorageId.BuiltInSystem,
|
||||
UserContent or
|
||||
User => StorageId.BuiltInUser,
|
||||
SdCardContent => StorageId.SdCard,
|
||||
Host => StorageId.Host,
|
||||
GamecardApp or
|
||||
GamecardContents or
|
||||
GamecardUpdate => StorageId.GameCard,
|
||||
_ => StorageId.None
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -8,7 +8,6 @@ namespace Ryujinx.HLE.FileSystem
|
||||
{
|
||||
public class EncryptedFileSystemCreator : IEncryptedFileSystemCreator
|
||||
{
|
||||
|
||||
public Result Create(ref SharedRef<IFileSystem> outEncryptedFileSystem,
|
||||
ref SharedRef<IFileSystem> baseFileSystem, IEncryptedFileSystemCreator.KeyId idIndex,
|
||||
in EncryptionSeed encryptionSeed)
|
||||
@ -18,10 +17,10 @@ namespace Ryujinx.HLE.FileSystem
|
||||
return ResultFs.InvalidArgument.Log();
|
||||
}
|
||||
|
||||
// Todo: Reenable when AesXtsFileSystem is fixed
|
||||
// TODO: Reenable when AesXtsFileSystem is fixed.
|
||||
outEncryptedFileSystem = SharedRef<IFileSystem>.CreateMove(ref baseFileSystem);
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
using LibHac.FsSystem;
|
||||
|
||||
namespace Ryujinx.HLE.FileSystem.Content
|
||||
namespace Ryujinx.HLE.FileSystem
|
||||
{
|
||||
public struct LocationEntry
|
||||
{
|
@ -1,12 +0,0 @@
|
||||
namespace Ryujinx.HLE.FileSystem
|
||||
{
|
||||
enum SaveDataType : byte
|
||||
{
|
||||
SystemSaveData,
|
||||
SaveData,
|
||||
BcatDeliveryCacheStorage,
|
||||
DeviceSaveData,
|
||||
TemporaryStorage,
|
||||
CacheStorage
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
using Ryujinx.HLE.HOS.Services.Account.Acc;
|
||||
|
||||
namespace Ryujinx.HLE.FileSystem
|
||||
{
|
||||
struct SaveInfo
|
||||
{
|
||||
public ulong TitleId { get; private set; }
|
||||
public long SaveId { get; private set; }
|
||||
public SaveDataType SaveDataType { get; private set; }
|
||||
public SaveSpaceId SaveSpaceId { get; private set; }
|
||||
public UserId UserId { get; private set; }
|
||||
|
||||
public SaveInfo(
|
||||
ulong titleId,
|
||||
long saveId,
|
||||
SaveDataType saveDataType,
|
||||
SaveSpaceId saveSpaceId,
|
||||
UserId userId = new UserId())
|
||||
{
|
||||
TitleId = titleId;
|
||||
SaveId = saveId;
|
||||
SaveDataType = saveDataType;
|
||||
SaveSpaceId = saveSpaceId;
|
||||
UserId = userId;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
namespace Ryujinx.HLE.FileSystem
|
||||
{
|
||||
enum SaveSpaceId
|
||||
{
|
||||
NandSystem,
|
||||
NandUser,
|
||||
SdCard,
|
||||
TemporaryStorage
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
namespace Ryujinx.HLE.FileSystem
|
||||
{
|
||||
public enum StorageId
|
||||
{
|
||||
None,
|
||||
Host,
|
||||
GameCard,
|
||||
NandSystem,
|
||||
NandUser,
|
||||
SdCard
|
||||
}
|
||||
}
|
@ -1,8 +1,7 @@
|
||||
using Ryujinx.HLE.Utilities;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace Ryujinx.HLE.FileSystem.Content
|
||||
namespace Ryujinx.HLE.FileSystem
|
||||
{
|
||||
public class SystemVersion
|
||||
{
|
@ -13,7 +13,6 @@ using LibHac.Tools.Fs;
|
||||
using LibHac.Tools.FsSystem;
|
||||
using Ryujinx.Common.Configuration;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.HLE.FileSystem.Content;
|
||||
using Ryujinx.HLE.HOS;
|
||||
using System;
|
||||
using System.Buffers.Text;
|
||||
@ -28,20 +27,29 @@ namespace Ryujinx.HLE.FileSystem
|
||||
{
|
||||
public class VirtualFileSystem : IDisposable
|
||||
{
|
||||
public const string NandPath = AppDataManager.DefaultNandDir;
|
||||
public const string SdCardPath = AppDataManager.DefaultSdcardDir;
|
||||
public static string SafeNandPath = Path.Combine(AppDataManager.DefaultNandDir, "safe");
|
||||
public static string SystemNandPath = Path.Combine(AppDataManager.DefaultNandDir, "system");
|
||||
public static string UserNandPath = Path.Combine(AppDataManager.DefaultNandDir, "user");
|
||||
|
||||
public static string SafeNandPath = Path.Combine(NandPath, "safe");
|
||||
public static string SystemNandPath = Path.Combine(NandPath, "system");
|
||||
public static string UserNandPath = Path.Combine(NandPath, "user");
|
||||
public KeySet KeySet { get; private set; }
|
||||
public EmulatedGameCard GameCard { get; private set; }
|
||||
public EmulatedSdCard SdCard { get; private set; }
|
||||
public ModLoader ModLoader { get; private set; }
|
||||
public Stream RomFs { get; private set; }
|
||||
|
||||
private static bool _isInitialized = false;
|
||||
|
||||
public KeySet KeySet { get; private set; }
|
||||
public EmulatedGameCard GameCard { get; private set; }
|
||||
public EmulatedSdCard SdCard { get; private set; }
|
||||
public static VirtualFileSystem CreateInstance()
|
||||
{
|
||||
if (_isInitialized)
|
||||
{
|
||||
throw new InvalidOperationException("VirtualFileSystem can only be instantiated once!");
|
||||
}
|
||||
|
||||
public ModLoader ModLoader { get; private set; }
|
||||
_isInitialized = true;
|
||||
|
||||
return new VirtualFileSystem();
|
||||
}
|
||||
|
||||
private VirtualFileSystem()
|
||||
{
|
||||
@ -49,8 +57,6 @@ namespace Ryujinx.HLE.FileSystem
|
||||
ModLoader = new ModLoader(); // Should only be created once
|
||||
}
|
||||
|
||||
public Stream RomFs { get; private set; }
|
||||
|
||||
public void LoadRomFs(string fileName)
|
||||
{
|
||||
RomFs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
|
||||
@ -79,7 +85,7 @@ namespace Ryujinx.HLE.FileSystem
|
||||
|
||||
string fullPath = Path.GetFullPath(Path.Combine(basePath, fileName));
|
||||
|
||||
if (!fullPath.StartsWith(GetBasePath()))
|
||||
if (!fullPath.StartsWith(AppDataManager.BaseDirPath))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@ -87,14 +93,8 @@ namespace Ryujinx.HLE.FileSystem
|
||||
return fullPath;
|
||||
}
|
||||
|
||||
internal string GetBasePath() => AppDataManager.BaseDirPath;
|
||||
internal string GetSdCardPath() => MakeFullPath(SdCardPath);
|
||||
public string GetNandPath() => MakeFullPath(NandPath);
|
||||
|
||||
public string GetFullPartitionPath(string partitionPath)
|
||||
{
|
||||
return MakeFullPath(partitionPath);
|
||||
}
|
||||
internal string GetSdCardPath() => MakeFullPath(AppDataManager.DefaultSdcardDir);
|
||||
public string GetNandPath() => MakeFullPath(AppDataManager.DefaultNandDir);
|
||||
|
||||
public string SwitchPathToSystemPath(string switchPath)
|
||||
{
|
||||
@ -110,7 +110,7 @@ namespace Ryujinx.HLE.FileSystem
|
||||
|
||||
public string SystemPathToSwitchPath(string systemPath)
|
||||
{
|
||||
string baseSystemPath = GetBasePath() + Path.DirectorySeparatorChar;
|
||||
string baseSystemPath = AppDataManager.BaseDirPath + Path.DirectorySeparatorChar;
|
||||
|
||||
if (systemPath.StartsWith(baseSystemPath))
|
||||
{
|
||||
@ -136,8 +136,7 @@ namespace Ryujinx.HLE.FileSystem
|
||||
switch (path)
|
||||
{
|
||||
case ContentPath.SdCard:
|
||||
case "@Sdcard":
|
||||
path = SdCardPath;
|
||||
path = AppDataManager.DefaultSdcardDir;
|
||||
break;
|
||||
case ContentPath.User:
|
||||
path = UserNandPath;
|
||||
@ -146,7 +145,7 @@ namespace Ryujinx.HLE.FileSystem
|
||||
path = SystemNandPath;
|
||||
break;
|
||||
case ContentPath.SdCardContent:
|
||||
path = Path.Combine(SdCardPath, "Nintendo", "Contents");
|
||||
path = Path.Combine(AppDataManager.DefaultSdcardDir, "Nintendo", "Contents");
|
||||
break;
|
||||
case ContentPath.UserContent:
|
||||
path = Path.Combine(UserNandPath, "Contents");
|
||||
@ -156,27 +155,19 @@ namespace Ryujinx.HLE.FileSystem
|
||||
break;
|
||||
}
|
||||
|
||||
string fullPath = Path.Combine(GetBasePath(), path);
|
||||
string fullPath = Path.Combine(AppDataManager.BaseDirPath, path);
|
||||
|
||||
if (isDirectory)
|
||||
if (isDirectory && !Directory.Exists(fullPath))
|
||||
{
|
||||
if (!Directory.Exists(fullPath))
|
||||
{
|
||||
Directory.CreateDirectory(fullPath);
|
||||
}
|
||||
Directory.CreateDirectory(fullPath);
|
||||
}
|
||||
|
||||
return fullPath;
|
||||
}
|
||||
|
||||
public DriveInfo GetDrive()
|
||||
{
|
||||
return new DriveInfo(Path.GetPathRoot(GetBasePath()));
|
||||
}
|
||||
|
||||
public void InitializeFsServer(LibHac.Horizon horizon, out HorizonClient fsServerClient)
|
||||
{
|
||||
LocalFileSystem serverBaseFs = new LocalFileSystem(GetBasePath());
|
||||
LocalFileSystem serverBaseFs = new LocalFileSystem(AppDataManager.BaseDirPath);
|
||||
|
||||
fsServerClient = horizon.CreatePrivilegedHorizonClient();
|
||||
var fsServer = new FileSystemServer(fsServerClient);
|
||||
@ -505,7 +496,7 @@ namespace Ryujinx.HLE.FileSystem
|
||||
|
||||
bool canFixBySaveDataId = extraData.Attribute.StaticSaveDataId == 0 && info.StaticSaveDataId != 0;
|
||||
|
||||
bool hasEmptyOwnerId = extraData.OwnerId == 0 && info.Type != LibHac.Fs.SaveDataType.System;
|
||||
bool hasEmptyOwnerId = extraData.OwnerId == 0 && info.Type != SaveDataType.System;
|
||||
|
||||
if (!canFixByProgramId && !canFixBySaveDataId && !hasEmptyOwnerId)
|
||||
{
|
||||
@ -523,7 +514,7 @@ namespace Ryujinx.HLE.FileSystem
|
||||
|
||||
// The rest of the extra data can't be created from the save data info.
|
||||
// On user saves the owner ID will almost certainly be the same as the program ID.
|
||||
if (info.Type != LibHac.Fs.SaveDataType.System)
|
||||
if (info.Type != SaveDataType.System)
|
||||
{
|
||||
extraData.OwnerId = info.ProgramId.Value;
|
||||
}
|
||||
@ -580,11 +571,6 @@ namespace Ryujinx.HLE.FileSystem
|
||||
}
|
||||
};
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
RomFs?.Dispose();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
@ -594,20 +580,8 @@ namespace Ryujinx.HLE.FileSystem
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
Unload();
|
||||
RomFs?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public static VirtualFileSystem CreateInstance()
|
||||
{
|
||||
if (_isInitialized)
|
||||
{
|
||||
throw new InvalidOperationException("VirtualFileSystem can only be instantiated once!");
|
||||
}
|
||||
|
||||
_isInitialized = true;
|
||||
|
||||
return new VirtualFileSystem();
|
||||
}
|
||||
}
|
||||
}
|
@ -3,7 +3,6 @@ using Ryujinx.Audio.Integration;
|
||||
using Ryujinx.Common.Configuration;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.HLE.FileSystem;
|
||||
using Ryujinx.HLE.FileSystem.Content;
|
||||
using Ryujinx.HLE.HOS;
|
||||
using Ryujinx.HLE.HOS.Services.Account.Acc;
|
||||
using Ryujinx.HLE.HOS.SystemState;
|
||||
|
@ -2,10 +2,10 @@
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.Fsa;
|
||||
using LibHac.FsSystem;
|
||||
using LibHac.Ncm;
|
||||
using LibHac.Tools.FsSystem;
|
||||
using LibHac.Tools.FsSystem.NcaUtils;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.HLE.FileSystem;
|
||||
using Ryujinx.HLE.HOS.Services.Am.AppletAE;
|
||||
using Ryujinx.HLE.HOS.SystemState;
|
||||
using System;
|
||||
@ -106,7 +106,7 @@ namespace Ryujinx.HLE.HOS.Applets.Error
|
||||
|
||||
private string GetMessageText(uint module, uint description, string key)
|
||||
{
|
||||
string binaryTitleContentPath = _horizon.ContentManager.GetInstalledContentPath(ErrorMessageBinaryTitleId, StorageId.NandSystem, NcaContentType.Data);
|
||||
string binaryTitleContentPath = _horizon.ContentManager.GetInstalledContentPath(ErrorMessageBinaryTitleId, StorageId.BuiltInSystem, NcaContentType.Data);
|
||||
|
||||
using (LibHac.Fs.IStorage ncaFileStream = new LocalStorage(_horizon.Device.FileSystem.SwitchPathToSystemPath(binaryTitleContentPath), FileAccess.Read, FileMode.Open))
|
||||
{
|
||||
|
@ -10,7 +10,7 @@ using Ryujinx.Audio.Integration;
|
||||
using Ryujinx.Audio.Output;
|
||||
using Ryujinx.Audio.Renderer.Device;
|
||||
using Ryujinx.Audio.Renderer.Server;
|
||||
using Ryujinx.HLE.FileSystem.Content;
|
||||
using Ryujinx.HLE.FileSystem;
|
||||
using Ryujinx.HLE.HOS.Kernel;
|
||||
using Ryujinx.HLE.HOS.Kernel.Memory;
|
||||
using Ryujinx.HLE.HOS.Kernel.Process;
|
||||
@ -238,6 +238,7 @@ namespace Ryujinx.HLE.HOS
|
||||
SurfaceFlinger = new SurfaceFlinger(device);
|
||||
|
||||
InitializeAudioRenderer();
|
||||
InitializeServices();
|
||||
}
|
||||
|
||||
private void InitializeAudioRenderer()
|
||||
@ -288,7 +289,7 @@ namespace Ryujinx.HLE.HOS
|
||||
AudioManager.Start();
|
||||
}
|
||||
|
||||
public void InitializeServices()
|
||||
private void InitializeServices()
|
||||
{
|
||||
SmServer = new ServerBase(KernelContext, "SmServer", () => new IUserInterface(KernelContext));
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
using Ryujinx.HLE.FileSystem;
|
||||
using LibHac.Ncm;
|
||||
|
||||
namespace Ryujinx.HLE.HOS.Services.Arp
|
||||
{
|
||||
@ -20,7 +20,7 @@ namespace Ryujinx.HLE.HOS.Services.Arp
|
||||
{
|
||||
TitleId = 0x00,
|
||||
Version = 0x00,
|
||||
BaseGameStorageId = (byte)StorageId.NandSystem,
|
||||
BaseGameStorageId = (byte)StorageId.BuiltInSystem,
|
||||
UpdateGameStorageId = (byte)StorageId.None
|
||||
};
|
||||
}
|
||||
@ -35,7 +35,7 @@ namespace Ryujinx.HLE.HOS.Services.Arp
|
||||
{
|
||||
TitleId = context.Device.Application.TitleId,
|
||||
Version = 0x00,
|
||||
BaseGameStorageId = (byte)StorageId.NandSystem,
|
||||
BaseGameStorageId = (byte)StorageId.BuiltInSystem,
|
||||
UpdateGameStorageId = (byte)StorageId.None
|
||||
};
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ using LibHac;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.Shim;
|
||||
using LibHac.FsSrv;
|
||||
using LibHac.FsSrv.Impl;
|
||||
using LibHac.FsSystem;
|
||||
using LibHac.Ncm;
|
||||
@ -19,7 +18,6 @@ using static Ryujinx.HLE.Utilities.StringUtils;
|
||||
using IFileSystem = LibHac.FsSrv.Sf.IFileSystem;
|
||||
using IStorage = LibHac.FsSrv.Sf.IStorage;
|
||||
using RightsId = LibHac.Fs.RightsId;
|
||||
using StorageId = Ryujinx.HLE.FileSystem.StorageId;
|
||||
|
||||
namespace Ryujinx.HLE.HOS.Services.Fs
|
||||
{
|
||||
|
@ -55,9 +55,11 @@ namespace Ryujinx.HLE.HOS.Services.Hid
|
||||
_storage = storage;
|
||||
|
||||
SharedMemory = SharedMemory.Create();
|
||||
|
||||
InitDevices();
|
||||
}
|
||||
|
||||
public void InitDevices()
|
||||
private void InitDevices()
|
||||
{
|
||||
DebugPad = new DebugPadDevice(_device, true);
|
||||
Touchscreen = new TouchDevice(_device, true);
|
||||
|
@ -1,4 +1,4 @@
|
||||
using Ryujinx.HLE.FileSystem;
|
||||
using LibHac.Ncm;
|
||||
using Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager;
|
||||
|
||||
namespace Ryujinx.HLE.HOS.Services.Ncm.Lr
|
||||
|
@ -1,6 +1,6 @@
|
||||
using LibHac.FsSystem;
|
||||
using LibHac.Ncm;
|
||||
using Ryujinx.HLE.FileSystem;
|
||||
using Ryujinx.HLE.FileSystem.Content;
|
||||
using System.Text;
|
||||
|
||||
using static Ryujinx.HLE.Utilities.StringUtils;
|
||||
|
@ -1,5 +1,5 @@
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.HLE.FileSystem;
|
||||
using LibHac.Ncm;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.HLE.HOS.Services.Arp;
|
||||
using Ryujinx.HLE.HOS.Services.Nim.ShopServiceAccessServerInterface;
|
||||
|
||||
|
@ -1,8 +1,24 @@
|
||||
namespace Ryujinx.HLE.HOS.Services.Nim.Ntc
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.HLE.HOS.Services.Nim.Ntc.StaticService;
|
||||
|
||||
namespace Ryujinx.HLE.HOS.Services.Nim.Ntc
|
||||
{
|
||||
[Service("ntc")]
|
||||
class IStaticService : IpcService
|
||||
{
|
||||
public IStaticService(ServiceCtx context) { }
|
||||
|
||||
[CommandHipc(0)]
|
||||
// OpenEnsureNetworkClockAvailabilityService(u64) -> object<nn::ntc::detail::service::IEnsureNetworkClockAvailabilityService>
|
||||
public ResultCode CreateAsyncInterface(ServiceCtx context)
|
||||
{
|
||||
ulong unknown = context.RequestData.ReadUInt64();
|
||||
|
||||
MakeObject(context, new IEnsureNetworkClockAvailabilityService(context));
|
||||
|
||||
Logger.Stub?.PrintStub(LogClass.ServiceNtc, new { unknown });
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.HLE.HOS.Ipc;
|
||||
using Ryujinx.HLE.HOS.Kernel.Common;
|
||||
using Ryujinx.HLE.HOS.Kernel.Threading;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.HLE.HOS.Services.Nim.Ntc.StaticService
|
||||
{
|
||||
class IEnsureNetworkClockAvailabilityService : IpcService
|
||||
{
|
||||
private KEvent _finishNotificationEvent;
|
||||
private ResultCode _taskResultCode;
|
||||
|
||||
public IEnsureNetworkClockAvailabilityService(ServiceCtx context)
|
||||
{
|
||||
_finishNotificationEvent = new KEvent(context.Device.System.KernelContext);
|
||||
_taskResultCode = ResultCode.Success;
|
||||
|
||||
// NOTE: The service starts a thread that polls Nintendo NTP server and syncs the time with it.
|
||||
// Additionnally it gets and uses some settings too:
|
||||
// autonomic_correction_interval_seconds, autonomic_correction_failed_retry_interval_seconds,
|
||||
// autonomic_correction_immediate_try_count_max, autonomic_correction_immediate_try_interval_milliseconds
|
||||
}
|
||||
|
||||
[CommandHipc(0)]
|
||||
// StartTask()
|
||||
public ResultCode StartTask(ServiceCtx context)
|
||||
{
|
||||
if (!context.Device.Configuration.EnableInternetAccess)
|
||||
{
|
||||
return (ResultCode)Time.ResultCode.NetworkTimeNotAvailable;
|
||||
}
|
||||
|
||||
// NOTE: Since we don't support the Nintendo NTP server, we can signal the event now to confirm the update task is done.
|
||||
_finishNotificationEvent.ReadableEvent.Signal();
|
||||
|
||||
Logger.Stub?.PrintStub(LogClass.ServiceNtc);
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandHipc(1)]
|
||||
// GetFinishNotificationEvent() -> handle<copy>
|
||||
public ResultCode GetFinishNotificationEvent(ServiceCtx context)
|
||||
{
|
||||
if (context.Process.HandleTable.GenerateHandle(_finishNotificationEvent.ReadableEvent, out int finishNotificationEventHandle) != KernelResult.Success)
|
||||
{
|
||||
throw new InvalidOperationException("Out of handles!");
|
||||
}
|
||||
|
||||
context.Response.HandleDesc = IpcHandleDesc.MakeCopy(finishNotificationEventHandle);
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandHipc(2)]
|
||||
// GetResult()
|
||||
public ResultCode GetResult(ServiceCtx context)
|
||||
{
|
||||
return _taskResultCode;
|
||||
}
|
||||
|
||||
[CommandHipc(3)]
|
||||
// Cancel()
|
||||
public ResultCode Cancel(ServiceCtx context)
|
||||
{
|
||||
// NOTE: The update task should be canceled here.
|
||||
_finishNotificationEvent.ReadableEvent.Signal();
|
||||
|
||||
_taskResultCode = (ResultCode)Time.ResultCode.NetworkTimeTaskCanceled;
|
||||
|
||||
Logger.Stub?.PrintStub(LogClass.ServiceNtc);
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
}
|
||||
}
|
@ -232,7 +232,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
|
||||
ulong virtualAddress = arguments.Offset + arguments.BufferOffset;
|
||||
|
||||
physicalAddress += arguments.BufferOffset;
|
||||
_asContext.Gmm.Map(physicalAddress, virtualAddress, arguments.MappingSize);
|
||||
_asContext.Gmm.Map(physicalAddress, virtualAddress, arguments.MappingSize, (PteKind)arguments.Kind);
|
||||
|
||||
return NvInternalResult.Success;
|
||||
}
|
||||
@ -282,7 +282,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
|
||||
{
|
||||
if (_asContext.ValidateFixedBuffer(arguments.Offset, size, pageSize))
|
||||
{
|
||||
_asContext.Gmm.Map(physicalAddress, arguments.Offset, size);
|
||||
_asContext.Gmm.Map(physicalAddress, arguments.Offset, size, (PteKind)arguments.Kind);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -301,7 +301,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
|
||||
_memoryAllocator.AllocateRange(va, size, freeAddressStartPosition);
|
||||
}
|
||||
|
||||
_asContext.Gmm.Map(physicalAddress, va, size);
|
||||
_asContext.Gmm.Map(physicalAddress, va, size, (PteKind)arguments.Kind);
|
||||
arguments.Offset = va;
|
||||
}
|
||||
|
||||
@ -366,26 +366,30 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
|
||||
|
||||
for (int index = 0; index < arguments.Length; index++)
|
||||
{
|
||||
ulong mapOffs = (ulong)arguments[index].MapOffset << 16;
|
||||
ulong gpuVa = (ulong)arguments[index].GpuOffset << 16;
|
||||
ulong size = (ulong)arguments[index].Pages << 16;
|
||||
ref RemapArguments argument = ref arguments[index];
|
||||
ulong gpuVa = (ulong)argument.GpuOffset << 16;
|
||||
ulong size = (ulong)argument.Pages << 16;
|
||||
int nvmapHandle = argument.NvMapHandle;
|
||||
|
||||
if (arguments[index].NvMapHandle == 0)
|
||||
if (nvmapHandle == 0)
|
||||
{
|
||||
gmm.Unmap(gpuVa, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
NvMapHandle map = NvMapDeviceFile.GetMapFromHandle(Owner, arguments[index].NvMapHandle);
|
||||
ulong mapOffs = (ulong)argument.MapOffset << 16;
|
||||
PteKind kind = (PteKind)argument.Kind;
|
||||
|
||||
NvMapHandle map = NvMapDeviceFile.GetMapFromHandle(Owner, nvmapHandle);
|
||||
|
||||
if (map == null)
|
||||
{
|
||||
Logger.Warning?.Print(LogClass.ServiceNv, $"Invalid NvMap handle 0x{arguments[index].NvMapHandle:x8}!");
|
||||
Logger.Warning?.Print(LogClass.ServiceNv, $"Invalid NvMap handle 0x{nvmapHandle:x8}!");
|
||||
|
||||
return NvInternalResult.InvalidInput;
|
||||
}
|
||||
|
||||
gmm.Map(mapOffs + map.Address, gpuVa, size);
|
||||
gmm.Map(mapOffs + map.Address, gpuVa, size, kind);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -251,7 +251,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel
|
||||
if (va != NvMemoryAllocator.PteUnmapped && va <= uint.MaxValue && (va + (uint)map.Size) <= uint.MaxValue)
|
||||
{
|
||||
_host1xContext.MemoryAllocator.AllocateRange(va, (uint)map.Size, freeAddressStartPosition);
|
||||
_host1xContext.Smmu.Map(map.Address, va, (uint)map.Size);
|
||||
_host1xContext.Smmu.Map(map.Address, va, (uint)map.Size, PteKind.Pitch); // FIXME: This should not use the GMMU.
|
||||
map.DmaMapAddress = va;
|
||||
}
|
||||
else
|
||||
|
@ -45,7 +45,7 @@ namespace Ryujinx.HLE.HOS.Services.Olsc
|
||||
return ResultCode.NullArgument;
|
||||
}
|
||||
|
||||
if (_saveDataBackupSettingDatabase[userId])
|
||||
if (_saveDataBackupSettingDatabase.TryGetValue(userId, out bool enabled) && enabled)
|
||||
{
|
||||
context.ResponseData.Write((byte)1); // TODO: Determine value.
|
||||
}
|
||||
|
@ -2,11 +2,11 @@ using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.Fsa;
|
||||
using LibHac.FsSystem;
|
||||
using LibHac.Ncm;
|
||||
using LibHac.Tools.FsSystem;
|
||||
using LibHac.Tools.FsSystem.NcaUtils;
|
||||
using Ryujinx.HLE.Exceptions;
|
||||
using Ryujinx.HLE.FileSystem;
|
||||
using Ryujinx.HLE.FileSystem.Content;
|
||||
using Ryujinx.HLE.HOS.Kernel.Memory;
|
||||
using Ryujinx.HLE.HOS.Services.Sdb.Pl.Types;
|
||||
using System;
|
||||
@ -63,7 +63,7 @@ namespace Ryujinx.HLE.HOS.Services.Sdb.Pl
|
||||
{
|
||||
if (contentManager.TryGetFontTitle(name, out ulong fontTitle) && contentManager.TryGetFontFilename(name, out string fontFilename))
|
||||
{
|
||||
string contentPath = contentManager.GetInstalledContentPath(fontTitle, StorageId.NandSystem, NcaContentType.Data);
|
||||
string contentPath = contentManager.GetInstalledContentPath(fontTitle, StorageId.BuiltInSystem, NcaContentType.Data);
|
||||
string fontPath = _device.FileSystem.SwitchPathToSystemPath(contentPath);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(fontPath))
|
||||
|
@ -3,9 +3,9 @@ using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.Fsa;
|
||||
using LibHac.FsSystem;
|
||||
using LibHac.Ncm;
|
||||
using LibHac.Tools.FsSystem.NcaUtils;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.HLE.FileSystem;
|
||||
using Ryujinx.HLE.HOS.SystemState;
|
||||
using Ryujinx.HLE.Utilities;
|
||||
using System;
|
||||
@ -290,7 +290,7 @@ namespace Ryujinx.HLE.HOS.Services.Settings
|
||||
{
|
||||
const ulong SystemVersionTitleId = 0x0100000000000809;
|
||||
|
||||
string contentPath = device.System.ContentManager.GetInstalledContentPath(SystemVersionTitleId, StorageId.NandSystem, NcaContentType.Data);
|
||||
string contentPath = device.System.ContentManager.GetInstalledContentPath(SystemVersionTitleId, StorageId.BuiltInSystem, NcaContentType.Data);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(contentPath))
|
||||
{
|
||||
|
@ -1,5 +1,4 @@
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.HLE.FileSystem.Content;
|
||||
using Ryujinx.HLE.FileSystem;
|
||||
using Ryujinx.HLE.HOS.Kernel.Common;
|
||||
using Ryujinx.HLE.HOS.Services.Spl.Types;
|
||||
|
||||
|
@ -3,13 +3,13 @@ using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.Fsa;
|
||||
using LibHac.FsSystem;
|
||||
using LibHac.Ncm;
|
||||
using LibHac.Tools.FsSystem;
|
||||
using LibHac.Tools.FsSystem.NcaUtils;
|
||||
using Ryujinx.Common.Configuration;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.HLE.Exceptions;
|
||||
using Ryujinx.HLE.FileSystem;
|
||||
using Ryujinx.HLE.FileSystem.Content;
|
||||
using Ryujinx.HLE.HOS.Services.Ssl.Types;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@ -82,7 +82,7 @@ namespace Ryujinx.HLE.HOS.Services.Ssl
|
||||
|
||||
public string GetCertStoreTitleContentPath()
|
||||
{
|
||||
return _contentManager.GetInstalledContentPath(CertStoreTitleId, StorageId.NandSystem, NcaContentType.Data);
|
||||
return _contentManager.GetInstalledContentPath(CertStoreTitleId, StorageId.BuiltInSystem, NcaContentType.Data);
|
||||
}
|
||||
|
||||
public bool HasCertStoreTitle()
|
||||
|
@ -7,16 +7,18 @@
|
||||
|
||||
Success = 0,
|
||||
|
||||
TimeServiceNotInitialized = (0 << ErrorCodeShift) | ModuleId,
|
||||
PermissionDenied = (1 << ErrorCodeShift) | ModuleId,
|
||||
TimeMismatch = (102 << ErrorCodeShift) | ModuleId,
|
||||
UninitializedClock = (103 << ErrorCodeShift) | ModuleId,
|
||||
TimeNotFound = (200 << ErrorCodeShift) | ModuleId,
|
||||
Overflow = (201 << ErrorCodeShift) | ModuleId,
|
||||
LocationNameTooLong = (801 << ErrorCodeShift) | ModuleId,
|
||||
OutOfRange = (902 << ErrorCodeShift) | ModuleId,
|
||||
TimeZoneConversionFailed = (903 << ErrorCodeShift) | ModuleId,
|
||||
TimeZoneNotFound = (989 << ErrorCodeShift) | ModuleId,
|
||||
NotImplemented = (990 << ErrorCodeShift) | ModuleId,
|
||||
TimeServiceNotInitialized = (0 << ErrorCodeShift) | ModuleId,
|
||||
PermissionDenied = (1 << ErrorCodeShift) | ModuleId,
|
||||
TimeMismatch = (102 << ErrorCodeShift) | ModuleId,
|
||||
UninitializedClock = (103 << ErrorCodeShift) | ModuleId,
|
||||
TimeNotFound = (200 << ErrorCodeShift) | ModuleId,
|
||||
Overflow = (201 << ErrorCodeShift) | ModuleId,
|
||||
LocationNameTooLong = (801 << ErrorCodeShift) | ModuleId,
|
||||
OutOfRange = (902 << ErrorCodeShift) | ModuleId,
|
||||
TimeZoneConversionFailed = (903 << ErrorCodeShift) | ModuleId,
|
||||
TimeZoneNotFound = (989 << ErrorCodeShift) | ModuleId,
|
||||
NotImplemented = (990 << ErrorCodeShift) | ModuleId,
|
||||
NetworkTimeNotAvailable = (1000 << ErrorCodeShift) | ModuleId,
|
||||
NetworkTimeTaskCanceled = (1003 << ErrorCodeShift) | ModuleId,
|
||||
}
|
||||
}
|
||||
|
@ -3,12 +3,12 @@ using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.Fsa;
|
||||
using LibHac.FsSystem;
|
||||
using LibHac.Ncm;
|
||||
using LibHac.Tools.FsSystem;
|
||||
using LibHac.Tools.FsSystem.NcaUtils;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.HLE.Exceptions;
|
||||
using Ryujinx.HLE.FileSystem;
|
||||
using Ryujinx.HLE.FileSystem.Content;
|
||||
using Ryujinx.HLE.HOS.Services.Time.Clock;
|
||||
using Ryujinx.HLE.Utilities;
|
||||
using System;
|
||||
@ -241,7 +241,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
|
||||
public string GetTimeZoneBinaryTitleContentPath()
|
||||
{
|
||||
return _contentManager.GetInstalledContentPath(TimeZoneBinaryTitleId, StorageId.NandSystem, NcaContentType.Data);
|
||||
return _contentManager.GetInstalledContentPath(TimeZoneBinaryTitleId, StorageId.BuiltInSystem, NcaContentType.Data);
|
||||
}
|
||||
|
||||
public bool HasTimeZoneBinaryTitle()
|
||||
|
@ -13,27 +13,17 @@ namespace Ryujinx.HLE
|
||||
{
|
||||
public class Switch : IDisposable
|
||||
{
|
||||
public HLEConfiguration Configuration { get; }
|
||||
|
||||
public HLEConfiguration Configuration { get; }
|
||||
public IHardwareDeviceDriver AudioDeviceDriver { get; }
|
||||
|
||||
internal MemoryBlock Memory { get; }
|
||||
|
||||
public GpuContext Gpu { get; }
|
||||
|
||||
public VirtualFileSystem FileSystem => Configuration.VirtualFileSystem;
|
||||
|
||||
public Horizon System { get; }
|
||||
|
||||
public ApplicationLoader Application { get; }
|
||||
|
||||
public PerformanceStatistics Statistics { get; }
|
||||
|
||||
public Hid Hid { get; }
|
||||
|
||||
public TamperMachine TamperMachine { get; }
|
||||
|
||||
public IHostUiHandler UiHandler { get; }
|
||||
public MemoryBlock Memory { get; }
|
||||
public GpuContext Gpu { get; }
|
||||
public VirtualFileSystem FileSystem { get; }
|
||||
public Horizon System { get; }
|
||||
public ApplicationLoader Application { get; }
|
||||
public PerformanceStatistics Statistics { get; }
|
||||
public Hid Hid { get; }
|
||||
public TamperMachine TamperMachine { get; }
|
||||
public IHostUiHandler UiHandler { get; }
|
||||
|
||||
public bool EnableDeviceVsync { get; set; } = true;
|
||||
|
||||
@ -55,47 +45,27 @@ namespace Ryujinx.HLE
|
||||
}
|
||||
|
||||
Configuration = configuration;
|
||||
FileSystem = Configuration.VirtualFileSystem;
|
||||
UiHandler = Configuration.HostUiHandler;
|
||||
|
||||
UiHandler = configuration.HostUiHandler;
|
||||
AudioDeviceDriver = new CompatLayerHardwareDeviceDriver(Configuration.AudioDeviceDriver);
|
||||
Memory = new MemoryBlock(Configuration.MemoryConfiguration.ToDramSize(), MemoryAllocationFlags.Reserve);
|
||||
Gpu = new GpuContext(Configuration.GpuRenderer);
|
||||
System = new Horizon(this);
|
||||
Statistics = new PerformanceStatistics();
|
||||
Hid = new Hid(this, System.HidStorage);
|
||||
Application = new ApplicationLoader(this);
|
||||
TamperMachine = new TamperMachine();
|
||||
|
||||
AudioDeviceDriver = new CompatLayerHardwareDeviceDriver(configuration.AudioDeviceDriver);
|
||||
|
||||
Memory = new MemoryBlock(configuration.MemoryConfiguration.ToDramSize(), MemoryAllocationFlags.Reserve);
|
||||
|
||||
Gpu = new GpuContext(configuration.GpuRenderer);
|
||||
|
||||
System = new Horizon(this);
|
||||
System.InitializeServices();
|
||||
|
||||
Statistics = new PerformanceStatistics();
|
||||
|
||||
Hid = new Hid(this, System.HidStorage);
|
||||
Hid.InitDevices();
|
||||
|
||||
Application = new ApplicationLoader(this);
|
||||
|
||||
TamperMachine = new TamperMachine();
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
private void Initialize()
|
||||
{
|
||||
System.State.SetLanguage(Configuration.SystemLanguage);
|
||||
|
||||
System.State.SetRegion(Configuration.Region);
|
||||
|
||||
EnableDeviceVsync = Configuration.EnableVsync;
|
||||
|
||||
System.State.DockedMode = Configuration.EnableDockedMode;
|
||||
|
||||
EnableDeviceVsync = Configuration.EnableVsync;
|
||||
System.State.DockedMode = Configuration.EnableDockedMode;
|
||||
System.PerformanceState.PerformanceMode = System.State.DockedMode ? PerformanceMode.Boost : PerformanceMode.Default;
|
||||
|
||||
System.EnablePtc = Configuration.EnablePtc;
|
||||
|
||||
System.FsIntegrityCheckLevel = Configuration.FsIntegrityCheckLevel;
|
||||
|
||||
System.GlobalAccessLogMode = Configuration.FsGlobalAccessLogMode;
|
||||
System.EnablePtc = Configuration.EnablePtc;
|
||||
System.FsIntegrityCheckLevel = Configuration.FsIntegrityCheckLevel;
|
||||
System.GlobalAccessLogMode = Configuration.FsGlobalAccessLogMode;
|
||||
}
|
||||
|
||||
public void LoadCart(string exeFsDir, string romFsFile = null)
|
||||
@ -132,7 +102,6 @@ namespace Ryujinx.HLE
|
||||
{
|
||||
Gpu.ProcessShaderCacheQueue();
|
||||
Gpu.Renderer.PreFrame();
|
||||
|
||||
Gpu.GPFifo.DispatchCalls();
|
||||
}
|
||||
|
||||
@ -182,9 +151,9 @@ namespace Ryujinx.HLE
|
||||
{
|
||||
System.Dispose();
|
||||
AudioDeviceDriver.Dispose();
|
||||
FileSystem.Unload();
|
||||
FileSystem.Dispose();
|
||||
Memory.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -20,7 +20,6 @@ using Ryujinx.Graphics.OpenGL;
|
||||
using Ryujinx.Headless.SDL2.OpenGL;
|
||||
using Ryujinx.HLE;
|
||||
using Ryujinx.HLE.FileSystem;
|
||||
using Ryujinx.HLE.FileSystem.Content;
|
||||
using Ryujinx.HLE.HOS;
|
||||
using Ryujinx.HLE.HOS.Services.Account.Acc;
|
||||
using Ryujinx.Input;
|
||||
@ -29,7 +28,6 @@ using Ryujinx.Input.SDL2;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
|
||||
|
@ -188,7 +188,7 @@ namespace Ryujinx.Memory.Tests
|
||||
Assert.False(alignedAfterTriggers);
|
||||
}
|
||||
|
||||
[Test, Timeout(1000)]
|
||||
[Test, Explicit, Timeout(1000)]
|
||||
public void Multithreading()
|
||||
{
|
||||
// Multithreading sanity test
|
||||
|
@ -1,5 +1,5 @@
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.HLE.FileSystem.Content;
|
||||
using Ryujinx.HLE.FileSystem;
|
||||
using Ryujinx.Ui.Widgets;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
@ -1,18 +1,10 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using ARMeilleure.Translation;
|
||||
using ARMeilleure.Translation;
|
||||
using ARMeilleure.Translation.PTC;
|
||||
|
||||
using Gtk;
|
||||
|
||||
using LibHac.Common;
|
||||
using LibHac.Common.Keys;
|
||||
using LibHac.FsSystem;
|
||||
using LibHac.Ncm;
|
||||
using LibHac.Ns;
|
||||
using LibHac.Tools.FsSystem;
|
||||
using Ryujinx.Audio.Backends.Dummy;
|
||||
@ -29,7 +21,6 @@ using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.GAL.Multithreading;
|
||||
using Ryujinx.Graphics.OpenGL;
|
||||
using Ryujinx.HLE.FileSystem;
|
||||
using Ryujinx.HLE.FileSystem.Content;
|
||||
using Ryujinx.HLE.HOS;
|
||||
using Ryujinx.HLE.HOS.Services.Account.Acc;
|
||||
using Ryujinx.HLE.HOS.SystemState;
|
||||
@ -42,9 +33,14 @@ using Ryujinx.Ui.Applet;
|
||||
using Ryujinx.Ui.Helper;
|
||||
using Ryujinx.Ui.Widgets;
|
||||
using Ryujinx.Ui.Windows;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using GUI = Gtk.Builder.ObjectAttribute;
|
||||
|
||||
using PtcLoadingState = ARMeilleure.Translation.PTC.PtcLoadingState;
|
||||
using ShaderCacheLoadingState = Ryujinx.Graphics.Gpu.Shader.ShaderCacheState;
|
||||
|
||||
@ -1283,7 +1279,7 @@ namespace Ryujinx.Ui
|
||||
|
||||
private void Load_Mii_Edit_Applet(object sender, EventArgs args)
|
||||
{
|
||||
string contentPath = _contentManager.GetInstalledContentPath(0x0100000000001009, StorageId.NandSystem, NcaContentType.Program);
|
||||
string contentPath = _contentManager.GetInstalledContentPath(0x0100000000001009, StorageId.BuiltInSystem, NcaContentType.Program);
|
||||
|
||||
LoadApplication(contentPath);
|
||||
}
|
||||
|
@ -3,10 +3,10 @@ using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.Fsa;
|
||||
using LibHac.FsSystem;
|
||||
using LibHac.Ncm;
|
||||
using LibHac.Tools.FsSystem;
|
||||
using LibHac.Tools.FsSystem.NcaUtils;
|
||||
using Ryujinx.HLE.FileSystem;
|
||||
using Ryujinx.HLE.FileSystem.Content;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.Formats.Png;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
@ -115,7 +115,7 @@ namespace Ryujinx.Ui.Windows
|
||||
return;
|
||||
}
|
||||
|
||||
string contentPath = contentManager.GetInstalledContentPath(0x010000000000080A, StorageId.NandSystem, NcaContentType.Data);
|
||||
string contentPath = contentManager.GetInstalledContentPath(0x010000000000080A, StorageId.BuiltInSystem, NcaContentType.Data);
|
||||
string avatarPath = virtualFileSystem.SwitchPathToSystemPath(contentPath);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(avatarPath))
|
||||
|
@ -105,9 +105,9 @@ namespace Ryujinx.Ui.Windows
|
||||
|
||||
#pragma warning restore CS0649, IDE0044
|
||||
|
||||
public SettingsWindow(MainWindow parent, VirtualFileSystem virtualFileSystem, HLE.FileSystem.Content.ContentManager contentManager) : this(parent, new Builder("Ryujinx.Ui.Windows.SettingsWindow.glade"), virtualFileSystem, contentManager) { }
|
||||
public SettingsWindow(MainWindow parent, VirtualFileSystem virtualFileSystem, ContentManager contentManager) : this(parent, new Builder("Ryujinx.Ui.Windows.SettingsWindow.glade"), virtualFileSystem, contentManager) { }
|
||||
|
||||
private SettingsWindow(MainWindow parent, Builder builder, VirtualFileSystem virtualFileSystem, HLE.FileSystem.Content.ContentManager contentManager) : base(builder.GetObject("_settingsWin").Handle)
|
||||
private SettingsWindow(MainWindow parent, Builder builder, VirtualFileSystem virtualFileSystem, ContentManager contentManager) : base(builder.GetObject("_settingsWin").Handle)
|
||||
{
|
||||
Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.Resources.Logo_Ryujinx.png");
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
using Gtk;
|
||||
using Ryujinx.HLE.FileSystem;
|
||||
using Ryujinx.HLE.FileSystem.Content;
|
||||
using Ryujinx.HLE.HOS.Services.Account.Acc;
|
||||
using Ryujinx.Ui.Widgets;
|
||||
using SixLabors.ImageSharp;
|
||||
@ -12,7 +11,7 @@ using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Image = SixLabors.ImageSharp.Image;
|
||||
using Image = SixLabors.ImageSharp.Image;
|
||||
using UserId = Ryujinx.HLE.HOS.Services.Account.Acc.UserId;
|
||||
|
||||
namespace Ryujinx.Ui.Windows
|
||||
|
Reference in New Issue
Block a user