From a9afcdfa10fc90e27abe3ffa5ce5d0e21bb6ecb5 Mon Sep 17 00:00:00 2001 From: gdk Date: Mon, 15 Nov 2021 15:47:26 -0300 Subject: [PATCH] Support format aliasing on SetImage --- .../DescriptorSetUpdater.cs | 9 ++-- Ryujinx.Graphics.Vulkan/TextureBuffer.cs | 35 +++++++++++++ Ryujinx.Graphics.Vulkan/TextureView.cs | 51 +++++++++++++++++++ 3 files changed, 92 insertions(+), 3 deletions(-) diff --git a/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs b/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs index 507b03bab..8a7743eeb 100644 --- a/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs +++ b/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs @@ -21,6 +21,7 @@ namespace Ryujinx.Graphics.Vulkan private Auto[] _imageRefs; private TextureBuffer[] _bufferTextureRefs; private TextureBuffer[] _bufferImageRefs; + private GAL.Format[] _bufferImageFormats; private DescriptorBufferInfo[] _uniformBuffers; private DescriptorBufferInfo[] _storageBuffers; @@ -113,9 +114,11 @@ namespace Ryujinx.Graphics.Vulkan { Array.Resize(ref _bufferImages, binding + 1); Array.Resize(ref _bufferImageRefs, binding + 1); + Array.Resize(ref _bufferImageFormats, binding + 1); } _bufferImageRefs[binding] = imageBuffer; + _bufferImageFormats[binding] = imageFormat; SignalDirty(DirtyFlags.BufferImage); } @@ -127,9 +130,9 @@ namespace Ryujinx.Graphics.Vulkan Array.Resize(ref _imageRefs, binding + 1); } - if (image != null) + if (image is TextureView view) { - _imageRefs[binding] = ((TextureView)image).GetIdentityImageView(); + _imageRefs[binding] = view.GetView(imageFormat).GetIdentityImageView(); _images[binding] = new DescriptorImageInfo() { ImageLayout = ImageLayout.General @@ -432,7 +435,7 @@ namespace Ryujinx.Graphics.Vulkan for (int i = 0; i < count; i++) { - _bufferImages[binding + i] = _bufferImageRefs[binding + i]?.GetBufferView(cbs) ?? default; + _bufferImages[binding + i] = _bufferImageRefs[binding + i]?.GetBufferView(cbs, _bufferImageFormats[binding + i]) ?? default; } ReadOnlySpan bufferImages = _bufferImages; diff --git a/Ryujinx.Graphics.Vulkan/TextureBuffer.cs b/Ryujinx.Graphics.Vulkan/TextureBuffer.cs index cc1cc3f1f..941f41b41 100644 --- a/Ryujinx.Graphics.Vulkan/TextureBuffer.cs +++ b/Ryujinx.Graphics.Vulkan/TextureBuffer.cs @@ -1,6 +1,7 @@ using Ryujinx.Graphics.GAL; using Silk.NET.Vulkan; using System; +using System.Collections.Generic; using VkFormat = Silk.NET.Vulkan.Format; namespace Ryujinx.Graphics.Vulkan @@ -13,6 +14,7 @@ namespace Ryujinx.Graphics.Vulkan private int _offset; private int _size; private Auto _bufferView; + private Dictionary> _selfManagedViews; public int Width { get; } public int Height { get; } @@ -72,6 +74,16 @@ namespace Ryujinx.Graphics.Vulkan private void ReleaseImpl() { + if (_selfManagedViews != null) + { + foreach (var bufferView in _selfManagedViews.Values) + { + bufferView.Dispose(); + } + + _selfManagedViews = null; + } + _bufferView?.Dispose(); _bufferView = null; } @@ -111,5 +123,28 @@ namespace Ryujinx.Graphics.Vulkan return _bufferView?.Get(cbs, _offset, _size).Value ?? default; } + + public BufferView GetBufferView(CommandBufferScoped cbs, GAL.Format format) + { + var vkFormat = FormatTable.GetFormat(format); + if (vkFormat == VkFormat) + { + return GetBufferView(cbs); + } + + if (_selfManagedViews != null && _selfManagedViews.TryGetValue(format, out var bufferView)) + { + return bufferView.Get(cbs, _offset, _size).Value; + } + + bufferView = _gd.BufferManager.CreateView(_bufferHandle, vkFormat, _offset, _size); + + if (bufferView != null) + { + (_selfManagedViews ??= new Dictionary>()).Add(format, bufferView); + } + + return bufferView?.Get(cbs, _offset, _size).Value ?? default; + } } } diff --git a/Ryujinx.Graphics.Vulkan/TextureView.cs b/Ryujinx.Graphics.Vulkan/TextureView.cs index 7c463e38c..ddeec1819 100644 --- a/Ryujinx.Graphics.Vulkan/TextureView.cs +++ b/Ryujinx.Graphics.Vulkan/TextureView.cs @@ -1,6 +1,7 @@ using Ryujinx.Graphics.GAL; using Silk.NET.Vulkan; using System; +using System.Collections.Generic; using System.Threading; using VkBuffer = Silk.NET.Vulkan.Buffer; using VkFormat = Silk.NET.Vulkan.Format; @@ -17,6 +18,7 @@ namespace Ryujinx.Graphics.Vulkan private readonly Auto _imageViewIdentity; private readonly Auto _imageView2dArray; private BufferHolder _flushStorage; + private Dictionary _selfManagedViews; private TextureCreateInfo _info; @@ -608,7 +610,46 @@ namespace Ryujinx.Graphics.Vulkan _gd.FormatCapabilities.FormatSupports(GAL.Format.S8Uint, formatFeatureFlags); } + public TextureView GetView(GAL.Format format) + { + if (format == Info.Format) + { + return this; + } + + if (_selfManagedViews != null && _selfManagedViews.TryGetValue(format, out var view)) + { + return view; + } + + view = CreateViewImpl(new TextureCreateInfo( + Info.Width, + Info.Height, + Info.Depth, + Info.Levels, + Info.Samples, + Info.BlockWidth, + Info.BlockHeight, + Info.BytesPerPixel, + format, + Info.DepthStencilMode, + Info.Target, + Info.SwizzleR, + Info.SwizzleG, + Info.SwizzleB, + Info.SwizzleA), 0, 0); + + (_selfManagedViews ??= new Dictionary()).Add(format, view); + + return view; + } + public ITexture CreateView(TextureCreateInfo info, int firstLayer, int firstLevel) + { + return CreateViewImpl(info, firstLayer, firstLevel); + } + + private TextureView CreateViewImpl(TextureCreateInfo info, int firstLayer, int firstLevel) { return new TextureView(_gd, _device, info, Storage, FirstLayer + firstLayer, FirstLevel + firstLevel); } @@ -921,6 +962,16 @@ namespace Ryujinx.Graphics.Vulkan public void Dispose() { + if (_selfManagedViews != null) + { + foreach (var view in _selfManagedViews.Values) + { + view.Dispose(); + } + + _selfManagedViews = null; + } + Dispose(true); }