Support format aliasing on SetImage

This commit is contained in:
gdk 2021-11-15 15:47:26 -03:00 committed by riperiperi
parent 616f14c46d
commit a9afcdfa10
3 changed files with 92 additions and 3 deletions

View file

@ -21,6 +21,7 @@ namespace Ryujinx.Graphics.Vulkan
private Auto<DisposableImageView>[] _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<BufferView> bufferImages = _bufferImages;

View file

@ -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<DisposableBufferView> _bufferView;
private Dictionary<GAL.Format, Auto<DisposableBufferView>> _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<GAL.Format, Auto<DisposableBufferView>>()).Add(format, bufferView);
}
return bufferView?.Get(cbs, _offset, _size).Value ?? default;
}
}
}

View file

@ -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<DisposableImageView> _imageViewIdentity;
private readonly Auto<DisposableImageView> _imageView2dArray;
private BufferHolder _flushStorage;
private Dictionary<GAL.Format, TextureView> _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<GAL.Format, TextureView>()).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);
}