Mesa (main): vulkan,docs: Document vk_instance

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Apr 7 16:53:49 UTC 2022


Module: Mesa
Branch: main
Commit: f6d4641433eb9a04a551e9be5a8ecc7179451873
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=f6d4641433eb9a04a551e9be5a8ecc7179451873

Author: Jason Ekstrand <jason.ekstrand at collabora.com>
Date:   Fri Mar 18 19:25:48 2022 -0500

vulkan,docs: Document vk_instance

Acked-by: Iago Toral Quiroga <itoral at igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15472>

---

 docs/doxygen-wrapper.py          |  1 +
 docs/vulkan/base-objs.rst        | 83 ++++++++++++++++++++++++++++++++++++++++
 src/vulkan/runtime/vk_instance.h | 68 +++++++++++++++++++++++++++++++-
 3 files changed, 151 insertions(+), 1 deletion(-)

diff --git a/docs/doxygen-wrapper.py b/docs/doxygen-wrapper.py
index 1eab6a78426..b415f2290ab 100755
--- a/docs/doxygen-wrapper.py
+++ b/docs/doxygen-wrapper.py
@@ -58,6 +58,7 @@ EXPAND_ONLY_PREDEF = YES
 # Defines required to keep doxygen from tripping on our attribute macros
 PREDEFINED  = PACKED=
 PREDEFINED += ATTRIBUTE_CONST=
