aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReinUsesLisp <reinuseslisp@airmail.cc>2018-09-19 18:26:49 -0300
committergdkchan <gab.dark.100@gmail.com>2018-09-19 18:26:49 -0300
commitbed13f2022e3b81d694e51e1c29ee66f4a18f5f9 (patch)
treed9b6782550f8a5e23229d271246656e7584af813
parente04221b293370dac53e4e874cddd4f9a2a64b52f (diff)
General improvements for GpuResourceManager (#421)
* General improvements to GpuResourceManager * Address feedback * Address feedback
-rw-r--r--Ryujinx.Graphics/Gal/IGalRenderTarget.cs2
-rw-r--r--Ryujinx.Graphics/Gal/OpenGL/OGLRenderTarget.cs42
-rw-r--r--Ryujinx.Graphics/GpuResourceManager.cs86
3 files changed, 68 insertions, 62 deletions
diff --git a/Ryujinx.Graphics/Gal/IGalRenderTarget.cs b/Ryujinx.Graphics/Gal/IGalRenderTarget.cs
index 6c9166f2..7ccf0981 100644
--- a/Ryujinx.Graphics/Gal/IGalRenderTarget.cs
+++ b/Ryujinx.Graphics/Gal/IGalRenderTarget.cs
@@ -35,7 +35,5 @@ namespace Ryujinx.Graphics.Gal
int DstY1);
void Reinterpret(long Key, GalImage NewImage);
-
- byte[] GetData(long Key);
}
} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLRenderTarget.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLRenderTarget.cs
index 7dde32d8..ff5dc1b8 100644
--- a/Ryujinx.Graphics/Gal/OpenGL/OGLRenderTarget.cs
+++ b/Ryujinx.Graphics/Gal/OpenGL/OGLRenderTarget.cs
@@ -56,6 +56,8 @@ namespace Ryujinx.Graphics.Gal.OpenGL
private int DepthAttachment;
private int StencilAttachment;
+ private int CopyPBO;
+
public OGLRenderTarget(OGLTexture Texture)
{
ColorAttachments = new int[8];
@@ -358,45 +360,33 @@ namespace Ryujinx.Graphics.Gal.OpenGL
return;
}
- byte[] Data = GetData(Key);
-
- GL.PixelStore(PixelStoreParameter.UnpackRowLength, OldImage.Width);
+ if (CopyPBO == 0)
+ {
+ CopyPBO = GL.GenBuffer();
+ }
- Texture.Create(Key, Data, NewImage);
+ GL.BindBuffer(BufferTarget.PixelPackBuffer, CopyPBO);
- GL.PixelStore(PixelStoreParameter.UnpackRowLength, 0);
- }
+ GL.BufferData(BufferTarget.PixelPackBuffer, Math.Max(ImageUtils.GetSize(OldImage), ImageUtils.GetSize(NewImage)), IntPtr.Zero, BufferUsageHint.StreamCopy);
- public byte[] GetData(long Key)
- {
if (!Texture.TryGetImageHandler(Key, out ImageHandler CachedImage))
{
- return null;
- }
-
- if (SrcFb == 0)
- {
- SrcFb = GL.GenFramebuffer();
+ throw new InvalidOperationException();
}
- GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, SrcFb);
-
- FramebufferAttachment Attachment = GetAttachment(CachedImage);
-
- GL.FramebufferTexture(FramebufferTarget.ReadFramebuffer, Attachment, CachedImage.Handle, 0);
+ (_, PixelFormat Format, PixelType Type) = OGLEnumConverter.GetImageFormat(CachedImage.Format);
- int Size = ImageUtils.GetSize(CachedImage.Image);
+ GL.BindTexture(TextureTarget.Texture2D, CachedImage.Handle);
- byte[] Data = new byte[Size];
+ GL.GetTexImage(TextureTarget.Texture2D, 0, Format, Type, IntPtr.Zero);
- int Width = CachedImage.Width;
- int Height = CachedImage.Height;
+ GL.BindBuffer(BufferTarget.PixelPackBuffer, 0);
- (_, PixelFormat Format, PixelType Type) = OGLEnumConverter.GetImageFormat(CachedImage.Format);
+ GL.BindBuffer(BufferTarget.PixelUnpackBuffer, CopyPBO);
- GL.ReadPixels(0, 0, Width, Height, Format, Type, Data);
+ Texture.Create(Key, ImageUtils.GetSize(NewImage), NewImage);
- return Data;
+ GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0);
}
private static FramebufferAttachment GetAttachment(ImageHandler CachedImage)
diff --git a/Ryujinx.Graphics/GpuResourceManager.cs b/Ryujinx.Graphics/GpuResourceManager.cs
index ba35910d..0a8d2014 100644
--- a/Ryujinx.Graphics/GpuResourceManager.cs
+++ b/Ryujinx.Graphics/GpuResourceManager.cs
@@ -7,10 +7,20 @@ namespace Ryujinx.Graphics
{
public class GpuResourceManager
{
+ private enum ImageType
+ {
+ None,
+ Texture,
+ ColorBuffer,
+ ZetaBuffer
+ }
+
private NvGpu Gpu;
private HashSet<long>[] UploadedKeys;
+ private Dictionary<long, ImageType> ImageTypes;
+
public GpuResourceManager(NvGpu Gpu)
{
this.Gpu = Gpu;
@@ -21,26 +31,21 @@ namespace Ryujinx.Graphics
{
UploadedKeys[Index] = new HashSet<long>();
}
+
+ ImageTypes = new Dictionary<long, ImageType>();
}
public void SendColorBuffer(NvGpuVmm Vmm, long Position, int Attachment, GalImage NewImage)
{
long Size = (uint)ImageUtils.GetSize(NewImage);
- MarkAsCached(Vmm, Position, Size, NvGpuBufferType.Texture);
+ ImageTypes[Position] = ImageType.ColorBuffer;
- bool IsCached = Gpu.Renderer.Texture.TryGetImage(Position, out GalImage CachedImage);
-
- if (IsCached && CachedImage.SizeMatches(NewImage))
+ if (!TryReuse(Vmm, Position, NewImage))
{
- Gpu.Renderer.RenderTarget.Reinterpret(Position, NewImage);
- Gpu.Renderer.RenderTarget.BindColor(Position, Attachment, NewImage);
-
- return;
+ Gpu.Renderer.Texture.Create(Position, (int)Size, NewImage);
}
- Gpu.Renderer.Texture.Create(Position, (int)Size, NewImage);
-
Gpu.Renderer.RenderTarget.BindColor(Position, Attachment, NewImage);
}
@@ -48,38 +53,49 @@ namespace Ryujinx.Graphics
{
long Size = (uint)ImageUtils.GetSize(NewImage);
- MarkAsCached(Vmm, Position, Size, NvGpuBufferType.Texture);
+ ImageTypes[Position] = ImageType.ZetaBuffer;
- bool IsCached = Gpu.Renderer.Texture.TryGetImage(Position, out GalImage CachedImage);
-
- if (IsCached && CachedImage.SizeMatches(NewImage))
+ if (!TryReuse(Vmm, Position, NewImage))
{
- Gpu.Renderer.RenderTarget.Reinterpret(Position, NewImage);
- Gpu.Renderer.RenderTarget.BindZeta(Position, NewImage);
-
- return;
+ Gpu.Renderer.Texture.Create(Position, (int)Size, NewImage);
}
- Gpu.Renderer.Texture.Create(Position, (int)Size, NewImage);
-
Gpu.Renderer.RenderTarget.BindZeta(Position, NewImage);
}
public void SendTexture(NvGpuVmm Vmm, long Position, GalImage NewImage, int TexIndex = -1)
{
- long Size = (uint)ImageUtils.GetSize(NewImage);
+ PrepareSendTexture(Vmm, Position, NewImage);
+
+ if (TexIndex >= 0)
+ {
+ Gpu.Renderer.Texture.Bind(Position, TexIndex, NewImage);
+ }
+
+ ImageTypes[Position] = ImageType.Texture;
+ }
+
+ private void PrepareSendTexture(NvGpuVmm Vmm, long Position, GalImage NewImage)
+ {
+ long Size = ImageUtils.GetSize(NewImage);
- if (!MemoryRegionModified(Vmm, Position, Size, NvGpuBufferType.Texture))
+ bool SkipCheck = false;
+
+ if (ImageTypes.TryGetValue(Position, out ImageType OldType))
{
- if (Gpu.Renderer.Texture.TryGetImage(Position, out GalImage CachedImage) && CachedImage.SizeMatches(NewImage))
+ if (OldType == ImageType.ColorBuffer || OldType == ImageType.ZetaBuffer)
{
- Gpu.Renderer.RenderTarget.Reinterpret(Position, NewImage);
+ //Avoid data destruction
+ MemoryRegionModified(Vmm, Position, Size, NvGpuBufferType.Texture);
- if (TexIndex >= 0)
- {
- Gpu.Renderer.Texture.Bind(Position, TexIndex, NewImage);
- }
+ SkipCheck = true;
+ }
+ }
+ if (SkipCheck || !MemoryRegionModified(Vmm, Position, Size, NvGpuBufferType.Texture))
+ {
+ if (TryReuse(Vmm, Position, NewImage))
+ {
return;
}
}
@@ -87,16 +103,18 @@ namespace Ryujinx.Graphics
byte[] Data = ImageUtils.ReadTexture(Vmm, NewImage, Position);
Gpu.Renderer.Texture.Create(Position, Data, NewImage);
+ }
- if (TexIndex >= 0)
+ private bool TryReuse(NvGpuVmm Vmm, long Position, GalImage NewImage)
+ {
+ if (Gpu.Renderer.Texture.TryGetImage(Position, out GalImage CachedImage) && CachedImage.SizeMatches(NewImage))
{
- Gpu.Renderer.Texture.Bind(Position, TexIndex, NewImage);
+ Gpu.Renderer.RenderTarget.Reinterpret(Position, NewImage);
+
+ return true;
}
- }
- private void MarkAsCached(NvGpuVmm Vmm, long Position, long Size, NvGpuBufferType Type)
- {
- Vmm.IsRegionModified(Position, Size, Type);
+ return false;
}
private bool MemoryRegionModified(NvGpuVmm Vmm, long Position, long Size, NvGpuBufferType Type)