Browse Source

[vk, qcom] Remove VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE for QCOM drivers

pull/3062/head
CamilleLaVey 1 month ago
committed by lizzie
parent
commit
37c38cb0c7
  1. 16
      src/video_core/renderer_vulkan/vk_buffer_cache.cpp
  2. 3
      src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
  3. 35
      src/video_core/vulkan_common/vulkan_device.cpp
  4. 7
      src/video_core/vulkan_common/vulkan_device.h

16
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<Buffer>& 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) {

3
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);
}
}

35
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) {

7
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.

Loading…
Cancel
Save