From b2b2e046696e9c187cd9d7d4e3e92dc521082fe5 Mon Sep 17 00:00:00 2001
From: gdk <gab.dark.100@gmail.com>
Date: Sat, 23 Nov 2019 02:17:22 -0300
Subject: [PATCH] Small optimizations on texture and sampler pool invalidation

---
 Ryujinx.Graphics.Gpu/Image/SamplerPool.cs    |  9 +++-
 Ryujinx.Graphics.Gpu/Image/TexturePool.cs    | 13 ++---
 Ryujinx.Graphics.Gpu/Memory/BufferManager.cs | 17 +++++--
 Ryujinx.Graphics.Gpu/State/GpuState.cs       | 51 +++++++++++++++-----
 4 files changed, 68 insertions(+), 22 deletions(-)

diff --git a/Ryujinx.Graphics.Gpu/Image/SamplerPool.cs b/Ryujinx.Graphics.Gpu/Image/SamplerPool.cs
index 970a09832d..5555510952 100644
--- a/Ryujinx.Graphics.Gpu/Image/SamplerPool.cs
+++ b/Ryujinx.Graphics.Gpu/Image/SamplerPool.cs
@@ -5,6 +5,8 @@ namespace Ryujinx.Graphics.Gpu.Image
 {
     class SamplerPool : Pool<Sampler>
     {
+        private int _sequenceNumber;
+
         public SamplerPool(GpuContext context, ulong address, int maximumId) : base(context, address, maximumId) { }
 
         public override Sampler Get(int id)
@@ -14,7 +16,12 @@ namespace Ryujinx.Graphics.Gpu.Image
                 return null;
             }
 
-            SynchronizeMemory();
+            if (_sequenceNumber != Context.SequenceNumber)
+            {
+                _sequenceNumber = Context.SequenceNumber;
+
+                SynchronizeMemory();
+            }
 
             Sampler sampler = Items[id];
 
diff --git a/Ryujinx.Graphics.Gpu/Image/TexturePool.cs b/Ryujinx.Graphics.Gpu/Image/TexturePool.cs
index 8512e3708d..6014f07cd6 100644
--- a/Ryujinx.Graphics.Gpu/Image/TexturePool.cs
+++ b/Ryujinx.Graphics.Gpu/Image/TexturePool.cs
@@ -11,11 +11,7 @@ namespace Ryujinx.Graphics.Gpu.Image
     {
         public LinkedListNode<TexturePool> CacheNode { get; set; }
 
-        private struct TextureContainer
-        {
-            public Texture Texture0 { get; set; }
-            public Texture Texture1 { get; set; }
-        }
+        private int _sequenceNumber;
 
         public TexturePool(
             GpuContext context,
@@ -29,7 +25,12 @@ namespace Ryujinx.Graphics.Gpu.Image
                 return null;
             }
 
-            SynchronizeMemory();
+            if (_sequenceNumber != Context.SequenceNumber)
+            {
+                _sequenceNumber = Context.SequenceNumber;
+
+                SynchronizeMemory();
+            }
 
             Texture texture = Items[id];
 
diff --git a/Ryujinx.Graphics.Gpu/Memory/BufferManager.cs b/Ryujinx.Graphics.Gpu/Memory/BufferManager.cs
index 78b7bc986e..30bd130200 100644
--- a/Ryujinx.Graphics.Gpu/Memory/BufferManager.cs
+++ b/Ryujinx.Graphics.Gpu/Memory/BufferManager.cs
@@ -3,7 +3,6 @@ using Ryujinx.Graphics.GAL.InputAssembler;
 using Ryujinx.Graphics.Gpu.State;
 using Ryujinx.Graphics.Shader;
 using System;
-using System.Runtime.InteropServices;
 
 namespace Ryujinx.Graphics.Gpu.Memory
 {
@@ -48,6 +47,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
 
         private bool _indexBufferDirty;
         private bool _vertexBuffersDirty;
+        private uint _vertexBuffersEnableMask;
 
         private bool _rebind;
 
@@ -93,6 +93,15 @@ namespace Ryujinx.Graphics.Gpu.Memory
             _vertexBuffers[index].Divisor = divisor;
 
             _vertexBuffersDirty = true;
+
+            if (address != 0)
+            {
+                _vertexBuffersEnableMask |= 1u << index;
+            }
+            else
+            {
+                _vertexBuffersEnableMask &= ~(1u << index);
+            }
         }
 
         public void SetComputeStorageBuffer(int index, ulong gpuVa, ulong size)
@@ -322,13 +331,15 @@ namespace Ryujinx.Graphics.Gpu.Memory
                 SynchronizeBufferRange(_indexBuffer.Address, _indexBuffer.Size);
             }
 
+            uint vbEnableMask = _vertexBuffersEnableMask;
+
             if (_vertexBuffersDirty || _rebind)
             {
                 _vertexBuffersDirty = false;
 
                 VertexBufferDescriptor[] vertexBuffers = new VertexBufferDescriptor[Constants.TotalVertexBuffers];
 
-                for (int index = 0; index < Constants.TotalVertexBuffers; index++)
+                for (int index = 0; (vbEnableMask >> index) != 0; index++)
                 {
                     VertexBuffer vb = _vertexBuffers[index];
 
@@ -346,7 +357,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
             }
             else
             {
-                for (int index = 0; index < Constants.TotalVertexBuffers; index++)
+                for (int index = 0; (vbEnableMask >> index) != 0; index++)
                 {
                     VertexBuffer vb = _vertexBuffers[index];
 
diff --git a/Ryujinx.Graphics.Gpu/State/GpuState.cs b/Ryujinx.Graphics.Gpu/State/GpuState.cs
index ecbaa00459..bf7734dd39 100644
--- a/Ryujinx.Graphics.Gpu/State/GpuState.cs
+++ b/Ryujinx.Graphics.Gpu/State/GpuState.cs
@@ -114,18 +114,6 @@ namespace Ryujinx.Graphics.Gpu.State
             _registers[(int)offset].Callback = callback;
         }
 
-        public bool QueryModified(params MethodOffset[] offsets)
-        {
-            bool modified = false;
-
-            for (int index = 0; index < offsets.Length; index++)
-            {
-                modified |= QueryModified(offsets[index]);
-            }
-
-            return modified;
-        }
-
         public bool QueryModified(MethodOffset offset)
         {
             bool modified = _registers[(int)offset].Modified;
@@ -135,6 +123,45 @@ namespace Ryujinx.Graphics.Gpu.State
             return modified;
         }
 
+        public bool QueryModified(MethodOffset m1, MethodOffset m2)
+        {
+            bool modified = _registers[(int)m1].Modified ||
+                            _registers[(int)m2].Modified;
+
+            _registers[(int)m1].Modified = false;
+            _registers[(int)m2].Modified = false;
+
+            return modified;
+        }
+
+        public bool QueryModified(MethodOffset m1, MethodOffset m2, MethodOffset m3)
+        {
+            bool modified = _registers[(int)m1].Modified ||
+                            _registers[(int)m2].Modified ||
+                            _registers[(int)m3].Modified;
+
+            _registers[(int)m1].Modified = false;
+            _registers[(int)m2].Modified = false;
+            _registers[(int)m3].Modified = false;
+
+            return modified;
+        }
+
+        public bool QueryModified(MethodOffset m1, MethodOffset m2, MethodOffset m3, MethodOffset m4)
+        {
+            bool modified = _registers[(int)m1].Modified ||
+                            _registers[(int)m2].Modified ||
+                            _registers[(int)m3].Modified ||
+                            _registers[(int)m4].Modified;
+
+            _registers[(int)m1].Modified = false;
+            _registers[(int)m2].Modified = false;
+            _registers[(int)m3].Modified = false;
+            _registers[(int)m4].Modified = false;
+
+            return modified;
+        }
+
         public T Get<T>(MethodOffset offset, int index) where T : struct
         {
             Register register = _registers[(int)offset];