mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2026-05-18 03:05:46 +00:00
Memory Changes part 2 (ryubing/ryujinx!123)
See merge request ryubing/ryujinx!123
This commit is contained in:
@@ -26,13 +26,17 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
public bool BecomesUnsetFrom(in BitMapStruct<T> from, ref BitMapStruct<T> into)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
Span<long> masksSpan = _masks.AsSpan();
|
||||
Span<long> fMasksSpan = from._masks.AsSpan();
|
||||
Span<long> iMasksSpan = into._masks.AsSpan();
|
||||
|
||||
int masks = _masks.Length;
|
||||
int masks = masksSpan.Length;
|
||||
for (int i = 0; i < masks; i++)
|
||||
{
|
||||
long fromMask = from._masks[i];
|
||||
long unsetMask = (~fromMask) & (fromMask ^ _masks[i]);
|
||||
into._masks[i] = unsetMask;
|
||||
long fromMask = fMasksSpan[i];
|
||||
long unsetMask = (~fromMask) & (fromMask ^ masksSpan[i]);
|
||||
iMasksSpan[i] = unsetMask;
|
||||
|
||||
result |= unsetMask != 0;
|
||||
}
|
||||
@@ -49,11 +53,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
// Iterate the set bits in the result, and signal them.
|
||||
|
||||
int offset = 0;
|
||||
int masks = _masks.Length;
|
||||
ref T resultMasks = ref result._masks;
|
||||
Span<long> rMasksSpan = result._masks.AsSpan();
|
||||
int masks = rMasksSpan.Length;
|
||||
for (int i = 0; i < masks; i++)
|
||||
{
|
||||
long value = resultMasks[i];
|
||||
long value = rMasksSpan[i];
|
||||
while (value != 0)
|
||||
{
|
||||
int bit = BitOperations.TrailingZeroCount((ulong)value);
|
||||
@@ -75,10 +79,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
// Iterate the set bits in the result, and signal them.
|
||||
|
||||
int offset = 0;
|
||||
int masks = _masks.Length;
|
||||
Span<long> masksSpan = _masks.AsSpan();
|
||||
int masks = masksSpan.Length;
|
||||
for (int i = 0; i < masks; i++)
|
||||
{
|
||||
long value = _masks[i];
|
||||
long value = masksSpan[i];
|
||||
while (value != 0)
|
||||
{
|
||||
int bit = BitOperations.TrailingZeroCount((ulong)value);
|
||||
@@ -94,9 +99,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
public bool AnySet()
|
||||
{
|
||||
for (int i = 0; i < _masks.Length; i++)
|
||||
Span<long> masksSpan = _masks.AsSpan();
|
||||
|
||||
for (int i = 0; i < masksSpan.Length; i++)
|
||||
{
|
||||
if (_masks[i] != 0)
|
||||
if (masksSpan[i] != 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -139,10 +146,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Span<long> masksSpan = _masks.AsSpan();
|
||||
|
||||
for (int i = startIndex + 1; i < endIndex; i++)
|
||||
{
|
||||
if (_masks[i] != 0)
|
||||
if (masksSpan[i] != 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -200,21 +209,23 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
int endIndex = end >> IntShift;
|
||||
int endBit = end & IntMask;
|
||||
long endMask = (long)(ulong.MaxValue >> (IntMask - endBit));
|
||||
|
||||
Span<long> masksSpan = _masks.AsSpan();
|
||||
|
||||
if (startIndex == endIndex)
|
||||
{
|
||||
_masks[startIndex] |= startMask & endMask;
|
||||
masksSpan[startIndex] |= startMask & endMask;
|
||||
}
|
||||
else
|
||||
{
|
||||
_masks[startIndex] |= startMask;
|
||||
masksSpan[startIndex] |= startMask;
|
||||
|
||||
for (int i = startIndex + 1; i < endIndex; i++)
|
||||
{
|
||||
_masks[i] |= -1L;
|
||||
masksSpan[i] |= -1L;
|
||||
}
|
||||
|
||||
_masks[endIndex] |= endMask;
|
||||
masksSpan[endIndex] |= endMask;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,13 +233,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
BitMapStruct<T> result = new();
|
||||
|
||||
ref T masks = ref _masks;
|
||||
ref T otherMasks = ref other._masks;
|
||||
ref T newMasks = ref result._masks;
|
||||
Span<long> masksSpan = _masks.AsSpan();
|
||||
Span<long> oMasksSpan = other._masks.AsSpan();
|
||||
Span<long> nMasksSpan = result._masks.AsSpan();
|
||||
|
||||
for (int i = 0; i < masks.Length; i++)
|
||||
for (int i = 0; i < masksSpan.Length; i++)
|
||||
{
|
||||
newMasks[i] = masks[i] | otherMasks[i];
|
||||
nMasksSpan[i] = masksSpan[i] | oMasksSpan[i];
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -246,17 +257,21 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
for (int i = 0; i < _masks.Length; i++)
|
||||
Span<long> masksSpan = _masks.AsSpan();
|
||||
|
||||
for (int i = 0; i < masksSpan.Length; i++)
|
||||
{
|
||||
_masks[i] = 0;
|
||||
masksSpan[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearInt(int start, int end)
|
||||
{
|
||||
Span<long> masksSpan = _masks.AsSpan();
|
||||
|
||||
for (int i = start; i <= end; i++)
|
||||
{
|
||||
_masks[i] = 0;
|
||||
masksSpan[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -680,7 +680,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
ShaderCollection program = _program;
|
||||
|
||||
if (_dirty.HasFlag(DirtyFlags.Uniform))
|
||||
if ((_dirty & DirtyFlags.Uniform) == DirtyFlags.Uniform)
|
||||
{
|
||||
if (program.UsePushDescriptors)
|
||||
{
|
||||
@@ -692,12 +692,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
}
|
||||
}
|
||||
|
||||
if (_dirty.HasFlag(DirtyFlags.Storage))
|
||||
if ((_dirty & DirtyFlags.Storage) == DirtyFlags.Storage)
|
||||
{
|
||||
UpdateAndBind(cbs, program, PipelineBase.StorageSetIndex, pbp);
|
||||
}
|
||||
|
||||
if (_dirty.HasFlag(DirtyFlags.Texture))
|
||||
if ((_dirty & DirtyFlags.Texture) == DirtyFlags.Texture)
|
||||
{
|
||||
if (program.UpdateTexturesWithoutTemplate)
|
||||
{
|
||||
@@ -709,7 +709,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
}
|
||||
}
|
||||
|
||||
if (_dirty.HasFlag(DirtyFlags.Image))
|
||||
if ((_dirty & DirtyFlags.Image) == DirtyFlags.Image)
|
||||
{
|
||||
UpdateAndBind(cbs, program, PipelineBase.ImageSetIndex, pbp);
|
||||
}
|
||||
|
||||
@@ -710,9 +710,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 PipelineColorBlendAttachmentState vkBlend = ref _newState.Internal.ColorBlendAttachmentState[index];
|
||||
ref PipelineColorBlendAttachmentState vkBlend = ref colorBlendAttachmentStateSpan[index];
|
||||
|
||||
if (index == 0)
|
||||
{
|
||||
@@ -985,10 +987,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 PipelineColorBlendAttachmentState vkBlend = ref _newState.Internal.ColorBlendAttachmentState[i];
|
||||
ref PipelineColorBlendAttachmentState vkBlend = ref colorBlendAttachmentStateSpan[i];
|
||||
ColorComponentFlags newMask = (ColorComponentFlags)componentMask[i];
|
||||
|
||||
// When color write mask is 0, remove all blend state to help the pipeline cache.
|
||||
@@ -1166,6 +1170,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++)
|
||||
{
|
||||
@@ -1179,7 +1185,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),
|
||||
@@ -1214,7 +1220,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
int validCount = 1;
|
||||
|
||||
BufferHandle lastHandle = default;
|
||||
Auto<DisposableBuffer> lastBuffer = default;
|
||||
Auto<DisposableBuffer> lastBuffer = null;
|
||||
|
||||
Span<VertexInputBindingDescription> vertexBindingDescriptionsSpan = _newState.Internal.VertexBindingDescriptions.AsSpan();
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
@@ -1236,7 +1244,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
int binding = i + 1;
|
||||
int descriptorIndex = validCount++;
|
||||
|
||||
_newState.Internal.VertexBindingDescriptions[descriptorIndex] = new VertexInputBindingDescription(
|
||||
vertexBindingDescriptionsSpan[descriptorIndex] = new VertexInputBindingDescription(
|
||||
(uint)binding,
|
||||
(uint)vertexBuffer.Stride,
|
||||
inputRate);
|
||||
@@ -1405,6 +1413,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)
|
||||
@@ -1412,7 +1423,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
continue;
|
||||
}
|
||||
|
||||
ref PipelineColorBlendAttachmentState vkBlend = ref _newState.Internal.ColorBlendAttachmentState[i];
|
||||
ref PipelineColorBlendAttachmentState vkBlend = ref colorBlendAttachmentStateSpan[i];
|
||||
|
||||
for (int j = 0; j < i; j++)
|
||||
{
|
||||
@@ -1421,7 +1432,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
if (colors[i] == colors[j])
|
||||
{
|
||||
// Prefer the binding with no write mask.
|
||||
ref PipelineColorBlendAttachmentState vkBlend2 = ref _newState.Internal.ColorBlendAttachmentState[j];
|
||||
ref PipelineColorBlendAttachmentState vkBlend2 = ref colorBlendAttachmentStateSpan[j];
|
||||
if (vkBlend.ColorWriteMask == 0)
|
||||
{
|
||||
colors[i] = null;
|
||||
|
||||
@@ -2,7 +2,8 @@ using Ryujinx.Common;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.Vulkan;
|
||||
using System;
|
||||
using Format = Silk.NET.Vulkan.Format;
|
||||
using VulkanFormat = Silk.NET.Vulkan.Format;
|
||||
using GALFormat = Ryujinx.Graphics.GAL.Format;
|
||||
using PolygonMode = Silk.NET.Vulkan.PolygonMode;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan
|
||||
@@ -23,7 +24,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
AttachmentReference* attachmentReferences = stackalloc AttachmentReference[MaxAttachments];
|
||||
|
||||
Span<int> attachmentIndices = stackalloc int[MaxAttachments];
|
||||
Span<Format> attachmentFormats = stackalloc Format[MaxAttachments];
|
||||
Span<VulkanFormat> attachmentFormats = stackalloc VulkanFormat[MaxAttachments];
|
||||
|
||||
int attachmentCount = 0;
|
||||
int colorCount = 0;
|
||||
@@ -32,14 +33,17 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
bool isNotMsOrSupportsStorage = gd.Capabilities.SupportsShaderStorageImageMultisample ||
|
||||
!state.DepthStencilFormat.IsImageCompatible();
|
||||
|
||||
for (int i = 0; i < state.AttachmentEnable.Length; i++)
|
||||
Span<bool> attachmentEnableSpan = state.AttachmentEnable.AsSpan();
|
||||
Span<GALFormat> attachmentFormatsSpan = state.AttachmentFormats.AsSpan();
|
||||
|
||||
for (int i = 0; i < attachmentEnableSpan.Length; i++)
|
||||
{
|
||||
if (state.AttachmentEnable[i])
|
||||
if (attachmentEnableSpan[i])
|
||||
{
|
||||
bool isNotMsOrSupportsStorageAttachments = gd.Capabilities.SupportsShaderStorageImageMultisample ||
|
||||
!state.AttachmentFormats[i].IsImageCompatible();
|
||||
!attachmentFormatsSpan[i].IsImageCompatible();
|
||||
|
||||
attachmentFormats[attachmentCount] = gd.FormatCapabilities.ConvertToVkFormat(state.AttachmentFormats[i], isNotMsOrSupportsStorageAttachments);
|
||||
attachmentFormats[attachmentCount] = gd.FormatCapabilities.ConvertToVkFormat(attachmentFormatsSpan[i], isNotMsOrSupportsStorageAttachments);
|
||||
|
||||
attachmentIndices[attachmentCount++] = i;
|
||||
colorCount++;
|
||||
@@ -222,13 +226,15 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
int vbCount = Math.Min(Constants.MaxVertexBuffers, state.VertexBufferCount);
|
||||
|
||||
Span<int> vbScalarSizes = stackalloc int[vbCount];
|
||||
Span<VertexAttribDescriptor> vertexAttribsSpan = state.VertexAttribs.AsSpan();
|
||||
Span<VertexInputAttributeDescription> vertexAttributeDescriptionsSpan = pipeline.Internal.VertexAttributeDescriptions.AsSpan();
|
||||
|
||||
for (int i = 0; i < vaCount; i++)
|
||||
{
|
||||
VertexAttribDescriptor attribute = state.VertexAttribs[i];
|
||||
VertexAttribDescriptor attribute = vertexAttribsSpan[i];
|
||||
int bufferIndex = attribute.IsZero ? 0 : attribute.BufferIndex + 1;
|
||||
|
||||
pipeline.Internal.VertexAttributeDescriptions[i] = new VertexInputAttributeDescription(
|
||||
vertexAttributeDescriptionsSpan[i] = new VertexInputAttributeDescription(
|
||||
(uint)i,
|
||||
(uint)bufferIndex,
|
||||
gd.FormatCapabilities.ConvertToVertexVkFormat(attribute.Format),
|
||||
@@ -243,9 +249,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
int descriptorIndex = 1;
|
||||
pipeline.Internal.VertexBindingDescriptions[0] = new VertexInputBindingDescription(0, 0, VertexInputRate.Vertex);
|
||||
|
||||
Span<BufferPipelineDescriptor> vertexBuffersSpan = state.VertexBuffers.AsSpan();
|
||||
Span<VertexInputBindingDescription> vertexBindingDescriptionsSpan = pipeline.Internal.VertexBindingDescriptions.AsSpan();
|
||||
|
||||
for (int i = 0; i < vbCount; i++)
|
||||
{
|
||||
BufferPipelineDescriptor vertexBuffer = state.VertexBuffers[i];
|
||||
BufferPipelineDescriptor vertexBuffer = vertexBuffersSpan[i];
|
||||
|
||||
if (vertexBuffer.Enable)
|
||||
{
|
||||
@@ -259,7 +268,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
}
|
||||
|
||||
// TODO: Support divisor > 1
|
||||
pipeline.Internal.VertexBindingDescriptions[descriptorIndex++] = new VertexInputBindingDescription(
|
||||
vertexBindingDescriptionsSpan[descriptorIndex++] = new VertexInputBindingDescription(
|
||||
(uint)i + 1,
|
||||
(uint)alignedStride,
|
||||
inputRate);
|
||||
@@ -268,15 +277,19 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
pipeline.VertexBindingDescriptionsCount = (uint)descriptorIndex;
|
||||
|
||||
Span<BlendDescriptor> blendDescriptorsSpan = state.BlendDescriptors.AsSpan();
|
||||
Span<uint> colorWriteMaskSpan = state.ColorWriteMask.AsSpan();
|
||||
Span<PipelineColorBlendAttachmentState> colorBlendAttachmentStateSpan = pipeline.Internal.ColorBlendAttachmentState.AsSpan();
|
||||
|
||||
// NOTE: Viewports, Scissors are dynamic.
|
||||
|
||||
for (int i = 0; i < Constants.MaxRenderTargets; i++)
|
||||
{
|
||||
BlendDescriptor blend = state.BlendDescriptors[i];
|
||||
BlendDescriptor blend = blendDescriptorsSpan[i];
|
||||
|
||||
if (blend.Enable && state.ColorWriteMask[i] != 0)
|
||||
if (blend.Enable && colorWriteMaskSpan[i] != 0)
|
||||
{
|
||||
pipeline.Internal.ColorBlendAttachmentState[i] = new PipelineColorBlendAttachmentState(
|
||||
colorBlendAttachmentStateSpan[i] = new PipelineColorBlendAttachmentState(
|
||||
blend.Enable,
|
||||
blend.ColorSrcFactor.Convert(),
|
||||
blend.ColorDstFactor.Convert(),
|
||||
@@ -284,12 +297,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
blend.AlphaSrcFactor.Convert(),
|
||||
blend.AlphaDstFactor.Convert(),
|
||||
blend.AlphaOp.Convert(),
|
||||
(ColorComponentFlags)state.ColorWriteMask[i]);
|
||||
(ColorComponentFlags)colorWriteMaskSpan[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
pipeline.Internal.ColorBlendAttachmentState[i] = new PipelineColorBlendAttachmentState(
|
||||
colorWriteMask: (ColorComponentFlags)state.ColorWriteMask[i]);
|
||||
colorBlendAttachmentStateSpan[i] = new PipelineColorBlendAttachmentState(
|
||||
colorWriteMask: (ColorComponentFlags)colorWriteMaskSpan[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,23 +310,27 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
int maxColorAttachmentIndex = -1;
|
||||
uint attachmentIntegerFormatMask = 0;
|
||||
bool allFormatsFloatOrSrgb = true;
|
||||
|
||||
Span<bool> attachmentEnableSpan = state.AttachmentEnable.AsSpan();
|
||||
Span<GALFormat> attachmentFormatsSpan = state.AttachmentFormats.AsSpan();
|
||||
Span<VulkanFormat> pAttachmentFormatsSpan = pipeline.Internal.AttachmentFormats.AsSpan();
|
||||
|
||||
for (int i = 0; i < Constants.MaxRenderTargets; i++)
|
||||
{
|
||||
if (state.AttachmentEnable[i])
|
||||
if (attachmentEnableSpan[i])
|
||||
{
|
||||
bool isNotMsOrSupportsStorage = gd.Capabilities.SupportsShaderStorageImageMultisample ||
|
||||
!state.AttachmentFormats[i].IsImageCompatible();
|
||||
!attachmentFormatsSpan[i].IsImageCompatible();
|
||||
|
||||
pipeline.Internal.AttachmentFormats[attachmentCount++] = gd.FormatCapabilities.ConvertToVkFormat(state.AttachmentFormats[i], isNotMsOrSupportsStorage);
|
||||
pAttachmentFormatsSpan[attachmentCount++] = gd.FormatCapabilities.ConvertToVkFormat(attachmentFormatsSpan[i], isNotMsOrSupportsStorage);
|
||||
maxColorAttachmentIndex = i;
|
||||
|
||||
if (state.AttachmentFormats[i].IsInteger())
|
||||
if (attachmentFormatsSpan[i].IsInteger())
|
||||
{
|
||||
attachmentIntegerFormatMask |= 1u << i;
|
||||
}
|
||||
|
||||
allFormatsFloatOrSrgb &= state.AttachmentFormats[i].IsFloatOrSrgb();
|
||||
allFormatsFloatOrSrgb &= attachmentFormatsSpan[i].IsFloatOrSrgb();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -322,7 +339,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
bool isNotMsOrSupportsStorage = !state.DepthStencilFormat.IsImageCompatible() ||
|
||||
gd.Capabilities.SupportsShaderStorageImageMultisample;
|
||||
|
||||
pipeline.Internal.AttachmentFormats[attachmentCount++] = gd.FormatCapabilities.ConvertToVkFormat(state.DepthStencilFormat, isNotMsOrSupportsStorage);
|
||||
pAttachmentFormatsSpan[attachmentCount++] = gd.FormatCapabilities.ConvertToVkFormat(state.DepthStencilFormat, isNotMsOrSupportsStorage);
|
||||
}
|
||||
|
||||
pipeline.ColorBlendAttachmentStateCount = (uint)(maxColorAttachmentIndex + 1);
|
||||
|
||||
@@ -121,32 +121,32 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
Vk api = gd.Api;
|
||||
|
||||
if (_dirty.HasFlag(DirtyFlags.Blend))
|
||||
if ((_dirty & DirtyFlags.Blend) == DirtyFlags.Blend)
|
||||
{
|
||||
RecordBlend(api, commandBuffer);
|
||||
}
|
||||
|
||||
if (_dirty.HasFlag(DirtyFlags.DepthBias))
|
||||
if ((_dirty & DirtyFlags.DepthBias) == DirtyFlags.DepthBias)
|
||||
{
|
||||
RecordDepthBias(api, commandBuffer);
|
||||
}
|
||||
|
||||
if (_dirty.HasFlag(DirtyFlags.Scissor))
|
||||
if ((_dirty & DirtyFlags.Scissor) == DirtyFlags.Scissor)
|
||||
{
|
||||
RecordScissor(api, commandBuffer);
|
||||
}
|
||||
|
||||
if (_dirty.HasFlag(DirtyFlags.Stencil))
|
||||
if ((_dirty & DirtyFlags.Stencil) == DirtyFlags.Stencil)
|
||||
{
|
||||
RecordStencilMasks(api, commandBuffer);
|
||||
}
|
||||
|
||||
if (_dirty.HasFlag(DirtyFlags.Viewport))
|
||||
if ((_dirty & DirtyFlags.Viewport) == DirtyFlags.Viewport)
|
||||
{
|
||||
RecordViewport(api, commandBuffer);
|
||||
}
|
||||
|
||||
if (_dirty.HasFlag(DirtyFlags.FeedbackLoop) && gd.Capabilities.SupportsDynamicAttachmentFeedbackLoop)
|
||||
if ((_dirty & DirtyFlags.FeedbackLoop) == DirtyFlags.FeedbackLoop && gd.Capabilities.SupportsDynamicAttachmentFeedbackLoop)
|
||||
{
|
||||
RecordFeedbackLoop(gd.DynamicFeedbackLoopApi, commandBuffer);
|
||||
}
|
||||
|
||||
@@ -520,6 +520,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
};
|
||||
|
||||
uint blendEnables = 0;
|
||||
|
||||
Span<PipelineColorBlendAttachmentState> colorBlendAttachmentStateSpan =
|
||||
Internal.ColorBlendAttachmentState.AsSpan();
|
||||
|
||||
if (gd.IsMoltenVk && Internal.AttachmentIntegerFormatMask != 0)
|
||||
{
|
||||
@@ -530,12 +533,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
int i = BitOperations.TrailingZeroCount(attachmentIntegerFormatMask);
|
||||
|
||||
if (Internal.ColorBlendAttachmentState[i].BlendEnable)
|
||||
if (colorBlendAttachmentStateSpan[i].BlendEnable)
|
||||
{
|
||||
blendEnables |= 1u << i;
|
||||
}
|
||||
|
||||
Internal.ColorBlendAttachmentState[i].BlendEnable = false;
|
||||
colorBlendAttachmentStateSpan[i].BlendEnable = false;
|
||||
attachmentIntegerFormatMask &= ~(1u << i);
|
||||
}
|
||||
}
|
||||
@@ -656,7 +659,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
int i = BitOperations.TrailingZeroCount(blendEnables);
|
||||
|
||||
Internal.ColorBlendAttachmentState[i].BlendEnable = true;
|
||||
colorBlendAttachmentStateSpan[i].BlendEnable = true;
|
||||
blendEnables &= ~(1u << i);
|
||||
}
|
||||
}
|
||||
@@ -675,14 +678,21 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
// To work around this, we reduce the format to something that doesn't exceed the stride if possible.
|
||||
// The assumption is that the exceeding components are not actually accessed on the shader.
|
||||
|
||||
Span<VertexInputAttributeDescription> vertexAttributeDescriptionsSpan =
|
||||
Internal.VertexAttributeDescriptions.AsSpan();
|
||||
Span<VertexInputBindingDescription> vertexBindingDescriptionsSpan =
|
||||
Internal.VertexBindingDescriptions.AsSpan();
|
||||
Span<VertexInputAttributeDescription> vertexAttributeDescriptions2Span =
|
||||
_vertexAttributeDescriptions2.AsSpan();
|
||||
|
||||
for (int index = 0; index < VertexAttributeDescriptionsCount; index++)
|
||||
{
|
||||
VertexInputAttributeDescription attribute = Internal.VertexAttributeDescriptions[index];
|
||||
VertexInputAttributeDescription attribute = vertexAttributeDescriptionsSpan[index];
|
||||
int vbIndex = GetVertexBufferIndex(attribute.Binding);
|
||||
|
||||
if (vbIndex >= 0)
|
||||
{
|
||||
ref VertexInputBindingDescription vb = ref Internal.VertexBindingDescriptions[vbIndex];
|
||||
ref VertexInputBindingDescription vb = ref vertexBindingDescriptionsSpan[vbIndex];
|
||||
|
||||
Format format = attribute.Format;
|
||||
|
||||
@@ -707,15 +717,18 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
}
|
||||
}
|
||||
|
||||
_vertexAttributeDescriptions2[index] = attribute;
|
||||
vertexAttributeDescriptions2Span[index] = attribute;
|
||||
}
|
||||
}
|
||||
|
||||
private int GetVertexBufferIndex(uint binding)
|
||||
{
|
||||
Span<VertexInputBindingDescription> vertexBindingDescriptionsSpan =
|
||||
Internal.VertexBindingDescriptions.AsSpan();
|
||||
|
||||
for (int index = 0; index < VertexBindingDescriptionsCount; index++)
|
||||
{
|
||||
if (Internal.VertexBindingDescriptions[index].Binding == binding)
|
||||
if (vertexBindingDescriptionsSpan[index].Binding == binding)
|
||||
{
|
||||
return index;
|
||||
}
|
||||
|
||||
@@ -86,37 +86,45 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
Id6 * 23 ^
|
||||
Id7 * 23 ^
|
||||
Id8 * 23;
|
||||
|
||||
ReadOnlySpan<VertexInputAttributeDescription> vertexAttributeDescriptionsSpan = VertexAttributeDescriptions.AsSpan();
|
||||
|
||||
for (int i = 0; i < (int)VertexAttributeDescriptionsCount; i++)
|
||||
{
|
||||
hash64 ^= VertexAttributeDescriptions[i].Binding * 23;
|
||||
hash64 ^= (uint)VertexAttributeDescriptions[i].Format * 23;
|
||||
hash64 ^= VertexAttributeDescriptions[i].Location * 23;
|
||||
hash64 ^= VertexAttributeDescriptions[i].Offset * 23;
|
||||
hash64 ^= vertexAttributeDescriptionsSpan[i].Binding * 23;
|
||||
hash64 ^= (uint)vertexAttributeDescriptionsSpan[i].Format * 23;
|
||||
hash64 ^= vertexAttributeDescriptionsSpan[i].Location * 23;
|
||||
hash64 ^= vertexAttributeDescriptionsSpan[i].Offset * 23;
|
||||
}
|
||||
|
||||
ReadOnlySpan<VertexInputBindingDescription> vertexBindingDescriptionsSpan = VertexBindingDescriptions.AsSpan();
|
||||
|
||||
for (int i = 0; i < (int)VertexBindingDescriptionsCount; i++)
|
||||
{
|
||||
hash64 ^= VertexBindingDescriptions[i].Binding * 23;
|
||||
hash64 ^= (uint)VertexBindingDescriptions[i].InputRate * 23;
|
||||
hash64 ^= VertexBindingDescriptions[i].Stride * 23;
|
||||
hash64 ^= vertexBindingDescriptionsSpan[i].Binding * 23;
|
||||
hash64 ^= (uint)vertexBindingDescriptionsSpan[i].InputRate * 23;
|
||||
hash64 ^= vertexBindingDescriptionsSpan[i].Stride * 23;
|
||||
}
|
||||
|
||||
ReadOnlySpan<PipelineColorBlendAttachmentState> colorBlendAttachmentStateSpan = ColorBlendAttachmentState.AsSpan();
|
||||
|
||||
for (int i = 0; i < (int)ColorBlendAttachmentStateCount; i++)
|
||||
{
|
||||
hash64 ^= ColorBlendAttachmentState[i].BlendEnable * 23;
|
||||
hash64 ^= (uint)ColorBlendAttachmentState[i].SrcColorBlendFactor * 23;
|
||||
hash64 ^= (uint)ColorBlendAttachmentState[i].DstColorBlendFactor * 23;
|
||||
hash64 ^= (uint)ColorBlendAttachmentState[i].ColorBlendOp * 23;
|
||||
hash64 ^= (uint)ColorBlendAttachmentState[i].SrcAlphaBlendFactor * 23;
|
||||
hash64 ^= (uint)ColorBlendAttachmentState[i].DstAlphaBlendFactor * 23;
|
||||
hash64 ^= (uint)ColorBlendAttachmentState[i].AlphaBlendOp * 23;
|
||||
hash64 ^= (uint)ColorBlendAttachmentState[i].ColorWriteMask * 23;
|
||||
hash64 ^= colorBlendAttachmentStateSpan[i].BlendEnable * 23;
|
||||
hash64 ^= (uint)colorBlendAttachmentStateSpan[i].SrcColorBlendFactor * 23;
|
||||
hash64 ^= (uint)colorBlendAttachmentStateSpan[i].DstColorBlendFactor * 23;
|
||||
hash64 ^= (uint)colorBlendAttachmentStateSpan[i].ColorBlendOp * 23;
|
||||
hash64 ^= (uint)colorBlendAttachmentStateSpan[i].SrcAlphaBlendFactor * 23;
|
||||
hash64 ^= (uint)colorBlendAttachmentStateSpan[i].DstAlphaBlendFactor * 23;
|
||||
hash64 ^= (uint)colorBlendAttachmentStateSpan[i].AlphaBlendOp * 23;
|
||||
hash64 ^= (uint)colorBlendAttachmentStateSpan[i].ColorWriteMask * 23;
|
||||
}
|
||||
|
||||
ReadOnlySpan<Format> attachmentFormatsSpan = AttachmentFormats.AsSpan();
|
||||
|
||||
for (int i = 0; i < (int)ColorBlendAttachmentStateCount; i++)
|
||||
{
|
||||
hash64 ^= (uint)AttachmentFormats[i] * 23;
|
||||
hash64 ^= (uint)attachmentFormatsSpan[i] * 23;
|
||||
}
|
||||
|
||||
return (int)hash64 ^ ((int)(hash64 >> 32) * 17);
|
||||
|
||||
Reference in New Issue
Block a user