aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Gpu
diff options
context:
space:
mode:
authorgdk <gab.dark.100@gmail.com>2019-11-23 23:24:03 -0300
committerThog <thog@protonmail.com>2020-01-09 02:13:00 +0100
commit16d88c21fc98cd7302811e142a39d590370e182e (patch)
treee2c1a457666a11427ca3a26d701720bfe508e0e3 /Ryujinx.Graphics.Gpu
parentb2b2e046696e9c187cd9d7d4e3e92dc521082fe5 (diff)
Improved and simplified window texture presentation
Diffstat (limited to 'Ryujinx.Graphics.Gpu')
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/Methods.cs2
-rw-r--r--Ryujinx.Graphics.Gpu/GpuContext.cs38
-rw-r--r--Ryujinx.Graphics.Gpu/Image/Texture.cs12
-rw-r--r--Ryujinx.Graphics.Gpu/Image/TextureManager.cs26
-rw-r--r--Ryujinx.Graphics.Gpu/Memory/ConcurrentRangeList.cs208
-rw-r--r--Ryujinx.Graphics.Gpu/Window.cs94
6 files changed, 100 insertions, 280 deletions
diff --git a/Ryujinx.Graphics.Gpu/Engine/Methods.cs b/Ryujinx.Graphics.Gpu/Engine/Methods.cs
index 1832a5e3..19e67993 100644
--- a/Ryujinx.Graphics.Gpu/Engine/Methods.cs
+++ b/Ryujinx.Graphics.Gpu/Engine/Methods.cs
@@ -76,8 +76,6 @@ namespace Ryujinx.Graphics.Gpu.Engine
state.RegisterCallback(MethodOffset.UniformBufferBindFragment, UniformBufferBindFragment);
}
- public Image.Texture GetTexture(ulong address) => _textureManager.Find2(address);
-
private void UpdateState(GpuState state)
{
// Shaders must be the first one to be updated if modified, because
diff --git a/Ryujinx.Graphics.Gpu/GpuContext.cs b/Ryujinx.Graphics.Gpu/GpuContext.cs
index b52e4e49..51961522 100644
--- a/Ryujinx.Graphics.Gpu/GpuContext.cs
+++ b/Ryujinx.Graphics.Gpu/GpuContext.cs
@@ -1,9 +1,6 @@
using Ryujinx.Graphics.GAL;
-using Ryujinx.Graphics.GAL.Texture;
using Ryujinx.Graphics.Gpu.Engine;
-using Ryujinx.Graphics.Gpu.Image;
using Ryujinx.Graphics.Gpu.Memory;
-using Ryujinx.Graphics.Gpu.State;
using System;
namespace Ryujinx.Graphics.Gpu
@@ -24,6 +21,8 @@ namespace Ryujinx.Graphics.Gpu
public DmaPusher DmaPusher { get; }
+ public Window Window { get; }
+
internal int SequenceNumber { get; private set; }
private Lazy<Capabilities> _caps;
@@ -44,6 +43,8 @@ namespace Ryujinx.Graphics.Gpu
DmaPusher = new DmaPusher(this);
+ Window = new Window(this);
+
_caps = new Lazy<Capabilities>(GetCapabilities);
}
@@ -52,37 +53,6 @@ namespace Ryujinx.Graphics.Gpu
SequenceNumber++;
}
- public ITexture GetTexture(
- ulong address,
- int width,
- int height,
- int stride,
- bool isLinear,
- int gobBlocksInY,
- Format format,
- int bytesPerPixel)
- {
- FormatInfo formatInfo = new FormatInfo(format, 1, 1, bytesPerPixel);
-
- TextureInfo info = new TextureInfo(
- address,
- width,
- height,
- 1,
- 1,
- 1,
- 1,
- stride,
- isLinear,
- gobBlocksInY,
- 1,
- 1,
- Target.Texture2D,
- formatInfo);
-
- return Methods.GetTexture(address)?.HostTexture;
- }
-
private Capabilities GetCapabilities()
{
return Renderer.GetCapabilities();
diff --git a/Ryujinx.Graphics.Gpu/Image/Texture.cs b/Ryujinx.Graphics.Gpu/Image/Texture.cs
index 28ad3f77..120abe3f 100644
--- a/Ryujinx.Graphics.Gpu/Image/Texture.cs
+++ b/Ryujinx.Graphics.Gpu/Image/Texture.cs
@@ -335,18 +335,6 @@ namespace Ryujinx.Graphics.Gpu.Image
return true;
}
- if (_info.FormatInfo.Format == Format.R8G8B8A8Srgb &&
- info.FormatInfo.Format == Format.R8G8B8A8Unorm && !strict)
- {
- return true;
- }
-
- if (_info.FormatInfo.Format == Format.R8G8B8A8Unorm &&
- info.FormatInfo.Format == Format.R8G8B8A8Srgb && !strict)
- {
- return true;
- }
-
return _info.FormatInfo.Format == info.FormatInfo.Format;
}
diff --git a/Ryujinx.Graphics.Gpu/Image/TextureManager.cs b/Ryujinx.Graphics.Gpu/Image/TextureManager.cs
index 045c2ed9..413ba327 100644
--- a/Ryujinx.Graphics.Gpu/Image/TextureManager.cs
+++ b/Ryujinx.Graphics.Gpu/Image/TextureManager.cs
@@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Image
private ITexture[] _rtHostColors;
private ITexture _rtHostDs;
- private ConcurrentRangeList<Texture> _textures;
+ private RangeList<Texture> _textures;
private AutoDeleteCache _cache;
@@ -39,7 +39,7 @@ namespace Ryujinx.Graphics.Gpu.Image
_rtHostColors = new ITexture[Constants.TotalRenderTargets];
- _textures = new ConcurrentRangeList<Texture>();
+ _textures = new RangeList<Texture>();
_cache = new AutoDeleteCache();
}
@@ -561,28 +561,6 @@ namespace Ryujinx.Graphics.Gpu.Image
info.SwizzleA);
}
- public Texture Find2(ulong address)
- {
- Texture[] ts = _textures.FindOverlaps(address, 1);
-
- if (ts.Length == 2)
- {
- return ts[1];
- }
-
- if (ts.Length == 0)
- {
- ts = _textures.FindOverlaps(address - 1, 2);
- }
-
- if (ts.Length == 0)
- {
- return null;
- }
-
- return ts[0];
- }
-
public void Flush()
{
foreach (Texture texture in _cache)
diff --git a/Ryujinx.Graphics.Gpu/Memory/ConcurrentRangeList.cs b/Ryujinx.Graphics.Gpu/Memory/ConcurrentRangeList.cs
deleted file mode 100644
index 6d7d1ce2..00000000
--- a/Ryujinx.Graphics.Gpu/Memory/ConcurrentRangeList.cs
+++ /dev/null
@@ -1,208 +0,0 @@
-using System.Collections.Generic;
-
-namespace Ryujinx.Graphics.Gpu.Memory
-{
- class ConcurrentRangeList<T> where T : IRange<T>
- {
- private List<T> _items;
-
- public ConcurrentRangeList()
- {
- _items = new List<T>();
- }
-
- public void Add(T item)
- {
- lock (_items)
- {
- int index = BinarySearch(item.Address);
-
- if (index < 0)
- {
- index = ~index;
- }
-
- _items.Insert(index, item);
- }
- }
-
- public bool Remove(T item)
- {
- lock (_items)
- {
- int index = BinarySearch(item.Address);
-
- if (index >= 0)
- {
- while (index > 0 && _items[index - 1].Address == item.Address)
- {
- index--;
- }
-
- while (index < _items.Count)
- {
- if (_items[index].Equals(item))
- {
- _items.RemoveAt(index);
-
- return true;
- }
-
- if (_items[index].Address > item.Address)
- {
- break;
- }
-
- index++;
- }
- }
- }
-
- return false;
- }
-
- public T FindFirstOverlap(T item)
- {
- return FindFirstOverlap(item.Address, item.Size);
- }
-
- public T FindFirstOverlap(ulong address, ulong size)
- {
- lock (_items)
- {
- int index = BinarySearch(address, size);
-
- if (index < 0)
- {
- return default(T);
- }
-
- return _items[index];
- }
- }
-
- public T[] FindOverlaps(T item)
- {
- return FindOverlaps(item.Address, item.Size);
- }
-
- public T[] FindOverlaps(ulong address, ulong size)
- {
- List<T> overlapsList = new List<T>();
-
- ulong endAddress = address + size;
-
- lock (_items)
- {
- foreach (T item in _items)
- {
- if (item.Address >= endAddress)
- {
- break;
- }
-
- if (item.OverlapsWith(address, size))
- {
- overlapsList.Add(item);
- }
- }
- }
-
- return overlapsList.ToArray();
- }
-
- public T[] FindOverlaps(ulong address)
- {
- List<T> overlapsList = new List<T>();
-
- lock (_items)
- {
- int index = BinarySearch(address);
-
- if (index >= 0)
- {
- while (index > 0 && _items[index - 1].Address == address)
- {
- index--;
- }
-
- while (index < _items.Count)
- {
- T overlap = _items[index++];
-
- if (overlap.Address != address)
- {
- break;
- }
-
- overlapsList.Add(overlap);
- }
- }
- }
-
- return overlapsList.ToArray();
- }
-
- private int BinarySearch(ulong address)
- {
- int left = 0;
- int right = _items.Count - 1;
-
- while (left <= right)
- {
- int range = right - left;
-
- int middle = left + (range >> 1);
-
- T item = _items[middle];
-
- if (item.Address == address)
- {
- return middle;
- }
-
- if (address < item.Address)
- {
- right = middle - 1;
- }
- else
- {
- left = middle + 1;
- }
- }
-
- return ~left;
- }
-
- private int BinarySearch(ulong address, ulong size)
- {
- int left = 0;
- int right = _items.Count - 1;
-
- while (left <= right)
- {
- int range = right - left;
-
- int middle = left + (range >> 1);
-
- T item = _items[middle];
-
- if (item.OverlapsWith(address, size))
- {
- return middle;
- }
-
- if (address < item.Address)
- {
- right = middle - 1;
- }
- else
- {
- left = middle + 1;
- }
- }
-
- return ~left;
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics.Gpu/Window.cs b/Ryujinx.Graphics.Gpu/Window.cs
new file mode 100644
index 00000000..a3dc3b26
--- /dev/null
+++ b/Ryujinx.Graphics.Gpu/Window.cs
@@ -0,0 +1,94 @@
+using Ryujinx.Graphics.GAL;
+using Ryujinx.Graphics.GAL.Texture;
+using Ryujinx.Graphics.Gpu.Image;
+using System;
+using System.Collections.Concurrent;
+
+namespace Ryujinx.Graphics.Gpu
+{
+ public class Window
+ {
+ private GpuContext _context;
+
+ private struct PresentationTexture
+ {
+ public TextureInfo Info { get; }
+ public ImageCrop Crop { get; }
+ public Action<object> Callback { get; }
+ public object UserObj { get; }
+
+ public PresentationTexture(
+ TextureInfo info,
+ ImageCrop crop,
+ Action<object> callback,
+ object userObj)
+ {
+ Info = info;
+ Crop = crop;
+ Callback = callback;
+ UserObj = userObj;
+ }
+ }
+
+ private ConcurrentQueue<PresentationTexture> _frameQueue;
+
+ public Window(GpuContext context)
+ {
+ _context = context;
+
+ _frameQueue = new ConcurrentQueue<PresentationTexture>();
+ }
+
+ public void EnqueueFrameThreadSafe(
+ ulong address,
+ int width,
+ int height,
+ int stride,
+ bool isLinear,
+ int gobBlocksInY,
+ Format format,
+ int bytesPerPixel,
+ ImageCrop crop,
+ Action<object> callback,
+ object userObj)
+ {
+ FormatInfo formatInfo = new FormatInfo(format, 1, 1, bytesPerPixel);
+
+ TextureInfo info = new TextureInfo(
+ address,
+ width,
+ height,
+ 1,
+ 1,
+ 1,
+ 1,
+ stride,
+ isLinear,
+ gobBlocksInY,
+ 1,
+ 1,
+ Target.Texture2D,
+ formatInfo);
+
+ _frameQueue.Enqueue(new PresentationTexture(info, crop, callback, userObj));
+ }
+
+ public void Present(Action swapBuffersCallback)
+ {
+ _context.AdvanceSequence();
+
+ if (_frameQueue.TryDequeue(out PresentationTexture pt))
+ {
+ Image.Texture texture = _context.Methods.TextureManager.FindOrCreateTexture(pt.Info);
+
+ texture.SynchronizeMemory();
+
+ _context.Renderer.Window.Present(texture.HostTexture, pt.Crop);
+
+ swapBuffersCallback();
+
+ pt.Callback(pt.UserObj);
+ }
+ }
+ }
+} \ No newline at end of file