Use correct frame buffer and viewport sizes, started to clean up the copy engine
This commit is contained in:
parent
06e84b40f4
commit
035f39038e
6 changed files with 67 additions and 97 deletions
|
@ -78,11 +78,6 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
|
||||
public void Create(long Key, int Width, int Height)
|
||||
{
|
||||
//TODO: We should either use the original frame buffer size,
|
||||
//or just remove the Width/Height arguments.
|
||||
Width = Window.Width;
|
||||
Height = Window.Height;
|
||||
|
||||
if (Fbs.TryGetValue(Key, out FrameBuffer Fb))
|
||||
{
|
||||
if (Fb.Width != Width ||
|
||||
|
@ -125,8 +120,6 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
|
||||
GL.DrawBuffer(DrawBufferMode.ColorAttachment0);
|
||||
|
||||
GL.Viewport(0, 0, Width, Height);
|
||||
|
||||
Fbs.Add(Key, Fb);
|
||||
}
|
||||
|
||||
|
@ -230,7 +223,16 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
{
|
||||
Viewport = new Rect(X, Y, Width, Height);
|
||||
|
||||
//TODO
|
||||
SetViewport(Viewport);
|
||||
}
|
||||
|
||||
private void SetViewport(Rect Viewport)
|
||||
{
|
||||
GL.Viewport(
|
||||
Viewport.X,
|
||||
Viewport.Y,
|
||||
Viewport.Width,
|
||||
Viewport.Height);
|
||||
}
|
||||
|
||||
public void Render()
|
||||
|
@ -300,7 +302,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
GL.Enable(EnableCap.Blend);
|
||||
}
|
||||
|
||||
//GL.Viewport(0, 0, 1280, 720);
|
||||
SetViewport(Viewport);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -329,15 +331,6 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
}
|
||||
}
|
||||
|
||||
private void SetViewport(Rect Viewport)
|
||||
{
|
||||
GL.Viewport(
|
||||
Viewport.X,
|
||||
Viewport.Y,
|
||||
Viewport.Width,
|
||||
Viewport.Height);
|
||||
}
|
||||
|
||||
private void EnsureInitialized()
|
||||
{
|
||||
if (!IsInitialized)
|
||||
|
|
|
@ -64,6 +64,8 @@ namespace Ryujinx.HLE.Gpu.Engines
|
|||
bool SrcLinear = ReadRegister(NvGpuEngine2dReg.SrcLinear) != 0;
|
||||
int SrcWidth = ReadRegister(NvGpuEngine2dReg.SrcWidth);
|
||||
int SrcHeight = ReadRegister(NvGpuEngine2dReg.SrcHeight);
|
||||
int SrcPitch = ReadRegister(NvGpuEngine2dReg.SrcPitch);
|
||||
int SrcBlkDim = ReadRegister(NvGpuEngine2dReg.SrcBlockDimensions);
|
||||
|
||||
bool DstLinear = ReadRegister(NvGpuEngine2dReg.DstLinear) != 0;
|
||||
int DstWidth = ReadRegister(NvGpuEngine2dReg.DstWidth);
|
||||
|
@ -71,78 +73,64 @@ namespace Ryujinx.HLE.Gpu.Engines
|
|||
int DstPitch = ReadRegister(NvGpuEngine2dReg.DstPitch);
|
||||
int DstBlkDim = ReadRegister(NvGpuEngine2dReg.DstBlockDimensions);
|
||||
|
||||
TextureSwizzle SrcSwizzle = SrcLinear
|
||||
? TextureSwizzle.Pitch
|
||||
: TextureSwizzle.BlockLinear;
|
||||
|
||||
TextureSwizzle DstSwizzle = DstLinear
|
||||
? TextureSwizzle.Pitch
|
||||
: TextureSwizzle.BlockLinear;
|
||||
|
||||
int SrcBlockHeight = 1 << ((SrcBlkDim >> 4) & 0xf);
|
||||
int DstBlockHeight = 1 << ((DstBlkDim >> 4) & 0xf);
|
||||
|
||||
long Key = Vmm.GetPhysicalAddress(MakeInt64From2xInt32(NvGpuEngine2dReg.SrcAddress));
|
||||
|
||||
long SrcAddress = MakeInt64From2xInt32(NvGpuEngine2dReg.SrcAddress);
|
||||
long DstAddress = MakeInt64From2xInt32(NvGpuEngine2dReg.DstAddress);
|
||||
|
||||
bool IsFbTexture = Gpu.Engine3d.IsFrameBufferPosition(Key);
|
||||
long SrcKey = Vmm.GetPhysicalAddress(SrcAddress);
|
||||
long DstKey = Vmm.GetPhysicalAddress(DstAddress);
|
||||
|
||||
if (IsFbTexture && DstLinear)
|
||||
bool IsSrcFb = Gpu.Engine3d.IsFrameBufferPosition(SrcKey);
|
||||
bool IsDstFb = Gpu.Engine3d.IsFrameBufferPosition(DstKey);
|
||||
|
||||
if (IsSrcFb && DstLinear)
|
||||
{
|
||||
DstSwizzle = TextureSwizzle.BlockLinear;
|
||||
}
|
||||
|
||||
if (IsFbTexture)
|
||||
{
|
||||
//TODO: Change this when the correct frame buffer resolution is used.
|
||||
//Currently, the frame buffer size is hardcoded to 1280x720.
|
||||
SrcWidth = 1280;
|
||||
SrcHeight = 720;
|
||||
}
|
||||
TextureInfo SrcTexture = new TextureInfo(
|
||||
SrcAddress,
|
||||
SrcWidth,
|
||||
SrcHeight,
|
||||
SrcPitch,
|
||||
SrcBlockHeight, 1,
|
||||
SrcSwizzle,
|
||||
GalTextureFormat.A8B8G8R8);
|
||||
|
||||
TextureInfo DstTexture = new TextureInfo(
|
||||
DstAddress,
|
||||
SrcWidth,
|
||||
SrcHeight,
|
||||
DstWidth,
|
||||
DstHeight,
|
||||
DstPitch,
|
||||
DstBlockHeight, 1,
|
||||
DstSwizzle,
|
||||
GalTextureFormat.A8B8G8R8);
|
||||
|
||||
if (IsFbTexture)
|
||||
//TODO: fb -> fb copies, tex -> fb copies, formats other than RGBA8,
|
||||
//make it throw for unimpl stuff (like the copy mode)...
|
||||
if (IsSrcFb)
|
||||
{
|
||||
Gpu.Renderer.FrameBuffer.GetBufferData(Key, (byte[] Buffer) =>
|
||||
Gpu.Renderer.FrameBuffer.GetBufferData(SrcKey, (byte[] Buffer) =>
|
||||
{
|
||||
CopyTexture(
|
||||
Vmm,
|
||||
DstTexture,
|
||||
Buffer,
|
||||
SrcWidth,
|
||||
SrcHeight);
|
||||
TextureWriter.Write(Vmm, DstTexture, Buffer);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
long Size = SrcWidth * SrcHeight * 4;
|
||||
|
||||
byte[] Buffer = Vmm.ReadBytes(SrcAddress, Size);
|
||||
|
||||
CopyTexture(
|
||||
Vmm,
|
||||
DstTexture,
|
||||
Buffer,
|
||||
SrcWidth,
|
||||
SrcHeight);
|
||||
TextureWriter.Write(Vmm, DstTexture, TextureReader.Read(Vmm, SrcTexture));
|
||||
}
|
||||
}
|
||||
|
||||
private void CopyTexture(
|
||||
NvGpuVmm Vmm,
|
||||
TextureInfo Texture,
|
||||
byte[] Buffer,
|
||||
int Width,
|
||||
int Height)
|
||||
{
|
||||
TextureWriter.Write(Vmm, Texture, Buffer, Width, Height);
|
||||
}
|
||||
|
||||
private long MakeInt64From2xInt32(NvGpuEngine2dReg Reg)
|
||||
{
|
||||
return
|
||||
|
|
|
@ -132,10 +132,17 @@ namespace Ryujinx.HLE.Gpu.Engines
|
|||
int Width = ReadRegister(NvGpuEngine3dReg.FrameBufferNWidth + FbIndex * 0x10);
|
||||
int Height = ReadRegister(NvGpuEngine3dReg.FrameBufferNHeight + FbIndex * 0x10);
|
||||
|
||||
//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.FrameBuffer.Create(Key, 1280, 720);
|
||||
int ViewportXW = ReadRegister(NvGpuEngine3dReg.ViewportNHoriz + FbIndex * 4);
|
||||
int ViewportYH = ReadRegister(NvGpuEngine3dReg.ViewportNVert + FbIndex * 4);
|
||||
|
||||
Gpu.Renderer.FrameBuffer.Create(Key, Width, Height);
|
||||
Gpu.Renderer.FrameBuffer.Bind(Key);
|
||||
|
||||
Gpu.Renderer.FrameBuffer.SetViewport(
|
||||
(ushort)(ViewportXW >> 0),
|
||||
(ushort)(ViewportYH >> 0),
|
||||
(ushort)(ViewportXW >> 16),
|
||||
(ushort)(ViewportYH >> 16));
|
||||
}
|
||||
|
||||
private long[] UploadShaders(NvGpuVmm Vmm)
|
||||
|
@ -195,8 +202,8 @@ namespace Ryujinx.HLE.Gpu.Engines
|
|||
Gpu.Renderer.Shader.Bind(Key);
|
||||
}
|
||||
|
||||
float SignX = GetFlipSign(NvGpuEngine3dReg.ViewportScaleX);
|
||||
float SignY = GetFlipSign(NvGpuEngine3dReg.ViewportScaleY);
|
||||
float SignX = GetFlipSign(NvGpuEngine3dReg.ViewportNScaleX);
|
||||
float SignY = GetFlipSign(NvGpuEngine3dReg.ViewportNScaleY);
|
||||
|
||||
Gpu.Renderer.Shader.SetFlip(SignX, SignY);
|
||||
|
||||
|
@ -220,8 +227,8 @@ namespace Ryujinx.HLE.Gpu.Engines
|
|||
|
||||
private void SetFrontFace()
|
||||
{
|
||||
float SignX = GetFlipSign(NvGpuEngine3dReg.ViewportScaleX);
|
||||
float SignY = GetFlipSign(NvGpuEngine3dReg.ViewportScaleY);
|
||||
float SignX = GetFlipSign(NvGpuEngine3dReg.ViewportNScaleX);
|
||||
float SignY = GetFlipSign(NvGpuEngine3dReg.ViewportNScaleY);
|
||||
|
||||
GalFrontFace FrontFace = (GalFrontFace)ReadRegister(NvGpuEngine3dReg.FrontFace);
|
||||
|
||||
|
|
|
@ -6,12 +6,14 @@ namespace Ryujinx.HLE.Gpu.Engines
|
|||
FrameBufferNWidth = 0x202,
|
||||
FrameBufferNHeight = 0x203,
|
||||
FrameBufferNFormat = 0x204,
|
||||
ViewportScaleX = 0x280,
|
||||
ViewportScaleY = 0x281,
|
||||
ViewportScaleZ = 0x282,
|
||||
ViewportTranslateX = 0x283,
|
||||
ViewportTranslateY = 0x284,
|
||||
ViewportTranslateZ = 0x285,
|
||||
ViewportNScaleX = 0x280,
|
||||
ViewportNScaleY = 0x281,
|
||||
ViewportNScaleZ = 0x282,
|
||||
ViewportNTranslateX = 0x283,
|
||||
ViewportNTranslateY = 0x284,
|
||||
ViewportNTranslateZ = 0x285,
|
||||
ViewportNHoriz = 0x300,
|
||||
ViewportNVert = 0x301,
|
||||
VertexArrayFirst = 0x35d,
|
||||
VertexArrayCount = 0x35e,
|
||||
ClearDepth = 0x364,
|
||||
|
|
|
@ -6,27 +6,7 @@ namespace Ryujinx.HLE.Gpu.Texture
|
|||
{
|
||||
static class TextureWriter
|
||||
{
|
||||
public static void Write(
|
||||
IAMemory Memory,
|
||||
TextureInfo Texture,
|
||||
byte[] Data,
|
||||
int Width,
|
||||
int Height)
|
||||
{
|
||||
switch (Texture.Format)
|
||||
{
|
||||
case GalTextureFormat.A8B8G8R8: Write4Bpp(Memory, Texture, Data, Width, Height); break;
|
||||
|
||||
default: throw new NotImplementedException(Texture.Format.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
private unsafe static void Write4Bpp(
|
||||
IAMemory Memory,
|
||||
TextureInfo Texture,
|
||||
byte[] Data,
|
||||
int Width,
|
||||
int Height)
|
||||
public unsafe static void Write(IAMemory Memory, TextureInfo Texture, byte[] Data)
|
||||
{
|
||||
ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, 1, 4);
|
||||
|
||||
|
@ -38,8 +18,8 @@ namespace Ryujinx.HLE.Gpu.Texture
|
|||
{
|
||||
long InOffs = 0;
|
||||
|
||||
for (int Y = 0; Y < Height; Y++)
|
||||
for (int X = 0; X < Width; X++)
|
||||
for (int Y = 0; Y < Texture.Height; Y++)
|
||||
for (int X = 0; X < Texture.Width; X++)
|
||||
{
|
||||
long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y);
|
||||
|
||||
|
|
|
@ -279,8 +279,8 @@ namespace Ryujinx.HLE.OsHle.Services.Android
|
|||
|
||||
private void SendFrameBuffer(ServiceCtx Context, int Slot)
|
||||
{
|
||||
int FbWidth = 1280;
|
||||
int FbHeight = 720;
|
||||
int FbWidth = BufferQueue[Slot].Data.Width;
|
||||
int FbHeight = BufferQueue[Slot].Data.Height;
|
||||
|
||||
int NvMapHandle = BitConverter.ToInt32(BufferQueue[Slot].Data.RawData, 0x4c);
|
||||
int BufferOffset = BitConverter.ToInt32(BufferQueue[Slot].Data.RawData, 0x50);
|
||||
|
|
Loading…
Add table
Reference in a new issue