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 <michael.blumenkrantz@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36061>
This commit is contained in:
Mel Henning 2025-07-10 17:56:36 -04:00
parent 9d295f4e21
commit b5973bed78
8 changed files with 128 additions and 1 deletions

View file

@ -23,6 +23,10 @@ we can compare the ZINK profiles with Vulkan devices profiles generated with
`Vulkaninfo <https://vulkan.lunarg.com/doc/view/latest/windows/vulkaninfo.html>`__
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
^^^^^^^^^^

View file

@ -112,6 +112,7 @@ if with_tools.contains('all')
'nir',
'nouveau',
'panfrost',
'zink',
]
endif

View file

@ -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`)',
)

View file

@ -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,
)

View file

@ -0,0 +1,73 @@
/*
* Copyright 2025 Valve Corporation
*
* SPDX-License-Identifier: MIT
*/
#include <stdexcept>
#include <iostream>
#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<VpProfileProperties> profiles(count);
vpGetProfiles(&count, profiles.data());
for (const VpProfileProperties& profile : profiles) {
checkProfile(profile);
}
}

View file

@ -116,3 +116,7 @@ if with_tests
suite : ['zink'],
)
endif
if with_tools.contains('zink')
subdir('check_requirements')
endif

View file

@ -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

View file

@ -0,0 +1,2 @@
project('Vulkan-Profiles', [])
gen_profiles_solution = files('scripts/gen_profiles_solution.py')