mirror of
https://git.naxdy.org/Mirror/Ryujinx.git
synced 2025-02-21 16:43:35 +00:00
Do not require null descriptors support
This commit is contained in:
parent
c832f55618
commit
74a8f37f8d
4 changed files with 64 additions and 13 deletions
|
@ -1,5 +1,6 @@
|
||||||
using Silk.NET.Vulkan;
|
using Silk.NET.Vulkan;
|
||||||
using System;
|
using System;
|
||||||
|
using VkBuffer = Silk.NET.Vulkan.Buffer;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Vulkan
|
namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
|
@ -15,17 +16,15 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_descriptorSets = descriptorSets;
|
_descriptorSets = descriptorSets;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InitializeBuffers(int setIndex, int baseBinding, int countPerUnit, DescriptorType type)
|
public void InitializeBuffers(int setIndex, int baseBinding, int countPerUnit, DescriptorType type, VkBuffer dummyBuffer)
|
||||||
{
|
{
|
||||||
Span<DescriptorBufferInfo> infos = stackalloc DescriptorBufferInfo[countPerUnit];
|
Span<DescriptorBufferInfo> infos = stackalloc DescriptorBufferInfo[countPerUnit];
|
||||||
|
|
||||||
for (int j = 0; j < countPerUnit; j++)
|
infos.Fill(new DescriptorBufferInfo()
|
||||||
{
|
{
|
||||||
infos[j] = new DescriptorBufferInfo()
|
Buffer = dummyBuffer,
|
||||||
{
|
Range = Vk.WholeSize
|
||||||
Range = Vk.WholeSize
|
});
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateBuffers(setIndex, baseBinding, infos, type);
|
UpdateBuffers(setIndex, baseBinding, infos, type);
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
private DirtyFlags _dirty;
|
private DirtyFlags _dirty;
|
||||||
|
|
||||||
|
private readonly BufferHolder _dummyBuffer;
|
||||||
private readonly TextureView _dummyTexture;
|
private readonly TextureView _dummyTexture;
|
||||||
private readonly SamplerHolder _dummySampler;
|
private readonly SamplerHolder _dummySampler;
|
||||||
|
|
||||||
|
@ -62,6 +63,17 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_bufferTextures = Array.Empty<BufferView>();
|
_bufferTextures = Array.Empty<BufferView>();
|
||||||
_bufferImages = Array.Empty<BufferView>();
|
_bufferImages = Array.Empty<BufferView>();
|
||||||
|
|
||||||
|
if (gd.Capabilities.SupportsNullDescriptors)
|
||||||
|
{
|
||||||
|
// If null descriptors are supported, we can pass null as the handle.
|
||||||
|
_dummyBuffer = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If null descriptors are not supported, we need to pass the handle of a dummy buffer on unused bindings.
|
||||||
|
_dummyBuffer = gd.BufferManager.Create(gd, 0x10000, forConditionalRendering: false, deviceLocal: true);
|
||||||
|
}
|
||||||
|
|
||||||
_dummyTexture = (TextureView)gd.CreateTexture(new GAL.TextureCreateInfo(
|
_dummyTexture = (TextureView)gd.CreateTexture(new GAL.TextureCreateInfo(
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
|
@ -283,13 +295,18 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private static void UpdateBuffer(CommandBufferScoped cbs, ref DescriptorBufferInfo info, Auto<DisposableBuffer> buffer)
|
private static void UpdateBuffer(
|
||||||
|
CommandBufferScoped cbs,
|
||||||
|
ref DescriptorBufferInfo info,
|
||||||
|
Auto<DisposableBuffer> buffer,
|
||||||
|
Auto<DisposableBuffer> dummyBuffer)
|
||||||
{
|
{
|
||||||
info.Buffer = buffer?.Get(cbs, (int)info.Offset, (int)info.Range).Value ?? default;
|
info.Buffer = buffer?.Get(cbs, (int)info.Offset, (int)info.Range).Value ?? default;
|
||||||
|
|
||||||
// The spec requires that buffers with null handle have offset as 0 and range as VK_WHOLE_SIZE.
|
// The spec requires that buffers with null handle have offset as 0 and range as VK_WHOLE_SIZE.
|
||||||
if (info.Buffer.Handle == 0)
|
if (info.Buffer.Handle == 0)
|
||||||
{
|
{
|
||||||
|
info.Buffer = dummyBuffer?.Get(cbs).Value ?? default;
|
||||||
info.Offset = 0;
|
info.Offset = 0;
|
||||||
info.Range = Vk.WholeSize;
|
info.Range = Vk.WholeSize;
|
||||||
}
|
}
|
||||||
|
@ -304,6 +321,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var dummyBuffer = _dummyBuffer?.GetBuffer();
|
||||||
|
|
||||||
var dsc = _program.GetNewDescriptorSetCollection(_gd, cbs.CommandBufferIndex, setIndex, out var isNew).Get(cbs);
|
var dsc = _program.GetNewDescriptorSetCollection(_gd, cbs.CommandBufferIndex, setIndex, out var isNew).Get(cbs);
|
||||||
|
|
||||||
if (isNew)
|
if (isNew)
|
||||||
|
@ -352,7 +371,7 @@ 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]);
|
UpdateBuffer(cbs, ref _uniformBuffers[binding + i], _uniformBufferRefs[binding + i], dummyBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReadOnlySpan<DescriptorBufferInfo> uniformBuffers = _uniformBuffers;
|
ReadOnlySpan<DescriptorBufferInfo> uniformBuffers = _uniformBuffers;
|
||||||
|
@ -369,7 +388,7 @@ 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]);
|
UpdateBuffer(cbs, ref _storageBuffers[binding + i], _storageBufferRefs[binding + i], dummyBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReadOnlySpan<DescriptorBufferInfo> storageBuffers = _storageBuffers;
|
ReadOnlySpan<DescriptorBufferInfo> storageBuffers = _storageBuffers;
|
||||||
|
@ -461,6 +480,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private void Initialize(CommandBufferScoped cbs, int setIndex, DescriptorSetCollection dsc)
|
private void Initialize(CommandBufferScoped cbs, int setIndex, DescriptorSetCollection dsc)
|
||||||
{
|
{
|
||||||
|
var dummyBuffer = _dummyBuffer?.GetBuffer().Get(cbs).Value ?? default;
|
||||||
|
|
||||||
uint stages = _program.Stages;
|
uint stages = _program.Stages;
|
||||||
|
|
||||||
while (stages != 0)
|
while (stages != 0)
|
||||||
|
@ -470,11 +491,21 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
if (setIndex == PipelineBase.UniformSetIndex)
|
if (setIndex == PipelineBase.UniformSetIndex)
|
||||||
{
|
{
|
||||||
dsc.InitializeBuffers(0, 1 + stage * Constants.MaxUniformBuffersPerStage, Constants.MaxUniformBuffersPerStage, DescriptorType.UniformBuffer);
|
dsc.InitializeBuffers(
|
||||||
|
0,
|
||||||
|
1 + stage * Constants.MaxUniformBuffersPerStage,
|
||||||
|
Constants.MaxUniformBuffersPerStage,
|
||||||
|
DescriptorType.UniformBuffer,
|
||||||
|
dummyBuffer);
|
||||||
}
|
}
|
||||||
else if (setIndex == PipelineBase.StorageSetIndex)
|
else if (setIndex == PipelineBase.StorageSetIndex)
|
||||||
{
|
{
|
||||||
dsc.InitializeBuffers(0, stage * Constants.MaxStorageBuffersPerStage, Constants.MaxStorageBuffersPerStage, DescriptorType.StorageBuffer);
|
dsc.InitializeBuffers(
|
||||||
|
0,
|
||||||
|
stage * Constants.MaxStorageBuffersPerStage,
|
||||||
|
Constants.MaxStorageBuffersPerStage,
|
||||||
|
DescriptorType.StorageBuffer,
|
||||||
|
dummyBuffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
public bool SupportsConditionalRendering { get; }
|
public bool SupportsConditionalRendering { get; }
|
||||||
public bool SupportsExtendedDynamicState { get; }
|
public bool SupportsExtendedDynamicState { get; }
|
||||||
|
public bool SupportsNullDescriptors { get; }
|
||||||
public bool SupportsTransformFeedback { get; }
|
public bool SupportsTransformFeedback { get; }
|
||||||
public bool SupportsTransformFeedbackQueries { get; }
|
public bool SupportsTransformFeedbackQueries { get; }
|
||||||
public bool SupportsGeometryShader { get; }
|
public bool SupportsGeometryShader { get; }
|
||||||
|
@ -16,6 +17,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
public HardwareCapabilities(
|
public HardwareCapabilities(
|
||||||
bool supportsConditionalRendering,
|
bool supportsConditionalRendering,
|
||||||
bool supportsExtendedDynamicState,
|
bool supportsExtendedDynamicState,
|
||||||
|
bool supportsNullDescriptors,
|
||||||
bool supportsTransformFeedback,
|
bool supportsTransformFeedback,
|
||||||
bool supportsTransformFeedbackQueries,
|
bool supportsTransformFeedbackQueries,
|
||||||
bool supportsGeometryShader,
|
bool supportsGeometryShader,
|
||||||
|
@ -25,6 +27,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
SupportsConditionalRendering = supportsConditionalRendering;
|
SupportsConditionalRendering = supportsConditionalRendering;
|
||||||
SupportsExtendedDynamicState = supportsExtendedDynamicState;
|
SupportsExtendedDynamicState = supportsExtendedDynamicState;
|
||||||
|
SupportsNullDescriptors = supportsNullDescriptors;
|
||||||
SupportsTransformFeedback = supportsTransformFeedback;
|
SupportsTransformFeedback = supportsTransformFeedback;
|
||||||
SupportsTransformFeedbackQueries = supportsTransformFeedbackQueries;
|
SupportsTransformFeedbackQueries = supportsTransformFeedbackQueries;
|
||||||
SupportsGeometryShader = supportsGeometryShader;
|
SupportsGeometryShader = supportsGeometryShader;
|
||||||
|
|
|
@ -195,9 +195,27 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
Api.GetPhysicalDeviceProperties2(_physicalDevice, &properties2);
|
Api.GetPhysicalDeviceProperties2(_physicalDevice, &properties2);
|
||||||
|
|
||||||
|
PhysicalDeviceFeatures2 features2 = new PhysicalDeviceFeatures2()
|
||||||
|
{
|
||||||
|
SType = StructureType.PhysicalDeviceFeatures2
|
||||||
|
};
|
||||||
|
|
||||||
|
PhysicalDeviceRobustness2FeaturesEXT featuresRobustness2 = new PhysicalDeviceRobustness2FeaturesEXT()
|
||||||
|
{
|
||||||
|
SType = StructureType.PhysicalDeviceRobustness2FeaturesExt
|
||||||
|
};
|
||||||
|
|
||||||
|
if (supportedExtensions.Contains("VK_EXT_robustness2"))
|
||||||
|
{
|
||||||
|
features2.PNext = &featuresRobustness2;
|
||||||
|
}
|
||||||
|
|
||||||
|
Api.GetPhysicalDeviceFeatures2(_physicalDevice, &features2);
|
||||||
|
|
||||||
Capabilities = new HardwareCapabilities(
|
Capabilities = new HardwareCapabilities(
|
||||||
supportedExtensions.Contains(ExtConditionalRendering.ExtensionName),
|
supportedExtensions.Contains(ExtConditionalRendering.ExtensionName),
|
||||||
supportedExtensions.Contains(ExtExtendedDynamicState.ExtensionName),
|
supportedExtensions.Contains(ExtExtendedDynamicState.ExtensionName),
|
||||||
|
featuresRobustness2.NullDescriptor,
|
||||||
supportsTransformFeedback,
|
supportsTransformFeedback,
|
||||||
propertiesTransformFeedback.TransformFeedbackQueries,
|
propertiesTransformFeedback.TransformFeedbackQueries,
|
||||||
supportedFeatures.GeometryShader,
|
supportedFeatures.GeometryShader,
|
||||||
|
@ -392,7 +410,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
uint driverVersionRaw = properties.DriverVersion;
|
uint driverVersionRaw = properties.DriverVersion;
|
||||||
|
|
||||||
// NVIDIA differ from the standard here and use a different format.
|
// NVIDIA differ from the standard here and uses a different format.
|
||||||
if (properties.VendorID == 0x10DE)
|
if (properties.VendorID == 0x10DE)
|
||||||
{
|
{
|
||||||
return $"{(driverVersionRaw >> 22) & 0x3FF}.{(driverVersionRaw >> 14) & 0xFF}.{(driverVersionRaw >> 6) & 0xFF}.{driverVersionRaw & 0x3F}";
|
return $"{(driverVersionRaw >> 22) & 0x3FF}.{(driverVersionRaw >> 14) & 0xFF}.{(driverVersionRaw >> 6) & 0xFF}.{driverVersionRaw & 0x3F}";
|
||||||
|
|
Loading…
Reference in a new issue