diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2018-06-23 21:39:25 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-06-23 21:39:25 -0300 |
| commit | e7559f128f99058774a8d53aa45213b51c085e76 (patch) | |
| tree | 42d367bfb4248b19cf2ce55439d24437bbbd2ccb /Ryujinx.HLE | |
| parent | 69697957e6406235d512a89d9144c160fe7efbfd (diff) | |
Small OpenGL Renderer refactoring (#177)
* Call OpenGL functions directly, remove the pfifo thread, some refactoring
* Fix PerformanceStatistics calculating the wrong host fps, remove wait event on PFIFO as this wasn't exactly was causing the freezes (may replace with an exception later)
* Organized the Gpu folder a bit more, renamed a few things, address PR feedback
* Make PerformanceStatistics thread safe
* Remove unused constant
* Use unlimited update rate for better pref
Diffstat (limited to 'Ryujinx.HLE')
| -rw-r--r-- | Ryujinx.HLE/Gpu/Engines/INvGpuEngine.cs (renamed from Ryujinx.HLE/Gpu/INvGpuEngine.cs) | 4 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Engines/MacroInterpreter.cs (renamed from Ryujinx.HLE/Gpu/MacroInterpreter.cs) | 19 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Engines/NvGpuEngine.cs (renamed from Ryujinx.HLE/Gpu/NvGpuEngine.cs) | 2 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Engines/NvGpuEngine2d.cs (renamed from Ryujinx.HLE/Gpu/NvGpuEngine2d.cs) | 22 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Engines/NvGpuEngine2dReg.cs (renamed from Ryujinx.HLE/Gpu/NvGpuEngine2dReg.cs) | 2 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs (renamed from Ryujinx.HLE/Gpu/NvGpuEngine3d.cs) | 106 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Engines/NvGpuEngine3dReg.cs (renamed from Ryujinx.HLE/Gpu/NvGpuEngine3dReg.cs) | 2 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Engines/NvGpuEngineDma.cs (renamed from Ryujinx.HLE/Gpu/NvGpuEngineDma.cs) | 4 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Engines/NvGpuEngineDmaReg.cs (renamed from Ryujinx.HLE/Gpu/NvGpuEngineDmaReg.cs) | 2 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Engines/NvGpuFifo.cs (renamed from Ryujinx.HLE/Gpu/NvGpuFifo.cs) | 3 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Engines/NvGpuFifoMeth.cs (renamed from Ryujinx.HLE/Gpu/NvGpuFifoMeth.cs) | 2 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Engines/NvGpuMethod.cs (renamed from Ryujinx.HLE/Gpu/NvGpuMethod.cs) | 4 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Exceptions/GpuException.cs | 11 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Exceptions/GpuExceptionHelper.cs | 12 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Memory/NvGpuBufferType.cs (renamed from Ryujinx.HLE/Gpu/NvGpuBufferType.cs) | 2 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Memory/NvGpuPBEntry.cs (renamed from Ryujinx.HLE/Gpu/NvGpuPBEntry.cs) | 2 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Memory/NvGpuPushBuffer.cs (renamed from Ryujinx.HLE/Gpu/NvGpuPushBuffer.cs) | 2 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Memory/NvGpuVmm.cs (renamed from Ryujinx.HLE/Gpu/NvGpuVmm.cs) | 2 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Memory/NvGpuVmmCache.cs (renamed from Ryujinx.HLE/Gpu/NvGpuVmmCache.cs) | 2 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/NvGpu.cs | 22 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Texture/BlockLinearSwizzle.cs (renamed from Ryujinx.HLE/Gpu/BlockLinearSwizzle.cs) | 2 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Texture/ISwizzle.cs (renamed from Ryujinx.HLE/Gpu/ISwizzle.cs) | 2 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Texture/LinearSwizzle.cs (renamed from Ryujinx.HLE/Gpu/LinearSwizzle.cs) | 2 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Texture/TextureFactory.cs (renamed from Ryujinx.HLE/Gpu/TextureFactory.cs) | 5 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Texture/TextureHelper.cs (renamed from Ryujinx.HLE/Gpu/TextureHelper.cs) | 5 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Texture/TextureInfo.cs (renamed from Ryujinx.HLE/Gpu/Texture.cs) | 8 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Texture/TextureReader.cs (renamed from Ryujinx.HLE/Gpu/TextureReader.cs) | 22 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Texture/TextureSwizzle.cs (renamed from Ryujinx.HLE/Gpu/TextureSwizzle.cs) | 2 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Texture/TextureWriter.cs (renamed from Ryujinx.HLE/Gpu/TextureWriter.cs) | 22 | ||||
| -rw-r--r-- | Ryujinx.HLE/Loaders/Npdm/ACI0.cs | 3 | ||||
| -rw-r--r-- | Ryujinx.HLE/Loaders/Npdm/ACID.cs | 3 | ||||
| -rw-r--r-- | Ryujinx.HLE/Loaders/Npdm/Npdm.cs | 6 | ||||
| -rw-r--r-- | Ryujinx.HLE/Loaders/Npdm/ServiceAccessControl.cs | 5 | ||||
| -rw-r--r-- | Ryujinx.HLE/OsHle/Services/Nv/NvGpuAS/NvGpuASIoctl.cs | 2 | ||||
| -rw-r--r-- | Ryujinx.HLE/OsHle/Services/Nv/NvHostChannel/NvHostChannelIoctl.cs | 2 | ||||
| -rw-r--r-- | Ryujinx.HLE/OsHle/Services/Nv/NvMap/NvMapIoctl.cs | 2 | ||||
| -rw-r--r-- | Ryujinx.HLE/OsHle/Services/Vi/NvFlinger.cs | 11 | ||||
| -rw-r--r-- | Ryujinx.HLE/PerformanceStatistics.cs | 135 | ||||
| -rw-r--r-- | Ryujinx.HLE/Switch.cs | 5 |
39 files changed, 277 insertions, 194 deletions
diff --git a/Ryujinx.HLE/Gpu/INvGpuEngine.cs b/Ryujinx.HLE/Gpu/Engines/INvGpuEngine.cs index 62307f58..068878a9 100644 --- a/Ryujinx.HLE/Gpu/INvGpuEngine.cs +++ b/Ryujinx.HLE/Gpu/Engines/INvGpuEngine.cs @@ -1,4 +1,6 @@ -namespace Ryujinx.HLE.Gpu +using Ryujinx.HLE.Gpu.Memory; + +namespace Ryujinx.HLE.Gpu.Engines { interface INvGpuEngine { diff --git a/Ryujinx.HLE/Gpu/MacroInterpreter.cs b/Ryujinx.HLE/Gpu/Engines/MacroInterpreter.cs index c333046a..aef2eb4c 100644 --- a/Ryujinx.HLE/Gpu/MacroInterpreter.cs +++ b/Ryujinx.HLE/Gpu/Engines/MacroInterpreter.cs @@ -1,10 +1,16 @@ +using Ryujinx.HLE.Gpu.Exceptions; +using Ryujinx.HLE.Gpu.Memory; using System; using System.Collections.Generic; -namespace Ryujinx.HLE.Gpu +namespace Ryujinx.HLE.Gpu.Engines { class MacroInterpreter { + private const int MaxCallCountPerRun = 500; + + private int CallCount; + private enum AssignmentOperation { IgnoreAndFetch = 0, @@ -96,6 +102,8 @@ namespace Ryujinx.HLE.Gpu MethIncr = 0; Carry = false; + + CallCount = 0; } private bool Step(NvGpuVmm Vmm, int[] Mme) @@ -407,6 +415,15 @@ namespace Ryujinx.HLE.Gpu private void Send(NvGpuVmm Vmm, int Value) { + //This is an artificial limit that prevents excessive calls + //to VertexEndGl since that triggers rendering, and in the + //case that something is bugged and causes an absurd amount of + //draw calls, this prevents the system from freezing (and throws instead). + if (MethAddr == 0x585 && ++CallCount > MaxCallCountPerRun) + { + GpuExceptionHelper.ThrowCallCoundExceeded(); + } + NvGpuPBEntry PBEntry = new NvGpuPBEntry(MethAddr, 0, Value); Engine.CallMethod(Vmm, PBEntry); diff --git a/Ryujinx.HLE/Gpu/NvGpuEngine.cs b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine.cs index 41697ed6..f9d6342c 100644 --- a/Ryujinx.HLE/Gpu/NvGpuEngine.cs +++ b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.Gpu +namespace Ryujinx.HLE.Gpu.Engines { enum NvGpuEngine { diff --git a/Ryujinx.HLE/Gpu/NvGpuEngine2d.cs b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine2d.cs index 15667eeb..f150b3f5 100644 --- a/Ryujinx.HLE/Gpu/NvGpuEngine2d.cs +++ b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine2d.cs @@ -1,7 +1,9 @@ using Ryujinx.Graphics.Gal; +using Ryujinx.HLE.Gpu.Memory; +using Ryujinx.HLE.Gpu.Texture; using System.Collections.Generic; -namespace Ryujinx.HLE.Gpu +namespace Ryujinx.HLE.Gpu.Engines { class NvGpuEngine2d : INvGpuEngine { @@ -75,19 +77,19 @@ namespace Ryujinx.HLE.Gpu int DstBlockHeight = 1 << ((DstBlkDim >> 4) & 0xf); - long Tag = Vmm.GetPhysicalAddress(MakeInt64From2xInt32(NvGpuEngine2dReg.SrcAddress)); + long Key = Vmm.GetPhysicalAddress(MakeInt64From2xInt32(NvGpuEngine2dReg.SrcAddress)); long SrcAddress = MakeInt64From2xInt32(NvGpuEngine2dReg.SrcAddress); long DstAddress = MakeInt64From2xInt32(NvGpuEngine2dReg.DstAddress); - bool IsFbTexture = Gpu.Engine3d.IsFrameBufferPosition(Tag); + bool IsFbTexture = Gpu.Engine3d.IsFrameBufferPosition(Key); if (IsFbTexture && DstLinear) { DstSwizzle = TextureSwizzle.BlockLinear; } - Texture DstTexture = new Texture( + TextureInfo DstTexture = new TextureInfo( DstAddress, DstWidth, DstHeight, @@ -103,7 +105,7 @@ namespace Ryujinx.HLE.Gpu SrcWidth = 1280; SrcHeight = 720; - Gpu.Renderer.GetFrameBufferData(Tag, (byte[] Buffer) => + Gpu.Renderer.FrameBuffer.GetBufferData(Key, (byte[] Buffer) => { CopyTexture( Vmm, @@ -129,11 +131,11 @@ namespace Ryujinx.HLE.Gpu } private void CopyTexture( - NvGpuVmm Vmm, - Texture Texture, - byte[] Buffer, - int Width, - int Height) + NvGpuVmm Vmm, + TextureInfo Texture, + byte[] Buffer, + int Width, + int Height) { TextureWriter.Write(Vmm, Texture, Buffer, Width, Height); } diff --git a/Ryujinx.HLE/Gpu/NvGpuEngine2dReg.cs b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine2dReg.cs index 1039e368..29d66d46 100644 --- a/Ryujinx.HLE/Gpu/NvGpuEngine2dReg.cs +++ b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine2dReg.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.Gpu +namespace Ryujinx.HLE.Gpu.Engines { enum NvGpuEngine2dReg { diff --git a/Ryujinx.HLE/Gpu/NvGpuEngine3d.cs b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs index 6d03e6b8..02461d5d 100644 --- a/Ryujinx.HLE/Gpu/NvGpuEngine3d.cs +++ b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs @@ -1,8 +1,10 @@ using Ryujinx.Graphics.Gal; +using Ryujinx.HLE.Gpu.Memory; +using Ryujinx.HLE.Gpu.Texture; using System; using System.Collections.Generic; -namespace Ryujinx.HLE.Gpu +namespace Ryujinx.HLE.Gpu.Engines { class NvGpuEngine3d : INvGpuEngine { @@ -73,13 +75,13 @@ namespace Ryujinx.HLE.Gpu { SetFrameBuffer(Vmm, 0); - long[] Tags = UploadShaders(Vmm); + long[] Keys = UploadShaders(Vmm); - Gpu.Renderer.BindProgram(); + Gpu.Renderer.Shader.BindProgram(); SetAlphaBlending(); - UploadTextures(Vmm, Tags); + UploadTextures(Vmm, Keys); UploadUniforms(Vmm); UploadVertexArrays(Vmm); } @@ -113,13 +115,13 @@ namespace Ryujinx.HLE.Gpu //Note: Using the Width/Height results seems to give incorrect results. //Maybe the size of all frame buffers is hardcoded to screen size? This seems unlikely. - Gpu.Renderer.CreateFrameBuffer(PA, 1280, 720); - Gpu.Renderer.BindFrameBuffer(PA); + Gpu.Renderer.FrameBuffer.Create(PA, 1280, 720); + Gpu.Renderer.FrameBuffer.Bind(PA); } private long[] UploadShaders(NvGpuVmm Vmm) { - long[] Tags = new long[5]; + long[] Keys = new long[5]; long BasePosition = MakeInt64From2xInt32(NvGpuEngine3dReg.ShaderAddress); @@ -136,14 +138,14 @@ namespace Ryujinx.HLE.Gpu continue; } - long Tag = BasePosition + (uint)Offset; + long Key = BasePosition + (uint)Offset; GalShaderType ShaderType = GetTypeFromProgram(Index); - Tags[(int)ShaderType] = Tag; + Keys[(int)ShaderType] = Key; - Gpu.Renderer.CreateShader(Vmm, Tag, ShaderType); - Gpu.Renderer.BindShader(Tag); + Gpu.Renderer.Shader.Create(Vmm, Key, ShaderType); + Gpu.Renderer.Shader.Bind(Key); } int RawSX = ReadRegister(NvGpuEngine3dReg.ViewportScaleX); @@ -155,9 +157,9 @@ namespace Ryujinx.HLE.Gpu float SignX = MathF.Sign(SX); float SignY = MathF.Sign(SY); - Gpu.Renderer.SetUniform2F(GalConsts.FlipUniformName, SignX, SignY); + Gpu.Renderer.Shader.SetFlip(SignX, SignY); - return Tags; + return Keys; } private static GalShaderType GetTypeFromProgram(int Program) @@ -180,7 +182,14 @@ namespace Ryujinx.HLE.Gpu //TODO: Support independent blend properly. bool Enable = (ReadRegister(NvGpuEngine3dReg.IBlendNEnable) & 1) != 0; - Gpu.Renderer.SetBlendEnable(Enable); + if (Enable) + { + Gpu.Renderer.Blend.Enable(); + } + else + { + Gpu.Renderer.Blend.Disable(); + } if (!Enable) { @@ -203,7 +212,7 @@ namespace Ryujinx.HLE.Gpu GalBlendFactor FuncSrcAlpha = (GalBlendFactor)ReadRegister(NvGpuEngine3dReg.IBlendNFuncSrcAlpha); GalBlendFactor FuncDstAlpha = (GalBlendFactor)ReadRegister(NvGpuEngine3dReg.IBlendNFuncDstAlpha); - Gpu.Renderer.SetBlendSeparate( + Gpu.Renderer.Blend.SetSeparate( EquationRgb, EquationAlpha, FuncSrcRgb, @@ -213,11 +222,11 @@ namespace Ryujinx.HLE.Gpu } else { - Gpu.Renderer.SetBlend(EquationRgb, FuncSrcRgb, FuncDstRgb); + Gpu.Renderer.Blend.Set(EquationRgb, FuncSrcRgb, FuncDstRgb); } } - private void UploadTextures(NvGpuVmm Vmm, long[] Tags) + private void UploadTextures(NvGpuVmm Vmm, long[] Keys) { long BaseShPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.ShaderAddress); @@ -227,15 +236,15 @@ namespace Ryujinx.HLE.Gpu //reserved for drawing the frame buffer. int TexIndex = 1; - for (int Index = 0; Index < Tags.Length; Index++) + for (int Index = 0; Index < Keys.Length; Index++) { - foreach (ShaderDeclInfo DeclInfo in Gpu.Renderer.GetTextureUsage(Tags[Index])) + foreach (ShaderDeclInfo DeclInfo in Gpu.Renderer.Shader.GetTextureUsage(Keys[Index])) { long Position = ConstBuffers[Index][TextureCbIndex].Position; UploadTexture(Vmm, Position, TexIndex, DeclInfo.Index); - Gpu.Renderer.SetUniform1(DeclInfo.Name, TexIndex); + Gpu.Renderer.Shader.EnsureTextureBinding(DeclInfo.Name, TexIndex); TexIndex++; } @@ -270,7 +279,7 @@ namespace Ryujinx.HLE.Gpu long TextureAddress = Vmm.ReadInt64(TicPosition + 4) & 0xffffffffffff; - long Tag = TextureAddress; + long Key = TextureAddress; TextureAddress = Vmm.GetPhysicalAddress(TextureAddress); @@ -280,7 +289,7 @@ namespace Ryujinx.HLE.Gpu //we shouldn't read anything from memory and bind //the frame buffer texture instead, since we're not //really writing anything to memory. - Gpu.Renderer.BindFrameBufferTexture(TextureAddress, TexIndex, Sampler); + Gpu.Renderer.FrameBuffer.BindTexture(TextureAddress, TexIndex); } else { @@ -288,22 +297,29 @@ namespace Ryujinx.HLE.Gpu long Size = (uint)TextureHelper.GetTextureSize(NewTexture); - if (Gpu.Renderer.TryGetCachedTexture(Tag, Size, out GalTexture Texture)) + bool HasCachedTexture = false; + + if (Gpu.Renderer.Texture.TryGetCachedTexture(Key, Size, out GalTexture Texture)) { - if (NewTexture.Equals(Texture) && !Vmm.IsRegionModified(Tag, Size, NvGpuBufferType.Texture)) + if (NewTexture.Equals(Texture) && !Vmm.IsRegionModified(Key, Size, NvGpuBufferType.Texture)) { - Gpu.Renderer.BindTexture(Tag, TexIndex); + Gpu.Renderer.Texture.Bind(Key, TexIndex); - return; + HasCachedTexture = true; } } - byte[] Data = TextureFactory.GetTextureData(Vmm, TicPosition); + if (!HasCachedTexture) + { + byte[] Data = TextureFactory.GetTextureData(Vmm, TicPosition); - Gpu.Renderer.SetTextureAndSampler(Tag, Data, NewTexture, Sampler); + Gpu.Renderer.Texture.Create(Key, Data, NewTexture); + } - Gpu.Renderer.BindTexture(Tag, TexIndex); + Gpu.Renderer.Texture.Bind(Key, TexIndex); } + + Gpu.Renderer.Texture.SetSampler(Sampler); } private void UploadUniforms(NvGpuVmm Vmm) @@ -331,7 +347,7 @@ namespace Ryujinx.HLE.Gpu { byte[] Data = Vmm.ReadBytes(Cb.Position, (uint)Cb.Size); - Gpu.Renderer.SetConstBuffer(BasePosition + (uint)Offset, Cbuf, Data); + Gpu.Renderer.Shader.SetConstBuffer(BasePosition + (uint)Offset, Cbuf, Data); } } } @@ -341,33 +357,33 @@ namespace Ryujinx.HLE.Gpu { long IndexPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.IndexArrayAddress); - int IndexSize = ReadRegister(NvGpuEngine3dReg.IndexArrayFormat); - int IndexFirst = ReadRegister(NvGpuEngine3dReg.IndexBatchFirst); - int IndexCount = ReadRegister(NvGpuEngine3dReg.IndexBatchCount); + int IndexEntryFmt = ReadRegister(NvGpuEngine3dReg.IndexArrayFormat); + int IndexFirst = ReadRegister(NvGpuEngine3dReg.IndexBatchFirst); + int IndexCount = ReadRegister(NvGpuEngine3dReg.IndexBatchCount); - GalIndexFormat IndexFormat = (GalIndexFormat)IndexSize; + GalIndexFormat IndexFormat = (GalIndexFormat)IndexEntryFmt; - IndexSize = 1 << IndexSize; + int IndexEntrySize = 1 << IndexEntryFmt; - if (IndexSize > 4) + if (IndexEntrySize > 4) { throw new InvalidOperationException(); } if (IndexCount != 0) { - int IbSize = IndexCount * IndexSize; + int IbSize = IndexCount * IndexEntrySize; - bool IboCached = Gpu.Renderer.IsIboCached(IndexPosition, (uint)IbSize); + bool IboCached = Gpu.Renderer.Rasterizer.IsIboCached(IndexPosition, (uint)IbSize); if (!IboCached || Vmm.IsRegionModified(IndexPosition, (uint)IbSize, NvGpuBufferType.Index)) { byte[] Data = Vmm.ReadBytes(IndexPosition, (uint)IbSize); - Gpu.Renderer.CreateIbo(IndexPosition, Data); + Gpu.Renderer.Rasterizer.CreateIbo(IndexPosition, Data); } - Gpu.Renderer.SetIndexArray(IndexPosition, IbSize, IndexFormat); + Gpu.Renderer.Rasterizer.SetIndexArray(IndexPosition, IbSize, IndexFormat); } List<GalVertexAttrib>[] Attribs = new List<GalVertexAttrib>[32]; @@ -429,27 +445,27 @@ namespace Ryujinx.HLE.Gpu VbSize = VertexCount * Stride; } - bool VboCached = Gpu.Renderer.IsVboCached(VertexPosition, VbSize); + bool VboCached = Gpu.Renderer.Rasterizer.IsVboCached(VertexPosition, VbSize); if (!VboCached || Vmm.IsRegionModified(VertexPosition, VbSize, NvGpuBufferType.Vertex)) { byte[] Data = Vmm.ReadBytes(VertexPosition, VbSize); - Gpu.Renderer.CreateVbo(VertexPosition, Data); + Gpu.Renderer.Rasterizer.CreateVbo(VertexPosition, Data); } - Gpu.Renderer.SetVertexArray(Index, Stride, VertexPosition, Attribs[Index].ToArray()); + Gpu.Renderer.Rasterizer.SetVertexArray(Index, Stride, VertexPosition, Attribs[Index].ToArray()); } GalPrimitiveType PrimType = (GalPrimitiveType)(PrimCtrl & 0xffff); if (IndexCount != 0) { - Gpu.Renderer.DrawElements(IndexPosition, IndexFirst, PrimType); + Gpu.Renderer.Rasterizer.DrawElements(IndexPosition, IndexFirst, PrimType); } else { - Gpu.Renderer.DrawArrays(VertexFirst, VertexCount, PrimType); + Gpu.Renderer.Rasterizer.DrawArrays(VertexFirst, VertexCount, PrimType); } } diff --git a/Ryujinx.HLE/Gpu/NvGpuEngine3dReg.cs b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3dReg.cs index e0de4777..de2b2eef 100644 --- a/Ryujinx.HLE/Gpu/NvGpuEngine3dReg.cs +++ b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3dReg.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.Gpu +namespace Ryujinx.HLE.Gpu.Engines { enum NvGpuEngine3dReg { diff --git a/Ryujinx.HLE/Gpu/NvGpuEngineDma.cs b/Ryujinx.HLE/Gpu/Engines/NvGpuEngineDma.cs index ed7819e9..7e355e8d 100644 --- a/Ryujinx.HLE/Gpu/NvGpuEngineDma.cs +++ b/Ryujinx.HLE/Gpu/Engines/NvGpuEngineDma.cs @@ -1,6 +1,8 @@ +using Ryujinx.HLE.Gpu.Memory; +using Ryujinx.HLE.Gpu.Texture; using System.Collections.Generic; -namespace Ryujinx.HLE.Gpu +namespace Ryujinx.HLE.Gpu.Engines { class NvGpuEngineDma : INvGpuEngine { diff --git a/Ryujinx.HLE/Gpu/NvGpuEngineDmaReg.cs b/Ryujinx.HLE/Gpu/Engines/NvGpuEngineDmaReg.cs index 55b404c5..835a822d 100644 --- a/Ryujinx.HLE/Gpu/NvGpuEngineDmaReg.cs +++ b/Ryujinx.HLE/Gpu/Engines/NvGpuEngineDmaReg.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.Gpu +namespace Ryujinx.HLE.Gpu.Engines { enum NvGpuEngineDmaReg { diff --git a/Ryujinx.HLE/Gpu/NvGpuFifo.cs b/Ryujinx.HLE/Gpu/Engines/NvGpuFifo.cs index 361c8bce..0bc682a7 100644 --- a/Ryujinx.HLE/Gpu/NvGpuFifo.cs +++ b/Ryujinx.HLE/Gpu/Engines/NvGpuFifo.cs @@ -1,6 +1,7 @@ +using Ryujinx.HLE.Gpu.Memory; using System.Collections.Concurrent; -namespace Ryujinx.HLE.Gpu +namespace Ryujinx.HLE.Gpu.Engines { class NvGpuFifo { diff --git a/Ryujinx.HLE/Gpu/NvGpuFifoMeth.cs b/Ryujinx.HLE/Gpu/Engines/NvGpuFifoMeth.cs index 247a7bfc..ffd179f2 100644 --- a/Ryujinx.HLE/Gpu/NvGpuFifoMeth.cs +++ b/Ryujinx.HLE/Gpu/Engines/NvGpuFifoMeth.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.Gpu +namespace Ryujinx.HLE.Gpu.Engines { enum NvGpuFifoMeth { diff --git a/Ryujinx.HLE/Gpu/NvGpuMethod.cs b/Ryujinx.HLE/Gpu/Engines/NvGpuMethod.cs index f7ff6647..04c92f2a 100644 --- a/Ryujinx.HLE/Gpu/NvGpuMethod.cs +++ b/Ryujinx.HLE/Gpu/Engines/NvGpuMethod.cs @@ -1,4 +1,6 @@ -namespace Ryujinx.HLE.Gpu +using Ryujinx.HLE.Gpu.Memory; + +namespace Ryujinx.HLE.Gpu.Engines { delegate void NvGpuMethod(NvGpuVmm Vmm, NvGpuPBEntry PBEntry); }
\ No newline at end of file diff --git a/Ryujinx.HLE/Gpu/Exceptions/GpuException.cs b/Ryujinx.HLE/Gpu/Exceptions/GpuException.cs new file mode 100644 index 00000000..c0bce5a5 --- /dev/null +++ b/Ryujinx.HLE/Gpu/Exceptions/GpuException.cs @@ -0,0 +1,11 @@ +using System; + +namespace Ryujinx.HLE.Gpu.Exceptions +{ + class GpuException : Exception + { + public GpuException() : base() { } + + public GpuException(string ExMsg) : base(ExMsg) { } + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/Gpu/Exceptions/GpuExceptionHelper.cs b/Ryujinx.HLE/Gpu/Exceptions/GpuExceptionHelper.cs new file mode 100644 index 00000000..aeab9a29 --- /dev/null +++ b/Ryujinx.HLE/Gpu/Exceptions/GpuExceptionHelper.cs @@ -0,0 +1,12 @@ +namespace Ryujinx.HLE.Gpu.Exceptions +{ + static class GpuExceptionHelper + { + private const string CallCountExceeded = "Method call count exceeded the limit allowed per run!"; + + public static void ThrowCallCoundExceeded() + { + throw new GpuException(CallCountExceeded); + } + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/Gpu/NvGpuBufferType.cs b/Ryujinx.HLE/Gpu/Memory/NvGpuBufferType.cs index a44a772d..7474aa33 100644 --- a/Ryujinx.HLE/Gpu/NvGpuBufferType.cs +++ b/Ryujinx.HLE/Gpu/Memory/NvGpuBufferType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.Gpu +namespace Ryujinx.HLE.Gpu.Memory { enum NvGpuBufferType { diff --git a/Ryujinx.HLE/Gpu/NvGpuPBEntry.cs b/Ryujinx.HLE/Gpu/Memory/NvGpuPBEntry.cs index 2cd663fe..aba89e3c 100644 --- a/Ryujinx.HLE/Gpu/NvGpuPBEntry.cs +++ b/Ryujinx.HLE/Gpu/Memory/NvGpuPBEntry.cs @@ -1,7 +1,7 @@ using System; using System.Collections.ObjectModel; -namespace Ryujinx.HLE.Gpu +namespace Ryujinx.HLE.Gpu.Memory { struct NvGpuPBEntry { diff --git a/Ryujinx.HLE/Gpu/NvGpuPushBuffer.cs b/Ryujinx.HLE/Gpu/Memory/NvGpuPushBuffer.cs index 2d4f0c1a..6121b3e6 100644 --- a/Ryujinx.HLE/Gpu/NvGpuPushBuffer.cs +++ b/Ryujinx.HLE/Gpu/Memory/NvGpuPushBuffer.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using System.IO; -namespace Ryujinx.HLE.Gpu +namespace Ryujinx.HLE.Gpu.Memory { static class NvGpuPushBuffer { diff --git a/Ryujinx.HLE/Gpu/NvGpuVmm.cs b/Ryujinx.HLE/Gpu/Memory/NvGpuVmm.cs index b0ba3e90..36f6406a 100644 --- a/Ryujinx.HLE/Gpu/NvGpuVmm.cs +++ b/Ryujinx.HLE/Gpu/Memory/NvGpuVmm.cs @@ -2,7 +2,7 @@ using ChocolArm64.Memory; using Ryujinx.Graphics.Gal; using System.Collections.Concurrent; -namespace Ryujinx.HLE.Gpu +namespace Ryujinx.HLE.Gpu.Memory { class NvGpuVmm : IAMemory, IGalMemory { diff --git a/Ryujinx.HLE/Gpu/NvGpuVmmCache.cs b/Ryujinx.HLE/Gpu/Memory/NvGpuVmmCache.cs index 38b25e4f..c7108f00 100644 --- a/Ryujinx.HLE/Gpu/NvGpuVmmCache.cs +++ b/Ryujinx.HLE/Gpu/Memory/NvGpuVmmCache.cs @@ -2,7 +2,7 @@ using ChocolArm64.Memory; using System; using System.Collections.Generic; -namespace Ryujinx.HLE.Gpu +namespace Ryujinx.HLE.Gpu.Memory { class NvGpuVmmCache { diff --git a/Ryujinx.HLE/Gpu/NvGpu.cs b/Ryujinx.HLE/Gpu/NvGpu.cs index 0301fcf2..625cb727 100644 --- a/Ryujinx.HLE/Gpu/NvGpu.cs +++ b/Ryujinx.HLE/Gpu/NvGpu.cs @@ -1,5 +1,5 @@ using Ryujinx.Graphics.Gal; -using System.Threading; +using Ryujinx.HLE.Gpu.Engines; namespace Ryujinx.HLE.Gpu { @@ -13,10 +13,6 @@ namespace Ryujinx.HLE.Gpu public NvGpuEngine3d Engine3d { get; private set; } public NvGpuEngineDma EngineDma { get; private set; } - private Thread FifoProcessing; - - private bool KeepRunning; - public NvGpu(IGalRenderer Renderer) { this.Renderer = Renderer; @@ -26,22 +22,6 @@ namespace Ryujinx.HLE.Gpu Engine2d = new NvGpuEngine2d(this); Engine3d = new NvGpuEngine3d(this); EngineDma = new NvGpuEngineDma(this); - - KeepRunning = true; - - FifoProcessing = new Thread(ProcessFifo); - - FifoProcessing.Start(); - } - - private void ProcessFifo() - { - while (KeepRunning) - { - Fifo.DispatchCalls(); - - Thread.Yield(); - } } } }
\ No newline at end of file diff --git a/Ryujinx.HLE/Gpu/BlockLinearSwizzle.cs b/Ryujinx.HLE/Gpu/Texture/BlockLinearSwizzle.cs index 366f5740..e66d7613 100644 --- a/Ryujinx.HLE/Gpu/BlockLinearSwizzle.cs +++ b/Ryujinx.HLE/Gpu/Texture/BlockLinearSwizzle.cs @@ -1,6 +1,6 @@ using System; -namespace Ryujinx.HLE.Gpu +namespace Ryujinx.HLE.Gpu.Texture { class BlockLinearSwizzle : ISwizzle { diff --git a/Ryujinx.HLE/Gpu/ISwizzle.cs b/Ryujinx.HLE/Gpu/Texture/ISwizzle.cs index 525707ba..222aab16 100644 --- a/Ryujinx.HLE/Gpu/ISwizzle.cs +++ b/Ryujinx.HLE/Gpu/Texture/ISwizzle.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.Gpu +namespace Ryujinx.HLE.Gpu.Texture { interface ISwizzle { diff --git a/Ryujinx.HLE/Gpu/LinearSwizzle.cs b/Ryujinx.HLE/Gpu/Texture/LinearSwizzle.cs index 995866ad..720f7832 100644 --- a/Ryujinx.HLE/Gpu/LinearSwizzle.cs +++ b/Ryujinx.HLE/Gpu/Texture/LinearSwizzle.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.Gpu +namespace Ryujinx.HLE.Gpu.Texture { class LinearSwizzle : ISwizzle { diff --git a/Ryujinx.HLE/Gpu/TextureFactory.cs b/Ryujinx.HLE/Gpu/Texture/TextureFactory.cs index 94c6eb18..9df0b600 100644 --- a/Ryujinx.HLE/Gpu/TextureFactory.cs +++ b/Ryujinx.HLE/Gpu/Texture/TextureFactory.cs @@ -1,7 +1,8 @@ using Ryujinx.Graphics.Gal; +using Ryujinx.HLE.Gpu.Memory; using System; -namespace Ryujinx.HLE.Gpu +namespace Ryujinx.HLE.Gpu.Texture { static class TextureFactory { @@ -61,7 +62,7 @@ namespace Ryujinx.HLE.Gpu int Width = (Tic[4] & 0xffff) + 1; int Height = (Tic[5] & 0xffff) + 1; - Texture Texture = new Texture( + TextureInfo Texture = new TextureInfo( TextureAddress, Width, Height, diff --git a/Ryujinx.HLE/Gpu/TextureHelper.cs b/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs index 237d87ab..ac8f75c5 100644 --- a/Ryujinx.HLE/Gpu/TextureHelper.cs +++ b/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs @@ -1,12 +1,13 @@ using ChocolArm64.Memory; using Ryujinx.Graphics.Gal; +using Ryujinx.HLE.Gpu.Memory; using System; -namespace Ryujinx.HLE.Gpu +namespace Ryujinx.HLE.Gpu.Texture { static class TextureHelper { - public static ISwizzle GetSwizzle(Texture Texture, int Width, int Bpp) + public static ISwizzle GetSwizzle(TextureInfo Texture, int Width, int Bpp) { switch (Texture.Swizzle) { diff --git a/Ryujinx.HLE/Gpu/Texture.cs b/Ryujinx.HLE/Gpu/Texture/TextureInfo.cs index 1de7f302..31784bbc 100644 --- a/Ryujinx.HLE/Gpu/Texture.cs +++ b/Ryujinx.HLE/Gpu/Texture/TextureInfo.cs @@ -1,8 +1,8 @@ using Ryujinx.Graphics.Gal; -namespace Ryujinx.HLE.Gpu +namespace Ryujinx.HLE.Gpu.Texture { - struct Texture + struct TextureInfo { public long Position { get; private set; } @@ -16,7 +16,7 @@ namespace Ryujinx.HLE.Gpu public GalTextureFormat Format { get; private set; } - public Texture( + public TextureInfo( long Position, int Width, int Height) @@ -34,7 +34,7 @@ namespace Ryujinx.HLE.Gpu Format = GalTextureFormat.A8B8G8R8; } - public Texture( + public TextureInfo( long Position, int Width, int Height, diff --git a/Ryujinx.HLE/Gpu/TextureReader.cs b/Ryujinx.HLE/Gpu/Texture/TextureReader.cs index 9e9ff783..48bf1a90 100644 --- a/Ryujinx.HLE/Gpu/TextureReader.cs +++ b/Ryujinx.HLE/Gpu/Texture/TextureReader.cs @@ -2,11 +2,11 @@ using ChocolArm64.Memory; using Ryujinx.Graphics.Gal; using System; -namespace Ryujinx.HLE.Gpu +namespace Ryujinx.HLE.Gpu.Texture { static class TextureReader { - public static byte[] Read(IAMemory Memory, Texture Texture) + public static byte[] Read(IAMemory Memory, TextureInfo Texture) { switch (Texture.Format) { @@ -31,7 +31,7 @@ namespace Ryujinx.HLE.Gpu throw new NotImplementedException(Texture.Format.ToString()); } - private unsafe static byte[] Read1Bpp(IAMemory Memory, Texture Texture) + private unsafe static byte[] Read1Bpp(IAMemory Memory, TextureInfo Texture) { int Width = Texture.Width; int Height = Texture.Height; @@ -64,7 +64,7 @@ namespace Ryujinx.HLE.Gpu return Output; } - private unsafe static byte[] Read5551(IAMemory Memory, Texture Texture) + private unsafe static byte[] Read5551(IAMemory Memory, TextureInfo Texture) { int Width = Texture.Width; int Height = Texture.Height; @@ -102,7 +102,7 @@ namespace Ryujinx.HLE.Gpu return Output; } - private unsafe static byte[] Read565(IAMemory Memory, Texture Texture) + private unsafe static byte[] Read565(IAMemory Memory, TextureInfo Texture) { int Width = Texture.Width; int Height = Texture.Height; @@ -139,7 +139,7 @@ namespace Ryujinx.HLE.Gpu return Output; } - private unsafe static byte[] Read2Bpp(IAMemory Memory, Texture Texture) + private unsafe static byte[] Read2Bpp(IAMemory Memory, TextureInfo Texture) { int Width = Texture.Width; int Height = Texture.Height; @@ -172,7 +172,7 @@ namespace Ryujinx.HLE.Gpu return Output; } - private unsafe static byte[] Read4Bpp(IAMemory Memory, Texture Texture) + private unsafe static byte[] Read4Bpp(IAMemory Memory, TextureInfo Texture) { int Width = Texture.Width; int Height = Texture.Height; @@ -205,7 +205,7 @@ namespace Ryujinx.HLE.Gpu return Output; } - private unsafe static byte[] Read8Bpp(IAMemory Memory, Texture Texture) + private unsafe static byte[] Read8Bpp(IAMemory Memory, TextureInfo Texture) { int Width = Texture.Width; int Height = Texture.Height; @@ -238,7 +238,7 @@ namespace Ryujinx.HLE.Gpu return Output; } - private unsafe static byte[] Read16Bpp(IAMemory Memory, Texture Texture) + private unsafe static byte[] Read16Bpp(IAMemory Memory, TextureInfo Texture) { int Width = Texture.Width; int Height = Texture.Height; @@ -273,7 +273,7 @@ namespace Ryujinx.HLE.Gpu return Output; } - private unsafe static byte[] Read8Bpt4x4(IAMemory Memory, Texture Texture) + private unsafe static byte[] Read8Bpt4x4(IAMemory Memory, TextureInfo Texture) { int Width = (Texture.Width + 3) / 4; int Height = (Texture.Height + 3) / 4; @@ -306,7 +306,7 @@ namespace Ryujinx.HLE.Gpu return Output; } - private unsafe static byte[] Read16Bpt4x4(IAMemory Memory, Texture Texture) + private unsafe static byte[] Read16Bpt4x4(IAMemory Memory, TextureInfo Texture) { int Width = (Texture.Width + 3) / 4; int Height = (Texture.Height + 3) / 4; diff --git a/Ryujinx.HLE/Gpu/TextureSwizzle.cs b/Ryujinx.HLE/Gpu/Texture/TextureSwizzle.cs index 5e32f4c7..076df97a 100644 --- a/Ryujinx.HLE/Gpu/TextureSwizzle.cs +++ b/Ryujinx.HLE/Gpu/Texture/TextureSwizzle.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.Gpu +namespace Ryujinx.HLE.Gpu.Texture { enum TextureSwizzle { diff --git a/Ryujinx.HLE/Gpu/TextureWriter.cs b/Ryujinx.HLE/Gpu/Texture/TextureWriter.cs index ad92961c..b64302a5 100644 --- a/Ryujinx.HLE/Gpu/TextureWriter.cs +++ b/Ryujinx.HLE/Gpu/Texture/TextureWriter.cs @@ -2,16 +2,16 @@ using ChocolArm64.Memory; using Ryujinx.Graphics.Gal; using System; -namespace Ryujinx.HLE.Gpu +namespace Ryujinx.HLE.Gpu.Texture { static class TextureWriter { public static void Write( - IAMemory Memory, - Texture Texture, - byte[] Data, - int Width, - int Height) + IAMemory Memory, + TextureInfo Texture, + byte[] Data, + int Width, + int Height) { switch (Texture.Format) { @@ -22,11 +22,11 @@ namespace Ryujinx.HLE.Gpu } private unsafe static void Write4Bpp( - IAMemory Memory, - Texture Texture, - byte[] Data, - int Width, - int Height) + IAMemory Memory, + TextureInfo Texture, + byte[] Data, + int Width, + int Height) { ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, Width, 4); diff --git a/Ryujinx.HLE/Loaders/Npdm/ACI0.cs b/Ryujinx.HLE/Loaders/Npdm/ACI0.cs index 1f1b810e..47b30a3c 100644 --- a/Ryujinx.HLE/Loaders/Npdm/ACI0.cs +++ b/Ryujinx.HLE/Loaders/Npdm/ACI0.cs @@ -1,4 +1,3 @@ -using Ryujinx.HLE.OsHle.Utilities;
using System;
using System.IO;
@@ -20,7 +19,7 @@ namespace Ryujinx.HLE.Loaders.Npdm public KernelAccessControl KernelAccessControl;
public const long ACI0Magic = 'A' << 0 | 'C' << 8 | 'I' << 16 | '0' << 24;
-
+
public ACI0(Stream ACI0Stream, int Offset)
{
ACI0Stream.Seek(Offset, SeekOrigin.Begin);
diff --git a/Ryujinx.HLE/Loaders/Npdm/ACID.cs b/Ryujinx.HLE/Loaders/Npdm/ACID.cs index d0f0acdd..09768a92 100644 --- a/Ryujinx.HLE/Loaders/Npdm/ACID.cs +++ b/Ryujinx.HLE/Loaders/Npdm/ACID.cs @@ -1,4 +1,3 @@ -using Ryujinx.HLE.OsHle.Utilities;
using System;
using System.IO;
@@ -24,7 +23,7 @@ namespace Ryujinx.HLE.Loaders.Npdm public FSAccessControl FSAccessControl;
public ServiceAccessControl ServiceAccessControl;
public KernelAccessControl KernelAccessControl;
-
+
public const long ACIDMagic = 'A' << 0 | 'C' << 8 | 'I' << 16 | 'D' << 24;
public ACID(Stream ACIDStream, int Offset)
diff --git a/Ryujinx.HLE/Loaders/Npdm/Npdm.cs b/Ryujinx.HLE/Loaders/Npdm/Npdm.cs index d255e668..eaa662f0 100644 --- a/Ryujinx.HLE/Loaders/Npdm/Npdm.cs +++ b/Ryujinx.HLE/Loaders/Npdm/Npdm.cs @@ -1,6 +1,4 @@ using Ryujinx.HLE.OsHle.Utilities;
-using System;
-using System.Collections.Generic;
using System.IO;
using System.Text;
@@ -29,7 +27,7 @@ namespace Ryujinx.HLE.Loaders.Npdm public ACI0 ACI0;
public ACID ACID;
-
+
public const long NpdmMagic = 'M' << 0 | 'E' << 8 | 'T' << 16 | 'A' << 24;
public Npdm(Stream NPDMStream)
@@ -61,7 +59,7 @@ namespace Ryujinx.HLE.Loaders.Npdm // ProcessCategory (0: regular title, 1: kernel built-in). Should be 0 here.
ProcessCategory = EndianSwap.Swap32(Reader.ReadInt32());
- // Main entrypoint stack size
+ // Main entrypoint stack size
// (Should(?) be page-aligned. In non-nspwn scenarios, values of 0 can also rarely break in Horizon.
// This might be something auto-adapting or a security feature of some sort ?)
MainEntrypointStackSize = Reader.ReadInt32();
diff --git a/Ryujinx.HLE/Loaders/Npdm/ServiceAccessControl.cs b/Ryujinx.HLE/Loaders/Npdm/ServiceAccessControl.cs index fd33841a..ddd7d7ed 100644 --- a/Ryujinx.HLE/Loaders/Npdm/ServiceAccessControl.cs +++ b/Ryujinx.HLE/Loaders/Npdm/ServiceAccessControl.cs @@ -1,5 +1,4 @@ -using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.IO;
using System.Text;
@@ -25,7 +24,7 @@ namespace Ryujinx.HLE.Loaders.Npdm int Length = ((ControlByte & 0x07)) + 1;
bool RegisterAllowed = ((ControlByte & 0x80) != 0);
-
+
Services.Add((Encoding.ASCII.GetString(Reader.ReadBytes(Length), 0, Length), RegisterAllowed));
ByteReaded += Length + 1;
diff --git a/Ryujinx.HLE/OsHle/Services/Nv/NvGpuAS/NvGpuASIoctl.cs b/Ryujinx.HLE/OsHle/Services/Nv/NvGpuAS/NvGpuASIoctl.cs index c96c04c8..fcc478a4 100644 --- a/Ryujinx.HLE/OsHle/Services/Nv/NvGpuAS/NvGpuASIoctl.cs +++ b/Ryujinx.HLE/OsHle/Services/Nv/NvGpuAS/NvGpuASIoctl.cs @@ -1,5 +1,5 @@ using ChocolArm64.Memory; -using Ryujinx.HLE.Gpu; +using Ryujinx.HLE.Gpu.Memory; using Ryujinx.HLE.Logging; using Ryujinx.HLE.OsHle.Services.Nv.NvMap; using System; diff --git a/Ryujinx.HLE/OsHle/Services/Nv/NvHostChannel/NvHostChannelIoctl.cs b/Ryujinx.HLE/OsHle/Services/Nv/NvHostChannel/NvHostChannelIoctl.cs index c461fa28..8f3d3cd7 100644 --- a/Ryujinx.HLE/OsHle/Services/Nv/NvHostChannel/NvHostChannelIoctl.cs +++ b/Ryujinx.HLE/OsHle/Services/Nv/NvHostChannel/NvHostChannelIoctl.cs @@ -1,5 +1,5 @@ using ChocolArm64.Memory; -using Ryujinx.HLE.Gpu; +using Ryujinx.HLE.Gpu.Memory; using Ryujinx.HLE.Logging; using Ryujinx.HLE.OsHle.Services.Nv.NvGpuAS; using System; diff --git a/Ryujinx.HLE/OsHle/Services/Nv/NvMap/NvMapIoctl.cs b/Ryujinx.HLE/OsHle/Services/Nv/NvMap/NvMapIoctl.cs index 43de4edb..ec10a375 100644 --- a/Ryujinx.HLE/OsHle/Services/Nv/NvMap/NvMapIoctl.cs +++ b/Ryujinx.HLE/OsHle/Services/Nv/NvMap/NvMapIoctl.cs @@ -1,5 +1,5 @@ using ChocolArm64.Memory; -using Ryujinx.HLE.Gpu; +using Ryujinx.HLE.Gpu.Memory; using Ryujinx.HLE.Logging; using Ryujinx.HLE.OsHle.Utilities; using System.Collections.Concurrent; diff --git a/Ryujinx.HLE/OsHle/Services/Vi/NvFlinger.cs b/Ryujinx.HLE/OsHle/Services/Vi/NvFlinger.cs index b45dac6b..a3ed3ab5 100644 --- a/Ryujinx.HLE/OsHle/Services/Vi/NvFlinger.cs +++ b/Ryujinx.HLE/OsHle/Services/Vi/NvFlinger.cs @@ -1,5 +1,5 @@ using Ryujinx.Graphics.Gal; -using Ryujinx.HLE.Gpu; +using Ryujinx.HLE.Gpu.Texture; using Ryujinx.HLE.Logging; using Ryujinx.HLE.OsHle.Handles; using Ryujinx.HLE.OsHle.Services.Nv.NvMap; @@ -8,6 +8,7 @@ using System.Collections.Generic; using System.IO; using System.Text; using System.Threading; + using static Ryujinx.HLE.OsHle.Services.Android.Parcel; namespace Ryujinx.HLE.OsHle.Services.Android @@ -339,7 +340,7 @@ namespace Ryujinx.HLE.OsHle.Services.Android Rotate = -MathF.PI * 0.5f; } - Renderer.SetFrameBufferTransform(ScaleX, ScaleY, Rotate, OffsX, OffsY); + Renderer.QueueAction(() => Renderer.FrameBuffer.SetTransform(ScaleX, ScaleY, Rotate, OffsX, OffsY)); //TODO: Support double buffering here aswell, it is broken for GPU //frame buffers because it seems to be completely out of sync. @@ -347,17 +348,17 @@ namespace Ryujinx.HLE.OsHle.Services.Android { //Frame buffer is rendered to by the GPU, we can just //bind the frame buffer texture, it's not necessary to read anything. - Renderer.SetFrameBuffer(FbAddr); + Renderer.QueueAction(() => Renderer.FrameBuffer.Set(FbAddr)); } else { //Frame buffer is not set on the GPU registers, in this case //assume that the app is manually writing to it. - Texture Texture = new Texture(FbAddr, FbWidth, FbHeight); + TextureInfo Texture = new TextureInfo(FbAddr, FbWidth, FbHeight); byte[] Data = TextureReader.Read(Context.Memory, Texture); - Renderer.SetFrameBuffer(Data, FbWidth, FbHeight); + Renderer.QueueAction(() => Renderer.FrameBuffer.Set(Data, FbWidth, FbHeight)); } Context.Ns.Gpu.Renderer.QueueAction(() => ReleaseBuffer(Slot)); diff --git a/Ryujinx.HLE/PerformanceStatistics.cs b/Ryujinx.HLE/PerformanceStatistics.cs index bbcdc645..9bc3d6b4 100644 --- a/Ryujinx.HLE/PerformanceStatistics.cs +++ b/Ryujinx.HLE/PerformanceStatistics.cs @@ -1,84 +1,119 @@ using System.Diagnostics; using System.Timers; + namespace Ryujinx.HLE { public class PerformanceStatistics { - Stopwatch ExecutionTime = new Stopwatch(); - Timer ResetTimer = new Timer(1000); - - long CurrentGameFrameEnded; - long CurrentSystemFrameEnded; - long CurrentSystemFrameStart; - long LastGameFrameEnded; - long LastSystemFrameEnded; - - double AccumulatedGameFrameTime; - double AccumulatedSystemFrameTime; - double CurrentGameFrameTime; - double CurrentSystemFrameTime; - double PreviousGameFrameTime; - double PreviousSystemFrameTime; - public double GameFrameRate { get; private set; } - public double SystemFrameRate { get; private set; } - public long SystemFramesRendered; - public long GameFramesRendered; - public long ElapsedMilliseconds => ExecutionTime.ElapsedMilliseconds; - public long ElapsedMicroseconds => (long) - (((double)ExecutionTime.ElapsedTicks / Stopwatch.Frequency) * 1000000); - public long ElapsedNanoseconds => (long) - (((double)ExecutionTime.ElapsedTicks / Stopwatch.Frequency) * 1000000000); + private const double FrameRateWeight = 0.5; + + private const int FrameTypeSystem = 0; + private const int FrameTypeGame = 1; + + private double[] AverageFrameRate; + private double[] AccumulatedFrameTime; + private double[] PreviousFrameTime; + + private long[] FramesRendered; + + private object[] FrameLock; + + private double TicksToSeconds; + + private Stopwatch ExecutionTime; + + private Timer ResetTimer; public PerformanceStatistics() { + AverageFrameRate = new double[2]; + AccumulatedFrameTime = new double[2]; + PreviousFrameTime = new double[2]; + + FramesRendered = new long[2]; + + FrameLock = new object[] { new object(), new object() }; + + ExecutionTime = new Stopwatch(); + ExecutionTime.Start(); + + ResetTimer = new Timer(1000); + ResetTimer.Elapsed += ResetTimerElapsed; + ResetTimer.AutoReset = true; + ResetTimer.Start(); + + TicksToSeconds = 1.0 / Stopwatch.Frequency; } private void ResetTimerElapsed(object sender, ElapsedEventArgs e) { - ResetStatistics(); + CalculateAverageFrameRate(FrameTypeSystem); + CalculateAverageFrameRate(FrameTypeGame); } - public void StartSystemFrame() + private void CalculateAverageFrameRate(int FrameType) { - PreviousSystemFrameTime = CurrentSystemFrameTime; - LastSystemFrameEnded = CurrentSystemFrameEnded; - CurrentSystemFrameStart = ElapsedMicroseconds; + double FrameRate = 0; + + if (AccumulatedFrameTime[FrameType] > 0) + { + FrameRate = FramesRendered[FrameType] / AccumulatedFrameTime[FrameType]; + } + + lock (FrameLock[FrameType]) + { + AverageFrameRate[FrameType] = LinearInterpolate(AverageFrameRate[FrameType], FrameRate); + + FramesRendered[FrameType] = 0; + + AccumulatedFrameTime[FrameType] = 0; + } } - public void EndSystemFrame() + private double LinearInterpolate(double Old, double New) { - CurrentSystemFrameEnded = ElapsedMicroseconds; - CurrentSystemFrameTime = CurrentSystemFrameEnded - CurrentSystemFrameStart; - AccumulatedSystemFrameTime += CurrentSystemFrameTime; - SystemFramesRendered++; + return Old * (1.0 - FrameRateWeight) + New * FrameRateWeight; + } + + public void RecordSystemFrameTime() + { + RecordFrameTime(FrameTypeSystem); } public void RecordGameFrameTime() { - CurrentGameFrameEnded = ElapsedMicroseconds; - CurrentGameFrameTime = CurrentGameFrameEnded - LastGameFrameEnded; - PreviousGameFrameTime = CurrentGameFrameTime; - LastGameFrameEnded = CurrentGameFrameEnded; - AccumulatedGameFrameTime += CurrentGameFrameTime; - GameFramesRendered++; + RecordFrameTime(FrameTypeGame); + } + + private void RecordFrameTime(int FrameType) + { + double CurrentFrameTime = ExecutionTime.ElapsedTicks * TicksToSeconds; + + double ElapsedFrameTime = CurrentFrameTime - PreviousFrameTime[FrameType]; + + PreviousFrameTime[FrameType] = CurrentFrameTime; + + lock (FrameLock[FrameType]) + { + AccumulatedFrameTime[FrameType] += ElapsedFrameTime; + + FramesRendered[FrameType]++; + } + } + + public double GetSystemFrameRate() + { + return AverageFrameRate[FrameTypeSystem]; } - public void ResetStatistics() + public double GetGameFrameRate() { - GameFrameRate = 1000 / ((AccumulatedGameFrameTime / GameFramesRendered) / 1000); - GameFrameRate = double.IsNaN(GameFrameRate) ? 0 : GameFrameRate; - SystemFrameRate = 1000 / ((AccumulatedSystemFrameTime / SystemFramesRendered) / 1000); - SystemFrameRate = double.IsNaN(SystemFrameRate) ? 0 : SystemFrameRate; - - GameFramesRendered = 0; - SystemFramesRendered = 0; - AccumulatedGameFrameTime = 0; - AccumulatedSystemFrameTime = 0; + return AverageFrameRate[FrameTypeGame]; } } } diff --git a/Ryujinx.HLE/Switch.cs b/Ryujinx.HLE/Switch.cs index f75b2490..f7b263cd 100644 --- a/Ryujinx.HLE/Switch.cs +++ b/Ryujinx.HLE/Switch.cs @@ -71,6 +71,11 @@ namespace Ryujinx.HLE Os.LoadProgram(FileName); } + public void ProcessFrame() + { + Gpu.Fifo.DispatchCalls(); + } + internal virtual void OnFinish(EventArgs e) { Finish?.Invoke(this, e); |
