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
34extern "C" {
35#endif
36
37struct hash_table;
38
39struct vk_device;
40
41struct vk_object_base {
42   VK_LOADER_DATA _loader_data;
43   VkObjectType type;
44
45   struct vk_device *device;
46
47   /* True if this object is fully constructed and visible to the client */
48   bool client_visible;
49
50   /* For VK_EXT_private_data */
51   struct util_sparse_array private_data;
52
53   /* VK_EXT_debug_utils */
54   char *object_name;
55};
56
57void vk_object_base_init(UNUSED struct vk_device *device,
58                         struct vk_object_base *base,
59                         UNUSED VkObjectType obj_type);
60void vk_object_base_finish(UNUSED struct vk_object_base *base);
61
62static inline void
63vk_object_base_assert_valid(ASSERTED struct vk_object_base *base,
64                            ASSERTED VkObjectType obj_type)
65{
66   assert(base == NULL || base->type == obj_type);
67}
68
69static inline struct vk_object_base *
70vk_object_base_from_u64_handle(uint64_t handle, VkObjectType obj_type)
71{
72   struct vk_object_base *base = (struct vk_object_base *)(uintptr_t)handle;
73   vk_object_base_assert_valid(base, obj_type);
74   return base;
75}
76
77#define VK_DEFINE_HANDLE_CASTS(__driver_type, __base, __VkType, __VK_TYPE) \
78   static inline struct __driver_type *                                    \
79   __driver_type ## _from_handle(__VkType _handle)                         \
80   {                                                                       \
81      struct vk_object_base *base = (struct vk_object_base *)_handle;      \
82      vk_object_base_assert_valid(base, __VK_TYPE);                        \
83      STATIC_ASSERT(offsetof(struct __driver_type, __base) == 0);          \
84      return (struct __driver_type *) base;                                \
85   }                                                                       \
86                                                                           \
87   static inline __VkType                                                  \
88   __driver_type ## _to_handle(struct __driver_type *_obj)                 \
89   {                                                                       \
90      vk_object_base_assert_valid(&_obj->__base, __VK_TYPE);               \
91      if (_obj != NULL)                                                    \
92         _obj->__base.client_visible = true;                               \
93      return (__VkType) _obj;                                              \
94   }
95
96#define VK_DEFINE_NONDISP_HANDLE_CASTS(__driver_type, __base, __VkType, __VK_TYPE) \
97   static inline struct __driver_type *                                    \
98   __driver_type ## _from_handle(__VkType _handle)                         \
99   {                                                                       \
100      struct vk_object_base *base =                                        \
101         (struct vk_object_base *)(uintptr_t)_handle;                      \
102      vk_object_base_assert_valid(base, __VK_TYPE);                        \
103      STATIC_ASSERT(offsetof(struct __driver_type, __base) == 0);          \
104      return (struct __driver_type *)base;                                 \
105   }                                                                       \
106                                                                           \
107   static inline __VkType                                                  \
108   __driver_type ## _to_handle(struct __driver_type *_obj)                 \
109   {                                                                       \
110      vk_object_base_assert_valid(&_obj->__base, __VK_TYPE);               \
111      if (_obj != NULL)                                                    \
112         _obj->__base.client_visible = true;                               \
113      return (__VkType)(uintptr_t) _obj;                                   \
114   }
115
116#define VK_FROM_HANDLE(__driver_type, __name, __handle) \
117   struct __driver_type *__name = __driver_type ## _from_handle(__handle)
118
119/* Helpers for vk object (de)allocation and (de)initialization */
120void *
121vk_object_alloc(struct vk_device *device,
122                const VkAllocationCallbacks *alloc,
123                size_t size,
124                VkObjectType vk_obj_type);
125
126void *
127vk_object_zalloc(struct vk_device *device,
128                const VkAllocationCallbacks *alloc,
129                size_t size,
130                VkObjectType vk_obj_type);
131
132struct vk_multialloc;
133
134void *
135vk_object_multialloc(struct vk_device *device,
136                     struct vk_multialloc *ma,
137                     const VkAllocationCallbacks *alloc,
138                     VkObjectType vk_obj_type);
139
140void *
141vk_object_multizalloc(struct vk_device *device,
142                      struct vk_multialloc *ma,
143                      const VkAllocationCallbacks *alloc,
144                      VkObjectType vk_obj_type);
145
146void
147vk_object_free(struct vk_device *device,
148               const VkAllocationCallbacks *alloc,
149               void *data);
150
151
152struct vk_private_data_slot {
153   struct vk_object_base base;
154   uint32_t index;
155};
156VK_DEFINE_NONDISP_HANDLE_CASTS(vk_private_data_slot, base,
157                               VkPrivateDataSlotEXT,
158                               VK_OBJECT_TYPE_PRIVATE_DATA_SLOT_EXT);
159
160VkResult
161vk_private_data_slot_create(struct vk_device *device,
162                            const VkPrivateDataSlotCreateInfoEXT* pCreateInfo,
163                            const VkAllocationCallbacks* pAllocator,
164                            VkPrivateDataSlotEXT* pPrivateDataSlot);
165void
166vk_private_data_slot_destroy(struct vk_device *device,
167                             VkPrivateDataSlotEXT privateDataSlot,
168                             const VkAllocationCallbacks *pAllocator);
169VkResult
170vk_object_base_set_private_data(struct vk_device *device,
171                                VkObjectType objectType,
172                                uint64_t objectHandle,
173                                VkPrivateDataSlotEXT privateDataSlot,
174                                uint64_t data);
175void
176vk_object_base_get_private_data(struct vk_device *device,
177                                VkObjectType objectType,
178                                uint64_t objectHandle,
179                                VkPrivateDataSlotEXT privateDataSlot,
180                                uint64_t *pData);
181
182const char *
183vk_object_base_name(struct vk_object_base *obj);
184
185#ifdef __cplusplus
186}
187#endif
188
189#endif /* VK_OBJECT_H */
190