summaryrefslogtreecommitdiff
path: root/src/vulkan/runtime/vk_instance.h
blob: b1ddf6a060a2e376b881c49cd5b6eff3931e903e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
/*
 * Copyright © 2021 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */
#ifndef VK_INSTANCE_H
#define VK_INSTANCE_H

#include "vk_dispatch_table.h"
#include "vk_extensions.h"
#include "vk_object.h"

#include "c11/threads.h"
#include "util/list.h"

#ifdef __cplusplus
extern "C" {
#endif

struct vk_app_info {
   /** VkApplicationInfo::pApplicationName */
   const char*        app_name;

   /** VkApplicationInfo::applicationVersion */
   uint32_t           app_version;

   /** VkApplicationInfo::pEngineName */
   const char*        engine_name;

   /** VkApplicationInfo::engineVersion */
   uint32_t           engine_version;

   /** VkApplicationInfo::apiVersion or `VK_API_VERSION_1_0`
    *
    * If the application does not provide a `pApplicationInfo` or the
    * `apiVersion` field is 0, this is set to `VK_API_VERSION_1_0`.
    */
   uint32_t           api_version;
};

struct _drmDevice;
struct vk_physical_device;

/** Base struct for all `VkInstance` implementations
 *
 * This contains data structures necessary for detecting enabled extensions,
 * handling entrypoint dispatch, and implementing `vkGetInstanceProcAddr()`.
 * It also contains data copied from the `VkInstanceCreateInfo` such as the
 * application information.
 */
struct vk_instance {
   struct vk_object_base base;

   /** Allocator used when creating this instance
    *
    * This is used as a fall-back for when a NULL pAllocator is passed into a
    * device-level create function such as vkCreateImage().
    */
   VkAllocationCallbacks alloc;

   /** VkInstanceCreateInfo::pApplicationInfo */
   struct vk_app_info app_info;

   /** Table of all supported instance extensions
    *
    * This is the static const struct passed by the driver as the
    * `supported_extensions` parameter to `vk_instance_init()`.
    */
   const struct vk_instance_extension_table *supported_extensions;

   /** Table of all enabled instance extensions
    *
    * This is generated automatically as part of `vk_instance_init()` from
    * VkInstanceCreateInfo::ppEnabledExtensionNames.
    */
   struct vk_instance_extension_table enabled_extensions;

   /** Instance-level dispatch table */
   struct vk_instance_dispatch_table dispatch_table;

   /* VK_EXT_debug_report debug callbacks */
   struct {
      mtx_t callbacks_mutex;
      struct list_head callbacks;
   } debug_report;

   /* VK_EXT_debug_utils */
   struct {
      /* These callbacks are only used while creating or destroying an
       * instance
       */
      struct list_head instance_callbacks;
      mtx_t callbacks_mutex;
      /* Persistent callbacks */
      struct list_head callbacks;
   } debug_utils;

   /** List of all physical devices and callbacks
   *
   * This is used for automatic physical device creation,
   * deletion and enumeration.
   */
   struct {
      struct list_head list;
      bool enumerated;

      /** Enumerate physical devices for this instance
       *
       * The driver can implement this callback for custom physical device
       * enumeration. The returned value must be a valid return code of
       * vkEnumeratePhysicalDevices.
       *
       * Note that the loader calls vkEnumeratePhysicalDevices of all
       * installed ICDs and fails device enumeration when any of the calls
       * fails. The driver should return VK_SUCCESS when it does not find any
       * compatible device.
       *
       * If this callback is not set, try_create_for_drm will be used for
       * enumeration.
       */
      VkResult (*enumerate)(struct vk_instance *instance);

      /** Try to create a physical device for a drm device
       *
       * The returned value must be a valid return code of
       * vkEnumeratePhysicalDevices, or VK_ERROR_INCOMPATIBLE_DRIVER. When
       * VK_ERROR_INCOMPATIBLE_DRIVER is returned, the error and the drm
       * device are silently ignored.
       */
      VkResult (*try_create_for_drm)(struct vk_instance *instance,
                                     struct _drmDevice *device,
                                     struct vk_physical_device **out);

      /** Handle the destruction of a physical device
       *
       * This callback has to be implemented when using common physical device
       * management. The device pointer and any resource allocated for the
       * device should be freed here.
       */
      void (*destroy)(struct vk_physical_device *pdevice);

      mtx_t mutex;
   } physical_devices;
};

VK_DEFINE_HANDLE_CASTS(vk_instance, base, VkInstance,
                       VK_OBJECT_TYPE_INSTANCE);

/** Initialize a vk_instance
 *
 * Along with initializing the data structures in `vk_instance`, this function
 * validates the Vulkan version number provided by the client and checks that
 * every extension specified by
 * `VkInstanceCreateInfo::ppEnabledExtensionNames` is actually supported by
 * the implementation and returns `VK_ERROR_EXTENSION_NOT_PRESENT` if an
 * unsupported extension is requested.
 *
 * @param[out] instance             The instance to initialize
 * @param[in]  supported_extensions Table of all instance extensions supported
 *                                  by this instance
 * @param[in]  dispatch_table       Instance-level dispatch table
 * @param[in]  pCreateInfo          VkInstanceCreateInfo pointer passed to
 *                                  `vkCreateInstance()`
 * @param[in]  alloc                Allocation callbacks used to create this
 *                                  instance; must not be `NULL`
 */
VkResult MUST_CHECK
vk_instance_init(struct vk_instance *instance,
                 const struct vk_instance_extension_table *supported_extensions,
                 const struct vk_instance_dispatch_table *dispatch_table,
                 const VkInstanceCreateInfo *pCreateInfo,
                 const VkAllocationCallbacks *alloc);

/** Tears down a vk_instance
 *
 * @param[out] instance             The instance to tear down
 */
void
vk_instance_finish(struct vk_instance *instance);

/** Implementaiton of vkEnumerateInstanceExtensionProperties() */
VkResult
vk_enumerate_instance_extension_properties(
    const struct vk_instance_extension_table *supported_extensions,
    uint32_t *pPropertyCount,
    VkExtensionProperties *pProperties);

/** Implementaiton of vkGetInstanceProcAddr() */
PFN_vkVoidFunction
vk_instance_get_proc_addr(const struct vk_instance *instance,
                          const struct vk_instance_entrypoint_table *entrypoints,
                          const char *name);

/** Unchecked version of vk_instance_get_proc_addr
 *
 * This is identical to `vk_instance_get_proc_addr()` except that it doesn't
 * check whether extensions are enabled before returning function pointers.
 * This is useful in window-system code where we may use extensions without
 * the client explicitly enabling them.
 */
PFN_vkVoidFunction
vk_instance_get_proc_addr_unchecked(const struct vk_instance *instance,
                                    const char *name);

/** Implementaiton of vk_icdGetPhysicalDeviceProcAddr() */
PFN_vkVoidFunction
vk_instance_get_physical_device_proc_addr(const struct vk_instance *instance,
                                          const char *name);

#ifdef __cplusplus
}
#endif

#endif /* VK_INSTANCE_H */