Allow copy between frame buffers
This commit is contained in:
parent
095db47e13
commit
fdb9d53e00
3 changed files with 70 additions and 29 deletions
|
@ -22,6 +22,18 @@ namespace Ryujinx.Graphics.Gal
|
||||||
|
|
||||||
void Render();
|
void Render();
|
||||||
|
|
||||||
|
void Copy(
|
||||||
|
long SrcKey,
|
||||||
|
long DstKey,
|
||||||
|
int SrcX0,
|
||||||
|
int SrcY0,
|
||||||
|
int SrcX1,
|
||||||
|
int SrcY1,
|
||||||
|
int DstX0,
|
||||||
|
int DstY0,
|
||||||
|
int DstX1,
|
||||||
|
int DstY1);
|
||||||
|
|
||||||
void GetBufferData(long Key, Action<byte[]> Callback);
|
void GetBufferData(long Key, Action<byte[]> Callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -304,6 +304,34 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Copy(
|
||||||
|
long SrcKey,
|
||||||
|
long DstKey,
|
||||||
|
int SrcX0,
|
||||||
|
int SrcY0,
|
||||||
|
int SrcX1,
|
||||||
|
int SrcY1,
|
||||||
|
int DstX0,
|
||||||
|
int DstY0,
|
||||||
|
int DstX1,
|
||||||
|
int DstY1)
|
||||||
|
{
|
||||||
|
if (Fbs.TryGetValue(SrcKey, out FrameBuffer SrcFb) &&
|
||||||
|
Fbs.TryGetValue(DstKey, out FrameBuffer DstFb))
|
||||||
|
{
|
||||||
|
GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, SrcFb.Handle);
|
||||||
|
GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, DstFb.Handle);
|
||||||
|
|
||||||
|
GL.Clear(ClearBufferMask.ColorBufferBit);
|
||||||
|
|
||||||
|
GL.BlitFramebuffer(
|
||||||
|
SrcX0, SrcY0, SrcX1, SrcY1,
|
||||||
|
DstX0, DstY0, DstX1, DstY1,
|
||||||
|
ClearBufferMask.ColorBufferBit,
|
||||||
|
BlitFramebufferFilter.Linear);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void GetBufferData(long Key, Action<byte[]> Callback)
|
public void GetBufferData(long Key, Action<byte[]> Callback)
|
||||||
{
|
{
|
||||||
if (Fbs.TryGetValue(Key, out FrameBuffer Fb))
|
if (Fbs.TryGetValue(Key, out FrameBuffer Fb))
|
||||||
|
|
|
@ -77,14 +77,16 @@ namespace Ryujinx.HLE.Gpu.Engines
|
||||||
|
|
||||||
int DstBlockHeight = 1 << ((DstBlkDim >> 4) & 0xf);
|
int DstBlockHeight = 1 << ((DstBlkDim >> 4) & 0xf);
|
||||||
|
|
||||||
long Key = Vmm.GetPhysicalAddress(MakeInt64From2xInt32(NvGpuEngine2dReg.SrcAddress));
|
|
||||||
|
|
||||||
long SrcAddress = MakeInt64From2xInt32(NvGpuEngine2dReg.SrcAddress);
|
long SrcAddress = MakeInt64From2xInt32(NvGpuEngine2dReg.SrcAddress);
|
||||||
long DstAddress = MakeInt64From2xInt32(NvGpuEngine2dReg.DstAddress);
|
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;
|
DstSwizzle = TextureSwizzle.BlockLinear;
|
||||||
}
|
}
|
||||||
|
@ -93,26 +95,40 @@ namespace Ryujinx.HLE.Gpu.Engines
|
||||||
DstAddress,
|
DstAddress,
|
||||||
DstWidth,
|
DstWidth,
|
||||||
DstHeight,
|
DstHeight,
|
||||||
DstBlockHeight,
|
DstPitch,
|
||||||
DstBlockHeight,
|
DstBlockHeight,
|
||||||
DstSwizzle,
|
DstSwizzle,
|
||||||
GalTextureFormat.A8B8G8R8);
|
GalTextureFormat.A8B8G8R8);
|
||||||
|
|
||||||
if (IsFbTexture)
|
if (IsSrcFb && IsDstFb)
|
||||||
|
{
|
||||||
|
//TODO: Change this when the correct frame buffer resolution is used.
|
||||||
|
//Currently, the frame buffer size is hardcoded to 1280x720.
|
||||||
|
DstWidth = 1280;
|
||||||
|
DstHeight = 720;
|
||||||
|
|
||||||
|
Gpu.Renderer.FrameBuffer.Copy(
|
||||||
|
SrcKey,
|
||||||
|
DstKey,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
SrcWidth,
|
||||||
|
SrcHeight,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
DstWidth,
|
||||||
|
DstHeight);
|
||||||
|
}
|
||||||
|
else if (IsSrcFb)
|
||||||
{
|
{
|
||||||
//TODO: Change this when the correct frame buffer resolution is used.
|
//TODO: Change this when the correct frame buffer resolution is used.
|
||||||
//Currently, the frame buffer size is hardcoded to 1280x720.
|
//Currently, the frame buffer size is hardcoded to 1280x720.
|
||||||
SrcWidth = 1280;
|
SrcWidth = 1280;
|
||||||
SrcHeight = 720;
|
SrcHeight = 720;
|
||||||
|
|
||||||
Gpu.Renderer.FrameBuffer.GetBufferData(Key, (byte[] Buffer) =>
|
Gpu.Renderer.FrameBuffer.GetBufferData(SrcKey, (byte[] Buffer) =>
|
||||||
{
|
{
|
||||||
CopyTexture(
|
TextureWriter.Write(Vmm, DstTexture, Buffer, SrcWidth, SrcHeight);
|
||||||
Vmm,
|
|
||||||
DstTexture,
|
|
||||||
Buffer,
|
|
||||||
SrcWidth,
|
|
||||||
SrcHeight);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -121,25 +137,10 @@ namespace Ryujinx.HLE.Gpu.Engines
|
||||||
|
|
||||||
byte[] Buffer = Vmm.ReadBytes(SrcAddress, Size);
|
byte[] Buffer = Vmm.ReadBytes(SrcAddress, Size);
|
||||||
|
|
||||||
CopyTexture(
|
TextureWriter.Write(Vmm, DstTexture, Buffer, SrcWidth, SrcHeight);
|
||||||
Vmm,
|
|
||||||
DstTexture,
|
|
||||||
Buffer,
|
|
||||||
SrcWidth,
|
|
||||||
SrcHeight);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
private long MakeInt64From2xInt32(NvGpuEngine2dReg Reg)
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
|
|
Loading…
Reference in a new issue