vulkan,docs: Document vk_instance

Acked-by: Iago Toral Quiroga <itoral@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15472>
This commit is contained in:
Jason Ekstrand 2022-03-18 19:25:48 -05:00 committed by Marge Bot
parent f06fa8f7e0
commit f6d4641433
3 changed files with 151 additions and 1 deletions

View File

@ -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=[]):

View File

@ -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

View File

@ -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);