From eaabd2ffd7abcdeddef000cdf08cf1589dd23f8d Mon Sep 17 00:00:00 2001 From: Giovanni Mascellani Date: Mon, 20 Oct 2025 22:57:40 +0200 Subject: [PATCH] vkd3d-shader/msl: Allow binding to descriptor arrays. This requires merging adjacent bindings in the Metal shader runner, mostly like 805a4bc1e8dbce695b0b59950aef8cb4443303ee did for the d3d12 backend. --- libs/vkd3d-shader/msl.c | 12 ++++++++++-- tests/shader_runner_metal.m | 23 ++++++++++++++++++----- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/libs/vkd3d-shader/msl.c b/libs/vkd3d-shader/msl.c index c974c9e53..fc8d7ba6f 100644 --- a/libs/vkd3d-shader/msl.c +++ b/libs/vkd3d-shader/msl.c @@ -226,14 +226,22 @@ static bool msl_get_binding(const struct msl_generator *gen, const struct vkd3d_ continue; if (binding->register_space != descriptor->register_space) continue; - if (binding->register_index != register_idx) + if (binding->register_index > descriptor->register_index) + continue; + if (descriptor->count != ~0u && binding->binding.count < descriptor->count) + continue; + if (descriptor->count != ~0u + && binding->binding.count - descriptor->count < descriptor->register_index - binding->register_index) + continue; + if (descriptor->count == ~0u + && binding->binding.count <= descriptor->register_index - binding->register_index) continue; if (!msl_check_shader_visibility(gen, binding->shader_visibility)) continue; if ((binding->flags & flags) != flags) continue; - *idx = binding->binding.binding; + *idx = register_idx + binding->binding.binding - binding->register_index; return true; } diff --git a/tests/shader_runner_metal.m b/tests/shader_runner_metal.m index 6241161b0..23e19638f 100644 --- a/tests/shader_runner_metal.m +++ b/tests/shader_runner_metal.m @@ -387,8 +387,8 @@ static bool compile_shader(struct metal_runner *runner, enum shader_type type, s struct vkd3d_shader_interface_info interface_info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_INTERFACE_INFO}; struct vkd3d_shader_compile_info info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO}; struct vkd3d_shader_resource_binding bindings[MAX_RESOURCES + MAX_SAMPLERS + 1 /* CBV */]; - struct vkd3d_shader_resource_binding *binding; - unsigned int i; + struct vkd3d_shader_resource_binding *binding, *base_binding = NULL; + unsigned int i, binding_idx = 0; char *messages; int ret; @@ -422,9 +422,10 @@ static bool compile_shader(struct metal_runner *runner, enum shader_type type, s binding->shader_visibility = VKD3D_SHADER_VISIBILITY_ALL; binding->flags = VKD3D_SHADER_BINDING_FLAG_BUFFER; binding->binding.set = 0; - binding->binding.binding = interface_info.binding_count; + binding->binding.binding = binding_idx; binding->binding.count = 1; ++interface_info.binding_count; + ++binding_idx; } for (i = 0; i < runner->r.resource_count; ++i) @@ -448,9 +449,20 @@ static bool compile_shader(struct metal_runner *runner, enum shader_type type, s else binding->flags = VKD3D_SHADER_BINDING_FLAG_IMAGE; binding->binding.set = 0; - binding->binding.binding = interface_info.binding_count; + binding->binding.binding = binding_idx; binding->binding.count = 1; + + if (base_binding && base_binding->type == binding->type && base_binding->flags == binding->flags + && base_binding->register_index + base_binding->binding.count == resource->r.desc.slot) + { + ++base_binding->binding.count; + ++binding_idx; + break; + } + + base_binding = binding; ++interface_info.binding_count; + ++binding_idx; break; case RESOURCE_TYPE_RENDER_TARGET: @@ -470,9 +482,10 @@ static bool compile_shader(struct metal_runner *runner, enum shader_type type, s binding->shader_visibility = VKD3D_SHADER_VISIBILITY_ALL; binding->flags = 0; binding->binding.set = 0; - binding->binding.binding = interface_info.binding_count; + binding->binding.binding = binding_idx; binding->binding.count = 1; ++interface_info.binding_count; + ++binding_idx; } interface_info.bindings = bindings;