mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 02:38:04 +02:00
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 <michael.blumenkrantz@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11328>
This commit is contained in:
parent
a0122385f0
commit
b5d344c3af
4 changed files with 113 additions and 20 deletions
|
|
@ -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
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
/* generated stub functions */
|
||||
## see zink_device_info.py for why this is needed
|
||||
<% generated_funcs = set() %>
|
||||
|
||||
%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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue