NvServices refactoring (#120)

* Initial implementation of NvMap/NvHostCtrl

* More work on NvHostCtrl

* Refactoring of nvservices, move GPU Vmm, make Vmm per-process, refactor most gpu devices, move Gpu to Core, fix CbBind

* Implement GetGpuTime, support CancelSynchronization, fix issue on InsertWaitingMutex, proper double buffering support (again, not working properly for commercial games, only hb)

* Try to fix perf regression reading/writing textures, moved syncpts and events to a UserCtx class, delete global state when the process exits, other minor tweaks

* Remove now unused code, add comment about probably wrong result codes
This commit is contained in:
gdkchan 2018-05-07 15:53:23 -03:00 committed by GitHub
parent 4419e8d6b4
commit 34037701c7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
75 changed files with 2472 additions and 1440 deletions

View file

@ -1,9 +1,9 @@
using ChocolArm64.Memory;
using Ryujinx.Core.Gpu;
using Ryujinx.Core.Logging;
using Ryujinx.Core.OsHle.Handles;
using Ryujinx.Core.OsHle.Services.Nv;
using Ryujinx.Core.OsHle.Services.Nv.NvMap;
using Ryujinx.Graphics.Gal;
using Ryujinx.Graphics.Gpu;
using System;
using System.Collections.Generic;
using System.IO;
@ -282,20 +282,12 @@ namespace Ryujinx.Core.OsHle.Services.Android
int FbWidth = 1280;
int FbHeight = 720;
NvMap Map = GetNvMap(Context, Slot);
int NvMapHandle = BitConverter.ToInt32(BufferQueue[Slot].Data.RawData, 0x4c);
int BufferOffset = BitConverter.ToInt32(BufferQueue[Slot].Data.RawData, 0x50);
NvMapFb MapFb = (NvMapFb)INvDrvServices.NvMapsFb.GetData(Context.Process, 0);
NvMapHandle Map = NvMapIoctl.GetNvMap(Context, NvMapHandle);;
long CpuAddr = Map.CpuAddress;
long GpuAddr = Map.GpuAddress;
if (MapFb.HasBufferOffset(Slot))
{
CpuAddr += MapFb.GetBufferOffset(Slot);
//TODO: Enable once the frame buffers problems are fixed.
//GpuAddr += MapFb.GetBufferOffset(Slot);
}
long FbAddr = Map.Address + BufferOffset;
BufferQueue[Slot].State = BufferState.Acquired;
@ -352,17 +344,17 @@ namespace Ryujinx.Core.OsHle.Services.Android
//TODO: Support double buffering here aswell, it is broken for GPU
//frame buffers because it seems to be completely out of sync.
if (Context.Ns.Gpu.Engine3d.IsFrameBufferPosition(GpuAddr))
if (Context.Ns.Gpu.Engine3d.IsFrameBufferPosition(FbAddr))
{
//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(GpuAddr);
Renderer.SetFrameBuffer(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(CpuAddr, FbWidth, FbHeight);
Texture Texture = new Texture(FbAddr, FbWidth, FbHeight);
byte[] Data = TextureReader.Read(Context.Memory, Texture);
@ -372,22 +364,6 @@ namespace Ryujinx.Core.OsHle.Services.Android
Context.Ns.Gpu.Renderer.QueueAction(() => ReleaseBuffer(Slot));
}
private NvMap GetNvMap(ServiceCtx Context, int Slot)
{
int NvMapHandle = BitConverter.ToInt32(BufferQueue[Slot].Data.RawData, 0x4c);
if (!BitConverter.IsLittleEndian)
{
byte[] RawValue = BitConverter.GetBytes(NvMapHandle);
Array.Reverse(RawValue);
NvMapHandle = BitConverter.ToInt32(RawValue, 0);
}
return INvDrvServices.NvMaps.GetData<NvMap>(Context.Process, NvMapHandle);
}
private void ReleaseBuffer(int Slot)
{
BufferQueue[Slot].State = BufferState.Free;