mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-12-16 01:36:57 +00:00
Memory changes 3 (ryubing/ryujinx!202)
See merge request ryubing/ryujinx!202
This commit is contained in:
parent
ab7aeee67b
commit
92b61f9d73
43 changed files with 686 additions and 315 deletions
|
|
@ -1,6 +1,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 VkFormat = Silk.NET.Vulkan.Format;
|
||||
|
|
@ -10,26 +11,27 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
class FramebufferParams
|
||||
{
|
||||
private readonly Device _device;
|
||||
private readonly Auto<DisposableImageView>[] _attachments;
|
||||
private readonly TextureView[] _colors;
|
||||
private readonly TextureView _depthStencil;
|
||||
private readonly TextureView[] _colorsCanonical;
|
||||
private readonly TextureView _baseAttachment;
|
||||
private readonly uint _validColorAttachments;
|
||||
private Auto<DisposableImageView>[] _attachments;
|
||||
private TextureView[] _colors;
|
||||
private TextureView _depthStencil;
|
||||
private TextureView[] _colorsCanonical;
|
||||
private TextureView _baseAttachment;
|
||||
private uint _validColorAttachments;
|
||||
private int _totalCount;
|
||||
|
||||
public uint Width { get; }
|
||||
public uint Height { get; }
|
||||
public uint Layers { get; }
|
||||
public uint Width { get; private set; }
|
||||
public uint Height { get; private set; }
|
||||
public uint Layers { get; private set; }
|
||||
|
||||
public uint[] AttachmentSamples { get; }
|
||||
public VkFormat[] AttachmentFormats { get; }
|
||||
public int[] AttachmentIndices { get; }
|
||||
public uint AttachmentIntegerFormatMask { get; }
|
||||
public bool LogicOpsAllowed { get; }
|
||||
public uint[] AttachmentSamples { get; private set; }
|
||||
public VkFormat[] AttachmentFormats { get; private set; }
|
||||
public int[] AttachmentIndices { get; private set; }
|
||||
public uint AttachmentIntegerFormatMask { get; private set; }
|
||||
public bool LogicOpsAllowed { get; private set; }
|
||||
|
||||
public int AttachmentsCount { get; }
|
||||
public int MaxColorAttachmentIndex => AttachmentIndices.Length > 0 ? AttachmentIndices[^1] : -1;
|
||||
public bool HasDepthStencil { get; }
|
||||
public int AttachmentsCount { get; private set; }
|
||||
public int MaxColorAttachmentIndex => ColorAttachmentsCount > 0 ? AttachmentIndices[ColorAttachmentsCount - 1] : -1;
|
||||
public bool HasDepthStencil { get; private set; }
|
||||
public int ColorAttachmentsCount => AttachmentsCount - (HasDepthStencil ? 1 : 0);
|
||||
|
||||
public FramebufferParams(Device device, TextureView view, uint width, uint height)
|
||||
|
|
@ -50,7 +52,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
else
|
||||
{
|
||||
_colors = [view];
|
||||
_colorsCanonical = _colors;
|
||||
_colorsCanonical = [view];
|
||||
}
|
||||
|
||||
Width = width;
|
||||
|
|
@ -64,6 +66,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
LogicOpsAllowed = !format.IsFloatOrSrgb();
|
||||
|
||||
AttachmentsCount = 1;
|
||||
_totalCount = 1;
|
||||
|
||||
HasDepthStencil = isDepthStencil;
|
||||
}
|
||||
|
|
@ -133,7 +136,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
AttachmentIntegerFormatMask = attachmentIntegerFormatMask;
|
||||
LogicOpsAllowed = !allFormatsFloatOrSrgb;
|
||||
|
||||
if (depthStencil is TextureView dsTexture && dsTexture.Valid)
|
||||
if (depthStencil is TextureView { Valid: true } dsTexture)
|
||||
{
|
||||
_attachments[count - 1] = dsTexture.GetImageViewForAttachment();
|
||||
_depthStencil = dsTexture;
|
||||
|
|
@ -159,11 +162,151 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
Layers = layers;
|
||||
|
||||
AttachmentsCount = count;
|
||||
_totalCount = colors.Length;
|
||||
}
|
||||
|
||||
public FramebufferParams Update(ITexture[] colors, ITexture depthStencil)
|
||||
{
|
||||
int colorsCount = colors.Count(IsValidTextureView);
|
||||
|
||||
int count = colorsCount + (IsValidTextureView(depthStencil) ? 1 : 0);
|
||||
|
||||
Array.Clear(_attachments);
|
||||
Array.Clear(_colors);
|
||||
|
||||
if (_attachments.Length < count)
|
||||
{
|
||||
Array.Resize(ref _attachments, count);
|
||||
}
|
||||
if (_colors.Length < colorsCount)
|
||||
{
|
||||
Array.Resize(ref _colors, colorsCount);
|
||||
}
|
||||
if (_colorsCanonical.Length < colors.Length)
|
||||
{
|
||||
Array.Resize(ref _colorsCanonical, colors.Length);
|
||||
}
|
||||
|
||||
for (int i = 0; i < colors.Length; i++)
|
||||
{
|
||||
ITexture color = colors[i];
|
||||
if (color is TextureView { Valid: true } view)
|
||||
{
|
||||
_colorsCanonical[i] = view;
|
||||
}
|
||||
else
|
||||
{
|
||||
_colorsCanonical[i] = null;
|
||||
}
|
||||
}
|
||||
|
||||
Array.Clear(AttachmentSamples);
|
||||
Array.Clear(AttachmentFormats);
|
||||
Array.Clear(AttachmentIndices);
|
||||
|
||||
if (AttachmentSamples.Length < count)
|
||||
{
|
||||
uint[] attachmentSamples = AttachmentSamples;
|
||||
Array.Resize(ref attachmentSamples, count);
|
||||
AttachmentSamples = attachmentSamples;
|
||||
}
|
||||
if (AttachmentFormats.Length < count)
|
||||
{
|
||||
VkFormat[] attachmentFormats = AttachmentFormats;
|
||||
Array.Resize(ref attachmentFormats, count);
|
||||
AttachmentFormats = attachmentFormats;
|
||||
}
|
||||
if (AttachmentIndices.Length < colorsCount)
|
||||
{
|
||||
int[] attachmentIndices = AttachmentIndices;
|
||||
Array.Resize(ref attachmentIndices, colorsCount);
|
||||
AttachmentIndices = attachmentIndices;
|
||||
}
|
||||
|
||||
uint width = uint.MaxValue;
|
||||
uint height = uint.MaxValue;
|
||||
uint layers = uint.MaxValue;
|
||||
|
||||
int index = 0;
|
||||
uint attachmentIntegerFormatMask = 0;
|
||||
bool allFormatsFloatOrSrgb = colorsCount != 0;
|
||||
|
||||
_validColorAttachments = 0;
|
||||
_baseAttachment = null;
|
||||
|
||||
for (int bindIndex = 0; bindIndex < colors.Length; bindIndex++)
|
||||
{
|
||||
TextureView texture = _colorsCanonical[bindIndex];
|
||||
if (texture is not null)
|
||||
{
|
||||
_attachments[index] = texture.GetImageViewForAttachment();
|
||||
_colors[index] = texture;
|
||||
_validColorAttachments |= 1u << bindIndex;
|
||||
_baseAttachment = texture;
|
||||
|
||||
AttachmentSamples[index] = (uint)texture.Info.Samples;
|
||||
AttachmentFormats[index] = texture.VkFormat;
|
||||
AttachmentIndices[index] = bindIndex;
|
||||
|
||||
Format format = texture.Info.Format;
|
||||
|
||||
if (format.IsInteger())
|
||||
{
|
||||
attachmentIntegerFormatMask |= 1u << bindIndex;
|
||||
}
|
||||
|
||||
allFormatsFloatOrSrgb &= format.IsFloatOrSrgb();
|
||||
|
||||
width = Math.Min(width, (uint)texture.Width);
|
||||
height = Math.Min(height, (uint)texture.Height);
|
||||
layers = Math.Min(layers, (uint)texture.Layers);
|
||||
|
||||
if (++index >= colorsCount)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AttachmentIntegerFormatMask = attachmentIntegerFormatMask;
|
||||
LogicOpsAllowed = !allFormatsFloatOrSrgb;
|
||||
_depthStencil = null;
|
||||
HasDepthStencil = false;
|
||||
|
||||
if (depthStencil is TextureView { Valid: true } dsTexture)
|
||||
{
|
||||
_attachments[count - 1] = dsTexture.GetImageViewForAttachment();
|
||||
_depthStencil = dsTexture;
|
||||
_baseAttachment ??= dsTexture;
|
||||
|
||||
AttachmentSamples[count - 1] = (uint)dsTexture.Info.Samples;
|
||||
AttachmentFormats[count - 1] = dsTexture.VkFormat;
|
||||
|
||||
width = Math.Min(width, (uint)dsTexture.Width);
|
||||
height = Math.Min(height, (uint)dsTexture.Height);
|
||||
layers = Math.Min(layers, (uint)dsTexture.Layers);
|
||||
|
||||
HasDepthStencil = true;
|
||||
}
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
width = height = layers = 1;
|
||||
}
|
||||
|
||||
Width = width;
|
||||
Height = height;
|
||||
Layers = layers;
|
||||
|
||||
AttachmentsCount = count;
|
||||
_totalCount = colors.Length;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Auto<DisposableImageView> GetAttachment(int index)
|
||||
{
|
||||
if ((uint)index >= _attachments.Length)
|
||||
if ((uint)index >= AttachmentsCount)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
|
@ -183,7 +326,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
|
||||
public ComponentType GetAttachmentComponentType(int index)
|
||||
{
|
||||
if (_colors != null && (uint)index < _colors.Length)
|
||||
if (_colors != null && (uint)index < ColorAttachmentsCount)
|
||||
{
|
||||
Format format = _colors[index].Info.Format;
|
||||
|
||||
|
|
@ -218,7 +361,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
|
||||
private static bool IsValidTextureView(ITexture texture)
|
||||
{
|
||||
return texture is TextureView view && view.Valid;
|
||||
return texture is TextureView { Valid: true };
|
||||
}
|
||||
|
||||
public ClearRect GetClearRect(Rectangle<int> scissor, int layer, int layerCount)
|
||||
|
|
@ -233,9 +376,9 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
|
||||
public unsafe Auto<DisposableFramebuffer> Create(Vk api, CommandBufferScoped cbs, Auto<DisposableRenderPass> renderPass)
|
||||
{
|
||||
ImageView* attachments = stackalloc ImageView[_attachments.Length];
|
||||
ImageView* attachments = stackalloc ImageView[AttachmentsCount];
|
||||
|
||||
for (int i = 0; i < _attachments.Length; i++)
|
||||
for (int i = 0; i < AttachmentsCount; i++)
|
||||
{
|
||||
attachments[i] = _attachments[i].Get(cbs).Value;
|
||||
}
|
||||
|
|
@ -244,7 +387,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
{
|
||||
SType = StructureType.FramebufferCreateInfo,
|
||||
RenderPass = renderPass.Get(cbs).Value,
|
||||
AttachmentCount = (uint)_attachments.Length,
|
||||
AttachmentCount = (uint)AttachmentsCount,
|
||||
PAttachments = attachments,
|
||||
Width = Width,
|
||||
Height = Height,
|
||||
|
|
@ -252,14 +395,13 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
};
|
||||
|
||||
api.CreateFramebuffer(_device, in framebufferCreateInfo, null, out Framebuffer framebuffer).ThrowOnError();
|
||||
return new Auto<DisposableFramebuffer>(new DisposableFramebuffer(api, _device, framebuffer), null, _attachments);
|
||||
return new Auto<DisposableFramebuffer>(new DisposableFramebuffer(api, _device, framebuffer), null, _attachments[..AttachmentsCount]);
|
||||
}
|
||||
|
||||
public TextureView[] GetAttachmentViews()
|
||||
{
|
||||
TextureView[] result = new TextureView[_attachments.Length];
|
||||
|
||||
_colors?.CopyTo(result, 0);
|
||||
TextureView[] result = new TextureView[AttachmentsCount];
|
||||
_colors?.AsSpan(..ColorAttachmentsCount).CopyTo(result.AsSpan());
|
||||
|
||||
if (_depthStencil != null)
|
||||
{
|
||||
|
|
@ -278,8 +420,11 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
{
|
||||
if (_colors != null)
|
||||
{
|
||||
foreach (TextureView color in _colors)
|
||||
int count = ColorAttachmentsCount;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
TextureView color = _colors[i];
|
||||
// If Clear or DontCare were used, this would need to be write bit.
|
||||
color.Storage?.QueueLoadOpBarrier(cbs, false);
|
||||
}
|
||||
|
|
@ -294,8 +439,11 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
{
|
||||
if (_colors != null)
|
||||
{
|
||||
foreach (TextureView color in _colors)
|
||||
int count = ColorAttachmentsCount;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
TextureView color = _colors[i];
|
||||
color.Storage?.AddStoreOpUsage(false);
|
||||
}
|
||||
}
|
||||
|
|
@ -307,7 +455,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
{
|
||||
_depthStencil?.Storage.ClearBindings();
|
||||
|
||||
for (int i = 0; i < _colorsCanonical.Length; i++)
|
||||
for (int i = 0; i < _totalCount; i++)
|
||||
{
|
||||
_colorsCanonical[i]?.Storage.ClearBindings();
|
||||
}
|
||||
|
|
@ -317,7 +465,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
{
|
||||
_depthStencil?.Storage.AddBinding(_depthStencil);
|
||||
|
||||
for (int i = 0; i < _colorsCanonical.Length; i++)
|
||||
for (int i = 0; i < _totalCount; i++)
|
||||
{
|
||||
TextureView color = _colorsCanonical[i];
|
||||
color?.Storage.AddBinding(color);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue