Memory Changes part 2

* Slightly refactors RangeLists from the last Memory Changes MR, which fixes issue 61.

* Convert as many const size array iterators to span iterators as possible. When iterating over a const size array, every iteration created a Span, now only the first iteration does in most places.

* Now using object pooling for a few object types that were rapidly deleted and recreated.

* Converted a few flag checks to binary operations to save memory allocations.
This commit is contained in:
LotP 2025-08-25 17:44:15 -05:00 committed by KeatonTheBot
parent 01cb33f658
commit 171624e7f0
89 changed files with 2121 additions and 1157 deletions

View file

@ -708,9 +708,11 @@ namespace Ryujinx.Graphics.Vulkan
public void SetBlendState(AdvancedBlendDescriptor blend)
{
Span<PipelineColorBlendAttachmentState> colorBlendAttachmentStateSpan = _newState.Internal.ColorBlendAttachmentState.AsSpan();
for (int index = 0; index < Constants.MaxRenderTargets; index++)
{
ref var vkBlend = ref _newState.Internal.ColorBlendAttachmentState[index];
ref var vkBlend = ref colorBlendAttachmentStateSpan[index];
if (index == 0)
{
@ -983,10 +985,12 @@ namespace Ryujinx.Graphics.Vulkan
{
int count = Math.Min(Constants.MaxRenderTargets, componentMask.Length);
int writtenAttachments = 0;
Span<PipelineColorBlendAttachmentState> colorBlendAttachmentStateSpan = _newState.Internal.ColorBlendAttachmentState.AsSpan();
for (int i = 0; i < count; i++)
{
ref var vkBlend = ref _newState.Internal.ColorBlendAttachmentState[i];
ref var vkBlend = ref colorBlendAttachmentStateSpan[i];
var newMask = (ColorComponentFlags)componentMask[i];
// When color write mask is 0, remove all blend state to help the pipeline cache.
@ -1164,6 +1168,8 @@ namespace Ryujinx.Graphics.Vulkan
int count = Math.Min(Constants.MaxVertexAttributes, vertexAttribs.Length);
uint dirtyVbSizes = 0;
Span<VertexInputAttributeDescription> vertexAttributeDescriptionsSpan = _newState.Internal.VertexAttributeDescriptions.AsSpan();
for (int i = 0; i < count; i++)
{
@ -1177,7 +1183,7 @@ namespace Ryujinx.Graphics.Vulkan
dirtyVbSizes |= 1u << rawIndex;
}
_newState.Internal.VertexAttributeDescriptions[i] = new VertexInputAttributeDescription(
vertexAttributeDescriptionsSpan[i] = new VertexInputAttributeDescription(
(uint)i,
(uint)bufferIndex,
formatCapabilities.ConvertToVertexVkFormat(attribute.Format),
@ -1212,7 +1218,7 @@ namespace Ryujinx.Graphics.Vulkan
int validCount = 1;
BufferHandle lastHandle = default;
Auto<DisposableBuffer> lastBuffer = default;
Auto<DisposableBuffer> lastBuffer = null;
for (int i = 0; i < count; i++)
{
@ -1403,6 +1409,9 @@ namespace Ryujinx.Graphics.Vulkan
// Look for textures that are masked out.
Span<PipelineColorBlendAttachmentState> colorBlendAttachmentStateSpan =
_newState.Internal.ColorBlendAttachmentState.AsSpan();
for (int i = 0; i < colors.Length; i++)
{
if (colors[i] == null)
@ -1410,7 +1419,7 @@ namespace Ryujinx.Graphics.Vulkan
continue;
}
ref var vkBlend = ref _newState.Internal.ColorBlendAttachmentState[i];
ref var vkBlend = ref colorBlendAttachmentStateSpan[i];
for (int j = 0; j < i; j++)
{
@ -1419,7 +1428,7 @@ namespace Ryujinx.Graphics.Vulkan
if (colors[i] == colors[j])
{
// Prefer the binding with no write mask.
ref var vkBlend2 = ref _newState.Internal.ColorBlendAttachmentState[j];
ref var vkBlend2 = ref colorBlendAttachmentStateSpan[j];
if (vkBlend.ColorWriteMask == 0)
{
colors[i] = null;