From 76fd1388d87e5600c1c55cd7ebf6959c78e118f7 Mon Sep 17 00:00:00 2001 From: Conor McCarthy Date: Fri, 25 Oct 2024 13:23:43 +1000 Subject: [PATCH] vkd3d: Check the IASetVertexBuffers() view count against the device limits. For example, current MoltenVK only supports 31 vertex buffers. --- libs/vkd3d/command.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c index ed4cc370..a55a97f6 100644 --- a/libs/vkd3d/command.c +++ b/libs/vkd3d/command.c @@ -4804,15 +4804,16 @@ static void STDMETHODCALLTYPE d3d12_command_list_IASetVertexBuffers(ID3D12Graphi VkDeviceSize offsets[ARRAY_SIZE(list->strides)]; const struct vkd3d_vk_device_procs *vk_procs; VkBuffer buffers[ARRAY_SIZE(list->strides)]; + struct d3d12_device *device = list->device; + unsigned int i, stride, max_view_count; struct d3d12_resource *resource; bool invalidate = false; - unsigned int i, stride; TRACE("iface %p, start_slot %u, view_count %u, views %p.\n", iface, start_slot, view_count, views); - vk_procs = &list->device->vk_procs; - null_resources = &list->device->null_resources; - gpu_va_allocator = &list->device->gpu_va_allocator; + vk_procs = &device->vk_procs; + null_resources = &device->null_resources; + gpu_va_allocator = &device->gpu_va_allocator; if (!vkd3d_bound_range(start_slot, view_count, ARRAY_SIZE(list->strides))) { @@ -4820,6 +4821,27 @@ static void STDMETHODCALLTYPE d3d12_command_list_IASetVertexBuffers(ID3D12Graphi return; } + max_view_count = device->vk_info.device_limits.maxVertexInputBindings; + if (start_slot < max_view_count) + max_view_count -= start_slot; + else + max_view_count = 0; + + /* Although simply skipping unsupported binding slots isn't especially + * likely to work well in the general case, applications sometimes + * explicitly set all 32 vertex buffer bindings slots supported by + * Direct3D 12, with unused slots set to NULL. "Spider-Man Remastered" is + * an example of such an application. */ + if (view_count > max_view_count) + { + for (i = max_view_count; i < view_count; ++i) + { + if (views && views[i].BufferLocation) + WARN("Ignoring unsupported vertex buffer slot %u.\n", start_slot + i); + } + view_count = max_view_count; + } + for (i = 0; i < view_count; ++i) { if (views && views[i].BufferLocation)