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