anv,vulkan: Implement VK_EXT_private_data
[mesa.git] / src / vulkan / util / vk_object.c
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
24 #include "vk_object.h"
25
26 #include "vk_alloc.h"
27
28 void
29 vk_object_base_init(UNUSED struct vk_device *device,
30 struct vk_object_base *base,
31 UNUSED VkObjectType obj_type)
32 {
33 base->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
34 base->type = obj_type;
35 util_sparse_array_init(&base->private_data, sizeof(uint64_t), 8);
36 }
37
38 void
39 vk_object_base_finish(struct vk_object_base *base)
40 {
41 util_sparse_array_finish(&base->private_data);
42 }
43
44 void
45 vk_device_init(struct vk_device *device,
46 UNUSED const VkDeviceCreateInfo *pCreateInfo,
47 const VkAllocationCallbacks *instance_alloc,
48 const VkAllocationCallbacks *device_alloc)
49 {
50 vk_object_base_init(device, &device->base, VK_OBJECT_TYPE_DEVICE);
51 if (device_alloc)
52 device->alloc = *device_alloc;
53 else
54 device->alloc = *instance_alloc;
55
56 p_atomic_set(&device->private_data_next_index, 0);
57 }
58
59 void
60 vk_device_finish(UNUSED struct vk_device *device)
61 {
62 vk_object_base_finish(&device->base);
63 }
64
65 VkResult
66 vk_private_data_slot_create(struct vk_device *device,
67 const VkPrivateDataSlotCreateInfoEXT* pCreateInfo,
68 const VkAllocationCallbacks* pAllocator,
69 VkPrivateDataSlotEXT* pPrivateDataSlot)
70 {
71 struct vk_private_data_slot *slot =
72 vk_alloc2(&device->alloc, pAllocator, sizeof(*slot), 8,
73 VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
74 if (slot == NULL)
75 return VK_ERROR_OUT_OF_HOST_MEMORY;
76
77 vk_object_base_init(device, &slot->base,
78 VK_OBJECT_TYPE_PRIVATE_DATA_SLOT_EXT);
79 slot->index = p_atomic_inc_return(&device->private_data_next_index);
80
81 *pPrivateDataSlot = vk_private_data_slot_to_handle(slot);
82
83 return VK_SUCCESS;
84 }
85
86 void
87 vk_private_data_slot_destroy(struct vk_device *device,
88 VkPrivateDataSlotEXT privateDataSlot,
89 const VkAllocationCallbacks *pAllocator)
90 {
91 VK_FROM_HANDLE(vk_private_data_slot, slot, privateDataSlot);
92 if (slot == NULL)
93 return;
94
95 vk_object_base_finish(&slot->base);
96 vk_free2(&device->alloc, pAllocator, slot);
97 }
98
99 static uint64_t *
100 vk_object_base_private_data(VkObjectType objectType,
101 uint64_t objectHandle,
102 VkPrivateDataSlotEXT privateDataSlot)
103 {
104 VK_FROM_HANDLE(vk_private_data_slot, slot, privateDataSlot);
105 struct vk_object_base *obj =
106 vk_object_base_from_u64_handle(objectHandle, objectType);
107 return util_sparse_array_get(&obj->private_data, slot->index);
108 }
109
110 VkResult
111 vk_object_base_set_private_data(struct vk_device *device,
112 VkObjectType objectType,
113 uint64_t objectHandle,
114 VkPrivateDataSlotEXT privateDataSlot,
115 uint64_t data)
116 {
117 uint64_t *private_data =
118 vk_object_base_private_data(objectType, objectHandle, privateDataSlot);
119 *private_data = data;
120 return VK_SUCCESS;
121 }
122
123 void
124 vk_object_base_get_private_data(struct vk_device *device,
125 VkObjectType objectType,
126 uint64_t objectHandle,
127 VkPrivateDataSlotEXT privateDataSlot,
128 uint64_t *pData)
129 {
130 uint64_t *private_data =
131 vk_object_base_private_data(objectType, objectHandle, privateDataSlot);
132 *pData = *private_data;
133 }