1 /*
2  * Copyright © 2020 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 #ifndef VK_OBJECT_H
24 #define VK_OBJECT_H
25 
26 #include <vulkan/vulkan.h>
27 #include <vulkan/vk_icd.h>
28 
29 #include "c11/threads.h"
30 #include "util/macros.h"
31 #include "util/sparse_array.h"
32 
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36 
37 struct hash_table;
38 
39 struct vk_device;
40 
41 struct vk_object_base {
42    VK_LOADER_DATA _loader_data;
43    VkObjectType type;
44 
45    /* For VK_EXT_private_data */
46    struct util_sparse_array private_data;
47 };
48 
49 void vk_object_base_init(UNUSED struct vk_device *device,
50                          struct vk_object_base *base,
51                          UNUSED VkObjectType obj_type);
52 void vk_object_base_finish(UNUSED struct vk_object_base *base);
53 
54 static inline void
vk_object_base_assert_valid(ASSERTED struct vk_object_base * base,ASSERTED VkObjectType obj_type)55 vk_object_base_assert_valid(ASSERTED struct vk_object_base *base,
56                             ASSERTED VkObjectType obj_type)
57 {
58    assert(base == NULL || base->type == obj_type);
59 }
60 
61 static inline struct vk_object_base *
vk_object_base_from_u64_handle(uint64_t handle,VkObjectType obj_type)62 vk_object_base_from_u64_handle(uint64_t handle, VkObjectType obj_type)
63 {
64    struct vk_object_base *base = (struct vk_object_base *)(uintptr_t)handle;
65    vk_object_base_assert_valid(base, obj_type);
66    return base;
67 }
68 
69 
70 struct vk_device {
71    struct vk_object_base base;
72    VkAllocationCallbacks alloc;
73 
74    /* For VK_EXT_private_data */
75    uint32_t private_data_next_index;
76 
77 #ifdef ANDROID
78    mtx_t swapchain_private_mtx;
79    struct hash_table *swapchain_private;
80 #endif
81 };
82 
83 void vk_device_init(struct vk_device *device,
84                     const VkDeviceCreateInfo *pCreateInfo,
85                     const VkAllocationCallbacks *instance_alloc,
86                     const VkAllocationCallbacks *device_alloc);
87 void vk_device_finish(struct vk_device *device);
88 
89 #define VK_DEFINE_HANDLE_CASTS(__driver_type, __base, __VkType, __VK_TYPE) \
90    static inline struct __driver_type *                                    \
91    __driver_type ## _from_handle(__VkType _handle)                         \
92    {                                                                       \
93       struct vk_object_base *base = (struct vk_object_base *)_handle;      \
94       vk_object_base_assert_valid(base, __VK_TYPE);                        \
95       STATIC_ASSERT(offsetof(struct __driver_type, __base) == 0);          \
96       return (struct __driver_type *) base;                                \
97    }                                                                       \
98                                                                            \
99    static inline __VkType                                                  \
100    __driver_type ## _to_handle(struct __driver_type *_obj)                 \
101    {                                                                       \
102       vk_object_base_assert_valid(&_obj->__base, __VK_TYPE);               \
103       return (__VkType) _obj;                                              \
104    }
105 
106 #define VK_DEFINE_NONDISP_HANDLE_CASTS(__driver_type, __base, __VkType, __VK_TYPE) \
107    static inline struct __driver_type *                                    \
108    __driver_type ## _from_handle(__VkType _handle)                         \
109    {                                                                       \
110       struct vk_object_base *base =                                        \
111          (struct vk_object_base *)(uintptr_t)_handle;                      \
112       vk_object_base_assert_valid(base, __VK_TYPE);                        \
113       STATIC_ASSERT(offsetof(struct __driver_type, __base) == 0);          \
114       return (struct __driver_type *)base;                                 \
115    }                                                                       \
116                                                                            \
117    static inline __VkType                                                  \
118    __driver_type ## _to_handle(struct __driver_type *_obj)                 \
119    {                                                                       \
120       vk_object_base_assert_valid(&_obj->__base, __VK_TYPE);               \
121       return (__VkType)(uintptr_t) _obj;                                   \
122    }
123 
124 #define VK_FROM_HANDLE(__driver_type, __name, __handle) \
125    struct __driver_type *__name = __driver_type ## _from_handle(__handle)
126 
127 /* Helpers for vk object (de)allocation and (de)initialization */
128 void *
129 vk_object_alloc(struct vk_device *device,
130                 const VkAllocationCallbacks *alloc,
131                 size_t size,
132                 VkObjectType vk_obj_type);
133 
134 void *
135 vk_object_zalloc(struct vk_device *device,
136                 const VkAllocationCallbacks *alloc,
137                 size_t size,
138                 VkObjectType vk_obj_type);
139 
140 void
141 vk_object_free(struct vk_device *device,
142                const VkAllocationCallbacks *alloc,
143                void *data);
144 
145 
146 struct vk_private_data_slot {
147    struct vk_object_base base;
148    uint32_t index;
149 };
150 VK_DEFINE_NONDISP_HANDLE_CASTS(vk_private_data_slot, base,
151                                VkPrivateDataSlotEXT,
152                                VK_OBJECT_TYPE_PRIVATE_DATA_SLOT_EXT);
153 
154 VkResult
155 vk_private_data_slot_create(struct vk_device *device,
156                             const VkPrivateDataSlotCreateInfoEXT* pCreateInfo,
157                             const VkAllocationCallbacks* pAllocator,
158                             VkPrivateDataSlotEXT* pPrivateDataSlot);
159 void
160 vk_private_data_slot_destroy(struct vk_device *device,
161                              VkPrivateDataSlotEXT privateDataSlot,
162                              const VkAllocationCallbacks *pAllocator);
163 VkResult
164 vk_object_base_set_private_data(struct vk_device *device,
165                                 VkObjectType objectType,
166                                 uint64_t objectHandle,
167                                 VkPrivateDataSlotEXT privateDataSlot,
168                                 uint64_t data);
169 void
170 vk_object_base_get_private_data(struct vk_device *device,
171                                 VkObjectType objectType,
172                                 uint64_t objectHandle,
173                                 VkPrivateDataSlotEXT privateDataSlot,
174                                 uint64_t *pData);
175 
176 #ifdef __cplusplus
177 }
178 #endif
179 
180 #endif /* VK_OBJECT_H */
181