aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics/NvGpuEngine3d.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-09-18 01:30:35 -0300
committerGitHub <noreply@github.com>2018-09-18 01:30:35 -0300
commitd4187aaa9d7194aa26d04aee838edbc3a38f1862 (patch)
tree06fe725c1067b4aeca21749799b835d85e7d2787 /Ryujinx.Graphics/NvGpuEngine3d.cs
parentbec95cacc1061f91373a1e3a1411981af7fe2e4e (diff)
Allow "reinterpretation" of framebuffer/zeta formats (#418)
* (Re)Implement format reinterpretation, other changes * Implement writeback to guest memory, some refactoring * More refactoring, implement reinterpretation the old way again * Clean up * Some fixes on M2MF (old Dma engine), added partial support for P2MF, fix conditional ssy, add Z24S8 zeta format, other fixes * nit: Formatting * Address PR feedback
Diffstat (limited to 'Ryujinx.Graphics/NvGpuEngine3d.cs')
-rw-r--r--Ryujinx.Graphics/NvGpuEngine3d.cs123
1 files changed, 46 insertions, 77 deletions
diff --git a/Ryujinx.Graphics/NvGpuEngine3d.cs b/Ryujinx.Graphics/NvGpuEngine3d.cs
index 624eddae..a1d0ec80 100644
--- a/Ryujinx.Graphics/NvGpuEngine3d.cs
+++ b/Ryujinx.Graphics/NvGpuEngine3d.cs
@@ -23,8 +23,6 @@ namespace Ryujinx.Graphics
private ConstBuffer[][] ConstBuffers;
- private HashSet<long> FrameBuffers;
-
private List<long>[] UploadedKeys;
private int CurrentInstance = 0;
@@ -60,8 +58,6 @@ namespace Ryujinx.Graphics
ConstBuffers[Index] = new ConstBuffer[18];
}
- FrameBuffers = new HashSet<long>();
-
UploadedKeys = new List<long>[(int)NvGpuBufferType.Count];
for (int i = 0; i < UploadedKeys.Length; i++)
@@ -96,7 +92,7 @@ namespace Ryujinx.Graphics
GalPipelineState State = new GalPipelineState();
- SetFlip(State);
+ SetFrameBuffer(State);
SetFrontFace(State);
SetCullFace(State);
SetDepth(State);
@@ -104,10 +100,7 @@ namespace Ryujinx.Graphics
SetAlphaBlending(State);
SetPrimitiveRestart(State);
- for (int FbIndex = 0; FbIndex < 8; FbIndex++)
- {
- SetFrameBuffer(Vmm, 0);
- }
+ SetFrameBuffer(Vmm, 0);
SetZeta(Vmm);
@@ -173,9 +166,9 @@ namespace Ryujinx.Graphics
{
long VA = MakeInt64From2xInt32(NvGpuEngine3dReg.FrameBufferNAddress + FbIndex * 0x10);
- int Format = ReadRegister(NvGpuEngine3dReg.FrameBufferNFormat + FbIndex * 0x10);
+ int SurfFormat = ReadRegister(NvGpuEngine3dReg.FrameBufferNFormat + FbIndex * 0x10);
- if (VA == 0 || Format == 0)
+ if (VA == 0 || SurfFormat == 0)
{
Gpu.Renderer.RenderTarget.UnbindColor(FbIndex);
@@ -184,11 +177,15 @@ namespace Ryujinx.Graphics
long Key = Vmm.GetPhysicalAddress(VA);
- FrameBuffers.Add(Key);
-
int Width = ReadRegister(NvGpuEngine3dReg.FrameBufferNWidth + FbIndex * 0x10);
int Height = ReadRegister(NvGpuEngine3dReg.FrameBufferNHeight + FbIndex * 0x10);
+ int BlockDim = ReadRegister(NvGpuEngine3dReg.FrameBufferNBlockDim + FbIndex * 0x10);
+
+ int GobBlockHeight = 1 << ((BlockDim >> 4) & 7);
+
+ GalMemoryLayout Layout = (GalMemoryLayout)((BlockDim >> 12) & 1);
+
float TX = ReadRegisterFloat(NvGpuEngine3dReg.ViewportNTranslateX + FbIndex * 8);
float TY = ReadRegisterFloat(NvGpuEngine3dReg.ViewportNTranslateY + FbIndex * 8);
@@ -201,48 +198,54 @@ namespace Ryujinx.Graphics
int VpW = (int)(TX + MathF.Abs(SX)) - VpX;
int VpH = (int)(TY + MathF.Abs(SY)) - VpY;
- GalImageFormat ImageFormat = ImageUtils.ConvertSurface((GalSurfaceFormat)Format);
+ GalImageFormat Format = ImageUtils.ConvertSurface((GalSurfaceFormat)SurfFormat);
- GalImage Image = new GalImage(Width, Height, ImageFormat);
+ GalImage Image = new GalImage(Width, Height, 1, GobBlockHeight, Layout, Format);
- long Size = ImageUtils.GetSize(Image);
+ Gpu.ResourceManager.SendColorBuffer(Vmm, Key, FbIndex, Image);
- Gpu.Renderer.Texture.CreateFb(Key, Size, Image);
+ Gpu.Renderer.RenderTarget.SetViewport(VpX, VpY, VpW, VpH);
+ }
- Gpu.Renderer.RenderTarget.BindColor(Key, FbIndex);
+ private void SetFrameBuffer(GalPipelineState State)
+ {
+ State.FramebufferSrgb = (ReadRegister(NvGpuEngine3dReg.FrameBufferSrgb) & 1) != 0;
- Gpu.Renderer.RenderTarget.SetViewport(VpX, VpY, VpW, VpH);
+ State.FlipX = GetFlipSign(NvGpuEngine3dReg.ViewportNScaleX);
+ State.FlipY = GetFlipSign(NvGpuEngine3dReg.ViewportNScaleY);
}
private void SetZeta(NvGpuVmm Vmm)
{
- long ZA = MakeInt64From2xInt32(NvGpuEngine3dReg.ZetaAddress);
+ long VA = MakeInt64From2xInt32(NvGpuEngine3dReg.ZetaAddress);
+
+ int ZetaFormat = ReadRegister(NvGpuEngine3dReg.ZetaFormat);
+
+ int BlockDim = ReadRegister(NvGpuEngine3dReg.ZetaBlockDimensions);
+
+ int GobBlockHeight = 1 << ((BlockDim >> 4) & 7);
- int Format = ReadRegister(NvGpuEngine3dReg.ZetaFormat);
+ GalMemoryLayout Layout = (GalMemoryLayout)((BlockDim >> 12) & 1); //?
bool ZetaEnable = (ReadRegister(NvGpuEngine3dReg.ZetaEnable) & 1) != 0;
- if (ZA == 0 || Format == 0 || !ZetaEnable)
+ if (VA == 0 || ZetaFormat == 0 || !ZetaEnable)
{
Gpu.Renderer.RenderTarget.UnbindZeta();
return;
}
- long Key = Vmm.GetPhysicalAddress(ZA);
+ long Key = Vmm.GetPhysicalAddress(VA);
int Width = ReadRegister(NvGpuEngine3dReg.ZetaHoriz);
int Height = ReadRegister(NvGpuEngine3dReg.ZetaVert);
- GalImageFormat ImageFormat = ImageUtils.ConvertZeta((GalZetaFormat)Format);
-
- GalImage Image = new GalImage(Width, Height, ImageFormat);
-
- long Size = ImageUtils.GetSize(Image);
+ GalImageFormat Format = ImageUtils.ConvertZeta((GalZetaFormat)ZetaFormat);
- Gpu.Renderer.Texture.CreateFb(Key, Size, Image);
+ GalImage Image = new GalImage(Width, Height, 1, GobBlockHeight, Layout, Format);
- Gpu.Renderer.RenderTarget.BindZeta(Key);
+ Gpu.ResourceManager.SendZetaBuffer(Vmm, Key, Image);
}
private long[] UploadShaders(NvGpuVmm Vmm)
@@ -322,12 +325,6 @@ namespace Ryujinx.Graphics
throw new ArgumentOutOfRangeException(nameof(Program));
}
- private void SetFlip(GalPipelineState State)
- {
- State.FlipX = GetFlipSign(NvGpuEngine3dReg.ViewportNScaleX);
- State.FlipY = GetFlipSign(NvGpuEngine3dReg.ViewportNScaleY);
- }
-
private void SetFrontFace(GalPipelineState State)
{
float SignX = GetFlipSign(NvGpuEngine3dReg.ViewportNScaleX);
@@ -504,54 +501,31 @@ namespace Ryujinx.Graphics
TicPosition += TicIndex * 0x20;
TscPosition += TscIndex * 0x20;
+ GalImage Image = TextureFactory.MakeTexture(Vmm, TicPosition);
+
GalTextureSampler Sampler = TextureFactory.MakeSampler(Gpu, Vmm, TscPosition);
long Key = Vmm.ReadInt64(TicPosition + 4) & 0xffffffffffff;
- Key = Vmm.GetPhysicalAddress(Key);
-
- if (Key == -1)
+ if (Image.Layout == GalMemoryLayout.BlockLinear)
{
- //FIXME: Should'nt ignore invalid addresses.
- return;
+ Key &= ~0x1ffL;
}
-
- if (IsFrameBufferPosition(Key))
+ else if (Image.Layout == GalMemoryLayout.Pitch)
{
- //This texture is a frame buffer texture,
- //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.RenderTarget.BindTexture(Key, TexIndex);
+ Key &= ~0x1fL;
}
- else
- {
- GalImage NewImage = TextureFactory.MakeTexture(Vmm, TicPosition);
-
- long Size = (uint)ImageUtils.GetSize(NewImage);
-
- bool HasCachedTexture = false;
-
- if (Gpu.Renderer.Texture.TryGetCachedTexture(Key, Size, out GalImage Image))
- {
- if (NewImage.Equals(Image) && !QueryKeyUpload(Vmm, Key, Size, NvGpuBufferType.Texture))
- {
- Gpu.Renderer.Texture.Bind(Key, TexIndex);
-
- HasCachedTexture = true;
- }
- }
-
- if (!HasCachedTexture)
- {
- byte[] Data = TextureFactory.GetTextureData(Vmm, TicPosition);
- Gpu.Renderer.Texture.Create(Key, Data, NewImage);
- }
+ Key = Vmm.GetPhysicalAddress(Key);
- Gpu.Renderer.Texture.Bind(Key, TexIndex);
+ if (Key == -1)
+ {
+ //FIXME: Shouldn't ignore invalid addresses.
+ return;
}
+ Gpu.ResourceManager.SendTexture(Vmm, Key, Image, TexIndex);
+
Gpu.Renderer.Texture.SetSampler(Sampler);
}
@@ -876,11 +850,6 @@ namespace Ryujinx.Graphics
Registers[(int)Reg] = Value;
}
- public bool IsFrameBufferPosition(long Position)
- {
- return FrameBuffers.Contains(Position);
- }
-
private bool QueryKeyUpload(NvGpuVmm Vmm, long Key, long Size, NvGpuBufferType Type)
{
List<long> Uploaded = UploadedKeys[(int)Type];