From ea5e15cde56d524b142eddac2a178dfefc8b9e59 Mon Sep 17 00:00:00 2001 From: PavelBARABANOV Date: Tue, 18 Nov 2025 22:30:43 +0300 Subject: [PATCH] [vk, pipeline_cache, qcom] Resolving pipeline usage for QCOM --- .../renderer_vulkan/vk_pipeline_cache.cpp | 23 ++++++++++++++++++- src/video_core/vulkan_common/vulkan_device.h | 6 +++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 14a4fee69b..f9b04b3b12 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -677,7 +677,17 @@ std::unique_ptr PipelineCache::CreateGraphicsPipeline( const auto runtime_info{MakeRuntimeInfo(programs, key, program, previous_stage)}; ConvertLegacyToGeneric(program, runtime_info); - const std::vector code{EmitSPIRV(profile, runtime_info, program, binding, this->optimize_spirv_output)}; + + // Adreno don't support subgroup operations in vertex stages + // Disable subgroup features for vertex shaders if not supported by the device + Shader::Profile stage_profile = profile; + if (program.stage == Shader::Stage::VertexA || program.stage == Shader::Stage::VertexB) { + if (!device.IsSubgroupSupportedForStage(VK_SHADER_STAGE_VERTEX_BIT)) { + stage_profile.support_vote = false; + } + } + + const std::vector code{EmitSPIRV(stage_profile, runtime_info, program, binding, this->optimize_spirv_output)}; device.SaveShader(code); modules[stage_index] = BuildShader(device, code); if (device.HasDebuggingToolAttached()) { @@ -771,6 +781,17 @@ std::unique_ptr PipelineCache::CreateComputePipeline( } auto program{TranslateProgram(pools.inst, pools.block, env, cfg, host_info)}; + + // Adreno have lower shared memory limits (32KB) + // Clamp shared memory usage to device maximum to avoid validation errors + const u32 max_shared_memory = device.GetMaxComputeSharedMemorySize(); + if (program.shared_memory_size > max_shared_memory) { + LOG_WARNING(Render_Vulkan, + "Compute shader 0x{:016x} requests {}KB shared memory but device max is {}KB - clamping", + key.unique_hash, program.shared_memory_size / 1024, max_shared_memory / 1024); + program.shared_memory_size = max_shared_memory; + } + const std::vector code{EmitSPIRV(profile, program, this->optimize_spirv_output)}; device.SaveShader(code); vk::ShaderModule spv_module{BuildShader(device, code)}; diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index cb13f28523..e649147264 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h @@ -365,6 +365,12 @@ public: return properties.subgroup_properties.supportedOperations & feature; } + /// Returns true if subgroup operations are supported in the specified shader stage. + /// Mobile GPUs (Qualcomm Adreno) often only support subgroups in fragment/compute stages. + bool IsSubgroupSupportedForStage(VkShaderStageFlagBits stage) const { + return properties.subgroup_properties.supportedStages & stage; + } + /// Returns the maximum number of push descriptors. u32 MaxPushDescriptors() const { return properties.push_descriptor.maxPushDescriptors;