Create very primitive physical device and instance.
[mesa.git] / src / libre-soc / vulkan / libresoc_device.c
1 /*
2 * Copyright © 2019 Raspberry Pi
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 <assert.h>
25 #include <stdbool.h>
26 #include <string.h>
27 #include <sys/mman.h>
28 #include <sys/sysinfo.h>
29 #include <unistd.h>
30
31 #include "libresoc_private.h"
32 #include "vk_util.h"
33 #include "vk_alloc.h"
34
35 VkResult
36 libresoc_EnumerateInstanceExtensionProperties(const char *pLayerName,
37 uint32_t *pPropertyCount,
38 VkExtensionProperties *pProperties)
39 {
40 if (getenv("LIBRESOC_TRACE")) {
41 fprintf(stderr, "EnumerateInstanceExtensionProperties called for: %s \n", pLayerName);
42 }
43 VK_OUTARRAY_MAKE(out, pProperties, pPropertyCount);
44
45 for (int i = 0; i < LIBRESOC_INSTANCE_EXTENSION_COUNT; i++) {
46 if (libresoc_instance_extensions_supported.extensions[i]) {
47 vk_outarray_append(&out, prop) {
48 *prop = libresoc_instance_extensions[i];
49 }
50 }
51 }
52
53 return vk_outarray_status(&out);
54 }
55
56 static void *
57 default_alloc_func(void *pUserData, size_t size, size_t align,
58 VkSystemAllocationScope allocationScope)
59 {
60 return malloc(size);
61 }
62
63 static void *
64 default_realloc_func(void *pUserData, void *pOriginal, size_t size,
65 size_t align, VkSystemAllocationScope allocationScope)
66 {
67 return realloc(pOriginal, size);
68 }
69
70 static void
71 default_free_func(void *pUserData, void *pMemory)
72 {
73 free(pMemory);
74 }
75
76 static const VkAllocationCallbacks default_alloc = {
77 .pUserData = NULL,
78 .pfnAllocation = default_alloc_func,
79 .pfnReallocation = default_realloc_func,
80 .pfnFree = default_free_func,
81 };
82
83 VkResult
84 libresoc_CreateInstance(const VkInstanceCreateInfo *pCreateInfo,
85 const VkAllocationCallbacks *pAllocator,
86 VkInstance *pInstance)
87 {
88 if (getenv("LIBRESOC_TRACE")) {
89 fprintf(stderr, "CreateInstance called. \n");
90 }
91 struct libresoc_instance *instance;
92
93 instance = vk_zalloc2(&default_alloc, pAllocator, sizeof(*instance), 8,
94 VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
95 if (!instance)
96 return vk_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY);
97
98 vk_object_base_init(NULL, &instance->base, VK_OBJECT_TYPE_INSTANCE);
99
100 if (pAllocator)
101 instance->alloc = *pAllocator;
102 else
103 instance->alloc = default_alloc;
104 /*TODO : enable extensions*/
105 *pInstance = libresoc_instance_to_handle(instance);
106
107 return VK_SUCCESS;
108 }
109
110 void
111 libresoc_DestroyInstance(VkInstance _instance,
112 const VkAllocationCallbacks *pAllocator)
113 {
114 if (getenv("LIBRESOC_TRACE")) {
115 fprintf(stderr, "DestroyInstance called. \n");
116 }
117 /* FIXME: stub */
118 }
119
120 static VkResult
121 libresoc_physical_device_try_create(struct libresoc_instance *instance,
122 struct libresoc_physical_device **device_out)
123 {
124 VkResult result;
125
126 struct libresoc_physical_device *device =
127 vk_zalloc2(&instance->alloc, NULL, sizeof(*device), 8,
128 VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
129 if (!device) {
130 result = vk_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY);
131 return result;
132 }
133
134 device->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
135 device->instance = instance;
136
137 *device_out = device;
138
139 return VK_SUCCESS;
140
141 }
142 static VkResult
143 libresoc_enumerate_physical_devices(struct libresoc_instance *instance)
144 {
145
146 VkResult result = VK_SUCCESS;
147 /* the driver creates a null
148 * device that allows to test the compiler without having a physical device
149 */
150 struct libresoc_physical_device *pdevice;
151
152 result = libresoc_physical_device_try_create(instance, &pdevice);
153 return result;
154
155 }
156
157 VkResult
158 libresoc_EnumeratePhysicalDevices(VkInstance _instance,
159 uint32_t *pPhysicalDeviceCount,
160 VkPhysicalDevice *pPhysicalDevices)
161 {
162 if (getenv("LIBRESOC_TRACE")) {
163 fprintf(stderr, "EnumeratePhysicalDevices called\n");
164 }
165 LIBRESOC_FROM_HANDLE(libresoc_instance, instance, _instance);
166 VK_OUTARRAY_MAKE(out, pPhysicalDevices, pPhysicalDeviceCount);
167
168 VkResult result = libresoc_enumerate_physical_devices(instance);
169 if (result != VK_SUCCESS)
170 return result;
171
172 vk_outarray_append(&out, i) {
173 *i = libresoc_physical_device_to_handle(&instance->physical_device);
174 }
175
176 return vk_outarray_status(&out);
177 /* FIXME: stub */
178 return VK_SUCCESS;
179 }
180
181 void
182 libresoc_GetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice,
183 VkPhysicalDeviceFeatures *pFeatures)
184 {
185 if (getenv("LIBRESOC_TRACE")) {
186 fprintf(stderr, "GetPhysicalDeviceFeatures called. \n");
187 }
188 /* FIXME: stub */
189 }
190
191 void
192 libresoc_GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
193 VkPhysicalDeviceProperties *pProperties)
194 {
195 if (getenv("LIBRESOC_TRACE")) {
196 fprintf(stderr, "GetPhysicalDeviceProperties called. \n");
197 }
198 /* FIXME: stub */
199 }
200
201 void
202 libresoc_GetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,
203 uint32_t *pCount,
204 VkQueueFamilyProperties *pQueueFamilyProperties)
205 {
206 if (getenv("LIBRESOC_TRACE")) {
207 fprintf(stderr, "GetPhysicalDeviceQueueFamilyProperites called. \n");
208 }
209 /* FIXME: stub */
210 }
211
212 void
213 libresoc_GetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice,
214 VkPhysicalDeviceMemoryProperties *pMemoryProperties)
215 {
216 if (getenv("LIBRESOC_TRACE")) {
217 fprintf(stderr, "GetPhysicalDEviceMemoryProperties called. \n");
218 }
219 /* FIXME: stub */
220 }
221
222 void
223 libresoc_GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties *pFormatProperties) {
224
225 if (getenv("LIBRESOC_TRACE")) {
226 fprintf(stderr, "GetPhysicalDeviceFormatProperties called. \n");
227 }
228 /* FIXME: stub */
229 }
230
231 VkResult
232 libresoc_GetPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkImageFormatProperties* pImageFormatProperties)
233 {
234 if (getenv("LIBRESOC_TRACE")) {
235 fprintf(stderr, "GetPhysicalDEviceImageFormatProperties called. \n");
236 }
237
238 /* FIXME: stub */
239 return VK_SUCCESS;
240 }
241 void
242 libresoc_GetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling, uint32_t* pPropertyCount, VkSparseImageFormatProperties* pProperties)
243 {
244 if (getenv("LIBRESOC_TRACE")) {
245 fprintf(stderr, "GetPhysicalDeviceSparseImageFormatProperties called. \n");
246 }
247 /* FIXME: stub */
248 }
249 PFN_vkVoidFunction
250 libresoc_GetInstanceProcAddr(VkInstance _instance,
251 const char *pName)
252 {
253 if (getenv("LIBRESOC_TRACE")) {
254 fprintf(stderr, "GetInstanceProcAddr called for: %s \n", pName);
255 }
256 LIBRESOC_FROM_HANDLE(libresoc_instance, instance, _instance);
257
258 /* The Vulkan 1.0 spec for vkGetInstanceProcAddr has a table of exactly
259 * when we have to return valid function pointers, NULL, or it's left
260 * undefined. See the table for exact details.
261 */
262 if (pName == NULL)
263 return NULL;
264
265 #define LOOKUP_LIBRESOC_ENTRYPOINT(entrypoint) \
266 if (strcmp(pName, "vk" #entrypoint) == 0) \
267 return (PFN_vkVoidFunction)libresoc_##entrypoint
268
269 LOOKUP_LIBRESOC_ENTRYPOINT(EnumerateInstanceExtensionProperties);
270 LOOKUP_LIBRESOC_ENTRYPOINT(CreateInstance);
271 LOOKUP_LIBRESOC_ENTRYPOINT(DestroyInstance);
272 LOOKUP_LIBRESOC_ENTRYPOINT(EnumeratePhysicalDevices);
273 LOOKUP_LIBRESOC_ENTRYPOINT(GetPhysicalDeviceFeatures);
274 LOOKUP_LIBRESOC_ENTRYPOINT(GetPhysicalDeviceFormatProperties);
275 LOOKUP_LIBRESOC_ENTRYPOINT(GetPhysicalDeviceImageFormatProperties);
276 LOOKUP_LIBRESOC_ENTRYPOINT(GetPhysicalDeviceProperties);
277 LOOKUP_LIBRESOC_ENTRYPOINT(GetPhysicalDeviceQueueFamilyProperties);
278 LOOKUP_LIBRESOC_ENTRYPOINT(GetPhysicalDeviceMemoryProperties);
279 LOOKUP_LIBRESOC_ENTRYPOINT(GetDeviceProcAddr);
280 LOOKUP_LIBRESOC_ENTRYPOINT(CreateDevice);
281 LOOKUP_LIBRESOC_ENTRYPOINT(EnumerateDeviceExtensionProperties);
282 LOOKUP_LIBRESOC_ENTRYPOINT(GetPhysicalDeviceSparseImageFormatProperties);
283
284
285 #undef LOOKUP_LIBRESOC_ENTRYPOINT
286
287 if (instance == NULL)
288 return NULL;
289
290 int idx = libresoc_get_instance_entrypoint_index(pName);
291 if (idx >= 0)
292 return instance->dispatch.entrypoints[idx];
293
294 idx = libresoc_get_physical_device_entrypoint_index(pName);
295 if (idx >= 0)
296 return instance->physical_device.dispatch.entrypoints[idx];
297
298 idx = libresoc_get_device_entrypoint_index(pName);
299 if (idx >= 0)
300 return instance->device_dispatch.entrypoints[idx];
301
302 return NULL;
303 }
304
305 /* With version 1+ of the loader interface the ICD should expose
306 * vk_icdGetInstanceProcAddr to work around certain LD_PRELOAD issues seen in apps.
307 */
308 PUBLIC
309 VKAPI_ATTR PFN_vkVoidFunction
310 VKAPI_CALL vk_icdGetInstanceProcAddr(VkInstance instance,
311 const char *pName);
312
313 PUBLIC
314 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
315 vk_icdGetInstanceProcAddr(VkInstance instance,
316 const char* pName)
317 {
318 if (getenv("LIBRESOC_TRACE")) {
319 fprintf(stderr, "vk_icdGetInstanceProcAddr called for: %s \n", pName);
320 }
321 return libresoc_GetInstanceProcAddr(instance, pName);
322 }
323
324 PFN_vkVoidFunction
325 libresoc_GetDeviceProcAddr(VkDevice _device,
326 const char *pName)
327 {
328 if (getenv("LIBRESOC_TRACE")) {
329 fprintf(stderr, "GetDeviceProcAddr called for: %s \n", pName);
330 }
331 LIBRESOC_FROM_HANDLE(libresoc_device, device, _device);
332
333 if (!device || !pName)
334 return NULL;
335
336 int idx = libresoc_get_device_entrypoint_index(pName);
337 if (idx < 0)
338 return NULL;
339
340 return device->dispatch.entrypoints[idx];
341 }
342
343 /* With version 4+ of the loader interface the ICD should expose
344 * vk_icdGetPhysicalDeviceProcAddr()
345 */
346 PUBLIC
347 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
348 vk_icdGetPhysicalDeviceProcAddr(VkInstance _instance,
349 const char* pName);
350
351 PFN_vkVoidFunction
352 vk_icdGetPhysicalDeviceProcAddr(VkInstance _instance,
353 const char* pName)
354 {
355 if (getenv("LIBRESOC_TRACE")) {
356 fprintf(stderr, "vk_icdGetPhysicalDeviceProcAddr called for: %s \n", pName);
357 }
358 LIBRESOC_FROM_HANDLE(libresoc_instance, instance, _instance);
359
360 if (!pName || !instance)
361 return NULL;
362
363 int idx = libresoc_get_physical_device_entrypoint_index(pName);
364 if (idx < 0)
365 return NULL;
366
367 return instance->physical_device.dispatch.entrypoints[idx];
368 }
369
370 VkResult
371 libresoc_EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
372 const char *pLayerName,
373 uint32_t *pPropertyCount,
374 VkExtensionProperties *pProperties)
375 {
376 if (getenv("LIBRESOC_TRACE")) {
377 fprintf(stderr, "EnumerateDeviceExtensionProperties called for layer: %s \n", pLayerName);
378 }
379 /* FIXME: stub */
380 return VK_SUCCESS;
381 }
382
383 VkResult
384 libresoc_CreateDevice(VkPhysicalDevice physicalDevice,
385 const VkDeviceCreateInfo *pCreateInfo,
386 const VkAllocationCallbacks *pAllocator,
387 VkDevice *pDevice)
388 {
389 if (getenv("LIBRESOC_TRACE")) {
390 fprintf(stderr, "CreateDevice called \n");
391 }
392 /* FIXME: stub */
393 return VK_SUCCESS;
394 }
395
396 void
397 libresoc_DestroyDevice(VkDevice _device,
398 const VkAllocationCallbacks *pAllocator)
399 {
400 if (getenv("LIBRESOC_TRACE")) {
401 fprintf(stderr, "DestroyDevice called. \n");
402 }
403 /* FIXME: stub */
404 }
405
406 void
407 libresoc_GetDeviceQueue(VkDevice _device,
408 uint32_t queueNodeIndex,
409 uint32_t queueIndex,
410 VkQueue *pQueue)
411 {
412 if (getenv("LIBRESOC_TRACE")) {
413 fprintf(stderr, "GetDeviceQueue called. \n");
414 }
415 /* FIXME: stub */
416 }