diff options
author | riperiperi <rhy3756547@hotmail.com> | 2024-01-31 22:49:50 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-31 23:49:50 +0100 |
commit | c94f0fbb8307873f68df982c100d3fb01aa6ccf5 (patch) | |
tree | 327a039f016b3e0ae45713e0f5dd413a04d673ae /src/Ryujinx.Graphics.Vulkan/TextureView.cs | |
parent | d1b30fbe08d79ad81167358779d77cf4e7167386 (diff) |
Vulkan: Add Render Pass / Framebuffer Cache (#6182)1.1.1154
* Vulkan: Add Render Pass / Framebuffer Cache
Cache is owned by each texture view.
- Window's way of getting framebuffer cache for swapchain images is really messy - it creates a TextureView out of just a vk image view, with invalid info and no storage.
* Clear up limited use of alternate TextureView constructor
* Formatting and messages
* More formatting and messages
I apologize for `_colorsCanonical[index]?.Storage?.InsertReadToWriteBarrier`, the compiler made me do it
* Self review, change GetFramebuffer to GetPassAndFramebuffer
* Avoid allocations on Remove for HashTableSlim
* Member can be readonly
* Generate texture create info for swapchain images
* Improve hashcode
* Remove format, samples, size and isDepthStencil when possible
Tested in a number of games, seems fine.
* Removed load op barriers
These can be introduced later.
* Reintroduce UpdateModifications
Technically meant to be replaced by load op stuff.
Diffstat (limited to 'src/Ryujinx.Graphics.Vulkan/TextureView.cs')
-rw-r--r-- | src/Ryujinx.Graphics.Vulkan/TextureView.cs | 67 |
1 files changed, 66 insertions, 1 deletions
diff --git a/src/Ryujinx.Graphics.Vulkan/TextureView.cs b/src/Ryujinx.Graphics.Vulkan/TextureView.cs index f5b80f94..393db261 100644 --- a/src/Ryujinx.Graphics.Vulkan/TextureView.cs +++ b/src/Ryujinx.Graphics.Vulkan/TextureView.cs @@ -3,6 +3,7 @@ using Ryujinx.Graphics.GAL; using Silk.NET.Vulkan; using System; using System.Collections.Generic; +using System.Linq; using Format = Ryujinx.Graphics.GAL.Format; using VkBuffer = Silk.NET.Vulkan.Buffer; using VkFormat = Silk.NET.Vulkan.Format; @@ -23,6 +24,8 @@ namespace Ryujinx.Graphics.Vulkan private readonly TextureCreateInfo _info; + private HashTableSlim<RenderPassCacheKey, RenderPassHolder> _renderPasses; + public TextureCreateInfo Info => _info; public TextureStorage Storage { get; } @@ -158,6 +161,26 @@ namespace Ryujinx.Graphics.Vulkan Valid = true; } + /// <summary> + /// Create a texture view for an existing swapchain image view. + /// Does not set storage, so only appropriate for swapchain use. + /// </summary> + /// <remarks>Do not use this for normal textures, and make sure uses do not try to read storage.</remarks> + public TextureView(VulkanRenderer gd, Device device, DisposableImageView view, TextureCreateInfo info, VkFormat format) + { + _gd = gd; + _device = device; + + _imageView = new Auto<DisposableImageView>(view); + _imageViewDraw = _imageView; + _imageViewIdentity = _imageView; + _info = info; + + VkFormat = format; + + Valid = true; + } + public Auto<DisposableImage> GetImage() { return Storage.GetImage(); @@ -939,6 +962,34 @@ namespace Ryujinx.Graphics.Vulkan throw new NotImplementedException(); } + public (Auto<DisposableRenderPass> renderPass, Auto<DisposableFramebuffer> framebuffer) GetPassAndFramebuffer( + VulkanRenderer gd, + Device device, + CommandBufferScoped cbs, + FramebufferParams fb) + { + var key = fb.GetRenderPassCacheKey(); + + if (_renderPasses == null || !_renderPasses.TryGetValue(ref key, out RenderPassHolder rpHolder)) + { + rpHolder = new RenderPassHolder(gd, device, key, fb); + } + + return (rpHolder.GetRenderPass(), rpHolder.GetFramebuffer(gd, cbs, fb)); + } + + public void AddRenderPass(RenderPassCacheKey key, RenderPassHolder renderPass) + { + _renderPasses ??= new HashTableSlim<RenderPassCacheKey, RenderPassHolder>(); + + _renderPasses.Add(ref key, renderPass); + } + + public void RemoveRenderPass(RenderPassCacheKey key) + { + _renderPasses.Remove(ref key); + } + protected virtual void Dispose(bool disposing) { if (disposing) @@ -948,15 +999,29 @@ namespace Ryujinx.Graphics.Vulkan if (_gd.Textures.Remove(this)) { _imageView.Dispose(); - _imageViewIdentity.Dispose(); _imageView2dArray?.Dispose(); + if (_imageViewIdentity != _imageView) + { + _imageViewIdentity.Dispose(); + } + if (_imageViewDraw != _imageViewIdentity) { _imageViewDraw.Dispose(); } Storage.DecrementViewsCount(); + + if (_renderPasses != null) + { + var renderPasses = _renderPasses.Values.ToArray(); + + foreach (var pass in renderPasses) + { + pass.Dispose(); + } + } } } } |