• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 /** Base struct for all Vulkan objects */
42 struct vk_object_base {
43    VK_LOADER_DATA _loader_data;
44 
45    /** Type of this object
46     *
47     * This is used for runtime type checking when casting to and from Vulkan
48     * handle types since compile-time type checking doesn't always work.
49     */
50    VkObjectType type;
51 
52    /** Pointer to the device in which this object exists, if any
53     *
54     * This is NULL for instances and physical devices but should point to a
55     * valid vk_device for almost everything else.  (There are a few WSI
56     * objects that don't inherit from a device.)
57     */
58    struct vk_device *device;
59 
60    /* True if this object is fully constructed and visible to the client */
61    bool client_visible;
62 
63    /* For VK_EXT_private_data */
64    struct util_sparse_array private_data;
65 
66    /* VK_EXT_debug_utils */
67    char *object_name;
68 };
69 
70 /** Initialize a vk_base_object
71  *
72  * @param[in]  device   The vk_device this object was created from or NULL
73  * @param[out] base     The vk_object_base to initialize
74  * @param[in]  obj_type The VkObjectType of the object being initialized
75  */
76 void vk_object_base_init(struct vk_device *device,
77                          struct vk_object_base *base,
78                          VkObjectType obj_type);
79 
80 /** Tear down a vk_object_base
81  *
82  * @param[out] base     The vk_object_base being torn down
83  */
84 void vk_object_base_finish(struct vk_object_base *base);
85 
86 static inline void
vk_object_base_assert_valid(ASSERTED struct vk_object_base * base,ASSERTED VkObjectType obj_type)87 vk_object_base_assert_valid(ASSERTED struct vk_object_base *base,
88                             ASSERTED VkObjectType obj_type)
89 {
90    assert(base == NULL || base->type == obj_type);
91 }
92 
93 static inline struct vk_object_base *
vk_object_base_from_u64_handle(uint64_t handle,VkObjectType obj_type)94 vk_object_base_from_u64_handle(uint64_t handle, VkObjectType obj_type)
95 {
96    struct vk_object_base *base = (struct vk_object_base *)(uintptr_t)handle;
97    vk_object_base_assert_valid(base, obj_type);
98    return base;
99 }
100 
101 /** Define handle cast macros for the given dispatchable handle type
102  *
103  * For a given `driver_struct`, this defines `driver_struct_to_handle()` and
104  * `driver_struct_from_handle()` helpers which provide type-safe (as much as
105  * possible with Vulkan handle types) casts to and from the `driver_struct`
106  * type.  As an added layer of protection, these casts use the provided
107  * `VkObjectType` to assert that the object is of the correct type when
108  * running with a debug build.
109  *
110  * @param __driver_type The name of the driver struct; it is assumed this is
111  *                      the name of a struct type and `struct` will be
112  *                      prepended automatically
113  *
114  * @param __base        The name of the vk_base_object member
115  *
116  * @param __VkType      The Vulkan object type such as VkImage
117  *
118  * @param __VK_TYPE     The VkObjectType corresponding to __VkType, such as
119  *                      VK_OBJECT_TYPE_IMAGE
120  */
121 #define VK_DEFINE_HANDLE_CASTS(__driver_type, __base, __VkType, __VK_TYPE) \
122    static inline struct __driver_type *                                    \
123    __driver_type ## _from_handle(__VkType _handle)                         \
124    {                                                                       \
125       struct vk_object_base *base = (struct vk_object_base *)_handle;      \
126       vk_object_base_assert_valid(base, __VK_TYPE);                        \
127       STATIC_ASSERT(offsetof(struct __driver_type, __base) == 0);          \
128       return (struct __driver_type *) base;                                \
129    }                                                                       \
130                                                                            \
131    static inline __VkType                                                  \
132    __driver_type ## _to_handle(struct __driver_type *_obj)                 \
133    {                                                                       \
134       vk_object_base_assert_valid(&_obj->__base, __VK_TYPE);               \
135       if (_obj != NULL)                                                    \
136          _obj->__base.client_visible = true;                               \
137       return (__VkType) _obj;                                              \
138    }
139 
140 /** Define handle cast macros for the given non-dispatchable handle type
141  *
142  * For a given `driver_struct`, this defines `driver_struct_to_handle()` and
143  * `driver_struct_from_handle()` helpers which provide type-safe (as much as
144  * possible with Vulkan handle types) casts to and from the `driver_struct`
145  * type.  As an added layer of protection, these casts use the provided
146  * `VkObjectType` to assert that the object is of the correct type when
147  * running with a debug build.
148  *
149  * @param __driver_type The name of the driver struct; it is assumed this is
150  *                      the name of a struct type and `struct` will be
151  *                      prepended automatically
152  *
153  * @param __base        The name of the vk_base_object member
154  *
155  * @param __VkType      The Vulkan object type such as VkImage
156  *
157  * @param __VK_TYPE     The VkObjectType corresponding to __VkType, such as
158  *                      VK_OBJECT_TYPE_IMAGE
159  */
160 #define VK_DEFINE_NONDISP_HANDLE_CASTS(__driver_type, __base, __VkType, __VK_TYPE) \
161    static inline struct __driver_type *                                    \
162    __driver_type ## _from_handle(__VkType _handle)                         \
163    {                                                                       \
164       struct vk_object_base *base =                                        \
165          (struct vk_object_base *)(uintptr_t)_handle;                      \
166       vk_object_base_assert_valid(base, __VK_TYPE);                        \
167       STATIC_ASSERT(offsetof(struct __driver_type, __base) == 0);          \
168       return (struct __driver_type *)base;                                 \
169    }                                                                       \
170                                                                            \
171    static inline __VkType                                                  \
172    __driver_type ## _to_handle(struct __driver_type *_obj)                 \
173    {                                                                       \
174       vk_object_base_assert_valid(&_obj->__base, __VK_TYPE);               \
175       if (_obj != NULL)                                                    \
176          _obj->__base.client_visible = true;                               \
177       return (__VkType)(uintptr_t) _obj;                                   \
178    }
179 
180 /** Declares a __driver_type pointer which represents __handle
181  *
182  * @param __driver_type The name of the driver struct; it is assumed this is
183  *                      the name of a struct type and `struct` will be
184  *                      prepended automatically
185  *
186  * @param __name        The name of the declared pointer
187  *
188  * @param __handle      The Vulkan object handle with which to initialize
189  *                      `__name`
190  */
191 #define VK_FROM_HANDLE(__driver_type, __name, __handle) \
192    struct __driver_type *__name = __driver_type ## _from_handle(__handle)
193 
194 /* Helpers for vk object (de)allocation and (de)initialization */
195 void *
196 vk_object_alloc(struct vk_device *device,
197                 const VkAllocationCallbacks *alloc,
198                 size_t size,
199                 VkObjectType vk_obj_type);
200 
201 void *
202 vk_object_zalloc(struct vk_device *device,
203                 const VkAllocationCallbacks *alloc,
204                 size_t size,
205                 VkObjectType vk_obj_type);
206 
207 struct vk_multialloc;
208 
209 void *
210 vk_object_multialloc(struct vk_device *device,
211                      struct vk_multialloc *ma,
212                      const VkAllocationCallbacks *alloc,
213                      VkObjectType vk_obj_type);
214 
215 void *
216 vk_object_multizalloc(struct vk_device *device,
217                       struct vk_multialloc *ma,
218                       const VkAllocationCallbacks *alloc,
219                       VkObjectType vk_obj_type);
220 
221 void
222 vk_object_free(struct vk_device *device,
223                const VkAllocationCallbacks *alloc,
224                void *data);
225 
226 
227 struct vk_private_data_slot {
228    struct vk_object_base base;
229    uint32_t index;
230 };
231 VK_DEFINE_NONDISP_HANDLE_CASTS(vk_private_data_slot, base,
232                                VkPrivateDataSlot,
233                                VK_OBJECT_TYPE_PRIVATE_DATA_SLOT);
234 
235 VkResult
236 vk_private_data_slot_create(struct vk_device *device,
237                             const VkPrivateDataSlotCreateInfo* pCreateInfo,
238                             const VkAllocationCallbacks* pAllocator,
239                             VkPrivateDataSlot* pPrivateDataSlot);
240 void
241 vk_private_data_slot_destroy(struct vk_device *device,
242                              VkPrivateDataSlot privateDataSlot,
243                              const VkAllocationCallbacks *pAllocator);
244 VkResult
245 vk_object_base_set_private_data(struct vk_device *device,
246                                 VkObjectType objectType,
247                                 uint64_t objectHandle,
248                                 VkPrivateDataSlot privateDataSlot,
249                                 uint64_t data);
250 void
251 vk_object_base_get_private_data(struct vk_device *device,
252                                 VkObjectType objectType,
253                                 uint64_t objectHandle,
254                                 VkPrivateDataSlot privateDataSlot,
255                                 uint64_t *pData);
256 
257 const char *
258 vk_object_base_name(struct vk_object_base *obj);
259 
260 #ifdef __cplusplus
261 }
262 #endif
263 
264 #endif /* VK_OBJECT_H */
265