diff --git a/windows/CMakeLists.txt b/windows/CMakeLists.txt index 88576bf44..ecb618323 100644 --- a/windows/CMakeLists.txt +++ b/windows/CMakeLists.txt @@ -48,6 +48,56 @@ else() set(MPV_LIB_DIR "${mpv_dev_SOURCE_DIR}") endif() +# libmpv >= 20260809 dynamically links the Khronos Vulkan loader instead of +# statically linking it, so libmpv-2.dll hard-imports vulkan-1.dll. On x64 +# the GPU driver normally installs the loader into System32, but +# Windows-on-ARM Adreno drivers (and driverless x64 machines such as VMs) +# do not ship it, which made the process fail before WinMain (#2110). +# Bundle the LunarG-built loader next to the executable; without a Vulkan +# ICD, gpu-api=auto falls back to D3D11 exactly as the old static loader +# did. +set(VULKAN_RT_VERSION "1.4.357.0") +if(CMAKE_SYSTEM_PROCESSOR STREQUAL "ARM64") + set(VULKAN_RT_SLUG "warm") + set(VULKAN_RT_COMPONENTS "VulkanRT-ARM64-${VULKAN_RT_VERSION}-Components") + set(VULKAN_RT_DLL_SUBPATH "${VULKAN_RT_COMPONENTS}/vulkan-1.dll") + set(VULKAN_RT_SHA256 "0a51a619525e0c7a156125c4f80c4f591c494cef9ff59dc4481735779a9a280c") +else() + set(VULKAN_RT_SLUG "windows") + set(VULKAN_RT_COMPONENTS "VulkanRT-X64-${VULKAN_RT_VERSION}-Components") + set(VULKAN_RT_DLL_SUBPATH "${VULKAN_RT_COMPONENTS}/x64/vulkan-1.dll") + set(VULKAN_RT_SHA256 "a14672efed15aafc7f5a16572d35cd3a3416eadf670aeee3cdf50ee32d5fbf83") +endif() +set(VULKAN_RT_DIR "${CMAKE_BINARY_DIR}/vulkan-runtime") +if(NOT EXISTS "${VULKAN_RT_DIR}/vulkan-1.dll" OR NOT EXISTS "${VULKAN_RT_DIR}/VulkanRT-License.txt") + set(VULKAN_RT_ZIP "${VULKAN_RT_DIR}/vulkan-runtime-components.zip") + message(STATUS "Downloading Vulkan runtime (${VULKAN_RT_SLUG} ${VULKAN_RT_VERSION})...") + # sdk.lunarg.com rejects requests without a recognized User-Agent. + file(DOWNLOAD + "https://sdk.lunarg.com/sdk/download/${VULKAN_RT_VERSION}/${VULKAN_RT_SLUG}/vulkan-runtime-components.zip" + "${VULKAN_RT_ZIP}" + HTTPHEADER "User-Agent: curl/8.4.0" + EXPECTED_HASH SHA256=${VULKAN_RT_SHA256} + STATUS VULKAN_RT_DL_STATUS) + list(GET VULKAN_RT_DL_STATUS 0 VULKAN_RT_DL_RESULT) + if(NOT VULKAN_RT_DL_RESULT EQUAL 0) + message(FATAL_ERROR "Failed to download Vulkan runtime: ${VULKAN_RT_DL_STATUS}") + endif() + execute_process( + COMMAND "${CMAKE_COMMAND}" -E tar xf "${VULKAN_RT_ZIP}" + WORKING_DIRECTORY "${VULKAN_RT_DIR}" + RESULT_VARIABLE VULKAN_RT_EXTRACT_RESULT + ) + if(NOT VULKAN_RT_EXTRACT_RESULT EQUAL 0) + message(FATAL_ERROR "Failed to extract Vulkan runtime archive") + endif() + file(RENAME "${VULKAN_RT_DIR}/${VULKAN_RT_DLL_SUBPATH}" "${VULKAN_RT_DIR}/vulkan-1.dll") + file(RENAME "${VULKAN_RT_DIR}/${VULKAN_RT_COMPONENTS}/VulkanRT-License.txt" + "${VULKAN_RT_DIR}/VulkanRT-License.txt") + file(REMOVE_RECURSE "${VULKAN_RT_DIR}/${VULKAN_RT_COMPONENTS}") + file(REMOVE "${VULKAN_RT_ZIP}") +endif() + # Fetch simdutf for SIMD-accelerated UTF-8 validation. # mpv strings are not guaranteed to be valid UTF-8; invalid bytes sent through # Flutter's StandardMessageCodec cause FormatException crashes. @@ -200,3 +250,10 @@ install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" install(FILES "${MPV_LIB_DIR}/libmpv-2.dll" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) + +# Install the Vulkan loader (and its license) next to the executable so the +# hard import in libmpv-2.dll resolves on machines whose GPU driver does not +# provide vulkan-1.dll. +install(FILES "${VULKAN_RT_DIR}/vulkan-1.dll" "${VULKAN_RT_DIR}/VulkanRT-License.txt" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime)