ryujinx/Ryujinx.HLE/Switch.cs
gdkchan 4d02a2d2c0
New NVDEC and VIC implementation (#1384)
* Initial NVDEC and VIC implementation

* Update FFmpeg.AutoGen to 4.3.0

* Add nvdec dependencies for Windows

* Unify some VP9 structures

* Rename VP9 structure fields

* Improvements to Video API

* XML docs for Common.Memory

* Remove now unused or redundant overloads from MemoryAccessor

* NVDEC UV surface read/write scalar paths

* Add FIXME comments about hacky things/stuff that will need to be fixed in the future

* Cleaned up VP9 memory allocation

* Remove some debug logs

* Rename some VP9 structs

* Remove unused struct

* No need to compile Ryujinx.Graphics.Host1x with unsafe anymore

* Name AsyncWorkQueue threads to make debugging easier

* Make Vp9PictureInfo a ref struct

* LayoutConverter no longer needs the depth argument (broken by rebase)

* Pooling of VP9 buffers, plus fix a memory leak on VP9

* Really wish VS could rename projects properly...

* Address feedback

* Remove using

* Catch OperationCanceledException

* Add licensing informations

* Add THIRDPARTY.md to release too

Co-authored-by: Thog <me@thog.eu>
2020-07-12 05:07:01 +02:00

187 lines
5.2 KiB
C#

using LibHac.FsSystem;
using Ryujinx.Audio;
using Ryujinx.Configuration;
using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.Gpu;
using Ryujinx.Graphics.Host1x;
using Ryujinx.Graphics.Nvdec;
using Ryujinx.Graphics.Vic;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.FileSystem.Content;
using Ryujinx.HLE.HOS;
using Ryujinx.HLE.HOS.Services;
using Ryujinx.HLE.HOS.Services.Hid;
using Ryujinx.HLE.HOS.SystemState;
using Ryujinx.Memory;
using System;
namespace Ryujinx.HLE
{
public class Switch : IDisposable
{
public IAalOutput AudioOut { get; private set; }
internal MemoryBlock Memory { get; private set; }
public GpuContext Gpu { get; private set; }
internal Host1xDevice Host1x { get; }
public VirtualFileSystem FileSystem { get; private set; }
public Horizon System { get; private set; }
public ApplicationLoader Application { get; }
public PerformanceStatistics Statistics { get; private set; }
public Hid Hid { get; private set; }
public bool EnableDeviceVsync { get; set; } = true;
public Switch(VirtualFileSystem fileSystem, ContentManager contentManager, IRenderer renderer, IAalOutput audioOut)
{
if (renderer == null)
{
throw new ArgumentNullException(nameof(renderer));
}
if (audioOut == null)
{
throw new ArgumentNullException(nameof(audioOut));
}
AudioOut = audioOut;
Memory = new MemoryBlock(1UL << 32);
Gpu = new GpuContext(renderer);
Host1x = new Host1xDevice(Gpu.Synchronization);
var nvdec = new NvdecDevice(Gpu.MemoryManager);
var vic = new VicDevice(Gpu.MemoryManager);
Host1x.RegisterDevice(ClassId.Nvdec, nvdec);
Host1x.RegisterDevice(ClassId.Vic, vic);
nvdec.FrameDecoded += (FrameDecodedEventArgs e) =>
{
// FIXME:
// Figure out what is causing frame ordering issues on H264.
// For now this is needed as workaround.
if (e.CodecId == CodecId.H264)
{
vic.SetSurfaceOverride(e.LumaOffset, e.ChromaOffset, 0);
}
else
{
vic.DisableSurfaceOverride();
}
};
FileSystem = fileSystem;
System = new Horizon(this, contentManager);
Statistics = new PerformanceStatistics();
Hid = new Hid(this, System.HidBaseAddress);
Hid.InitDevices();
Application = new ApplicationLoader(this, fileSystem, contentManager);
}
public void Initialize()
{
System.State.SetLanguage((SystemLanguage)ConfigurationState.Instance.System.Language.Value);
System.State.SetRegion((RegionCode)ConfigurationState.Instance.System.Region.Value);
EnableDeviceVsync = ConfigurationState.Instance.Graphics.EnableVsync;
System.State.DockedMode = ConfigurationState.Instance.System.EnableDockedMode;
if (ConfigurationState.Instance.System.EnableMulticoreScheduling)
{
System.EnableMultiCoreScheduling();
}
System.EnablePtc = ConfigurationState.Instance.System.EnablePtc;
System.FsIntegrityCheckLevel = GetIntegrityCheckLevel();
System.GlobalAccessLogMode = ConfigurationState.Instance.System.FsGlobalAccessLogMode;
ServiceConfiguration.IgnoreMissingServices = ConfigurationState.Instance.System.IgnoreMissingServices;
}
public static IntegrityCheckLevel GetIntegrityCheckLevel()
{
return ConfigurationState.Instance.System.EnableFsIntegrityChecks
? IntegrityCheckLevel.ErrorOnInvalid
: IntegrityCheckLevel.None;
}
public void LoadCart(string exeFsDir, string romFsFile = null)
{
Application.LoadCart(exeFsDir, romFsFile);
}
public void LoadXci(string xciFile)
{
Application.LoadXci(xciFile);
}
public void LoadNca(string ncaFile)
{
Application.LoadNca(ncaFile);
}
public void LoadNsp(string nspFile)
{
Application.LoadNsp(nspFile);
}
public void LoadProgram(string fileName)
{
Application.LoadProgram(fileName);
}
public bool WaitFifo()
{
return Gpu.DmaPusher.WaitForCommands();
}
public void ProcessFrame()
{
Gpu.DmaPusher.DispatchCalls();
}
public void PresentFrame(Action swapBuffersCallback)
{
Gpu.Window.Present(swapBuffersCallback);
}
public void DisposeGpu()
{
Gpu.Dispose();
}
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
System.Dispose();
Host1x.Dispose();
AudioOut.Dispose();
FileSystem.Unload();
Memory.Dispose();
}
}
}
}