aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Ryujinx.Graphics/Gal/GalTextureFormat.cs1
-rw-r--r--Ryujinx.Graphics/Gal/IGalRasterizer.cs7
-rw-r--r--Ryujinx.Graphics/Gal/IGalTexture.cs3
-rw-r--r--Ryujinx.Graphics/Gal/OpenGL/OGLCachedResource.cs43
-rw-r--r--Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs19
-rw-r--r--Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs16
-rw-r--r--Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs10
-rw-r--r--Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs20
-rw-r--r--Ryujinx.HLE/Gpu/Texture/TextureHelper.cs28
-rw-r--r--Ryujinx.HLE/Gpu/Texture/TextureReader.cs1
10 files changed, 122 insertions, 26 deletions
diff --git a/Ryujinx.Graphics/Gal/GalTextureFormat.cs b/Ryujinx.Graphics/Gal/GalTextureFormat.cs
index 7d19dc26..231d33ec 100644
--- a/Ryujinx.Graphics/Gal/GalTextureFormat.cs
+++ b/Ryujinx.Graphics/Gal/GalTextureFormat.cs
@@ -17,6 +17,7 @@ namespace Ryujinx.Graphics.Gal
BC3 = 0x26,
BC4 = 0x27,
BC5 = 0x28,
+ ZF32 = 0x2f,
Astc2D4x4 = 0x40,
Astc2D5x5 = 0x41,
Astc2D6x6 = 0x42,
diff --git a/Ryujinx.Graphics/Gal/IGalRasterizer.cs b/Ryujinx.Graphics/Gal/IGalRasterizer.cs
index 2598efb6..0c5d37e4 100644
--- a/Ryujinx.Graphics/Gal/IGalRasterizer.cs
+++ b/Ryujinx.Graphics/Gal/IGalRasterizer.cs
@@ -2,6 +2,9 @@ namespace Ryujinx.Graphics.Gal
{
public interface IGalRasterizer
{
+ void LockCaches();
+ void UnlockCaches();
+
void ClearBuffers(GalClearBufferFlags Flags);
bool IsVboCached(long Key, long DataSize);
@@ -46,9 +49,9 @@ namespace Ryujinx.Graphics.Gal
void CreateIbo(long Key, byte[] Buffer);
- void SetVertexArray(int VbIndex, int Stride, long VboKey, GalVertexAttrib[] Attribs);
+ void SetVertexArray(int Stride, long VboKey, GalVertexAttrib[] Attribs);
- void SetIndexArray(long Key, int Size, GalIndexFormat Format);
+ void SetIndexArray(int Size, GalIndexFormat Format);
void DrawArrays(int First, int PrimCount, GalPrimitiveType PrimType);
diff --git a/Ryujinx.Graphics/Gal/IGalTexture.cs b/Ryujinx.Graphics/Gal/IGalTexture.cs
index 6379e73a..2ab41199 100644
--- a/Ryujinx.Graphics/Gal/IGalTexture.cs
+++ b/Ryujinx.Graphics/Gal/IGalTexture.cs
@@ -2,6 +2,9 @@ namespace Ryujinx.Graphics.Gal
{
public interface IGalTexture
{
+ void LockCache();
+ void UnlockCache();
+
void Create(long Key, byte[] Data, GalTexture Texture);
bool TryGetCachedTexture(long Key, long DataSize, out GalTexture Texture);
diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLCachedResource.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLCachedResource.cs
index 06d76b8b..01ebf982 100644
--- a/Ryujinx.Graphics/Gal/OpenGL/OGLCachedResource.cs
+++ b/Ryujinx.Graphics/Gal/OpenGL/OGLCachedResource.cs
@@ -36,6 +36,10 @@ namespace Ryujinx.Graphics.Gal.OpenGL
private DeleteValue DeleteValueCallback;
+ private Queue<T> DeletePending;
+
+ private bool Locked;
+
public OGLCachedResource(DeleteValue DeleteValueCallback)
{
if (DeleteValueCallback == null)
@@ -48,11 +52,33 @@ namespace Ryujinx.Graphics.Gal.OpenGL
Cache = new Dictionary<long, CacheBucket>();
SortedCache = new LinkedList<long>();
+
+ DeletePending = new Queue<T>();
}
- public void AddOrUpdate(long Key, T Value, long Size)
+ public void Lock()
+ {
+ Locked = true;
+ }
+
+ public void Unlock()
{
+ Locked = false;
+
+ while (DeletePending.TryDequeue(out T Value))
+ {
+ DeleteValueCallback(Value);
+ }
+
ClearCacheIfNeeded();
+ }
+
+ public void AddOrUpdate(long Key, T Value, long Size)
+ {
+ if (!Locked)
+ {
+ ClearCacheIfNeeded();
+ }
LinkedListNode<long> Node = SortedCache.AddLast(Key);
@@ -60,7 +86,14 @@ namespace Ryujinx.Graphics.Gal.OpenGL
if (Cache.TryGetValue(Key, out CacheBucket Bucket))
{
- DeleteValueCallback(Bucket.Value);
+ if (Locked)
+ {
+ DeletePending.Enqueue(Bucket.Value);
+ }
+ else
+ {
+ DeleteValueCallback(Bucket.Value);
+ }
SortedCache.Remove(Bucket.Node);
@@ -78,6 +111,12 @@ namespace Ryujinx.Graphics.Gal.OpenGL
{
Value = Bucket.Value;
+ SortedCache.Remove(Bucket.Node);
+
+ LinkedListNode<long> Node = SortedCache.AddLast(Key);
+
+ Cache[Key] = new CacheBucket(Value, Bucket.DataSize, Node);
+
return true;
}
diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs
index 3a81150d..8f189d2b 100644
--- a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs
+++ b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs
@@ -129,15 +129,16 @@ namespace Ryujinx.Graphics.Gal.OpenGL
{
switch (Format)
{
- case GalTextureFormat.R32G32B32A32: return (PixelFormat.Rgba, PixelType.Float);
- case GalTextureFormat.R16G16B16A16: return (PixelFormat.Rgba, PixelType.HalfFloat);
- case GalTextureFormat.A8B8G8R8: return (PixelFormat.Rgba, PixelType.UnsignedByte);
- case GalTextureFormat.R32: return (PixelFormat.Red, PixelType.Float);
- case GalTextureFormat.A1B5G5R5: return (PixelFormat.Rgba, PixelType.UnsignedShort5551);
- case GalTextureFormat.B5G6R5: return (PixelFormat.Rgb, PixelType.UnsignedShort565);
- case GalTextureFormat.G8R8: return (PixelFormat.Rg, PixelType.UnsignedByte);
- case GalTextureFormat.R16: return (PixelFormat.Red, PixelType.HalfFloat);
- case GalTextureFormat.R8: return (PixelFormat.Red, PixelType.UnsignedByte);
+ case GalTextureFormat.R32G32B32A32: return (PixelFormat.Rgba, PixelType.Float);
+ case GalTextureFormat.R16G16B16A16: return (PixelFormat.Rgba, PixelType.HalfFloat);
+ case GalTextureFormat.A8B8G8R8: return (PixelFormat.Rgba, PixelType.UnsignedByte);
+ case GalTextureFormat.R32: return (PixelFormat.Red, PixelType.Float);
+ case GalTextureFormat.A1B5G5R5: return (PixelFormat.Rgba, PixelType.UnsignedShort5551);
+ case GalTextureFormat.B5G6R5: return (PixelFormat.Rgb, PixelType.UnsignedShort565);
+ case GalTextureFormat.G8R8: return (PixelFormat.Rg, PixelType.UnsignedByte);
+ case GalTextureFormat.R16: return (PixelFormat.Red, PixelType.HalfFloat);
+ case GalTextureFormat.R8: return (PixelFormat.Red, PixelType.UnsignedByte);
+ case GalTextureFormat.ZF32: return (PixelFormat.DepthComponent, PixelType.Float);
}
throw new NotImplementedException(Format.ToString());
diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs
index a4ec7f87..0dc56966 100644
--- a/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs
+++ b/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs
@@ -71,6 +71,18 @@ namespace Ryujinx.Graphics.Gal.OpenGL
IndexBuffer = new IbInfo();
}
+ public void LockCaches()
+ {
+ VboCache.Lock();
+ IboCache.Lock();
+ }
+
+ public void UnlockCaches()
+ {
+ VboCache.Unlock();
+ IboCache.Unlock();
+ }
+
public void ClearBuffers(GalClearBufferFlags Flags)
{
ClearBufferMask Mask = ClearBufferMask.ColorBufferBit;
@@ -223,7 +235,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
GL.BufferData(BufferTarget.ElementArrayBuffer, Length, Buffer, BufferUsageHint.StreamDraw);
}
- public void SetVertexArray(int VbIndex, int Stride, long VboKey, GalVertexAttrib[] Attribs)
+ public void SetVertexArray(int Stride, long VboKey, GalVertexAttrib[] Attribs)
{
if (!VboCache.TryGetValue(VboKey, out int VboHandle))
{
@@ -270,7 +282,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
}
}
- public void SetIndexArray(long Key, int Size, GalIndexFormat Format)
+ public void SetIndexArray(int Size, GalIndexFormat Format)
{
IndexBuffer.Type = OGLEnumConverter.GetDrawElementsType(Format);
diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs
index c50bdd71..5caca6ec 100644
--- a/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs
+++ b/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs
@@ -26,6 +26,16 @@ namespace Ryujinx.Graphics.Gal.OpenGL
TextureCache = new OGLCachedResource<TCE>(DeleteTexture);
}
+ public void LockCache()
+ {
+ TextureCache.Lock();
+ }
+
+ public void UnlockCache()
+ {
+ TextureCache.Unlock();
+ }
+
private static void DeleteTexture(TCE CachedTexture)
{
GL.DeleteTexture(CachedTexture.Handle);
diff --git a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs
index b9f9cc49..2bacd71b 100644
--- a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs
+++ b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs
@@ -73,6 +73,8 @@ namespace Ryujinx.HLE.Gpu.Engines
private void VertexEndGl(NvGpuVmm Vmm, NvGpuPBEntry PBEntry)
{
+ LockCaches();
+
SetFrameBuffer(Vmm, 0);
long[] Keys = UploadShaders(Vmm);
@@ -90,6 +92,20 @@ namespace Ryujinx.HLE.Gpu.Engines
UploadTextures(Vmm, Keys);
UploadUniforms(Vmm);
UploadVertexArrays(Vmm);
+
+ UnlockCaches();
+ }
+
+ private void LockCaches()
+ {
+ Gpu.Renderer.Rasterizer.LockCaches();
+ Gpu.Renderer.Texture.LockCache();
+ }
+
+ private void UnlockCaches()
+ {
+ Gpu.Renderer.Rasterizer.UnlockCaches();
+ Gpu.Renderer.Texture.UnlockCache();
}
private void ClearBuffers(NvGpuVmm Vmm, NvGpuPBEntry PBEntry)
@@ -570,7 +586,7 @@ namespace Ryujinx.HLE.Gpu.Engines
Gpu.Renderer.Rasterizer.CreateIbo(IboKey, Data);
}
- Gpu.Renderer.Rasterizer.SetIndexArray(IboKey, IbSize, IndexFormat);
+ Gpu.Renderer.Rasterizer.SetIndexArray(IbSize, IndexFormat);
}
List<GalVertexAttrib>[] Attribs = new List<GalVertexAttrib>[32];
@@ -634,7 +650,7 @@ namespace Ryujinx.HLE.Gpu.Engines
Gpu.Renderer.Rasterizer.CreateVbo(VboKey, Data);
}
- Gpu.Renderer.Rasterizer.SetVertexArray(Index, Stride, VboKey, Attribs[Index].ToArray());
+ Gpu.Renderer.Rasterizer.SetVertexArray(Stride, VboKey, Attribs[Index].ToArray());
}
GalPrimitiveType PrimType = (GalPrimitiveType)(PrimCtrl & 0xffff);
diff --git a/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs b/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs
index ac8f75c5..3c633b69 100644
--- a/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs
+++ b/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs
@@ -28,15 +28,25 @@ namespace Ryujinx.HLE.Gpu.Texture
{
switch (Texture.Format)
{
- case GalTextureFormat.R32G32B32A32: return Texture.Width * Texture.Height * 16;
- case GalTextureFormat.R16G16B16A16: return Texture.Width * Texture.Height * 8;
- case GalTextureFormat.A8B8G8R8: return Texture.Width * Texture.Height * 4;
- case GalTextureFormat.R32: return Texture.Width * Texture.Height * 4;
- case GalTextureFormat.A1B5G5R5: return Texture.Width * Texture.Height * 2;
- case GalTextureFormat.B5G6R5: return Texture.Width * Texture.Height * 2;
- case GalTextureFormat.G8R8: return Texture.Width * Texture.Height * 2;
- case GalTextureFormat.R16: return Texture.Width * Texture.Height * 2;
- case GalTextureFormat.R8: return Texture.Width * Texture.Height;
+ case GalTextureFormat.R32G32B32A32:
+ return Texture.Width * Texture.Height * 16;
+
+ case GalTextureFormat.R16G16B16A16:
+ return Texture.Width * Texture.Height * 8;
+
+ case GalTextureFormat.A8B8G8R8:
+ case GalTextureFormat.R32:
+ case GalTextureFormat.ZF32:
+ return Texture.Width * Texture.Height * 4;
+
+ case GalTextureFormat.A1B5G5R5:
+ case GalTextureFormat.B5G6R5:
+ case GalTextureFormat.G8R8:
+ case GalTextureFormat.R16:
+ return Texture.Width * Texture.Height * 2;
+
+ case GalTextureFormat.R8:
+ return Texture.Width * Texture.Height;
case GalTextureFormat.BC1:
case GalTextureFormat.BC4:
diff --git a/Ryujinx.HLE/Gpu/Texture/TextureReader.cs b/Ryujinx.HLE/Gpu/Texture/TextureReader.cs
index 48bf1a90..24bceffb 100644
--- a/Ryujinx.HLE/Gpu/Texture/TextureReader.cs
+++ b/Ryujinx.HLE/Gpu/Texture/TextureReader.cs
@@ -25,6 +25,7 @@ namespace Ryujinx.HLE.Gpu.Texture
case GalTextureFormat.BC3: return Read16Bpt4x4(Memory, Texture);
case GalTextureFormat.BC4: return Read8Bpt4x4 (Memory, Texture);
case GalTextureFormat.BC5: return Read16Bpt4x4(Memory, Texture);
+ case GalTextureFormat.ZF32: return Read4Bpp (Memory, Texture);
case GalTextureFormat.Astc2D4x4: return Read16Bpt4x4(Memory, Texture);
}