|
|
@@ -7,7 +7,7 @@ using System.Collections.Generic;
|
|
|
|
|
|
namespace Ryujinx.Graphics
|
|
|
{
|
|
|
- public class NvGpuEngine3d : INvGpuEngine
|
|
|
+ class NvGpuEngine3d : INvGpuEngine
|
|
|
{
|
|
|
public int[] Registers { get; private set; }
|
|
|
|
|
|
@@ -24,8 +24,6 @@ namespace Ryujinx.Graphics
|
|
|
|
|
|
private ConstBuffer[][] ConstBuffers;
|
|
|
|
|
|
- private List<long>[] UploadedKeys;
|
|
|
-
|
|
|
private int CurrentInstance = 0;
|
|
|
|
|
|
public NvGpuEngine3d(NvGpu Gpu)
|
|
|
@@ -59,13 +57,6 @@ namespace Ryujinx.Graphics
|
|
|
ConstBuffers[Index] = new ConstBuffer[18];
|
|
|
}
|
|
|
|
|
|
- UploadedKeys = new List<long>[(int)NvGpuBufferType.Count];
|
|
|
-
|
|
|
- for (int i = 0; i < UploadedKeys.Length; i++)
|
|
|
- {
|
|
|
- UploadedKeys[i] = new List<long>();
|
|
|
- }
|
|
|
-
|
|
|
//Ensure that all components are enabled by default.
|
|
|
//FIXME: Is this correct?
|
|
|
WriteRegister(NvGpuEngine3dReg.ColorMaskN, 0x1111);
|
|
|
@@ -81,27 +72,19 @@ namespace Ryujinx.Graphics
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- public void CallMethod(NvGpuVmm Vmm, NvGpuPBEntry PBEntry)
|
|
|
+ public void CallMethod(NvGpuVmm Vmm, GpuMethodCall MethCall)
|
|
|
{
|
|
|
- if (Methods.TryGetValue(PBEntry.Method, out NvGpuMethod Method))
|
|
|
+ if (Methods.TryGetValue(MethCall.Method, out NvGpuMethod Method))
|
|
|
{
|
|
|
- Method(Vmm, PBEntry);
|
|
|
+ Method(Vmm, MethCall);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- WriteRegister(PBEntry);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public void ResetCache()
|
|
|
- {
|
|
|
- foreach (List<long> Uploaded in UploadedKeys)
|
|
|
- {
|
|
|
- Uploaded.Clear();
|
|
|
+ WriteRegister(MethCall);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private void VertexEndGl(NvGpuVmm Vmm, NvGpuPBEntry PBEntry)
|
|
|
+ private void VertexEndGl(NvGpuVmm Vmm, GpuMethodCall MethCall)
|
|
|
{
|
|
|
LockCaches();
|
|
|
|
|
|
@@ -152,13 +135,11 @@ namespace Ryujinx.Graphics
|
|
|
Gpu.Renderer.Texture.UnlockCache();
|
|
|
}
|
|
|
|
|
|
- private void ClearBuffers(NvGpuVmm Vmm, NvGpuPBEntry PBEntry)
|
|
|
+ private void ClearBuffers(NvGpuVmm Vmm, GpuMethodCall MethCall)
|
|
|
{
|
|
|
- int Arg0 = PBEntry.Arguments[0];
|
|
|
+ int Attachment = (MethCall.Argument >> 6) & 0xf;
|
|
|
|
|
|
- int Attachment = (Arg0 >> 6) & 0xf;
|
|
|
-
|
|
|
- GalClearBufferFlags Flags = (GalClearBufferFlags)(Arg0 & 0x3f);
|
|
|
+ GalClearBufferFlags Flags = (GalClearBufferFlags)(MethCall.Argument & 0x3f);
|
|
|
|
|
|
float Red = ReadRegisterFloat(NvGpuEngine3dReg.ClearNColor + 0);
|
|
|
float Green = ReadRegisterFloat(NvGpuEngine3dReg.ClearNColor + 1);
|
|
|
@@ -234,6 +215,15 @@ namespace Ryujinx.Graphics
|
|
|
|
|
|
State.FlipX = GetFlipSign(NvGpuEngine3dReg.ViewportNScaleX);
|
|
|
State.FlipY = GetFlipSign(NvGpuEngine3dReg.ViewportNScaleY);
|
|
|
+
|
|
|
+ int ScreenYControl = ReadRegister(NvGpuEngine3dReg.ScreenYControl);
|
|
|
+
|
|
|
+ bool NegateY = (ScreenYControl & 1) != 0;
|
|
|
+
|
|
|
+ if (NegateY)
|
|
|
+ {
|
|
|
+ State.FlipY = -State.FlipY;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
private void SetZeta(NvGpuVmm Vmm)
|
|
|
@@ -566,8 +556,11 @@ namespace Ryujinx.Graphics
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+ bool LinkedTsc = ReadRegisterBool(NvGpuEngine3dReg.LinkedTsc);
|
|
|
+
|
|
|
int TicIndex = (TextureHandle >> 0) & 0xfffff;
|
|
|
- int TscIndex = (TextureHandle >> 20) & 0xfff;
|
|
|
+
|
|
|
+ int TscIndex = LinkedTsc ? TicIndex : (TextureHandle >> 20) & 0xfff;
|
|
|
|
|
|
long TicPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.TexHeaderPoolOffset);
|
|
|
long TscPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.TexSamplerPoolOffset);
|
|
|
@@ -618,7 +611,7 @@ namespace Ryujinx.Graphics
|
|
|
|
|
|
long Key = Vmm.GetPhysicalAddress(Cb.Position);
|
|
|
|
|
|
- if (QueryKeyUpload(Vmm, Key, Cb.Size, NvGpuBufferType.ConstBuffer))
|
|
|
+ if (Gpu.ResourceManager.MemoryRegionModified(Vmm, Key, Cb.Size, NvGpuBufferType.ConstBuffer))
|
|
|
{
|
|
|
IntPtr Source = Vmm.GetHostAddress(Cb.Position, Cb.Size);
|
|
|
|
|
|
@@ -661,7 +654,7 @@ namespace Ryujinx.Graphics
|
|
|
PrimType == GalPrimitiveType.Quads ||
|
|
|
PrimType == GalPrimitiveType.QuadStrip;
|
|
|
|
|
|
- if (!IboCached || QueryKeyUpload(Vmm, IboKey, (uint)IbSize, NvGpuBufferType.Index))
|
|
|
+ if (!IboCached || Gpu.ResourceManager.MemoryRegionModified(Vmm, IboKey, (uint)IbSize, NvGpuBufferType.Index))
|
|
|
{
|
|
|
if (!UsesLegacyQuads)
|
|
|
{
|
|
|
@@ -778,7 +771,7 @@ namespace Ryujinx.Graphics
|
|
|
|
|
|
bool VboCached = Gpu.Renderer.Rasterizer.IsVboCached(VboKey, VbSize);
|
|
|
|
|
|
- if (!VboCached || QueryKeyUpload(Vmm, VboKey, VbSize, NvGpuBufferType.Vertex))
|
|
|
+ if (!VboCached || Gpu.ResourceManager.MemoryRegionModified(Vmm, VboKey, VbSize, NvGpuBufferType.Vertex))
|
|
|
{
|
|
|
IntPtr DataAddress = Vmm.GetHostAddress(VertexPosition, VbSize);
|
|
|
|
|
|
@@ -877,9 +870,9 @@ namespace Ryujinx.Graphics
|
|
|
WriteCounterAndTimestamp
|
|
|
}
|
|
|
|
|
|
- private void QueryControl(NvGpuVmm Vmm, NvGpuPBEntry PBEntry)
|
|
|
+ private void QueryControl(NvGpuVmm Vmm, GpuMethodCall MethCall)
|
|
|
{
|
|
|
- WriteRegister(PBEntry);
|
|
|
+ WriteRegister(MethCall);
|
|
|
|
|
|
long Position = MakeInt64From2xInt32(NvGpuEngine3dReg.QueryAddress);
|
|
|
|
|
|
@@ -909,29 +902,24 @@ namespace Ryujinx.Graphics
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private void CbData(NvGpuVmm Vmm, NvGpuPBEntry PBEntry)
|
|
|
+ private void CbData(NvGpuVmm Vmm, GpuMethodCall MethCall)
|
|
|
{
|
|
|
long Position = MakeInt64From2xInt32(NvGpuEngine3dReg.ConstBufferAddress);
|
|
|
|
|
|
int Offset = ReadRegister(NvGpuEngine3dReg.ConstBufferOffset);
|
|
|
|
|
|
- foreach (int Arg in PBEntry.Arguments)
|
|
|
- {
|
|
|
- Vmm.WriteInt32(Position + Offset, Arg);
|
|
|
-
|
|
|
- Offset += 4;
|
|
|
- }
|
|
|
+ Vmm.WriteInt32(Position + Offset, MethCall.Argument);
|
|
|
|
|
|
- WriteRegister(NvGpuEngine3dReg.ConstBufferOffset, Offset);
|
|
|
+ WriteRegister(NvGpuEngine3dReg.ConstBufferOffset, Offset + 4);
|
|
|
|
|
|
- UploadedKeys[(int)NvGpuBufferType.ConstBuffer].Clear();
|
|
|
+ Gpu.ResourceManager.ClearPbCache(NvGpuBufferType.ConstBuffer);
|
|
|
}
|
|
|
|
|
|
- private void CbBind(NvGpuVmm Vmm, NvGpuPBEntry PBEntry)
|
|
|
+ private void CbBind(NvGpuVmm Vmm, GpuMethodCall MethCall)
|
|
|
{
|
|
|
- int Stage = (PBEntry.Method - 0x904) >> 3;
|
|
|
+ int Stage = (MethCall.Method - 0x904) >> 3;
|
|
|
|
|
|
- int Index = PBEntry.Arguments[0];
|
|
|
+ int Index = MethCall.Argument;
|
|
|
|
|
|
bool Enabled = (Index & 1) != 0;
|
|
|
|
|
|
@@ -970,14 +958,9 @@ namespace Ryujinx.Graphics
|
|
|
(uint)Registers[(int)Reg + 1];
|
|
|
}
|
|
|
|
|
|
- private void WriteRegister(NvGpuPBEntry PBEntry)
|
|
|
+ private void WriteRegister(GpuMethodCall MethCall)
|
|
|
{
|
|
|
- int ArgsCount = PBEntry.Arguments.Count;
|
|
|
-
|
|
|
- if (ArgsCount > 0)
|
|
|
- {
|
|
|
- Registers[PBEntry.Method] = PBEntry.Arguments[ArgsCount - 1];
|
|
|
- }
|
|
|
+ Registers[MethCall.Method] = MethCall.Argument;
|
|
|
}
|
|
|
|
|
|
private int ReadRegister(NvGpuEngine3dReg Reg)
|
|
|
@@ -999,19 +982,5 @@ namespace Ryujinx.Graphics
|
|
|
{
|
|
|
Registers[(int)Reg] = Value;
|
|
|
}
|
|
|
-
|
|
|
- private bool QueryKeyUpload(NvGpuVmm Vmm, long Key, long Size, NvGpuBufferType Type)
|
|
|
- {
|
|
|
- List<long> Uploaded = UploadedKeys[(int)Type];
|
|
|
-
|
|
|
- if (Uploaded.Contains(Key))
|
|
|
- {
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- Uploaded.Add(Key);
|
|
|
-
|
|
|
- return Vmm.IsRegionModified(Key, Size, Type);
|
|
|
- }
|
|
|
}
|
|
|
}
|