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