diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2018-04-13 15:12:58 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-04-13 15:12:58 -0300 |
| commit | c8c86a3854fb3c96e65eca6b59d6058270a21a17 (patch) | |
| tree | 0f280e0b595d953ca081e493eda41d884fb34ef6 /Ryujinx.Graphics/Gpu | |
| parent | 262b5b80541d23ed248d5b4f2220a479a35d5969 (diff) | |
Fix for current framebuffer issues (#78)
[GPU] Fix some of the current framebuffer issues
Diffstat (limited to 'Ryujinx.Graphics/Gpu')
| -rw-r--r-- | Ryujinx.Graphics/Gpu/NsGpu.cs | 6 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Gpu/NvGpuEngine3d.cs | 103 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Gpu/NvGpuEngine3dReg.cs | 8 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Gpu/Texture.cs | 20 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Gpu/TextureReader.cs | 2 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Gpu/TextureSwizzle.cs | 2 |
6 files changed, 96 insertions, 45 deletions
diff --git a/Ryujinx.Graphics/Gpu/NsGpu.cs b/Ryujinx.Graphics/Gpu/NsGpu.cs index 57380502..9a2e9012 100644 --- a/Ryujinx.Graphics/Gpu/NsGpu.cs +++ b/Ryujinx.Graphics/Gpu/NsGpu.cs @@ -9,9 +9,9 @@ namespace Ryujinx.Graphics.Gpu internal NsGpuMemoryMgr MemoryMgr { get; private set; } - public NvGpuFifo Fifo; + public NvGpuFifo Fifo { get; private set; } - internal NvGpuEngine3d Engine3d; + public NvGpuEngine3d Engine3d { get; private set; } private Thread FifoProcessing; @@ -29,7 +29,7 @@ namespace Ryujinx.Graphics.Gpu KeepRunning = true; - FifoProcessing = new Thread(ProcessFifo); + FifoProcessing = new Thread(ProcessFifo); FifoProcessing.Start(); } diff --git a/Ryujinx.Graphics/Gpu/NvGpuEngine3d.cs b/Ryujinx.Graphics/Gpu/NvGpuEngine3d.cs index f4486f46..1142e4aa 100644 --- a/Ryujinx.Graphics/Gpu/NvGpuEngine3d.cs +++ b/Ryujinx.Graphics/Gpu/NvGpuEngine3d.cs @@ -5,7 +5,7 @@ using System.Collections.Generic; namespace Ryujinx.Graphics.Gpu { - class NvGpuEngine3d : INvGpuEngine + public class NvGpuEngine3d : INvGpuEngine { public int[] Registers { get; private set; } @@ -20,9 +20,9 @@ namespace Ryujinx.Graphics.Gpu public int Size; } - private ConstBuffer[] Cbs; + private ConstBuffer[] ConstBuffers; - private bool HasDataToRender; + private HashSet<long> FrameBuffers; public NvGpuEngine3d(NsGpu Gpu) { @@ -48,7 +48,9 @@ namespace Ryujinx.Graphics.Gpu AddMethod(0x8e4, 16, 1, CbData); AddMethod(0x904, 1, 1, CbBind); - Cbs = new ConstBuffer[18]; + ConstBuffers = new ConstBuffer[18]; + + FrameBuffers = new HashSet<long>(); } public void CallMethod(AMemory Memory, NsGpuPBEntry PBEntry) @@ -76,19 +78,10 @@ namespace Ryujinx.Graphics.Gpu UploadTextures(Memory, Tags); UploadUniforms(Memory); UploadVertexArrays(Memory); - - HasDataToRender = true; } private void ClearBuffers(AMemory Memory, NsGpuPBEntry PBEntry) { - if (HasDataToRender) - { - HasDataToRender = false; - - Gpu.Renderer.DrawFrameBuffer(0); - } - int Arg0 = PBEntry.Arguments[0]; int FbIndex = (Arg0 >> 6) & 0xf; @@ -99,16 +92,23 @@ namespace Ryujinx.Graphics.Gpu SetFrameBuffer(0); - Gpu.Renderer.ClearBuffers(Layer, Flags); + //TODO: Enable this once the frame buffer problems are fixed. + //Gpu.Renderer.ClearBuffers(Layer, Flags); } private void SetFrameBuffer(int FbIndex) { - int Width = ReadRegister(NvGpuEngine3dReg.FrameBufferNWidth + FbIndex * 0x10); - int Height = ReadRegister(NvGpuEngine3dReg.FrameBufferNHeight + FbIndex * 0x10); + long Address = MakeInt64From2xInt32(NvGpuEngine3dReg.FrameBufferNAddress + FbIndex * 0x10); + + FrameBuffers.Add(Address); + + int Width = ReadRegister(NvGpuEngine3dReg.FrameBufferNWidth + FbIndex * 0x10); + int Height = ReadRegister(NvGpuEngine3dReg.FrameBufferNHeight + FbIndex * 0x10); - Gpu.Renderer.SetFb(FbIndex, Width, Height); - Gpu.Renderer.BindFrameBuffer(FbIndex); + //Note: Using the Width/Height results seems to give incorrect results. + //Maybe the size of all frame buffers is hardcoded to screen size? This seems unlikely. + Gpu.Renderer.CreateFrameBuffer(Address, 1280, 720); + Gpu.Renderer.BindFrameBuffer(Address); } private long[] UploadShaders(AMemory Memory) @@ -167,23 +167,24 @@ namespace Ryujinx.Graphics.Gpu private void SetAlphaBlending() { - bool BlendEnableMaster = (ReadRegister(NvGpuEngine3dReg.BlendEnableMaster) & 1) != 0; + //TODO: Support independent blend properly. + bool Enable = (ReadRegister(NvGpuEngine3dReg.IBlendEnable) & 1) != 0; - Gpu.Renderer.SetBlendEnable(BlendEnableMaster); + Gpu.Renderer.SetBlendEnable(Enable); - bool BlendSeparateAlpha = (ReadRegister(NvGpuEngine3dReg.BlendSeparateAlpha) & 1) != 0; + bool BlendSeparateAlpha = (ReadRegister(NvGpuEngine3dReg.IBlendNSeparateAlpha) & 1) != 0; - GalBlendEquation EquationRgb = (GalBlendEquation)ReadRegister(NvGpuEngine3dReg.BlendEquationRgb); + GalBlendEquation EquationRgb = (GalBlendEquation)ReadRegister(NvGpuEngine3dReg.IBlendNEquationRgb); - GalBlendFactor FuncSrcRgb = (GalBlendFactor)ReadRegister(NvGpuEngine3dReg.BlendFuncSrcRgb); - GalBlendFactor FuncDstRgb = (GalBlendFactor)ReadRegister(NvGpuEngine3dReg.BlendFuncDstRgb); + GalBlendFactor FuncSrcRgb = (GalBlendFactor)ReadRegister(NvGpuEngine3dReg.IBlendNFuncSrcRgb); + GalBlendFactor FuncDstRgb = (GalBlendFactor)ReadRegister(NvGpuEngine3dReg.IBlendNFuncDstRgb); if (BlendSeparateAlpha) { - GalBlendEquation EquationAlpha = (GalBlendEquation)ReadRegister(NvGpuEngine3dReg.BlendEquationAlpha); + GalBlendEquation EquationAlpha = (GalBlendEquation)ReadRegister(NvGpuEngine3dReg.IBlendNEquationAlpha); - GalBlendFactor FuncSrcAlpha = (GalBlendFactor)ReadRegister(NvGpuEngine3dReg.BlendFuncSrcAlpha); - GalBlendFactor FuncDstAlpha = (GalBlendFactor)ReadRegister(NvGpuEngine3dReg.BlendFuncDstAlpha); + GalBlendFactor FuncSrcAlpha = (GalBlendFactor)ReadRegister(NvGpuEngine3dReg.IBlendNFuncSrcAlpha); + GalBlendFactor FuncDstAlpha = (GalBlendFactor)ReadRegister(NvGpuEngine3dReg.IBlendNFuncDstAlpha); Gpu.Renderer.SetBlendSeparate( EquationRgb, @@ -205,11 +206,13 @@ namespace Ryujinx.Graphics.Gpu int TextureCbIndex = ReadRegister(NvGpuEngine3dReg.TextureCbIndex); - long BasePosition = Cbs[TextureCbIndex].Position; + long BasePosition = ConstBuffers[TextureCbIndex].Position; - long Size = (uint)Cbs[TextureCbIndex].Size; + long Size = (uint)ConstBuffers[TextureCbIndex].Size; - int TexIndex = 0; + //Note: On the emulator renderer, Texture Unit 0 is + //reserved for drawing the frame buffer. + int TexIndex = 1; for (int Index = 0; Index < Tags.Length; Index++) { @@ -241,8 +244,25 @@ namespace Ryujinx.Graphics.Gpu TicPosition += TicIndex * 0x20; TscPosition += TscIndex * 0x20; - Gpu.Renderer.SetTexture(TexIndex, TextureFactory.MakeTexture(Gpu, Memory, TicPosition)); - Gpu.Renderer.SetSampler(TexIndex, TextureFactory.MakeSampler(Gpu, Memory, TscPosition)); + GalTextureSampler Sampler = TextureFactory.MakeSampler(Gpu, Memory, TscPosition); + + long TextureAddress = Memory.ReadInt64(TicPosition + 4) & 0xffffffffffff; + + if (FrameBuffers.Contains(TextureAddress)) + { + //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.BindFrameBufferTexture(TextureAddress, TexIndex, Sampler); + } + else + { + GalTexture Texture = TextureFactory.MakeTexture(Gpu, Memory, TicPosition); + + Gpu.Renderer.SetTextureAndSampler(TexIndex, Texture, Sampler); + Gpu.Renderer.BindTexture(TexIndex); + } } private void UploadUniforms(AMemory Memory) @@ -262,9 +282,9 @@ namespace Ryujinx.Graphics.Gpu continue; } - for (int Cbuf = 0; Cbuf < Cbs.Length; Cbuf++) + for (int Cbuf = 0; Cbuf < ConstBuffers.Length; Cbuf++) { - ConstBuffer Cb = Cbs[Cbuf]; + ConstBuffer Cb = ConstBuffers[Cbuf]; if (Cb.Enabled) { @@ -379,7 +399,7 @@ namespace Ryujinx.Graphics.Gpu if (Mode == 0) { - //Write. + //Write mode. Memory.WriteInt32(Position, Seq); } } @@ -414,16 +434,16 @@ namespace Ryujinx.Graphics.Gpu if (TryGetCpuAddr(NvGpuEngine3dReg.ConstBufferNAddress, out long Position)) { - Cbs[Index].Position = Position; - Cbs[Index].Enabled = Enabled; + ConstBuffers[Index].Position = Position; + ConstBuffers[Index].Enabled = Enabled; - Cbs[Index].Size = ReadRegister(NvGpuEngine3dReg.ConstBufferNSize); + ConstBuffers[Index].Size = ReadRegister(NvGpuEngine3dReg.ConstBufferNSize); } } private int ReadCb(AMemory Memory, int Cbuf, int Offset) { - long Position = Cbs[Cbuf].Position; + long Position = ConstBuffers[Cbuf].Position; int Value = Memory.ReadInt32(Position + Offset); @@ -465,5 +485,10 @@ namespace Ryujinx.Graphics.Gpu { Registers[(int)Reg] = Value; } + + public bool IsFrameBufferPosition(long Position) + { + return FrameBuffers.Contains(Position); + } } }
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gpu/NvGpuEngine3dReg.cs b/Ryujinx.Graphics/Gpu/NvGpuEngine3dReg.cs index 4bba9abe..cb0b9d98 100644 --- a/Ryujinx.Graphics/Gpu/NvGpuEngine3dReg.cs +++ b/Ryujinx.Graphics/Gpu/NvGpuEngine3dReg.cs @@ -7,6 +7,7 @@ namespace Ryujinx.Graphics.Gpu FrameBufferNHeight = 0x203, FrameBufferNFormat = 0x204, VertexAttribNFormat = 0x458, + IBlendEnable = 0x4b9, BlendSeparateAlpha = 0x4cf, BlendEquationRgb = 0x4d0, BlendFuncSrcRgb = 0x4d1, @@ -31,6 +32,13 @@ namespace Ryujinx.Graphics.Gpu VertexArrayNControl = 0x700, VertexArrayNAddress = 0x701, VertexArrayNDivisor = 0x703, + IBlendNSeparateAlpha = 0x780, + IBlendNEquationRgb = 0x781, + IBlendNFuncSrcRgb = 0x782, + IBlendNFuncDstRgb = 0x783, + IBlendNEquationAlpha = 0x784, + IBlendNFuncSrcAlpha = 0x785, + IBlendNFuncDstAlpha = 0x786, VertexArrayNEndAddr = 0x7c0, ShaderNControl = 0x800, ShaderNOffset = 0x801, diff --git a/Ryujinx.Graphics/Gpu/Texture.cs b/Ryujinx.Graphics/Gpu/Texture.cs index 831c664d..cbfa683d 100644 --- a/Ryujinx.Graphics/Gpu/Texture.cs +++ b/Ryujinx.Graphics/Gpu/Texture.cs @@ -2,7 +2,7 @@ using Ryujinx.Graphics.Gal; namespace Ryujinx.Graphics.Gpu { - struct Texture + public struct Texture { public long Position { get; private set; } @@ -17,6 +17,24 @@ namespace Ryujinx.Graphics.Gpu public GalTextureFormat Format { get; private set; } public Texture( + long Position, + int Width, + int Height) + { + this.Position = Position; + this.Width = Width; + this.Height = Height; + + Pitch = 0; + + BlockHeight = 16; + + Swizzle = TextureSwizzle.BlockLinear; + + Format = GalTextureFormat.A8B8G8R8; + } + + public Texture( long Position, int Width, int Height, diff --git a/Ryujinx.Graphics/Gpu/TextureReader.cs b/Ryujinx.Graphics/Gpu/TextureReader.cs index b3b016ed..4c3b4fb1 100644 --- a/Ryujinx.Graphics/Gpu/TextureReader.cs +++ b/Ryujinx.Graphics/Gpu/TextureReader.cs @@ -4,7 +4,7 @@ using System; namespace Ryujinx.Graphics.Gpu { - static class TextureReader + public static class TextureReader { public static byte[] Read(AMemory Memory, Texture Texture) { diff --git a/Ryujinx.Graphics/Gpu/TextureSwizzle.cs b/Ryujinx.Graphics/Gpu/TextureSwizzle.cs index 2142e2c2..7d99279c 100644 --- a/Ryujinx.Graphics/Gpu/TextureSwizzle.cs +++ b/Ryujinx.Graphics/Gpu/TextureSwizzle.cs @@ -1,6 +1,6 @@ namespace Ryujinx.Graphics.Gpu { - enum TextureSwizzle + public enum TextureSwizzle { _1dBuffer = 0, PitchColorKey = 1, |
