Mesa (main): zink: move extension function verification to when it is used
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Sun Jun 13 19:09:02 UTC 2021
Module: Mesa
Branch: main
Commit: b5d344c3af8190db302fd00f1d491582e2c102c4
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=b5d344c3af8190db302fd00f1d491582e2c102c4
Author: Hoe Hao Cheng <haochengho12907 at gmail.com>
Date: Sat Jun 12 00:36:32 2021 +0800
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 at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11328>
---
src/gallium/drivers/zink/zink_device_info.py | 52 +++++++++++++++++++++---
src/gallium/drivers/zink/zink_instance.py | 59 ++++++++++++++++++++++++----
src/gallium/drivers/zink/zink_screen.c | 15 +++++--
src/gallium/drivers/zink/zink_screen.h | 3 ++
4 files changed, 111 insertions(+), 18 deletions(-)
diff --git a/src/gallium/drivers/zink/zink_device_info.py b/src/gallium/drivers/zink/zink_device_info.py
index 1c34799f562..3c5af02dbdd 100644
--- a/src/gallium/drivers/zink/zink_device_info.py
+++ b/src/gallium/drivers/zink/zink_device_info.py
@@ -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)
diff --git a/src/gallium/drivers/zink/zink_instance.py b/src/gallium/drivers/zink/zink_instance.py
index 5d5a683a849..9431a20d1bb 100644
--- a/src/gallium/drivers/zink/zink_instance.py
+++ b/src/gallium/drivers/zink/zink_instance.py
@@ -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)
diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c
index f6a21595f7d..abbdaaf4f08 100644
--- a/src/gallium/drivers/zink/zink_screen.c
+++ b/src/gallium/drivers/zink/zink_screen.c
@@ -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();
+}
diff --git a/src/gallium/drivers/zink/zink_screen.h b/src/gallium/drivers/zink/zink_screen.h
index d03bb9dd3c2..8008b39f5d4 100644
--- a/src/gallium/drivers/zink/zink_screen.h
+++ b/src/gallium/drivers/zink/zink_screen.h
@@ -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
More information about the mesa-commit
mailing list