• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2018 Collabora Ltd.
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  * on the rights to use, copy, modify, merge, publish, distribute, sub
8  * license, and/or sell copies of the Software, and to permit persons to whom
9  * the 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 NON-INFRINGEMENT. IN NO EVENT SHALL
18  * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21  * USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23 
24 #include "zink_screen.h"
25 
26 #include "zink_kopper.h"
27 #include "zink_compiler.h"
28 #include "zink_context.h"
29 #include "zink_descriptors.h"
30 #include "zink_fence.h"
31 #include "vk_format.h"
32 #include "zink_format.h"
33 #include "zink_framebuffer.h"
34 #include "zink_program.h"
35 #include "zink_public.h"
36 #include "zink_query.h"
37 #include "zink_resource.h"
38 #include "zink_state.h"
39 #include "nir_to_spirv/nir_to_spirv.h" // for SPIRV_VERSION
40 
41 #include "util/u_debug.h"
42 #include "util/u_dl.h"
43 #include "util/os_file.h"
44 #include "util/u_memory.h"
45 #include "util/u_screen.h"
46 #include "util/u_string.h"
47 #include "util/perf/u_trace.h"
48 #include "util/u_transfer_helper.h"
49 #include "util/hex.h"
50 #include "util/xmlconfig.h"
51 
52 #include "util/u_cpu_detect.h"
53 
54 #ifdef HAVE_LIBDRM
55 #include <xf86drm.h>
56 #include <fcntl.h>
57 #include <sys/stat.h>
58 #ifdef MAJOR_IN_MKDEV
59 #include <sys/mkdev.h>
60 #endif
61 #ifdef MAJOR_IN_SYSMACROS
62 #include <sys/sysmacros.h>
63 #endif
64 #endif
65 
66 static int num_screens = 0;
67 bool zink_tracing = false;
68 
69 #if DETECT_OS_WINDOWS
70 #include <io.h>
71 #define VK_LIBNAME "vulkan-1.dll"
72 #else
73 #include <unistd.h>
74 #if DETECT_OS_APPLE
75 #define VK_LIBNAME "libvulkan.1.dylib"
76 #elif DETECT_OS_ANDROID
77 #define VK_LIBNAME "libvulkan.so"
78 #elif DETECT_OS_OHOS
79 #define VK_LIBNAME "libvulkan.so"
80 #else
81 #define VK_LIBNAME "libvulkan.so.1"
82 #endif
83 #endif
84 
85 #ifdef __APPLE__
86 #include "MoltenVK/mvk_vulkan.h"
87 // Source of MVK_VERSION
88 #include "MoltenVK/mvk_config.h"
89 #define VK_NO_PROTOTYPES
90 #include "MoltenVK/mvk_deprecated_api.h"
91 #include "MoltenVK/mvk_private_api.h"
92 #endif /* __APPLE__ */
93 
94 #ifdef HAVE_LIBDRM
95 #include "drm-uapi/dma-buf.h"
96 #include <xf86drm.h>
97 #endif
98 
99 static const struct debug_named_value
100 zink_debug_options[] = {
101    { "nir", ZINK_DEBUG_NIR, "Dump NIR during program compile" },
102    { "spirv", ZINK_DEBUG_SPIRV, "Dump SPIR-V during program compile" },
103    { "tgsi", ZINK_DEBUG_TGSI, "Dump TGSI during program compile" },
104    { "validation", ZINK_DEBUG_VALIDATION, "Dump Validation layer output" },
105    { "vvl", ZINK_DEBUG_VALIDATION, "Dump Validation layer output" },
106    { "sync", ZINK_DEBUG_SYNC, "Force synchronization before draws/dispatches" },
107    { "compact", ZINK_DEBUG_COMPACT, "Use only 4 descriptor sets" },
108    { "noreorder", ZINK_DEBUG_NOREORDER, "Do not reorder command streams" },
109    { "gpl", ZINK_DEBUG_GPL, "Force using Graphics Pipeline Library for all shaders" },
110    { "shaderdb", ZINK_DEBUG_SHADERDB, "Do stuff to make shader-db work" },
111    { "rp", ZINK_DEBUG_RP, "Enable renderpass tracking/optimizations" },
112    { "norp", ZINK_DEBUG_NORP, "Disable renderpass tracking/optimizations" },
113    { "map", ZINK_DEBUG_MAP, "Track amount of mapped VRAM" },
114    { "flushsync", ZINK_DEBUG_FLUSHSYNC, "Force synchronous flushes/presents" },
115    { "noshobj", ZINK_DEBUG_NOSHOBJ, "Disable EXT_shader_object" },
116    { "optimal_keys", ZINK_DEBUG_OPTIMAL_KEYS, "Debug/use optimal_keys" },
117    { "noopt", ZINK_DEBUG_NOOPT, "Disable async optimized pipeline compiles" },
118    { "nobgc", ZINK_DEBUG_NOBGC, "Disable all async pipeline compiles" },
119    { "mem", ZINK_DEBUG_MEM, "Debug memory allocations" },
120    { "quiet", ZINK_DEBUG_QUIET, "Suppress warnings" },
121    { "ioopt", ZINK_DEBUG_IOOPT, "Optimize IO" },
122    { "nopc", ZINK_DEBUG_NOPC, "No precompilation" },
123    DEBUG_NAMED_VALUE_END
124 };
125 
126 DEBUG_GET_ONCE_FLAGS_OPTION(zink_debug, "ZINK_DEBUG", zink_debug_options, 0)
127 
128 uint32_t
129 zink_debug;
130 
131 
132 static const struct debug_named_value
133 zink_descriptor_options[] = {
134    { "auto", ZINK_DESCRIPTOR_MODE_AUTO, "Automatically detect best mode" },
135    { "lazy", ZINK_DESCRIPTOR_MODE_LAZY, "Don't cache, do least amount of updates" },
136    { "db", ZINK_DESCRIPTOR_MODE_DB, "Use descriptor buffers" },
137    DEBUG_NAMED_VALUE_END
138 };
139 
140 DEBUG_GET_ONCE_FLAGS_OPTION(zink_descriptor_mode, "ZINK_DESCRIPTORS", zink_descriptor_options, ZINK_DESCRIPTOR_MODE_AUTO)
141 
142 enum zink_descriptor_mode zink_descriptor_mode;
143 
144 struct zink_device {
145    unsigned refcount;
146    VkPhysicalDevice pdev;
147    VkDevice dev;
148    struct zink_device_info *info;
149 };
150 
151 static simple_mtx_t device_lock = SIMPLE_MTX_INITIALIZER;
152 static struct set device_table;
153 
154 static simple_mtx_t instance_lock = SIMPLE_MTX_INITIALIZER;
155 static struct zink_instance_info instance_info;
156 static unsigned instance_refcount;
157 static VkInstance instance;
158 
159 static const char *
zink_get_vendor(struct pipe_screen * pscreen)160 zink_get_vendor(struct pipe_screen *pscreen)
161 {
162    return "Mesa";
163 }
164 
165 static const char *
zink_get_device_vendor(struct pipe_screen * pscreen)166 zink_get_device_vendor(struct pipe_screen *pscreen)
167 {
168    return zink_screen(pscreen)->vendor_name;
169 }
170 
171 static const char *
zink_get_name(struct pipe_screen * pscreen)172 zink_get_name(struct pipe_screen *pscreen)
173 {
174    return zink_screen(pscreen)->device_name;
175 }
176 
177 static int
zink_set_driver_strings(struct zink_screen * screen)178 zink_set_driver_strings(struct zink_screen *screen)
179 {
180    char buf[1000];
181    const char *driver_name = vk_DriverId_to_str(zink_driverid(screen)) + strlen("VK_DRIVER_ID_");
182    int written = snprintf(buf, sizeof(buf), "zink Vulkan %d.%d(%s (%s))",
183       VK_VERSION_MAJOR(screen->info.device_version),
184       VK_VERSION_MINOR(screen->info.device_version),
185       screen->info.props.deviceName,
186       strstr(vk_DriverId_to_str(zink_driverid(screen)), "VK_DRIVER_ID_") ? driver_name : "Driver Unknown"
187    );
188    if (written < 0)
189       return written;
190    assert(written < sizeof(buf));
191    screen->device_name = ralloc_strdup(screen, buf);
192 
193    written = snprintf(buf, sizeof(buf), "Unknown (vendor-id: 0x%04x)", screen->info.props.vendorID);
194    if (written < 0)
195       return written;
196    assert(written < sizeof(buf));
197    screen->vendor_name = ralloc_strdup(screen, buf);
198    return 0;
199 }
200 
201 static void
zink_get_driver_uuid(struct pipe_screen * pscreen,char * uuid)202 zink_get_driver_uuid(struct pipe_screen *pscreen, char *uuid)
203 {
204    struct zink_screen *screen = zink_screen(pscreen);
205    if (screen->vk_version >= VK_MAKE_VERSION(1,2,0)) {
206       memcpy(uuid, screen->info.props11.driverUUID, VK_UUID_SIZE);
207    } else {
208       memcpy(uuid, screen->info.deviceid_props.driverUUID, VK_UUID_SIZE);
209    }
210 }
211 
212 static void
zink_get_device_uuid(struct pipe_screen * pscreen,char * uuid)213 zink_get_device_uuid(struct pipe_screen *pscreen, char *uuid)
214 {
215    struct zink_screen *screen = zink_screen(pscreen);
216    if (screen->vk_version >= VK_MAKE_VERSION(1,2,0)) {
217       memcpy(uuid, screen->info.props11.deviceUUID, VK_UUID_SIZE);
218    } else {
219       memcpy(uuid, screen->info.deviceid_props.deviceUUID, VK_UUID_SIZE);
220    }
221 }
222 
223 static void
zink_get_device_luid(struct pipe_screen * pscreen,char * luid)224 zink_get_device_luid(struct pipe_screen *pscreen, char *luid)
225 {
226    struct zink_screen *screen = zink_screen(pscreen);
227    if (screen->info.have_vulkan12) {
228       memcpy(luid, screen->info.props11.deviceLUID, VK_LUID_SIZE);
229    } else {
230       memcpy(luid, screen->info.deviceid_props.deviceLUID, VK_LUID_SIZE);
231    }
232 }
233 
234 static uint32_t
zink_get_device_node_mask(struct pipe_screen * pscreen)235 zink_get_device_node_mask(struct pipe_screen *pscreen)
236 {
237    struct zink_screen *screen = zink_screen(pscreen);
238    if (screen->info.have_vulkan12) {
239       return screen->info.props11.deviceNodeMask;
240    } else {
241       return screen->info.deviceid_props.deviceNodeMask;
242    }
243 }
244 
245 static void
zink_set_max_shader_compiler_threads(struct pipe_screen * pscreen,unsigned max_threads)246 zink_set_max_shader_compiler_threads(struct pipe_screen *pscreen, unsigned max_threads)
247 {
248    struct zink_screen *screen = zink_screen(pscreen);
249    util_queue_adjust_num_threads(&screen->cache_get_thread, max_threads, false);
250 }
251 
252 static bool
zink_is_parallel_shader_compilation_finished(struct pipe_screen * screen,void * shader,enum pipe_shader_type shader_type)253 zink_is_parallel_shader_compilation_finished(struct pipe_screen *screen, void *shader, enum pipe_shader_type shader_type)
254 {
255    if (shader_type == MESA_SHADER_COMPUTE) {
256       struct zink_program *pg = shader;
257       return !pg->can_precompile || util_queue_fence_is_signalled(&pg->cache_fence);
258    }
259 
260    struct zink_shader *zs = shader;
261    if (!util_queue_fence_is_signalled(&zs->precompile.fence))
262       return false;
263    bool finished = true;
264    set_foreach(zs->programs, entry) {
265       struct zink_gfx_program *prog = (void*)entry->key;
266       finished &= util_queue_fence_is_signalled(&prog->base.cache_fence);
267    }
268    return finished;
269 }
270 
271 static VkDeviceSize
get_video_mem(struct zink_screen * screen)272 get_video_mem(struct zink_screen *screen)
273 {
274    VkDeviceSize size = 0;
275    for (uint32_t i = 0; i < screen->info.mem_props.memoryHeapCount; ++i) {
276       if (screen->info.mem_props.memoryHeaps[i].flags &
277           VK_MEMORY_HEAP_DEVICE_LOCAL_BIT)
278          size += screen->info.mem_props.memoryHeaps[i].size;
279    }
280    return size;
281 }
282 
283 /**
284  * Creates the disk cache used by mesa/st frontend for caching the GLSL -> NIR
285  * path.
286  *
287  * The output that gets stored in the frontend's cache is the result of
288  * zink_shader_finalize().  So, our blake3 cache key here needs to include
289  * everything that would change the NIR we generate from a given set of GLSL
290  * source, including our driver build, the Vulkan device and driver (which could
291  * affect the pipe caps we show the frontend), and any debug flags that change
292  * codegen.
293  *
294  * This disk cache also gets used by zink itself for storing its output from NIR
295  * -> SPIRV translation.
296  */
297 static bool
disk_cache_init(struct zink_screen * screen)298 disk_cache_init(struct zink_screen *screen)
299 {
300    if (zink_debug & ZINK_DEBUG_SHADERDB)
301       return true;
302 
303 #ifdef ENABLE_SHADER_CACHE
304    struct mesa_blake3 ctx;
305    _mesa_blake3_init(&ctx);
306 
307 #ifdef HAVE_DL_ITERATE_PHDR
308    /* Hash in the zink driver build. */
309    const struct build_id_note *note =
310        build_id_find_nhdr_for_addr(disk_cache_init);
311    unsigned build_id_len = build_id_length(note);
312    assert(note && build_id_len == 20); /* blake3 */
313    _mesa_blake3_update(&ctx, build_id_data(note), build_id_len);
314 #endif
315 
316    /* Hash in the Vulkan pipeline cache UUID to identify the combination of
317    *  vulkan device and driver (or any inserted layer that would invalidate our
318    *  cached pipelines).
319    *
320    * "Although they have identical descriptions, VkPhysicalDeviceIDProperties
321    *  ::deviceUUID may differ from
322    *  VkPhysicalDeviceProperties2::pipelineCacheUUID. The former is intended to
323    *  identify and correlate devices across API and driver boundaries, while the
324    *  latter is used to identify a compatible device and driver combination to
325    *  use when serializing and de-serializing pipeline state."
326    */
327    _mesa_blake3_update(&ctx, screen->info.props.pipelineCacheUUID, VK_UUID_SIZE);
328 
329    /* Hash in our debug flags that affect NIR generation as of finalize_nir */
330    unsigned shader_debug_flags = zink_debug & ZINK_DEBUG_COMPACT;
331    _mesa_blake3_update(&ctx, &shader_debug_flags, sizeof(shader_debug_flags));
332 
333    /* add in these shader keys */
334    _mesa_blake3_update(&ctx, &screen->driver_compiler_workarounds, sizeof(screen->driver_compiler_workarounds));
335 
336    /* Some of the driconf options change shaders.  Let's just hash the whole
337     * thing to not forget any (especially as options get added).
338     */
339    _mesa_blake3_update(&ctx, &screen->driconf, sizeof(screen->driconf));
340 
341    /* EXT_shader_object causes different descriptor layouts for separate shaders */
342    _mesa_blake3_update(&ctx, &screen->info.have_EXT_shader_object, sizeof(screen->info.have_EXT_shader_object));
343 
344    /* Finish the blake3 and format it as text. */
345    blake3_hash blake3;
346    _mesa_blake3_final(&ctx, blake3);
347 
348    char cache_id[20 * 2 + 1];
349    mesa_bytes_to_hex(cache_id, blake3, 20);
350 
351    screen->disk_cache = disk_cache_create("zink", cache_id, 0);
352 
353    if (!screen->disk_cache)
354       return true;
355 
356    if (!util_queue_init(&screen->cache_put_thread, "zcq", 8, 1, UTIL_QUEUE_INIT_RESIZE_IF_FULL, screen)) {
357       mesa_loge("zink: Failed to create disk cache queue\n");
358 
359       disk_cache_destroy(screen->disk_cache);
360       screen->disk_cache = NULL;
361 
362       return false;
363    }
364 #endif
365 
366    return true;
367 }
368 
369 
370 static void
cache_put_job(void * data,void * gdata,int thread_index)371 cache_put_job(void *data, void *gdata, int thread_index)
372 {
373    struct zink_program *pg = data;
374    struct zink_screen *screen = gdata;
375    size_t size = 0;
376    u_rwlock_rdlock(&pg->pipeline_cache_lock);
377    VkResult result = VKSCR(GetPipelineCacheData)(screen->dev, pg->pipeline_cache, &size, NULL);
378    if (result != VK_SUCCESS) {
379       u_rwlock_rdunlock(&pg->pipeline_cache_lock);
380       mesa_loge("ZINK: vkGetPipelineCacheData failed (%s)", vk_Result_to_str(result));
381       return;
382    }
383    if (pg->pipeline_cache_size == size) {
384       u_rwlock_rdunlock(&pg->pipeline_cache_lock);
385       return;
386    }
387    void *pipeline_data = malloc(size);
388    if (!pipeline_data) {
389       u_rwlock_rdunlock(&pg->pipeline_cache_lock);
390       return;
391    }
392    result = VKSCR(GetPipelineCacheData)(screen->dev, pg->pipeline_cache, &size, pipeline_data);
393    u_rwlock_rdunlock(&pg->pipeline_cache_lock);
394    if (result == VK_SUCCESS) {
395       pg->pipeline_cache_size = size;
396 
397       cache_key key;
398       disk_cache_compute_key(screen->disk_cache, pg->blake3, sizeof(pg->blake3), key);
399       disk_cache_put_nocopy(screen->disk_cache, key, pipeline_data, size, NULL);
400    } else {
401       mesa_loge("ZINK: vkGetPipelineCacheData failed (%s)", vk_Result_to_str(result));
402    }
403 }
404 
405 void
zink_screen_update_pipeline_cache(struct zink_screen * screen,struct zink_program * pg,bool in_thread)406 zink_screen_update_pipeline_cache(struct zink_screen *screen, struct zink_program *pg, bool in_thread)
407 {
408    if (!screen->disk_cache || !pg->pipeline_cache)
409       return;
410 
411    if (in_thread)
412       cache_put_job(pg, screen, 0);
413    else if (util_queue_fence_is_signalled(&pg->cache_fence))
414       util_queue_add_job(&screen->cache_put_thread, pg, &pg->cache_fence, cache_put_job, NULL, 0);
415 }
416 
417 static void
cache_get_job(void * data,void * gdata,int thread_index)418 cache_get_job(void *data, void *gdata, int thread_index)
419 {
420    struct zink_program *pg = data;
421    struct zink_screen *screen = gdata;
422 
423    VkPipelineCacheCreateInfo pcci;
424    pcci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
425    pcci.pNext = NULL;
426    pcci.flags = screen->info.have_EXT_pipeline_creation_cache_control ? VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT : 0;
427    pcci.initialDataSize = 0;
428    pcci.pInitialData = NULL;
429 
430    cache_key key;
431    disk_cache_compute_key(screen->disk_cache, pg->blake3, sizeof(pg->blake3), key);
432    pcci.pInitialData = disk_cache_get(screen->disk_cache, key, &pg->pipeline_cache_size);
433    pcci.initialDataSize = pg->pipeline_cache_size;
434 
435    VkResult res = VKSCR(CreatePipelineCache)(screen->dev, &pcci, NULL, &pg->pipeline_cache);
436    if (res != VK_SUCCESS) {
437       mesa_loge("ZINK: vkCreatePipelineCache failed (%s)", vk_Result_to_str(res));
438    }
439    free((void*)pcci.pInitialData);
440 }
441 
442 void
zink_screen_get_pipeline_cache(struct zink_screen * screen,struct zink_program * pg,bool in_thread)443 zink_screen_get_pipeline_cache(struct zink_screen *screen, struct zink_program *pg, bool in_thread)
444 {
445    if (!screen->disk_cache)
446       return;
447 
448    if (in_thread)
449       cache_get_job(pg, screen, 0);
450    else
451       util_queue_add_job(&screen->cache_get_thread, pg, &pg->cache_fence, cache_get_job, NULL, 0);
452 }
453 
454 static int
zink_get_compute_param(struct pipe_screen * pscreen,enum pipe_shader_ir ir_type,enum pipe_compute_cap param,void * ret)455 zink_get_compute_param(struct pipe_screen *pscreen, enum pipe_shader_ir ir_type,
456                        enum pipe_compute_cap param, void *ret)
457 {
458    struct zink_screen *screen = zink_screen(pscreen);
459 #define RET(x) do {                  \
460    if (ret)                          \
461       memcpy(ret, x, sizeof(x));     \
462    return sizeof(x);                 \
463 } while (0)
464 
465    switch (param) {
466    case PIPE_COMPUTE_CAP_ADDRESS_BITS:
467       RET((uint32_t []){ 64 });
468 
469    case PIPE_COMPUTE_CAP_IR_TARGET:
470       if (ret)
471          strcpy(ret, "nir");
472       return 4;
473 
474    case PIPE_COMPUTE_CAP_GRID_DIMENSION:
475       RET((uint64_t []) { 3 });
476 
477    case PIPE_COMPUTE_CAP_MAX_GRID_SIZE:
478       RET(((uint64_t []) { screen->info.props.limits.maxComputeWorkGroupCount[0],
479                            screen->info.props.limits.maxComputeWorkGroupCount[1],
480                            screen->info.props.limits.maxComputeWorkGroupCount[2] }));
481 
482    case PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE:
483       /* MaxComputeWorkGroupSize[0..2] */
484       RET(((uint64_t []) {screen->info.props.limits.maxComputeWorkGroupSize[0],
485                           screen->info.props.limits.maxComputeWorkGroupSize[1],
486                           screen->info.props.limits.maxComputeWorkGroupSize[2]}));
487 
488    case PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK:
489    case PIPE_COMPUTE_CAP_MAX_VARIABLE_THREADS_PER_BLOCK:
490       RET((uint64_t []) { screen->info.props.limits.maxComputeWorkGroupInvocations });
491 
492    case PIPE_COMPUTE_CAP_MAX_LOCAL_SIZE:
493       RET((uint64_t []) { screen->info.props.limits.maxComputeSharedMemorySize });
494 
495    case PIPE_COMPUTE_CAP_IMAGES_SUPPORTED:
496       RET((uint32_t []) { 1 });
497 
498    case PIPE_COMPUTE_CAP_SUBGROUP_SIZES:
499       RET((uint32_t []) { screen->info.props11.subgroupSize });
500 
501    case PIPE_COMPUTE_CAP_MAX_MEM_ALLOC_SIZE:
502       RET((uint64_t []) { screen->clamp_video_mem });
503 
504    case PIPE_COMPUTE_CAP_MAX_GLOBAL_SIZE:
505       RET((uint64_t []) { screen->total_video_mem });
506 
507    case PIPE_COMPUTE_CAP_MAX_COMPUTE_UNITS:
508       // no way in vulkan to retrieve this information.
509       RET((uint32_t []) { 1 });
510 
511    case PIPE_COMPUTE_CAP_MAX_SUBGROUPS:
512    case PIPE_COMPUTE_CAP_MAX_CLOCK_FREQUENCY:
513    case PIPE_COMPUTE_CAP_MAX_PRIVATE_SIZE:
514    case PIPE_COMPUTE_CAP_MAX_INPUT_SIZE:
515       // XXX: I think these are for Clover...
516       return 0;
517 
518    default:
519       unreachable("unknown compute param");
520    }
521 }
522 
523 static uint32_t
get_smallest_buffer_heap(struct zink_screen * screen)524 get_smallest_buffer_heap(struct zink_screen *screen)
525 {
526    enum zink_heap heaps[] = {
527       ZINK_HEAP_DEVICE_LOCAL,
528       ZINK_HEAP_DEVICE_LOCAL_VISIBLE,
529       ZINK_HEAP_HOST_VISIBLE_COHERENT,
530       ZINK_HEAP_HOST_VISIBLE_COHERENT
531    };
532    unsigned size = UINT32_MAX;
533    for (unsigned i = 0; i < ARRAY_SIZE(heaps); i++) {
534       for (unsigned j = 0; j < screen->heap_count[i]; j++) {
535          unsigned heap_idx = screen->info.mem_props.memoryTypes[screen->heap_map[i][j]].heapIndex;
536          size = MIN2(screen->info.mem_props.memoryHeaps[heap_idx].size, size);
537       }
538    }
539    return size;
540 }
541 
542 static inline bool
have_fp32_filter_linear(struct zink_screen * screen)543 have_fp32_filter_linear(struct zink_screen *screen)
544 {
545    const VkFormat fp32_formats[] = {
546       VK_FORMAT_R32_SFLOAT,
547       VK_FORMAT_R32G32_SFLOAT,
548       VK_FORMAT_R32G32B32_SFLOAT,
549       VK_FORMAT_R32G32B32A32_SFLOAT,
550       VK_FORMAT_D32_SFLOAT,
551    };
552    for (int i = 0; i < ARRAY_SIZE(fp32_formats); ++i) {
553       VkFormatProperties props;
554       VKSCR(GetPhysicalDeviceFormatProperties)(screen->pdev,
555                                                fp32_formats[i],
556                                                &props);
557       if (((props.linearTilingFeatures | props.optimalTilingFeatures) &
558            (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
559             VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT)) ==
560           VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) {
561          return false;
562       }
563    }
564    return true;
565 }
566 
567 static int
zink_get_shader_param(struct pipe_screen * pscreen,gl_shader_stage shader,enum pipe_shader_cap param)568 zink_get_shader_param(struct pipe_screen *pscreen,
569                        gl_shader_stage shader,
570                        enum pipe_shader_cap param)
571 {
572    struct zink_screen *screen = zink_screen(pscreen);
573 
574    switch (param) {
575    case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
576       switch (shader) {
577       case MESA_SHADER_FRAGMENT:
578       case MESA_SHADER_VERTEX:
579          return INT_MAX;
580       case MESA_SHADER_TESS_CTRL:
581       case MESA_SHADER_TESS_EVAL:
582          if (screen->info.feats.features.tessellationShader &&
583              screen->info.have_KHR_maintenance2)
584             return INT_MAX;
585          break;
586 
587       case MESA_SHADER_GEOMETRY:
588          if (screen->info.feats.features.geometryShader)
589             return INT_MAX;
590          break;
591 
592       case MESA_SHADER_COMPUTE:
593          return INT_MAX;
594       default:
595          break;
596       }
597       return 0;
598    case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
599    case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
600    case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
601    case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
602       return INT_MAX;
603 
604    case PIPE_SHADER_CAP_MAX_INPUTS: {
605       uint32_t max = 0;
606       switch (shader) {
607       case MESA_SHADER_VERTEX:
608          max = MIN2(screen->info.props.limits.maxVertexInputAttributes, PIPE_MAX_ATTRIBS);
609          break;
610       case MESA_SHADER_TESS_CTRL:
611          max = screen->info.props.limits.maxTessellationControlPerVertexInputComponents / 4;
612          break;
613       case MESA_SHADER_TESS_EVAL:
614          max = screen->info.props.limits.maxTessellationEvaluationInputComponents / 4;
615          break;
616       case MESA_SHADER_GEOMETRY:
617          max = screen->info.props.limits.maxGeometryInputComponents / 4;
618          break;
619       case MESA_SHADER_FRAGMENT:
620          /* intel drivers report fewer components, but it's a value that's compatible
621           * with what we need for GL, so we can still force a conformant value here
622           */
623          if (zink_driverid(screen) == VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA ||
624              zink_driverid(screen) == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS)
625             return 32;
626          max = screen->info.props.limits.maxFragmentInputComponents / 4;
627          break;
628       default:
629          return 0; /* unsupported stage */
630       }
631       switch (shader) {
632       case MESA_SHADER_VERTEX:
633       case MESA_SHADER_TESS_EVAL:
634       case MESA_SHADER_GEOMETRY:
635          /* last vertex stage must support streamout, and this is capped in glsl compiler */
636          return MIN2(max, MAX_VARYING);
637       default: break;
638       }
639       return MIN2(max, 64); // prevent overflowing struct shader_info::inputs_read
640    }
641 
642    case PIPE_SHADER_CAP_MAX_OUTPUTS: {
643       uint32_t max = 0;
644       switch (shader) {
645       case MESA_SHADER_VERTEX:
646          max = screen->info.props.limits.maxVertexOutputComponents / 4;
647          break;
648       case MESA_SHADER_TESS_CTRL:
649          max = screen->info.props.limits.maxTessellationControlPerVertexOutputComponents / 4;
650          break;
651       case MESA_SHADER_TESS_EVAL:
652          max = screen->info.props.limits.maxTessellationEvaluationOutputComponents / 4;
653          break;
654       case MESA_SHADER_GEOMETRY:
655          max = screen->info.props.limits.maxGeometryOutputComponents / 4;
656          break;
657       case MESA_SHADER_FRAGMENT:
658          max = screen->info.props.limits.maxColorAttachments;
659          break;
660       default:
661          return 0; /* unsupported stage */
662       }
663       return MIN2(max, 64); // prevent overflowing struct shader_info::outputs_read/written
664    }
665 
666    case PIPE_SHADER_CAP_MAX_CONST_BUFFER0_SIZE:
667       /* At least 16384 is guaranteed by VK spec */
668       assert(screen->info.props.limits.maxUniformBufferRange >= 16384);
669       /* but Gallium can't handle values that are too big */
670       return MIN3(get_smallest_buffer_heap(screen),
671                   screen->info.props.limits.maxUniformBufferRange, BITFIELD_BIT(31));
672 
673    case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
674       return  MIN2(screen->info.props.limits.maxPerStageDescriptorUniformBuffers,
675                    PIPE_MAX_CONSTANT_BUFFERS);
676 
677    case PIPE_SHADER_CAP_MAX_TEMPS:
678       return INT_MAX;
679 
680    case PIPE_SHADER_CAP_INTEGERS:
681       return 1;
682 
683    case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
684    case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
685       return 1;
686 
687    case PIPE_SHADER_CAP_SUBROUTINES:
688    case PIPE_SHADER_CAP_INT64_ATOMICS:
689    case PIPE_SHADER_CAP_GLSL_16BIT_CONSTS:
690       return 0; /* not implemented */
691 
692    case PIPE_SHADER_CAP_FP16_CONST_BUFFERS:
693       //enabling this breaks GTF-GL46.gtf21.GL2Tests.glGetUniform.glGetUniform
694       //return screen->info.feats11.uniformAndStorageBuffer16BitAccess ||
695              //(screen->info.have_KHR_16bit_storage && screen->info.storage_16bit_feats.uniformAndStorageBuffer16BitAccess);
696       return 0;
697    case PIPE_SHADER_CAP_FP16_DERIVATIVES:
698       return 0; //spirv requires 32bit derivative srcs and dests
699    case PIPE_SHADER_CAP_FP16:
700       return screen->info.feats12.shaderFloat16 ||
701              (screen->info.have_KHR_shader_float16_int8 &&
702               screen->info.shader_float16_int8_feats.shaderFloat16);
703 
704    case PIPE_SHADER_CAP_INT16:
705       return screen->info.feats.features.shaderInt16;
706 
707    case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
708       return 0; /* not implemented */
709 
710    case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
711    case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
712       return MIN2(MIN2(screen->info.props.limits.maxPerStageDescriptorSamplers,
713                        screen->info.props.limits.maxPerStageDescriptorSampledImages),
714                   PIPE_MAX_SAMPLERS);
715 
716    case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
717       return 0; /* no idea */
718 
719    case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
720       switch (shader) {
721       case MESA_SHADER_VERTEX:
722       case MESA_SHADER_TESS_CTRL:
723       case MESA_SHADER_TESS_EVAL:
724       case MESA_SHADER_GEOMETRY:
725          if (!screen->info.feats.features.vertexPipelineStoresAndAtomics)
726             return 0;
727          break;
728 
729       case MESA_SHADER_FRAGMENT:
730          if (!screen->info.feats.features.fragmentStoresAndAtomics)
731             return 0;
732          break;
733 
734       default:
735          break;
736       }
737 
738       /* TODO: this limitation is dumb, and will need some fixes in mesa */
739       return MIN2(screen->info.props.limits.maxPerStageDescriptorStorageBuffers, PIPE_MAX_SHADER_BUFFERS);
740 
741    case PIPE_SHADER_CAP_SUPPORTED_IRS:
742       return (1 << PIPE_SHADER_IR_NIR) | (1 << PIPE_SHADER_IR_TGSI);
743 
744    case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
745       if (screen->info.feats.features.shaderStorageImageExtendedFormats &&
746           screen->info.feats.features.shaderStorageImageWriteWithoutFormat)
747          return MIN2(screen->info.props.limits.maxPerStageDescriptorStorageImages,
748                      ZINK_MAX_SHADER_IMAGES);
749       return 0;
750 
751    case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:
752    case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:
753       return 0; /* not implemented */
754    case PIPE_SHADER_CAP_CONT_SUPPORTED:
755       return 1;
756    }
757 
758    /* should only get here on unhandled cases */
759    return 0;
760 }
761 
762 static void
zink_init_screen_caps(struct zink_screen * screen)763 zink_init_screen_caps(struct zink_screen *screen)
764 {
765    struct pipe_caps *caps = (struct pipe_caps *)&screen->base.caps;
766 
767    u_init_pipe_screen_caps(&screen->base, screen->is_cpu ? 0 : 1);
768 
769    caps->null_textures = screen->info.rb_image_feats.robustImageAccess;
770    /* support OVR_multiview and OVR_multiview2 */
771    caps->multiview = screen->info.have_vulkan13 ? 2 * screen->info.feats11.multiview : 0;
772    caps->texrect = false;
773    caps->multi_draw_indirect_partial_stride = false;
774    caps->anisotropic_filter = screen->info.feats.features.samplerAnisotropy;
775    caps->emulate_nonfixed_primitive_restart = true;
776    {
777       uint32_t modes = BITFIELD_BIT(MESA_PRIM_LINE_STRIP) |
778          BITFIELD_BIT(MESA_PRIM_TRIANGLE_STRIP) |
779          BITFIELD_BIT(MESA_PRIM_LINE_STRIP_ADJACENCY) |
780          BITFIELD_BIT(MESA_PRIM_TRIANGLE_STRIP_ADJACENCY);
781       if (screen->have_triangle_fans)
782          modes |= BITFIELD_BIT(MESA_PRIM_TRIANGLE_FAN);
783       if (screen->info.have_EXT_primitive_topology_list_restart) {
784          modes |= BITFIELD_BIT(MESA_PRIM_POINTS) |
785             BITFIELD_BIT(MESA_PRIM_LINES) |
786             BITFIELD_BIT(MESA_PRIM_LINES_ADJACENCY) |
787             BITFIELD_BIT(MESA_PRIM_TRIANGLES) |
788             BITFIELD_BIT(MESA_PRIM_TRIANGLES_ADJACENCY);
789          if (screen->info.list_restart_feats.primitiveTopologyPatchListRestart)
790             modes |= BITFIELD_BIT(MESA_PRIM_PATCHES);
791       }
792       caps->supported_prim_modes_with_restart = modes;
793    }
794    {
795       uint32_t modes = BITFIELD_MASK(MESA_PRIM_COUNT);
796       if (!screen->have_triangle_fans || !screen->info.feats.features.geometryShader)
797          modes &= ~BITFIELD_BIT(MESA_PRIM_QUADS);
798       modes &= ~BITFIELD_BIT(MESA_PRIM_QUAD_STRIP);
799       modes &= ~BITFIELD_BIT(MESA_PRIM_POLYGON);
800       modes &= ~BITFIELD_BIT(MESA_PRIM_LINE_LOOP);
801       if (!screen->have_triangle_fans)
802          modes &= ~BITFIELD_BIT(MESA_PRIM_TRIANGLE_FAN);
803       caps->supported_prim_modes = modes;
804    }
805 #if defined(MVK_VERSION)
806    caps->fbfetch = 0;
807 #else
808    caps->fbfetch = 1;
809 #endif
810    caps->fbfetch_coherent = screen->info.have_EXT_rasterization_order_attachment_access;
811 
812    caps->memobj =
813       screen->instance_info->have_KHR_external_memory_capabilities &&
814       (screen->info.have_KHR_external_memory_fd ||
815        screen->info.have_KHR_external_memory_win32);
816    caps->fence_signal =
817       screen->info.have_KHR_external_semaphore_fd ||
818       screen->info.have_KHR_external_semaphore_win32;
819    caps->native_fence_fd =
820       screen->instance_info->have_KHR_external_semaphore_capabilities &&
821       screen->info.have_KHR_external_semaphore_fd;
822    caps->resource_from_user_memory = screen->info.have_EXT_external_memory_host;
823 
824    caps->surface_reinterpret_blocks =
825       screen->info.have_vulkan11 || screen->info.have_KHR_maintenance2;
826 
827    caps->validate_all_dirty_states = true;
828    caps->allow_mapped_buffers_during_execution = true;
829    caps->map_unsynchronized_thread_safe = true;
830    caps->shareable_shaders = true;
831    caps->device_reset_status_query = true;
832    caps->query_memory_info = true;
833    caps->npot_textures = true;
834    caps->tgsi_texcoord = true;
835    caps->draw_indirect = true;
836    caps->texture_query_lod = true;
837    caps->glsl_tess_levels_as_inputs = true;
838    caps->copy_between_compressed_and_plain_formats = true;
839    caps->force_persample_interp = true;
840    caps->framebuffer_no_attachment = true;
841    caps->shader_array_components = true;
842    caps->query_buffer_object = true;
843    caps->conditional_render_inverted = true;
844    caps->clip_halfz = true;
845    caps->texture_query_samples = true;
846    caps->texture_barrier = true;
847    caps->query_so_overflow = true;
848    caps->gl_spirv = true;
849    caps->clear_scissored = true;
850    caps->invalidate_buffer = true;
851    caps->prefer_real_buffer_in_constbuf0 = true;
852    caps->packed_uniforms = true;
853    caps->shader_pack_half_float = true;
854    caps->seamless_cube_map_per_texture = true;
855    caps->load_constbuf = true;
856    caps->multisample_z_resolve = true;
857    caps->allow_glthread_buffer_subdata_opt = true;
858    caps->nir_samplers_as_deref = true;
859    caps->call_finalize_nir_in_linker = true;
860    caps->texture_shadow_lod = true;
861 
862    caps->draw_vertex_state = screen->info.have_EXT_vertex_input_dynamic_state;
863 
864    caps->surface_sample_count = screen->vk_version >= VK_MAKE_VERSION(1,2,0);
865 
866    caps->shader_group_vote =
867       (screen->info.have_vulkan11 &&
868        (screen->info.subgroup.supportedOperations & VK_SUBGROUP_FEATURE_VOTE_BIT) &&
869        (screen->info.subgroup.supportedStages & VK_SHADER_STAGE_COMPUTE_BIT)) ||
870       screen->info.have_EXT_shader_subgroup_vote;
871    caps->quads_follow_provoking_vertex_convention = true;
872 
873    caps->texture_mirror_clamp_to_edge =
874       screen->info.have_KHR_sampler_mirror_clamp_to_edge ||
875       (screen->info.have_vulkan12 && screen->info.feats12.samplerMirrorClampToEdge);
876 
877    caps->polygon_offset_units_unscaled = true;
878 
879    caps->polygon_offset_clamp = screen->info.feats.features.depthBiasClamp;
880 
881    caps->query_pipeline_statistics_single =
882       screen->info.feats.features.pipelineStatisticsQuery;
883 
884    caps->robust_buffer_access_behavior =
885       screen->info.feats.features.robustBufferAccess &&
886       (screen->info.rb2_feats.robustImageAccess2 ||
887        screen->driver_compiler_workarounds.lower_robustImageAccess2);
888 
889    caps->multi_draw_indirect = screen->info.feats.features.multiDrawIndirect;
890 
891    caps->image_atomic_float_add =
892       (screen->info.have_EXT_shader_atomic_float &&
893        screen->info.atomic_float_feats.shaderSharedFloat32AtomicAdd &&
894        screen->info.atomic_float_feats.shaderBufferFloat32AtomicAdd);
895    caps->shader_atomic_int64 =
896       (screen->info.have_KHR_shader_atomic_int64 &&
897        screen->info.atomic_int_feats.shaderSharedInt64Atomics &&
898        screen->info.atomic_int_feats.shaderBufferInt64Atomics);
899 
900    caps->multi_draw_indirect_params = screen->info.have_KHR_draw_indirect_count;
901 
902    caps->start_instance =
903    caps->draw_parameters =
904       (screen->info.have_vulkan12 && screen->info.feats11.shaderDrawParameters) ||
905       screen->info.have_KHR_shader_draw_parameters;
906 
907    caps->vertex_element_instance_divisor =
908       screen->info.have_EXT_vertex_attribute_divisor;
909 
910    caps->max_vertex_streams = screen->info.tf_props.maxTransformFeedbackStreams;
911 
912    caps->compute_shader_derivatives = screen->info.have_NV_compute_shader_derivatives;
913 
914    caps->int64 = true;
915    caps->doubles = true;
916 
917    caps->max_dual_source_render_targets =
918       screen->info.feats.features.dualSrcBlend ?
919       screen->info.props.limits.maxFragmentDualSrcAttachments : 0;
920 
921    caps->max_render_targets = screen->info.props.limits.maxColorAttachments;
922 
923    caps->occlusion_query = screen->info.feats.features.occlusionQueryPrecise;
924 
925    caps->programmable_sample_locations =
926       screen->info.have_EXT_sample_locations &&
927       screen->info.have_EXT_extended_dynamic_state;
928 
929    caps->query_time_elapsed = screen->timestamp_valid_bits > 0;
930 
931    caps->texture_multisample = true;
932 
933    caps->fragment_shader_interlock = screen->info.have_EXT_fragment_shader_interlock;
934 
935    caps->shader_clock = screen->info.have_KHR_shader_clock;
936 
937    caps->shader_ballot =
938       screen->info.props11.subgroupSize <= 64 &&
939       ((screen->info.have_vulkan11 &&
940         screen->info.subgroup.supportedOperations & VK_SUBGROUP_FEATURE_BALLOT_BIT) ||
941        screen->info.have_EXT_shader_subgroup_ballot);
942 
943    caps->demote_to_helper_invocation =
944       screen->spirv_version >= SPIRV_VERSION(1, 6) ||
945       screen->info.have_EXT_shader_demote_to_helper_invocation;
946 
947    caps->sample_shading = screen->info.feats.features.sampleRateShading;
948 
949    caps->texture_swizzle = true;
950 
951    caps->vertex_input_alignment =
952       screen->info.have_EXT_legacy_vertex_attributes ?
953       PIPE_VERTEX_INPUT_ALIGNMENT_NONE : PIPE_VERTEX_INPUT_ALIGNMENT_ELEMENT;
954 
955    caps->gl_clamp = false;
956 
957    /* Assume that the vk driver is capable of moving imm arrays to some sort of constant storage on its own. */
958    caps->prefer_imm_arrays_as_constbuf = false;
959    {
960       enum pipe_quirk_texture_border_color_swizzle quirk =
961          PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_ALPHA_NOT_W;
962       if (!screen->info.border_color_feats.customBorderColorWithoutFormat)
963          quirk |= PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_FREEDRENO;
964       /* assume that if drivers don't implement this extension they either:
965        * - don't support custom border colors
966        * - handle things correctly
967        * - hate border color accuracy
968        */
969       else if (screen->info.have_EXT_border_color_swizzle &&
970                !screen->info.border_swizzle_feats.borderColorSwizzleFromImage)
971          quirk |= PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50;
972       caps->texture_border_color_quirk = quirk;
973    }
974    caps->max_texture_2d_size =
975       MIN2(screen->info.props.limits.maxImageDimension1D,
976            screen->info.props.limits.maxImageDimension2D);
977    caps->max_texture_3d_levels =
978       1 + util_logbase2(screen->info.props.limits.maxImageDimension3D);
979    caps->max_texture_cube_levels =
980       1 + util_logbase2(screen->info.props.limits.maxImageDimensionCube);
981 
982    caps->fragment_shader_texture_lod = true;
983    caps->fragment_shader_derivatives = true;
984 
985    caps->blend_equation_separate =
986    caps->indep_blend_enable =
987    caps->indep_blend_func = screen->info.feats.features.independentBlend;
988 
989    caps->dithering = false;
990 
991    caps->max_stream_output_buffers =
992       screen->info.have_EXT_transform_feedback ?
993       screen->info.tf_props.maxTransformFeedbackBuffers : 0;
994    caps->stream_output_pause_resume =
995    caps->stream_output_interleave_buffers = screen->info.have_EXT_transform_feedback;
996 
997    caps->max_texture_array_layers = screen->info.props.limits.maxImageArrayLayers;
998 
999    caps->depth_clip_disable = screen->info.have_EXT_depth_clip_enable;
1000 
1001    caps->shader_stencil_export = screen->info.have_EXT_shader_stencil_export;
1002 
1003    caps->vs_instanceid = true;
1004    caps->seamless_cube_map = true;
1005 
1006    caps->min_texel_offset = screen->info.props.limits.minTexelOffset;
1007    caps->max_texel_offset = screen->info.props.limits.maxTexelOffset;
1008 
1009    caps->vertex_color_unclamped = true;
1010 
1011    caps->conditional_render = true;
1012 
1013    caps->glsl_feature_level_compatibility =
1014    caps->glsl_feature_level = 460;
1015 
1016    caps->compute = true;
1017 
1018    caps->constant_buffer_offset_alignment =
1019       screen->info.props.limits.minUniformBufferOffsetAlignment;
1020 
1021    caps->query_timestamp = screen->timestamp_valid_bits > 0;
1022 
1023    caps->query_timestamp_bits = screen->timestamp_valid_bits;
1024 
1025    caps->timer_resolution = ceil(screen->info.props.limits.timestampPeriod);
1026 
1027    caps->min_map_buffer_alignment = 1 << MIN_SLAB_ORDER;
1028 
1029    caps->cube_map_array = screen->info.feats.features.imageCubeArray;
1030 
1031    caps->texture_buffer_objects = true;
1032    caps->primitive_restart = true;
1033 
1034    caps->bindless_texture =
1035       (zink_descriptor_mode != ZINK_DESCRIPTOR_MODE_DB ||
1036        (screen->info.db_props.maxDescriptorBufferBindings >= 2 &&
1037         screen->info.db_props.maxSamplerDescriptorBufferBindings >= 2)) &&
1038       screen->info.have_EXT_descriptor_indexing;
1039 
1040    caps->texture_buffer_offset_alignment =
1041       screen->info.props.limits.minTexelBufferOffsetAlignment;
1042 
1043    {
1044       enum pipe_texture_transfer_mode mode = PIPE_TEXTURE_TRANSFER_BLIT;
1045       if (!screen->is_cpu &&
1046           screen->info.have_KHR_8bit_storage &&
1047           screen->info.have_KHR_16bit_storage &&
1048           screen->info.have_KHR_shader_float16_int8)
1049          mode |= PIPE_TEXTURE_TRANSFER_COMPUTE;
1050       caps->texture_transfer_modes = mode;
1051    }
1052 
1053    caps->max_texel_buffer_elements =
1054       MIN2(get_smallest_buffer_heap(screen),
1055            screen->info.props.limits.maxTexelBufferElements);
1056 
1057    caps->endianness = PIPE_ENDIAN_NATIVE; /* unsure */
1058 
1059    caps->max_viewports =
1060       MIN2(screen->info.props.limits.maxViewports, PIPE_MAX_VIEWPORTS);
1061 
1062    caps->image_load_formatted =
1063       screen->info.feats.features.shaderStorageImageReadWithoutFormat;
1064 
1065    caps->image_store_formatted =
1066       screen->info.feats.features.shaderStorageImageWriteWithoutFormat;
1067 
1068    caps->mixed_framebuffer_sizes = true;
1069 
1070    caps->max_geometry_output_vertices =
1071       screen->info.props.limits.maxGeometryOutputVertices;
1072    caps->max_geometry_total_output_components =
1073       screen->info.props.limits.maxGeometryTotalOutputComponents;
1074 
1075    caps->max_texture_gather_components = 4;
1076 
1077    caps->min_texture_gather_offset = screen->info.props.limits.minTexelGatherOffset;
1078    caps->max_texture_gather_offset = screen->info.props.limits.maxTexelGatherOffset;
1079 
1080    caps->sampler_reduction_minmax_arb =
1081       screen->info.feats12.samplerFilterMinmax ||
1082       screen->info.have_EXT_sampler_filter_minmax;
1083 
1084    caps->opencl_integer_functions =
1085    caps->integer_multiply_32x16 = screen->info.have_INTEL_shader_integer_functions2;
1086 
1087    caps->fs_fine_derivative = true;
1088 
1089    caps->vendor_id = screen->info.props.vendorID;
1090    caps->device_id = screen->info.props.deviceID;
1091 
1092    caps->video_memory = get_video_mem(screen) >> 20;
1093    caps->uma = screen->info.props.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
1094 
1095    caps->max_vertex_attrib_stride =
1096       screen->info.props.limits.maxVertexInputBindingStride;
1097 
1098    caps->sampler_view_target = true;
1099 
1100    caps->vs_layer_viewport =
1101    caps->tes_layer_viewport =
1102       screen->info.have_EXT_shader_viewport_index_layer ||
1103       (screen->spirv_version >= SPIRV_VERSION(1, 5) &&
1104        screen->info.feats12.shaderOutputLayer &&
1105        screen->info.feats12.shaderOutputViewportIndex);
1106 
1107    caps->texture_float_linear = have_fp32_filter_linear(screen);
1108 
1109    caps->texture_half_float_linear = true;
1110 
1111    caps->shader_buffer_offset_alignment =
1112       screen->info.props.limits.minStorageBufferOffsetAlignment;
1113 
1114    caps->pci_group =
1115    caps->pci_bus =
1116    caps->pci_device =
1117    caps->pci_function = 0; /* TODO: figure these out */
1118 
1119    caps->cull_distance = screen->info.feats.features.shaderCullDistance;
1120 
1121    caps->sparse_buffer_page_size =
1122       screen->info.feats.features.sparseResidencyBuffer ? ZINK_SPARSE_BUFFER_PAGE_SIZE : 0;
1123 
1124    /* Sparse texture */
1125    caps->max_sparse_texture_size =
1126       screen->info.feats.features.sparseResidencyImage2D ?
1127       caps->max_texture_2d_size : 0;
1128    caps->max_sparse_3d_texture_size =
1129       screen->info.feats.features.sparseResidencyImage3D ?
1130       (1 << (caps->max_texture_3d_levels - 1)) : 0;
1131    caps->max_sparse_array_texture_layers =
1132       screen->info.feats.features.sparseResidencyImage2D ?
1133       caps->max_texture_array_layers : 0;
1134    caps->sparse_texture_full_array_cube_mipmaps =
1135       screen->info.feats.features.sparseResidencyImage2D;
1136    caps->query_sparse_texture_residency =
1137       screen->info.feats.features.sparseResidency2Samples &&
1138       screen->info.feats.features.shaderResourceResidency;
1139    caps->clamp_sparse_texture_lod =
1140       screen->info.feats.features.shaderResourceMinLod &&
1141       screen->info.feats.features.sparseResidency2Samples &&
1142       screen->info.feats.features.shaderResourceResidency;
1143 
1144    caps->viewport_subpixel_bits = screen->info.props.limits.viewportSubPixelBits;
1145 
1146    caps->max_gs_invocations = screen->info.props.limits.maxGeometryShaderInvocations;
1147 
1148    /* gallium handles this automatically */
1149    caps->max_combined_shader_buffers = 0;
1150 
1151    /* 1<<27 is required by VK spec */
1152    assert(screen->info.props.limits.maxStorageBufferRange >= 1 << 27);
1153    /* clamp to VK spec minimum */
1154    caps->max_shader_buffer_size =
1155       MIN2(get_smallest_buffer_heap(screen), screen->info.props.limits.maxStorageBufferRange);
1156 
1157    caps->fs_coord_origin_upper_left = true;
1158    caps->fs_coord_pixel_center_half_integer = true;
1159 
1160    caps->fs_coord_origin_lower_left = false;
1161    caps->fs_coord_pixel_center_integer = false;
1162 
1163    caps->fs_face_is_integer_sysval = true;
1164    caps->fs_point_is_sysval = true;
1165 
1166    caps->viewport_transform_lowered = true;
1167 
1168    caps->point_size_fixed =
1169       screen->info.have_KHR_maintenance5 ?
1170       PIPE_POINT_SIZE_LOWER_USER_ONLY : PIPE_POINT_SIZE_LOWER_ALWAYS;
1171    caps->flatshade = false;
1172    caps->alpha_test = false;
1173    caps->clip_planes = 0;
1174    caps->two_sided_color = false;
1175 
1176    caps->max_shader_patch_varyings =
1177       screen->info.props.limits.maxTessellationControlPerPatchOutputComponents / 4;
1178    /* need to reserve up to 60 of our varying components and 16 slots for streamout */
1179    caps->max_varyings =
1180       MIN2(screen->info.props.limits.maxVertexOutputComponents / 4 / 2, 16);
1181 
1182    caps->dmabuf =
1183 #if defined(HAVE_LIBDRM) && (DETECT_OS_LINUX || DETECT_OS_BSD)
1184       screen->info.have_KHR_external_memory_fd &&
1185       screen->info.have_EXT_external_memory_dma_buf &&
1186       screen->info.have_EXT_queue_family_foreign
1187       ? DRM_PRIME_CAP_IMPORT | DRM_PRIME_CAP_EXPORT : 0;
1188 #else
1189       0;
1190 #endif
1191 
1192    caps->depth_bounds_test = screen->info.feats.features.depthBounds;
1193 
1194    caps->post_depth_coverage = screen->info.have_EXT_post_depth_coverage;
1195 
1196    caps->string_marker = screen->instance_info->have_EXT_debug_utils;
1197 
1198    caps->min_line_width =
1199    caps->min_line_width_aa =
1200       screen->info.feats.features.wideLines ?
1201       MAX2(screen->info.props.limits.lineWidthRange[0], 0.01) : 1.0f;
1202 
1203    caps->min_point_size =
1204    caps->min_point_size_aa =
1205       screen->info.feats.features.largePoints ?
1206       MAX2(screen->info.props.limits.pointSizeRange[0], 0.01) : 1.0f;
1207 
1208    caps->line_width_granularity =
1209       screen->info.feats.features.wideLines ?
1210       screen->info.props.limits.lineWidthGranularity : 0.1f;
1211 
1212    caps->point_size_granularity =
1213       screen->info.feats.features.largePoints ?
1214       screen->info.props.limits.pointSizeGranularity : 0.1f;
1215 
1216    caps->max_line_width =
1217    caps->max_line_width_aa =
1218       screen->info.feats.features.wideLines ?
1219       screen->info.props.limits.lineWidthRange[1] : 1.0f;
1220 
1221    caps->max_point_size =
1222    caps->max_point_size_aa =
1223       screen->info.feats.features.largePoints ?
1224       screen->info.props.limits.pointSizeRange[1] : 1.0f;
1225 
1226    caps->max_texture_anisotropy =
1227       screen->info.feats.features.samplerAnisotropy ?
1228       screen->info.props.limits.maxSamplerAnisotropy : 1.0f;
1229 
1230    caps->max_texture_lod_bias = screen->info.props.limits.maxSamplerLodBias;
1231 }
1232 
1233 static VkSampleCountFlagBits
vk_sample_count_flags(uint32_t sample_count)1234 vk_sample_count_flags(uint32_t sample_count)
1235 {
1236    switch (sample_count) {
1237    case 1: return VK_SAMPLE_COUNT_1_BIT;
1238    case 2: return VK_SAMPLE_COUNT_2_BIT;
1239    case 4: return VK_SAMPLE_COUNT_4_BIT;
1240    case 8: return VK_SAMPLE_COUNT_8_BIT;
1241    case 16: return VK_SAMPLE_COUNT_16_BIT;
1242    case 32: return VK_SAMPLE_COUNT_32_BIT;
1243    case 64: return VK_SAMPLE_COUNT_64_BIT;
1244    default:
1245       return 0;
1246    }
1247 }
1248 
1249 static bool
zink_is_compute_copy_faster(struct pipe_screen * pscreen,enum pipe_format src_format,enum pipe_format dst_format,unsigned width,unsigned height,unsigned depth,bool cpu)1250 zink_is_compute_copy_faster(struct pipe_screen *pscreen,
1251                             enum pipe_format src_format,
1252                             enum pipe_format dst_format,
1253                             unsigned width,
1254                             unsigned height,
1255                             unsigned depth,
1256                             bool cpu)
1257 {
1258    if (cpu)
1259       /* very basic for now, probably even worse for some cases,
1260        * but fixes lots of others
1261        */
1262       return width * height * depth > 64 * 64;
1263    return false;
1264 }
1265 
1266 static bool
zink_is_format_supported(struct pipe_screen * pscreen,enum pipe_format format,enum pipe_texture_target target,unsigned sample_count,unsigned storage_sample_count,unsigned bind)1267 zink_is_format_supported(struct pipe_screen *pscreen,
1268                          enum pipe_format format,
1269                          enum pipe_texture_target target,
1270                          unsigned sample_count,
1271                          unsigned storage_sample_count,
1272                          unsigned bind)
1273 {
1274    struct zink_screen *screen = zink_screen(pscreen);
1275 
1276    if (storage_sample_count && !screen->info.feats.features.shaderStorageImageMultisample && bind & PIPE_BIND_SHADER_IMAGE)
1277       return false;
1278 
1279    if (format == PIPE_FORMAT_NONE)
1280       return screen->info.props.limits.framebufferNoAttachmentsSampleCounts &
1281              vk_sample_count_flags(sample_count);
1282 
1283    if (bind & PIPE_BIND_INDEX_BUFFER) {
1284       if (format == PIPE_FORMAT_R8_UINT &&
1285           !screen->info.have_EXT_index_type_uint8)
1286          return false;
1287       if (format != PIPE_FORMAT_R8_UINT &&
1288           format != PIPE_FORMAT_R16_UINT &&
1289           format != PIPE_FORMAT_R32_UINT)
1290          return false;
1291    }
1292 
1293    /* always use superset to determine feature support */
1294    VkFormat vkformat = zink_get_format(screen, PIPE_FORMAT_A8_UNORM ? zink_format_get_emulated_alpha(format) : format);
1295    if (vkformat == VK_FORMAT_UNDEFINED)
1296       return false;
1297 
1298    if (sample_count >= 1) {
1299       VkSampleCountFlagBits sample_mask = vk_sample_count_flags(sample_count);
1300       if (!sample_mask)
1301          return false;
1302       const struct util_format_description *desc = util_format_description(format);
1303       if (util_format_is_depth_or_stencil(format)) {
1304          if (util_format_has_depth(desc)) {
1305             if (bind & PIPE_BIND_DEPTH_STENCIL &&
1306                 (screen->info.props.limits.framebufferDepthSampleCounts & sample_mask) != sample_mask)
1307                return false;
1308             if (bind & PIPE_BIND_SAMPLER_VIEW &&
1309                 (screen->info.props.limits.sampledImageDepthSampleCounts & sample_mask) != sample_mask)
1310                return false;
1311          }
1312          if (util_format_has_stencil(desc)) {
1313             if (bind & PIPE_BIND_DEPTH_STENCIL &&
1314                 (screen->info.props.limits.framebufferStencilSampleCounts & sample_mask) != sample_mask)
1315                return false;
1316             if (bind & PIPE_BIND_SAMPLER_VIEW &&
1317                 (screen->info.props.limits.sampledImageStencilSampleCounts & sample_mask) != sample_mask)
1318                return false;
1319          }
1320       } else if (util_format_is_pure_integer(format)) {
1321          if (bind & PIPE_BIND_RENDER_TARGET &&
1322              !(screen->info.props.limits.framebufferColorSampleCounts & sample_mask))
1323             return false;
1324          if (bind & PIPE_BIND_SAMPLER_VIEW &&
1325              !(screen->info.props.limits.sampledImageIntegerSampleCounts & sample_mask))
1326             return false;
1327       } else {
1328          if (bind & PIPE_BIND_RENDER_TARGET &&
1329              !(screen->info.props.limits.framebufferColorSampleCounts & sample_mask))
1330             return false;
1331          if (bind & PIPE_BIND_SAMPLER_VIEW &&
1332              !(screen->info.props.limits.sampledImageColorSampleCounts & sample_mask))
1333             return false;
1334       }
1335       if (bind & PIPE_BIND_SHADER_IMAGE) {
1336           if (!(screen->info.props.limits.storageImageSampleCounts & sample_mask))
1337              return false;
1338       }
1339       VkResult ret;
1340       VkImageFormatProperties image_props;
1341       VkImageFormatProperties2 props2;
1342       props2.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2;
1343       props2.pNext = NULL;
1344       VkPhysicalDeviceImageFormatInfo2 info;
1345       info.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2;
1346       info.pNext = NULL;
1347       info.format = vkformat;
1348       info.flags = 0;
1349       info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1350       info.tiling = VK_IMAGE_TILING_OPTIMAL;
1351       switch (target) {
1352       case PIPE_TEXTURE_1D:
1353       case PIPE_TEXTURE_1D_ARRAY: {
1354          bool need_2D = false;
1355          if (util_format_is_depth_or_stencil(format))
1356             need_2D |= screen->need_2D_zs;
1357          info.type = need_2D ? VK_IMAGE_TYPE_2D : VK_IMAGE_TYPE_1D;
1358          break;
1359       }
1360 
1361       case PIPE_TEXTURE_CUBE:
1362       case PIPE_TEXTURE_CUBE_ARRAY:
1363          info.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
1364          FALLTHROUGH;
1365       case PIPE_TEXTURE_2D:
1366       case PIPE_TEXTURE_2D_ARRAY:
1367       case PIPE_TEXTURE_RECT:
1368          info.type = VK_IMAGE_TYPE_2D;
1369          break;
1370 
1371       case PIPE_TEXTURE_3D:
1372          info.type = VK_IMAGE_TYPE_3D;
1373          if (bind & (PIPE_BIND_RENDER_TARGET | PIPE_BIND_DEPTH_STENCIL))
1374             info.flags |= VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT;
1375          if (screen->info.have_EXT_image_2d_view_of_3d)
1376             info.flags |= VK_IMAGE_CREATE_2D_VIEW_COMPATIBLE_BIT_EXT;
1377          break;
1378 
1379       default:
1380          unreachable("unknown texture target");
1381       }
1382       u_foreach_bit(b, bind) {
1383          switch (1<<b) {
1384          case PIPE_BIND_RENDER_TARGET:
1385             info.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1386             break;
1387          case PIPE_BIND_DEPTH_STENCIL:
1388             info.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
1389             break;
1390          case PIPE_BIND_SAMPLER_VIEW:
1391             info.usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
1392             break;
1393          }
1394       }
1395 
1396       if (VKSCR(GetPhysicalDeviceImageFormatProperties2)) {
1397          ret = VKSCR(GetPhysicalDeviceImageFormatProperties2)(screen->pdev, &info, &props2);
1398          /* this is using VK_IMAGE_CREATE_EXTENDED_USAGE_BIT and can't be validated */
1399          if (vk_format_aspects(vkformat) & VK_IMAGE_ASPECT_PLANE_1_BIT)
1400             ret = VK_SUCCESS;
1401          image_props = props2.imageFormatProperties;
1402       } else {
1403          ret = VKSCR(GetPhysicalDeviceImageFormatProperties)(screen->pdev, vkformat, info.type,
1404                                                              info.tiling, info.usage, info.flags, &image_props);
1405       }
1406       if (ret != VK_SUCCESS)
1407          return false;
1408       if (!(sample_count & image_props.sampleCounts))
1409          return false;
1410    }
1411 
1412    const struct zink_format_props *props = zink_get_format_props(screen, format);
1413 
1414    if (target == PIPE_BUFFER) {
1415       if (bind & PIPE_BIND_VERTEX_BUFFER) {
1416          if (!(props->bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)) {
1417             enum pipe_format new_format = zink_decompose_vertex_format(format);
1418             if (!new_format)
1419                return false;
1420             if (!(zink_get_format_props(screen, new_format)->bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))
1421                return false;
1422          }
1423       }
1424 
1425       if (bind & PIPE_BIND_SAMPLER_VIEW &&
1426          !(props->bufferFeatures & VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT))
1427             return false;
1428 
1429       if (bind & PIPE_BIND_SHADER_IMAGE &&
1430           !(props->bufferFeatures & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT))
1431          return false;
1432    } else {
1433       /* all other targets are texture-targets */
1434       if (bind & PIPE_BIND_RENDER_TARGET &&
1435           !(props->optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
1436          return false;
1437 
1438       if (bind & PIPE_BIND_BLENDABLE &&
1439          !(props->optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT))
1440         return false;
1441 
1442       if (bind & PIPE_BIND_SAMPLER_VIEW &&
1443          !(props->optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT))
1444             return false;
1445 
1446       if (bind & PIPE_BIND_SAMPLER_REDUCTION_MINMAX &&
1447           !(props->optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT))
1448          return false;
1449 
1450       if ((bind & PIPE_BIND_SAMPLER_VIEW) || (bind & PIPE_BIND_RENDER_TARGET)) {
1451          /* if this is a 3-component texture, force gallium to give us 4 components by rejecting this one */
1452          const struct util_format_description *desc = util_format_description(format);
1453          if (desc->nr_channels == 3 &&
1454              (desc->block.bits == 24 || desc->block.bits == 48 || desc->block.bits == 96))
1455             return false;
1456       }
1457 
1458       if (bind & PIPE_BIND_DEPTH_STENCIL &&
1459           !(props->optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
1460          return false;
1461 
1462       if (bind & PIPE_BIND_SHADER_IMAGE &&
1463           !(props->optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT))
1464          return false;
1465    }
1466 
1467    return true;
1468 }
1469 
1470 static void
zink_set_damage_region(struct pipe_screen * pscreen,struct pipe_resource * pres,unsigned int nrects,const struct pipe_box * rects)1471 zink_set_damage_region(struct pipe_screen *pscreen, struct pipe_resource *pres, unsigned int nrects, const struct pipe_box *rects)
1472 {
1473    struct zink_resource *res = zink_resource(pres);
1474 
1475    for (unsigned i = 0; i < nrects; i++) {
1476       int y = pres->height0 - rects[i].y - rects[i].height;
1477       /* convert back to coord-based rects to use coordinate calcs */
1478       struct u_rect currect = {
1479          .x0 = res->damage.offset.x,
1480          .y0 = res->damage.offset.y,
1481          .x1 = res->damage.offset.x + res->damage.extent.width,
1482          .y1 = res->damage.offset.y + res->damage.extent.height,
1483       };
1484       struct u_rect newrect = {
1485          .x0 = rects[i].x,
1486          .y0 = y,
1487          .x1 = rects[i].x + rects[i].width,
1488          .y1 = y + rects[i].height,
1489       };
1490       struct u_rect u;
1491       u_rect_union(&u, &currect, &newrect);
1492       res->damage.extent.width = u.y1 - u.y0;
1493       res->damage.extent.height = u.x1 - u.x0;
1494       res->damage.offset.x = u.x0;
1495       res->damage.offset.y = u.y0;
1496    }
1497 
1498    res->use_damage = nrects > 0;
1499 }
1500 
1501 static void
zink_destroy_screen(struct pipe_screen * pscreen)1502 zink_destroy_screen(struct pipe_screen *pscreen)
1503 {
1504    struct zink_screen *screen = zink_screen(pscreen);
1505 
1506    if (screen->renderdoc_capture_all && p_atomic_dec_zero(&num_screens))
1507       screen->renderdoc_api->EndFrameCapture(RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(screen->instance), NULL);
1508 
1509    hash_table_foreach(&screen->dts, entry)
1510       zink_kopper_deinit_displaytarget(screen, entry->data);
1511 
1512    if (screen->copy_context)
1513       screen->copy_context->base.destroy(&screen->copy_context->base);
1514 
1515    struct zink_batch_state *bs = screen->free_batch_states;
1516    while (bs) {
1517       struct zink_batch_state *bs_next = bs->next;
1518       zink_batch_state_destroy(screen, bs);
1519       bs = bs_next;
1520    }
1521 
1522    if (VK_NULL_HANDLE != screen->debugUtilsCallbackHandle) {
1523       VKSCR(DestroyDebugUtilsMessengerEXT)(screen->instance, screen->debugUtilsCallbackHandle, NULL);
1524    }
1525 
1526    util_vertex_state_cache_deinit(&screen->vertex_state_cache);
1527 
1528    if (screen->gfx_push_constant_layout)
1529       VKSCR(DestroyPipelineLayout)(screen->dev, screen->gfx_push_constant_layout, NULL);
1530 
1531    u_transfer_helper_destroy(pscreen->transfer_helper);
1532    if (util_queue_is_initialized(&screen->cache_get_thread)) {
1533       util_queue_finish(&screen->cache_get_thread);
1534       util_queue_destroy(&screen->cache_get_thread);
1535    }
1536 #ifdef ENABLE_SHADER_CACHE
1537    if (screen->disk_cache && util_queue_is_initialized(&screen->cache_put_thread)) {
1538       util_queue_finish(&screen->cache_put_thread);
1539       disk_cache_wait_for_idle(screen->disk_cache);
1540       util_queue_destroy(&screen->cache_put_thread);
1541    }
1542 #endif
1543    disk_cache_destroy(screen->disk_cache);
1544 
1545    /* we don't have an API to check if a set is already initialized */
1546    for (unsigned i = 0; i < ARRAY_SIZE(screen->pipeline_libs); i++)
1547       if (screen->pipeline_libs[i].table)
1548          _mesa_set_clear(&screen->pipeline_libs[i], NULL);
1549 
1550    zink_bo_deinit(screen);
1551    util_live_shader_cache_deinit(&screen->shaders);
1552 
1553    zink_descriptor_layouts_deinit(screen);
1554 
1555    if (screen->sem)
1556       VKSCR(DestroySemaphore)(screen->dev, screen->sem, NULL);
1557 
1558    if (screen->fence)
1559       VKSCR(DestroyFence)(screen->dev, screen->fence, NULL);
1560 
1561    if (util_queue_is_initialized(&screen->flush_queue))
1562       util_queue_destroy(&screen->flush_queue);
1563 
1564    while (util_dynarray_contains(&screen->semaphores, VkSemaphore))
1565       VKSCR(DestroySemaphore)(screen->dev, util_dynarray_pop(&screen->semaphores, VkSemaphore), NULL);
1566    while (util_dynarray_contains(&screen->fd_semaphores, VkSemaphore))
1567       VKSCR(DestroySemaphore)(screen->dev, util_dynarray_pop(&screen->fd_semaphores, VkSemaphore), NULL);
1568    if (screen->bindless_layout)
1569       VKSCR(DestroyDescriptorSetLayout)(screen->dev, screen->bindless_layout, NULL);
1570 
1571    if (screen->dev) {
1572       simple_mtx_lock(&device_lock);
1573       set_foreach(&device_table, entry) {
1574          struct zink_device *zdev = (void*)entry->key;
1575          if (zdev->pdev == screen->pdev) {
1576             zdev->refcount--;
1577             if (!zdev->refcount) {
1578                VKSCR(DestroyDevice)(zdev->dev, NULL);
1579                _mesa_set_remove(&device_table, entry);
1580                free(zdev);
1581                break;
1582             }
1583          }
1584       }
1585       if (!device_table.entries) {
1586          ralloc_free(device_table.table);
1587          device_table.table = NULL;
1588       }
1589       simple_mtx_unlock(&device_lock);
1590    }
1591 
1592    simple_mtx_lock(&instance_lock);
1593    if (screen->instance && --instance_refcount == 0)
1594       VKSCR(DestroyInstance)(instance, NULL);
1595    simple_mtx_unlock(&instance_lock);
1596 
1597    util_idalloc_mt_fini(&screen->buffer_ids);
1598 
1599    if (screen->loader_lib)
1600       util_dl_close(screen->loader_lib);
1601 
1602    if (screen->drm_fd != -1)
1603       close(screen->drm_fd);
1604 
1605    slab_destroy_parent(&screen->transfer_pool);
1606    ralloc_free(screen);
1607    glsl_type_singleton_decref();
1608 }
1609 
1610 static int
zink_get_display_device(const struct zink_screen * screen,uint32_t pdev_count,const VkPhysicalDevice * pdevs,int64_t dev_major,int64_t dev_minor)1611 zink_get_display_device(const struct zink_screen *screen, uint32_t pdev_count,
1612                         const VkPhysicalDevice *pdevs, int64_t dev_major,
1613                         int64_t dev_minor)
1614 {
1615    VkPhysicalDeviceDrmPropertiesEXT drm_props = {
1616       .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRM_PROPERTIES_EXT,
1617    };
1618    VkPhysicalDeviceProperties2 props = {
1619       .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,
1620       .pNext = &drm_props,
1621    };
1622 
1623    for (uint32_t i = 0; i < pdev_count; ++i) {
1624       VKSCR(GetPhysicalDeviceProperties2)(pdevs[i], &props);
1625       if (drm_props.renderMajor == dev_major &&
1626           drm_props.renderMinor == dev_minor)
1627          return i;
1628    }
1629 
1630    return -1;
1631 }
1632 
1633 static int
zink_get_cpu_device_type(const struct zink_screen * screen,uint32_t pdev_count,const VkPhysicalDevice * pdevs)1634 zink_get_cpu_device_type(const struct zink_screen *screen, uint32_t pdev_count,
1635                          const VkPhysicalDevice *pdevs)
1636 {
1637    VkPhysicalDeviceProperties props;
1638 
1639    for (uint32_t i = 0; i < pdev_count; ++i) {
1640       VKSCR(GetPhysicalDeviceProperties)(pdevs[i], &props);
1641 
1642       /* if user wants cpu, only give them cpu */
1643       if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU)
1644          return i;
1645    }
1646 
1647    mesa_loge("ZINK: CPU device requested but none found!");
1648 
1649    return -1;
1650 }
1651 
1652 static int
zink_match_adapter_luid(const struct zink_screen * screen,uint32_t pdev_count,const VkPhysicalDevice * pdevs,uint64_t adapter_luid)1653 zink_match_adapter_luid(const struct zink_screen *screen, uint32_t pdev_count, const VkPhysicalDevice *pdevs, uint64_t adapter_luid)
1654 {
1655    VkPhysicalDeviceVulkan11Properties props11 = {
1656       VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES
1657    };
1658    VkPhysicalDeviceProperties2 props = {
1659       VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,
1660       &props11
1661    };
1662 
1663    for (uint32_t i = 0; i < pdev_count; ++i) {
1664       VKSCR(GetPhysicalDeviceProperties2)(pdevs[i], &props);
1665 
1666       if (!memcmp(props11.deviceLUID, &adapter_luid, sizeof(adapter_luid)))
1667          return i;
1668    }
1669 
1670    mesa_loge("ZINK: matching LUID not found!");
1671 
1672    return -1;
1673 }
1674 
1675 static void
choose_pdev(struct zink_screen * screen,int64_t dev_major,int64_t dev_minor,uint64_t adapter_luid)1676 choose_pdev(struct zink_screen *screen, int64_t dev_major, int64_t dev_minor, uint64_t adapter_luid)
1677 {
1678    bool cpu = debug_get_bool_option("LIBGL_ALWAYS_SOFTWARE", false) ||
1679               debug_get_bool_option("D3D_ALWAYS_SOFTWARE", false);
1680 
1681    if (cpu || (dev_major > 0 && dev_major < 255) || adapter_luid) {
1682       uint32_t pdev_count;
1683       int idx;
1684       VkPhysicalDevice *pdevs;
1685       VkResult result = VKSCR(EnumeratePhysicalDevices)(screen->instance, &pdev_count, NULL);
1686       if (result != VK_SUCCESS) {
1687          if (!screen->driver_name_is_inferred)
1688             mesa_loge("ZINK: vkEnumeratePhysicalDevices failed (%s)", vk_Result_to_str(result));
1689          return;
1690       }
1691 
1692       if (!pdev_count)
1693          return;
1694 
1695       pdevs = malloc(sizeof(*pdevs) * pdev_count);
1696       if (!pdevs) {
1697          if (!screen->driver_name_is_inferred)
1698             mesa_loge("ZINK: failed to allocate pdevs!");
1699          return;
1700       }
1701       result = VKSCR(EnumeratePhysicalDevices)(screen->instance, &pdev_count, pdevs);
1702       assert(result == VK_SUCCESS);
1703       assert(pdev_count > 0);
1704 
1705       if (adapter_luid)
1706          idx = zink_match_adapter_luid(screen, pdev_count, pdevs, adapter_luid);
1707       else if (cpu)
1708          idx = zink_get_cpu_device_type(screen, pdev_count, pdevs);
1709       else
1710          idx = zink_get_display_device(screen, pdev_count, pdevs, dev_major,
1711                                        dev_minor);
1712 
1713       if (idx != -1)
1714          /* valid cpu device */
1715          screen->pdev = pdevs[idx];
1716 
1717       free(pdevs);
1718 
1719       if (idx == -1)
1720          return;
1721 
1722    } else {
1723       VkPhysicalDevice pdev;
1724       unsigned pdev_count = 1;
1725       VkResult result = VKSCR(EnumeratePhysicalDevices)(screen->instance, &pdev_count, &pdev);
1726       if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
1727          if (!screen->driver_name_is_inferred)
1728             mesa_loge("ZINK: vkEnumeratePhysicalDevices failed (%s)", vk_Result_to_str(result));
1729          return;
1730       }
1731       if (!pdev_count)
1732          return;
1733       screen->pdev = pdev;
1734    }
1735    VKSCR(GetPhysicalDeviceProperties)(screen->pdev, &screen->info.props);
1736 
1737    /* allow software rendering only if forced by the user */
1738    if (!cpu && screen->info.props.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU) {
1739       screen->pdev = VK_NULL_HANDLE;
1740       return;
1741    }
1742 
1743    screen->info.device_version = screen->info.props.apiVersion;
1744 
1745    /* runtime version is the lesser of the instance version and device version */
1746    screen->vk_version = MIN2(screen->info.device_version, screen->instance_info->loader_version);
1747 
1748    /* calculate SPIR-V version based on VK version */
1749    if (screen->vk_version >= VK_MAKE_VERSION(1, 3, 0))
1750       screen->spirv_version = SPIRV_VERSION(1, 6);
1751    else if (screen->vk_version >= VK_MAKE_VERSION(1, 2, 0))
1752       screen->spirv_version = SPIRV_VERSION(1, 5);
1753    else if (screen->vk_version >= VK_MAKE_VERSION(1, 1, 0))
1754       screen->spirv_version = SPIRV_VERSION(1, 3);
1755    else
1756       screen->spirv_version = SPIRV_VERSION(1, 0);
1757 }
1758 
1759 static void
update_queue_props(struct zink_screen * screen)1760 update_queue_props(struct zink_screen *screen)
1761 {
1762    uint32_t num_queues;
1763    VKSCR(GetPhysicalDeviceQueueFamilyProperties)(screen->pdev, &num_queues, NULL);
1764    assert(num_queues > 0);
1765 
1766    VkQueueFamilyProperties *props = malloc(sizeof(*props) * num_queues);
1767    if (!props) {
1768       mesa_loge("ZINK: failed to allocate props!");
1769       return;
1770    }
1771 
1772    VKSCR(GetPhysicalDeviceQueueFamilyProperties)(screen->pdev, &num_queues, props);
1773 
1774    bool found_gfx = false;
1775    uint32_t sparse_only = UINT32_MAX;
1776    screen->sparse_queue = UINT32_MAX;
1777    for (uint32_t i = 0; i < num_queues; i++) {
1778       if (props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
1779          if (found_gfx)
1780             continue;
1781          screen->sparse_queue = screen->gfx_queue = i;
1782          screen->max_queues = props[i].queueCount;
1783          screen->timestamp_valid_bits = props[i].timestampValidBits;
1784          found_gfx = true;
1785       } else if (props[i].queueFlags & VK_QUEUE_SPARSE_BINDING_BIT)
1786          sparse_only = i;
1787    }
1788    if (sparse_only != UINT32_MAX)
1789       screen->sparse_queue = sparse_only;
1790    free(props);
1791 }
1792 
1793 static void
init_queue(struct zink_screen * screen)1794 init_queue(struct zink_screen *screen)
1795 {
1796    simple_mtx_init(&screen->queue_lock, mtx_plain);
1797    VKSCR(GetDeviceQueue)(screen->dev, screen->gfx_queue, 0, &screen->queue);
1798    if (screen->sparse_queue != screen->gfx_queue)
1799       VKSCR(GetDeviceQueue)(screen->dev, screen->sparse_queue, 0, &screen->queue_sparse);
1800    else
1801       screen->queue_sparse = screen->queue;
1802 }
1803 
1804 static void
zink_flush_frontbuffer(struct pipe_screen * pscreen,struct pipe_context * pctx,struct pipe_resource * pres,unsigned level,unsigned layer,void * winsys_drawable_handle,unsigned nboxes,struct pipe_box * sub_box)1805 zink_flush_frontbuffer(struct pipe_screen *pscreen,
1806                        struct pipe_context *pctx,
1807                        struct pipe_resource *pres,
1808                        unsigned level, unsigned layer,
1809                        void *winsys_drawable_handle,
1810                        unsigned nboxes,
1811                        struct pipe_box *sub_box)
1812 {
1813    struct zink_screen *screen = zink_screen(pscreen);
1814    struct zink_resource *res = zink_resource(pres);
1815    struct zink_context *ctx = zink_context(pctx);
1816 
1817    /* if the surface is no longer a swapchain, this is a no-op */
1818    if (!zink_is_swapchain(res))
1819       return;
1820 
1821    ctx = zink_tc_context_unwrap(pctx);
1822 
1823    if (!zink_kopper_acquired(res->obj->dt, res->obj->dt_idx)) {
1824       /* swapbuffers to an undefined surface: acquire and present garbage */
1825       zink_kopper_acquire(ctx, res, UINT64_MAX);
1826       zink_resource_reference(&ctx->needs_present, res);
1827       /* set batch usage to submit acquire semaphore */
1828       zink_batch_resource_usage_set(ctx->bs, res, true, false);
1829       /* ensure the resource is set up to present garbage */
1830       ctx->base.flush_resource(&ctx->base, pres);
1831    }
1832 
1833    /* handle any outstanding acquire submits (not just from above) */
1834    if (ctx->swapchain || ctx->needs_present) {
1835       ctx->bs->has_work = true;
1836       pctx->flush(pctx, NULL, PIPE_FLUSH_END_OF_FRAME);
1837       if (ctx->last_batch_state && screen->threaded_submit) {
1838          struct zink_batch_state *bs = ctx->last_batch_state;
1839          util_queue_fence_wait(&bs->flush_completed);
1840       }
1841    }
1842    res->use_damage = false;
1843 
1844    /* always verify that this was acquired */
1845    assert(zink_kopper_acquired(res->obj->dt, res->obj->dt_idx));
1846    zink_kopper_present_queue(screen, res, nboxes, sub_box);
1847 }
1848 
1849 bool
zink_is_depth_format_supported(struct zink_screen * screen,VkFormat format)1850 zink_is_depth_format_supported(struct zink_screen *screen, VkFormat format)
1851 {
1852    VkFormatProperties props;
1853    VKSCR(GetPhysicalDeviceFormatProperties)(screen->pdev, format, &props);
1854    return (props.linearTilingFeatures | props.optimalTilingFeatures) &
1855           VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT;
1856 }
1857 
1858 VkFormat
zink_get_format(struct zink_screen * screen,enum pipe_format format)1859 zink_get_format(struct zink_screen *screen, enum pipe_format format)
1860 {
1861    if (format == PIPE_FORMAT_A8_UNORM && !screen->driver_workarounds.missing_a8_unorm)
1862       return VK_FORMAT_A8_UNORM_KHR;
1863    else if (!screen->driver_workarounds.broken_l4a4 || format != PIPE_FORMAT_L4A4_UNORM)
1864       format = zink_format_get_emulated_alpha(format);
1865 
1866    VkFormat ret = vk_format_from_pipe_format(zink_format_emulate_x8(format));
1867 
1868    if (format == PIPE_FORMAT_X32_S8X24_UINT &&
1869        screen->have_D32_SFLOAT_S8_UINT)
1870       return VK_FORMAT_D32_SFLOAT_S8_UINT;
1871 
1872    if (format == PIPE_FORMAT_X24S8_UINT)
1873       /* valid when using aspects to extract stencil,
1874        * fails format test because it's emulated */
1875       ret = VK_FORMAT_D24_UNORM_S8_UINT;
1876 
1877    if (ret == VK_FORMAT_X8_D24_UNORM_PACK32 &&
1878        !screen->have_X8_D24_UNORM_PACK32) {
1879       assert(zink_is_depth_format_supported(screen, VK_FORMAT_D32_SFLOAT));
1880       return VK_FORMAT_D32_SFLOAT;
1881    }
1882 
1883    if (ret == VK_FORMAT_D24_UNORM_S8_UINT &&
1884        !screen->have_D24_UNORM_S8_UINT) {
1885       assert(screen->have_D32_SFLOAT_S8_UINT);
1886       return VK_FORMAT_D32_SFLOAT_S8_UINT;
1887    }
1888 
1889    if ((ret == VK_FORMAT_A4B4G4R4_UNORM_PACK16 &&
1890         !screen->info.format_4444_feats.formatA4B4G4R4) ||
1891        (ret == VK_FORMAT_A4R4G4B4_UNORM_PACK16 &&
1892         !screen->info.format_4444_feats.formatA4R4G4B4))
1893       return VK_FORMAT_UNDEFINED;
1894 
1895    if (format == PIPE_FORMAT_R4A4_UNORM)
1896       return VK_FORMAT_R4G4_UNORM_PACK8;
1897 
1898    return ret;
1899 }
1900 
1901 void
zink_convert_color(const struct zink_screen * screen,enum pipe_format format,union pipe_color_union * dst,const union pipe_color_union * src)1902 zink_convert_color(const struct zink_screen *screen, enum pipe_format format,
1903                    union pipe_color_union *dst,
1904                    const union pipe_color_union *src)
1905 {
1906    const struct util_format_description *desc = util_format_description(format);
1907    union pipe_color_union tmp = *src;
1908 
1909    for (unsigned i = 0; i < 4; i++)
1910       zink_format_clamp_channel_color(desc, &tmp, src, i);
1911 
1912    if (zink_format_is_emulated_alpha(format) &&
1913        /* Don't swizzle colors if the driver supports real A8_UNORM */
1914        (format != PIPE_FORMAT_A8_UNORM ||
1915          screen->driver_workarounds.missing_a8_unorm)) {
1916       if (util_format_is_alpha(format)) {
1917          tmp.ui[0] = tmp.ui[3];
1918          tmp.ui[1] = 0;
1919          tmp.ui[2] = 0;
1920          tmp.ui[3] = 0;
1921       } else if (util_format_is_luminance(format)) {
1922          tmp.ui[1] = 0;
1923          tmp.ui[2] = 0;
1924          tmp.f[3] = 1.0;
1925       } else if (util_format_is_luminance_alpha(format)) {
1926          tmp.ui[1] = tmp.ui[3];
1927          tmp.ui[2] = 0;
1928          tmp.f[3] = 1.0;
1929       } else /* zink_format_is_red_alpha */ {
1930          tmp.ui[1] = tmp.ui[3];
1931          tmp.ui[2] = 0;
1932          tmp.ui[3] = 0;
1933       }
1934    }
1935 
1936    memcpy(dst, &tmp, sizeof(union pipe_color_union));
1937 }
1938 
1939 static bool
check_have_device_time(struct zink_screen * screen)1940 check_have_device_time(struct zink_screen *screen)
1941 {
1942    uint32_t num_domains = 0;
1943    VkTimeDomainEXT domains[8]; //current max is 4
1944    VkResult result = VKSCR(GetPhysicalDeviceCalibrateableTimeDomainsEXT)(screen->pdev, &num_domains, NULL);
1945    if (result != VK_SUCCESS) {
1946       mesa_loge("ZINK: vkGetPhysicalDeviceCalibrateableTimeDomainsEXT failed (%s)", vk_Result_to_str(result));
1947    }
1948    assert(num_domains > 0);
1949    assert(num_domains < ARRAY_SIZE(domains));
1950 
1951    result = VKSCR(GetPhysicalDeviceCalibrateableTimeDomainsEXT)(screen->pdev, &num_domains, domains);
1952    if (result != VK_SUCCESS) {
1953       mesa_loge("ZINK: vkGetPhysicalDeviceCalibrateableTimeDomainsEXT failed (%s)", vk_Result_to_str(result));
1954    }
1955 
1956    /* VK_TIME_DOMAIN_DEVICE_EXT is used for the ctx->get_timestamp hook and is the only one we really need */
1957    for (unsigned i = 0; i < num_domains; i++) {
1958       if (domains[i] == VK_TIME_DOMAIN_DEVICE_EXT) {
1959          return true;
1960       }
1961    }
1962 
1963    return false;
1964 }
1965 
1966 static void
zink_error(const char * msg)1967 zink_error(const char *msg)
1968 {
1969 }
1970 
1971 static void
zink_warn(const char * msg)1972 zink_warn(const char *msg)
1973 {
1974 }
1975 
1976 static void
zink_info(const char * msg)1977 zink_info(const char *msg)
1978 {
1979 }
1980 
1981 static void
zink_msg(const char * msg)1982 zink_msg(const char *msg)
1983 {
1984 }
1985 
1986 static VKAPI_ATTR VkBool32 VKAPI_CALL
zink_debug_util_callback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,VkDebugUtilsMessageTypeFlagsEXT messageType,const VkDebugUtilsMessengerCallbackDataEXT * pCallbackData,void * pUserData)1987 zink_debug_util_callback(
1988     VkDebugUtilsMessageSeverityFlagBitsEXT           messageSeverity,
1989     VkDebugUtilsMessageTypeFlagsEXT                  messageType,
1990     const VkDebugUtilsMessengerCallbackDataEXT      *pCallbackData,
1991     void                                            *pUserData)
1992 {
1993    // Pick message prefix and color to use.
1994    // Only MacOS and Linux have been tested for color support
1995    if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) {
1996       zink_error(pCallbackData->pMessage);
1997    } else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) {
1998       zink_warn(pCallbackData->pMessage);
1999    } else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) {
2000       zink_info(pCallbackData->pMessage);
2001    } else
2002       zink_msg(pCallbackData->pMessage);
2003 
2004    return VK_FALSE;
2005 }
2006 
2007 static bool
create_debug(struct zink_screen * screen)2008 create_debug(struct zink_screen *screen)
2009 {
2010    VkDebugUtilsMessengerCreateInfoEXT vkDebugUtilsMessengerCreateInfoEXT = {
2011        VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
2012        NULL,
2013        0,  // flags
2014        VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
2015        VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT |
2016        VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
2017        VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,
2018        VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
2019        VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
2020        VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,
2021        zink_debug_util_callback,
2022        NULL
2023    };
2024 
2025    VkDebugUtilsMessengerEXT vkDebugUtilsCallbackEXT = VK_NULL_HANDLE;
2026 
2027    VkResult result = VKSCR(CreateDebugUtilsMessengerEXT)(
2028            screen->instance,
2029            &vkDebugUtilsMessengerCreateInfoEXT,
2030            NULL,
2031            &vkDebugUtilsCallbackEXT);
2032    if (result != VK_SUCCESS) {
2033       mesa_loge("ZINK: vkCreateDebugUtilsMessengerEXT failed (%s)", vk_Result_to_str(result));
2034    }
2035 
2036    screen->debugUtilsCallbackHandle = vkDebugUtilsCallbackEXT;
2037 
2038    return true;
2039 }
2040 
2041 static bool
zink_internal_setup_moltenvk(struct zink_screen * screen)2042 zink_internal_setup_moltenvk(struct zink_screen *screen)
2043 {
2044 #if defined(MVK_VERSION)
2045    // MoltenVK only supports VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE in newer Metal versions
2046    // disable unless we can get MoltenVK to confirm it is supported
2047    screen->have_dynamic_state_vertex_input_binding_stride = false;
2048 
2049    if (!screen->instance_info->have_MVK_moltenvk)
2050       return true;
2051 
2052    GET_PROC_ADDR_INSTANCE_LOCAL(screen, screen->instance, GetMoltenVKConfigurationMVK);
2053    GET_PROC_ADDR_INSTANCE_LOCAL(screen, screen->instance, SetMoltenVKConfigurationMVK);
2054    GET_PROC_ADDR_INSTANCE_LOCAL(screen, screen->instance, GetVersionStringsMVK);
2055    GET_PROC_ADDR_INSTANCE_LOCAL(screen, screen->instance, GetPhysicalDeviceMetalFeaturesMVK);
2056 
2057    if (vk_GetVersionStringsMVK) {
2058       char molten_version[64] = {0};
2059       char vulkan_version[64] = {0};
2060 
2061       vk_GetVersionStringsMVK(molten_version, sizeof(molten_version) - 1, vulkan_version, sizeof(vulkan_version) - 1);
2062 
2063       printf("zink: MoltenVK %s Vulkan %s \n", molten_version, vulkan_version);
2064    }
2065 
2066    if (vk_GetMoltenVKConfigurationMVK && vk_SetMoltenVKConfigurationMVK) {
2067       MVKConfiguration molten_config = {0};
2068       size_t molten_config_size = sizeof(molten_config);
2069 
2070       VkResult res = vk_GetMoltenVKConfigurationMVK(screen->instance, &molten_config, &molten_config_size);
2071       if (res == VK_SUCCESS || res == VK_INCOMPLETE) {
2072          // Needed to allow MoltenVK to accept VkImageView swizzles.
2073          // Encountered when using VK_FORMAT_R8G8_UNORM
2074          molten_config.fullImageViewSwizzle = VK_TRUE;
2075          vk_SetMoltenVKConfigurationMVK(screen->instance, &molten_config, &molten_config_size);
2076       }
2077    }
2078 
2079    if (vk_GetPhysicalDeviceMetalFeaturesMVK) {
2080       MVKPhysicalDeviceMetalFeatures metal_features={0};
2081       size_t metal_features_size = sizeof(metal_features);
2082 
2083       VkResult res = vk_GetPhysicalDeviceMetalFeaturesMVK(screen->pdev, &metal_features, &metal_features_size);
2084       if (res == VK_SUCCESS) {
2085         screen->have_dynamic_state_vertex_input_binding_stride = metal_features.dynamicVertexStride;
2086       }
2087    }
2088 #endif // MVK_VERSION
2089 
2090    return true;
2091 }
2092 
2093 void
zink_init_format_props(struct zink_screen * screen,enum pipe_format pformat)2094 zink_init_format_props(struct zink_screen *screen, enum pipe_format pformat)
2095 {
2096    VkFormat format;
2097 retry:
2098    format = zink_get_format(screen, pformat);
2099    if (!format)
2100       return;
2101    if (VKSCR(GetPhysicalDeviceFormatProperties2)) {
2102       VkFormatProperties2 props = {0};
2103       props.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
2104 
2105       VkDrmFormatModifierPropertiesListEXT mod_props;
2106       VkDrmFormatModifierPropertiesEXT mods[128];
2107       if (screen->info.have_EXT_image_drm_format_modifier) {
2108          mod_props.sType = VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT;
2109          mod_props.pNext = NULL;
2110          mod_props.drmFormatModifierCount = ARRAY_SIZE(mods);
2111          mod_props.pDrmFormatModifierProperties = mods;
2112          props.pNext = &mod_props;
2113       }
2114       VkFormatProperties3 props3 = {0};
2115       if (screen->info.have_KHR_format_feature_flags2 || screen->info.have_vulkan13) {
2116          props3.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3;
2117          props3.pNext = props.pNext;
2118          props.pNext = &props3;
2119       }
2120 
2121       VKSCR(GetPhysicalDeviceFormatProperties2)(screen->pdev, format, &props);
2122 
2123       if (screen->info.have_KHR_format_feature_flags2 || screen->info.have_vulkan13) {
2124          screen->format_props[pformat].linearTilingFeatures = props3.linearTilingFeatures;
2125          screen->format_props[pformat].optimalTilingFeatures = props3.optimalTilingFeatures;
2126          screen->format_props[pformat].bufferFeatures = props3.bufferFeatures;
2127 
2128          if (props3.linearTilingFeatures & VK_FORMAT_FEATURE_2_LINEAR_COLOR_ATTACHMENT_BIT_NV)
2129             screen->format_props[pformat].linearTilingFeatures |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
2130       } else {
2131          // MoltenVk is 1.2 API
2132          screen->format_props[pformat].linearTilingFeatures = props.formatProperties.linearTilingFeatures;
2133          screen->format_props[pformat].optimalTilingFeatures = props.formatProperties.optimalTilingFeatures;
2134          screen->format_props[pformat].bufferFeatures = props.formatProperties.bufferFeatures;
2135       }
2136 
2137       if (screen->info.have_EXT_image_drm_format_modifier && mod_props.drmFormatModifierCount) {
2138          screen->modifier_props[pformat].drmFormatModifierCount = mod_props.drmFormatModifierCount;
2139          screen->modifier_props[pformat].pDrmFormatModifierProperties = ralloc_array(screen, VkDrmFormatModifierPropertiesEXT, mod_props.drmFormatModifierCount);
2140          if (mod_props.pDrmFormatModifierProperties) {
2141             for (unsigned j = 0; j < mod_props.drmFormatModifierCount; j++)
2142                screen->modifier_props[pformat].pDrmFormatModifierProperties[j] = mod_props.pDrmFormatModifierProperties[j];
2143          }
2144       }
2145    } else {
2146       VkFormatProperties props = {0};
2147       VKSCR(GetPhysicalDeviceFormatProperties)(screen->pdev, format, &props);
2148       screen->format_props[pformat].linearTilingFeatures = props.linearTilingFeatures;
2149       screen->format_props[pformat].optimalTilingFeatures = props.optimalTilingFeatures;
2150       screen->format_props[pformat].bufferFeatures = props.bufferFeatures;
2151    }
2152    if (pformat == PIPE_FORMAT_A8_UNORM && !screen->driver_workarounds.missing_a8_unorm) {
2153       if (!screen->format_props[pformat].linearTilingFeatures &&
2154             !screen->format_props[pformat].optimalTilingFeatures &&
2155             !screen->format_props[pformat].bufferFeatures) {
2156          screen->driver_workarounds.missing_a8_unorm = true;
2157          goto retry;
2158       }
2159    }
2160    if (zink_format_is_emulated_alpha(pformat)) {
2161       VkFormatFeatureFlags blocked = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
2162       screen->format_props[pformat].linearTilingFeatures &= ~blocked;
2163       screen->format_props[pformat].optimalTilingFeatures &= ~blocked;
2164       screen->format_props[pformat].bufferFeatures = 0;
2165    }
2166    screen->format_props_init[pformat] = true;
2167 }
2168 
2169 static void
check_vertex_formats(struct zink_screen * screen)2170 check_vertex_formats(struct zink_screen *screen)
2171 {
2172    /* from vbuf */
2173    enum pipe_format format_list[] = {
2174       /* not supported by vk
2175       PIPE_FORMAT_R32_FIXED,
2176       PIPE_FORMAT_R32G32_FIXED,
2177       PIPE_FORMAT_R32G32B32_FIXED,
2178       PIPE_FORMAT_R32G32B32A32_FIXED,
2179       */
2180       PIPE_FORMAT_R16_FLOAT,
2181       PIPE_FORMAT_R16G16_FLOAT,
2182       PIPE_FORMAT_R16G16B16_FLOAT,
2183       PIPE_FORMAT_R16G16B16A16_FLOAT,
2184       /* not supported by vk
2185       PIPE_FORMAT_R64_FLOAT,
2186       PIPE_FORMAT_R64G64_FLOAT,
2187       PIPE_FORMAT_R64G64B64_FLOAT,
2188       PIPE_FORMAT_R64G64B64A64_FLOAT,
2189       PIPE_FORMAT_R32_UNORM,
2190       PIPE_FORMAT_R32G32_UNORM,
2191       PIPE_FORMAT_R32G32B32_UNORM,
2192       PIPE_FORMAT_R32G32B32A32_UNORM,
2193       PIPE_FORMAT_R32_SNORM,
2194       PIPE_FORMAT_R32G32_SNORM,
2195       PIPE_FORMAT_R32G32B32_SNORM,
2196       PIPE_FORMAT_R32G32B32A32_SNORM,
2197       PIPE_FORMAT_R32_USCALED,
2198       PIPE_FORMAT_R32G32_USCALED,
2199       PIPE_FORMAT_R32G32B32_USCALED,
2200       PIPE_FORMAT_R32G32B32A32_USCALED,
2201       PIPE_FORMAT_R32_SSCALED,
2202       PIPE_FORMAT_R32G32_SSCALED,
2203       PIPE_FORMAT_R32G32B32_SSCALED,
2204       PIPE_FORMAT_R32G32B32A32_SSCALED,
2205       */
2206       PIPE_FORMAT_R16_UNORM,
2207       PIPE_FORMAT_R16G16_UNORM,
2208       PIPE_FORMAT_R16G16B16_UNORM,
2209       PIPE_FORMAT_R16G16B16A16_UNORM,
2210       PIPE_FORMAT_R16_SNORM,
2211       PIPE_FORMAT_R16G16_SNORM,
2212       PIPE_FORMAT_R16G16B16_SNORM,
2213       PIPE_FORMAT_R16G16B16_SINT,
2214       PIPE_FORMAT_R16G16B16_UINT,
2215       PIPE_FORMAT_R16G16B16A16_SNORM,
2216       PIPE_FORMAT_R16_USCALED,
2217       PIPE_FORMAT_R16G16_USCALED,
2218       PIPE_FORMAT_R16G16B16_USCALED,
2219       PIPE_FORMAT_R16G16B16A16_USCALED,
2220       PIPE_FORMAT_R16_SSCALED,
2221       PIPE_FORMAT_R16G16_SSCALED,
2222       PIPE_FORMAT_R16G16B16_SSCALED,
2223       PIPE_FORMAT_R16G16B16A16_SSCALED,
2224       PIPE_FORMAT_R8_UNORM,
2225       PIPE_FORMAT_R8G8_UNORM,
2226       PIPE_FORMAT_R8G8B8_UNORM,
2227       PIPE_FORMAT_R8G8B8A8_UNORM,
2228       PIPE_FORMAT_R8_SNORM,
2229       PIPE_FORMAT_R8G8_SNORM,
2230       PIPE_FORMAT_R8G8B8_SNORM,
2231       PIPE_FORMAT_R8G8B8A8_SNORM,
2232       PIPE_FORMAT_R8_USCALED,
2233       PIPE_FORMAT_R8G8_USCALED,
2234       PIPE_FORMAT_R8G8B8_USCALED,
2235       PIPE_FORMAT_R8G8B8A8_USCALED,
2236       PIPE_FORMAT_R8_SSCALED,
2237       PIPE_FORMAT_R8G8_SSCALED,
2238       PIPE_FORMAT_R8G8B8_SSCALED,
2239       PIPE_FORMAT_R8G8B8A8_SSCALED,
2240    };
2241    for (unsigned i = 0; i < ARRAY_SIZE(format_list); i++) {
2242       if (zink_is_format_supported(&screen->base, format_list[i], PIPE_BUFFER, 0, 0, PIPE_BIND_VERTEX_BUFFER))
2243          continue;
2244       if (util_format_get_nr_components(format_list[i]) == 1)
2245          continue;
2246       enum pipe_format decomposed = zink_decompose_vertex_format(format_list[i]);
2247       if (zink_is_format_supported(&screen->base, decomposed, PIPE_BUFFER, 0, 0, PIPE_BIND_VERTEX_BUFFER)) {
2248          screen->need_decompose_attrs = true;
2249          mesa_logw("zink: this application would be much faster if %s supported vertex format %s", screen->info.props.deviceName, util_format_name(format_list[i]));
2250       }
2251    }
2252 }
2253 
2254 static void
populate_format_props(struct zink_screen * screen)2255 populate_format_props(struct zink_screen *screen)
2256 {
2257    zink_init_format_props(screen, PIPE_FORMAT_A8_UNORM);
2258    check_vertex_formats(screen);
2259    VkImageFormatProperties image_props;
2260    VkResult ret = VKSCR(GetPhysicalDeviceImageFormatProperties)(screen->pdev, VK_FORMAT_D32_SFLOAT,
2261                                                                 VK_IMAGE_TYPE_1D,
2262                                                                 VK_IMAGE_TILING_OPTIMAL,
2263                                                                 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
2264                                                                 0, &image_props);
2265    if (ret != VK_SUCCESS && ret != VK_ERROR_FORMAT_NOT_SUPPORTED) {
2266       mesa_loge("ZINK: vkGetPhysicalDeviceImageFormatProperties failed (%s)", vk_Result_to_str(ret));
2267    }
2268    screen->need_2D_zs = ret != VK_SUCCESS;
2269 
2270    if (screen->info.feats.features.sparseResidencyImage2D)
2271       screen->need_2D_sparse = !screen->base.get_sparse_texture_virtual_page_size(&screen->base, PIPE_TEXTURE_1D, false, PIPE_FORMAT_R32_FLOAT, 0, 16, NULL, NULL, NULL);
2272 }
2273 
2274 static void
setup_renderdoc(struct zink_screen * screen)2275 setup_renderdoc(struct zink_screen *screen)
2276 {
2277 #ifndef _WIN32
2278    const char *capture_id = debug_get_option("ZINK_RENDERDOC", NULL);
2279    if (!capture_id)
2280       return;
2281    void *renderdoc = dlopen("librenderdoc.so", RTLD_NOW | RTLD_NOLOAD);
2282    /* not loaded */
2283    if (!renderdoc)
2284       return;
2285 
2286    pRENDERDOC_GetAPI get_api = dlsym(renderdoc, "RENDERDOC_GetAPI");
2287    if (!get_api)
2288       return;
2289 
2290    /* need synchronous dispatch for renderdoc coherency */
2291    screen->threaded_submit = false;
2292    get_api(eRENDERDOC_API_Version_1_0_0, (void*)&screen->renderdoc_api);
2293    screen->renderdoc_api->SetActiveWindow(RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(screen->instance), NULL);
2294 
2295    int count = sscanf(capture_id, "%u:%u", &screen->renderdoc_capture_start, &screen->renderdoc_capture_end);
2296    if (count != 2) {
2297       count = sscanf(capture_id, "%u", &screen->renderdoc_capture_start);
2298       if (!count) {
2299          if (!strcmp(capture_id, "all")) {
2300             screen->renderdoc_capture_all = true;
2301          } else {
2302             printf("`ZINK_RENDERDOC` usage: ZINK_RENDERDOC=all|frame_no[:end_frame_no]\n");
2303             abort();
2304          }
2305       }
2306       screen->renderdoc_capture_end = screen->renderdoc_capture_start;
2307    }
2308    p_atomic_set(&screen->renderdoc_frame, 1);
2309 #endif
2310 }
2311 
2312 bool
zink_screen_init_semaphore(struct zink_screen * screen)2313 zink_screen_init_semaphore(struct zink_screen *screen)
2314 {
2315    VkSemaphoreCreateInfo sci = {0};
2316    VkSemaphoreTypeCreateInfo tci = {0};
2317    sci.pNext = &tci;
2318    sci.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
2319    tci.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO;
2320    tci.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE;
2321 
2322    return VKSCR(CreateSemaphore)(screen->dev, &sci, NULL, &screen->sem) == VK_SUCCESS;
2323 }
2324 
2325 VkSemaphore
zink_create_exportable_semaphore(struct zink_screen * screen)2326 zink_create_exportable_semaphore(struct zink_screen *screen)
2327 {
2328    VkExportSemaphoreCreateInfo eci = {
2329       VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
2330       NULL,
2331       VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT
2332    };
2333    VkSemaphoreCreateInfo sci = {
2334       VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
2335       &eci,
2336       0
2337    };
2338 
2339    VkSemaphore sem = VK_NULL_HANDLE;
2340    if (util_dynarray_contains(&screen->fd_semaphores, VkSemaphore)) {
2341       simple_mtx_lock(&screen->semaphores_lock);
2342       if (util_dynarray_contains(&screen->fd_semaphores, VkSemaphore))
2343          sem = util_dynarray_pop(&screen->fd_semaphores, VkSemaphore);
2344       simple_mtx_unlock(&screen->semaphores_lock);
2345    }
2346    if (sem)
2347       return sem;
2348    VkResult ret = VKSCR(CreateSemaphore)(screen->dev, &sci, NULL, &sem);
2349    return ret == VK_SUCCESS ? sem : VK_NULL_HANDLE;
2350 }
2351 
2352 VkSemaphore
zink_screen_export_dmabuf_semaphore(struct zink_screen * screen,struct zink_resource * res)2353 zink_screen_export_dmabuf_semaphore(struct zink_screen *screen, struct zink_resource *res)
2354 {
2355    VkSemaphore sem = VK_NULL_HANDLE;
2356 #if defined(HAVE_LIBDRM) && (DETECT_OS_LINUX || DETECT_OS_BSD)
2357    struct dma_buf_export_sync_file export = {
2358       .flags = DMA_BUF_SYNC_RW,
2359       .fd = -1,
2360    };
2361 
2362    int fd = -1;
2363    if (res->obj->is_aux) {
2364       fd = os_dupfd_cloexec(res->obj->handle);
2365    } else {
2366       VkMemoryGetFdInfoKHR fd_info = {0};
2367       fd_info.sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR;
2368       fd_info.memory = zink_bo_get_mem(res->obj->bo);
2369       fd_info.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
2370       VKSCR(GetMemoryFdKHR)(screen->dev, &fd_info, &fd);
2371    }
2372 
2373    if (unlikely(fd < 0)) {
2374       mesa_loge("MESA: Unable to get a valid memory fd");
2375       return VK_NULL_HANDLE;
2376    }
2377 
2378    int ret = drmIoctl(fd, DMA_BUF_IOCTL_EXPORT_SYNC_FILE, &export);
2379    if (ret) {
2380       if (errno == ENOTTY || errno == EBADF || errno == ENOSYS) {
2381          assert(!"how did this fail?");
2382          return VK_NULL_HANDLE;
2383       } else {
2384          mesa_loge("MESA: failed to import sync file '%s'", strerror(errno));
2385          return VK_NULL_HANDLE;
2386       }
2387    }
2388 
2389    sem = zink_create_exportable_semaphore(screen);
2390 
2391    const VkImportSemaphoreFdInfoKHR sdi = {
2392       .sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR,
2393       .semaphore = sem,
2394       .flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT,
2395       .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
2396       .fd = export.fd,
2397    };
2398    bool success = VKSCR(ImportSemaphoreFdKHR)(screen->dev, &sdi) == VK_SUCCESS;
2399    close(fd);
2400    if (!success) {
2401       VKSCR(DestroySemaphore)(screen->dev, sem, NULL);
2402       return VK_NULL_HANDLE;
2403    }
2404 #endif
2405    return sem;
2406 }
2407 
2408 bool
zink_screen_import_dmabuf_semaphore(struct zink_screen * screen,struct zink_resource * res,VkSemaphore sem)2409 zink_screen_import_dmabuf_semaphore(struct zink_screen *screen, struct zink_resource *res, VkSemaphore sem)
2410 {
2411 #if defined(HAVE_LIBDRM) && (DETECT_OS_LINUX || DETECT_OS_BSD)
2412    const VkSemaphoreGetFdInfoKHR get_fd_info = {
2413       .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
2414       .semaphore = sem,
2415       .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
2416    };
2417    int sync_file_fd = -1;
2418    VkResult result = VKSCR(GetSemaphoreFdKHR)(screen->dev, &get_fd_info, &sync_file_fd);
2419    if (result != VK_SUCCESS) {
2420       return false;
2421    }
2422 
2423    bool ret = false;
2424    int fd;
2425    if (res->obj->is_aux) {
2426       fd = os_dupfd_cloexec(res->obj->handle);
2427    } else {
2428       VkMemoryGetFdInfoKHR fd_info = {0};
2429       fd_info.sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR;
2430       fd_info.memory = zink_bo_get_mem(res->obj->bo);
2431       fd_info.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
2432       if (VKSCR(GetMemoryFdKHR)(screen->dev, &fd_info, &fd) != VK_SUCCESS)
2433          fd = -1;
2434    }
2435    if (fd != -1) {
2436       struct dma_buf_import_sync_file import = {
2437          .flags = DMA_BUF_SYNC_RW,
2438          .fd = sync_file_fd,
2439       };
2440       int ioctl_ret = drmIoctl(fd, DMA_BUF_IOCTL_IMPORT_SYNC_FILE, &import);
2441       if (ioctl_ret) {
2442          if (errno == ENOTTY || errno == EBADF || errno == ENOSYS) {
2443             assert(!"how did this fail?");
2444          } else {
2445             ret = true;
2446          }
2447       }
2448       close(fd);
2449    }
2450    close(sync_file_fd);
2451    return ret;
2452 #else
2453    return true;
2454 #endif
2455 }
2456 
2457 bool
zink_screen_timeline_wait(struct zink_screen * screen,uint64_t batch_id,uint64_t timeout)2458 zink_screen_timeline_wait(struct zink_screen *screen, uint64_t batch_id, uint64_t timeout)
2459 {
2460    VkSemaphoreWaitInfo wi = {0};
2461 
2462    if (zink_screen_check_last_finished(screen, batch_id))
2463       return true;
2464 
2465    wi.sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO;
2466    wi.semaphoreCount = 1;
2467    wi.pSemaphores = &screen->sem;
2468    wi.pValues = &batch_id;
2469    bool success = false;
2470    if (screen->device_lost)
2471       return true;
2472    VkResult ret = VKSCR(WaitSemaphores)(screen->dev, &wi, timeout);
2473    success = zink_screen_handle_vkresult(screen, ret);
2474 
2475    if (success)
2476       zink_screen_update_last_finished(screen, batch_id);
2477 
2478    return success;
2479 }
2480 
2481 static uint32_t
zink_get_loader_version(struct zink_screen * screen)2482 zink_get_loader_version(struct zink_screen *screen)
2483 {
2484 
2485    uint32_t loader_version = VK_API_VERSION_1_0;
2486 
2487    // Get the Loader version
2488    GET_PROC_ADDR_INSTANCE_LOCAL(screen, NULL, EnumerateInstanceVersion);
2489    if (vk_EnumerateInstanceVersion) {
2490       uint32_t loader_version_temp = VK_API_VERSION_1_0;
2491       VkResult result = (*vk_EnumerateInstanceVersion)(&loader_version_temp);
2492       if (VK_SUCCESS == result) {
2493          loader_version = loader_version_temp;
2494       } else {
2495          mesa_loge("ZINK: vkEnumerateInstanceVersion failed (%s)", vk_Result_to_str(result));
2496       }
2497    }
2498 
2499    return loader_version;
2500 }
2501 
2502 static void
zink_query_memory_info(struct pipe_screen * pscreen,struct pipe_memory_info * info)2503 zink_query_memory_info(struct pipe_screen *pscreen, struct pipe_memory_info *info)
2504 {
2505    struct zink_screen *screen = zink_screen(pscreen);
2506    memset(info, 0, sizeof(struct pipe_memory_info));
2507    if (screen->info.have_EXT_memory_budget && VKSCR(GetPhysicalDeviceMemoryProperties2)) {
2508       VkPhysicalDeviceMemoryProperties2 mem = {0};
2509       mem.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2;
2510 
2511       VkPhysicalDeviceMemoryBudgetPropertiesEXT budget = {0};
2512       budget.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT;
2513       mem.pNext = &budget;
2514       VKSCR(GetPhysicalDeviceMemoryProperties2)(screen->pdev, &mem);
2515 
2516       for (unsigned i = 0; i < mem.memoryProperties.memoryHeapCount; i++) {
2517          if (mem.memoryProperties.memoryHeaps[i].flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) {
2518             /* VRAM */
2519             info->total_device_memory += mem.memoryProperties.memoryHeaps[i].size / 1024;
2520             info->avail_device_memory += (mem.memoryProperties.memoryHeaps[i].size - budget.heapUsage[i]) / 1024;
2521          } else {
2522             /* GART */
2523             info->total_staging_memory += mem.memoryProperties.memoryHeaps[i].size / 1024;
2524             info->avail_staging_memory += (mem.memoryProperties.memoryHeaps[i].size - budget.heapUsage[i]) / 1024;
2525          }
2526       }
2527       /* evictions not yet supported in vulkan */
2528    } else {
2529       for (unsigned i = 0; i < screen->info.mem_props.memoryHeapCount; i++) {
2530          if (screen->info.mem_props.memoryHeaps[i].flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) {
2531             /* VRAM */
2532             info->total_device_memory += screen->info.mem_props.memoryHeaps[i].size / 1024;
2533             /* free real estate! */
2534             info->avail_device_memory += info->total_device_memory;
2535          } else {
2536             /* GART */
2537             info->total_staging_memory += screen->info.mem_props.memoryHeaps[i].size / 1024;
2538             /* free real estate! */
2539             info->avail_staging_memory += info->total_staging_memory;
2540          }
2541       }
2542    }
2543 }
2544 
2545 static void
zink_query_dmabuf_modifiers(struct pipe_screen * pscreen,enum pipe_format format,int max,uint64_t * modifiers,unsigned int * external_only,int * count)2546 zink_query_dmabuf_modifiers(struct pipe_screen *pscreen, enum pipe_format format, int max, uint64_t *modifiers, unsigned int *external_only, int *count)
2547 {
2548    struct zink_screen *screen = zink_screen(pscreen);
2549    const struct zink_modifier_props *props = zink_get_modifier_props(screen, format);
2550    *count = props->drmFormatModifierCount;
2551    for (int i = 0; i < MIN2(max, *count); i++) {
2552       modifiers[i] = props->pDrmFormatModifierProperties[i].drmFormatModifier;
2553       if (external_only)
2554          external_only[i] = !(props->pDrmFormatModifierProperties[i].drmFormatModifierTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT);
2555    }
2556 }
2557 
2558 static bool
zink_is_dmabuf_modifier_supported(struct pipe_screen * pscreen,uint64_t modifier,enum pipe_format format,bool * external_only)2559 zink_is_dmabuf_modifier_supported(struct pipe_screen *pscreen, uint64_t modifier, enum pipe_format format, bool *external_only)
2560 {
2561    struct zink_screen *screen = zink_screen(pscreen);
2562    const struct zink_modifier_props *props = zink_get_modifier_props(screen, format);
2563    for (unsigned i = 0; i < props->drmFormatModifierCount; i++)
2564       if (props->pDrmFormatModifierProperties[i].drmFormatModifier == modifier)
2565          return true;
2566    return false;
2567 }
2568 
2569 static unsigned
zink_get_dmabuf_modifier_planes(struct pipe_screen * pscreen,uint64_t modifier,enum pipe_format format)2570 zink_get_dmabuf_modifier_planes(struct pipe_screen *pscreen, uint64_t modifier, enum pipe_format format)
2571 {
2572    struct zink_screen *screen = zink_screen(pscreen);
2573    const struct zink_modifier_props *props = zink_get_modifier_props(screen, format);
2574    for (unsigned i = 0; i < props->drmFormatModifierCount; i++)
2575       if (props->pDrmFormatModifierProperties[i].drmFormatModifier == modifier)
2576          return props->pDrmFormatModifierProperties[i].drmFormatModifierPlaneCount;
2577    return util_format_get_num_planes(format);
2578 }
2579 
2580 static int
zink_get_sparse_texture_virtual_page_size(struct pipe_screen * pscreen,enum pipe_texture_target target,bool multi_sample,enum pipe_format pformat,unsigned offset,unsigned size,int * x,int * y,int * z)2581 zink_get_sparse_texture_virtual_page_size(struct pipe_screen *pscreen,
2582                                           enum pipe_texture_target target,
2583                                           bool multi_sample,
2584                                           enum pipe_format pformat,
2585                                           unsigned offset, unsigned size,
2586                                           int *x, int *y, int *z)
2587 {
2588    struct zink_screen *screen = zink_screen(pscreen);
2589    static const int page_size_2d[][3] = {
2590       { 256, 256, 1 }, /* 8bpp   */
2591       { 256, 128, 1 }, /* 16bpp  */
2592       { 128, 128, 1 }, /* 32bpp  */
2593       { 128, 64,  1 }, /* 64bpp  */
2594       { 64,  64,  1 }, /* 128bpp */
2595    };
2596    static const int page_size_3d[][3] = {
2597       { 64,  32,  32 }, /* 8bpp   */
2598       { 32,  32,  32 }, /* 16bpp  */
2599       { 32,  32,  16 }, /* 32bpp  */
2600       { 32,  16,  16 }, /* 64bpp  */
2601       { 16,  16,  16 }, /* 128bpp */
2602    };
2603    /* Only support one type of page size. */
2604    if (offset != 0)
2605       return 0;
2606 
2607    /* reject multisample if 2x isn't supported; assume none are */
2608    if (multi_sample && !screen->info.feats.features.sparseResidency2Samples)
2609       return 0;
2610 
2611    VkFormat format = zink_get_format(screen, pformat);
2612    bool is_zs = util_format_is_depth_or_stencil(pformat);
2613    VkImageType type;
2614    switch (target) {
2615    case PIPE_TEXTURE_1D:
2616    case PIPE_TEXTURE_1D_ARRAY:
2617       type = (screen->need_2D_sparse || (screen->need_2D_zs && is_zs)) ? VK_IMAGE_TYPE_2D : VK_IMAGE_TYPE_1D;
2618       break;
2619 
2620    case PIPE_TEXTURE_2D:
2621    case PIPE_TEXTURE_CUBE:
2622    case PIPE_TEXTURE_RECT:
2623    case PIPE_TEXTURE_2D_ARRAY:
2624    case PIPE_TEXTURE_CUBE_ARRAY:
2625       type = VK_IMAGE_TYPE_2D;
2626       break;
2627 
2628    case PIPE_TEXTURE_3D:
2629       type = VK_IMAGE_TYPE_3D;
2630       break;
2631 
2632    case PIPE_BUFFER:
2633       goto hack_it_up;
2634 
2635    default:
2636       return 0;
2637    }
2638 
2639    VkImageUsageFlags use_flags = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2640                                  VK_IMAGE_USAGE_STORAGE_BIT;
2641    use_flags |= is_zs ? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT : VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
2642    VkImageUsageFlags flags = zink_get_format_props(screen, pformat)->optimalTilingFeatures & use_flags;
2643    VkSparseImageFormatProperties props[4]; //planar?
2644    unsigned prop_count = ARRAY_SIZE(props);
2645    VKSCR(GetPhysicalDeviceSparseImageFormatProperties)(screen->pdev, format, type,
2646                                                        multi_sample ? VK_SAMPLE_COUNT_2_BIT : VK_SAMPLE_COUNT_1_BIT,
2647                                                        flags,
2648                                                        VK_IMAGE_TILING_OPTIMAL,
2649                                                        &prop_count, props);
2650    if (!prop_count) {
2651       /* format may not support storage; try without */
2652       flags &= ~VK_IMAGE_USAGE_STORAGE_BIT;
2653       prop_count = ARRAY_SIZE(props);
2654       VKSCR(GetPhysicalDeviceSparseImageFormatProperties)(screen->pdev, format, type,
2655                                                          multi_sample ? VK_SAMPLE_COUNT_2_BIT : VK_SAMPLE_COUNT_1_BIT,
2656                                                          flags,
2657                                                          VK_IMAGE_TILING_OPTIMAL,
2658                                                          &prop_count, props);
2659       if (!prop_count)
2660          return 0;
2661    }
2662 
2663    if (size) {
2664       if (x)
2665          *x = props[0].imageGranularity.width;
2666       if (y)
2667          *y = props[0].imageGranularity.height;
2668       if (z)
2669          *z = props[0].imageGranularity.depth;
2670    }
2671 
2672    return 1;
2673 hack_it_up:
2674    {
2675       const int (*page_sizes)[3] = target == PIPE_TEXTURE_3D ? page_size_3d : page_size_2d;
2676       int blk_size = util_format_get_blocksize(pformat);
2677 
2678       if (size) {
2679          unsigned index = util_logbase2(blk_size);
2680          if (x) *x = page_sizes[index][0];
2681          if (y) *y = page_sizes[index][1];
2682          if (z) *z = page_sizes[index][2];
2683       }
2684    }
2685    return 1;
2686 }
2687 
2688 static VkDevice
get_device(struct zink_screen * screen,VkDeviceCreateInfo * dci)2689 get_device(struct zink_screen *screen, VkDeviceCreateInfo *dci)
2690 {
2691    VkDevice dev = VK_NULL_HANDLE;
2692 
2693    simple_mtx_lock(&device_lock);
2694 
2695    if (!device_table.table)
2696       _mesa_set_init(&device_table, NULL, _mesa_hash_pointer, _mesa_key_pointer_equal);
2697 
2698    set_foreach(&device_table, entry) {
2699       struct zink_device *zdev = (void*)entry->key;
2700       if (zdev->pdev != screen->pdev)
2701          continue;
2702       zdev->refcount++;
2703       simple_mtx_unlock(&device_lock);
2704       return zdev->dev;
2705    }
2706 
2707    VkResult result = VKSCR(CreateDevice)(screen->pdev, dci, NULL, &dev);
2708    if (result != VK_SUCCESS)
2709       mesa_loge("ZINK: vkCreateDevice failed (%s)", vk_Result_to_str(result));
2710 
2711    struct zink_device *zdev = malloc(sizeof(struct zink_device));
2712    zdev->refcount = 1;
2713    zdev->pdev = screen->pdev;
2714    zdev->dev = dev;
2715    _mesa_set_add(&device_table, zdev);
2716    simple_mtx_unlock(&device_lock);
2717    return dev;
2718 }
2719 
2720 static VkDevice
zink_create_logical_device(struct zink_screen * screen)2721 zink_create_logical_device(struct zink_screen *screen)
2722 {
2723    VkDeviceQueueCreateInfo qci[2] = {0};
2724    uint32_t queues[3] = {
2725       screen->gfx_queue,
2726       screen->sparse_queue,
2727    };
2728    float dummy = 0.0f;
2729    for (unsigned i = 0; i < ARRAY_SIZE(qci); i++) {
2730       qci[i].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
2731       qci[i].queueFamilyIndex = queues[i];
2732       qci[i].queueCount = 1;
2733       qci[i].pQueuePriorities = &dummy;
2734    }
2735 
2736    unsigned num_queues = 1;
2737    if (screen->sparse_queue != screen->gfx_queue)
2738       num_queues++;
2739 
2740    VkDeviceCreateInfo dci = {0};
2741    dci.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
2742    dci.queueCreateInfoCount = num_queues;
2743    dci.pQueueCreateInfos = qci;
2744    /* extensions don't have bool members in pEnabledFeatures.
2745     * this requires us to pass the whole VkPhysicalDeviceFeatures2 struct
2746     */
2747    if (screen->info.feats.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2) {
2748       dci.pNext = &screen->info.feats;
2749    } else {
2750       dci.pEnabledFeatures = &screen->info.feats.features;
2751    }
2752 
2753    dci.ppEnabledExtensionNames = screen->info.extensions;
2754    dci.enabledExtensionCount = screen->info.num_extensions;
2755 
2756    return get_device(screen, &dci);
2757 }
2758 
2759 static void
check_base_requirements(struct zink_screen * screen)2760 check_base_requirements(struct zink_screen *screen)
2761 {
2762    if (zink_debug & ZINK_DEBUG_QUIET)
2763       return;
2764    if (zink_driverid(screen) == VK_DRIVER_ID_MESA_V3DV) {
2765       /* v3dv doesn't support straddling i/o, but zink doesn't do that so this is effectively supported:
2766        * don't spam errors in this case
2767        */
2768       screen->info.feats12.scalarBlockLayout = true;
2769       screen->info.have_EXT_scalar_block_layout = true;
2770    }
2771    if (!screen->info.feats.features.logicOp ||
2772        !screen->info.feats.features.fillModeNonSolid ||
2773        !screen->info.feats.features.shaderClipDistance ||
2774        !(screen->info.feats12.scalarBlockLayout ||
2775          screen->info.have_EXT_scalar_block_layout) ||
2776        !screen->info.have_KHR_maintenance1 ||
2777        !screen->info.have_EXT_custom_border_color ||
2778        !screen->info.have_EXT_line_rasterization) {
2779       fprintf(stderr, "WARNING: Some incorrect rendering "
2780               "might occur because the selected Vulkan device (%s) doesn't support "
2781               "base Zink requirements: ", screen->info.props.deviceName);
2782 #define CHECK_OR_PRINT(X) \
2783       if (!screen->info.X) \
2784          fprintf(stderr, "%s ", #X)
2785       CHECK_OR_PRINT(feats.features.logicOp);
2786       CHECK_OR_PRINT(feats.features.fillModeNonSolid);
2787       CHECK_OR_PRINT(feats.features.shaderClipDistance);
2788       if (!screen->info.feats12.scalarBlockLayout && !screen->info.have_EXT_scalar_block_layout)
2789          fprintf(stderr, "scalarBlockLayout OR EXT_scalar_block_layout ");
2790       CHECK_OR_PRINT(have_KHR_maintenance1);
2791       CHECK_OR_PRINT(have_EXT_custom_border_color);
2792       CHECK_OR_PRINT(have_EXT_line_rasterization);
2793       fprintf(stderr, "\n");
2794    }
2795    if (zink_driverid(screen) == VK_DRIVER_ID_MESA_V3DV) {
2796       screen->info.feats12.scalarBlockLayout = false;
2797       screen->info.have_EXT_scalar_block_layout = false;
2798    }
2799 }
2800 
2801 static void
zink_get_sample_pixel_grid(struct pipe_screen * pscreen,unsigned sample_count,unsigned * width,unsigned * height)2802 zink_get_sample_pixel_grid(struct pipe_screen *pscreen, unsigned sample_count,
2803                            unsigned *width, unsigned *height)
2804 {
2805    struct zink_screen *screen = zink_screen(pscreen);
2806    unsigned idx = util_logbase2_ceil(MAX2(sample_count, 1));
2807    assert(idx < ARRAY_SIZE(screen->maxSampleLocationGridSize));
2808    *width = screen->maxSampleLocationGridSize[idx].width;
2809    *height = screen->maxSampleLocationGridSize[idx].height;
2810 }
2811 
2812 static void
init_driver_workarounds(struct zink_screen * screen)2813 init_driver_workarounds(struct zink_screen *screen)
2814 {
2815    /* enable implicit sync for all non-mesa drivers */
2816    screen->driver_workarounds.implicit_sync = screen->info.driver_props.driverID != VK_DRIVER_ID_MESA_VENUS;
2817    switch (zink_driverid(screen)) {
2818    case VK_DRIVER_ID_MESA_RADV:
2819    case VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA:
2820    case VK_DRIVER_ID_MESA_LLVMPIPE:
2821    case VK_DRIVER_ID_MESA_TURNIP:
2822    case VK_DRIVER_ID_MESA_V3DV:
2823    case VK_DRIVER_ID_MESA_PANVK:
2824    case VK_DRIVER_ID_MESA_NVK:
2825       screen->driver_workarounds.implicit_sync = false;
2826       break;
2827    default:
2828       break;
2829    }
2830    /* TODO: maybe compile multiple variants for different set counts for compact mode? */
2831    if (screen->info.props.limits.maxBoundDescriptorSets < ZINK_DESCRIPTOR_ALL_TYPES ||
2832        zink_debug & (ZINK_DEBUG_COMPACT | ZINK_DEBUG_NOSHOBJ))
2833       screen->info.have_EXT_shader_object = false;
2834    /* EDS2 is only used with EDS1 */
2835    if (!screen->info.have_EXT_extended_dynamic_state) {
2836       screen->info.have_EXT_extended_dynamic_state2 = false;
2837       /* CWE usage needs EDS1 */
2838       screen->info.have_EXT_color_write_enable = false;
2839    }
2840    if (zink_driverid(screen) == VK_DRIVER_ID_AMD_PROPRIETARY)
2841       /* this completely breaks xfb somehow */
2842       screen->info.have_EXT_extended_dynamic_state2 = false;
2843    /* EDS3 is only used with EDS2 */
2844    if (!screen->info.have_EXT_extended_dynamic_state2)
2845       screen->info.have_EXT_extended_dynamic_state3 = false;
2846    /* EXT_vertex_input_dynamic_state is only used with EDS2 and above */
2847    if (!screen->info.have_EXT_extended_dynamic_state2)
2848       screen->info.have_EXT_vertex_input_dynamic_state = false;
2849    if (screen->info.line_rast_feats.stippledRectangularLines &&
2850        screen->info.line_rast_feats.stippledBresenhamLines &&
2851        screen->info.line_rast_feats.stippledSmoothLines &&
2852        !screen->info.dynamic_state3_feats.extendedDynamicState3LineStippleEnable)
2853       screen->info.have_EXT_extended_dynamic_state3 = false;
2854    if (!screen->info.dynamic_state3_feats.extendedDynamicState3PolygonMode ||
2855        !screen->info.dynamic_state3_feats.extendedDynamicState3DepthClampEnable ||
2856        !screen->info.dynamic_state3_feats.extendedDynamicState3DepthClipNegativeOneToOne ||
2857        !screen->info.dynamic_state3_feats.extendedDynamicState3DepthClipEnable ||
2858        !screen->info.dynamic_state3_feats.extendedDynamicState3ProvokingVertexMode ||
2859        !screen->info.dynamic_state3_feats.extendedDynamicState3LineRasterizationMode)
2860       screen->info.have_EXT_extended_dynamic_state3 = false;
2861    else if (screen->info.dynamic_state3_feats.extendedDynamicState3SampleMask &&
2862             screen->info.dynamic_state3_feats.extendedDynamicState3AlphaToCoverageEnable &&
2863             (!screen->info.feats.features.alphaToOne || screen->info.dynamic_state3_feats.extendedDynamicState3AlphaToOneEnable) &&
2864             screen->info.dynamic_state3_feats.extendedDynamicState3ColorBlendEnable &&
2865             screen->info.dynamic_state3_feats.extendedDynamicState3RasterizationSamples &&
2866             screen->info.dynamic_state3_feats.extendedDynamicState3ColorWriteMask &&
2867             screen->info.dynamic_state3_feats.extendedDynamicState3ColorBlendEquation &&
2868             screen->info.dynamic_state3_feats.extendedDynamicState3LogicOpEnable &&
2869             screen->info.dynamic_state2_feats.extendedDynamicState2LogicOp)
2870       screen->have_full_ds3 = true;
2871    if (screen->info.have_EXT_graphics_pipeline_library)
2872       screen->info.have_EXT_graphics_pipeline_library = screen->info.have_EXT_extended_dynamic_state &&
2873                                                         screen->info.have_EXT_extended_dynamic_state2 &&
2874                                                         ((zink_debug & ZINK_DEBUG_GPL) ||
2875                                                          screen->info.dynamic_state2_feats.extendedDynamicState2PatchControlPoints) &&
2876                                                         screen->info.have_EXT_extended_dynamic_state3 &&
2877                                                         screen->info.have_KHR_dynamic_rendering &&
2878                                                         screen->info.have_EXT_non_seamless_cube_map &&
2879                                                         (!(zink_debug & ZINK_DEBUG_GPL) ||
2880                                                          screen->info.gpl_props.graphicsPipelineLibraryFastLinking ||
2881                                                          screen->is_cpu);
2882    screen->driver_workarounds.broken_l4a4 = zink_driverid(screen) == VK_DRIVER_ID_NVIDIA_PROPRIETARY;
2883    if (zink_driverid(screen) == VK_DRIVER_ID_MESA_TURNIP) {
2884       /* performance */
2885       screen->info.border_color_feats.customBorderColorWithoutFormat = VK_FALSE;
2886    }
2887    if (!screen->info.have_KHR_maintenance5)
2888       screen->driver_workarounds.missing_a8_unorm = true;
2889 
2890    if ((!screen->info.have_EXT_line_rasterization ||
2891         !screen->info.line_rast_feats.stippledBresenhamLines) &&
2892        screen->info.feats.features.geometryShader &&
2893        screen->info.feats.features.sampleRateShading) {
2894       /* we're using stippledBresenhamLines as a proxy for all of these, to
2895        * avoid accidentally changing behavior on VK-drivers where we don't
2896        * want to add emulation.
2897        */
2898       screen->driver_workarounds.no_linestipple = true;
2899    }
2900 
2901    if (zink_driverid(screen) ==
2902        VK_DRIVER_ID_IMAGINATION_PROPRIETARY) {
2903       assert(screen->info.feats.features.geometryShader);
2904       screen->driver_workarounds.no_linesmooth = true;
2905    }
2906 
2907    /* This is a workarround for the lack of
2908     * gl_PointSize + glPolygonMode(..., GL_LINE), in the imagination
2909     * proprietary driver.
2910     */
2911    switch (zink_driverid(screen)) {
2912    case VK_DRIVER_ID_IMAGINATION_PROPRIETARY:
2913       screen->driver_workarounds.no_hw_gl_point = true;
2914       break;
2915    default:
2916       screen->driver_workarounds.no_hw_gl_point = false;
2917       break;
2918    }
2919 
2920    if (zink_driverid(screen) == VK_DRIVER_ID_AMD_OPEN_SOURCE ||
2921        zink_driverid(screen) == VK_DRIVER_ID_AMD_PROPRIETARY ||
2922        zink_driverid(screen) == VK_DRIVER_ID_NVIDIA_PROPRIETARY ||
2923        zink_driverid(screen) == VK_DRIVER_ID_MESA_RADV)
2924       screen->driver_workarounds.z24_unscaled_bias = 1<<23;
2925    else
2926       screen->driver_workarounds.z24_unscaled_bias = 1<<24;
2927    if (zink_driverid(screen) == VK_DRIVER_ID_NVIDIA_PROPRIETARY)
2928       screen->driver_workarounds.z16_unscaled_bias = 1<<15;
2929    else
2930       screen->driver_workarounds.z16_unscaled_bias = 1<<16;
2931    /* these drivers don't use VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT, so it can always be set */
2932    switch (zink_driverid(screen)) {
2933    case VK_DRIVER_ID_MESA_RADV:
2934    case VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA:
2935    case VK_DRIVER_ID_MESA_LLVMPIPE:
2936    case VK_DRIVER_ID_NVIDIA_PROPRIETARY:
2937    case VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS:
2938    case VK_DRIVER_ID_IMAGINATION_PROPRIETARY:
2939       screen->driver_workarounds.always_feedback_loop = screen->info.have_EXT_attachment_feedback_loop_layout;
2940       break;
2941    default:
2942       break;
2943    }
2944    /* these drivers don't use VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT, so it can always be set */
2945    switch (zink_driverid(screen)) {
2946    case VK_DRIVER_ID_MESA_LLVMPIPE:
2947    case VK_DRIVER_ID_NVIDIA_PROPRIETARY:
2948    case VK_DRIVER_ID_IMAGINATION_PROPRIETARY:
2949       screen->driver_workarounds.always_feedback_loop_zs = screen->info.have_EXT_attachment_feedback_loop_layout;
2950       break;
2951    default:
2952       break;
2953    }
2954    /* use same mechanics if dynamic state is supported */
2955    screen->driver_workarounds.always_feedback_loop |= screen->info.have_EXT_attachment_feedback_loop_dynamic_state;
2956    screen->driver_workarounds.always_feedback_loop_zs |= screen->info.have_EXT_attachment_feedback_loop_dynamic_state;
2957 
2958    /* these drivers cannot handle OOB gl_Layer values, and therefore need clamping in shader.
2959     * TODO: Vulkan extension that details whether vulkan driver can handle OOB layer values
2960     */
2961    switch (zink_driverid(screen)) {
2962    case VK_DRIVER_ID_IMAGINATION_PROPRIETARY:
2963       screen->driver_compiler_workarounds.needs_sanitised_layer = true;
2964       break;
2965    default:
2966       screen->driver_compiler_workarounds.needs_sanitised_layer = false;
2967       break;
2968    }
2969    /* these drivers will produce undefined results when using swizzle 1 with combined z/s textures
2970     * TODO: use a future device property when available
2971     */
2972    switch (zink_driverid(screen)) {
2973    case VK_DRIVER_ID_IMAGINATION_PROPRIETARY:
2974    case VK_DRIVER_ID_IMAGINATION_OPEN_SOURCE_MESA:
2975       screen->driver_compiler_workarounds.needs_zs_shader_swizzle = true;
2976       break;
2977    default:
2978       screen->driver_compiler_workarounds.needs_zs_shader_swizzle = false;
2979       break;
2980    }
2981 
2982    /* these drivers cannot handle arbitary const value types */
2983    switch (zink_driverid(screen)) {
2984    case VK_DRIVER_ID_IMAGINATION_PROPRIETARY:
2985       screen->driver_compiler_workarounds.broken_const = true;
2986       break;
2987    default:
2988       screen->driver_compiler_workarounds.broken_const = false;
2989       break;
2990    }
2991 
2992    /* When robust contexts are advertised but robustImageAccess2 is not available */
2993    screen->driver_compiler_workarounds.lower_robustImageAccess2 =
2994       !screen->info.rb2_feats.robustImageAccess2 &&
2995       screen->info.feats.features.robustBufferAccess &&
2996       screen->info.rb_image_feats.robustImageAccess;
2997 
2998    /* once more testing has been done, use the #if 0 block */
2999    unsigned illegal = ZINK_DEBUG_RP | ZINK_DEBUG_NORP;
3000    if ((zink_debug & illegal) == illegal) {
3001       mesa_loge("Cannot specify ZINK_DEBUG=rp and ZINK_DEBUG=norp");
3002       abort();
3003    }
3004 
3005    /* these drivers benefit from renderpass optimization */
3006    switch (zink_driverid(screen)) {
3007    case VK_DRIVER_ID_MESA_LLVMPIPE:
3008    case VK_DRIVER_ID_MESA_TURNIP:
3009    case VK_DRIVER_ID_MESA_PANVK:
3010    case VK_DRIVER_ID_MESA_V3DV:
3011    case VK_DRIVER_ID_IMAGINATION_PROPRIETARY:
3012    case VK_DRIVER_ID_QUALCOMM_PROPRIETARY:
3013    case VK_DRIVER_ID_BROADCOM_PROPRIETARY:
3014    case VK_DRIVER_ID_ARM_PROPRIETARY:
3015    case VK_DRIVER_ID_MESA_HONEYKRISP:
3016       screen->driver_workarounds.track_renderpasses = true; //screen->info.primgen_feats.primitivesGeneratedQueryWithRasterizerDiscard
3017       break;
3018    default:
3019       break;
3020    }
3021    if (zink_debug & ZINK_DEBUG_RP)
3022       screen->driver_workarounds.track_renderpasses = true;
3023    else if (zink_debug & ZINK_DEBUG_NORP)
3024       screen->driver_workarounds.track_renderpasses = false;
3025 
3026    /* these drivers can successfully do INVALID <-> LINEAR dri3 modifier swap */
3027    switch (zink_driverid(screen)) {
3028    case VK_DRIVER_ID_MESA_TURNIP:
3029    case VK_DRIVER_ID_MESA_NVK:
3030    case VK_DRIVER_ID_MESA_LLVMPIPE:
3031       screen->driver_workarounds.can_do_invalid_linear_modifier = true;
3032       break;
3033    default:
3034       break;
3035    }
3036 
3037    /* these drivers have no difference between unoptimized and optimized shader compilation */
3038    switch (zink_driverid(screen)) {
3039    case VK_DRIVER_ID_MESA_LLVMPIPE:
3040       screen->driver_workarounds.disable_optimized_compile = true;
3041       break;
3042    default:
3043       if (zink_debug & ZINK_DEBUG_NOOPT)
3044          screen->driver_workarounds.disable_optimized_compile = true;
3045       break;
3046    }
3047 
3048    switch (zink_driverid(screen)) {
3049    case VK_DRIVER_ID_MESA_RADV:
3050    case VK_DRIVER_ID_AMD_OPEN_SOURCE:
3051    case VK_DRIVER_ID_AMD_PROPRIETARY:
3052       /* this has bad perf on AMD */
3053       screen->info.have_KHR_push_descriptor = false;
3054       /* Interpolation is not consistent between two triangles of a rectangle. */
3055       screen->driver_workarounds.inconsistent_interpolation = true;
3056       break;
3057    default:
3058       break;
3059    }
3060 
3061    screen->driver_workarounds.can_2d_view_sparse = true;
3062    switch (zink_driverid(screen)) {
3063    case VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA:
3064    case VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS:
3065       /* this does wild things to block shapes */
3066       screen->driver_workarounds.can_2d_view_sparse = false;
3067       break;
3068    default:
3069       break;
3070    }
3071 
3072    switch (zink_driverid(screen)) {
3073    case VK_DRIVER_ID_MESA_RADV:
3074    case VK_DRIVER_ID_MESA_NVK:
3075    case VK_DRIVER_ID_NVIDIA_PROPRIETARY:
3076       screen->driver_workarounds.general_depth_layout = true;
3077       break;
3078    default:
3079       break;
3080    }
3081 
3082    if (!screen->resizable_bar)
3083       screen->info.have_EXT_host_image_copy = false;
3084 }
3085 
3086 static void
fixup_driver_props(struct zink_screen * screen)3087 fixup_driver_props(struct zink_screen *screen)
3088 {
3089    VkPhysicalDeviceProperties2 props = {
3090       VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2
3091    };
3092    if (screen->info.have_EXT_host_image_copy) {
3093       /* fill in layouts */
3094       screen->info.hic_props.pNext = props.pNext;
3095       props.pNext = &screen->info.hic_props;
3096       screen->info.hic_props.pCopySrcLayouts = ralloc_array(screen, VkImageLayout, screen->info.hic_props.copySrcLayoutCount);
3097       screen->info.hic_props.pCopyDstLayouts = ralloc_array(screen, VkImageLayout, screen->info.hic_props.copyDstLayoutCount);
3098    }
3099    if (props.pNext)
3100       screen->vk.GetPhysicalDeviceProperties2(screen->pdev, &props);
3101 
3102    if (screen->info.have_EXT_host_image_copy) {
3103       for (unsigned i = 0; i < screen->info.hic_props.copyDstLayoutCount; i++) {
3104          if (screen->info.hic_props.pCopyDstLayouts[i] == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
3105             screen->can_hic_shader_read = true;
3106             break;
3107          }
3108       }
3109    }
3110 }
3111 
3112 static void
init_optimal_keys(struct zink_screen * screen)3113 init_optimal_keys(struct zink_screen *screen)
3114 {
3115    /* assume that anyone who knows enough to enable optimal_keys on turnip doesn't care about missing line stipple */
3116    if (zink_debug & ZINK_DEBUG_OPTIMAL_KEYS && zink_driverid(screen) == VK_DRIVER_ID_MESA_TURNIP)
3117       zink_debug |= ZINK_DEBUG_QUIET;
3118    screen->optimal_keys = !screen->need_decompose_attrs &&
3119                           screen->info.have_EXT_non_seamless_cube_map &&
3120                           screen->info.have_EXT_provoking_vertex &&
3121                           !screen->driconf.inline_uniforms &&
3122                           !screen->driver_workarounds.no_linestipple &&
3123                           !screen->driver_workarounds.no_linesmooth &&
3124                           !screen->driver_workarounds.no_hw_gl_point &&
3125                           !screen->driver_compiler_workarounds.lower_robustImageAccess2 &&
3126                           !screen->driconf.emulate_point_smooth &&
3127                           !screen->driver_compiler_workarounds.needs_zs_shader_swizzle;
3128    if (!screen->optimal_keys && zink_debug & ZINK_DEBUG_OPTIMAL_KEYS && !(zink_debug & ZINK_DEBUG_QUIET)) {
3129       fprintf(stderr, "The following criteria are preventing optimal_keys enablement:\n");
3130       if (screen->need_decompose_attrs)
3131          fprintf(stderr, "missing vertex attribute formats\n");
3132       if (screen->driconf.inline_uniforms)
3133          fprintf(stderr, "uniform inlining must be disabled (set ZINK_INLINE_UNIFORMS=0 in your env)\n");
3134       if (screen->driconf.emulate_point_smooth)
3135          fprintf(stderr, "smooth point emulation is enabled\n");
3136       if (screen->driver_compiler_workarounds.needs_zs_shader_swizzle)
3137          fprintf(stderr, "Z/S shader swizzle workaround is enabled\n");
3138       CHECK_OR_PRINT(have_EXT_line_rasterization);
3139       CHECK_OR_PRINT(line_rast_feats.stippledBresenhamLines);
3140       CHECK_OR_PRINT(feats.features.geometryShader);
3141       CHECK_OR_PRINT(feats.features.sampleRateShading);
3142       CHECK_OR_PRINT(have_EXT_non_seamless_cube_map);
3143       CHECK_OR_PRINT(have_EXT_provoking_vertex);
3144       if (screen->driver_workarounds.no_linesmooth)
3145          fprintf(stderr, "driver does not support smooth lines\n");
3146       if (screen->driver_workarounds.no_hw_gl_point)
3147          fprintf(stderr, "driver does not support hardware GL_POINT\n");
3148       CHECK_OR_PRINT(rb2_feats.robustImageAccess2);
3149       CHECK_OR_PRINT(feats.features.robustBufferAccess);
3150       CHECK_OR_PRINT(rb_image_feats.robustImageAccess);
3151       printf("\n");
3152       mesa_logw("zink: force-enabling optimal_keys despite missing features. Good luck!");
3153    }
3154    if (zink_debug & ZINK_DEBUG_OPTIMAL_KEYS)
3155       screen->optimal_keys = true;
3156    if (!screen->optimal_keys)
3157       screen->info.have_EXT_graphics_pipeline_library = false;
3158 
3159    if (!screen->optimal_keys ||
3160        !screen->info.have_KHR_maintenance5 ||
3161       /* EXT_shader_object needs either dynamic feedback loop or per-app enablement */
3162        (!screen->driconf.zink_shader_object_enable && !screen->info.have_EXT_attachment_feedback_loop_dynamic_state))
3163       screen->info.have_EXT_shader_object = false;
3164    if (screen->info.have_EXT_shader_object)
3165       screen->have_full_ds3 = true;
3166 }
3167 
3168 static struct disk_cache *
zink_get_disk_shader_cache(struct pipe_screen * _screen)3169 zink_get_disk_shader_cache(struct pipe_screen *_screen)
3170 {
3171    struct zink_screen *screen = zink_screen(_screen);
3172 
3173    return screen->disk_cache;
3174 }
3175 
3176 VkSemaphore
zink_create_semaphore(struct zink_screen * screen)3177 zink_create_semaphore(struct zink_screen *screen)
3178 {
3179    VkSemaphoreCreateInfo sci = {
3180       VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
3181       NULL,
3182       0
3183    };
3184    VkSemaphore sem = VK_NULL_HANDLE;
3185    if (util_dynarray_contains(&screen->semaphores, VkSemaphore)) {
3186       simple_mtx_lock(&screen->semaphores_lock);
3187       if (util_dynarray_contains(&screen->semaphores, VkSemaphore))
3188          sem = util_dynarray_pop(&screen->semaphores, VkSemaphore);
3189       simple_mtx_unlock(&screen->semaphores_lock);
3190    }
3191    if (sem)
3192       return sem;
3193    VkResult ret = VKSCR(CreateSemaphore)(screen->dev, &sci, NULL, &sem);
3194    return ret == VK_SUCCESS ? sem : VK_NULL_HANDLE;
3195 }
3196 
3197 void
zink_screen_lock_context(struct zink_screen * screen)3198 zink_screen_lock_context(struct zink_screen *screen)
3199 {
3200    simple_mtx_lock(&screen->copy_context_lock);
3201    if (!screen->copy_context)
3202       screen->copy_context = zink_context(screen->base.context_create(&screen->base, NULL, ZINK_CONTEXT_COPY_ONLY));
3203    if (!screen->copy_context) {
3204       mesa_loge("zink: failed to create copy context");
3205       /* realistically there's nothing that can be done here */
3206    }
3207 }
3208 
3209 void
zink_screen_unlock_context(struct zink_screen * screen)3210 zink_screen_unlock_context(struct zink_screen *screen)
3211 {
3212    simple_mtx_unlock(&screen->copy_context_lock);
3213 }
3214 
3215 static bool
init_layouts(struct zink_screen * screen)3216 init_layouts(struct zink_screen *screen)
3217 {
3218    if (screen->info.have_EXT_descriptor_indexing) {
3219       VkDescriptorSetLayoutBinding bindings[4];
3220       const unsigned num_bindings = 4;
3221       VkDescriptorSetLayoutCreateInfo dcslci = {0};
3222       dcslci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
3223       dcslci.pNext = NULL;
3224       VkDescriptorSetLayoutBindingFlagsCreateInfo fci = {0};
3225       VkDescriptorBindingFlags flags[4];
3226       dcslci.pNext = &fci;
3227       if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB)
3228          dcslci.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT;
3229       else
3230          dcslci.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT;
3231       fci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO;
3232       fci.bindingCount = num_bindings;
3233       fci.pBindingFlags = flags;
3234       for (unsigned i = 0; i < num_bindings; i++) {
3235          flags[i] = VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT | VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT;
3236          if (zink_descriptor_mode != ZINK_DESCRIPTOR_MODE_DB)
3237             flags[i] |= VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT;
3238       }
3239       /* there is exactly 1 bindless descriptor set per context, and it has 4 bindings, 1 for each descriptor type */
3240       for (unsigned i = 0; i < num_bindings; i++) {
3241          bindings[i].binding = i;
3242          bindings[i].descriptorType = zink_descriptor_type_from_bindless_index(i);
3243          bindings[i].descriptorCount = ZINK_MAX_BINDLESS_HANDLES;
3244          bindings[i].stageFlags = VK_SHADER_STAGE_ALL_GRAPHICS | VK_SHADER_STAGE_COMPUTE_BIT;
3245          bindings[i].pImmutableSamplers = NULL;
3246       }
3247 
3248       dcslci.bindingCount = num_bindings;
3249       dcslci.pBindings = bindings;
3250       VkResult result = VKSCR(CreateDescriptorSetLayout)(screen->dev, &dcslci, 0, &screen->bindless_layout);
3251       if (result != VK_SUCCESS) {
3252          mesa_loge("ZINK: vkCreateDescriptorSetLayout failed (%s)", vk_Result_to_str(result));
3253          return false;
3254       }
3255    }
3256 
3257    screen->gfx_push_constant_layout = zink_pipeline_layout_create(screen, NULL, 0, false, 0);
3258    return !!screen->gfx_push_constant_layout;
3259 }
3260 
3261 static int
zink_screen_get_fd(struct pipe_screen * pscreen)3262 zink_screen_get_fd(struct pipe_screen *pscreen)
3263 {
3264    struct zink_screen *screen = zink_screen(pscreen);
3265 
3266    return screen->drm_fd;
3267 }
3268 
3269 static const char*
zink_cl_cts_version(struct pipe_screen * pscreen)3270 zink_cl_cts_version(struct pipe_screen *pscreen)
3271 {
3272    /* https://www.khronos.org/conformance/adopters/conformant-products/opencl#submission_437 */
3273    return "v2024-08-08-00";
3274 }
3275 
3276 static struct zink_screen *
zink_internal_create_screen(const struct pipe_screen_config * config,int64_t dev_major,int64_t dev_minor,uint64_t adapter_luid)3277 zink_internal_create_screen(const struct pipe_screen_config *config, int64_t dev_major, int64_t dev_minor, uint64_t adapter_luid)
3278 {
3279    if (getenv("ZINK_USE_LAVAPIPE")) {
3280       mesa_loge("ZINK_USE_LAVAPIPE is obsolete. Use LIBGL_ALWAYS_SOFTWARE\n");
3281       return NULL;
3282    }
3283 
3284    struct zink_screen *screen = rzalloc(NULL, struct zink_screen);
3285    if (!screen) {
3286       if (!config || !config->driver_name_is_inferred)
3287          mesa_loge("ZINK: failed to allocate screen");
3288       return NULL;
3289    }
3290 
3291    screen->driver_name_is_inferred = config && config->driver_name_is_inferred;
3292    screen->drm_fd = -1;
3293 
3294    glsl_type_singleton_init_or_ref();
3295    zink_debug = debug_get_option_zink_debug();
3296    if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_AUTO)
3297       zink_descriptor_mode = debug_get_option_zink_descriptor_mode();
3298 
3299    screen->threaded = util_get_cpu_caps()->nr_cpus > 1 && debug_get_bool_option("GALLIUM_THREAD", util_get_cpu_caps()->nr_cpus > 1);
3300    if (zink_debug & ZINK_DEBUG_FLUSHSYNC)
3301       screen->threaded_submit = false;
3302    else
3303       screen->threaded_submit = screen->threaded;
3304    screen->abort_on_hang = debug_get_bool_option("ZINK_HANG_ABORT", false);
3305 
3306 
3307    u_trace_state_init();
3308 
3309    screen->loader_lib = util_dl_open(VK_LIBNAME);
3310    if (!screen->loader_lib) {
3311       if (!screen->driver_name_is_inferred)
3312          mesa_loge("ZINK: failed to load "VK_LIBNAME);
3313       goto fail;
3314    }
3315 
3316    screen->vk_GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)util_dl_get_proc_address(screen->loader_lib, "vkGetInstanceProcAddr");
3317    screen->vk_GetDeviceProcAddr = (PFN_vkGetDeviceProcAddr)util_dl_get_proc_address(screen->loader_lib, "vkGetDeviceProcAddr");
3318    if (!screen->vk_GetInstanceProcAddr ||
3319        !screen->vk_GetDeviceProcAddr) {
3320       if (!screen->driver_name_is_inferred)
3321          mesa_loge("ZINK: failed to get proc address");
3322       goto fail;
3323    }
3324 
3325    if (config) {
3326       driParseConfigFiles(config->options, config->options_info, 0, "zink",
3327                           NULL, NULL, NULL, 0, NULL, 0);
3328       screen->driconf.dual_color_blend_by_location = driQueryOptionb(config->options, "dual_color_blend_by_location");
3329       //screen->driconf.inline_uniforms = driQueryOptionb(config->options, "radeonsi_inline_uniforms");
3330       screen->driconf.emulate_point_smooth = driQueryOptionb(config->options, "zink_emulate_point_smooth");
3331       screen->driconf.zink_shader_object_enable = driQueryOptionb(config->options, "zink_shader_object_enable");
3332    }
3333 
3334    simple_mtx_lock(&instance_lock);
3335    if (++instance_refcount == 1) {
3336       instance_info.loader_version = zink_get_loader_version(screen);
3337       instance = zink_create_instance(screen, &instance_info);
3338       if (!instance)
3339          goto fail;
3340    } else {
3341       assert(instance);
3342    }
3343    screen->instance = instance;
3344    screen->instance_info = &instance_info;
3345    simple_mtx_unlock(&instance_lock);
3346 
3347    if (zink_debug & ZINK_DEBUG_VALIDATION) {
3348       if (!screen->instance_info->have_layer_KHRONOS_validation &&
3349           !screen->instance_info->have_layer_LUNARG_standard_validation) {
3350          if (!screen->driver_name_is_inferred)
3351             mesa_loge("Failed to load validation layer");
3352          goto fail;
3353       }
3354    }
3355 
3356    vk_instance_uncompacted_dispatch_table_load(&screen->vk.instance,
3357                                                 screen->vk_GetInstanceProcAddr,
3358                                                 screen->instance);
3359    vk_physical_device_uncompacted_dispatch_table_load(&screen->vk.physical_device,
3360                                                       screen->vk_GetInstanceProcAddr,
3361                                                       screen->instance);
3362 
3363    zink_verify_instance_extensions(screen);
3364 
3365    if (screen->instance_info->have_EXT_debug_utils &&
3366       (zink_debug & ZINK_DEBUG_VALIDATION) && !create_debug(screen)) {
3367       if (!screen->driver_name_is_inferred)
3368          debug_printf("ZINK: failed to setup debug utils\n");
3369    }
3370 
3371    choose_pdev(screen, dev_major, dev_minor, adapter_luid);
3372    if (screen->pdev == VK_NULL_HANDLE) {
3373       if (!screen->driver_name_is_inferred)
3374          mesa_loge("ZINK: failed to choose pdev");
3375       goto fail;
3376    }
3377    screen->is_cpu = screen->info.props.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU;
3378 
3379    update_queue_props(screen);
3380 
3381    screen->have_X8_D24_UNORM_PACK32 = zink_is_depth_format_supported(screen,
3382                                               VK_FORMAT_X8_D24_UNORM_PACK32);
3383    screen->have_D24_UNORM_S8_UINT = zink_is_depth_format_supported(screen,
3384                                               VK_FORMAT_D24_UNORM_S8_UINT);
3385    screen->have_D32_SFLOAT_S8_UINT = zink_is_depth_format_supported(screen,
3386                                               VK_FORMAT_D32_SFLOAT_S8_UINT);
3387    screen->have_dynamic_state_vertex_input_binding_stride = true;
3388 
3389    if (!zink_get_physical_device_info(screen)) {
3390       if (!screen->driver_name_is_inferred)
3391          debug_printf("ZINK: failed to detect features\n");
3392       goto fail;
3393    }
3394 
3395    screen->info.feats11.protectedMemory = false;
3396    screen->info.have_EXT_provoking_vertex = true;
3397 
3398    if (zink_set_driver_strings(screen)) {
3399       mesa_loge("ZINK: failed to set driver strings\n");
3400       goto fail;
3401    }
3402 
3403    memset(&screen->heap_map, UINT8_MAX, sizeof(screen->heap_map));
3404    for (enum zink_heap i = 0; i < ZINK_HEAP_MAX; i++) {
3405       for (unsigned j = 0; j < screen->info.mem_props.memoryTypeCount; j++) {
3406          VkMemoryPropertyFlags domains = vk_domain_from_heap(i);
3407          if ((screen->info.mem_props.memoryTypes[j].propertyFlags & domains) == domains) {
3408             screen->heap_map[i][screen->heap_count[i]++] = j;
3409          }
3410       }
3411    }
3412 
3413    bool maybe_has_rebar = true;
3414    /* iterate again to check for missing heaps */
3415    for (enum zink_heap i = 0; i < ZINK_HEAP_MAX; i++) {
3416       /* not found: use compatible heap */
3417       if (screen->heap_map[i][0] == UINT8_MAX) {
3418          /* only cached mem has a failure case for now */
3419          assert(i == ZINK_HEAP_HOST_VISIBLE_COHERENT_CACHED || i == ZINK_HEAP_DEVICE_LOCAL_LAZY ||
3420                 i == ZINK_HEAP_DEVICE_LOCAL_VISIBLE);
3421          if (i == ZINK_HEAP_HOST_VISIBLE_COHERENT_CACHED) {
3422             memcpy(screen->heap_map[i], screen->heap_map[ZINK_HEAP_HOST_VISIBLE_COHERENT], screen->heap_count[ZINK_HEAP_HOST_VISIBLE_COHERENT]);
3423             screen->heap_count[i] = screen->heap_count[ZINK_HEAP_HOST_VISIBLE_COHERENT];
3424          } else {
3425             memcpy(screen->heap_map[i], screen->heap_map[ZINK_HEAP_DEVICE_LOCAL], screen->heap_count[ZINK_HEAP_DEVICE_LOCAL]);
3426             screen->heap_count[i] = screen->heap_count[ZINK_HEAP_DEVICE_LOCAL];
3427             if (i == ZINK_HEAP_DEVICE_LOCAL_VISIBLE)
3428                maybe_has_rebar = false;
3429          }
3430       }
3431    }
3432    if (maybe_has_rebar) {
3433       uint64_t biggest_vis_vram = 0;
3434       for (unsigned i = 0; i < screen->heap_count[ZINK_HEAP_DEVICE_LOCAL_VISIBLE]; i++)
3435          biggest_vis_vram = MAX2(biggest_vis_vram, screen->info.mem_props.memoryHeaps[screen->info.mem_props.memoryTypes[screen->heap_map[ZINK_HEAP_DEVICE_LOCAL_VISIBLE][i]].heapIndex].size);
3436       uint64_t biggest_vram = 0;
3437       for (unsigned i = 0; i < screen->heap_count[ZINK_HEAP_DEVICE_LOCAL]; i++)
3438          biggest_vram = MAX2(biggest_vram, screen->info.mem_props.memoryHeaps[screen->info.mem_props.memoryTypes[screen->heap_map[ZINK_HEAP_DEVICE_LOCAL][i]].heapIndex].size);
3439       /* determine if vis vram is roughly equal to total vram */
3440       if (biggest_vis_vram > biggest_vram * 0.9)
3441          screen->resizable_bar = true;
3442    }
3443 
3444    setup_renderdoc(screen);
3445    if (screen->threaded_submit && !util_queue_init(&screen->flush_queue, "zfq", 8, 1, UTIL_QUEUE_INIT_RESIZE_IF_FULL, screen)) {
3446       if (!screen->driver_name_is_inferred)
3447          mesa_loge("zink: Failed to create flush queue.\n");
3448       goto fail;
3449    }
3450 
3451    zink_internal_setup_moltenvk(screen);
3452    if (!screen->info.have_KHR_timeline_semaphore && !screen->info.feats12.timelineSemaphore) {
3453       if (!screen->driver_name_is_inferred)
3454          mesa_loge("zink: KHR_timeline_semaphore is required");
3455       goto fail;
3456    }
3457 
3458    if (zink_driverid(screen) == VK_DRIVER_ID_IMAGINATION_PROPRIETARY && !screen->info.feats.features.geometryShader) {
3459       if (!screen->driver_name_is_inferred)
3460          mesa_loge("zink: Imagination proprietary driver w/o geometryShader is unsupported");
3461       goto fail;
3462    }
3463 
3464    if (zink_debug & ZINK_DEBUG_MEM) {
3465       simple_mtx_init(&screen->debug_mem_lock, mtx_plain);
3466       screen->debug_mem_sizes = _mesa_hash_table_create(screen, _mesa_hash_string, _mesa_key_string_equal);
3467    }
3468 
3469    fixup_driver_props(screen);
3470 
3471    init_driver_workarounds(screen);
3472 
3473    screen->dev = zink_create_logical_device(screen);
3474    if (!screen->dev)
3475       goto fail;
3476 
3477    vk_device_uncompacted_dispatch_table_load(&screen->vk.device,
3478                                              screen->vk_GetDeviceProcAddr,
3479                                              screen->dev);
3480 
3481    init_queue(screen);
3482 
3483    zink_verify_device_extensions(screen);
3484 
3485    /* descriptor set indexing is determined by 'compact' descriptor mode:
3486     * by default, 6 sets are used to provide more granular updating
3487     * in compact mode, a maximum of 4 sets are used, with like-types combined
3488     */
3489    if ((zink_debug & ZINK_DEBUG_COMPACT) ||
3490        screen->info.props.limits.maxBoundDescriptorSets < ZINK_MAX_DESCRIPTOR_SETS) {
3491       screen->desc_set_id[ZINK_DESCRIPTOR_TYPE_UNIFORMS] = 0;
3492       screen->desc_set_id[ZINK_DESCRIPTOR_TYPE_UBO] = 1;
3493       screen->desc_set_id[ZINK_DESCRIPTOR_TYPE_SSBO] = 1;
3494       screen->desc_set_id[ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW] = 2;
3495       screen->desc_set_id[ZINK_DESCRIPTOR_TYPE_IMAGE] = 2;
3496       screen->desc_set_id[ZINK_DESCRIPTOR_BINDLESS] = 3;
3497       screen->compact_descriptors = true;
3498    } else {
3499       screen->desc_set_id[ZINK_DESCRIPTOR_TYPE_UNIFORMS] = 0;
3500       screen->desc_set_id[ZINK_DESCRIPTOR_TYPE_UBO] = 1;
3501       screen->desc_set_id[ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW] = 2;
3502       screen->desc_set_id[ZINK_DESCRIPTOR_TYPE_SSBO] = 3;
3503       screen->desc_set_id[ZINK_DESCRIPTOR_TYPE_IMAGE] = 4;
3504       screen->desc_set_id[ZINK_DESCRIPTOR_BINDLESS] = 5;
3505    }
3506 
3507    if (screen->info.have_EXT_calibrated_timestamps && !check_have_device_time(screen))
3508       goto fail;
3509 
3510    screen->have_triangle_fans = true;
3511 #if defined(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME)
3512    if (screen->info.have_KHR_portability_subset) {
3513       screen->have_triangle_fans = (VK_TRUE == screen->info.portability_subset_feats.triangleFans);
3514    }
3515 #endif // VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME
3516 
3517    check_base_requirements(screen);
3518    util_live_shader_cache_init(&screen->shaders, zink_create_gfx_shader_state, zink_delete_shader_state);
3519 
3520    screen->base.get_name = zink_get_name;
3521    if (screen->instance_info->have_KHR_external_memory_capabilities) {
3522       screen->base.get_device_uuid = zink_get_device_uuid;
3523       screen->base.get_driver_uuid = zink_get_driver_uuid;
3524    }
3525    if (screen->info.have_KHR_external_memory_win32) {
3526       screen->base.get_device_luid = zink_get_device_luid;
3527       screen->base.get_device_node_mask = zink_get_device_node_mask;
3528    }
3529    screen->base.set_max_shader_compiler_threads = zink_set_max_shader_compiler_threads;
3530    screen->base.is_parallel_shader_compilation_finished = zink_is_parallel_shader_compilation_finished;
3531    screen->base.get_vendor = zink_get_vendor;
3532    screen->base.get_device_vendor = zink_get_device_vendor;
3533    screen->base.get_compute_param = zink_get_compute_param;
3534    screen->base.get_timestamp = zink_get_timestamp;
3535    screen->base.query_memory_info = zink_query_memory_info;
3536    screen->base.get_shader_param = zink_get_shader_param;
3537    screen->base.get_compiler_options = zink_get_compiler_options;
3538    screen->base.get_sample_pixel_grid = zink_get_sample_pixel_grid;
3539    screen->base.is_compute_copy_faster = zink_is_compute_copy_faster;
3540    screen->base.is_format_supported = zink_is_format_supported;
3541    screen->base.driver_thread_add_job = zink_driver_thread_add_job;
3542    if (screen->info.have_EXT_image_drm_format_modifier && screen->info.have_EXT_external_memory_dma_buf) {
3543       screen->base.query_dmabuf_modifiers = zink_query_dmabuf_modifiers;
3544       screen->base.is_dmabuf_modifier_supported = zink_is_dmabuf_modifier_supported;
3545       screen->base.get_dmabuf_modifier_planes = zink_get_dmabuf_modifier_planes;
3546    }
3547 #if defined(_WIN32)
3548    if (screen->info.have_KHR_external_memory_win32)
3549       screen->base.create_fence_win32 = zink_create_fence_win32;
3550 #endif
3551    screen->base.context_create = zink_context_create;
3552    screen->base.flush_frontbuffer = zink_flush_frontbuffer;
3553    screen->base.destroy = zink_destroy_screen;
3554    screen->base.finalize_nir = zink_shader_finalize;
3555    screen->base.get_disk_shader_cache = zink_get_disk_shader_cache;
3556    screen->base.get_sparse_texture_virtual_page_size = zink_get_sparse_texture_virtual_page_size;
3557    screen->base.get_driver_query_group_info = zink_get_driver_query_group_info;
3558    screen->base.get_driver_query_info = zink_get_driver_query_info;
3559    screen->base.set_damage_region = zink_set_damage_region;
3560    screen->base.get_cl_cts_version = zink_cl_cts_version;
3561 
3562    zink_init_screen_caps(screen);
3563 
3564    if (screen->info.have_EXT_sample_locations) {
3565       VkMultisamplePropertiesEXT prop;
3566       prop.sType = VK_STRUCTURE_TYPE_MULTISAMPLE_PROPERTIES_EXT;
3567       prop.pNext = NULL;
3568       for (unsigned i = 0; i < ARRAY_SIZE(screen->maxSampleLocationGridSize); i++) {
3569          if (screen->info.sample_locations_props.sampleLocationSampleCounts & (1 << i)) {
3570             VKSCR(GetPhysicalDeviceMultisamplePropertiesEXT)(screen->pdev, 1 << i, &prop);
3571             screen->maxSampleLocationGridSize[i] = prop.maxSampleLocationGridSize;
3572          }
3573       }
3574    }
3575 
3576    if (!zink_screen_resource_init(&screen->base))
3577       goto fail;
3578    if (!zink_bo_init(screen)) {
3579       if (!screen->driver_name_is_inferred)
3580          mesa_loge("ZINK: failed to initialize suballocator");
3581       goto fail;
3582    }
3583    zink_screen_fence_init(&screen->base);
3584 
3585    if (zink_debug & ZINK_DEBUG_IOOPT)
3586       screen->driver_compiler_workarounds.io_opt = true;
3587    zink_screen_init_compiler(screen);
3588    if (!disk_cache_init(screen)) {
3589       if (!screen->driver_name_is_inferred)
3590          mesa_loge("ZINK: failed to initialize disk cache");
3591       goto fail;
3592    }
3593    if (!util_queue_init(&screen->cache_get_thread, "zcfq", 8, 4,
3594                         UTIL_QUEUE_INIT_RESIZE_IF_FULL, screen))
3595       goto fail;
3596    populate_format_props(screen);
3597 
3598    slab_create_parent(&screen->transfer_pool, sizeof(struct zink_transfer), 16);
3599 
3600    screen->driconf.inline_uniforms = debug_get_bool_option("ZINK_INLINE_UNIFORMS", screen->is_cpu);
3601 
3602    screen->total_video_mem = get_video_mem(screen);
3603    screen->clamp_video_mem = screen->total_video_mem * 0.8;
3604    if (!os_get_total_physical_memory(&screen->total_mem)) {
3605       if (!screen->driver_name_is_inferred)
3606          mesa_loge("ZINK: failed to get total physical memory");
3607       goto fail;
3608    }
3609 
3610    if (!zink_screen_init_semaphore(screen)) {
3611       if (!screen->driver_name_is_inferred)
3612          mesa_loge("zink: failed to create timeline semaphore");
3613       goto fail;
3614    }
3615 
3616    bool can_db = true;
3617    {
3618       if (!screen->info.have_EXT_descriptor_buffer) {
3619          if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
3620             if (!screen->driver_name_is_inferred)
3621                mesa_loge("Cannot use db descriptor mode without EXT_descriptor_buffer");
3622             goto fail;
3623          }
3624          can_db = false;
3625       }
3626       if (!screen->resizable_bar) {
3627          if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
3628             if (!screen->driver_name_is_inferred)
3629                mesa_loge("Cannot use db descriptor mode without resizable bar");
3630             goto fail;
3631          }
3632          can_db = false;
3633       }
3634       if (!screen->info.have_EXT_non_seamless_cube_map) {
3635          if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
3636             if (!screen->driver_name_is_inferred)
3637                mesa_loge("Cannot use db descriptor mode without EXT_non_seamless_cube_map");
3638             goto fail;
3639          }
3640          can_db = false;
3641       }
3642       if (!screen->info.rb2_feats.nullDescriptor) {
3643          if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
3644             if (!screen->driver_name_is_inferred)
3645                mesa_loge("Cannot use db descriptor mode without robustness2.nullDescriptor");
3646             goto fail;
3647          }
3648          can_db = false;
3649       }
3650       if (ZINK_FBFETCH_DESCRIPTOR_SIZE < screen->info.db_props.inputAttachmentDescriptorSize) {
3651          if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
3652             if (!screen->driver_name_is_inferred)
3653                mesa_loge("Cannot use db descriptor mode with inputAttachmentDescriptorSize(%u) > %u", (unsigned)screen->info.db_props.inputAttachmentDescriptorSize, ZINK_FBFETCH_DESCRIPTOR_SIZE);
3654             goto fail;
3655          }
3656          mesa_logw("zink: bug detected: inputAttachmentDescriptorSize(%u) > %u", (unsigned)screen->info.db_props.inputAttachmentDescriptorSize, ZINK_FBFETCH_DESCRIPTOR_SIZE);
3657          can_db = false;
3658       }
3659       if (screen->info.db_props.maxDescriptorBufferBindings < 2 || screen->info.db_props.maxSamplerDescriptorBufferBindings < 2) {
3660          if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
3661             /* allow for testing, but disable bindless */
3662             mesa_logw("Cannot use bindless and db descriptor mode with (maxDescriptorBufferBindings||maxSamplerDescriptorBufferBindings) < 2");
3663          } else {
3664             can_db = false;
3665          }
3666       }
3667    }
3668    if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_AUTO) {
3669       switch(screen->info.driver_props.driverID) {
3670       /* descriptor buffer is not performant with virt yet */
3671       case VK_DRIVER_ID_MESA_VENUS:
3672       /* db descriptor mode is known to be broken on IMG proprietary drivers */
3673       case VK_DRIVER_ID_IMAGINATION_PROPRIETARY:
3674          zink_descriptor_mode = ZINK_DESCRIPTOR_MODE_LAZY;
3675 	 break;
3676       default:
3677          zink_descriptor_mode = can_db ? ZINK_DESCRIPTOR_MODE_DB : ZINK_DESCRIPTOR_MODE_LAZY;
3678       }
3679    }
3680    if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
3681       const uint32_t sampler_size = MAX2(screen->info.db_props.combinedImageSamplerDescriptorSize, screen->info.db_props.robustUniformTexelBufferDescriptorSize);
3682       const uint32_t image_size = MAX2(screen->info.db_props.storageImageDescriptorSize, screen->info.db_props.robustStorageTexelBufferDescriptorSize);
3683       if (screen->compact_descriptors) {
3684          screen->db_size[ZINK_DESCRIPTOR_TYPE_UBO] = screen->info.db_props.robustUniformBufferDescriptorSize +
3685                                                      screen->info.db_props.robustStorageBufferDescriptorSize;
3686          screen->db_size[ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW] = sampler_size + image_size;
3687       } else {
3688          screen->db_size[ZINK_DESCRIPTOR_TYPE_UBO] = screen->info.db_props.robustUniformBufferDescriptorSize;
3689          screen->db_size[ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW] = sampler_size;
3690          screen->db_size[ZINK_DESCRIPTOR_TYPE_SSBO] = screen->info.db_props.robustStorageBufferDescriptorSize;
3691          screen->db_size[ZINK_DESCRIPTOR_TYPE_IMAGE] = image_size;
3692       }
3693       screen->db_size[ZINK_DESCRIPTOR_TYPE_UNIFORMS] = screen->info.db_props.robustUniformBufferDescriptorSize;
3694       screen->info.have_KHR_push_descriptor = false;
3695       screen->base_descriptor_size = MAX4(screen->db_size[0], screen->db_size[1], screen->db_size[2], screen->db_size[3]);
3696    }
3697 
3698    simple_mtx_init(&screen->free_batch_states_lock, mtx_plain);
3699    simple_mtx_init(&screen->dt_lock, mtx_plain);
3700 
3701    util_idalloc_mt_init_tc(&screen->buffer_ids);
3702 
3703    simple_mtx_init(&screen->semaphores_lock, mtx_plain);
3704    util_dynarray_init(&screen->semaphores, screen);
3705    util_dynarray_init(&screen->fd_semaphores, screen);
3706 
3707    util_vertex_state_cache_init(&screen->vertex_state_cache,
3708                                 zink_create_vertex_state, zink_vertex_state_destroy);
3709    screen->base.create_vertex_state = zink_cache_create_vertex_state;
3710    screen->base.vertex_state_destroy = zink_cache_vertex_state_destroy;
3711 
3712    zink_synchronization_init(screen);
3713 
3714    zink_init_screen_pipeline_libs(screen);
3715 
3716    if (!init_layouts(screen)) {
3717       if (!screen->driver_name_is_inferred)
3718          mesa_loge("ZINK: failed to initialize layouts");
3719       goto fail;
3720    }
3721 
3722    if (!zink_descriptor_layouts_init(screen)) {
3723       if (!screen->driver_name_is_inferred)
3724          mesa_loge("ZINK: failed to initialize descriptor layouts");
3725       goto fail;
3726    }
3727 
3728    simple_mtx_init(&screen->copy_context_lock, mtx_plain);
3729 
3730    init_optimal_keys(screen);
3731 
3732    screen->screen_id = p_atomic_inc_return(&num_screens);
3733    zink_tracing = screen->instance_info->have_EXT_debug_utils &&
3734                   (u_trace_is_enabled(U_TRACE_TYPE_PERFETTO) || u_trace_is_enabled(U_TRACE_TYPE_MARKERS));
3735 
3736    screen->frame_marker_emitted = zink_screen_debug_marker_begin(screen, "frame");
3737 
3738    return screen;
3739 
3740 fail:
3741    zink_destroy_screen(&screen->base);
3742    return NULL;
3743 }
3744 
3745 struct pipe_screen *
zink_create_screen(struct sw_winsys * winsys,const struct pipe_screen_config * config)3746 zink_create_screen(struct sw_winsys *winsys, const struct pipe_screen_config *config)
3747 {
3748    struct zink_screen *ret = zink_internal_create_screen(config, -1, -1, 0);
3749    if (ret) {
3750       ret->drm_fd = -1;
3751    }
3752 
3753    return &ret->base;
3754 }
3755 
3756 static inline int
zink_render_rdev(int fd,int64_t * dev_major,int64_t * dev_minor)3757 zink_render_rdev(int fd, int64_t *dev_major, int64_t *dev_minor)
3758 {
3759    int ret = 0;
3760    *dev_major = *dev_minor = -1;
3761 #ifdef HAVE_LIBDRM
3762    struct stat stx;
3763    drmDevicePtr dev;
3764 
3765    if (fd == -1)
3766       return 0;
3767 
3768    if (drmGetDevice2(fd, 0, &dev))
3769       return -1;
3770 
3771    if(!(dev->available_nodes & (1 << DRM_NODE_RENDER))) {
3772       ret = -1;
3773       goto free_device;
3774    }
3775 
3776    if(stat(dev->nodes[DRM_NODE_RENDER], &stx)) {
3777       ret = -1;
3778       goto free_device;
3779    }
3780 
3781    *dev_major = major(stx.st_rdev);
3782    *dev_minor = minor(stx.st_rdev);
3783 
3784 free_device:
3785    drmFreeDevice(&dev);
3786 #endif //HAVE_LIBDRM
3787 
3788    return ret;
3789 }
3790 
3791 struct pipe_screen *
zink_drm_create_screen(int fd,const struct pipe_screen_config * config)3792 zink_drm_create_screen(int fd, const struct pipe_screen_config *config)
3793 {
3794    int64_t dev_major, dev_minor;
3795    struct zink_screen *ret;
3796 
3797    if (zink_render_rdev(fd, &dev_major, &dev_minor))
3798       return NULL;
3799 
3800    ret = zink_internal_create_screen(config, dev_major, dev_minor, 0);
3801 
3802    if (ret)
3803       ret->drm_fd = os_dupfd_cloexec(fd);
3804    if (ret && !ret->info.have_KHR_external_memory_fd) {
3805       debug_printf("ZINK: KHR_external_memory_fd required!\n");
3806       zink_destroy_screen(&ret->base);
3807       return NULL;
3808    }
3809 
3810    return &ret->base;
3811 }
3812 
3813 struct pipe_screen *
zink_win32_create_screen(uint64_t adapter_luid)3814 zink_win32_create_screen(uint64_t adapter_luid)
3815 {
3816    struct zink_screen *ret = zink_internal_create_screen(NULL, -1, -1, adapter_luid);
3817    return ret ? &ret->base : NULL;
3818 }
3819 
zink_stub_function_not_loaded()3820 void VKAPI_PTR zink_stub_function_not_loaded()
3821 {
3822    /* this will be used by the zink_verify_*_extensions() functions on a
3823     * release build
3824     */
3825    mesa_loge("ZINK: a Vulkan function was called without being loaded");
3826    abort();
3827 }
3828 
3829 bool
zink_screen_debug_marker_begin(struct zink_screen * screen,const char * fmt,...)3830 zink_screen_debug_marker_begin(struct zink_screen *screen, const char *fmt, ...)
3831 {
3832    if (!zink_tracing)
3833       return false;
3834 
3835    char *name;
3836    va_list va;
3837    va_start(va, fmt);
3838    int ret = vasprintf(&name, fmt, va);
3839    va_end(va);
3840 
3841    if (ret == -1)
3842       return false;
3843 
3844    VkDebugUtilsLabelEXT info = { 0 };
3845    info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT;
3846    info.pLabelName = name;
3847 
3848    VKSCR(QueueBeginDebugUtilsLabelEXT)(screen->queue, &info);
3849 
3850    free(name);
3851    return true;
3852 }
3853 
3854 void
zink_screen_debug_marker_end(struct zink_screen * screen,bool emitted)3855 zink_screen_debug_marker_end(struct zink_screen *screen, bool emitted)
3856 {
3857    if (emitted)
3858       VKSCR(QueueEndDebugUtilsLabelEXT)(screen->queue);
3859 }
3860