diff options
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(); + } + } } } } |