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_compiler.h"
27#include "zink_context.h"
28#include "zink_device_info.h"
29#include "zink_descriptors.h"
30#include "zink_fence.h"
31#include "zink_format.h"
32#include "zink_framebuffer.h"
33#include "zink_instance.h"
34#include "zink_program.h"
35#include "zink_public.h"
36#include "zink_resource.h"
37#include "nir_to_spirv/nir_to_spirv.h" // for SPIRV_VERSION
38
39#include "os/os_process.h"
40#include "util/u_debug.h"
41#include "util/format/u_format.h"
42#include "util/hash_table.h"
43#include "util/os_file.h"
44#include "util/u_math.h"
45#include "util/u_memory.h"
46#include "util/u_screen.h"
47#include "util/u_string.h"
48#include "util/u_transfer_helper.h"
49#include "util/xmlconfig.h"
50
51#include "util/u_cpu_detect.h"
52
53#include "frontend/sw_winsys.h"
54
55#if DETECT_OS_WINDOWS
56#include <io.h>
57#else
58#include <unistd.h>
59#endif
60
61#if defined(__APPLE__)
62// Source of MVK_VERSION
63#include "MoltenVK/vk_mvk_moltenvk.h"
64#endif
65
66static const struct debug_named_value
67zink_debug_options[] = {
68   { "nir", ZINK_DEBUG_NIR, "Dump NIR during program compile" },
69   { "spirv", ZINK_DEBUG_SPIRV, "Dump SPIR-V during program compile" },
70   { "tgsi", ZINK_DEBUG_TGSI, "Dump TGSI during program compile" },
71   { "validation", ZINK_DEBUG_VALIDATION, "Dump Validation layer output" },
72   DEBUG_NAMED_VALUE_END
73};
74
75DEBUG_GET_ONCE_FLAGS_OPTION(zink_debug, "ZINK_DEBUG", zink_debug_options, 0)
76
77uint32_t
78zink_debug;
79
80
81static const struct debug_named_value
82zink_descriptor_options[] = {
83   { "auto", ZINK_DESCRIPTOR_MODE_AUTO, "Automatically detect best mode" },
84   { "lazy", ZINK_DESCRIPTOR_MODE_LAZY, "Don't cache, do least amount of updates" },
85   { "nofallback", ZINK_DESCRIPTOR_MODE_NOFALLBACK, "Cache, never use lazy fallback" },
86   { "notemplates", ZINK_DESCRIPTOR_MODE_NOTEMPLATES, "Cache, but disable templated updates" },
87   DEBUG_NAMED_VALUE_END
88};
89
90DEBUG_GET_ONCE_FLAGS_OPTION(zink_descriptor_mode, "ZINK_DESCRIPTORS", zink_descriptor_options, ZINK_DESCRIPTOR_MODE_AUTO)
91
92static const char *
93zink_get_vendor(struct pipe_screen *pscreen)
94{
95   return "Collabora Ltd";
96}
97
98static const char *
99zink_get_device_vendor(struct pipe_screen *pscreen)
100{
101   struct zink_screen *screen = zink_screen(pscreen);
102   static char buf[1000];
103   snprintf(buf, sizeof(buf), "Unknown (vendor-id: 0x%04x)", screen->info.props.vendorID);
104   return buf;
105}
106
107static const char *
108zink_get_name(struct pipe_screen *pscreen)
109{
110   struct zink_screen *screen = zink_screen(pscreen);
111   static char buf[1000];
112   snprintf(buf, sizeof(buf), "zink (%s)", screen->info.props.deviceName);
113   return buf;
114}
115
116static uint32_t
117hash_framebuffer_state(const void *key)
118{
119   struct zink_framebuffer_state* s = (struct zink_framebuffer_state*)key;
120   return _mesa_hash_data(key, offsetof(struct zink_framebuffer_state, attachments) + sizeof(s->attachments[0]) * s->num_attachments);
121}
122
123static bool
124equals_framebuffer_state(const void *a, const void *b)
125{
126   struct zink_framebuffer_state *s = (struct zink_framebuffer_state*)a;
127   return memcmp(a, b, offsetof(struct zink_framebuffer_state, attachments) + sizeof(s->attachments[0]) * s->num_attachments) == 0;
128}
129
130static VkDeviceSize
131get_video_mem(struct zink_screen *screen)
132{
133   VkDeviceSize size = 0;
134   for (uint32_t i = 0; i < screen->info.mem_props.memoryHeapCount; ++i) {
135      if (screen->info.mem_props.memoryHeaps[i].flags &
136          VK_MEMORY_HEAP_DEVICE_LOCAL_BIT)
137         size += screen->info.mem_props.memoryHeaps[i].size;
138   }
139   return size;
140}
141
142static void
143disk_cache_init(struct zink_screen *screen)
144{
145#ifdef ENABLE_SHADER_CACHE
146   static char buf[1000];
147   snprintf(buf, sizeof(buf), "zink_%x04x", screen->info.props.vendorID);
148
149   screen->disk_cache = disk_cache_create(buf, screen->info.props.deviceName, 0);
150   if (screen->disk_cache) {
151      util_queue_init(&screen->cache_put_thread, "zcq", 8, 1, UTIL_QUEUE_INIT_RESIZE_IF_FULL, screen);
152      util_queue_init(&screen->cache_get_thread, "zcfq", 8, 4, UTIL_QUEUE_INIT_RESIZE_IF_FULL, screen);
153   }
154#endif
155}
156
157
158static void
159cache_put_job(void *data, void *gdata, int thread_index)
160{
161   struct zink_program *pg = data;
162   struct zink_screen *screen = gdata;
163   size_t size = 0;
164   if (VKSCR(GetPipelineCacheData)(screen->dev, pg->pipeline_cache, &size, NULL) != VK_SUCCESS)
165      return;
166   if (pg->pipeline_cache_size == size)
167      return;
168   void *pipeline_data = malloc(size);
169   if (!pipeline_data)
170      return;
171   if (VKSCR(GetPipelineCacheData)(screen->dev, pg->pipeline_cache, &size, pipeline_data) == VK_SUCCESS) {
172      pg->pipeline_cache_size = size;
173
174      cache_key key;
175      disk_cache_compute_key(screen->disk_cache, pg->sha1, sizeof(pg->sha1), key);
176      disk_cache_put_nocopy(screen->disk_cache, key, pipeline_data, size, NULL);
177   }
178}
179
180void
181zink_screen_update_pipeline_cache(struct zink_screen *screen, struct zink_program *pg)
182{
183   util_queue_fence_init(&pg->cache_fence);
184   if (!screen->disk_cache)
185      return;
186
187   util_queue_add_job(&screen->cache_put_thread, pg, NULL, cache_put_job, NULL, 0);
188}
189
190static void
191cache_get_job(void *data, void *gdata, int thread_index)
192{
193   struct zink_program *pg = data;
194   struct zink_screen *screen = gdata;
195
196   VkPipelineCacheCreateInfo pcci;
197   pcci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
198   pcci.pNext = NULL;
199   pcci.flags = screen->info.have_EXT_pipeline_creation_cache_control ? VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT_EXT : 0;
200   pcci.initialDataSize = 0;
201   pcci.pInitialData = NULL;
202
203   cache_key key;
204   disk_cache_compute_key(screen->disk_cache, pg->sha1, sizeof(pg->sha1), key);
205   pcci.pInitialData = disk_cache_get(screen->disk_cache, key, &pg->pipeline_cache_size);
206   pcci.initialDataSize = pg->pipeline_cache_size;
207   VKSCR(CreatePipelineCache)(screen->dev, &pcci, NULL, &pg->pipeline_cache);
208   free((void*)pcci.pInitialData);
209}
210
211void
212zink_screen_get_pipeline_cache(struct zink_screen *screen, struct zink_program *pg)
213{
214   util_queue_fence_init(&pg->cache_fence);
215   if (!screen->disk_cache)
216      return;
217
218   util_queue_add_job(&screen->cache_get_thread, pg, &pg->cache_fence, cache_get_job, NULL, 0);
219}
220
221static int
222zink_get_compute_param(struct pipe_screen *pscreen, enum pipe_shader_ir ir_type,
223                       enum pipe_compute_cap param, void *ret)
224{
225   struct zink_screen *screen = zink_screen(pscreen);
226#define RET(x) do {                  \
227   if (ret)                          \
228      memcpy(ret, x, sizeof(x));     \
229   return sizeof(x);                 \
230} while (0)
231
232   switch (param) {
233   case PIPE_COMPUTE_CAP_ADDRESS_BITS:
234      RET((uint32_t []){ 32 });
235
236   case PIPE_COMPUTE_CAP_IR_TARGET:
237      if (ret)
238         strcpy(ret, "nir");
239      return 4;
240
241   case PIPE_COMPUTE_CAP_GRID_DIMENSION:
242      RET((uint64_t []) { 3 });
243
244   case PIPE_COMPUTE_CAP_MAX_GRID_SIZE:
245      RET(((uint64_t []) { screen->info.props.limits.maxComputeWorkGroupCount[0],
246                           screen->info.props.limits.maxComputeWorkGroupCount[1],
247                           screen->info.props.limits.maxComputeWorkGroupCount[2] }));
248
249   case PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE:
250      /* MaxComputeWorkGroupSize[0..2] */
251      RET(((uint64_t []) {screen->info.props.limits.maxComputeWorkGroupSize[0],
252                          screen->info.props.limits.maxComputeWorkGroupSize[1],
253                          screen->info.props.limits.maxComputeWorkGroupSize[2]}));
254
255   case PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK:
256   case PIPE_COMPUTE_CAP_MAX_VARIABLE_THREADS_PER_BLOCK:
257      RET((uint64_t []) { screen->info.props.limits.maxComputeWorkGroupInvocations });
258
259   case PIPE_COMPUTE_CAP_MAX_LOCAL_SIZE:
260      RET((uint64_t []) { screen->info.props.limits.maxComputeSharedMemorySize });
261
262   case PIPE_COMPUTE_CAP_IMAGES_SUPPORTED:
263      RET((uint32_t []) { 1 });
264
265   case PIPE_COMPUTE_CAP_SUBGROUP_SIZE:
266      RET((uint32_t []) { screen->info.props11.subgroupSize });
267
268   case PIPE_COMPUTE_CAP_MAX_MEM_ALLOC_SIZE:
269   case PIPE_COMPUTE_CAP_MAX_CLOCK_FREQUENCY:
270   case PIPE_COMPUTE_CAP_MAX_COMPUTE_UNITS:
271   case PIPE_COMPUTE_CAP_MAX_GLOBAL_SIZE:
272   case PIPE_COMPUTE_CAP_MAX_PRIVATE_SIZE:
273   case PIPE_COMPUTE_CAP_MAX_INPUT_SIZE:
274      // XXX: I think these are for Clover...
275      return 0;
276
277   default:
278      unreachable("unknown compute param");
279   }
280}
281
282static uint32_t
283get_smallest_buffer_heap(struct zink_screen *screen)
284{
285   enum zink_heap heaps[] = {
286      ZINK_HEAP_DEVICE_LOCAL,
287      ZINK_HEAP_DEVICE_LOCAL_VISIBLE,
288      ZINK_HEAP_HOST_VISIBLE_COHERENT,
289      ZINK_HEAP_HOST_VISIBLE_COHERENT
290   };
291   unsigned size = UINT32_MAX;
292   for (unsigned i = 0; i < ARRAY_SIZE(heaps); i++) {
293      unsigned heap_idx = screen->info.mem_props.memoryTypes[screen->heap_map[i]].heapIndex;
294      size = MIN2(screen->info.mem_props.memoryHeaps[heap_idx].size, size);
295   }
296   return size;
297}
298
299static int
300zink_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
301{
302   struct zink_screen *screen = zink_screen(pscreen);
303
304   switch (param) {
305   case PIPE_CAP_ANISOTROPIC_FILTER:
306      return screen->info.feats.features.samplerAnisotropy;
307   case PIPE_CAP_EMULATE_NONFIXED_PRIMITIVE_RESTART:
308      return 1;
309   case PIPE_CAP_SUPPORTED_PRIM_MODES_WITH_RESTART: {
310      uint32_t modes = BITFIELD_BIT(PIPE_PRIM_LINE_STRIP) |
311                       BITFIELD_BIT(PIPE_PRIM_TRIANGLE_STRIP) |
312                       BITFIELD_BIT(PIPE_PRIM_LINE_STRIP_ADJACENCY) |
313                       BITFIELD_BIT(PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY);
314      if (screen->have_triangle_fans)
315         modes |= BITFIELD_BIT(PIPE_PRIM_TRIANGLE_FAN);
316      if (screen->info.have_EXT_primitive_topology_list_restart) {
317         modes |= BITFIELD_BIT(PIPE_PRIM_POINTS) |
318                  BITFIELD_BIT(PIPE_PRIM_LINES) |
319                  BITFIELD_BIT(PIPE_PRIM_TRIANGLES) |
320                  BITFIELD_BIT(PIPE_PRIM_TRIANGLES_ADJACENCY);
321         if (screen->info.list_restart_feats.primitiveTopologyPatchListRestart)
322            modes |= BITFIELD_BIT(PIPE_PRIM_PATCHES);
323      }
324      return modes;
325   }
326   case PIPE_CAP_SUPPORTED_PRIM_MODES: {
327      uint32_t modes = BITFIELD_MASK(PIPE_PRIM_MAX);
328      modes &= ~BITFIELD_BIT(PIPE_PRIM_QUADS);
329      modes &= ~BITFIELD_BIT(PIPE_PRIM_QUAD_STRIP);
330      modes &= ~BITFIELD_BIT(PIPE_PRIM_POLYGON);
331      modes &= ~BITFIELD_BIT(PIPE_PRIM_LINE_LOOP);
332      if (!screen->have_triangle_fans)
333         modes &= ~BITFIELD_BIT(PIPE_PRIM_TRIANGLE_FAN);
334      return modes;
335   }
336
337   case PIPE_CAP_FBFETCH:
338      return 1;
339
340   case PIPE_CAP_QUERY_MEMORY_INFO:
341   case PIPE_CAP_NPOT_TEXTURES:
342   case PIPE_CAP_TGSI_TEXCOORD:
343   case PIPE_CAP_DRAW_INDIRECT:
344   case PIPE_CAP_TEXTURE_QUERY_LOD:
345   case PIPE_CAP_GLSL_TESS_LEVELS_AS_INPUTS:
346   case PIPE_CAP_CLEAR_TEXTURE:
347   case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS:
348   case PIPE_CAP_FORCE_PERSAMPLE_INTERP:
349   case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:
350   case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
351   case PIPE_CAP_TGSI_ARRAY_COMPONENTS:
352   case PIPE_CAP_QUERY_BUFFER_OBJECT:
353   case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
354   case PIPE_CAP_CLIP_HALFZ:
355   case PIPE_CAP_TGSI_TXQS:
356   case PIPE_CAP_TEXTURE_BARRIER:
357   case PIPE_CAP_QUERY_SO_OVERFLOW:
358   case PIPE_CAP_GL_SPIRV:
359   case PIPE_CAP_CLEAR_SCISSORED:
360   case PIPE_CAP_INVALIDATE_BUFFER:
361   case PIPE_CAP_PREFER_REAL_BUFFER_IN_CONSTBUF0:
362   case PIPE_CAP_PACKED_UNIFORMS:
363   case PIPE_CAP_TGSI_PACK_HALF_FLOAT:
364      return 1;
365
366   case PIPE_CAP_SURFACE_SAMPLE_COUNT:
367      return screen->vk_version >= VK_MAKE_VERSION(1,2,0);
368
369   case PIPE_CAP_DRAW_PARAMETERS:
370      return screen->info.feats11.shaderDrawParameters || screen->info.have_KHR_shader_draw_parameters;
371
372   case PIPE_CAP_TGSI_VOTE:
373      return screen->spirv_version >= SPIRV_VERSION(1, 3);
374
375   case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
376      return screen->info.have_EXT_provoking_vertex;
377
378   case PIPE_CAP_TEXTURE_MIRROR_CLAMP_TO_EDGE:
379      return screen->info.have_KHR_sampler_mirror_clamp_to_edge;
380
381   case PIPE_CAP_POLYGON_OFFSET_CLAMP:
382      return screen->info.feats.features.depthBiasClamp;
383
384   case PIPE_CAP_QUERY_PIPELINE_STATISTICS_SINGLE:
385      return screen->info.feats.features.pipelineStatisticsQuery;
386
387   case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR:
388      return screen->info.feats.features.robustBufferAccess;
389
390   case PIPE_CAP_MULTI_DRAW_INDIRECT:
391      return screen->info.feats.features.multiDrawIndirect;
392
393   case PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS:
394      return screen->info.have_KHR_draw_indirect_count;
395
396   case PIPE_CAP_START_INSTANCE:
397      return (screen->info.have_vulkan12 && screen->info.feats11.shaderDrawParameters) ||
398              screen->info.have_KHR_shader_draw_parameters;
399
400   case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
401      return screen->info.have_EXT_vertex_attribute_divisor;
402
403   case PIPE_CAP_MAX_VERTEX_STREAMS:
404      return screen->info.tf_props.maxTransformFeedbackStreams;
405
406   case PIPE_CAP_INT64:
407   case PIPE_CAP_INT64_DIVMOD:
408   case PIPE_CAP_DOUBLES:
409      return 1;
410
411   case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
412      if (!screen->info.feats.features.dualSrcBlend)
413         return 0;
414      return screen->info.props.limits.maxFragmentDualSrcAttachments;
415
416   case PIPE_CAP_MAX_RENDER_TARGETS:
417      return screen->info.props.limits.maxColorAttachments;
418
419   case PIPE_CAP_OCCLUSION_QUERY:
420      return screen->info.feats.features.occlusionQueryPrecise;
421
422   case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS:
423      return screen->info.have_EXT_sample_locations && screen->info.have_EXT_extended_dynamic_state;
424
425   case PIPE_CAP_QUERY_TIME_ELAPSED:
426      return screen->timestamp_valid_bits > 0;
427
428   case PIPE_CAP_TEXTURE_MULTISAMPLE:
429      return 1;
430
431   case PIPE_CAP_FRAGMENT_SHADER_INTERLOCK:
432      return screen->info.have_EXT_fragment_shader_interlock;
433
434   case PIPE_CAP_TGSI_CLOCK:
435      return screen->info.have_KHR_shader_clock;
436
437   case PIPE_CAP_POINT_SPRITE:
438      return 1;
439
440   case PIPE_CAP_TGSI_BALLOT:
441      return screen->info.have_vulkan12 && screen->info.have_EXT_shader_subgroup_ballot && screen->info.props11.subgroupSize <= 64;
442
443   case PIPE_CAP_SAMPLE_SHADING:
444      return screen->info.feats.features.sampleRateShading;
445
446   case PIPE_CAP_TEXTURE_SWIZZLE:
447      return 1;
448
449   case PIPE_CAP_GL_CLAMP:
450      return 0;
451
452   case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
453      /* This is also broken on the other AMD drivers for old HW, but
454       * there's no obvious way to test for that.
455       */
456      if (screen->info.driver_props.driverID == VK_DRIVER_ID_MESA_RADV ||
457          screen->info.driver_props.driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY)
458         return PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50;
459      return 0;
460
461   case PIPE_CAP_MAX_TEXTURE_2D_SIZE:
462      return screen->info.props.limits.maxImageDimension2D;
463   case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
464      return 1 + util_logbase2(screen->info.props.limits.maxImageDimension3D);
465   case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
466      return 1 + util_logbase2(screen->info.props.limits.maxImageDimensionCube);
467
468   case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD:
469   case PIPE_CAP_FRAGMENT_SHADER_DERIVATIVES:
470   case PIPE_CAP_VERTEX_SHADER_SATURATE:
471      return 1;
472
473   case PIPE_CAP_BLEND_EQUATION_SEPARATE:
474   case PIPE_CAP_INDEP_BLEND_ENABLE:
475   case PIPE_CAP_INDEP_BLEND_FUNC:
476      return screen->info.feats.features.independentBlend;
477
478   case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
479      return screen->info.have_EXT_transform_feedback ? screen->info.tf_props.maxTransformFeedbackBuffers : 0;
480   case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
481   case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS:
482      return screen->info.have_EXT_transform_feedback;
483
484   case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
485      return screen->info.props.limits.maxImageArrayLayers;
486
487   case PIPE_CAP_DEPTH_CLIP_DISABLE:
488      return screen->info.feats.features.depthClamp;
489
490   case PIPE_CAP_SHADER_STENCIL_EXPORT:
491      return screen->info.have_EXT_shader_stencil_export;
492
493   case PIPE_CAP_TGSI_INSTANCEID:
494   case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
495   case PIPE_CAP_SEAMLESS_CUBE_MAP:
496      return 1;
497
498   case PIPE_CAP_MIN_TEXEL_OFFSET:
499      return screen->info.props.limits.minTexelOffset;
500   case PIPE_CAP_MAX_TEXEL_OFFSET:
501      return screen->info.props.limits.maxTexelOffset;
502
503   case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
504      return 1;
505
506   case PIPE_CAP_CONDITIONAL_RENDER:
507     return 1;
508
509   case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY:
510   case PIPE_CAP_GLSL_FEATURE_LEVEL:
511      return 460;
512
513   case PIPE_CAP_COMPUTE:
514      return 1;
515
516   case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
517      return screen->info.props.limits.minUniformBufferOffsetAlignment;
518
519   case PIPE_CAP_QUERY_TIMESTAMP:
520      return screen->info.have_EXT_calibrated_timestamps &&
521             screen->timestamp_valid_bits > 0;
522
523   case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
524      return screen->info.props.limits.minMemoryMapAlignment;
525
526   case PIPE_CAP_CUBE_MAP_ARRAY:
527      return screen->info.feats.features.imageCubeArray;
528
529   case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
530   case PIPE_CAP_PRIMITIVE_RESTART:
531      return 1;
532
533   case PIPE_CAP_BINDLESS_TEXTURE:
534      return screen->info.have_EXT_descriptor_indexing &&
535             /* push, 4 types, bindless */
536             screen->info.props.limits.maxBoundDescriptorSets >= 6;
537
538   case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
539      return screen->info.props.limits.minTexelBufferOffsetAlignment;
540
541   case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
542      return 1;
543
544   case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
545      return MIN2(get_smallest_buffer_heap(screen),
546                  screen->info.props.limits.maxTexelBufferElements);
547
548   case PIPE_CAP_ENDIANNESS:
549      return PIPE_ENDIAN_NATIVE; /* unsure */
550
551   case PIPE_CAP_MAX_VIEWPORTS:
552      return MIN2(screen->info.props.limits.maxViewports, PIPE_MAX_VIEWPORTS);
553
554   case PIPE_CAP_IMAGE_LOAD_FORMATTED:
555      return screen->info.feats.features.shaderStorageImageReadWithoutFormat;
556
557   case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
558      return 1;
559
560   case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES:
561      return screen->info.props.limits.maxGeometryOutputVertices;
562   case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:
563      return screen->info.props.limits.maxGeometryTotalOutputComponents;
564
565   case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
566      return 4;
567
568   case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:
569      return screen->info.props.limits.minTexelGatherOffset;
570   case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:
571      return screen->info.props.limits.maxTexelGatherOffset;
572
573   case PIPE_CAP_SAMPLER_REDUCTION_MINMAX_ARB:
574      return screen->vk_version >= VK_MAKE_VERSION(1,2,0) || screen->info.have_EXT_sampler_filter_minmax;
575
576   case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE:
577      return 1;
578
579   case PIPE_CAP_VENDOR_ID:
580      return screen->info.props.vendorID;
581   case PIPE_CAP_DEVICE_ID:
582      return screen->info.props.deviceID;
583
584   case PIPE_CAP_ACCELERATED:
585      return 1;
586   case PIPE_CAP_VIDEO_MEMORY:
587      return get_video_mem(screen) >> 20;
588   case PIPE_CAP_UMA:
589      return screen->info.props.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
590
591   case PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE:
592      return screen->info.props.limits.maxVertexInputBindingStride;
593
594   case PIPE_CAP_SAMPLER_VIEW_TARGET:
595      return 1;
596
597   case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT:
598   case PIPE_CAP_TGSI_TES_LAYER_VIEWPORT:
599      return screen->info.have_EXT_shader_viewport_index_layer ||
600             (screen->spirv_version >= SPIRV_VERSION(1, 5) &&
601              screen->info.feats12.shaderOutputLayer &&
602              screen->info.feats12.shaderOutputViewportIndex);
603
604   case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
605   case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
606      return 1;
607
608   case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
609      return screen->info.props.limits.minStorageBufferOffsetAlignment;
610
611   case PIPE_CAP_PCI_GROUP:
612   case PIPE_CAP_PCI_BUS:
613   case PIPE_CAP_PCI_DEVICE:
614   case PIPE_CAP_PCI_FUNCTION:
615      return 0; /* TODO: figure these out */
616
617   case PIPE_CAP_CULL_DISTANCE:
618      return screen->info.feats.features.shaderCullDistance;
619
620   case PIPE_CAP_SPARSE_BUFFER_PAGE_SIZE:
621
622      return screen->info.feats.features.sparseBinding ? ZINK_SPARSE_BUFFER_PAGE_SIZE : 0;
623
624   case PIPE_CAP_VIEWPORT_SUBPIXEL_BITS:
625      return screen->info.props.limits.viewportSubPixelBits;
626
627   case PIPE_CAP_GLSL_OPTIMIZE_CONSERVATIVELY:
628      return 0; /* not sure */
629
630   case PIPE_CAP_MAX_GS_INVOCATIONS:
631      return screen->info.props.limits.maxGeometryShaderInvocations;
632
633   case PIPE_CAP_MAX_COMBINED_SHADER_BUFFERS:
634      /* gallium handles this automatically */
635      return 0;
636
637   case PIPE_CAP_MAX_SHADER_BUFFER_SIZE:
638      /* 1<<27 is required by VK spec */
639      assert(screen->info.props.limits.maxStorageBufferRange >= 1 << 27);
640      /* but Gallium can't handle values that are too big, so clamp to VK spec minimum */
641      return MIN2(get_smallest_buffer_heap(screen), 1 << 27);
642
643   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
644   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
645      return 1;
646
647   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
648   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
649      return 0;
650
651   case PIPE_CAP_NIR_COMPACT_ARRAYS:
652      return 1;
653
654   case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
655      return 1;
656
657   case PIPE_CAP_VIEWPORT_TRANSFORM_LOWERED:
658      return 1;
659
660   case PIPE_CAP_FLATSHADE:
661   case PIPE_CAP_ALPHA_TEST:
662   case PIPE_CAP_CLIP_PLANES:
663   case PIPE_CAP_POINT_SIZE_FIXED:
664   case PIPE_CAP_TWO_SIDED_COLOR:
665      return 0;
666
667   case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS:
668      return screen->info.props.limits.maxTessellationControlPerVertexOutputComponents / 4;
669   case PIPE_CAP_MAX_VARYINGS:
670      /* need to reserve up to 60 of our varying components and 16 slots for streamout */
671      return MIN2(screen->info.props.limits.maxVertexOutputComponents / 4 / 2, 16);
672
673   case PIPE_CAP_DMABUF:
674      return screen->info.have_KHR_external_memory_fd &&
675             screen->info.have_EXT_external_memory_dma_buf &&
676             screen->info.have_EXT_queue_family_foreign &&
677             screen->info.have_EXT_image_drm_format_modifier;
678
679   case PIPE_CAP_DEPTH_BOUNDS_TEST:
680      return screen->info.feats.features.depthBounds;
681
682   case PIPE_CAP_POST_DEPTH_COVERAGE:
683      return screen->info.have_EXT_post_depth_coverage;
684
685   case PIPE_CAP_STRING_MARKER:
686      return screen->instance_info.have_EXT_debug_utils;
687
688   default:
689      return u_pipe_screen_get_param_defaults(pscreen, param);
690   }
691}
692
693static float
694zink_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)
695{
696   struct zink_screen *screen = zink_screen(pscreen);
697
698   switch (param) {
699   case PIPE_CAPF_MAX_LINE_WIDTH:
700   case PIPE_CAPF_MAX_LINE_WIDTH_AA:
701      if (!screen->info.feats.features.wideLines)
702         return 1.0f;
703      return screen->info.props.limits.lineWidthRange[1];
704
705   case PIPE_CAPF_MAX_POINT_WIDTH:
706   case PIPE_CAPF_MAX_POINT_WIDTH_AA:
707      if (!screen->info.feats.features.largePoints)
708         return 1.0f;
709      return screen->info.props.limits.pointSizeRange[1];
710
711   case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
712      if (!screen->info.feats.features.samplerAnisotropy)
713         return 1.0f;
714      return screen->info.props.limits.maxSamplerAnisotropy;
715
716   case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
717      return screen->info.props.limits.maxSamplerLodBias;
718
719   case PIPE_CAPF_MIN_CONSERVATIVE_RASTER_DILATE:
720   case PIPE_CAPF_MAX_CONSERVATIVE_RASTER_DILATE:
721   case PIPE_CAPF_CONSERVATIVE_RASTER_DILATE_GRANULARITY:
722      return 0.0f; /* not implemented */
723   }
724
725   /* should only get here on unhandled cases */
726   return 0.0f;
727}
728
729static int
730zink_get_shader_param(struct pipe_screen *pscreen,
731                       enum pipe_shader_type shader,
732                       enum pipe_shader_cap param)
733{
734   struct zink_screen *screen = zink_screen(pscreen);
735
736   switch (param) {
737   case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
738      switch (shader) {
739      case PIPE_SHADER_FRAGMENT:
740      case PIPE_SHADER_VERTEX:
741         return INT_MAX;
742      case PIPE_SHADER_TESS_CTRL:
743      case PIPE_SHADER_TESS_EVAL:
744         if (screen->info.feats.features.tessellationShader &&
745             screen->info.have_KHR_maintenance2)
746            return INT_MAX;
747         break;
748
749      case PIPE_SHADER_GEOMETRY:
750         if (screen->info.feats.features.geometryShader)
751            return INT_MAX;
752         break;
753
754      case PIPE_SHADER_COMPUTE:
755         return INT_MAX;
756      default:
757         break;
758      }
759      return 0;
760   case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
761   case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
762   case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
763   case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
764      return INT_MAX;
765
766   case PIPE_SHADER_CAP_MAX_INPUTS: {
767      uint32_t max = 0;
768      switch (shader) {
769      case PIPE_SHADER_VERTEX:
770         max = MIN2(screen->info.props.limits.maxVertexInputAttributes, PIPE_MAX_ATTRIBS);
771         break;
772      case PIPE_SHADER_TESS_CTRL:
773         max = screen->info.props.limits.maxTessellationControlPerVertexInputComponents / 4;
774         break;
775      case PIPE_SHADER_TESS_EVAL:
776         max = screen->info.props.limits.maxTessellationEvaluationInputComponents / 4;
777         break;
778      case PIPE_SHADER_GEOMETRY:
779         max = screen->info.props.limits.maxGeometryInputComponents;
780         break;
781      case PIPE_SHADER_FRAGMENT:
782         /* intel drivers report fewer components, but it's a value that's compatible
783          * with what we need for GL, so we can still force a conformant value here
784          */
785         if (screen->info.driver_props.driverID == VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA_KHR ||
786             screen->info.driver_props.driverID == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR)
787            return 32;
788         max = screen->info.props.limits.maxFragmentInputComponents / 4;
789         break;
790      default:
791         return 0; /* unsupported stage */
792      }
793      switch (shader) {
794      case PIPE_SHADER_VERTEX:
795      case PIPE_SHADER_TESS_EVAL:
796      case PIPE_SHADER_GEOMETRY:
797         /* last vertex stage must support streamout, and this is capped in glsl compiler */
798         return MIN2(max, MAX_VARYING);
799      default: break;
800      }
801      return MIN2(max, 64); // prevent overflowing struct shader_info::inputs_read
802   }
803
804   case PIPE_SHADER_CAP_MAX_OUTPUTS: {
805      uint32_t max = 0;
806      switch (shader) {
807      case PIPE_SHADER_VERTEX:
808         max = screen->info.props.limits.maxVertexOutputComponents / 4;
809         break;
810      case PIPE_SHADER_TESS_CTRL:
811         max = screen->info.props.limits.maxTessellationControlPerVertexOutputComponents / 4;
812         break;
813      case PIPE_SHADER_TESS_EVAL:
814         max = screen->info.props.limits.maxTessellationEvaluationOutputComponents / 4;
815         break;
816      case PIPE_SHADER_GEOMETRY:
817         max = screen->info.props.limits.maxGeometryOutputComponents / 4;
818         break;
819      case PIPE_SHADER_FRAGMENT:
820         max = screen->info.props.limits.maxColorAttachments;
821         break;
822      default:
823         return 0; /* unsupported stage */
824      }
825      return MIN2(max, 64); // prevent overflowing struct shader_info::outputs_read/written
826   }
827
828   case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
829      /* At least 16384 is guaranteed by VK spec */
830      assert(screen->info.props.limits.maxUniformBufferRange >= 16384);
831      /* but Gallium can't handle values that are too big */
832      return MIN3(get_smallest_buffer_heap(screen),
833                  screen->info.props.limits.maxUniformBufferRange, 1 << 31);
834
835   case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
836      return  MIN2(screen->info.props.limits.maxPerStageDescriptorUniformBuffers,
837                   PIPE_MAX_CONSTANT_BUFFERS);
838
839   case PIPE_SHADER_CAP_MAX_TEMPS:
840      return INT_MAX;
841
842   case PIPE_SHADER_CAP_INTEGERS:
843      return 1;
844
845   case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
846      return 1;
847
848   case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
849   case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
850   case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
851   case PIPE_SHADER_CAP_SUBROUTINES:
852   case PIPE_SHADER_CAP_INT64_ATOMICS:
853   case PIPE_SHADER_CAP_GLSL_16BIT_CONSTS:
854      return 0; /* not implemented */
855
856   case PIPE_SHADER_CAP_FP16_CONST_BUFFERS:
857      //enabling this breaks GTF-GL46.gtf21.GL2Tests.glGetUniform.glGetUniform
858      //return screen->info.feats11.uniformAndStorageBuffer16BitAccess ||
859             //(screen->info.have_KHR_16bit_storage && screen->info.storage_16bit_feats.uniformAndStorageBuffer16BitAccess);
860      return 0;
861   case PIPE_SHADER_CAP_FP16_DERIVATIVES:
862      return 0; //spirv requires 32bit derivative srcs and dests
863   case PIPE_SHADER_CAP_FP16:
864      return screen->info.feats12.shaderFloat16 ||
865             (screen->info.have_KHR_shader_float16_int8 &&
866              screen->info.shader_float16_int8_feats.shaderFloat16);
867
868   case PIPE_SHADER_CAP_INT16:
869      return screen->info.feats.features.shaderInt16;
870
871   case PIPE_SHADER_CAP_PREFERRED_IR:
872      return PIPE_SHADER_IR_NIR;
873
874   case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
875      return 0; /* not implemented */
876
877   case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
878   case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
879      return MIN2(MIN2(screen->info.props.limits.maxPerStageDescriptorSamplers,
880                       screen->info.props.limits.maxPerStageDescriptorSampledImages),
881                  PIPE_MAX_SAMPLERS);
882
883   case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
884   case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
885   case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
886      return 0; /* not implemented */
887
888   case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
889      return 0; /* no idea */
890
891   case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT:
892      return 0;
893
894   case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
895      switch (shader) {
896      case PIPE_SHADER_VERTEX:
897      case PIPE_SHADER_TESS_CTRL:
898      case PIPE_SHADER_TESS_EVAL:
899      case PIPE_SHADER_GEOMETRY:
900         if (!screen->info.feats.features.vertexPipelineStoresAndAtomics)
901            return 0;
902         break;
903
904      case PIPE_SHADER_FRAGMENT:
905         if (!screen->info.feats.features.fragmentStoresAndAtomics)
906            return 0;
907         break;
908
909      default:
910         break;
911      }
912
913      /* TODO: this limitation is dumb, and will need some fixes in mesa */
914      return MIN2(screen->info.props.limits.maxPerStageDescriptorStorageBuffers, PIPE_MAX_SHADER_BUFFERS);
915
916   case PIPE_SHADER_CAP_SUPPORTED_IRS:
917      return (1 << PIPE_SHADER_IR_NIR) | (1 << PIPE_SHADER_IR_TGSI);
918
919   case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
920      if (screen->info.feats.features.shaderStorageImageExtendedFormats &&
921          screen->info.feats.features.shaderStorageImageWriteWithoutFormat)
922         return MIN2(screen->info.props.limits.maxPerStageDescriptorStorageImages,
923                     PIPE_MAX_SHADER_IMAGES);
924      return 0;
925
926   case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD:
927   case PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS:
928      return 0; /* unsure */
929
930   case PIPE_SHADER_CAP_TGSI_LDEXP_SUPPORTED:
931   case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:
932   case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:
933   case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
934      return 0; /* not implemented */
935   }
936
937   /* should only get here on unhandled cases */
938   return 0;
939}
940
941static VkSampleCountFlagBits
942vk_sample_count_flags(uint32_t sample_count)
943{
944   switch (sample_count) {
945   case 1: return VK_SAMPLE_COUNT_1_BIT;
946   case 2: return VK_SAMPLE_COUNT_2_BIT;
947   case 4: return VK_SAMPLE_COUNT_4_BIT;
948   case 8: return VK_SAMPLE_COUNT_8_BIT;
949   case 16: return VK_SAMPLE_COUNT_16_BIT;
950   case 32: return VK_SAMPLE_COUNT_32_BIT;
951   case 64: return VK_SAMPLE_COUNT_64_BIT;
952   default:
953      return 0;
954   }
955}
956
957static bool
958zink_is_format_supported(struct pipe_screen *pscreen,
959                         enum pipe_format format,
960                         enum pipe_texture_target target,
961                         unsigned sample_count,
962                         unsigned storage_sample_count,
963                         unsigned bind)
964{
965   struct zink_screen *screen = zink_screen(pscreen);
966
967   if (storage_sample_count && !screen->info.feats.features.shaderStorageImageMultisample && bind & PIPE_BIND_SHADER_IMAGE)
968      return false;
969
970   if (format == PIPE_FORMAT_NONE)
971      return screen->info.props.limits.framebufferNoAttachmentsSampleCounts &
972             vk_sample_count_flags(sample_count);
973
974   if (bind & PIPE_BIND_INDEX_BUFFER) {
975      if (format == PIPE_FORMAT_R8_UINT &&
976          !screen->info.have_EXT_index_type_uint8)
977         return false;
978      if (format != PIPE_FORMAT_R8_UINT &&
979          format != PIPE_FORMAT_R16_UINT &&
980          format != PIPE_FORMAT_R32_UINT)
981         return false;
982   }
983
984   VkFormat vkformat = zink_get_format(screen, format);
985   if (vkformat == VK_FORMAT_UNDEFINED)
986      return false;
987
988   if (sample_count >= 1) {
989      VkSampleCountFlagBits sample_mask = vk_sample_count_flags(sample_count);
990      if (!sample_mask)
991         return false;
992      const struct util_format_description *desc = util_format_description(format);
993      if (util_format_is_depth_or_stencil(format)) {
994         if (util_format_has_depth(desc)) {
995            if (bind & PIPE_BIND_DEPTH_STENCIL &&
996                (screen->info.props.limits.framebufferDepthSampleCounts & sample_mask) != sample_mask)
997               return false;
998            if (bind & PIPE_BIND_SAMPLER_VIEW &&
999                (screen->info.props.limits.sampledImageDepthSampleCounts & sample_mask) != sample_mask)
1000               return false;
1001         }
1002         if (util_format_has_stencil(desc)) {
1003            if (bind & PIPE_BIND_DEPTH_STENCIL &&
1004                (screen->info.props.limits.framebufferStencilSampleCounts & sample_mask) != sample_mask)
1005               return false;
1006            if (bind & PIPE_BIND_SAMPLER_VIEW &&
1007                (screen->info.props.limits.sampledImageStencilSampleCounts & sample_mask) != sample_mask)
1008               return false;
1009         }
1010      } else if (util_format_is_pure_integer(format)) {
1011         if (bind & PIPE_BIND_RENDER_TARGET &&
1012             !(screen->info.props.limits.framebufferColorSampleCounts & sample_mask))
1013            return false;
1014         if (bind & PIPE_BIND_SAMPLER_VIEW &&
1015             !(screen->info.props.limits.sampledImageIntegerSampleCounts & sample_mask))
1016            return false;
1017      } else {
1018         if (bind & PIPE_BIND_RENDER_TARGET &&
1019             !(screen->info.props.limits.framebufferColorSampleCounts & sample_mask))
1020            return false;
1021         if (bind & PIPE_BIND_SAMPLER_VIEW &&
1022             !(screen->info.props.limits.sampledImageColorSampleCounts & sample_mask))
1023            return false;
1024      }
1025      if (bind & PIPE_BIND_SHADER_IMAGE) {
1026          if (!(screen->info.props.limits.storageImageSampleCounts & sample_mask))
1027             return false;
1028      }
1029   }
1030
1031   VkFormatProperties props = screen->format_props[format];
1032
1033   if (target == PIPE_BUFFER) {
1034      if (bind & PIPE_BIND_VERTEX_BUFFER) {
1035         if (!(props.bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)) {
1036            enum pipe_format new_format = zink_decompose_vertex_format(format);
1037            if (!new_format)
1038               return false;
1039            if (!(screen->format_props[new_format].bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))
1040               return false;
1041         }
1042      }
1043
1044      if (bind & PIPE_BIND_SAMPLER_VIEW &&
1045         !(props.bufferFeatures & VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT))
1046            return false;
1047
1048      if (bind & PIPE_BIND_SHADER_IMAGE &&
1049          !(props.bufferFeatures & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT))
1050         return false;
1051   } else {
1052      /* all other targets are texture-targets */
1053      if (bind & PIPE_BIND_RENDER_TARGET &&
1054          !(props.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
1055         return false;
1056
1057      if (bind & PIPE_BIND_BLENDABLE &&
1058         !(props.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT))
1059        return false;
1060
1061      if (bind & PIPE_BIND_SAMPLER_VIEW &&
1062         !(props.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT))
1063            return false;
1064
1065      if (bind & PIPE_BIND_SAMPLER_REDUCTION_MINMAX &&
1066          !(props.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT))
1067         return false;
1068
1069      if ((bind & PIPE_BIND_SAMPLER_VIEW) || (bind & PIPE_BIND_RENDER_TARGET)) {
1070         /* if this is a 3-component texture, force gallium to give us 4 components by rejecting this one */
1071         const struct util_format_description *desc = util_format_description(format);
1072         if (desc->nr_channels == 3 &&
1073             (desc->block.bits == 24 || desc->block.bits == 48 || desc->block.bits == 96))
1074            return false;
1075      }
1076
1077      if (bind & PIPE_BIND_DEPTH_STENCIL &&
1078          !(props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
1079         return false;
1080
1081      if (bind & PIPE_BIND_SHADER_IMAGE &&
1082          !(props.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT))
1083         return false;
1084   }
1085
1086   if (util_format_is_compressed(format)) {
1087      const struct util_format_description *desc = util_format_description(format);
1088      if (desc->layout == UTIL_FORMAT_LAYOUT_BPTC &&
1089          !screen->info.feats.features.textureCompressionBC)
1090         return false;
1091   }
1092
1093   return true;
1094}
1095
1096static void
1097zink_destroy_screen(struct pipe_screen *pscreen)
1098{
1099   struct zink_screen *screen = zink_screen(pscreen);
1100
1101   if (VK_NULL_HANDLE != screen->debugUtilsCallbackHandle) {
1102      VKSCR(DestroyDebugUtilsMessengerEXT)(screen->instance, screen->debugUtilsCallbackHandle, NULL);
1103   }
1104
1105   if (!screen->info.have_KHR_imageless_framebuffer) {
1106      hash_table_foreach(&screen->framebuffer_cache, entry) {
1107         struct zink_framebuffer* fb = (struct zink_framebuffer*)entry->data;
1108         zink_destroy_framebuffer(screen, fb);
1109      }
1110      simple_mtx_destroy(&screen->framebuffer_mtx);
1111   }
1112
1113   u_transfer_helper_destroy(pscreen->transfer_helper);
1114#ifdef ENABLE_SHADER_CACHE
1115   if (screen->disk_cache) {
1116      util_queue_finish(&screen->cache_put_thread);
1117      util_queue_finish(&screen->cache_get_thread);
1118      disk_cache_wait_for_idle(screen->disk_cache);
1119      util_queue_destroy(&screen->cache_put_thread);
1120      util_queue_destroy(&screen->cache_get_thread);
1121   }
1122#endif
1123   disk_cache_destroy(screen->disk_cache);
1124   zink_bo_deinit(screen);
1125   util_live_shader_cache_deinit(&screen->shaders);
1126
1127   if (screen->sem)
1128      VKSCR(DestroySemaphore)(screen->dev, screen->sem, NULL);
1129   if (screen->prev_sem)
1130      VKSCR(DestroySemaphore)(screen->dev, screen->prev_sem, NULL);
1131
1132   if (screen->threaded)
1133      util_queue_destroy(&screen->flush_queue);
1134
1135   simple_mtx_destroy(&screen->queue_lock);
1136   VKSCR(DestroyDevice)(screen->dev, NULL);
1137   vkDestroyInstance(screen->instance, NULL);
1138   util_idalloc_mt_fini(&screen->buffer_ids);
1139
1140   if (screen->drm_fd != -1)
1141      close(screen->drm_fd);
1142
1143   slab_destroy_parent(&screen->transfer_pool);
1144   ralloc_free(screen);
1145}
1146
1147static void
1148choose_pdev(struct zink_screen *screen)
1149{
1150   uint32_t i, pdev_count;
1151   VkPhysicalDevice *pdevs;
1152   VkResult result = vkEnumeratePhysicalDevices(screen->instance, &pdev_count, NULL);
1153   if (result != VK_SUCCESS)
1154      return;
1155
1156   assert(pdev_count > 0);
1157
1158   pdevs = malloc(sizeof(*pdevs) * pdev_count);
1159   result = vkEnumeratePhysicalDevices(screen->instance, &pdev_count, pdevs);
1160   assert(result == VK_SUCCESS);
1161   assert(pdev_count > 0);
1162
1163   VkPhysicalDeviceProperties *props = &screen->info.props;
1164   for (i = 0; i < pdev_count; ++i) {
1165      vkGetPhysicalDeviceProperties(pdevs[i], props);
1166
1167#ifdef ZINK_WITH_SWRAST_VK
1168      char *use_lavapipe = getenv("ZINK_USE_LAVAPIPE");
1169      if (use_lavapipe) {
1170         if (props->deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU) {
1171            screen->pdev = pdevs[i];
1172            screen->info.device_version = props->apiVersion;
1173            break;
1174         }
1175         continue;
1176      }
1177#endif
1178      if (props->deviceType != VK_PHYSICAL_DEVICE_TYPE_CPU) {
1179         screen->pdev = pdevs[i];
1180         screen->info.device_version = props->apiVersion;
1181         break;
1182      }
1183   }
1184   free(pdevs);
1185
1186   /* runtime version is the lesser of the instance version and device version */
1187   screen->vk_version = MIN2(screen->info.device_version, screen->instance_info.loader_version);
1188
1189   /* calculate SPIR-V version based on VK version */
1190   if (screen->vk_version >= VK_MAKE_VERSION(1, 2, 0))
1191      screen->spirv_version = SPIRV_VERSION(1, 5);
1192   else if (screen->vk_version >= VK_MAKE_VERSION(1, 1, 0))
1193      screen->spirv_version = SPIRV_VERSION(1, 3);
1194   else
1195      screen->spirv_version = SPIRV_VERSION(1, 0);
1196}
1197
1198static void
1199update_queue_props(struct zink_screen *screen)
1200{
1201   uint32_t num_queues;
1202   vkGetPhysicalDeviceQueueFamilyProperties(screen->pdev, &num_queues, NULL);
1203   assert(num_queues > 0);
1204
1205   VkQueueFamilyProperties *props = malloc(sizeof(*props) * num_queues);
1206   vkGetPhysicalDeviceQueueFamilyProperties(screen->pdev, &num_queues, props);
1207
1208   for (uint32_t i = 0; i < num_queues; i++) {
1209      if (props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
1210         screen->gfx_queue = i;
1211         screen->max_queues = props[i].queueCount;
1212         screen->timestamp_valid_bits = props[i].timestampValidBits;
1213         break;
1214      }
1215   }
1216   free(props);
1217}
1218
1219static void
1220init_queue(struct zink_screen *screen)
1221{
1222   simple_mtx_init(&screen->queue_lock, mtx_plain);
1223   vkGetDeviceQueue(screen->dev, screen->gfx_queue, 0, &screen->queue);
1224   if (screen->threaded && screen->max_queues > 1)
1225      vkGetDeviceQueue(screen->dev, screen->gfx_queue, 1, &screen->thread_queue);
1226   else
1227      screen->thread_queue = screen->queue;
1228}
1229
1230static void
1231zink_flush_frontbuffer(struct pipe_screen *pscreen,
1232                       struct pipe_context *pcontext,
1233                       struct pipe_resource *pres,
1234                       unsigned level, unsigned layer,
1235                       void *winsys_drawable_handle,
1236                       struct pipe_box *sub_box)
1237{
1238   struct zink_screen *screen = zink_screen(pscreen);
1239   struct sw_winsys *winsys = screen->winsys;
1240   struct zink_resource *res = zink_resource(pres);
1241
1242   if (!winsys)
1243     return;
1244   void *map = winsys->displaytarget_map(winsys, res->dt, 0);
1245
1246   if (map) {
1247      struct pipe_transfer *transfer = NULL;
1248      void *res_map = pipe_texture_map(pcontext, pres, level, layer, PIPE_MAP_READ, 0, 0,
1249                                        u_minify(pres->width0, level),
1250                                        u_minify(pres->height0, level),
1251                                        &transfer);
1252      if (res_map) {
1253         util_copy_rect((ubyte*)map, pres->format, res->dt_stride, 0, 0,
1254                        transfer->box.width, transfer->box.height,
1255                        (const ubyte*)res_map, transfer->stride, 0, 0);
1256         pipe_texture_unmap(pcontext, transfer);
1257      }
1258      winsys->displaytarget_unmap(winsys, res->dt);
1259   }
1260
1261   winsys->displaytarget_display(winsys, res->dt, winsys_drawable_handle, sub_box);
1262}
1263
1264bool
1265zink_is_depth_format_supported(struct zink_screen *screen, VkFormat format)
1266{
1267   VkFormatProperties props;
1268   VKSCR(GetPhysicalDeviceFormatProperties)(screen->pdev, format, &props);
1269   return (props.linearTilingFeatures | props.optimalTilingFeatures) &
1270          VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT;
1271}
1272
1273static enum pipe_format
1274emulate_x8(enum pipe_format format)
1275{
1276   /* convert missing X8 variants to A8 */
1277   switch (format) {
1278   case PIPE_FORMAT_B8G8R8X8_UNORM:
1279      return PIPE_FORMAT_B8G8R8A8_UNORM;
1280
1281   case PIPE_FORMAT_B8G8R8X8_SRGB:
1282      return PIPE_FORMAT_B8G8R8A8_SRGB;
1283
1284   case PIPE_FORMAT_R8G8B8X8_SINT:
1285      return PIPE_FORMAT_R8G8B8A8_SINT;
1286   case PIPE_FORMAT_R8G8B8X8_SNORM:
1287      return PIPE_FORMAT_R8G8B8A8_SNORM;
1288   case PIPE_FORMAT_R8G8B8X8_UNORM:
1289      return PIPE_FORMAT_R8G8B8A8_UNORM;
1290
1291   case PIPE_FORMAT_R16G16B16X16_FLOAT:
1292      return PIPE_FORMAT_R16G16B16A16_FLOAT;
1293   case PIPE_FORMAT_R16G16B16X16_SINT:
1294      return PIPE_FORMAT_R16G16B16A16_SINT;
1295   case PIPE_FORMAT_R16G16B16X16_SNORM:
1296      return PIPE_FORMAT_R16G16B16A16_SNORM;
1297   case PIPE_FORMAT_R16G16B16X16_UNORM:
1298      return PIPE_FORMAT_R16G16B16A16_UNORM;
1299
1300   default:
1301      return format;
1302   }
1303}
1304
1305VkFormat
1306zink_get_format(struct zink_screen *screen, enum pipe_format format)
1307{
1308   VkFormat ret = zink_pipe_format_to_vk_format(emulate_x8(format));
1309
1310   if (format == PIPE_FORMAT_X32_S8X24_UINT)
1311      return VK_FORMAT_D32_SFLOAT_S8_UINT;
1312
1313   if (format == PIPE_FORMAT_X24S8_UINT)
1314      /* valid when using aspects to extract stencil,
1315       * fails format test because it's emulated */
1316      ret = VK_FORMAT_D24_UNORM_S8_UINT;
1317
1318   if (ret == VK_FORMAT_X8_D24_UNORM_PACK32 &&
1319       !screen->have_X8_D24_UNORM_PACK32) {
1320      assert(zink_is_depth_format_supported(screen, VK_FORMAT_D32_SFLOAT));
1321      return VK_FORMAT_D32_SFLOAT;
1322   }
1323
1324   if (ret == VK_FORMAT_D24_UNORM_S8_UINT &&
1325       !screen->have_D24_UNORM_S8_UINT) {
1326      assert(zink_is_depth_format_supported(screen,
1327                                            VK_FORMAT_D32_SFLOAT_S8_UINT));
1328      return VK_FORMAT_D32_SFLOAT_S8_UINT;
1329   }
1330
1331   if ((ret == VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT &&
1332        !screen->info.format_4444_feats.formatA4B4G4R4) ||
1333       (ret == VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT &&
1334        !screen->info.format_4444_feats.formatA4R4G4B4))
1335      return VK_FORMAT_UNDEFINED;
1336
1337   return ret;
1338}
1339
1340void
1341zink_screen_init_descriptor_funcs(struct zink_screen *screen, bool fallback)
1342{
1343   if (screen->info.have_KHR_descriptor_update_template &&
1344       !fallback &&
1345       screen->descriptor_mode == ZINK_DESCRIPTOR_MODE_LAZY) {
1346#define LAZY(FUNC) screen->FUNC = zink_##FUNC##_lazy
1347      LAZY(descriptor_program_init);
1348      LAZY(descriptor_program_deinit);
1349      LAZY(context_invalidate_descriptor_state);
1350      LAZY(batch_descriptor_init);
1351      LAZY(batch_descriptor_reset);
1352      LAZY(batch_descriptor_deinit);
1353      LAZY(descriptors_init);
1354      LAZY(descriptors_deinit);
1355      LAZY(descriptors_update);
1356#undef LAZY
1357   } else {
1358#define DEFAULT(FUNC) screen->FUNC = zink_##FUNC
1359      DEFAULT(descriptor_program_init);
1360      DEFAULT(descriptor_program_deinit);
1361      DEFAULT(context_invalidate_descriptor_state);
1362      DEFAULT(batch_descriptor_init);
1363      DEFAULT(batch_descriptor_reset);
1364      DEFAULT(batch_descriptor_deinit);
1365      DEFAULT(descriptors_init);
1366      DEFAULT(descriptors_deinit);
1367      DEFAULT(descriptors_update);
1368#undef DEFAULT
1369   }
1370}
1371
1372static bool
1373check_have_device_time(struct zink_screen *screen)
1374{
1375   uint32_t num_domains = 0;
1376   VkTimeDomainEXT domains[8]; //current max is 4
1377   VKSCR(GetPhysicalDeviceCalibrateableTimeDomainsEXT)(screen->pdev, &num_domains, NULL);
1378   assert(num_domains > 0);
1379   assert(num_domains < ARRAY_SIZE(domains));
1380
1381   VKSCR(GetPhysicalDeviceCalibrateableTimeDomainsEXT)(screen->pdev, &num_domains, domains);
1382
1383   /* VK_TIME_DOMAIN_DEVICE_EXT is used for the ctx->get_timestamp hook and is the only one we really need */
1384   for (unsigned i = 0; i < num_domains; i++) {
1385      if (domains[i] == VK_TIME_DOMAIN_DEVICE_EXT) {
1386         return true;
1387      }
1388   }
1389
1390   return false;
1391}
1392
1393static void
1394zink_error(const char *msg)
1395{
1396}
1397
1398static void
1399zink_warn(const char *msg)
1400{
1401}
1402
1403static void
1404zink_info(const char *msg)
1405{
1406}
1407
1408static void
1409zink_msg(const char *msg)
1410{
1411}
1412
1413static VKAPI_ATTR VkBool32 VKAPI_CALL
1414zink_debug_util_callback(
1415    VkDebugUtilsMessageSeverityFlagBitsEXT           messageSeverity,
1416    VkDebugUtilsMessageTypeFlagsEXT                  messageType,
1417    const VkDebugUtilsMessengerCallbackDataEXT      *pCallbackData,
1418    void                                            *pUserData)
1419{
1420   // Pick message prefix and color to use.
1421   // Only MacOS and Linux have been tested for color support
1422   if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) {
1423      zink_error(pCallbackData->pMessage);
1424   } else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) {
1425      zink_warn(pCallbackData->pMessage);
1426   } else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) {
1427      zink_info(pCallbackData->pMessage);
1428   } else
1429      zink_msg(pCallbackData->pMessage);
1430
1431   return VK_FALSE;
1432}
1433
1434static bool
1435create_debug(struct zink_screen *screen)
1436{
1437   VkDebugUtilsMessengerCreateInfoEXT vkDebugUtilsMessengerCreateInfoEXT = {
1438       VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
1439       NULL,
1440       0,  // flags
1441       VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
1442       VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT |
1443       VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
1444       VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,
1445       VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
1446       VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
1447       VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,
1448       zink_debug_util_callback,
1449       NULL
1450   };
1451
1452   VkDebugUtilsMessengerEXT vkDebugUtilsCallbackEXT = VK_NULL_HANDLE;
1453
1454   VKSCR(CreateDebugUtilsMessengerEXT)(
1455       screen->instance,
1456       &vkDebugUtilsMessengerCreateInfoEXT,
1457       NULL,
1458       &vkDebugUtilsCallbackEXT
1459   );
1460
1461   screen->debugUtilsCallbackHandle = vkDebugUtilsCallbackEXT;
1462
1463   return true;
1464}
1465
1466static bool
1467zink_internal_setup_moltenvk(struct zink_screen *screen)
1468{
1469#if defined(MVK_VERSION)
1470   if (!screen->instance_info.have_MVK_moltenvk)
1471      return true;
1472
1473   GET_PROC_ADDR_INSTANCE_LOCAL(screen->instance, GetMoltenVKConfigurationMVK);
1474   GET_PROC_ADDR_INSTANCE_LOCAL(screen->instance, SetMoltenVKConfigurationMVK);
1475   GET_PROC_ADDR_INSTANCE_LOCAL(screen->instance, GetVersionStringsMVK);
1476
1477   if (vk_GetVersionStringsMVK) {
1478      char molten_version[64] = {0};
1479      char vulkan_version[64] = {0};
1480
1481      vk_GetVersionStringsMVK(molten_version, sizeof(molten_version) - 1, vulkan_version, sizeof(vulkan_version) - 1);
1482
1483      printf("zink: MoltenVK %s Vulkan %s \n", molten_version, vulkan_version);
1484   }
1485
1486   if (vk_GetMoltenVKConfigurationMVK && vk_SetMoltenVKConfigurationMVK) {
1487      MVKConfiguration molten_config = {0};
1488      size_t molten_config_size = sizeof(molten_config);
1489
1490      VkResult res = vk_GetMoltenVKConfigurationMVK(screen->instance, &molten_config, &molten_config_size);
1491      if (res == VK_SUCCESS || res == VK_INCOMPLETE) {
1492         // Needed to allow MoltenVK to accept VkImageView swizzles.
1493         // Encountered when using VK_FORMAT_R8G8_UNORM
1494         molten_config.fullImageViewSwizzle = VK_TRUE;
1495         vk_SetMoltenVKConfigurationMVK(screen->instance, &molten_config, &molten_config_size);
1496      }
1497   }
1498#endif // MVK_VERSION
1499
1500   return true;
1501}
1502
1503static void
1504check_device_needs_mesa_wsi(struct zink_screen *screen)
1505{
1506   if (
1507       /* Raspberry Pi 4 V3DV driver */
1508       (screen->info.props.vendorID == 0x14E4 &&
1509        screen->info.props.deviceID == 42) ||
1510       /* RADV */
1511       screen->info.driver_props.driverID == VK_DRIVER_ID_MESA_RADV_KHR
1512      ) {
1513      screen->needs_mesa_wsi = true;
1514   } else if (screen->info.driver_props.driverID == VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA_KHR)
1515      screen->needs_mesa_flush_wsi = true;
1516
1517}
1518
1519static void
1520populate_format_props(struct zink_screen *screen)
1521{
1522   for (unsigned i = 0; i < PIPE_FORMAT_COUNT; i++) {
1523      VkFormat format = zink_get_format(screen, i);
1524      if (!format)
1525         continue;
1526      if (VKSCR(GetPhysicalDeviceFormatProperties2)) {
1527         VkFormatProperties2 props = {0};
1528         props.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
1529
1530         VkDrmFormatModifierPropertiesListEXT mod_props;
1531         VkDrmFormatModifierPropertiesEXT mods[128];
1532         if (screen->info.have_EXT_image_drm_format_modifier) {
1533            mod_props.sType = VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT;
1534            mod_props.pNext = NULL;
1535            mod_props.drmFormatModifierCount = ARRAY_SIZE(mods);
1536            mod_props.pDrmFormatModifierProperties = mods;
1537            props.pNext = &mod_props;
1538         }
1539         VKSCR(GetPhysicalDeviceFormatProperties2)(screen->pdev, format, &props);
1540         screen->format_props[i] = props.formatProperties;
1541         if (screen->info.have_EXT_image_drm_format_modifier && mod_props.drmFormatModifierCount) {
1542            screen->modifier_props[i].drmFormatModifierCount = mod_props.drmFormatModifierCount;
1543            screen->modifier_props[i].pDrmFormatModifierProperties = ralloc_array(screen, VkDrmFormatModifierPropertiesEXT, mod_props.drmFormatModifierCount);
1544            if (mod_props.pDrmFormatModifierProperties) {
1545               for (unsigned j = 0; j < mod_props.drmFormatModifierCount; j++)
1546                  screen->modifier_props[i].pDrmFormatModifierProperties[j] = mod_props.pDrmFormatModifierProperties[j];
1547            }
1548         }
1549      } else
1550         VKSCR(GetPhysicalDeviceFormatProperties)(screen->pdev, format, &screen->format_props[i]);
1551   }
1552}
1553
1554bool
1555zink_screen_init_semaphore(struct zink_screen *screen)
1556{
1557   VkSemaphoreCreateInfo sci = {0};
1558   VkSemaphoreTypeCreateInfo tci = {0};
1559   VkSemaphore sem;
1560   sci.pNext = &tci;
1561   sci.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
1562   tci.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO;
1563   tci.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE;
1564
1565   if (VKSCR(CreateSemaphore)(screen->dev, &sci, NULL, &sem) == VK_SUCCESS) {
1566      /* semaphore signal values can never decrease,
1567       * so we need a new semaphore anytime we overflow
1568       */
1569      if (screen->prev_sem)
1570         VKSCR(DestroySemaphore)(screen->dev, screen->prev_sem, NULL);
1571      screen->prev_sem = screen->sem;
1572      screen->sem = sem;
1573      return true;
1574   }
1575   screen->info.have_KHR_timeline_semaphore = false;
1576   return false;
1577}
1578
1579bool
1580zink_screen_timeline_wait(struct zink_screen *screen, uint32_t batch_id, uint64_t timeout)
1581{
1582   VkSemaphoreWaitInfo wi = {0};
1583
1584   if (zink_screen_check_last_finished(screen, batch_id))
1585      return true;
1586
1587   wi.sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO;
1588   wi.semaphoreCount = 1;
1589   /* handle batch_id overflow */
1590   wi.pSemaphores = batch_id > screen->curr_batch ? &screen->prev_sem : &screen->sem;
1591   uint64_t batch_id64 = batch_id;
1592   wi.pValues = &batch_id64;
1593   bool success = false;
1594   if (screen->device_lost)
1595      return true;
1596   VkResult ret = VKSCR(WaitSemaphores)(screen->dev, &wi, timeout);
1597   success = zink_screen_handle_vkresult(screen, ret);
1598
1599   if (success)
1600      zink_screen_update_last_finished(screen, batch_id);
1601
1602   return success;
1603}
1604
1605struct noop_submit_info {
1606   struct zink_screen *screen;
1607   VkFence fence;
1608};
1609
1610static void
1611noop_submit(void *data, void *gdata, int thread_index)
1612{
1613   struct noop_submit_info *n = data;
1614   VkSubmitInfo si = {0};
1615   si.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1616   simple_mtx_lock(&n->screen->queue_lock);
1617   if (n->VKSCR(QueueSubmit)(n->screen->threaded ? n->screen->thread_queue : n->screen->queue,
1618                     1, &si, n->fence) != VK_SUCCESS) {
1619      debug_printf("ZINK: vkQueueSubmit() failed\n");
1620      n->screen->device_lost = true;
1621   }
1622   simple_mtx_unlock(&n->screen->queue_lock);
1623}
1624
1625bool
1626zink_screen_batch_id_wait(struct zink_screen *screen, uint32_t batch_id, uint64_t timeout)
1627{
1628   if (zink_screen_check_last_finished(screen, batch_id))
1629      return true;
1630
1631   if (screen->info.have_KHR_timeline_semaphore)
1632      return zink_screen_timeline_wait(screen, batch_id, timeout);
1633
1634   if (!timeout)
1635      return false;
1636
1637   uint32_t new_id = 0;
1638   while (!new_id)
1639      new_id = p_atomic_inc_return(&screen->curr_batch);
1640   VkResult ret;
1641   struct noop_submit_info n;
1642   uint64_t abs_timeout = os_time_get_absolute_timeout(timeout);
1643   uint64_t remaining = PIPE_TIMEOUT_INFINITE;
1644   VkFenceCreateInfo fci = {0};
1645   struct util_queue_fence fence;
1646   util_queue_fence_init(&fence);
1647   fci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
1648
1649   if (VKSCR(CreateFence)(screen->dev, &fci, NULL, &n.fence) != VK_SUCCESS)
1650      return false;
1651
1652   n.screen = screen;
1653   if (screen->threaded) {
1654      /* must use thread dispatch for sanity */
1655      util_queue_add_job(&screen->flush_queue, &n, &fence, noop_submit, NULL, 0);
1656      util_queue_fence_wait(&fence);
1657   } else {
1658      noop_submit(&n, NULL, 0);
1659   }
1660   if (timeout != PIPE_TIMEOUT_INFINITE) {
1661      int64_t time_ns = os_time_get_nano();
1662      remaining = abs_timeout > time_ns ? abs_timeout - time_ns : 0;
1663   }
1664
1665   if (remaining)
1666      ret = VKSCR(WaitForFences)(screen->dev, 1, &n.fence, VK_TRUE, remaining);
1667   else
1668      ret = VKSCR(GetFenceStatus)(screen->dev, n.fence);
1669   VKSCR(DestroyFence)(screen->dev, n.fence, NULL);
1670   bool success = zink_screen_handle_vkresult(screen, ret);
1671
1672   if (success)
1673      zink_screen_update_last_finished(screen, new_id);
1674
1675   return success;
1676}
1677
1678static uint32_t
1679zink_get_loader_version(void)
1680{
1681
1682   uint32_t loader_version = VK_API_VERSION_1_0;
1683
1684   // Get the Loader version
1685   GET_PROC_ADDR_INSTANCE_LOCAL(NULL, EnumerateInstanceVersion);
1686   if (vk_EnumerateInstanceVersion) {
1687      uint32_t loader_version_temp = VK_API_VERSION_1_0;
1688      if (VK_SUCCESS == (*vk_EnumerateInstanceVersion)(&loader_version_temp)) {
1689         loader_version = loader_version_temp;
1690      }
1691   }
1692
1693   return loader_version;
1694}
1695
1696static void
1697zink_query_memory_info(struct pipe_screen *pscreen, struct pipe_memory_info *info)
1698{
1699   struct zink_screen *screen = zink_screen(pscreen);
1700   memset(info, 0, sizeof(struct pipe_memory_info));
1701   if (screen->info.have_EXT_memory_budget && VKSCR(GetPhysicalDeviceMemoryProperties2)) {
1702      VkPhysicalDeviceMemoryProperties2 mem = {0};
1703      mem.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2;
1704
1705      VkPhysicalDeviceMemoryBudgetPropertiesEXT budget = {0};
1706      budget.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT;
1707      mem.pNext = &budget;
1708      VKSCR(GetPhysicalDeviceMemoryProperties2)(screen->pdev, &mem);
1709
1710      for (unsigned i = 0; i < mem.memoryProperties.memoryHeapCount; i++) {
1711         if (mem.memoryProperties.memoryHeaps[i].flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) {
1712            /* VRAM */
1713            info->total_device_memory += mem.memoryProperties.memoryHeaps[i].size / 1024;
1714            info->avail_device_memory += (mem.memoryProperties.memoryHeaps[i].size - budget.heapUsage[i]) / 1024;
1715         } else {
1716            /* GART */
1717            info->total_staging_memory += mem.memoryProperties.memoryHeaps[i].size / 1024;
1718            info->avail_staging_memory += (mem.memoryProperties.memoryHeaps[i].size - budget.heapUsage[i]) / 1024;
1719         }
1720      }
1721      /* evictions not yet supported in vulkan */
1722   } else {
1723      for (unsigned i = 0; i < screen->info.mem_props.memoryHeapCount; i++) {
1724         if (screen->info.mem_props.memoryHeaps[i].flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) {
1725            /* VRAM */
1726            info->total_device_memory += screen->info.mem_props.memoryHeaps[i].size / 1024;
1727            /* free real estate! */
1728            info->avail_device_memory += info->total_device_memory;
1729         } else {
1730            /* GART */
1731            info->total_staging_memory += screen->info.mem_props.memoryHeaps[i].size / 1024;
1732            /* free real estate! */
1733            info->avail_staging_memory += info->total_staging_memory;
1734         }
1735      }
1736   }
1737}
1738
1739static void
1740zink_query_dmabuf_modifiers(struct pipe_screen *pscreen, enum pipe_format format, int max, uint64_t *modifiers, unsigned int *external_only, int *count)
1741{
1742   struct zink_screen *screen = zink_screen(pscreen);
1743   *count = screen->modifier_props[format].drmFormatModifierCount;
1744   for (int i = 0; i < MIN2(max, *count); i++)
1745      modifiers[i] = screen->modifier_props[format].pDrmFormatModifierProperties[i].drmFormatModifier;
1746}
1747
1748static bool
1749zink_is_dmabuf_modifier_supported(struct pipe_screen *pscreen, uint64_t modifier, enum pipe_format format, bool *external_only)
1750{
1751   struct zink_screen *screen = zink_screen(pscreen);
1752   for (unsigned i = 0; i < screen->modifier_props[format].drmFormatModifierCount; i++)
1753      if (screen->modifier_props[format].pDrmFormatModifierProperties[i].drmFormatModifier == modifier)
1754         return true;
1755   return false;
1756}
1757
1758static unsigned
1759zink_get_dmabuf_modifier_planes(struct pipe_screen *pscreen, uint64_t modifier, enum pipe_format format)
1760{
1761   struct zink_screen *screen = zink_screen(pscreen);
1762   for (unsigned i = 0; i < screen->modifier_props[format].drmFormatModifierCount; i++)
1763      if (screen->modifier_props[format].pDrmFormatModifierProperties[i].drmFormatModifier == modifier)
1764         return screen->modifier_props[format].pDrmFormatModifierProperties[i].drmFormatModifierPlaneCount;
1765   return 0;
1766}
1767
1768static VkDevice
1769zink_create_logical_device(struct zink_screen *screen)
1770{
1771   VkDevice dev = VK_NULL_HANDLE;
1772
1773   VkDeviceQueueCreateInfo qci = {0};
1774   float dummy = 0.0f;
1775   qci.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
1776   qci.queueFamilyIndex = screen->gfx_queue;
1777   qci.queueCount = screen->threaded && screen->max_queues > 1 ? 2 : 1;
1778   qci.pQueuePriorities = &dummy;
1779
1780   VkDeviceCreateInfo dci = {0};
1781   dci.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
1782   dci.queueCreateInfoCount = 1;
1783   dci.pQueueCreateInfos = &qci;
1784   /* extensions don't have bool members in pEnabledFeatures.
1785    * this requires us to pass the whole VkPhysicalDeviceFeatures2 struct
1786    */
1787   if (screen->info.feats.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2) {
1788      dci.pNext = &screen->info.feats;
1789   } else {
1790      dci.pEnabledFeatures = &screen->info.feats.features;
1791   }
1792
1793   dci.ppEnabledExtensionNames = screen->info.extensions;
1794   dci.enabledExtensionCount = screen->info.num_extensions;
1795
1796   vkCreateDevice(screen->pdev, &dci, NULL, &dev);
1797   return dev;
1798}
1799
1800static void
1801pre_hash_descriptor_states(struct zink_screen *screen)
1802{
1803   VkImageViewCreateInfo null_info = {.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO};
1804   VkBufferViewCreateInfo null_binfo = {.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO};
1805   screen->null_descriptor_hashes.image_view = _mesa_hash_data(&null_info, sizeof(VkImageViewCreateInfo));
1806   screen->null_descriptor_hashes.buffer_view = _mesa_hash_data(&null_binfo, sizeof(VkBufferViewCreateInfo));
1807}
1808
1809static void
1810check_base_requirements(struct zink_screen *screen)
1811{
1812   if (!screen->info.feats.features.logicOp ||
1813       !screen->info.feats.features.fillModeNonSolid ||
1814       !screen->info.feats.features.wideLines ||
1815       !screen->info.feats.features.largePoints ||
1816       !screen->info.feats.features.shaderClipDistance ||
1817       !(screen->info.feats12.scalarBlockLayout ||
1818         screen->info.have_EXT_scalar_block_layout) ||
1819       !screen->info.have_KHR_maintenance1 ||
1820       !screen->info.have_EXT_custom_border_color ||
1821       !screen->info.have_EXT_line_rasterization) {
1822      fprintf(stderr, "WARNING: Some incorrect rendering "
1823              "might occur because the selected Vulkan device (%s) doesn't support "
1824              "base Zink requirements: ", screen->info.props.deviceName);
1825#define CHECK_OR_PRINT(X) \
1826      if (!screen->info.X) \
1827         fprintf(stderr, "%s ", #X)
1828      CHECK_OR_PRINT(feats.features.logicOp);
1829      CHECK_OR_PRINT(feats.features.fillModeNonSolid);
1830      CHECK_OR_PRINT(feats.features.wideLines);
1831      CHECK_OR_PRINT(feats.features.largePoints);
1832      CHECK_OR_PRINT(feats.features.shaderClipDistance);
1833      if (!screen->info.feats12.scalarBlockLayout && !screen->info.have_EXT_scalar_block_layout)
1834         printf("scalarBlockLayout OR EXT_scalar_block_layout ");
1835      CHECK_OR_PRINT(have_KHR_maintenance1);
1836      CHECK_OR_PRINT(have_EXT_custom_border_color);
1837      CHECK_OR_PRINT(have_EXT_line_rasterization);
1838      fprintf(stderr, "\n");
1839   }
1840}
1841
1842static void
1843zink_get_sample_pixel_grid(struct pipe_screen *pscreen, unsigned sample_count,
1844                           unsigned *width, unsigned *height)
1845{
1846   struct zink_screen *screen = zink_screen(pscreen);
1847   unsigned idx = util_logbase2_ceil(MAX2(sample_count, 1));
1848   assert(idx < ARRAY_SIZE(screen->maxSampleLocationGridSize));
1849   *width = screen->maxSampleLocationGridSize[idx].width;
1850   *height = screen->maxSampleLocationGridSize[idx].height;
1851}
1852
1853static struct zink_screen *
1854zink_internal_create_screen(const struct pipe_screen_config *config)
1855{
1856   struct zink_screen *screen = rzalloc(NULL, struct zink_screen);
1857   if (!screen)
1858      return NULL;
1859
1860   util_cpu_detect();
1861   screen->threaded = util_get_cpu_caps()->nr_cpus > 1 && debug_get_bool_option("GALLIUM_THREAD", util_get_cpu_caps()->nr_cpus > 1);
1862   if (screen->threaded)
1863      util_queue_init(&screen->flush_queue, "zfq", 8, 1, UTIL_QUEUE_INIT_RESIZE_IF_FULL, NULL);
1864
1865   zink_debug = debug_get_option_zink_debug();
1866   screen->descriptor_mode = debug_get_option_zink_descriptor_mode();
1867   if (screen->descriptor_mode > ZINK_DESCRIPTOR_MODE_NOTEMPLATES) {
1868      printf("Specify exactly one descriptor mode.\n");
1869      abort();
1870   }
1871
1872   screen->instance_info.loader_version = zink_get_loader_version();
1873   screen->instance = zink_create_instance(&screen->instance_info);
1874
1875   if (!screen->instance)
1876      goto fail;
1877
1878   vk_instance_dispatch_table_load(&screen->vk.instance, &vkGetInstanceProcAddr, screen->instance);
1879   vk_physical_device_dispatch_table_load(&screen->vk.physical_device, &vkGetInstanceProcAddr, screen->instance);
1880
1881   zink_verify_instance_extensions(screen);
1882
1883   if (screen->instance_info.have_EXT_debug_utils &&
1884      (zink_debug & ZINK_DEBUG_VALIDATION) && !create_debug(screen))
1885      debug_printf("ZINK: failed to setup debug utils\n");
1886
1887   choose_pdev(screen);
1888   if (screen->pdev == VK_NULL_HANDLE)
1889      goto fail;
1890
1891   update_queue_props(screen);
1892
1893   screen->have_X8_D24_UNORM_PACK32 = zink_is_depth_format_supported(screen,
1894                                              VK_FORMAT_X8_D24_UNORM_PACK32);
1895   screen->have_D24_UNORM_S8_UINT = zink_is_depth_format_supported(screen,
1896                                              VK_FORMAT_D24_UNORM_S8_UINT);
1897
1898   if (!zink_get_physical_device_info(screen)) {
1899      debug_printf("ZINK: failed to detect features\n");
1900      goto fail;
1901   }
1902
1903   /* Some Vulkan implementations have special requirements for WSI
1904    * allocations.
1905    */
1906   check_device_needs_mesa_wsi(screen);
1907
1908   zink_internal_setup_moltenvk(screen);
1909
1910   screen->dev = zink_create_logical_device(screen);
1911   if (!screen->dev)
1912      goto fail;
1913
1914   init_queue(screen);
1915   if (screen->info.driver_props.driverID == VK_DRIVER_ID_MESA_RADV ||
1916       screen->info.driver_props.driverID == VK_DRIVER_ID_AMD_OPEN_SOURCE ||
1917       screen->info.driver_props.driverID == VK_DRIVER_ID_AMD_PROPRIETARY)
1918      /* this has bad perf on AMD */
1919      screen->info.have_KHR_push_descriptor = false;
1920
1921   vk_device_dispatch_table_load(&screen->vk.device, &vkGetDeviceProcAddr, screen->dev);
1922
1923   zink_verify_device_extensions(screen);
1924
1925   if (screen->info.have_EXT_calibrated_timestamps && !check_have_device_time(screen))
1926      goto fail;
1927
1928   screen->have_triangle_fans = true;
1929#if defined(VK_EXTX_PORTABILITY_SUBSET_EXTENSION_NAME)
1930   if (screen->info.have_EXTX_portability_subset) {
1931      screen->have_triangle_fans = (VK_TRUE == screen->info.portability_subset_extx_feats.triangleFans);
1932   }
1933#endif // VK_EXTX_PORTABILITY_SUBSET_EXTENSION_NAME
1934
1935   check_base_requirements(screen);
1936   util_live_shader_cache_init(&screen->shaders, zink_create_gfx_shader_state, zink_delete_shader_state);
1937
1938   screen->base.get_name = zink_get_name;
1939   screen->base.get_vendor = zink_get_vendor;
1940   screen->base.get_device_vendor = zink_get_device_vendor;
1941   screen->base.get_compute_param = zink_get_compute_param;
1942   screen->base.query_memory_info = zink_query_memory_info;
1943   screen->base.get_param = zink_get_param;
1944   screen->base.get_paramf = zink_get_paramf;
1945   screen->base.get_shader_param = zink_get_shader_param;
1946   screen->base.get_compiler_options = zink_get_compiler_options;
1947   screen->base.get_sample_pixel_grid = zink_get_sample_pixel_grid;
1948   screen->base.is_format_supported = zink_is_format_supported;
1949   if (screen->info.have_EXT_image_drm_format_modifier && screen->info.have_EXT_external_memory_dma_buf) {
1950      screen->base.query_dmabuf_modifiers = zink_query_dmabuf_modifiers;
1951      screen->base.is_dmabuf_modifier_supported = zink_is_dmabuf_modifier_supported;
1952      screen->base.get_dmabuf_modifier_planes = zink_get_dmabuf_modifier_planes;
1953   }
1954   screen->base.context_create = zink_context_create;
1955   screen->base.flush_frontbuffer = zink_flush_frontbuffer;
1956   screen->base.destroy = zink_destroy_screen;
1957   screen->base.finalize_nir = zink_shader_finalize;
1958
1959   if (screen->info.have_EXT_sample_locations) {
1960      VkMultisamplePropertiesEXT prop;
1961      prop.sType = VK_STRUCTURE_TYPE_MULTISAMPLE_PROPERTIES_EXT;
1962      prop.pNext = NULL;
1963      for (unsigned i = 0; i < ARRAY_SIZE(screen->maxSampleLocationGridSize); i++) {
1964         if (screen->info.sample_locations_props.sampleLocationSampleCounts & (1 << i)) {
1965            VKSCR(GetPhysicalDeviceMultisamplePropertiesEXT)(screen->pdev, 1 << i, &prop);
1966            screen->maxSampleLocationGridSize[i] = prop.maxSampleLocationGridSize;
1967         }
1968      }
1969   }
1970
1971   if (!zink_screen_resource_init(&screen->base))
1972      goto fail;
1973   zink_bo_init(screen);
1974   zink_screen_fence_init(&screen->base);
1975
1976   zink_screen_init_compiler(screen);
1977   disk_cache_init(screen);
1978   populate_format_props(screen);
1979   pre_hash_descriptor_states(screen);
1980
1981   slab_create_parent(&screen->transfer_pool, sizeof(struct zink_transfer), 16);
1982
1983#if WITH_XMLCONFIG
1984   if (config) {
1985      driParseConfigFiles(config->options, config->options_info, 0, "zink",
1986                          NULL, NULL, NULL, 0, NULL, 0);
1987      screen->driconf.dual_color_blend_by_location = driQueryOptionb(config->options, "dual_color_blend_by_location");
1988      //screen->driconf.inline_uniforms = driQueryOptionb(config->options, "radeonsi_inline_uniforms");
1989   }
1990#endif
1991   screen->driconf.inline_uniforms = debug_get_bool_option("ZINK_INLINE_UNIFORMS", false);
1992
1993   screen->total_video_mem = get_video_mem(screen);
1994   screen->clamp_video_mem = screen->total_video_mem * 0.8;
1995   if (!os_get_total_physical_memory(&screen->total_mem))
1996      goto fail;
1997
1998   if (debug_get_bool_option("ZINK_NO_TIMELINES", false))
1999      screen->info.have_KHR_timeline_semaphore = false;
2000   if (screen->info.have_KHR_timeline_semaphore)
2001      zink_screen_init_semaphore(screen);
2002
2003   memset(&screen->heap_map, UINT8_MAX, sizeof(screen->heap_map));
2004   for (enum zink_heap i = 0; i < ZINK_HEAP_MAX; i++) {
2005      for (unsigned j = 0; j < screen->info.mem_props.memoryTypeCount; j++) {
2006         VkMemoryPropertyFlags domains = vk_domain_from_heap(i);
2007         if ((screen->info.mem_props.memoryTypes[j].propertyFlags & domains) == domains) {
2008            assert(screen->heap_map[i] == UINT8_MAX);
2009            screen->heap_map[i] = j;
2010            break;
2011         }
2012      }
2013
2014      /* not found: use compatible heap */
2015      if (screen->heap_map[i] == UINT8_MAX) {
2016         /* only cached mem has a failure case for now */
2017         assert(i == ZINK_HEAP_HOST_VISIBLE_CACHED || i == ZINK_HEAP_DEVICE_LOCAL_LAZY);
2018         if (i == ZINK_HEAP_HOST_VISIBLE_CACHED)
2019            screen->heap_map[i] = screen->heap_map[ZINK_HEAP_HOST_VISIBLE_COHERENT];
2020         else
2021            screen->heap_map[i] = screen->heap_map[ZINK_HEAP_DEVICE_LOCAL];
2022      }
2023   }
2024   {
2025      unsigned vis_vram = screen->heap_map[ZINK_HEAP_DEVICE_LOCAL_VISIBLE];
2026      unsigned vram = screen->heap_map[ZINK_HEAP_DEVICE_LOCAL];
2027      /* determine if vis vram is roughly equal to total vram */
2028      if (screen->info.mem_props.memoryHeaps[screen->info.mem_props.memoryTypes[vis_vram].heapIndex].size >
2029          screen->info.mem_props.memoryHeaps[screen->info.mem_props.memoryTypes[vram].heapIndex].size * 0.9)
2030         screen->resizable_bar = true;
2031   }
2032
2033   if (!screen->info.have_KHR_imageless_framebuffer) {
2034      simple_mtx_init(&screen->framebuffer_mtx, mtx_plain);
2035      _mesa_hash_table_init(&screen->framebuffer_cache, screen, hash_framebuffer_state, equals_framebuffer_state);
2036   }
2037
2038   zink_screen_init_descriptor_funcs(screen, false);
2039   util_idalloc_mt_init_tc(&screen->buffer_ids);
2040
2041   return screen;
2042
2043fail:
2044   ralloc_free(screen);
2045   return NULL;
2046}
2047
2048struct pipe_screen *
2049zink_create_screen(struct sw_winsys *winsys)
2050{
2051   struct zink_screen *ret = zink_internal_create_screen(NULL);
2052   if (ret) {
2053      ret->winsys = winsys;
2054      ret->drm_fd = -1;
2055   }
2056
2057   return &ret->base;
2058}
2059
2060struct pipe_screen *
2061zink_drm_create_screen(int fd, const struct pipe_screen_config *config)
2062{
2063   struct zink_screen *ret = zink_internal_create_screen(config);
2064
2065   if (ret)
2066      ret->drm_fd = os_dupfd_cloexec(fd);
2067   if (ret && !ret->info.have_KHR_external_memory_fd) {
2068      debug_printf("ZINK: KHR_external_memory_fd required!\n");
2069      zink_destroy_screen(&ret->base);
2070      return NULL;
2071   }
2072
2073   return &ret->base;
2074}
2075
2076void zink_stub_function_not_loaded()
2077{
2078   /* this will be used by the zink_verify_*_extensions() functions on a
2079    * release build
2080    */
2081   mesa_loge("ZINK: a Vulkan function was called without being loaded");
2082   abort();
2083}
2084