mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-13 14:48:32 +09:00
[Fix] (MG_Backend/DirectVulkan): fix Voxy subgroup and indirect draw sync
- Implement Vulkan subgroup capability querying and expose KHR subgroup getter values. - Fix DirectVulkan memory barriers so GL_COMMAND_BARRIER_BIT makes generated indirect draw commands visible. - Keep Voxy on the DirectVulkan gpu_shader_int64 quad decode path while filtering unsupported optional int64 usage on backends that do not advertise it. - Add MG_Test coverage for subgroup getters, Voxy subgroup/int64 shader probes, command barrier mapping, and indirect draw command layout. - Check for whether driver supports shader subgroup operation, disable on demand, and provide env var `MOBILEGL_DISABLE_SUBGROUP` to explicitly disable subgroup features
This commit is contained in:
@@ -8,6 +8,9 @@
|
||||
|
||||
#include "Loader.h"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
namespace MobileGL::MG_Util::BackendLoader {
|
||||
namespace {
|
||||
struct VulkanDynamicFunctions {
|
||||
@@ -33,6 +36,14 @@ namespace MobileGL::MG_Util::BackendLoader {
|
||||
|
||||
return loaded;
|
||||
}
|
||||
|
||||
Bool IsShaderSubgroupForcedDisabled() {
|
||||
const char* value = std::getenv("MOBILEGL_DISABLE_SUBGROUP");
|
||||
if (!value) {
|
||||
return false;
|
||||
}
|
||||
return std::strcmp(value, "true") == 0 || std::strcmp(value, "TRUE") == 0;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
inline Version DecodeApiVersion(uint32_t version) {
|
||||
@@ -46,6 +57,12 @@ namespace MobileGL::MG_Util::BackendLoader {
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
inline Bool HasUsableShaderSubgroupSupport(const VkPhysicalDeviceSubgroupProperties& subgroupProps) {
|
||||
return subgroupProps.subgroupSize > 0 &&
|
||||
(subgroupProps.supportedStages & VK_SHADER_STAGE_COMPUTE_BIT) != 0 &&
|
||||
(subgroupProps.supportedOperations & VK_SUBGROUP_FEATURE_BASIC_BIT) != 0;
|
||||
}
|
||||
|
||||
Bool QueryVulkanCapabilities(MobileGL::MG_External::VulkanCapabilities& caps, VkInstance instance,
|
||||
VkPhysicalDevice physicalDevice) {
|
||||
if (!physicalDevice) {
|
||||
@@ -69,8 +86,12 @@ namespace MobileGL::MG_Util::BackendLoader {
|
||||
return false;
|
||||
}
|
||||
|
||||
VkPhysicalDeviceSubgroupProperties subgroupProps{};
|
||||
subgroupProps.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES;
|
||||
|
||||
VkPhysicalDeviceProperties2 props2{};
|
||||
props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
|
||||
props2.pNext = &subgroupProps;
|
||||
if (vk.vkGetPhysicalDeviceProperties2) {
|
||||
vk.vkGetPhysicalDeviceProperties2(physicalDevice, &props2);
|
||||
} else {
|
||||
@@ -84,6 +105,28 @@ namespace MobileGL::MG_Util::BackendLoader {
|
||||
caps.DriverVersionString = DecodeDriverVersion(p.driverVersion);
|
||||
caps.UniformBufferOffsetAlignment = static_cast<int>(p.limits.minUniformBufferOffsetAlignment);
|
||||
caps.MaxShaderStorageBlockSize = static_cast<SizeT>(p.limits.maxStorageBufferRange);
|
||||
const Bool supportsShaderSubgroup = vk.vkGetPhysicalDeviceProperties2 &&
|
||||
HasUsableShaderSubgroupSupport(subgroupProps);
|
||||
const Bool forceDisableShaderSubgroup = IsShaderSubgroupForcedDisabled();
|
||||
caps.SupportsShaderSubgroup = supportsShaderSubgroup && !forceDisableShaderSubgroup;
|
||||
if (caps.SupportsShaderSubgroup) {
|
||||
caps.SubgroupSize = subgroupProps.subgroupSize;
|
||||
caps.SubgroupSupportedStages = subgroupProps.supportedStages;
|
||||
caps.SubgroupSupportedOperations = subgroupProps.supportedOperations;
|
||||
caps.SubgroupQuadOperationsInAllStages = subgroupProps.quadOperationsInAllStages == VK_TRUE;
|
||||
} else {
|
||||
caps.SubgroupSize = 0;
|
||||
caps.SubgroupSupportedStages = 0;
|
||||
caps.SubgroupSupportedOperations = 0;
|
||||
caps.SubgroupQuadOperationsInAllStages = false;
|
||||
}
|
||||
|
||||
MGLOG_I("Vulkan shader subgroup support: detected=%s advertised=%s size=%u stages=0x%x operations=0x%x",
|
||||
supportsShaderSubgroup ? "true" : "false", caps.SupportsShaderSubgroup ? "true" : "false",
|
||||
subgroupProps.subgroupSize, subgroupProps.supportedStages, subgroupProps.supportedOperations);
|
||||
if (supportsShaderSubgroup && forceDisableShaderSubgroup) {
|
||||
MGLOG_W("Vulkan shader subgroup support forced off by MOBILEGL_DISABLE_SUBGROUP");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -95,5 +138,10 @@ namespace MobileGL::MG_Util::BackendLoader {
|
||||
caps.DriverVersionString = DecodeDriverVersion(properties.driverVersion);
|
||||
caps.UniformBufferOffsetAlignment = static_cast<int>(properties.limits.minUniformBufferOffsetAlignment);
|
||||
caps.MaxShaderStorageBlockSize = static_cast<SizeT>(properties.limits.maxStorageBufferRange);
|
||||
caps.SupportsShaderSubgroup = false;
|
||||
caps.SubgroupSize = 0;
|
||||
caps.SubgroupSupportedStages = 0;
|
||||
caps.SubgroupSupportedOperations = 0;
|
||||
caps.SubgroupQuadOperationsInAllStages = false;
|
||||
}
|
||||
} // namespace MobileGL::MG_Util::BackendLoader
|
||||
|
||||
Reference in New Issue
Block a user