From e630d4fb709b39152a6ba0bf385258b563afd1d2 Mon Sep 17 00:00:00 2001 From: "duncan.hopkins" Date: Wed, 27 Nov 2024 12:18:59 +0000 Subject: [PATCH] zink: MoltenVk has conditional VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE support. MoltenVK support for VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE depends on the Metal API version in use. Which is directly related to the MacOS version. Even if all the correct extensions or Vk versions are supported. Detect if the feature is supported, assume it is not on MacOS unless told otherwise, and adjust the pipelines to honor this. Part-of: --- src/gallium/drivers/zink/zink_context.c | 3 +++ src/gallium/drivers/zink/zink_program_state.hpp | 3 +++ src/gallium/drivers/zink/zink_screen.c | 16 ++++++++++++++++ src/gallium/drivers/zink/zink_types.h | 1 + 4 files changed, 23 insertions(+) diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index 77a13b9b734..1b656f69bce 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -5272,6 +5272,9 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags) ctx->gfx_pipeline_state.dyn_state2.vertices_per_patch = 1; ctx->gfx_pipeline_state.uses_dynamic_stride = screen->info.have_EXT_extended_dynamic_state || screen->info.have_EXT_vertex_input_dynamic_state; +#if defined(MVK_VERSION) + ctx->gfx_pipeline_state.uses_dynamic_stride = ctx->gfx_pipeline_state.uses_dynamic_stride && screen->have_dynamic_state_vertex_input_binding_stride; +#endif ctx->compute_pipeline_state.dirty = true; ctx->fb_changed = ctx->rp_changed = true; ctx->sample_mask_changed = true; diff --git a/src/gallium/drivers/zink/zink_program_state.hpp b/src/gallium/drivers/zink/zink_program_state.hpp index 3489cd72958..55d66916fec 100644 --- a/src/gallium/drivers/zink/zink_program_state.hpp +++ b/src/gallium/drivers/zink/zink_program_state.hpp @@ -139,6 +139,9 @@ zink_get_gfx_pipeline(struct zink_context *ctx, state->final_hash ^= state->vertex_hash; /* even if dynamic stride is available, it may not be usable with the current pipeline */ if (DYNAMIC_STATE != ZINK_NO_DYNAMIC_STATE) +#if defined(MVK_VERSION) + if (screen->have_dynamic_state_vertex_input_binding_stride) +#endif uses_dynamic_stride = check_vertex_strides(ctx); if (!uses_dynamic_stride) { uint32_t hash = 0; diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c index 9d1a0c3f71a..7f7f8aaca00 100644 --- a/src/gallium/drivers/zink/zink_screen.c +++ b/src/gallium/drivers/zink/zink_screen.c @@ -2106,12 +2106,17 @@ static bool zink_internal_setup_moltenvk(struct zink_screen *screen) { #if defined(MVK_VERSION) + // MoltenVK only supports VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE in newer Metal versions + // disable unless we can get MoltenVK to confirm it is supported + screen->have_dynamic_state_vertex_input_binding_stride = false; + if (!screen->instance_info.have_MVK_moltenvk) return true; GET_PROC_ADDR_INSTANCE_LOCAL(screen, screen->instance, GetMoltenVKConfigurationMVK); GET_PROC_ADDR_INSTANCE_LOCAL(screen, screen->instance, SetMoltenVKConfigurationMVK); GET_PROC_ADDR_INSTANCE_LOCAL(screen, screen->instance, GetVersionStringsMVK); + GET_PROC_ADDR_INSTANCE_LOCAL(screen, screen->instance, GetPhysicalDeviceMetalFeaturesMVK); if (vk_GetVersionStringsMVK) { char molten_version[64] = {0}; @@ -2134,6 +2139,16 @@ zink_internal_setup_moltenvk(struct zink_screen *screen) vk_SetMoltenVKConfigurationMVK(screen->instance, &molten_config, &molten_config_size); } } + + if (vk_GetPhysicalDeviceMetalFeaturesMVK) { + MVKPhysicalDeviceMetalFeatures metal_features={0}; + size_t metal_features_size = sizeof(metal_features); + + VkResult res = vk_GetPhysicalDeviceMetalFeaturesMVK(screen->pdev, &metal_features, &metal_features_size); + if (res == VK_SUCCESS) { + screen->have_dynamic_state_vertex_input_binding_stride = metal_features.dynamicVertexStride; + } + } #endif // MVK_VERSION return true; @@ -3397,6 +3412,7 @@ zink_internal_create_screen(const struct pipe_screen_config *config, int64_t dev VK_FORMAT_D24_UNORM_S8_UINT); screen->have_D32_SFLOAT_S8_UINT = zink_is_depth_format_supported(screen, VK_FORMAT_D32_SFLOAT_S8_UINT); + screen->have_dynamic_state_vertex_input_binding_stride = true; if (!zink_get_physical_device_info(screen)) { if (!screen->driver_name_is_inferred) diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h index e86a60a1e2b..9853a5b9df7 100644 --- a/src/gallium/drivers/zink/zink_types.h +++ b/src/gallium/drivers/zink/zink_types.h @@ -1480,6 +1480,7 @@ struct zink_screen { bool have_D24_UNORM_S8_UINT; bool have_D32_SFLOAT_S8_UINT; bool have_triangle_fans; + bool have_dynamic_state_vertex_input_binding_stride; bool need_decompose_attrs; bool need_2D_zs; bool need_2D_sparse;