Commit b5d344c3 authored by He Haocheng's avatar He Haocheng Committed by Marge Bot
Browse files

zink: move extension function verification to when it is used



Some vulkan functions are not loaded when the corresponding features are
not enabled, but the verifier checks for *all* functions, so make the
verifier more forgiving and use a stub to catch when we actually use a
function that is not loaded.
Reviewed-By: Mike Blumenkrantz's avatarMike Blumenkrantz <michael.blumenkrantz@gmail.com>
Part-of: <mesa/mesa!11328>
parent a0122385
......@@ -268,9 +268,20 @@ struct zink_device_info {
bool
zink_get_physical_device_info(struct zink_screen *screen);
bool
void
zink_verify_device_extensions(struct zink_screen *screen);
/* stub functions that get inserted into the dispatch table if they are not
* properly loaded.
*/
%for ext in extensions:
%if registry.in_registry(ext.name):
%for cmd in registry.get_registry_entry(ext.name).device_commands:
void zink_stub_${cmd.lstrip("vk")}(void);
%endfor
%endif
%endfor
#endif
"""
......@@ -443,7 +454,7 @@ fail:
return false;
}
bool
void
zink_verify_device_extensions(struct zink_screen *screen)
{
%for ext in extensions:
......@@ -451,16 +462,45 @@ zink_verify_device_extensions(struct zink_screen *screen)
if (screen->info.have_${ext.name_with_vendor()}) {
%for cmd in registry.get_registry_entry(ext.name).device_commands:
if (!screen->vk.${cmd.lstrip("vk")}) {
mesa_loge("ZINK: GetDeviceProcAddr failed: ${cmd}\\n");
return false;
#ifndef NDEBUG
screen->vk.${cmd.lstrip("vk")} = (PFN_${cmd})zink_stub_${cmd.lstrip("vk")};
#else
screen->vk.${cmd.lstrip("vk")} = (PFN_${cmd})zink_stub_function_not_loaded;
#endif
}
%endfor
}
%endif
%endfor
}
return true;
#ifndef NDEBUG
/* generated stub functions */
## remember the stub functions that are already generated
<% generated_funcs = set() %>
%for ext in extensions:
%if registry.in_registry(ext.name):
%for cmd in registry.get_registry_entry(ext.name).device_commands:
##
## some functions are added by multiple extensions, which creates duplication
## and thus redefinition of stubs (eg. vkCmdPushDescriptorSetWithTemplateKHR)
##
%if cmd in generated_funcs:
<% continue %>
%else:
<% generated_funcs.add(cmd) %>
%endif
void
zink_stub_${cmd.lstrip("vk")}()
{
mesa_loge("ZINK: ${cmd} is not loaded properly!");
abort();
}
%endfor
%endif
%endfor
#endif
"""
......@@ -531,7 +571,7 @@ if __name__ == "__main__":
lookup.put_string("helpers", include_template)
with open(header_path, "w") as header_file:
header = Template(header_code, lookup=lookup).render(extensions=extensions, versions=versions).strip()
header = Template(header_code, lookup=lookup).render(extensions=extensions, versions=versions, registry=registry).strip()
header = replace_code(header, replacement)
print(header, file=header_file)
......
......@@ -87,9 +87,23 @@ struct zink_instance_info {
VkInstance
zink_create_instance(struct zink_instance_info *instance_info);
bool
void
zink_verify_instance_extensions(struct zink_screen *screen);
/* stub functions that get inserted into the dispatch table if they are not
* properly loaded.
*/
%for ext in extensions:
%if registry.in_registry(ext.name):
%for cmd in registry.get_registry_entry(ext.name).instance_commands:
void zink_stub_${cmd.lstrip("vk")}(void);
%endfor
%for cmd in registry.get_registry_entry(ext.name).pdevice_commands:
void zink_stub_${cmd.lstrip("vk")}(void);
%endfor
%endif
%endfor
#endif
"""
......@@ -218,7 +232,7 @@ zink_create_instance(struct zink_instance_info *instance_info)
return instance;
}
bool
void
zink_verify_instance_extensions(struct zink_screen *screen)
{
%for ext in extensions:
......@@ -226,22 +240,51 @@ zink_verify_instance_extensions(struct zink_screen *screen)
if (screen->instance_info.have_${ext.name_with_vendor()}) {
%for cmd in registry.get_registry_entry(ext.name).instance_commands:
if (!screen->vk.${cmd.lstrip("vk")}) {
mesa_loge("ZINK: GetInstanceProcAddr failed: ${cmd}\\n");
return false;
#ifndef NDEBUG
screen->vk.${cmd.lstrip("vk")} = (PFN_${cmd})zink_stub_${cmd.lstrip("vk")};
#else
screen->vk.${cmd.lstrip("vk")} = (PFN_${cmd})zink_stub_function_not_loaded;
#endif
}
%endfor
%for cmd in registry.get_registry_entry(ext.name).pdevice_commands:
if (!screen->vk.${cmd.lstrip("vk")}) {
mesa_loge("ZINK: GetInstanceProcAddr failed: ${cmd}\\n");
return false;
#ifndef NDEBUG
screen->vk.${cmd.lstrip("vk")} = (PFN_${cmd})zink_stub_${cmd.lstrip("vk")};
#else
screen->vk.${cmd.lstrip("vk")} = (PFN_${cmd})zink_stub_function_not_loaded;
#endif
}
%endfor
}
%endif
%endfor
}
#ifndef NDEBUG
/* generated stub functions */
## see zink_device_info.py for why this is needed
<% generated_funcs = set() %>
return true;
%for ext in extensions:
%if registry.in_registry(ext.name):
%for cmd in registry.get_registry_entry(ext.name).instance_commands + registry.get_registry_entry(ext.name).pdevice_commands:
%if cmd in generated_funcs:
<% continue %>
%else:
<% generated_funcs.add(cmd) %>
%endif
void
zink_stub_${cmd.lstrip("vk")}()
{
mesa_loge("ZINK: ${cmd} is not loaded properly!");
abort();
}
%endfor
%endif
%endfor
#endif
"""
......@@ -298,7 +341,7 @@ if __name__ == "__main__":
exit(1)
with open(header_path, "w") as header_file:
header = Template(header_code).render(extensions=extensions, layers=layers).strip()
header = Template(header_code).render(extensions=extensions, layers=layers, registry=registry).strip()
header = replace_code(header, replacement)
print(header, file=header_file)
......
......@@ -1586,8 +1586,7 @@ zink_internal_create_screen(const struct pipe_screen_config *config)
vk_instance_dispatch_table_load(&screen->vk.instance, &vkGetInstanceProcAddr, screen->instance);
vk_physical_device_dispatch_table_load(&screen->vk.physical_device, &vkGetInstanceProcAddr, screen->instance);
if (!zink_verify_instance_extensions(screen))
goto fail;
zink_verify_instance_extensions(screen);
if (screen->instance_info.have_EXT_debug_utils &&
(zink_debug & ZINK_DEBUG_VALIDATION) && !create_debug(screen))
......@@ -1628,8 +1627,7 @@ zink_internal_create_screen(const struct pipe_screen_config *config)
vk_device_dispatch_table_load(&screen->vk.device, &vkGetDeviceProcAddr, screen->dev);
if (!zink_verify_device_extensions(screen))
goto fail;
zink_verify_device_extensions(screen);
if (screen->info.have_EXT_calibrated_timestamps && !check_have_device_time(screen))
goto fail;
......@@ -1775,3 +1773,12 @@ zink_drm_create_screen(int fd, const struct pipe_screen_config *config)
return &ret->base;
}
void zink_stub_function_not_loaded()
{
/* this will be used by the zink_verify_*_extensions() functions on a
* release build
*/
mesa_loge("ZINK: a Vulkan function was called without being loaded");
abort();
}
......@@ -265,4 +265,7 @@ zink_screen_update_pipeline_cache(struct zink_screen *screen);
void
zink_screen_init_descriptor_funcs(struct zink_screen *screen, bool fallback);
void
zink_stub_function_not_loaded(void);
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment