aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics/Gpu
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-04-13 15:12:58 -0300
committerGitHub <noreply@github.com>2018-04-13 15:12:58 -0300
commitc8c86a3854fb3c96e65eca6b59d6058270a21a17 (patch)
tree0f280e0b595d953ca081e493eda41d884fb34ef6 /Ryujinx.Graphics/Gpu
parent262b5b80541d23ed248d5b4f2220a479a35d5969 (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.cs6
-rw-r--r--Ryujinx.Graphics/Gpu/NvGpuEngine3d.cs103
-rw-r--r--Ryujinx.Graphics/Gpu/NvGpuEngine3dReg.cs8
-rw-r--r--Ryujinx.Graphics/Gpu/Texture.cs20
-rw-r--r--Ryujinx.Graphics/Gpu/TextureReader.cs2
-rw-r--r--Ryujinx.Graphics/Gpu/TextureSwizzle.cs2
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,