1 /*
2 * Copyright © 2021 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_physical_device.h"
25
26 #include "vk_common_entrypoints.h"
27 #include "vk_device.h"
28 #include "vk_util.h"
29
30 VkResult
vk_physical_device_init(struct vk_physical_device * pdevice,struct vk_instance * instance,const struct vk_device_extension_table * supported_extensions,const struct vk_features * supported_features,const struct vk_properties * properties,const struct vk_physical_device_dispatch_table * dispatch_table)31 vk_physical_device_init(struct vk_physical_device *pdevice,
32 struct vk_instance *instance,
33 const struct vk_device_extension_table *supported_extensions,
34 const struct vk_features *supported_features,
35 const struct vk_properties *properties,
36 const struct vk_physical_device_dispatch_table *dispatch_table)
37 {
38 memset(pdevice, 0, sizeof(*pdevice));
39 vk_object_base_instance_init(instance, &pdevice->base, VK_OBJECT_TYPE_PHYSICAL_DEVICE);
40 pdevice->instance = instance;
41
42 if (supported_extensions != NULL)
43 pdevice->supported_extensions = *supported_extensions;
44
45 if (supported_features != NULL)
46 pdevice->supported_features = *supported_features;
47
48 if (properties != NULL)
49 pdevice->properties = *properties;
50
51 pdevice->dispatch_table = *dispatch_table;
52
53 /* Add common entrypoints without overwriting driver-provided ones. */
54 vk_physical_device_dispatch_table_from_entrypoints(
55 &pdevice->dispatch_table, &vk_common_physical_device_entrypoints, false);
56
57 /* TODO */
58 pdevice->disk_cache = NULL;
59
60 return VK_SUCCESS;
61 }
62
63 void
vk_physical_device_finish(struct vk_physical_device * physical_device)64 vk_physical_device_finish(struct vk_physical_device *physical_device)
65 {
66 vk_object_base_finish(&physical_device->base);
67 }
68
69 VKAPI_ATTR VkResult VKAPI_CALL
vk_common_EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,uint32_t * pPropertyCount,VkLayerProperties * pProperties)70 vk_common_EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,
71 uint32_t *pPropertyCount,
72 VkLayerProperties *pProperties)
73 {
74 if (pProperties == NULL) {
75 *pPropertyCount = 0;
76 return VK_SUCCESS;
77 }
78
79 /* None supported at this time */
80 return VK_ERROR_LAYER_NOT_PRESENT;
81 }
82
83 VKAPI_ATTR VkResult VKAPI_CALL
vk_common_EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,const char * pLayerName,uint32_t * pPropertyCount,VkExtensionProperties * pProperties)84 vk_common_EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
85 const char *pLayerName,
86 uint32_t *pPropertyCount,
87 VkExtensionProperties *pProperties)
88 {
89 VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice);
90 VK_OUTARRAY_MAKE_TYPED(VkExtensionProperties, out, pProperties, pPropertyCount);
91
92 for (int i = 0; i < VK_DEVICE_EXTENSION_COUNT; i++) {
93 if (!pdevice->supported_extensions.extensions[i])
94 continue;
95
96 #ifdef ANDROID_STRICT
97 if (!vk_android_allowed_device_extensions.extensions[i])
98 continue;
99 #endif
100
101 vk_outarray_append_typed(VkExtensionProperties, &out, prop) {
102 *prop = vk_device_extensions[i];
103 }
104 }
105
106 return vk_outarray_status(&out);
107 }
108
109 VKAPI_ATTR void VKAPI_CALL
vk_common_GetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice,VkPhysicalDeviceFeatures * pFeatures)110 vk_common_GetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice,
111 VkPhysicalDeviceFeatures *pFeatures)
112 {
113 VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice);
114
115 /* Don't zero-init this struct since the driver fills it out entirely */
116 VkPhysicalDeviceFeatures2 features2;
117 features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
118 features2.pNext = NULL;
119
120 pdevice->dispatch_table.GetPhysicalDeviceFeatures2(physicalDevice,
121 &features2);
122 *pFeatures = features2.features;
123 }
124
125 VKAPI_ATTR void VKAPI_CALL
vk_common_GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,VkPhysicalDeviceProperties * pProperties)126 vk_common_GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
127 VkPhysicalDeviceProperties *pProperties)
128 {
129 VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice);
130
131 /* Don't zero-init this struct since the driver fills it out entirely */
132 VkPhysicalDeviceProperties2 props2;
133 props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
134 props2.pNext = NULL;
135
136 pdevice->dispatch_table.GetPhysicalDeviceProperties2(physicalDevice,
137 &props2);
138 *pProperties = props2.properties;
139 }
140
141 VKAPI_ATTR void VKAPI_CALL
vk_common_GetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,uint32_t * pQueueFamilyPropertyCount,VkQueueFamilyProperties * pQueueFamilyProperties)142 vk_common_GetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,
143 uint32_t *pQueueFamilyPropertyCount,
144 VkQueueFamilyProperties *pQueueFamilyProperties)
145 {
146 VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice);
147
148 if (!pQueueFamilyProperties) {
149 pdevice->dispatch_table.GetPhysicalDeviceQueueFamilyProperties2(physicalDevice,
150 pQueueFamilyPropertyCount,
151 NULL);
152 return;
153 }
154
155 STACK_ARRAY(VkQueueFamilyProperties2, props2, *pQueueFamilyPropertyCount);
156
157 for (unsigned i = 0; i < *pQueueFamilyPropertyCount; ++i) {
158 props2[i].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2;
159 props2[i].pNext = NULL;
160 }
161
162 pdevice->dispatch_table.GetPhysicalDeviceQueueFamilyProperties2(physicalDevice,
163 pQueueFamilyPropertyCount,
164 props2);
165
166 for (unsigned i = 0; i < *pQueueFamilyPropertyCount; ++i)
167 pQueueFamilyProperties[i] = props2[i].queueFamilyProperties;
168
169 STACK_ARRAY_FINISH(props2);
170 }
171
172 VKAPI_ATTR void VKAPI_CALL
vk_common_GetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice,VkPhysicalDeviceMemoryProperties * pMemoryProperties)173 vk_common_GetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice,
174 VkPhysicalDeviceMemoryProperties *pMemoryProperties)
175 {
176 VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice);
177
178 /* Don't zero-init this struct since the driver fills it out entirely */
179 VkPhysicalDeviceMemoryProperties2 props2;
180 props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2;
181 props2.pNext = NULL;
182
183 pdevice->dispatch_table.GetPhysicalDeviceMemoryProperties2(physicalDevice,
184 &props2);
185 *pMemoryProperties = props2.memoryProperties;
186 }
187
188 VKAPI_ATTR void VKAPI_CALL
vk_common_GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice,VkFormat format,VkFormatProperties * pFormatProperties)189 vk_common_GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice,
190 VkFormat format,
191 VkFormatProperties *pFormatProperties)
192 {
193 VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice);
194
195 /* Don't zero-init this struct since the driver fills it out entirely */
196 VkFormatProperties2 props2;
197 props2.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
198 props2.pNext = NULL;
199
200 pdevice->dispatch_table.GetPhysicalDeviceFormatProperties2(physicalDevice,
201 format, &props2);
202 *pFormatProperties = props2.formatProperties;
203 }
204
205 VKAPI_ATTR VkResult VKAPI_CALL
vk_common_GetPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice,VkFormat format,VkImageType type,VkImageTiling tiling,VkImageUsageFlags usage,VkImageCreateFlags flags,VkImageFormatProperties * pImageFormatProperties)206 vk_common_GetPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice,
207 VkFormat format,
208 VkImageType type,
209 VkImageTiling tiling,
210 VkImageUsageFlags usage,
211 VkImageCreateFlags flags,
212 VkImageFormatProperties *pImageFormatProperties)
213 {
214 VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice);
215
216 VkPhysicalDeviceImageFormatInfo2 info = {
217 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
218 .format = format,
219 .type = type,
220 .tiling = tiling,
221 .usage = usage,
222 .flags = flags
223 };
224
225 /* Don't zero-init this struct since the driver fills it out entirely */
226 VkImageFormatProperties2 props2;
227 props2.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2;
228 props2.pNext = NULL;
229
230 VkResult result =
231 pdevice->dispatch_table.GetPhysicalDeviceImageFormatProperties2(physicalDevice,
232 &info, &props2);
233 *pImageFormatProperties = props2.imageFormatProperties;
234
235 return result;
236 }
237
238 VKAPI_ATTR void VKAPI_CALL
vk_common_GetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice,VkFormat format,VkImageType type,VkSampleCountFlagBits samples,VkImageUsageFlags usage,VkImageTiling tiling,uint32_t * pNumProperties,VkSparseImageFormatProperties * pProperties)239 vk_common_GetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice,
240 VkFormat format,
241 VkImageType type,
242 VkSampleCountFlagBits samples,
243 VkImageUsageFlags usage,
244 VkImageTiling tiling,
245 uint32_t *pNumProperties,
246 VkSparseImageFormatProperties *pProperties)
247 {
248 VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice);
249
250 VkPhysicalDeviceSparseImageFormatInfo2 info = {
251 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2,
252 .format = format,
253 .type = type,
254 .samples = samples,
255 .usage = usage,
256 .tiling = tiling
257 };
258
259 if (!pProperties) {
260 pdevice->dispatch_table.GetPhysicalDeviceSparseImageFormatProperties2(physicalDevice,
261 &info,
262 pNumProperties,
263 NULL);
264 return;
265 }
266
267 STACK_ARRAY(VkSparseImageFormatProperties2, props2, *pNumProperties);
268
269 for (unsigned i = 0; i < *pNumProperties; ++i) {
270 props2[i].sType = VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2;
271 props2[i].pNext = NULL;
272 }
273
274 pdevice->dispatch_table.GetPhysicalDeviceSparseImageFormatProperties2(physicalDevice,
275 &info,
276 pNumProperties,
277 props2);
278
279 for (unsigned i = 0; i < *pNumProperties; ++i)
280 pProperties[i] = props2[i].properties;
281
282 STACK_ARRAY_FINISH(props2);
283 }
284
285 /* VK_KHR_calibrated_timestamps */
286 VKAPI_ATTR VkResult VKAPI_CALL
vk_common_GetPhysicalDeviceCalibrateableTimeDomainsKHR(VkPhysicalDevice physicalDevice,uint32_t * pTimeDomainCount,VkTimeDomainKHR * pTimeDomains)287 vk_common_GetPhysicalDeviceCalibrateableTimeDomainsKHR(
288 VkPhysicalDevice physicalDevice, uint32_t *pTimeDomainCount,
289 VkTimeDomainKHR *pTimeDomains)
290 {
291 VK_OUTARRAY_MAKE_TYPED(VkTimeDomainKHR, out, pTimeDomains, pTimeDomainCount);
292
293 vk_outarray_append_typed(VkTimeDomainKHR, &out, p)
294 *p = VK_TIME_DOMAIN_DEVICE_KHR;
295
296 const VkTimeDomainKHR host_time_domains[] = {
297 VK_TIME_DOMAIN_CLOCK_MONOTONIC_KHR,
298 VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_KHR,
299 };
300 for (uint32_t i = 0; i < ARRAY_SIZE(host_time_domains); i++) {
301 const VkTimeDomainKHR domain = host_time_domains[i];
302 uint64_t ts;
303 if (vk_device_get_timestamp(NULL, domain, &ts) == VK_SUCCESS) {
304 vk_outarray_append_typed(VkTimeDomainKHR, &out, p)
305 *p = domain;
306 }
307 }
308
309 return vk_outarray_status(&out);
310 }
311
312 /* VK_EXT_tooling_info */
313 VKAPI_ATTR VkResult VKAPI_CALL
vk_common_GetPhysicalDeviceToolProperties(VkPhysicalDevice physicalDevice,uint32_t * pToolCount,VkPhysicalDeviceToolProperties * pToolProperties)314 vk_common_GetPhysicalDeviceToolProperties(VkPhysicalDevice physicalDevice,
315 uint32_t *pToolCount,
316 VkPhysicalDeviceToolProperties *pToolProperties)
317 {
318 VK_OUTARRAY_MAKE_TYPED(VkPhysicalDeviceToolProperties, out, pToolProperties, pToolCount);
319
320 return vk_outarray_status(&out);
321 }
322