diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2018-09-18 01:30:35 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-09-18 01:30:35 -0300 |
| commit | d4187aaa9d7194aa26d04aee838edbc3a38f1862 (patch) | |
| tree | 06fe725c1067b4aeca21749799b835d85e7d2787 /Ryujinx.Graphics/NvGpuEngine3d.cs | |
| parent | bec95cacc1061f91373a1e3a1411981af7fe2e4e (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.cs | 123 |
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]; |
