Check if the subgroup size is supported before passing a explicit size

This commit is contained in:
gdk 2022-04-10 18:05:36 -03:00 committed by riperiperi
parent 4f086b0ec9
commit 1edc85c26e
3 changed files with 51 additions and 13 deletions

View file

@ -1,16 +1,27 @@
namespace Ryujinx.Graphics.Vulkan
using Silk.NET.Vulkan;
namespace Ryujinx.Graphics.Vulkan
{
struct HardwareCapabilities
{
public bool SupportsConditionalRendering { get; }
public bool SupportsExtendedDynamicState { get; }
public uint MinSubgroupSize { get; }
public uint MaxSubgroupSize { get; }
public ShaderStageFlags RequiredSubgroupSizeStages { get; }
public HardwareCapabilities(
bool supportsConditionalRendering,
bool supportsExtendedDynamicState)
bool supportsExtendedDynamicState,
uint minSubgroupSize,
uint maxSubgroupSize,
ShaderStageFlags requiredSubgroupSizeStages)
{
SupportsConditionalRendering = supportsConditionalRendering;
SupportsExtendedDynamicState = supportsExtendedDynamicState;
MinSubgroupSize = minSubgroupSize;
MaxSubgroupSize = maxSubgroupSize;
RequiredSubgroupSizeStages = requiredSubgroupSizeStages;
}
}
}

View file

@ -5,6 +5,8 @@ namespace Ryujinx.Graphics.Vulkan
{
struct PipelineState : IDisposable
{
private const int RequiredSubgroupSize = 32;
public PipelineUid Internal;
public float LineWidth
@ -309,7 +311,7 @@ namespace Ryujinx.Graphics.Vulkan
StageRequiredSubgroupSizes[index] = new PipelineShaderStageRequiredSubgroupSizeCreateInfoEXT()
{
SType = StructureType.PipelineShaderStageRequiredSubgroupSizeCreateInfoExt,
RequiredSubgroupSize = 32
RequiredSubgroupSize = RequiredSubgroupSize
};
}
}
@ -327,7 +329,7 @@ namespace Ryujinx.Graphics.Vulkan
if (gd.SupportsSubgroupSizeControl)
{
UpdateStageRequiredSubgroupSizes(1);
UpdateStageRequiredSubgroupSizes(gd, 1);
}
var pipelineCreateInfo = new ComputePipelineCreateInfo()
@ -516,7 +518,7 @@ namespace Ryujinx.Graphics.Vulkan
if (gd.SupportsSubgroupSizeControl)
{
UpdateStageRequiredSubgroupSizes((int)StagesCount);
UpdateStageRequiredSubgroupSizes(gd, (int)StagesCount);
}
var pipelineCreateInfo = new GraphicsPipelineCreateInfo()
@ -548,11 +550,16 @@ namespace Ryujinx.Graphics.Vulkan
return pipeline;
}
private unsafe void UpdateStageRequiredSubgroupSizes(int count)
private unsafe void UpdateStageRequiredSubgroupSizes(VulkanGraphicsDevice gd, int count)
{
for (int index = 0; index < count; index++)
{
Stages[index].PNext = StageRequiredSubgroupSizes.Pointer + index;
bool canUseExplicitSubgroupSize =
(gd.Capabilities.RequiredSubgroupSizeStages & Stages[index].Stage) != 0 &&
gd.Capabilities.MinSubgroupSize <= RequiredSubgroupSize &&
gd.Capabilities.MaxSubgroupSize >= RequiredSubgroupSize;
Stages[index].PNext = canUseExplicitSubgroupSize ? StageRequiredSubgroupSizes.Pointer + index : null;
}
}

View file

@ -94,7 +94,7 @@ namespace Ryujinx.Graphics.Vulkan
Samplers = new HashSet<SamplerHolder>();
}
private void SetupContext(GraphicsDebugLevel logLevel)
private unsafe void SetupContext(GraphicsDebugLevel logLevel)
{
var api = Vk.GetApi();
@ -119,10 +119,6 @@ namespace Ryujinx.Graphics.Vulkan
_device = VulkanInitialization.CreateDevice(api, _physicalDevice, queueFamilyIndex, supportedExtensions, maxQueueCount);
Capabilities = new HardwareCapabilities(
supportedExtensions.Contains(ExtConditionalRendering.ExtensionName),
supportedExtensions.Contains(ExtExtendedDynamicState.ExtensionName));
SupportsIndexTypeUint8 = supportedExtensions.Contains("VK_EXT_index_type_uint8");
SupportsCustomBorderColor = supportedExtensions.Contains("VK_EXT_custom_border_color");
SupportsIndirectParameters = supportedExtensions.Contains(KhrDrawIndirectCount.ExtensionName);
@ -165,7 +161,31 @@ namespace Ryujinx.Graphics.Vulkan
BackgroundQueueLock = new object();
}
Api.GetPhysicalDeviceProperties(_physicalDevice, out var properties);
PhysicalDeviceProperties2 properties2 = new PhysicalDeviceProperties2()
{
SType = StructureType.PhysicalDeviceProperties2
};
PhysicalDeviceSubgroupSizeControlPropertiesEXT propertiesSubgroupSizeControl = new PhysicalDeviceSubgroupSizeControlPropertiesEXT()
{
SType = StructureType.PhysicalDeviceSubgroupSizeControlPropertiesExt
};
if (SupportsSubgroupSizeControl)
{
properties2.PNext = &propertiesSubgroupSizeControl;
}
Api.GetPhysicalDeviceProperties2(_physicalDevice, &properties2);
Capabilities = new HardwareCapabilities(
supportedExtensions.Contains(ExtConditionalRendering.ExtensionName),
supportedExtensions.Contains(ExtExtendedDynamicState.ExtensionName),
propertiesSubgroupSizeControl.MinSubgroupSize,
propertiesSubgroupSizeControl.MaxSubgroupSize,
propertiesSubgroupSizeControl.RequiredSubgroupSizeStages);
ref var properties = ref properties2.Properties;
MemoryAllocator = new MemoryAllocator(api, _device, properties.Limits.MaxMemoryAllocationCount);