From 1edc85c26ef57530ac18b9a6aab3375d8e87a10e Mon Sep 17 00:00:00 2001 From: gdk Date: Sun, 10 Apr 2022 18:05:36 -0300 Subject: [PATCH] Check if the subgroup size is supported before passing a explicit size --- .../HardwareCapabilities.cs | 15 +++++++-- Ryujinx.Graphics.Vulkan/PipelineState.cs | 17 +++++++--- .../VulkanGraphicsDevice.cs | 32 +++++++++++++++---- 3 files changed, 51 insertions(+), 13 deletions(-) diff --git a/Ryujinx.Graphics.Vulkan/HardwareCapabilities.cs b/Ryujinx.Graphics.Vulkan/HardwareCapabilities.cs index d387ee024..b61744495 100644 --- a/Ryujinx.Graphics.Vulkan/HardwareCapabilities.cs +++ b/Ryujinx.Graphics.Vulkan/HardwareCapabilities.cs @@ -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; } } } diff --git a/Ryujinx.Graphics.Vulkan/PipelineState.cs b/Ryujinx.Graphics.Vulkan/PipelineState.cs index d9c2e8c99..affa13dda 100644 --- a/Ryujinx.Graphics.Vulkan/PipelineState.cs +++ b/Ryujinx.Graphics.Vulkan/PipelineState.cs @@ -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; } } diff --git a/Ryujinx.Graphics.Vulkan/VulkanGraphicsDevice.cs b/Ryujinx.Graphics.Vulkan/VulkanGraphicsDevice.cs index c0bfd654d..8c0834006 100644 --- a/Ryujinx.Graphics.Vulkan/VulkanGraphicsDevice.cs +++ b/Ryujinx.Graphics.Vulkan/VulkanGraphicsDevice.cs @@ -94,7 +94,7 @@ namespace Ryujinx.Graphics.Vulkan Samplers = new HashSet(); } - 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);