mirror of
https://git.naxdy.org/Mirror/Ryujinx.git
synced 2025-02-22 09:03:36 +00:00
Push descriptor support check, buffer redundancy checks
Should make push descriptors faster, needs more testing though.
This commit is contained in:
parent
db4e7d28ea
commit
cd3ad0a6ab
4 changed files with 92 additions and 19 deletions
|
@ -30,6 +30,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
private BufferView[] _bufferTextures;
|
private BufferView[] _bufferTextures;
|
||||||
private BufferView[] _bufferImages;
|
private BufferView[] _bufferImages;
|
||||||
|
|
||||||
|
private bool[] _uniformSet;
|
||||||
|
private bool[] _storageSet;
|
||||||
|
private Silk.NET.Vulkan.Buffer _cachedSupportBuffer;
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
private enum DirtyFlags
|
private enum DirtyFlags
|
||||||
{
|
{
|
||||||
|
@ -68,6 +72,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_bufferTextures = new BufferView[Constants.MaxTextureBindings];
|
_bufferTextures = new BufferView[Constants.MaxTextureBindings];
|
||||||
_bufferImages = new BufferView[Constants.MaxImageBindings];
|
_bufferImages = new BufferView[Constants.MaxImageBindings];
|
||||||
|
|
||||||
|
_uniformSet = new bool[Constants.MaxUniformBufferBindings];
|
||||||
|
_storageSet = new bool[Constants.MaxStorageBufferBindings];
|
||||||
|
|
||||||
if (gd.Capabilities.SupportsNullDescriptors)
|
if (gd.Capabilities.SupportsNullDescriptors)
|
||||||
{
|
{
|
||||||
// If null descriptors are supported, we can pass null as the handle.
|
// If null descriptors are supported, we can pass null as the handle.
|
||||||
|
@ -147,14 +154,25 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
for (int i = 0; i < buffers.Length; i++)
|
for (int i = 0; i < buffers.Length; i++)
|
||||||
{
|
{
|
||||||
var buffer = buffers[i];
|
var buffer = buffers[i];
|
||||||
|
int index = first + i;
|
||||||
|
|
||||||
_storageBufferRefs[first + i] = _gd.BufferManager.GetBuffer(commandBuffer, buffer.Handle, false);
|
Auto<DisposableBuffer> vkBuffer = _gd.BufferManager.GetBuffer(commandBuffer, buffer.Handle, false);
|
||||||
|
ref Auto<DisposableBuffer> currentVkBuffer = ref _storageBufferRefs[index];
|
||||||
|
|
||||||
_storageBuffers[first + i] = new DescriptorBufferInfo()
|
DescriptorBufferInfo info = new DescriptorBufferInfo()
|
||||||
{
|
{
|
||||||
Offset = (ulong)buffer.Offset,
|
Offset = (ulong)buffer.Offset,
|
||||||
Range = (ulong)buffer.Size
|
Range = (ulong)buffer.Size
|
||||||
};
|
};
|
||||||
|
ref DescriptorBufferInfo currentInfo = ref _storageBuffers[index];
|
||||||
|
|
||||||
|
if (vkBuffer != currentVkBuffer || currentInfo.Offset != info.Offset || currentInfo.Range != info.Range)
|
||||||
|
{
|
||||||
|
_storageSet[index] = false;
|
||||||
|
|
||||||
|
currentInfo = info;
|
||||||
|
currentVkBuffer = vkBuffer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SignalDirty(DirtyFlags.Storage);
|
SignalDirty(DirtyFlags.Storage);
|
||||||
|
@ -194,14 +212,25 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
for (int i = 0; i < buffers.Length; i++)
|
for (int i = 0; i < buffers.Length; i++)
|
||||||
{
|
{
|
||||||
var buffer = buffers[i];
|
var buffer = buffers[i];
|
||||||
|
int index = first + i;
|
||||||
|
|
||||||
_uniformBufferRefs[first + i] = _gd.BufferManager.GetBuffer(commandBuffer, buffer.Handle, false);
|
Auto<DisposableBuffer> vkBuffer = _gd.BufferManager.GetBuffer(commandBuffer, buffer.Handle, false);
|
||||||
|
ref Auto<DisposableBuffer> currentVkBuffer = ref _uniformBufferRefs[index];
|
||||||
|
|
||||||
_uniformBuffers[first + i] = new DescriptorBufferInfo()
|
DescriptorBufferInfo info = new DescriptorBufferInfo()
|
||||||
{
|
{
|
||||||
Offset = (ulong)buffer.Offset,
|
Offset = (ulong)buffer.Offset,
|
||||||
Range = (ulong)buffer.Size
|
Range = (ulong)buffer.Size
|
||||||
};
|
};
|
||||||
|
ref DescriptorBufferInfo currentInfo = ref _uniformBuffers[index];
|
||||||
|
|
||||||
|
if (vkBuffer != currentVkBuffer || currentInfo.Offset != info.Offset || currentInfo.Range != info.Range)
|
||||||
|
{
|
||||||
|
_uniformSet[index] = false;
|
||||||
|
|
||||||
|
currentInfo = info;
|
||||||
|
currentVkBuffer = vkBuffer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SignalDirty(DirtyFlags.Uniform);
|
SignalDirty(DirtyFlags.Uniform);
|
||||||
|
@ -294,11 +323,17 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
Span<DescriptorBufferInfo> uniformBuffer = stackalloc DescriptorBufferInfo[1];
|
Span<DescriptorBufferInfo> uniformBuffer = stackalloc DescriptorBufferInfo[1];
|
||||||
|
|
||||||
|
if (!_uniformSet[0])
|
||||||
|
{
|
||||||
|
_cachedSupportBuffer = _gd.BufferManager.GetBuffer(cbs.CommandBuffer, _pipeline.SupportBufferUpdater.Handle, false).Get(cbs, 0, SupportBuffer.RequiredSize).Value;
|
||||||
|
_uniformSet[0] = true;
|
||||||
|
}
|
||||||
|
|
||||||
uniformBuffer[0] = new DescriptorBufferInfo()
|
uniformBuffer[0] = new DescriptorBufferInfo()
|
||||||
{
|
{
|
||||||
Offset = 0,
|
Offset = 0,
|
||||||
Range = (ulong)SupportBuffer.RequiredSize,
|
Range = (ulong)SupportBuffer.RequiredSize,
|
||||||
Buffer = _gd.BufferManager.GetBuffer(cbs.CommandBuffer, _pipeline.SupportBufferUpdater.Handle, false).Get(cbs, 0, SupportBuffer.RequiredSize).Value
|
Buffer = _cachedSupportBuffer
|
||||||
};
|
};
|
||||||
|
|
||||||
dsc.UpdateBuffers(0, 0, uniformBuffer, DescriptorType.UniformBuffer);
|
dsc.UpdateBuffers(0, 0, uniformBuffer, DescriptorType.UniformBuffer);
|
||||||
|
@ -325,7 +360,14 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
UpdateBuffer(cbs, ref _uniformBuffers[binding + i], _uniformBufferRefs[binding + i], dummyBuffer);
|
int index = binding + i;
|
||||||
|
|
||||||
|
if (!_uniformSet[index])
|
||||||
|
{
|
||||||
|
UpdateBuffer(cbs, ref _uniformBuffers[index], _uniformBufferRefs[index], dummyBuffer);
|
||||||
|
|
||||||
|
_uniformSet[index] = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReadOnlySpan<DescriptorBufferInfo> uniformBuffers = _uniformBuffers;
|
ReadOnlySpan<DescriptorBufferInfo> uniformBuffers = _uniformBuffers;
|
||||||
|
@ -335,7 +377,14 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
UpdateBuffer(cbs, ref _storageBuffers[binding + i], _storageBufferRefs[binding + i], dummyBuffer);
|
int index = binding + i;
|
||||||
|
|
||||||
|
if (!_storageSet[index])
|
||||||
|
{
|
||||||
|
UpdateBuffer(cbs, ref _storageBuffers[index], _storageBufferRefs[index], dummyBuffer);
|
||||||
|
|
||||||
|
_storageSet[index] = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReadOnlySpan<DescriptorBufferInfo> storageBuffers = _storageBuffers;
|
ReadOnlySpan<DescriptorBufferInfo> storageBuffers = _storageBuffers;
|
||||||
|
@ -442,16 +491,21 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
var dummyBuffer = _dummyBuffer?.GetBuffer();
|
var dummyBuffer = _dummyBuffer?.GetBuffer();
|
||||||
int stagesCount = _program.Bindings[PipelineBase.UniformSetIndex].Length;
|
int stagesCount = _program.Bindings[PipelineBase.UniformSetIndex].Length;
|
||||||
|
|
||||||
Span<DescriptorBufferInfo> uniformBuffer = stackalloc DescriptorBufferInfo[1];
|
if (!_uniformSet[0])
|
||||||
|
|
||||||
uniformBuffer[0] = new DescriptorBufferInfo()
|
|
||||||
{
|
{
|
||||||
Offset = 0,
|
Span<DescriptorBufferInfo> uniformBuffer = stackalloc DescriptorBufferInfo[1];
|
||||||
Range = (ulong)SupportBuffer.RequiredSize,
|
|
||||||
Buffer = _gd.BufferManager.GetBuffer(cbs.CommandBuffer, _pipeline.SupportBufferUpdater.Handle, false).Get(cbs, 0, SupportBuffer.RequiredSize).Value
|
|
||||||
};
|
|
||||||
|
|
||||||
UpdateBuffers(cbs, pbp, 0, uniformBuffer, DescriptorType.UniformBuffer);
|
uniformBuffer[0] = new DescriptorBufferInfo()
|
||||||
|
{
|
||||||
|
Offset = 0,
|
||||||
|
Range = (ulong)SupportBuffer.RequiredSize,
|
||||||
|
Buffer = _gd.BufferManager.GetBuffer(cbs.CommandBuffer, _pipeline.SupportBufferUpdater.Handle, false).Get(cbs, 0, SupportBuffer.RequiredSize).Value
|
||||||
|
};
|
||||||
|
|
||||||
|
_uniformSet[0] = true;
|
||||||
|
|
||||||
|
UpdateBuffers(cbs, pbp, 0, uniformBuffer, DescriptorType.UniformBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
for (int stageIndex = 0; stageIndex < stagesCount; stageIndex++)
|
for (int stageIndex = 0; stageIndex < stagesCount; stageIndex++)
|
||||||
{
|
{
|
||||||
|
@ -469,13 +523,25 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool doUpdate = false;
|
||||||
|
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
UpdateBuffer(cbs, ref _uniformBuffers[binding + i], _uniformBufferRefs[binding + i], dummyBuffer);
|
int index = binding + i;
|
||||||
|
|
||||||
|
if (!_uniformSet[index])
|
||||||
|
{
|
||||||
|
UpdateBuffer(cbs, ref _uniformBuffers[index], _uniformBufferRefs[index], dummyBuffer);
|
||||||
|
_uniformSet[index] = true;
|
||||||
|
doUpdate = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReadOnlySpan<DescriptorBufferInfo> uniformBuffers = _uniformBuffers;
|
if (doUpdate)
|
||||||
UpdateBuffers(cbs, pbp, binding, uniformBuffers.Slice(binding, count), DescriptorType.UniformBuffer);
|
{
|
||||||
|
ReadOnlySpan<DescriptorBufferInfo> uniformBuffers = _uniformBuffers;
|
||||||
|
UpdateBuffers(cbs, pbp, binding, uniformBuffers.Slice(binding, count), DescriptorType.UniformBuffer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -516,6 +582,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
public void SignalCommandBufferChange()
|
public void SignalCommandBufferChange()
|
||||||
{
|
{
|
||||||
_dirty = DirtyFlags.All;
|
_dirty = DirtyFlags.All;
|
||||||
|
|
||||||
|
Array.Clear(_uniformSet);
|
||||||
|
Array.Clear(_storageSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void Dispose(bool disposing)
|
protected virtual void Dispose(bool disposing)
|
||||||
|
|
|
@ -8,6 +8,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
public readonly bool SupportsExtendedDynamicState;
|
public readonly bool SupportsExtendedDynamicState;
|
||||||
public readonly bool SupportsMultiView;
|
public readonly bool SupportsMultiView;
|
||||||
public readonly bool SupportsNullDescriptors;
|
public readonly bool SupportsNullDescriptors;
|
||||||
|
public readonly bool SupportsPushDescriptors;
|
||||||
public readonly bool SupportsTransformFeedback;
|
public readonly bool SupportsTransformFeedback;
|
||||||
public readonly bool SupportsTransformFeedbackQueries;
|
public readonly bool SupportsTransformFeedbackQueries;
|
||||||
public readonly bool SupportsGeometryShader;
|
public readonly bool SupportsGeometryShader;
|
||||||
|
@ -20,6 +21,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
bool supportsExtendedDynamicState,
|
bool supportsExtendedDynamicState,
|
||||||
bool supportsMultiView,
|
bool supportsMultiView,
|
||||||
bool supportsNullDescriptors,
|
bool supportsNullDescriptors,
|
||||||
|
bool supportsPushDescriptors,
|
||||||
bool supportsTransformFeedback,
|
bool supportsTransformFeedback,
|
||||||
bool supportsTransformFeedbackQueries,
|
bool supportsTransformFeedbackQueries,
|
||||||
bool supportsGeometryShader,
|
bool supportsGeometryShader,
|
||||||
|
@ -31,6 +33,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
SupportsExtendedDynamicState = supportsExtendedDynamicState;
|
SupportsExtendedDynamicState = supportsExtendedDynamicState;
|
||||||
SupportsMultiView = supportsMultiView;
|
SupportsMultiView = supportsMultiView;
|
||||||
SupportsNullDescriptors = supportsNullDescriptors;
|
SupportsNullDescriptors = supportsNullDescriptors;
|
||||||
|
SupportsPushDescriptors = supportsPushDescriptors;
|
||||||
SupportsTransformFeedback = supportsTransformFeedback;
|
SupportsTransformFeedback = supportsTransformFeedback;
|
||||||
SupportsTransformFeedbackQueries = supportsTransformFeedbackQueries;
|
SupportsTransformFeedbackQueries = supportsTransformFeedbackQueries;
|
||||||
SupportsGeometryShader = supportsGeometryShader;
|
SupportsGeometryShader = supportsGeometryShader;
|
||||||
|
|
|
@ -90,7 +90,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
_shaders = internalShaders;
|
_shaders = internalShaders;
|
||||||
|
|
||||||
bool usePd = !isMinimal && VulkanConfiguration.UsePushDescriptors;
|
bool usePd = !isMinimal && VulkanConfiguration.UsePushDescriptors && _gd.Capabilities.SupportsPushDescriptors;
|
||||||
|
|
||||||
_plce = isMinimal
|
_plce = isMinimal
|
||||||
? gd.PipelineLayoutCache.Create(gd, device, shaders)
|
? gd.PipelineLayoutCache.Create(gd, device, shaders)
|
||||||
|
|
|
@ -212,6 +212,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
supportedExtensions.Contains(ExtExtendedDynamicState.ExtensionName),
|
supportedExtensions.Contains(ExtExtendedDynamicState.ExtensionName),
|
||||||
features2.Features.MultiViewport,
|
features2.Features.MultiViewport,
|
||||||
featuresRobustness2.NullDescriptor,
|
featuresRobustness2.NullDescriptor,
|
||||||
|
supportedExtensions.Contains(KhrPushDescriptor.ExtensionName),
|
||||||
supportsTransformFeedback,
|
supportsTransformFeedback,
|
||||||
propertiesTransformFeedback.TransformFeedbackQueries,
|
propertiesTransformFeedback.TransformFeedbackQueries,
|
||||||
supportedFeatures.GeometryShader,
|
supportedFeatures.GeometryShader,
|
||||||
|
|
Loading…
Reference in a new issue