zink: fix instance/device versioning (for real this time)
the maximum allowable runtime version of vk can be computed by MIN(instance_version, device_version) despite this, instances and devices can be created using the maximum version available for each respective type. the restriction is applied only at the point of enabling/applying features and extensions, meaning that to correctly handle this, zink must: 1. create an instance using the maximum allowable version 2. select a physical device using the instance 3. compute MIN(instance_version, device_version) 4. only now begin to enable/use features requiring vk 1.1+ ref #4392 Reviewed-by: Adam Jackson <ajax@redhat.com> Acked-by: Hoe Hao Cheng <haochengho12907@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9479>
This commit is contained in:

committed by
Marge Bot

parent
1d70863c12
commit
5945d7d2e9
@@ -247,10 +247,6 @@ zink_get_physical_device_info(struct zink_screen *screen)
|
||||
%endfor
|
||||
uint32_t num_extensions = 0;
|
||||
|
||||
// get device API support
|
||||
vkGetPhysicalDeviceProperties(screen->pdev, &info->props);
|
||||
info->device_version = info->props.apiVersion;
|
||||
|
||||
// get device memory properties
|
||||
vkGetPhysicalDeviceMemoryProperties(screen->pdev, &info->mem_props);
|
||||
|
||||
@@ -268,7 +264,7 @@ zink_get_physical_device_info(struct zink_screen *screen)
|
||||
%if ext.core_since:
|
||||
%for version in versions:
|
||||
%if ext.core_since.struct_version == version.struct_version:
|
||||
if (${version.version()} >= info->device_version) {
|
||||
if (${version.version()} >= screen->vk_version) {
|
||||
%if not (ext.has_features or ext.has_properties):
|
||||
info->have_${ext.name_with_vendor()} = true;
|
||||
%else:
|
||||
@@ -305,7 +301,7 @@ zink_get_physical_device_info(struct zink_screen *screen)
|
||||
info->feats.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
|
||||
|
||||
%for version in versions:
|
||||
if (${version.version()} <= info->device_version) {
|
||||
if (${version.version()} <= screen->vk_version) {
|
||||
info->feats${version.struct()}.sType = ${version.stype("FEATURES")};
|
||||
info->feats${version.struct()}.pNext = info->feats.pNext;
|
||||
info->feats.pNext = &info->feats${version.struct()};
|
||||
@@ -336,7 +332,7 @@ zink_get_physical_device_info(struct zink_screen *screen)
|
||||
props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
|
||||
|
||||
%for version in versions:
|
||||
if (${version.version()} <= info->device_version) {
|
||||
if (${version.version()} <= screen->vk_version) {
|
||||
info->props${version.struct()}.sType = ${version.stype("PROPERTIES")};
|
||||
info->props${version.struct()}.pNext = props.pNext;
|
||||
props.pNext = &info->props${version.struct()};
|
||||
|
@@ -133,21 +133,10 @@ zink_create_instance(struct zink_instance_info *instance_info)
|
||||
if (vkEnumerateInstanceExtensionProperties(NULL, &extension_count, extension_props) == VK_SUCCESS) {
|
||||
for (uint32_t i = 0; i < extension_count; i++) {
|
||||
%for ext in extensions:
|
||||
%if not ext.core_since:
|
||||
if (!strcmp(extension_props[i].extensionName, ${ext.extension_name_literal()})) {
|
||||
have_${ext.name_with_vendor()} = true;
|
||||
extensions[num_extensions++] = ${ext.extension_name_literal()};
|
||||
}
|
||||
%else:
|
||||
if (instance_info->loader_version < ${ext.core_since.version()}) {
|
||||
if (!strcmp(extension_props[i].extensionName, ${ext.extension_name_literal()})) {
|
||||
have_${ext.name_with_vendor()} = true;
|
||||
extensions[num_extensions++] = ${ext.extension_name_literal()};
|
||||
}
|
||||
} else {
|
||||
have_${ext.name_with_vendor()} = true;
|
||||
}
|
||||
%endif
|
||||
%endfor
|
||||
}
|
||||
}
|
||||
@@ -213,7 +202,7 @@ zink_create_instance(struct zink_instance_info *instance_info)
|
||||
ai.pApplicationName = "unknown";
|
||||
|
||||
ai.pEngineName = "mesa zink";
|
||||
ai.apiVersion = VK_MAKE_VERSION(1, 0, 0);
|
||||
ai.apiVersion = instance_info->loader_version;
|
||||
|
||||
VkInstanceCreateInfo ici = {};
|
||||
ici.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||
@@ -248,10 +237,11 @@ zink_load_instance_extensions(struct zink_screen *screen)
|
||||
}
|
||||
%elif bool(ext.instance_funcs):
|
||||
if (screen->instance_info.have_${ext.name_with_vendor()}) {
|
||||
if (screen->instance_info.loader_version < ${ext.core_since.version()}) {
|
||||
if (screen->vk_version < ${ext.core_since.version()}) {
|
||||
%for func in ext.instance_funcs:
|
||||
GET_PROC_ADDR_INSTANCE_LOCAL(screen->instance, ${func}${ext.vendor()});
|
||||
screen->vk_${func} = vk_${func}${ext.vendor()};
|
||||
if (!screen->vk_${func}) return false;
|
||||
%endfor
|
||||
} else {
|
||||
%for func in ext.instance_funcs:
|
||||
@@ -318,6 +308,9 @@ if __name__ == "__main__":
|
||||
error_count += 1
|
||||
print("The instance function {} is not added by the extension {}.".format(func, ext.name))
|
||||
|
||||
if entry.promoted_in:
|
||||
ext.core_since = Version((*entry.promoted_in, 0))
|
||||
|
||||
if error_count > 0:
|
||||
print("zink_instance.py: Found {} error(s) in total. Quitting.".format(error_count))
|
||||
exit(1)
|
||||
|
@@ -852,43 +852,47 @@ zink_destroy_screen(struct pipe_screen *pscreen)
|
||||
FREE(screen);
|
||||
}
|
||||
|
||||
static VkPhysicalDevice
|
||||
choose_pdev(const VkInstance instance)
|
||||
static void
|
||||
choose_pdev(struct zink_screen *screen)
|
||||
{
|
||||
uint32_t i, pdev_count;
|
||||
VkPhysicalDevice *pdevs, pdev = NULL;
|
||||
VkResult result = vkEnumeratePhysicalDevices(instance, &pdev_count, NULL);
|
||||
VkPhysicalDevice *pdevs;
|
||||
VkResult result = vkEnumeratePhysicalDevices(screen->instance, &pdev_count, NULL);
|
||||
if (result != VK_SUCCESS)
|
||||
return VK_NULL_HANDLE;
|
||||
return;
|
||||
|
||||
assert(pdev_count > 0);
|
||||
|
||||
pdevs = malloc(sizeof(*pdevs) * pdev_count);
|
||||
result = vkEnumeratePhysicalDevices(instance, &pdev_count, pdevs);
|
||||
result = vkEnumeratePhysicalDevices(screen->instance, &pdev_count, pdevs);
|
||||
assert(result == VK_SUCCESS);
|
||||
assert(pdev_count > 0);
|
||||
|
||||
VkPhysicalDeviceProperties *props = &screen->info.props;
|
||||
for (i = 0; i < pdev_count; ++i) {
|
||||
VkPhysicalDeviceProperties props;
|
||||
vkGetPhysicalDeviceProperties(pdevs[i], &props);
|
||||
vkGetPhysicalDeviceProperties(pdevs[i], props);
|
||||
|
||||
#ifdef ZINK_WITH_SWRAST_VK
|
||||
char *use_lavapipe = getenv("ZINK_USE_LAVAPIPE");
|
||||
if (use_lavapipe) {
|
||||
if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU) {
|
||||
pdev = pdevs[i];
|
||||
if (props->deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU) {
|
||||
screen->pdev = pdevs[i];
|
||||
screen->info.device_version = props->apiVersion;
|
||||
break;
|
||||
} else
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (props.deviceType != VK_PHYSICAL_DEVICE_TYPE_CPU) {
|
||||
pdev = pdevs[i];
|
||||
if (props->deviceType != VK_PHYSICAL_DEVICE_TYPE_CPU) {
|
||||
screen->pdev = pdevs[i];
|
||||
screen->info.device_version = props->apiVersion;
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(pdevs);
|
||||
return pdev;
|
||||
|
||||
/* runtime version is the lesser of the instance version and device version */
|
||||
screen->vk_version = MIN2(screen->info.device_version, screen->instance_info.loader_version);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1260,13 +1264,10 @@ zink_internal_create_screen(const struct pipe_screen_config *config)
|
||||
if (!screen->instance)
|
||||
goto fail;
|
||||
|
||||
if (!zink_load_instance_extensions(screen))
|
||||
goto fail;
|
||||
|
||||
if (screen->instance_info.have_EXT_debug_utils && !create_debug(screen))
|
||||
debug_printf("ZINK: failed to setup debug utils\n");
|
||||
|
||||
screen->pdev = choose_pdev(screen->instance);
|
||||
choose_pdev(screen);
|
||||
if (screen->pdev == VK_NULL_HANDLE)
|
||||
goto fail;
|
||||
|
||||
@@ -1277,6 +1278,9 @@ zink_internal_create_screen(const struct pipe_screen_config *config)
|
||||
screen->have_D24_UNORM_S8_UINT = zink_is_depth_format_supported(screen,
|
||||
VK_FORMAT_D24_UNORM_S8_UINT);
|
||||
|
||||
if (!zink_load_instance_extensions(screen))
|
||||
goto fail;
|
||||
|
||||
if (!zink_get_physical_device_info(screen)) {
|
||||
debug_printf("ZINK: failed to detect features\n");
|
||||
goto fail;
|
||||
|
@@ -66,6 +66,7 @@ struct zink_screen {
|
||||
struct zink_instance_info instance_info;
|
||||
|
||||
VkPhysicalDevice pdev;
|
||||
uint32_t vk_version;
|
||||
|
||||
struct zink_device_info info;
|
||||
struct nir_shader_compiler_options nir_options;
|
||||
|
Reference in New Issue
Block a user