summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorJason Ekstrand <jason.ekstrand@collabora.com>2022-03-18 17:31:35 -0500
committerMarge Bot <emma+marge@anholt.net>2022-04-07 16:32:21 +0000
commitf06fa8f7e0df525fc38135e3717f257d0ab39f68 (patch)
tree5afdb2376b3d0ec3be48fdffb49769c5ca5c05c9 /docs
parent0ca8b95824191d59955f5fc9654fbf804841c1d7 (diff)
vulkan,docs: Document vk_object_base
Acked-by: Iago Toral Quiroga <itoral@igalia.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15472>
Diffstat (limited to 'docs')
-rw-r--r--docs/vulkan/base-objs.rst83
-rw-r--r--docs/vulkan/index.rst1
2 files changed, 84 insertions, 0 deletions
diff --git a/docs/vulkan/base-objs.rst b/docs/vulkan/base-objs.rst
new file mode 100644
index 00000000000..fbad2b25282
--- /dev/null
+++ b/docs/vulkan/base-objs.rst
@@ -0,0 +1,83 @@
+Base object structs
+===================
+
+The Vulkan runtime code provides a set of base object structs which must be
+used if you want your driver to take advantage of any of the runtime code.
+There are other base structs for various things which are not covered here
+but those are optional. The ones covered here are the bare minimum set
+which form the core of the Vulkan runtime code:
+
+.. contents::
+ :local:
+
+
+vk_object_base
+--------------
+
+The root base struct for all Vulkan objects is
+:cpp:struct:`vk_object_base`. Every object exposed to the client through
+the Vulkan API *must* inherit from :cpp:struct:`vk_object_base` by having a
+:cpp:struct:`vk_object_base` or some struct that inherits from
+:cpp:struct:`vk_object_base` as the driver struct's first member. Even
+though we have `container_of()` and use it liberally, the
+:cpp:struct:`vk_object_base` should be the first member as there are a few
+places, particularly in the logging framework, where we use void pointers
+to avoid casting and this only works if the address of the driver struct is
+the same as the address of the :cpp:struct:`vk_object_base`.
+
+The standard pattern for defining a Vulkan object inside a driver looks
+something like this:
+
+.. code-block:: c
+
+ struct drv_sampler {
+ struct vk_object_base base;
+
+ /* Driver fields */
+ };
+
+ VK_DEFINE_NONDISP_HANDLE_CASTS(drv_sampler, base, VkSampler,
+ VK_OBJECT_TYPE_SAMPLER);
+
+Then, to the object in a Vulkan entrypoint,
+
+.. code-block:: c
+
+ VKAPI_ATTR void VKAPI_CALL drv_DestroySampler(
+ VkDevice _device,
+ VkSampler _sampler,
+ const VkAllocationCallbacks* pAllocator)
+ {
+ VK_FROM_HANDLE(drv_device, device, _device);
+ VK_FROM_HANDLE(drv_sampler, sampler, _sampler);
+
+ if (!sampler)
+ return;
+
+ /* Tear down the sampler */
+
+ vk_object_free(&device->vk, pAllocator, sampler);
+ }
+
+The :cpp:any:`VK_DEFINE_NONDISP_HANDLE_CASTS()` macro defines a set of
+type-safe cast functions called ``drv_sampler_from_handle()`` and
+``drv_sampler_to_handle()`` which cast a :cpp:type:`VkSampler` to and from a
+``struct drv_sampler *``. Because compile-time type checking with Vulkan
+handle types doesn't always work in C, the ``_from_handle()`` helper uses the
+provided :cpp:type:`VkObjectType` to assert at runtime that the provided
+handle is the correct type of object. Both cast helpers properly handle
+``NULL`` and ``VK_NULL_HANDLE`` as inputs. The :cpp:any:`VK_FROM_HANDLE()`
+macro provides a convenient way to declare a ``drv_foo`` pointer and
+initialize it from a ``VkFoo`` handle in one smooth motion.
+
+.. doxygenstruct:: vk_object_base
+ :members:
+
+.. doxygenfunction:: vk_object_base_init
+.. doxygenfunction:: vk_object_base_finish
+
+.. doxygendefine:: VK_DEFINE_HANDLE_CASTS
+
+.. doxygendefine:: VK_DEFINE_NONDISP_HANDLE_CASTS
+
+.. doxygendefine:: VK_FROM_HANDLE
diff --git a/docs/vulkan/index.rst b/docs/vulkan/index.rst
index 58e387d6f97..b0993ffce5e 100644
--- a/docs/vulkan/index.rst
+++ b/docs/vulkan/index.rst
@@ -9,4 +9,5 @@ hardware-agnostic bits in common code.
.. toctree::
:maxdepth: 2
+ base-objs
renderpass