aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-03-20 12:18:25 -0300
committergdkchan <gab.dark.100@gmail.com>2018-03-20 12:18:25 -0300
commit1bd99e559785ecf6a40e1bcb4a717642014c078f (patch)
tree5d167c29acefd0d2f108348b79ff03ef5b89f6db
parent4314a8f3e5b76bbf2143f701c06e9354de712027 (diff)
Support different framebuffer offsets (fixes #59)
-rw-r--r--Ryujinx.Core/OsHle/GlobalStateTable.cs11
-rw-r--r--Ryujinx.Core/OsHle/IdDictionary.cs5
-rw-r--r--Ryujinx.Core/OsHle/Process.cs4
-rw-r--r--Ryujinx.Core/OsHle/Services/Nv/NvMap.cs2
-rw-r--r--Ryujinx.Core/OsHle/Services/Nv/NvMapFb.cs40
-rw-r--r--Ryujinx.Core/OsHle/Services/Nv/ServiceNvDrv.cs17
-rw-r--r--Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs17
7 files changed, 82 insertions, 14 deletions
diff --git a/Ryujinx.Core/OsHle/GlobalStateTable.cs b/Ryujinx.Core/OsHle/GlobalStateTable.cs
index ffc9f262..2a5714ad 100644
--- a/Ryujinx.Core/OsHle/GlobalStateTable.cs
+++ b/Ryujinx.Core/OsHle/GlobalStateTable.cs
@@ -12,11 +12,18 @@ namespace Ryujinx.Core.OsHle
DictByProcess = new ConcurrentDictionary<Process, IdDictionary>();
}
- public int Add(Process Process, object Obj)
+ public bool Add(Process Process, int Id, object Data)
{
IdDictionary Dict = DictByProcess.GetOrAdd(Process, (Key) => new IdDictionary());
- return Dict.Add(Obj);
+ return Dict.Add(Id, Data);
+ }
+
+ public int Add(Process Process, object Data)
+ {
+ IdDictionary Dict = DictByProcess.GetOrAdd(Process, (Key) => new IdDictionary());
+
+ return Dict.Add(Data);
}
public object GetData(Process Process, int Id)
diff --git a/Ryujinx.Core/OsHle/IdDictionary.cs b/Ryujinx.Core/OsHle/IdDictionary.cs
index 0746ae81..2a498e7f 100644
--- a/Ryujinx.Core/OsHle/IdDictionary.cs
+++ b/Ryujinx.Core/OsHle/IdDictionary.cs
@@ -15,6 +15,11 @@ namespace Ryujinx.Core.OsHle
Objs = new ConcurrentDictionary<int, object>();
}
+ public bool Add(int Id, object Data)
+ {
+ return Objs.TryAdd(Id, Data);
+ }
+
public int Add(object Data)
{
if (Objs.TryAdd(FreeIdHint, Data))
diff --git a/Ryujinx.Core/OsHle/Process.cs b/Ryujinx.Core/OsHle/Process.cs
index 1846e576..25c10a43 100644
--- a/Ryujinx.Core/OsHle/Process.cs
+++ b/Ryujinx.Core/OsHle/Process.cs
@@ -356,9 +356,9 @@ namespace Ryujinx.Core.OsHle
ServiceNvDrv.Fds.DeleteProcess(this);
- ServiceNvDrv.NvMaps.DeleteProcess(this);
-
+ ServiceNvDrv.NvMaps .DeleteProcess(this);
ServiceNvDrv.NvMapsById.DeleteProcess(this);
+ ServiceNvDrv.NvMapsFb .DeleteProcess(this);
Scheduler.Dispose();
diff --git a/Ryujinx.Core/OsHle/Services/Nv/NvMap.cs b/Ryujinx.Core/OsHle/Services/Nv/NvMap.cs
index ca844f9f..d5a5a800 100644
--- a/Ryujinx.Core/OsHle/Services/Nv/NvMap.cs
+++ b/Ryujinx.Core/OsHle/Services/Nv/NvMap.cs
@@ -7,6 +7,6 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
public int Size;
public int Align;
public int Kind;
- public long Address;
+ public long CpuAddress;
}
} \ No newline at end of file
diff --git a/Ryujinx.Core/OsHle/Services/Nv/NvMapFb.cs b/Ryujinx.Core/OsHle/Services/Nv/NvMapFb.cs
new file mode 100644
index 00000000..1066cc95
--- /dev/null
+++ b/Ryujinx.Core/OsHle/Services/Nv/NvMapFb.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Collections.Generic;
+
+namespace Ryujinx.Core.OsHle.IpcServices.NvServices
+{
+ class NvMapFb
+ {
+ private List<long> BufferOffs;
+
+ public NvMapFb()
+ {
+ BufferOffs = new List<long>();
+ }
+
+ public void AddBufferOffset(long Offset)
+ {
+ BufferOffs.Add(Offset);
+ }
+
+ public bool HasBufferOffset(int Index)
+ {
+ if ((uint)Index >= BufferOffs.Count)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ public long GetBufferOffset(int Index)
+ {
+ if ((uint)Index >= BufferOffs.Count)
+ {
+ throw new ArgumentOutOfRangeException(nameof(Index));
+ }
+
+ return BufferOffs[Index];
+ }
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.Core/OsHle/Services/Nv/ServiceNvDrv.cs b/Ryujinx.Core/OsHle/Services/Nv/ServiceNvDrv.cs
index ef223772..a1e0e532 100644
--- a/Ryujinx.Core/OsHle/Services/Nv/ServiceNvDrv.cs
+++ b/Ryujinx.Core/OsHle/Services/Nv/ServiceNvDrv.cs
@@ -22,6 +22,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
public static GlobalStateTable NvMaps { get; private set; }
public static GlobalStateTable NvMapsById { get; private set; }
+ public static GlobalStateTable NvMapsFb { get; private set; }
private KEvent Event;
@@ -76,6 +77,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
NvMaps = new GlobalStateTable();
NvMapsById = new GlobalStateTable();
+ NvMapsFb = new GlobalStateTable();
}
public long Open(ServiceCtx Context)
@@ -131,6 +133,8 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
Context.ResponseData.Write(0);
+ NvMapsFb.Add(Context.Process, 0, new NvMapFb());
+
return 0;
}
@@ -209,8 +213,11 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
if (Handle == 0)
{
- //Handle 0 is valid here, but it refers to something else.
- //TODO: Figure out what, for now just return success.
+ //This is used to store offsets for the Framebuffer(s);
+ NvMapFb MapFb = (NvMapFb)NvMapsFb.GetData(Context.Process, 0);
+
+ MapFb.AddBufferOffset(BuffAddr);
+
return 0;
}
@@ -225,11 +232,11 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
if ((Flags & 1) != 0)
{
- Offset = Context.Ns.Gpu.MapMemory(Map.Address, Offset, Map.Size);
+ Offset = Context.Ns.Gpu.MapMemory(Map.CpuAddress, Offset, Map.Size);
}
else
{
- Offset = Context.Ns.Gpu.MapMemory(Map.Address, Map.Size);
+ Offset = Context.Ns.Gpu.MapMemory(Map.CpuAddress, Map.Size);
}
Context.Memory.WriteInt64(Position + 0x20, Offset);
@@ -614,7 +621,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
return -1; //TODO: Corrent error code.
}
- Map.Address = Addr;
+ Map.CpuAddress = Addr;
Map.Align = Align;
Map.Kind = Kind;
diff --git a/Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs b/Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs
index 3a7a2ee6..550260bb 100644
--- a/Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs
+++ b/Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs
@@ -289,11 +289,20 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
long FbSize = (uint)FbWidth * FbHeight * 4;
- NvMap NvMap = GetNvMap(Context, Slot);
+ NvMap Map = GetNvMap(Context, Slot);
- if ((ulong)(NvMap.Address + FbSize) > AMemoryMgr.AddrSize)
+ NvMapFb MapFb = (NvMapFb)ServiceNvDrv.NvMapsFb.GetData(Context.Process, 0);
+
+ long Address = Map.CpuAddress;
+
+ if (MapFb.HasBufferOffset(Slot))
+ {
+ Address += MapFb.GetBufferOffset(Slot);
+ }
+
+ if ((ulong)(Address + FbSize) > AMemoryMgr.AddrSize)
{
- Logging.Error($"Frame buffer address {NvMap.Address:x16} is invalid!");
+ Logging.Error($"Frame buffer address {Address:x16} is invalid!");
BufferQueue[Slot].State = BufferState.Free;
@@ -365,7 +374,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
Interlocked.Increment(ref RenderQueueCount);
}
- byte* Fb = (byte*)Context.Memory.Ram + NvMap.Address;
+ byte* Fb = (byte*)Context.Memory.Ram + Address;
Context.Ns.Gpu.Renderer.QueueAction(delegate()
{