Allow texture copy between frame buffers
This commit is contained in:
parent
9069e17222
commit
efab5d7d06
3 changed files with 152 additions and 18 deletions
|
@ -22,6 +22,25 @@ 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);
|
||||||
|
|
||||||
|
void SetBufferData(
|
||||||
|
long Key,
|
||||||
|
int Width,
|
||||||
|
int Height,
|
||||||
|
GalTextureFormat Format,
|
||||||
|
byte[] Buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -306,6 +306,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))
|
||||||
|
@ -331,6 +359,37 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetBufferData(
|
||||||
|
long Key,
|
||||||
|
int Width,
|
||||||
|
int Height,
|
||||||
|
GalTextureFormat Format,
|
||||||
|
byte[] Buffer)
|
||||||
|
{
|
||||||
|
if (Fbs.TryGetValue(Key, out FrameBuffer Fb))
|
||||||
|
{
|
||||||
|
GL.BindTexture(TextureTarget.Texture2D, Fb.TexHandle);
|
||||||
|
|
||||||
|
const int Level = 0;
|
||||||
|
const int Border = 0;
|
||||||
|
|
||||||
|
const PixelInternalFormat InternalFmt = PixelInternalFormat.Rgba;
|
||||||
|
|
||||||
|
(PixelFormat GlFormat, PixelType Type) = OGLEnumConverter.GetTextureFormat(Format);
|
||||||
|
|
||||||
|
GL.TexImage2D(
|
||||||
|
TextureTarget.Texture2D,
|
||||||
|
Level,
|
||||||
|
InternalFmt,
|
||||||
|
Width,
|
||||||
|
Height,
|
||||||
|
Border,
|
||||||
|
GlFormat,
|
||||||
|
Type,
|
||||||
|
Buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void EnsureInitialized()
|
private void EnsureInitialized()
|
||||||
{
|
{
|
||||||
if (!IsInitialized)
|
if (!IsInitialized)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using Ryujinx.Graphics.Gal;
|
using Ryujinx.Graphics.Gal;
|
||||||
using Ryujinx.HLE.Gpu.Memory;
|
using Ryujinx.HLE.Gpu.Memory;
|
||||||
using Ryujinx.HLE.Gpu.Texture;
|
using Ryujinx.HLE.Gpu.Texture;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.Gpu.Engines
|
namespace Ryujinx.HLE.Gpu.Engines
|
||||||
|
@ -93,7 +94,9 @@ namespace Ryujinx.HLE.Gpu.Engines
|
||||||
bool IsSrcFb = Gpu.Engine3d.IsFrameBufferPosition(SrcKey);
|
bool IsSrcFb = Gpu.Engine3d.IsFrameBufferPosition(SrcKey);
|
||||||
bool IsDstFb = Gpu.Engine3d.IsFrameBufferPosition(DstKey);
|
bool IsDstFb = Gpu.Engine3d.IsFrameBufferPosition(DstKey);
|
||||||
|
|
||||||
TextureInfo SrcTexture = new TextureInfo(
|
TextureInfo SrcTexture()
|
||||||
|
{
|
||||||
|
return new TextureInfo(
|
||||||
SrcAddress,
|
SrcAddress,
|
||||||
SrcWidth,
|
SrcWidth,
|
||||||
SrcHeight,
|
SrcHeight,
|
||||||
|
@ -101,8 +104,11 @@ namespace Ryujinx.HLE.Gpu.Engines
|
||||||
SrcBlockHeight, 1,
|
SrcBlockHeight, 1,
|
||||||
SrcSwizzle,
|
SrcSwizzle,
|
||||||
GalTextureFormat.A8B8G8R8);
|
GalTextureFormat.A8B8G8R8);
|
||||||
|
}
|
||||||
|
|
||||||
TextureInfo DstTexture = new TextureInfo(
|
TextureInfo DstTexture()
|
||||||
|
{
|
||||||
|
return new TextureInfo(
|
||||||
DstAddress,
|
DstAddress,
|
||||||
DstWidth,
|
DstWidth,
|
||||||
DstHeight,
|
DstHeight,
|
||||||
|
@ -110,19 +116,69 @@ namespace Ryujinx.HLE.Gpu.Engines
|
||||||
DstBlockHeight, 1,
|
DstBlockHeight, 1,
|
||||||
DstSwizzle,
|
DstSwizzle,
|
||||||
GalTextureFormat.A8B8G8R8);
|
GalTextureFormat.A8B8G8R8);
|
||||||
|
}
|
||||||
|
|
||||||
//TODO: fb -> fb copies, tex -> fb copies, formats other than RGBA8,
|
//TODO: fb -> fb copies, tex -> fb copies, formats other than RGBA8,
|
||||||
//make it throw for unimpl stuff (like the copy mode)...
|
//make it throw for unimpl stuff (like the copy mode)...
|
||||||
|
if (IsSrcFb && IsDstFb)
|
||||||
|
{
|
||||||
|
//Frame Buffer -> Frame Buffer copy.
|
||||||
|
Gpu.Renderer.FrameBuffer.Copy(
|
||||||
|
SrcKey,
|
||||||
|
DstKey,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
SrcWidth,
|
||||||
|
SrcHeight,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
DstWidth,
|
||||||
|
DstHeight);
|
||||||
|
}
|
||||||
if (IsSrcFb)
|
if (IsSrcFb)
|
||||||
{
|
{
|
||||||
|
//Frame Buffer -> Texture copy.
|
||||||
Gpu.Renderer.FrameBuffer.GetBufferData(SrcKey, (byte[] Buffer) =>
|
Gpu.Renderer.FrameBuffer.GetBufferData(SrcKey, (byte[] Buffer) =>
|
||||||
{
|
{
|
||||||
TextureWriter.Write(Vmm, DstTexture, Buffer);
|
TextureInfo Src = SrcTexture();
|
||||||
|
TextureInfo Dst = DstTexture();
|
||||||
|
|
||||||
|
if (Src.Width != Dst.Width ||
|
||||||
|
Src.Height != Dst.Height)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException("Texture resizing is not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
TextureWriter.Write(Vmm, Dst, Buffer);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
else if (IsDstFb)
|
||||||
|
{
|
||||||
|
//Texture -> Frame Buffer copy.
|
||||||
|
const GalTextureFormat Format = GalTextureFormat.A8B8G8R8;
|
||||||
|
|
||||||
|
byte[] Buffer = TextureReader.Read(Vmm, SrcTexture());
|
||||||
|
|
||||||
|
Gpu.Renderer.FrameBuffer.SetBufferData(
|
||||||
|
DstKey,
|
||||||
|
DstWidth,
|
||||||
|
DstHeight,
|
||||||
|
Format,
|
||||||
|
Buffer);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TextureWriter.Write(Vmm, DstTexture, TextureReader.Read(Vmm, SrcTexture));
|
//Texture -> Texture copy.
|
||||||
|
TextureInfo Src = SrcTexture();
|
||||||
|
TextureInfo Dst = DstTexture();
|
||||||
|
|
||||||
|
if (Src.Width != Dst.Width ||
|
||||||
|
Src.Height != Dst.Height)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException("Texture resizing is not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
TextureWriter.Write(Vmm, Dst, TextureReader.Read(Vmm, Src));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue