From 4cd3d1917b52bb1befd077661a739ff35f19b7db Mon Sep 17 00:00:00 2001 From: Andy Hovingh <6198728+AndyHovingh@users.noreply.github.com> Date: Fri, 2 May 2025 14:09:00 -0500 Subject: [PATCH] webgpu: do not include constants that are absent in the WGSL --- filament/backend/src/webgpu/WGPUProgram.cpp | 67 +++++++++++++-------- 1 file changed, 41 insertions(+), 26 deletions(-) diff --git a/filament/backend/src/webgpu/WGPUProgram.cpp b/filament/backend/src/webgpu/WGPUProgram.cpp index 5a62874557..6828ad123b 100644 --- a/filament/backend/src/webgpu/WGPUProgram.cpp +++ b/filament/backend/src/webgpu/WGPUProgram.cpp @@ -27,6 +27,7 @@ #include +#include #include #include #include @@ -125,50 +126,64 @@ namespace { return module; } -wgpu::StringView getSpecConstantStringValue(uint32_t value) { - switch (value) { +// This is a 1 to 1 mapping of the ReservedSpecializationConstants enum in EngineEnums.h +// The _hack is a workaround until https://issues.chromium.org/issues/42250586 is resolved +// This workaround is the same one being used on the generateSpecializationConstant() function +wgpu::StringView getSpecConstantStringId(uint32_t id) { + switch (id) { case 0: - return "BACKEND_FEATURE_LEVEL_hack"; + return "0";// BACKEND_FEATURE_LEVEL_hack case 1: - return "CONFIG_MAX_INSTANCES_hack"; + return "1";// CONFIG_MAX_INSTANCES_hack case 2: - return "CONFIG_STATIC_TEXTURE_TARGET_WORKAROUND_hack"; + return "2";// ONFIG_STATIC_TEXTURE_TARGET_WORKAROUND_hack case 3: - return "CONFIG_SRGB_SWAPCHAIN_EMULATION_hack"; + return "3";// CONFIG_SRGB_SWAPCHAIN_EMULATION_hack case 4: - return "CONFIG_FROXEL_BUFFER_HEIGHT_hack"; + return "4";// CONFIG_FROXEL_BUFFER_HEIGHT_hack case 5: - return "CONFIG_POWER_VR_SHADER_WORKAROUNDS_hack"; + return "5";// CONFIG_POWER_VR_SHADER_WORKAROUNDS_hack case 6: - return "CONFIG_DEBUG_DIRECTIONAL_SHADOWMAP_hack"; + return "6";// CONFIG_DEBUG_DIRECTIONAL_SHADOWMAP_hack case 7: - return "CONFIG_DEBUG_FROXEL_VISUALIZATION_hack"; + return "7";// CONFIG_DEBUG_FROXEL_VISUALIZATION_hack case 8: - return "CONFIG_STEREO_EYE_COUNT_hack"; + return "8";// CONFIG_STEREO_EYE_COUNT_hack case 9: - return "CONFIG_SH_BANDS_COUNT_hack"; + return "9";// CONFIG_SH_BANDS_COUNT_hack case 10: - return "CONFIG_SHADOW_SAMPLING_METHOD_hack"; + return "10";// CONFIG_SHADOW_SAMPLING_METHOD_hack + default: + PANIC_POSTCONDITION("Unknown/unhandled spec constant key/id: %d", id); } - return ""; } std::vector convertConstants( utils::FixedCapacityVector const& constantsInfo) { - std::vector constants(constantsInfo.size()); - return constants; - for (size_t i = 0; i < constantsInfo.size(); i++) { - filament::backend::Program::SpecializationConstant const& specConstant = constantsInfo[i]; - wgpu::ConstantEntry& constantEntry = constants[i]; - constantEntry.key = getSpecConstantStringValue(specConstant.id); - if (auto* v = std::get_if(&specConstant.value)) { - constantEntry.value = static_cast(*v); - } else if (auto* f = std::get_if(&specConstant.value)) { - constantEntry.value = static_cast(*f); - } else if (auto* b = std::get_if(&specConstant.value)) { - constantEntry.value = *b ? 0.0 : 1.0; + std::vector constants; + constants.reserve(constantsInfo.size()); + for (filament::backend::Program::SpecializationConstant const& constant: constantsInfo) { + // CONFIG_MAX_INSTANCES (1) and CONFIG_FROXEL_BUFFER_HEIGHT (4) will not be present + // as constant overrides in the generated WGSL, because WGSL doesn't support specialization + // constants as an array length + // More information at https://github.com/gpuweb/gpuweb/issues/572#issuecomment-649760005 + // CONFIG_SRGB_SWAPCHAIN_EMULATION (3) is being skipped all together since it's only + // included for the case of mFeatureLevel == FeatureLevel::FEATURE_LEVEL_0, which should + // not be possible for WebGPU + if (constant.id == 1 || constant.id == 3 || constant.id == 4) { + continue; } + double value = 0.0; + if (auto* v = std::get_if(&constant.value)) { + value = static_cast(*v); + } else if (auto* f = std::get_if(&constant.value)) { + value = static_cast(*f); + } else if (auto* b = std::get_if(&constant.value)) { + value = *b ? 0.0 : 1.0; + } + constants.push_back( + wgpu::ConstantEntry{ .key = getSpecConstantStringId(constant.id), .value = value }); } return constants; }