1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2020 Intel Corporation 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21bf215546Sopenharmony_ci * IN THE SOFTWARE. 22bf215546Sopenharmony_ci */ 23bf215546Sopenharmony_ci#ifndef VK_OBJECT_H 24bf215546Sopenharmony_ci#define VK_OBJECT_H 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_ci#include <vulkan/vulkan.h> 27bf215546Sopenharmony_ci#include <vulkan/vk_icd.h> 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_ci#include "c11/threads.h" 30bf215546Sopenharmony_ci#include "util/macros.h" 31bf215546Sopenharmony_ci#include "util/sparse_array.h" 32bf215546Sopenharmony_ci 33bf215546Sopenharmony_ci#ifdef __cplusplus 34bf215546Sopenharmony_ciextern "C" { 35bf215546Sopenharmony_ci#endif 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_cistruct hash_table; 38bf215546Sopenharmony_ci 39bf215546Sopenharmony_cistruct vk_device; 40bf215546Sopenharmony_ci 41bf215546Sopenharmony_ci/** Base struct for all Vulkan objects */ 42bf215546Sopenharmony_cistruct vk_object_base { 43bf215546Sopenharmony_ci VK_LOADER_DATA _loader_data; 44bf215546Sopenharmony_ci 45bf215546Sopenharmony_ci /** Type of this object 46bf215546Sopenharmony_ci * 47bf215546Sopenharmony_ci * This is used for runtime type checking when casting to and from Vulkan 48bf215546Sopenharmony_ci * handle types since compile-time type checking doesn't always work. 49bf215546Sopenharmony_ci */ 50bf215546Sopenharmony_ci VkObjectType type; 51bf215546Sopenharmony_ci 52bf215546Sopenharmony_ci /** Pointer to the device in which this object exists, if any 53bf215546Sopenharmony_ci * 54bf215546Sopenharmony_ci * This is NULL for instances and physical devices but should point to a 55bf215546Sopenharmony_ci * valid vk_device for almost everything else. (There are a few WSI 56bf215546Sopenharmony_ci * objects that don't inherit from a device.) 57bf215546Sopenharmony_ci */ 58bf215546Sopenharmony_ci struct vk_device *device; 59bf215546Sopenharmony_ci 60bf215546Sopenharmony_ci /* True if this object is fully constructed and visible to the client */ 61bf215546Sopenharmony_ci bool client_visible; 62bf215546Sopenharmony_ci 63bf215546Sopenharmony_ci /* For VK_EXT_private_data */ 64bf215546Sopenharmony_ci struct util_sparse_array private_data; 65bf215546Sopenharmony_ci 66bf215546Sopenharmony_ci /* VK_EXT_debug_utils */ 67bf215546Sopenharmony_ci char *object_name; 68bf215546Sopenharmony_ci}; 69bf215546Sopenharmony_ci 70bf215546Sopenharmony_ci/** Initialize a vk_base_object 71bf215546Sopenharmony_ci * 72bf215546Sopenharmony_ci * @param[in] device The vk_device this object was created from or NULL 73bf215546Sopenharmony_ci * @param[out] base The vk_object_base to initialize 74bf215546Sopenharmony_ci * @param[in] obj_type The VkObjectType of the object being initialized 75bf215546Sopenharmony_ci */ 76bf215546Sopenharmony_civoid vk_object_base_init(struct vk_device *device, 77bf215546Sopenharmony_ci struct vk_object_base *base, 78bf215546Sopenharmony_ci VkObjectType obj_type); 79bf215546Sopenharmony_ci 80bf215546Sopenharmony_ci/** Tear down a vk_object_base 81bf215546Sopenharmony_ci * 82bf215546Sopenharmony_ci * @param[out] base The vk_object_base being torn down 83bf215546Sopenharmony_ci */ 84bf215546Sopenharmony_civoid vk_object_base_finish(struct vk_object_base *base); 85bf215546Sopenharmony_ci 86bf215546Sopenharmony_cistatic inline void 87bf215546Sopenharmony_civk_object_base_assert_valid(ASSERTED struct vk_object_base *base, 88bf215546Sopenharmony_ci ASSERTED VkObjectType obj_type) 89bf215546Sopenharmony_ci{ 90bf215546Sopenharmony_ci assert(base == NULL || base->type == obj_type); 91bf215546Sopenharmony_ci} 92bf215546Sopenharmony_ci 93bf215546Sopenharmony_cistatic inline struct vk_object_base * 94bf215546Sopenharmony_civk_object_base_from_u64_handle(uint64_t handle, VkObjectType obj_type) 95bf215546Sopenharmony_ci{ 96bf215546Sopenharmony_ci struct vk_object_base *base = (struct vk_object_base *)(uintptr_t)handle; 97bf215546Sopenharmony_ci vk_object_base_assert_valid(base, obj_type); 98bf215546Sopenharmony_ci return base; 99bf215546Sopenharmony_ci} 100bf215546Sopenharmony_ci 101bf215546Sopenharmony_ci/** Define handle cast macros for the given dispatchable handle type 102bf215546Sopenharmony_ci * 103bf215546Sopenharmony_ci * For a given `driver_struct`, this defines `driver_struct_to_handle()` and 104bf215546Sopenharmony_ci * `driver_struct_from_handle()` helpers which provide type-safe (as much as 105bf215546Sopenharmony_ci * possible with Vulkan handle types) casts to and from the `driver_struct` 106bf215546Sopenharmony_ci * type. As an added layer of protection, these casts use the provided 107bf215546Sopenharmony_ci * `VkObjectType` to assert that the object is of the correct type when 108bf215546Sopenharmony_ci * running with a debug build. 109bf215546Sopenharmony_ci * 110bf215546Sopenharmony_ci * @param __driver_type The name of the driver struct; it is assumed this is 111bf215546Sopenharmony_ci * the name of a struct type and `struct` will be 112bf215546Sopenharmony_ci * prepended automatically 113bf215546Sopenharmony_ci * 114bf215546Sopenharmony_ci * @param __base The name of the vk_base_object member 115bf215546Sopenharmony_ci * 116bf215546Sopenharmony_ci * @param __VkType The Vulkan object type such as VkImage 117bf215546Sopenharmony_ci * 118bf215546Sopenharmony_ci * @param __VK_TYPE The VkObjectType corresponding to __VkType, such as 119bf215546Sopenharmony_ci * VK_OBJECT_TYPE_IMAGE 120bf215546Sopenharmony_ci */ 121bf215546Sopenharmony_ci#define VK_DEFINE_HANDLE_CASTS(__driver_type, __base, __VkType, __VK_TYPE) \ 122bf215546Sopenharmony_ci static inline struct __driver_type * \ 123bf215546Sopenharmony_ci __driver_type ## _from_handle(__VkType _handle) \ 124bf215546Sopenharmony_ci { \ 125bf215546Sopenharmony_ci struct vk_object_base *base = (struct vk_object_base *)_handle; \ 126bf215546Sopenharmony_ci vk_object_base_assert_valid(base, __VK_TYPE); \ 127bf215546Sopenharmony_ci STATIC_ASSERT(offsetof(struct __driver_type, __base) == 0); \ 128bf215546Sopenharmony_ci return (struct __driver_type *) base; \ 129bf215546Sopenharmony_ci } \ 130bf215546Sopenharmony_ci \ 131bf215546Sopenharmony_ci static inline __VkType \ 132bf215546Sopenharmony_ci __driver_type ## _to_handle(struct __driver_type *_obj) \ 133bf215546Sopenharmony_ci { \ 134bf215546Sopenharmony_ci vk_object_base_assert_valid(&_obj->__base, __VK_TYPE); \ 135bf215546Sopenharmony_ci if (_obj != NULL) \ 136bf215546Sopenharmony_ci _obj->__base.client_visible = true; \ 137bf215546Sopenharmony_ci return (__VkType) _obj; \ 138bf215546Sopenharmony_ci } 139bf215546Sopenharmony_ci 140bf215546Sopenharmony_ci/** Define handle cast macros for the given non-dispatchable handle type 141bf215546Sopenharmony_ci * 142bf215546Sopenharmony_ci * For a given `driver_struct`, this defines `driver_struct_to_handle()` and 143bf215546Sopenharmony_ci * `driver_struct_from_handle()` helpers which provide type-safe (as much as 144bf215546Sopenharmony_ci * possible with Vulkan handle types) casts to and from the `driver_struct` 145bf215546Sopenharmony_ci * type. As an added layer of protection, these casts use the provided 146bf215546Sopenharmony_ci * `VkObjectType` to assert that the object is of the correct type when 147bf215546Sopenharmony_ci * running with a debug build. 148bf215546Sopenharmony_ci * 149bf215546Sopenharmony_ci * @param __driver_type The name of the driver struct; it is assumed this is 150bf215546Sopenharmony_ci * the name of a struct type and `struct` will be 151bf215546Sopenharmony_ci * prepended automatically 152bf215546Sopenharmony_ci * 153bf215546Sopenharmony_ci * @param __base The name of the vk_base_object member 154bf215546Sopenharmony_ci * 155bf215546Sopenharmony_ci * @param __VkType The Vulkan object type such as VkImage 156bf215546Sopenharmony_ci * 157bf215546Sopenharmony_ci * @param __VK_TYPE The VkObjectType corresponding to __VkType, such as 158bf215546Sopenharmony_ci * VK_OBJECT_TYPE_IMAGE 159bf215546Sopenharmony_ci */ 160bf215546Sopenharmony_ci#define VK_DEFINE_NONDISP_HANDLE_CASTS(__driver_type, __base, __VkType, __VK_TYPE) \ 161bf215546Sopenharmony_ci static inline struct __driver_type * \ 162bf215546Sopenharmony_ci __driver_type ## _from_handle(__VkType _handle) \ 163bf215546Sopenharmony_ci { \ 164bf215546Sopenharmony_ci struct vk_object_base *base = \ 165bf215546Sopenharmony_ci (struct vk_object_base *)(uintptr_t)_handle; \ 166bf215546Sopenharmony_ci vk_object_base_assert_valid(base, __VK_TYPE); \ 167bf215546Sopenharmony_ci STATIC_ASSERT(offsetof(struct __driver_type, __base) == 0); \ 168bf215546Sopenharmony_ci return (struct __driver_type *)base; \ 169bf215546Sopenharmony_ci } \ 170bf215546Sopenharmony_ci \ 171bf215546Sopenharmony_ci static inline __VkType \ 172bf215546Sopenharmony_ci __driver_type ## _to_handle(struct __driver_type *_obj) \ 173bf215546Sopenharmony_ci { \ 174bf215546Sopenharmony_ci vk_object_base_assert_valid(&_obj->__base, __VK_TYPE); \ 175bf215546Sopenharmony_ci if (_obj != NULL) \ 176bf215546Sopenharmony_ci _obj->__base.client_visible = true; \ 177bf215546Sopenharmony_ci return (__VkType)(uintptr_t) _obj; \ 178bf215546Sopenharmony_ci } 179bf215546Sopenharmony_ci 180bf215546Sopenharmony_ci/** Declares a __driver_type pointer which represents __handle 181bf215546Sopenharmony_ci * 182bf215546Sopenharmony_ci * @param __driver_type The name of the driver struct; it is assumed this is 183bf215546Sopenharmony_ci * the name of a struct type and `struct` will be 184bf215546Sopenharmony_ci * prepended automatically 185bf215546Sopenharmony_ci * 186bf215546Sopenharmony_ci * @param __name The name of the declared pointer 187bf215546Sopenharmony_ci * 188bf215546Sopenharmony_ci * @param __handle The Vulkan object handle with which to initialize 189bf215546Sopenharmony_ci * `__name` 190bf215546Sopenharmony_ci */ 191bf215546Sopenharmony_ci#define VK_FROM_HANDLE(__driver_type, __name, __handle) \ 192bf215546Sopenharmony_ci struct __driver_type *__name = __driver_type ## _from_handle(__handle) 193bf215546Sopenharmony_ci 194bf215546Sopenharmony_ci/* Helpers for vk object (de)allocation and (de)initialization */ 195bf215546Sopenharmony_civoid * 196bf215546Sopenharmony_civk_object_alloc(struct vk_device *device, 197bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc, 198bf215546Sopenharmony_ci size_t size, 199bf215546Sopenharmony_ci VkObjectType vk_obj_type); 200bf215546Sopenharmony_ci 201bf215546Sopenharmony_civoid * 202bf215546Sopenharmony_civk_object_zalloc(struct vk_device *device, 203bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc, 204bf215546Sopenharmony_ci size_t size, 205bf215546Sopenharmony_ci VkObjectType vk_obj_type); 206bf215546Sopenharmony_ci 207bf215546Sopenharmony_cistruct vk_multialloc; 208bf215546Sopenharmony_ci 209bf215546Sopenharmony_civoid * 210bf215546Sopenharmony_civk_object_multialloc(struct vk_device *device, 211bf215546Sopenharmony_ci struct vk_multialloc *ma, 212bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc, 213bf215546Sopenharmony_ci VkObjectType vk_obj_type); 214bf215546Sopenharmony_ci 215bf215546Sopenharmony_civoid * 216bf215546Sopenharmony_civk_object_multizalloc(struct vk_device *device, 217bf215546Sopenharmony_ci struct vk_multialloc *ma, 218bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc, 219bf215546Sopenharmony_ci VkObjectType vk_obj_type); 220bf215546Sopenharmony_ci 221bf215546Sopenharmony_civoid 222bf215546Sopenharmony_civk_object_free(struct vk_device *device, 223bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc, 224bf215546Sopenharmony_ci void *data); 225bf215546Sopenharmony_ci 226bf215546Sopenharmony_ci 227bf215546Sopenharmony_cistruct vk_private_data_slot { 228bf215546Sopenharmony_ci struct vk_object_base base; 229bf215546Sopenharmony_ci uint32_t index; 230bf215546Sopenharmony_ci}; 231bf215546Sopenharmony_ciVK_DEFINE_NONDISP_HANDLE_CASTS(vk_private_data_slot, base, 232bf215546Sopenharmony_ci VkPrivateDataSlot, 233bf215546Sopenharmony_ci VK_OBJECT_TYPE_PRIVATE_DATA_SLOT); 234bf215546Sopenharmony_ci 235bf215546Sopenharmony_ciVkResult 236bf215546Sopenharmony_civk_private_data_slot_create(struct vk_device *device, 237bf215546Sopenharmony_ci const VkPrivateDataSlotCreateInfo* pCreateInfo, 238bf215546Sopenharmony_ci const VkAllocationCallbacks* pAllocator, 239bf215546Sopenharmony_ci VkPrivateDataSlot* pPrivateDataSlot); 240bf215546Sopenharmony_civoid 241bf215546Sopenharmony_civk_private_data_slot_destroy(struct vk_device *device, 242bf215546Sopenharmony_ci VkPrivateDataSlot privateDataSlot, 243bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator); 244bf215546Sopenharmony_ciVkResult 245bf215546Sopenharmony_civk_object_base_set_private_data(struct vk_device *device, 246bf215546Sopenharmony_ci VkObjectType objectType, 247bf215546Sopenharmony_ci uint64_t objectHandle, 248bf215546Sopenharmony_ci VkPrivateDataSlot privateDataSlot, 249bf215546Sopenharmony_ci uint64_t data); 250bf215546Sopenharmony_civoid 251bf215546Sopenharmony_civk_object_base_get_private_data(struct vk_device *device, 252bf215546Sopenharmony_ci VkObjectType objectType, 253bf215546Sopenharmony_ci uint64_t objectHandle, 254bf215546Sopenharmony_ci VkPrivateDataSlot privateDataSlot, 255bf215546Sopenharmony_ci uint64_t *pData); 256bf215546Sopenharmony_ci 257bf215546Sopenharmony_ciconst char * 258bf215546Sopenharmony_civk_object_base_name(struct vk_object_base *obj); 259bf215546Sopenharmony_ci 260bf215546Sopenharmony_ci#ifdef __cplusplus 261bf215546Sopenharmony_ci} 262bf215546Sopenharmony_ci#endif 263bf215546Sopenharmony_ci 264bf215546Sopenharmony_ci#endif /* VK_OBJECT_H */ 265