From 37c38cb0c7ef669ecad2c8df465acf3836814898 Mon Sep 17 00:00:00 2001 From: CamilleLaVey Date: Wed, 19 Nov 2025 18:26:21 -0400 Subject: [PATCH] [vk, qcom] Remove VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE for QCOM drivers --- .../renderer_vulkan/vk_buffer_cache.cpp | 16 +++++++-- .../renderer_vulkan/vk_graphics_pipeline.cpp | 3 +- .../vulkan_common/vulkan_device.cpp | 35 ++++++++----------- src/video_core/vulkan_common/vulkan_device.h | 7 ++++ 4 files changed, 38 insertions(+), 23 deletions(-) diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp index 00f2decba4..2d427d50fb 100644 --- a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp @@ -584,7 +584,13 @@ void BufferCacheRuntime::BindVertexBuffer(u32 index, VkBuffer buffer, u32 offset if (index >= device.GetMaxVertexInputBindings()) { return; } - if (device.IsExtExtendedDynamicStateSupported()) { + // Use EDS1 BindVertexBuffers2EXT (with stride) unless: + // 1. EDS1 not supported, OR + // 2. Qualcomm Adreno < 762.24 (broken VERTEX_INPUT_BINDING_STRIDE) + const bool use_eds1 = device.IsExtExtendedDynamicStateSupported() && + !device.HasBrokenVertexInputStride(); + + if (use_eds1) { scheduler.Record([index, buffer, offset, size, stride](vk::CommandBuffer cmdbuf) { const VkDeviceSize vk_offset = buffer != VK_NULL_HANDLE ? offset : 0; const VkDeviceSize vk_size = buffer != VK_NULL_HANDLE ? size : VK_WHOLE_SIZE; @@ -624,7 +630,13 @@ void BufferCacheRuntime::BindVertexBuffers(VideoCommon::HostBindings& bi if (binding_count == 0) { return; } - if (device.IsExtExtendedDynamicStateSupported()) { + // Use EDS1 BindVertexBuffers2EXT (with stride) unless: + // 1. EDS1 not supported, OR + // 2. Qualcomm Adreno < 762.24 (broken VERTEX_INPUT_BINDING_STRIDE) + const bool use_eds1 = device.IsExtExtendedDynamicStateSupported() && + !device.HasBrokenVertexInputStride(); + + if (use_eds1) { scheduler.Record([bindings_ = std::move(bindings), buffer_handles_ = std::move(buffer_handles), binding_count](vk::CommandBuffer cmdbuf) { diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 8d7b4a0c6b..4b4e681d07 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -884,7 +884,8 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { // Note: VERTEX_INPUT_BINDING_STRIDE is part of EDS1, not VIDS // When VIDS is disabled, we still need dynamic stride with BindVertexBuffers2EXT - if (!key.state.dynamic_vertex_input) { + // Skip on Qualcomm Adreno < 762.24 (broken implementation) + if (!key.state.dynamic_vertex_input && !device.HasBrokenVertexInputStride()) { dynamic_states.push_back(VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT); } } diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 5e19d6ec1b..c13b58d1fb 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -1257,6 +1257,21 @@ bool Device::GetSuitability(bool requires_swapchain) { } } + // Qualcomm Adreno < 762.24: Broken VERTEX_INPUT_BINDING_STRIDE + // EDS1 works fine for other states, but vkCmdBindVertexBuffers2EXT triggers validation errors: + // "VkPipeline doesn't set up VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE" + // Tested working: 676.0 (with VIDS), 762.24, 819.2 + // Solution: Keep EDS1 enabled, but use legacy BindVertexBuffers path + if (extensions.extended_dynamic_state && is_qualcomm) { + const u32 version = (properties.properties.driverVersion << 3) >> 3; + if (version <= VK_MAKE_API_VERSION(0, 0, 762, 24)) { + LOG_WARNING(Render_Vulkan, + "Qualcomm Adreno ≤ 762.24: VERTEX_INPUT_BINDING_STRIDE broken, " + "using legacy vertex buffer binding"); + has_broken_vertex_input_stride = true; + } + } + // VK_EXT_extended_dynamic_state2 // RADV < 22.3.1: Broken ExtendedDynamicState2 implementation @@ -1270,18 +1285,6 @@ bool Device::GetSuitability(bool requires_swapchain) { } } - // Qualcomm Adreno 7xx (drivers 676.0 - 679.x): Broken ExtendedDynamicState2 - // Disable ExtendedDynamicState2 on affected driver versions - if (extensions.extended_dynamic_state2 && is_qualcomm) { - const u32 version = (properties.properties.driverVersion << 3) >> 3; - if (version >= VK_MAKE_API_VERSION(0, 0, 676, 0) && - version < VK_MAKE_API_VERSION(0, 0, 680, 0)) { - LOG_WARNING(Render_Vulkan, - "Qualcomm Adreno 7xx (676-679): Disabling broken VK_EXT_extended_dynamic_state2"); - features.extended_dynamic_state2.extendedDynamicState2 = false; - } - } - // VK_EXT_extended_dynamic_state3 // AMD/Samsung: Broken extendedDynamicState3ColorBlendEquation @@ -1323,14 +1326,6 @@ bool Device::GetSuitability(bool requires_swapchain) { } } - // Qualcomm: Broken VertexInputDynamicState implementation - // Disable VertexInputDynamicState on all Qualcomm drivers - if (extensions.vertex_input_dynamic_state && is_qualcomm) { - LOG_WARNING(Render_Vulkan, - "Qualcomm: Disabling broken VK_EXT_vertex_input_dynamic_state"); - features.vertex_input_dynamic_state.vertexInputDynamicState = false; - } - // Intel Windows < 27.20.100.0: Broken VertexInputDynamicState // Disable VertexInputDynamicState on old Intel Windows drivers if (extensions.vertex_input_dynamic_state && is_intel_windows) { diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index 03b063befc..22092a4659 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h @@ -825,6 +825,12 @@ public: return has_broken_parallel_compiling; } + /// Returns true when VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE is broken. + /// Qualcomm Adreno drivers < 762.24 have broken BindVertexBuffers2EXT validation. + bool HasBrokenVertexInputStride() const { + return has_broken_vertex_input_stride; + } + /// Returns the vendor name reported from Vulkan. std::string_view GetVendorName() const { return properties.driver.driverName; @@ -1031,6 +1037,7 @@ private: bool has_broken_compute{}; ///< Compute shaders can cause crashes bool has_broken_cube_compatibility{}; ///< Has broken cube compatibility bit bool has_broken_parallel_compiling{}; ///< Has broken parallel shader compiling. + bool has_broken_vertex_input_stride{}; ///< VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE broken bool has_renderdoc{}; ///< Has RenderDoc attached bool has_nsight_graphics{}; ///< Has Nsight Graphics attached bool has_radeon_gpu_profiler{}; ///< Has Radeon GPU Profiler attached.