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;