From b5973bed781a1b01a9c4bacdd787f1122d009956 Mon Sep 17 00:00:00 2001 From: Mel Henning Date: Thu, 10 Jul 2025 17:56:36 -0400 Subject: [PATCH] zink: Add zink_check_requirements This is a new tool that checks a driver against the vulkan profile and complains about any missing features. Acked-by: Mike Blumenkrantz Part-of: --- docs/drivers/zink.rst | 4 + meson.build | 1 + meson.options | 2 +- .../zink/check_requirements/meson.build | 37 ++++++++++ .../zink_check_requirements.cpp | 73 +++++++++++++++++++ src/gallium/drivers/zink/meson.build | 4 + subprojects/Vulkan-Profiles.wrap | 6 ++ .../packagefiles/Vulkan-Profiles/meson.build | 2 + 8 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 src/gallium/drivers/zink/check_requirements/meson.build create mode 100644 src/gallium/drivers/zink/check_requirements/zink_check_requirements.cpp create mode 100644 subprojects/Vulkan-Profiles.wrap create mode 100644 subprojects/packagefiles/Vulkan-Profiles/meson.build diff --git a/docs/drivers/zink.rst b/docs/drivers/zink.rst index 02b59a5d03b..08c1c6198f9 100644 --- a/docs/drivers/zink.rst +++ b/docs/drivers/zink.rst @@ -23,6 +23,10 @@ we can compare the ZINK profiles with Vulkan devices profiles generated with `Vulkaninfo `__ or `downloaded from GPUinfo.org`_ to establish the feature-levels supported by these drivers. +You can check a running driver against the Zink profiles by building mesa with +``--tools=zink`` and running +``./src/gallium/drivers/zink/check_requirements/zink_check_requirements`` +from the build directory. OpenGL 2.1 ^^^^^^^^^^ diff --git a/meson.build b/meson.build index 9cc75f6636e..be9a538ec84 100644 --- a/meson.build +++ b/meson.build @@ -112,6 +112,7 @@ if with_tools.contains('all') 'nir', 'nouveau', 'panfrost', + 'zink', ] endif diff --git a/meson.options b/meson.options index 71d7640661f..ac92e414d1d 100644 --- a/meson.options +++ b/meson.options @@ -545,7 +545,7 @@ option( value : [], choices : ['drm-shim', 'etnaviv', 'freedreno', 'glsl', 'intel', 'intel-ui', 'nir', 'nouveau', 'lima', 'panfrost', 'asahi', 'imagination', - 'all', 'dlclose-skip'], + 'zink', 'all', 'dlclose-skip'], description : 'List of tools to build. (Note: `intel-ui` selects `intel`)', ) diff --git a/src/gallium/drivers/zink/check_requirements/meson.build b/src/gallium/drivers/zink/check_requirements/meson.build new file mode 100644 index 00000000000..5cd141b1f16 --- /dev/null +++ b/src/gallium/drivers/zink/check_requirements/meson.build @@ -0,0 +1,37 @@ +gen_profiles_solution = subproject('Vulkan-Profiles').get_variable('gen_profiles_solution') + +vulkan_profiles_hpp = custom_target( + 'vulkan_profiles.hpp', + output : 'vulkan_profiles.hpp', + input : [ + gen_profiles_solution, + '../VP_ZINK_requirements.json', + vk_api_xml, + ], + command : [ + prog_python, + '@INPUT0@', + + # The program awkwardly demands the input folder and file name as + # different arguments, so cut off the trailing file name using '/..' + '--input', '@INPUT1@/..', + '--input-filenames', 'VP_ZINK_requirements.json', + + # Output is similar, but the file name is implicit + '--output-library-inc', '@OUTPUT@/..', + + '--registry', '@INPUT2@', + '--config', 'debug', + ], +) + +vulkan_dep = dependency('vulkan') + +executable('zink_check_requirements', + [vulkan_profiles_hpp, 'zink_check_requirements.cpp'], + dependencies: [ + vulkan_dep, + ], + include_directories : [inc_include], + install : false, +) diff --git a/src/gallium/drivers/zink/check_requirements/zink_check_requirements.cpp b/src/gallium/drivers/zink/check_requirements/zink_check_requirements.cpp new file mode 100644 index 00000000000..b6c72c10bd0 --- /dev/null +++ b/src/gallium/drivers/zink/check_requirements/zink_check_requirements.cpp @@ -0,0 +1,73 @@ +/* + * Copyright 2025 Valve Corporation + * + * SPDX-License-Identifier: MIT + */ + +#include +#include + +#include "vulkan_profiles.hpp" + +static void checkProfile(const VpProfileProperties& profile_properties) { + std::cout << "Checking profile " << profile_properties.profileName + << std::endl; + VkBool32 instance_profile_supported = false; + vpGetInstanceProfileSupport(nullptr, &profile_properties, + &instance_profile_supported); + if (!instance_profile_supported) { + throw std::runtime_error{"UNSUPPORTED instance"}; + } + + VkInstanceCreateInfo create_info{}; + create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; + + VpInstanceCreateInfo instance_create_info{}; + instance_create_info.pEnabledFullProfiles = &profile_properties; + instance_create_info.enabledFullProfileCount = 1; + instance_create_info.pCreateInfo = &create_info; + + VkInstance instance = VK_NULL_HANDLE; + VkResult result = vpCreateInstance(&instance_create_info, nullptr, + &instance); + if (result != VK_SUCCESS) { + throw std::runtime_error{"Failed to create instance"}; + } + + uint32_t deviceCount = 1; + VkPhysicalDevice pdev = VK_NULL_HANDLE; + vkEnumeratePhysicalDevices(instance, &deviceCount, &pdev); + if (deviceCount == 0) { + vkDestroyInstance(instance, nullptr); + throw std::runtime_error("No physical devices found"); + } + + VkPhysicalDeviceProperties2 properties = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, + }; + vkGetPhysicalDeviceProperties2(pdev, &properties); + std::cout << "Checking device " << properties.properties.deviceName + << std::endl; + + VkBool32 pdev_profile_supported = false; + vpGetPhysicalDeviceProfileSupport(instance, pdev, &profile_properties, + &pdev_profile_supported); + if (!pdev_profile_supported) { + std::cout << "UNSUPPORTED physical device\n\n"; + } else { + std::cout << "Supported\n\n"; + } + + vkDestroyInstance(instance, nullptr); +} + +int main() { + uint32_t count = 0; + vpGetProfiles(&count, nullptr); + std::vector profiles(count); + vpGetProfiles(&count, profiles.data()); + + for (const VpProfileProperties& profile : profiles) { + checkProfile(profile); + } +} diff --git a/src/gallium/drivers/zink/meson.build b/src/gallium/drivers/zink/meson.build index a3a9ae9ec9a..97adf9ddc5a 100644 --- a/src/gallium/drivers/zink/meson.build +++ b/src/gallium/drivers/zink/meson.build @@ -116,3 +116,7 @@ if with_tests suite : ['zink'], ) endif + +if with_tools.contains('zink') + subdir('check_requirements') +endif diff --git a/subprojects/Vulkan-Profiles.wrap b/subprojects/Vulkan-Profiles.wrap new file mode 100644 index 00000000000..db2bfe21828 --- /dev/null +++ b/subprojects/Vulkan-Profiles.wrap @@ -0,0 +1,6 @@ +[wrap-file] +directory = Vulkan-Profiles-1f1817e2f7dc78e26c04f496285fc39486b767dc +source_url = https://github.com/KhronosGroup/Vulkan-Profiles/archive/1f1817e2f7dc78e26c04f496285fc39486b767dc.zip +source_filename = Vulkan-Profiles-1f1817e2f7.zip +source_hash = c81784e521629597241237b5a1cfaff5d2d19818d283c05d851e4b728ccbbdcc +patch_directory = Vulkan-Profiles diff --git a/subprojects/packagefiles/Vulkan-Profiles/meson.build b/subprojects/packagefiles/Vulkan-Profiles/meson.build new file mode 100644 index 00000000000..1402410ae15 --- /dev/null +++ b/subprojects/packagefiles/Vulkan-Profiles/meson.build @@ -0,0 +1,2 @@ +project('Vulkan-Profiles', []) +gen_profiles_solution = files('scripts/gen_profiles_solution.py')