+PREDEFINED += MUST_CHECK=
 """)
 
 def run_doxygen(output_path, input_paths=[]):
diff --git a/docs/vulkan/base-objs.rst b/docs/vulkan/base-objs.rst
index fbad2b25282..5b66738c4c5 100644
--- a/docs/vulkan/base-objs.rst
+++ b/docs/vulkan/base-objs.rst
@@ -10,6 +10,13 @@ which form the core of the Vulkan runtime code:
 .. contents::
    :local:
 
+As one might expect, :cpp:struct:`vk_instance` is the required base struct
+for implementing ``VkInstance``, :cpp:struct:`vk_physical_device` is
+required for ``VkPhysicalDevice``, and :cpp:struct:`vk_device` for
+``VkDevice``.  Everything else must derive from
+:cpp:struct:`vk_vk_objet_base` or from some struct that derives from
+:cpp:struct:`vk_vk_objet_base`.
+
 
 vk_object_base
 --------------
@@ -81,3 +88,79 @@ initialize it from a ``VkFoo`` handle in one smooth motion.
 .. doxygendefine:: VK_DEFINE_NONDISP_HANDLE_CASTS
 
 .. doxygendefine:: VK_FROM_HANDLE
+
+
+vk_instance
+-----------
+
+.. doxygenstruct:: vk_instance
+   :members:
+
+.. doxygenfunction:: vk_instance_init
+.. doxygenfunction:: vk_instance_finish
+
+Once a driver has a :cpp:struct:`vk_instance`, implementing all the various
+instance-level ``vkGet*ProcAddr()`` entrypoints is trivial:
+
+.. code-block:: c
+
+   VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
+   drv_GetInstanceProcAddr(VkInstance _instance,
+                           const char *pName)
+   {
+      VK_FROM_HANDLE(vk_instance, instance, _instance);
+      return vk_instance_get_proc_addr(instance,
+                                       &drv_instance_entrypoints,
+                                       pName);
+   }
+
+   PUBLIC VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
+   vk_icdGetInstanceProcAddr(VkInstance instance,
+                             const char *pName);
+
+   PUBLIC VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
+   vk_icdGetInstanceProcAddr(VkInstance instance,
+                             const char *pName)
+   {
+      return drv_GetInstanceProcAddr(instance, pName);
+   }
+
+   PUBLIC VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
+   vk_icdGetPhysicalDeviceProcAddr(VkInstance  _instance,
+                                   const char* pName);
+
+   PUBLIC VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
+   vk_icdGetPhysicalDeviceProcAddr(VkInstance  _instance,
+                                   const char* pName)
+   {
+      VK_FROM_HANDLE(vk_instance, instance, _instance);
+      return vk_instance_get_physical_device_proc_addr(instance, pName);
+   }
+
+The prototypes for the ``vk_icd*`` versions are needed because those are not
+actually defined in the Vulkan headers and you need the prototype somewhere
+to get the C compiler to not complain.  These are all implemented by
+wrapping one of the provided ``vk_instance_get*_proc_addr()`` functions.
+
+.. doxygenfunction:: vk_instance_get_proc_addr
+.. doxygenfunction:: vk_instance_get_proc_addr_unchecked
+.. doxygenfunction:: vk_instance_get_physical_device_proc_addr
+
+We also provide an implementation of
+``vkEnumerateInstanceExtensionProperties()`` which can be used similarly:
+
+.. code-block:: c
+
+   VKAPI_ATTR VkResult VKAPI_CALL
+   drv_EnumerateInstanceExtensionProperties(const char *pLayerName,
+                                            uint32_t *pPropertyCount,
+                                            VkExtensionProperties *pProperties)
+   {
+      if (pLayerName)
+         return vk_error(NULL, VK_ERROR_LAYER_NOT_PRESENT);
+
+      return vk_enumerate_instance_extension_properties(
+         &instance_extensions, pPropertyCount, pProperties);
+   }
+
+.. doxygenfunction:: vk_enumerate_instance_extension_properties
diff --git a/src/vulkan/runtime/vk_instance.h b/src/vulkan/runtime/vk_instance.h
index 88af1a6b4ed..3609afc634b 100644
--- a/src/vulkan/runtime/vk_instance.h
+++ b/src/vulkan/runtime/vk_instance.h
@@ -35,20 +35,54 @@ extern "C" {
 #endif
 
 struct vk_app_info {
+   /** VkApplicationInfo::pApplicationName */
    const char*        app_name;
+
+   /** VkApplicationInfo::applicationVersion */
    uint32_t           app_version;
+
+   /** VkApplicationInfo::pEngineName */
    const char*        engine_name;
+
+   /** VkApplicationInfo::engineVersion */
    uint32_t           engine_version;
+
+   /** VkApplicationInfo::apiVersion or `VK_API_VERSION_1_0`
+    *
+    * If the application does not provide a `pApplicationInfo` or the
+    * `apiVersion` field is 0, this is set to `VK_API_VERSION_1_0`.
+    */
    uint32_t           api_version;
 };
 
+/** Base struct for all `VkInstance` implementations
+ *
+ * This contains data structures necessary for detecting enabled extensions,
+ * handling entrypoint dispatch, and implementing `vkGetInstanceProcAddr()`.
+ * It also contains data copied from the `VkInstanceCreateInfo` such as the
+ * application information.
+ */
 struct vk_instance {
    struct vk_object_base base;
+
+   /** Allocator used when creating this instance
+    *
+    * This is used as a fall-back for when a NULL pAllocator is passed into a
+    * device-level create function such as vkCreateImage().
+    */
    VkAllocationCallbacks alloc;
 
+   /** VkInstanceCreateInfo::pApplicationInfo */
    struct vk_app_info app_info;
+
+   /** Table of all enabled instance extensions
+    *
+    * This is generated automatically as part of `vk_instance_init()` from
+    * VkInstanceCreateInfo::ppEnabledExtensionNames.
+    */
    struct vk_instance_extension_table enabled_extensions;
 
+   /** Instance-level dispatch table */
    struct vk_instance_dispatch_table dispatch_table;
 
    /* VK_EXT_debug_report debug callbacks */
@@ -70,8 +104,26 @@ struct vk_instance {
 };
 
 VK_DEFINE_HANDLE_CASTS(vk_instance, base, VkInstance,
-                       VK_OBJECT_TYPE_INSTANCE)
+                       VK_OBJECT_TYPE_INSTANCE);
 
+/** Initialize a vk_instance
+ *
+ * Along with initializing the data structures in `vk_instance`, this function
+ * validates the Vulkan version number provided by the client and checks that
+ * every extension specified by
+ * `VkInstanceCreateInfo::ppEnabledExtensionNames` is actually supported by
+ * the implementation and returns `VK_ERROR_EXTENSION_NOT_PRESENT` if an
+ * unsupported extension is requested.
+ *
+ * @param[out] instance             The instance to initialize
+ * @param[in]  supported_extensions Table of all instance extensions supported
+ *                                  by this instance
+ * @param[in]  dispatch_table       Instance-level dispatch table
+ * @param[in]  pCreateInfo          VkInstanceCreateInfo pointer passed to
+ *                                  `vkCreateInstance()`
+ * @param[in]  alloc                Allocation callbacks used to create this
+ *                                  instance; must not be `NULL`
+ */
 VkResult MUST_CHECK
 vk_instance_init(struct vk_instance *instance,
                  const struct vk_instance_extension_table *supported_extensions,
@@ -79,24 +131,38 @@ vk_instance_init(struct vk_instance *instance,
                  const VkInstanceCreateInfo *pCreateInfo,
                  const VkAllocationCallbacks *alloc);
 
+/** Tears down a vk_instance
+ *
+ * @param[out] instance             The instance to tear down
+ */
 void
 vk_instance_finish(struct vk_instance *instance);
 
+/** Implementaiton of vkEnumerateInstanceExtensionProperties() */
 VkResult
 vk_enumerate_instance_extension_properties(
     const struct vk_instance_extension_table *supported_extensions,
     uint32_t *pPropertyCount,
     VkExtensionProperties *pProperties);
 
+/** Implementaiton of vkGetInstanceProcAddr() */
 PFN_vkVoidFunction
 vk_instance_get_proc_addr(const struct vk_instance *instance,
                           const struct vk_instance_entrypoint_table *entrypoints,
                           const char *name);
 
+/** Unchecked version of vk_instance_get_proc_addr
+ *
+ * This is identical to `vk_instance_get_proc_addr()` except that it doesn't
+ * check whether extensions are enabled before returning function pointers.
+ * This is useful in window-system code where we may use extensions without
+ * the client explicitly enabling them.
+ */
 PFN_vkVoidFunction
 vk_instance_get_proc_addr_unchecked(const struct vk_instance *instance,
                                     const char *name);
 
+/** Implementaiton of vk_icdGetPhysicalDeviceProcAddr() */
 PFN_vkVoidFunction
 vk_instance_get_physical_device_proc_addr(const struct vk_instance *instance,
                                           const char *name);



More information about the mesa-commit mailing list