Making SWAPChain exntesions work.
[mesa.git] / src / libre-soc / vulkan / libresoc_private.h
1 /*
2 * Copyright © 2019 Raspberry Pi
3 *
4 * based in part on anv driver which is:
5 * Copyright © 2015 Intel Corporation
6 *
7 * based in part on libresoc driver which is:
8 * Copyright © 2016 Red Hat.
9 * Copyright © 2016 Bas Nieuwenhuizen
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a
12 * copy of this software and associated documentation files (the "Software"),
13 * to deal in the Software without restriction, including without limitation
14 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 * and/or sell copies of the Software, and to permit persons to whom the
16 * Software is furnished to do so, subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice (including the next
19 * paragraph) shall be included in all copies or substantial portions of the
20 * Software.
21 *
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
28 * IN THE SOFTWARE.
29 */
30 #ifndef LIBRESOC_PRIVATE_H
31 #define LIBRESOC_PRIVATE_H
32
33 #include <stdio.h>
34 #include <string.h>
35 #include <vulkan/vulkan.h>
36 #include <vulkan/vk_icd.h>
37
38 #include "vk_alloc.h"
39 #include "vk_debug_report.h"
40 #include "util/xmlconfig.h"
41 #include "compiler/shader_enums.h"
42
43 #include "vk_object.h"
44 #include "libresoc_entrypoints.h"
45 #include "libresoc_extensions.h"
46 #include "libresoc_constants.h"
47 #include "libresoc_debug.h"
48
49 #include "wsi_common.h"
50 #define LIBRESOC_MAX_QUEUE_FAMILIES 1
51
52 static inline uint32_t
53 align_u32(uint32_t v, uint32_t a)
54 {
55 assert(a != 0 && a == (a & -a));
56 return (v + a - 1) & ~(a - 1);
57 }
58
59 static inline uint32_t
60 align_u32_npot(uint32_t v, uint32_t a)
61 {
62 return (v + a - 1) / a * a;
63 }
64
65 static inline uint64_t
66 align_u64(uint64_t v, uint64_t a)
67 {
68 assert(a != 0 && a == (a & -a));
69 return (v + a - 1) & ~(a - 1);
70 }
71
72 static inline int32_t
73 align_i32(int32_t v, int32_t a)
74 {
75 assert(a != 0 && a == (a & -a));
76 return (v + a - 1) & ~(a - 1);
77 }
78
79 /** Alignment must be a power of 2. */
80 static inline bool
81 libresoc_is_aligned(uintmax_t n, uintmax_t a)
82 {
83 assert(a == (a & -a));
84 return (n & (a - 1)) == 0;
85 }
86
87 static inline uint32_t
88 round_up_u32(uint32_t v, uint32_t a)
89 {
90 return (v + a - 1) / a;
91 }
92
93 static inline uint64_t
94 round_up_u64(uint64_t v, uint64_t a)
95 {
96 return (v + a - 1) / a;
97 }
98
99 static inline uint32_t
100 libresoc_minify(uint32_t n, uint32_t levels)
101 {
102 if (unlikely(n == 0))
103 return 0;
104 else
105 return MAX2(n >> levels, 1);
106 }
107 static inline float
108 libresoc_clamp_f(float f, float min, float max)
109 {
110 assert(min < max);
111
112 if (f > max)
113 return max;
114 else if (f < min)
115 return min;
116 else
117 return f;
118 }
119
120 static inline bool
121 libresoc_clear_mask(uint32_t *inout_mask, uint32_t clear_mask)
122 {
123 if (*inout_mask & clear_mask) {
124 *inout_mask &= ~clear_mask;
125 return true;
126 } else {
127 return false;
128 }
129 }
130
131 struct libresoc_fence {
132 struct vk_object_base base;
133 };
134
135 struct libresoc_image_create_info {
136 const VkImageCreateInfo *vk_info;
137 bool scanout;
138 bool no_metadata_planes;
139 };
140
141 struct libresoc_image {
142 struct vk_object_base base;
143 VkImageType type;
144 /* The original VkFormat provided by the client. This may not match any
145 * of the actual surface formats.
146 */
147 VkFormat vk_format;
148 VkImageAspectFlags aspects;
149 VkImageUsageFlags usage; /**< Superset of VkImageCreateInfo::usage. */
150 VkImageTiling tiling; /** VkImageCreateInfo::tiling */
151 VkImageCreateFlags flags; /** VkImageCreateInfo::flags */
152
153 VkDeviceSize size;
154 uint32_t alignment;
155
156 unsigned queue_family_mask;
157 bool exclusive;
158 bool shareable;
159
160 };
161
162 VkResult libresoc_image_create(VkDevice _device,
163 const struct libresoc_image_create_info *info,
164 const VkAllocationCallbacks* alloc,
165 VkImage *pImage);
166
167 struct libresoc_cmd_pool {
168 struct vk_object_base base;
169 VkAllocationCallbacks alloc;
170 struct list_head cmd_buffers;
171 struct list_head free_cmd_buffers;
172 uint32_t queue_family_index;
173 };
174
175 struct libresoc_semaphore {
176 struct vk_object_base base;
177 };
178
179 struct libresoc_instance;
180 struct libresoc_device;
181 struct cache_entry;
182
183 struct libresoc_pipeline_cache {
184 struct vk_object_base base;
185 struct libresoc_device * device;
186 pthread_mutex_t mutex;
187 VkPipelineCacheCreateFlags flags;
188
189 uint32_t total_size;
190 uint32_t table_size;
191 uint32_t kernel_count;
192 struct cache_entry ** hash_table;
193 bool modified;
194
195 VkAllocationCallbacks alloc;
196 };
197
198
199 struct libresoc_shader_binary;
200 struct libresoc_shader_variant;
201
202 void
203 libresoc_pipeline_cache_init(struct libresoc_pipeline_cache *cache,
204 struct libresoc_device *device);
205 void
206 libresoc_pipeline_cache_finish(struct libresoc_pipeline_cache *cache);
207 bool
208 libresoc_pipeline_cache_load(struct libresoc_pipeline_cache *cache,
209 const void *data, size_t size);
210
211 bool
212 libresoc_create_shader_variants_from_pipeline_cache(struct libresoc_device *device,
213 struct libresoc_pipeline_cache *cache,
214 const unsigned char *sha1,
215 struct libresoc_shader_variant **variants,
216 bool *found_in_application_cache);
217
218 void
219 libresoc_pipeline_cache_insert_shaders(struct libresoc_device *device,
220 struct libresoc_pipeline_cache *cache,
221 const unsigned char *sha1,
222 struct libresoc_shader_variant **variants,
223 struct libresoc_shader_binary *const *binaries);
224
225 VkResult libresoc_init_wsi(struct libresoc_physical_device *physical_device);
226 void libresoc_finish_wsi(struct libresoc_physical_device *physical_device);
227
228 struct libresoc_device {
229
230 struct vk_device vk;
231 VkAllocationCallbacks alloc;
232
233 struct libresoc_instance *instance;
234
235 struct libresoc_device_extension_table enabled_extensions;
236 struct libresoc_device_dispatch_table dispatch;
237
238 struct libresoc_queue *queues[LIBRESOC_MAX_QUEUE_FAMILIES];
239 int queue_count[LIBRESOC_MAX_QUEUE_FAMILIES];
240 struct radeon_cmdbuf *empty_cs[LIBRESOC_MAX_QUEUE_FAMILIES];
241 struct libresoc_physical_device *physical_device;
242
243 /* Backup in-memory cache to be used if the app doesn't provide one */
244 struct libresoc_pipeline_cache * mem_cache;
245 /* Condition variable for legacy timelines, to notify waiters when a
246 * new point gets submitted. */
247 pthread_cond_t timeline_cond;
248 /* Overallocation. */
249 bool overallocation_disallowed;
250 uint64_t allocated_memory_size[VK_MAX_MEMORY_HEAPS];
251 mtx_t overallocation_mutex;
252 /* FIXME: stub */
253 };
254
255
256 struct libresoc_physical_device {
257 VK_LOADER_DATA _loader_data;
258
259 struct list_head link;
260 struct libresoc_instance *instance;
261 struct wsi_device wsi_device;
262 struct libresoc_device_extension_table supported_extensions;
263 struct libresoc_physical_device_dispatch_table dispatch;
264
265 char name[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE];
266 uint8_t driver_uuid[VK_UUID_SIZE];
267 uint8_t device_uuid[VK_UUID_SIZE];
268 uint8_t cache_uuid[VK_UUID_SIZE];
269 int local_fd;
270 int master_fd;
271 VkPhysicalDeviceMemoryProperties memory_properties;
272 /* FIXME: stub */
273 };
274
275 struct libresoc_app_info {
276 const char *app_name;
277 uint32_t app_version;
278 const char *engine_name;
279 uint32_t engine_version;
280 uint32_t api_version;
281 };
282
283 struct libresoc_instance {
284 struct vk_object_base base;
285
286 VkAllocationCallbacks alloc;
287
288 uint32_t apiVersion;
289
290 uint64_t debug_flags;
291 char * engineName;
292 uint32_t engineVersion;
293 struct libresoc_app_info app_info;
294
295 bool physical_devices_enumerated;
296 struct libresoc_instance_extension_table enabled_extensions;
297 struct libresoc_instance_dispatch_table dispatch;
298 struct libresoc_device_dispatch_table device_dispatch;
299 struct libresoc_physical_device_dispatch_table physical_device_dispatch;
300 int physical_device_count;
301 struct list_head physical_devices;
302
303 struct driOptionCache dri_options;
304 struct driOptionCache available_dri_options;
305 struct vk_debug_report_instance debug_report_callbacks;
306 };
307
308 struct libresoc_deferred_queue_submission;
309 struct libresoc_queue {
310 VK_LOADER_DATA _loader_data;
311
312 struct libresoc_device *device;
313
314 uint32_t queue_family_index;
315 int queue_idx;
316 VkDeviceQueueCreateFlags flags;
317
318 struct list_head pending_submissions;
319 pthread_mutex_t pending_mutex;
320 pthread_mutex_t thread_mutex;
321 pthread_cond_t thread_cond;
322 //struct libresoc_deferred_queue_submission *thread_submission;
323 pthread_t submission_thread;
324 bool thread_exit;
325 bool thread_running;
326 /* FIXME: stub */
327 };
328
329 struct libresoc_cmd_buffer_upload {
330 uint8_t *map;
331 unsigned offset;
332 uint64_t size;
333 struct list_head list;
334 };
335
336 enum libresoc_cmd_buffer_status {
337 LIBRESOC_CMD_BUFFER_STATUS_INVALID,
338 LIBRESOC_CMD_BUFFER_STATUS_INITIAL,
339 LIBRESOC_CMD_BUFFER_STATUS_RECORDING,
340 LIBRESOC_CMD_BUFFER_STATUS_EXECUTABLE,
341 LIBRESOC_CMD_BUFFER_STATUS_PENDING,
342 };
343
344 struct libresoc_cmd_buffer {
345 struct vk_object_base base;
346
347 struct libresoc_device * device;
348
349 struct libresoc_cmd_pool * pool;
350 struct list_head pool_link;
351
352 VkCommandBufferUsageFlags usage_flags;
353 VkCommandBufferLevel level;
354 enum libresoc_cmd_buffer_status status;
355 //struct radeon_cmdbuf *cs;
356 // struct libresoc_cmd_state state;
357 // struct libresoc_vertex_binding vertex_bindings[MAX_VBS];
358 // struct libresoc_streamout_binding streamout_bindings[MAX_SO_BUFFERS];
359 uint32_t queue_family_index;
360
361 uint8_t push_constants[MAX_PUSH_CONSTANTS_SIZE];
362 VkShaderStageFlags push_constant_stages;
363 // struct libresoc_descriptor_set meta_push_descriptors;
364
365 // struct libresoc_descriptor_state descriptors[MAX_BIND_POINTS];
366
367 struct libresoc_cmd_buffer_upload upload;
368
369 uint32_t scratch_size_per_wave_needed;
370 uint32_t scratch_waves_wanted;
371 uint32_t compute_scratch_size_per_wave_needed;
372 uint32_t compute_scratch_waves_wanted;
373 uint32_t esgs_ring_size_needed;
374 uint32_t gsvs_ring_size_needed;
375 bool tess_rings_needed;
376 bool sample_positions_needed;
377
378 VkResult record_result;
379
380 };
381
382 struct libresoc_device_memory {
383 struct vk_object_base base;
384 /* for dedicated allocations */
385 struct libresoc_image *image;
386 //struct libresoc_buffer *buffer;
387 uint32_t heap_index;
388 uint64_t alloc_size;
389 void * map;
390 void * user_ptr;
391 };
392
393 void libresoc_free_memory(struct libresoc_device *device,
394 const VkAllocationCallbacks* pAllocator,
395 struct libresoc_device_memory *mem);
396
397 uint32_t libresoc_physical_device_api_version(struct libresoc_physical_device *dev);
398
399 int libresoc_get_instance_entrypoint_index(const char *name);
400 int libresoc_get_device_entrypoint_index(const char *name);
401 int libresoc_get_physical_device_entrypoint_index(const char *name);
402
403 const char *libresoc_get_instance_entry_name(int index);
404 const char *libresoc_get_physical_device_entry_name(int index);
405 const char *libresoc_get_device_entry_name(int index);
406
407 bool
408 libresoc_instance_entrypoint_is_enabled(int index, uint32_t core_version,
409 const struct libresoc_instance_extension_table *instance);
410 bool
411 libresoc_physical_device_entrypoint_is_enabled(int index, uint32_t core_version,
412 const struct libresoc_instance_extension_table *instance);
413 bool
414 libresoc_device_entrypoint_is_enabled(int index, uint32_t core_version,
415 const struct libresoc_instance_extension_table *instance,
416 const struct libresoc_device_extension_table *device);
417
418 void *libresoc_lookup_entrypoint(const char *name);
419
420 const char *
421 libresoc_get_debug_option_name(int id);
422
423 struct libresoc_binning_settings {
424 unsigned context_states_per_bin; /* allowed range: [1, 6] */
425 unsigned persistent_states_per_bin; /* allowed range: [1, 32] */
426 unsigned fpovs_per_batch; /* allowed range: [0, 255], 0 = unlimited */
427 };
428
429 struct libresoc_binning_settings
430 libresoc_get_binning_settings(const struct libresoc_physical_device *pdev);
431
432 struct vk_format_description;
433 uint32_t libresoc_translate_buffer_dataformat(const struct vk_format_description *desc,
434 int first_non_void);
435 uint32_t libresoc_translate_buffer_numformat(const struct vk_format_description *desc,
436 int first_non_void);
437 bool libresoc_is_buffer_format_supported(VkFormat format, bool *scaled);
438 uint32_t libresoc_translate_colorformat(VkFormat format);
439 uint32_t libresoc_translate_color_numformat(VkFormat format,
440 const struct vk_format_description *desc,
441 int first_non_void);
442 uint32_t libresoc_colorformat_endian_swap(uint32_t colorformat);
443 unsigned libresoc_translate_colorswap(VkFormat format, bool do_endian_swap);
444 uint32_t libresoc_translate_dbformat(VkFormat format);
445 uint32_t libresoc_translate_tex_dataformat(VkFormat format,
446 const struct vk_format_description *desc,
447 int first_non_void);
448 uint32_t libresoc_translate_tex_numformat(VkFormat format,
449 const struct vk_format_description *desc,
450 int first_non_void);
451 bool libresoc_format_pack_clear_color(VkFormat format,
452 uint32_t clear_vals[2],
453 VkClearColorValue *value);
454 bool libresoc_is_colorbuffer_format_supported(VkFormat format, bool *blendable);
455 bool libresoc_dcc_formats_compatible(VkFormat format1,
456 VkFormat format2);
457 bool libresoc_device_supports_etc(struct libresoc_physical_device *physical_device);
458
459
460 /* Whether the image has a htile that is known consistent with the contents of
461 * the image and is allowed to be in compressed form.
462 *
463 * If this is false reads that don't use the htile should be able to return
464 * correct results.
465 */
466 bool libresoc_layout_is_htile_compressed(const struct libresoc_image *image,
467 VkImageLayout layout,
468 bool in_render_loop,
469 unsigned queue_mask);
470
471 bool libresoc_layout_can_fast_clear(const struct libresoc_image *image,
472 VkImageLayout layout,
473 bool in_render_loop,
474 unsigned queue_mask);
475
476 bool libresoc_layout_dcc_compressed(const struct libresoc_device *device,
477 const struct libresoc_image *image,
478 VkImageLayout layout,
479 bool in_render_loop,
480 unsigned queue_mask);
481
482 #define libresoc_printflike(a, b) __attribute__((__format__(__printf__, a, b)))
483
484 VkResult __vk_errorf(struct libresoc_instance *instance, VkResult error,
485 const char *file, int line,
486 const char *format, ...);
487
488 #define vk_error(instance, error) __vk_errorf(instance, error, __FILE__, __LINE__, NULL);
489 #define vk_errorf(instance, error, format, ...) __vk_errorf(instance, error, __FILE__, __LINE__, format, ## __VA_ARGS__);
490
491 void libresoc_loge(const char *format, ...) libresoc_printflike(1, 2);
492 void libresoc_loge_v(const char *format, va_list va);
493
494 #define LIBRESOC_DEFINE_HANDLE_CASTS(__libresoc_type, __VkType) \
495 \
496 static inline struct __libresoc_type * \
497 __libresoc_type ## _from_handle(__VkType _handle) \
498 { \
499 return (struct __libresoc_type *) _handle; \
500 } \
501 \
502 static inline __VkType \
503 __libresoc_type ## _to_handle(struct __libresoc_type *_obj) \
504 { \
505 return (__VkType) _obj; \
506 }
507
508 #define LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(__libresoc_type, __VkType) \
509 \
510 static inline struct __libresoc_type * \
511 __libresoc_type ## _from_handle(__VkType _handle) \
512 { \
513 return (struct __libresoc_type *)(uintptr_t) _handle; \
514 } \
515 \
516 static inline __VkType \
517 __libresoc_type ## _to_handle(struct __libresoc_type *_obj) \
518 { \
519 return (__VkType)(uintptr_t) _obj; \
520 }
521
522 #define LIBRESOC_FROM_HANDLE(__libresoc_type, __name, __handle) \
523 struct __libresoc_type *__name = __libresoc_type ## _from_handle(__handle)
524
525 LIBRESOC_DEFINE_HANDLE_CASTS(libresoc_cmd_buffer, VkCommandBuffer)
526 LIBRESOC_DEFINE_HANDLE_CASTS(libresoc_device, VkDevice)
527 LIBRESOC_DEFINE_HANDLE_CASTS(libresoc_instance, VkInstance)
528 LIBRESOC_DEFINE_HANDLE_CASTS(libresoc_physical_device, VkPhysicalDevice)
529 LIBRESOC_DEFINE_HANDLE_CASTS(libresoc_queue, VkQueue)
530
531 LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_cmd_pool, VkCommandPool)
532 //LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_buffer, VkBuffer)
533 //LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_buffer_view, VkBufferView)
534 //LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_descriptor_pool, VkDescriptorPool)
535 //LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_descriptor_set, VkDescriptorSet)
536 //LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_descriptor_set_layout, VkDescriptorSetLayout)
537 //LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_descriptor_update_template, VkDescriptorUpdateTemplate)
538 LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_device_memory, VkDeviceMemory)
539 LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_fence, VkFence)
540 //LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_event, VkEvent)
541 //LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_framebuffer, VkFramebuffer)
542 LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_image, VkImage)
543 //LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_image_view, VkImageView);
544 LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_pipeline_cache, VkPipelineCache)
545 //LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_pipeline, VkPipeline)
546 //LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_pipeline_layout, VkPipelineLayout)
547 //LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_query_pool, VkQueryPool)
548 //LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_render_pass, VkRenderPass)
549 //LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_sampler, VkSampler)
550 //LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_sampler_ycbcr_conversion, VkSamplerYcbcrConversion)
551 //LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_shader_module, VkShaderModule)
552 LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_semaphore, VkSemaphore)
553
554 #endif /* LIBRESOC_PRIVATE_H */