• 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_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 
66 static const struct debug_named_value
67 zink_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 
75 DEBUG_GET_ONCE_FLAGS_OPTION(zink_debug, "ZINK_DEBUG", zink_debug_options, 0)
76 
77 uint32_t
78 zink_debug;
79 
80 
81 static const struct debug_named_value
82 zink_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 
90 DEBUG_GET_ONCE_FLAGS_OPTION(zink_descriptor_mode, "ZINK_DESCRIPTORS", zink_descriptor_options, ZINK_DESCRIPTOR_MODE_AUTO)
91 
92 static const char *
zink_get_vendor(struct pipe_screen * pscreen)93 zink_get_vendor(struct pipe_screen *pscreen)
94 {
95    return "Collabora Ltd";
96 }
97 
98 static const char *
zink_get_device_vendor(struct pipe_screen * pscreen)99 zink_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 
107 static const char *
zink_get_name(struct pipe_screen * pscreen)108 zink_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 
116 static uint32_t
hash_framebuffer_state(const void * key)117 hash_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 
123 static bool
equals_framebuffer_state(const void * a,const void * b)124 equals_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 
130 static VkDeviceSize
get_video_mem(struct zink_screen * screen)131 get_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 
142 static void
disk_cache_init(struct zink_screen * screen)143 disk_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 
158 static void
cache_put_job(void * data,void * gdata,int thread_index)159 cache_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 
180 void
zink_screen_update_pipeline_cache(struct zink_screen * screen,struct zink_program * pg)181 zink_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 
190 static void
cache_get_job(void * data,void * gdata,int thread_index)191 cache_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 
211 void
zink_screen_get_pipeline_cache(struct zink_screen * screen,struct zink_program * pg)212 zink_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 
221 static int
zink_get_compute_param(struct pipe_screen * pscreen,enum pipe_shader_ir ir_type,enum pipe_compute_cap param,void * ret)222 zink_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 
282 static uint32_t
get_smallest_buffer_heap(struct zink_screen * screen)283 get_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 
299 static int
zink_get_param(struct pipe_screen * pscreen,enum pipe_cap param)300 zink_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->vk_version >= VK_MAKE_VERSION(1,2,0) && 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 && screen->info.have_EXT_external_memory_dma_buf && screen->info.have_EXT_queue_family_foreign;
675 
676    case PIPE_CAP_DEPTH_BOUNDS_TEST:
677       return screen->info.feats.features.depthBounds;
678 
679    case PIPE_CAP_POST_DEPTH_COVERAGE:
680       return screen->info.have_EXT_post_depth_coverage;
681 
682    case PIPE_CAP_STRING_MARKER:
683       return screen->instance_info.have_EXT_debug_utils;
684 
685    default:
686       return u_pipe_screen_get_param_defaults(pscreen, param);
687    }
688 }
689 
690 static float
zink_get_paramf(struct pipe_screen * pscreen,enum pipe_capf param)691 zink_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)
692 {
693    struct zink_screen *screen = zink_screen(pscreen);
694 
695    switch (param) {
696    case PIPE_CAPF_MAX_LINE_WIDTH:
697    case PIPE_CAPF_MAX_LINE_WIDTH_AA:
698       if (!screen->info.feats.features.wideLines)
699          return 1.0f;
700       return screen->info.props.limits.lineWidthRange[1];
701 
702    case PIPE_CAPF_MAX_POINT_WIDTH:
703    case PIPE_CAPF_MAX_POINT_WIDTH_AA:
704       if (!screen->info.feats.features.largePoints)
705          return 1.0f;
706       return screen->info.props.limits.pointSizeRange[1];
707 
708    case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
709       if (!screen->info.feats.features.samplerAnisotropy)
710          return 1.0f;
711       return screen->info.props.limits.maxSamplerAnisotropy;
712 
713    case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
714       return screen->info.props.limits.maxSamplerLodBias;
715 
716    case PIPE_CAPF_MIN_CONSERVATIVE_RASTER_DILATE:
717    case PIPE_CAPF_MAX_CONSERVATIVE_RASTER_DILATE:
718    case PIPE_CAPF_CONSERVATIVE_RASTER_DILATE_GRANULARITY:
719       return 0.0f; /* not implemented */
720    }
721 
722    /* should only get here on unhandled cases */
723    return 0.0f;
724 }
725 
726 static int
zink_get_shader_param(struct pipe_screen * pscreen,enum pipe_shader_type shader,enum pipe_shader_cap param)727 zink_get_shader_param(struct pipe_screen *pscreen,
728                        enum pipe_shader_type shader,
729                        enum pipe_shader_cap param)
730 {
731    struct zink_screen *screen = zink_screen(pscreen);
732 
733    switch (param) {
734    case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
735       switch (shader) {
736       case PIPE_SHADER_FRAGMENT:
737       case PIPE_SHADER_VERTEX:
738          return INT_MAX;
739       case PIPE_SHADER_TESS_CTRL:
740       case PIPE_SHADER_TESS_EVAL:
741          if (screen->info.feats.features.tessellationShader &&
742              screen->info.have_KHR_maintenance2)
743             return INT_MAX;
744          break;
745 
746       case PIPE_SHADER_GEOMETRY:
747          if (screen->info.feats.features.geometryShader)
748             return INT_MAX;
749          break;
750 
751       case PIPE_SHADER_COMPUTE:
752          return INT_MAX;
753       default:
754          break;
755       }
756       return 0;
757    case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
758    case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
759    case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
760    case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
761       return INT_MAX;
762 
763    case PIPE_SHADER_CAP_MAX_INPUTS: {
764       uint32_t max = 0;
765       switch (shader) {
766       case PIPE_SHADER_VERTEX:
767          max = MIN2(screen->info.props.limits.maxVertexInputAttributes, PIPE_MAX_ATTRIBS);
768          break;
769       case PIPE_SHADER_TESS_CTRL:
770          max = screen->info.props.limits.maxTessellationControlPerVertexInputComponents / 4;
771          break;
772       case PIPE_SHADER_TESS_EVAL:
773          max = screen->info.props.limits.maxTessellationEvaluationInputComponents / 4;
774          break;
775       case PIPE_SHADER_GEOMETRY:
776          max = screen->info.props.limits.maxGeometryInputComponents;
777          break;
778       case PIPE_SHADER_FRAGMENT:
779          /* intel drivers report fewer components, but it's a value that's compatible
780           * with what we need for GL, so we can still force a conformant value here
781           */
782          if (screen->info.driver_props.driverID == VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA_KHR ||
783              screen->info.driver_props.driverID == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR)
784             return 32;
785          max = screen->info.props.limits.maxFragmentInputComponents / 4;
786          break;
787       default:
788          return 0; /* unsupported stage */
789       }
790       switch (shader) {
791       case PIPE_SHADER_VERTEX:
792       case PIPE_SHADER_TESS_EVAL:
793       case PIPE_SHADER_GEOMETRY:
794          /* last vertex stage must support streamout, and this is capped in glsl compiler */
795          return MIN2(max, MAX_VARYING);
796       default: break;
797       }
798       return MIN2(max, 64); // prevent overflowing struct shader_info::inputs_read
799    }
800 
801    case PIPE_SHADER_CAP_MAX_OUTPUTS: {
802       uint32_t max = 0;
803       switch (shader) {
804       case PIPE_SHADER_VERTEX:
805          max = screen->info.props.limits.maxVertexOutputComponents / 4;
806          break;
807       case PIPE_SHADER_TESS_CTRL:
808          max = screen->info.props.limits.maxTessellationControlPerVertexOutputComponents / 4;
809          break;
810       case PIPE_SHADER_TESS_EVAL:
811          max = screen->info.props.limits.maxTessellationEvaluationOutputComponents / 4;
812          break;
813       case PIPE_SHADER_GEOMETRY:
814          max = screen->info.props.limits.maxGeometryOutputComponents / 4;
815          break;
816       case PIPE_SHADER_FRAGMENT:
817          max = screen->info.props.limits.maxColorAttachments;
818          break;
819       default:
820          return 0; /* unsupported stage */
821       }
822       return MIN2(max, 64); // prevent overflowing struct shader_info::outputs_read/written
823    }
824 
825    case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
826       /* At least 16384 is guaranteed by VK spec */
827       assert(screen->info.props.limits.maxUniformBufferRange >= 16384);
828       /* but Gallium can't handle values that are too big */
829       return MIN3(get_smallest_buffer_heap(screen),
830                   screen->info.props.limits.maxUniformBufferRange, 1 << 31);
831 
832    case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
833       return  MIN2(screen->info.props.limits.maxPerStageDescriptorUniformBuffers,
834                    PIPE_MAX_CONSTANT_BUFFERS);
835 
836    case PIPE_SHADER_CAP_MAX_TEMPS:
837       return INT_MAX;
838 
839    case PIPE_SHADER_CAP_INTEGERS:
840       return 1;
841 
842    case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
843       return 1;
844 
845    case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
846    case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
847    case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
848    case PIPE_SHADER_CAP_SUBROUTINES:
849    case PIPE_SHADER_CAP_INT64_ATOMICS:
850    case PIPE_SHADER_CAP_GLSL_16BIT_CONSTS:
851       return 0; /* not implemented */
852 
853    case PIPE_SHADER_CAP_FP16_CONST_BUFFERS:
854       return screen->info.feats11.uniformAndStorageBuffer16BitAccess ||
855              (screen->info.have_KHR_16bit_storage && screen->info.storage_16bit_feats.uniformAndStorageBuffer16BitAccess);
856    case PIPE_SHADER_CAP_FP16_DERIVATIVES:
857       return 0; //spirv requires 32bit derivative srcs and dests
858    case PIPE_SHADER_CAP_FP16:
859       return screen->info.feats12.shaderFloat16 ||
860              (screen->info.have_KHR_shader_float16_int8 &&
861               screen->info.shader_float16_int8_feats.shaderFloat16);
862 
863    case PIPE_SHADER_CAP_INT16:
864       return screen->info.feats.features.shaderInt16;
865 
866    case PIPE_SHADER_CAP_PREFERRED_IR:
867       return PIPE_SHADER_IR_NIR;
868 
869    case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
870       return 0; /* not implemented */
871 
872    case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
873    case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
874       return MIN2(MIN2(screen->info.props.limits.maxPerStageDescriptorSamplers,
875                        screen->info.props.limits.maxPerStageDescriptorSampledImages),
876                   PIPE_MAX_SAMPLERS);
877 
878    case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
879    case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
880    case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
881       return 0; /* not implemented */
882 
883    case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
884       return 0; /* no idea */
885 
886    case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT:
887       return 0;
888 
889    case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
890       switch (shader) {
891       case PIPE_SHADER_VERTEX:
892       case PIPE_SHADER_TESS_CTRL:
893       case PIPE_SHADER_TESS_EVAL:
894       case PIPE_SHADER_GEOMETRY:
895          if (!screen->info.feats.features.vertexPipelineStoresAndAtomics)
896             return 0;
897          break;
898 
899       case PIPE_SHADER_FRAGMENT:
900          if (!screen->info.feats.features.fragmentStoresAndAtomics)
901             return 0;
902          break;
903 
904       default:
905          break;
906       }
907 
908       /* TODO: this limitation is dumb, and will need some fixes in mesa */
909       return MIN2(screen->info.props.limits.maxPerStageDescriptorStorageBuffers, PIPE_MAX_SHADER_BUFFERS);
910 
911    case PIPE_SHADER_CAP_SUPPORTED_IRS:
912       return (1 << PIPE_SHADER_IR_NIR) | (1 << PIPE_SHADER_IR_TGSI);
913 
914    case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
915       if (screen->info.feats.features.shaderStorageImageExtendedFormats &&
916           screen->info.feats.features.shaderStorageImageWriteWithoutFormat)
917          return MIN2(screen->info.props.limits.maxPerStageDescriptorStorageImages,
918                      PIPE_MAX_SHADER_IMAGES);
919       return 0;
920 
921    case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD:
922    case PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS:
923       return 0; /* unsure */
924 
925    case PIPE_SHADER_CAP_TGSI_LDEXP_SUPPORTED:
926    case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:
927    case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:
928    case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
929       return 0; /* not implemented */
930    }
931 
932    /* should only get here on unhandled cases */
933    return 0;
934 }
935 
936 static VkSampleCountFlagBits
vk_sample_count_flags(uint32_t sample_count)937 vk_sample_count_flags(uint32_t sample_count)
938 {
939    switch (sample_count) {
940    case 1: return VK_SAMPLE_COUNT_1_BIT;
941    case 2: return VK_SAMPLE_COUNT_2_BIT;
942    case 4: return VK_SAMPLE_COUNT_4_BIT;
943    case 8: return VK_SAMPLE_COUNT_8_BIT;
944    case 16: return VK_SAMPLE_COUNT_16_BIT;
945    case 32: return VK_SAMPLE_COUNT_32_BIT;
946    case 64: return VK_SAMPLE_COUNT_64_BIT;
947    default:
948       return 0;
949    }
950 }
951 
952 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)953 zink_is_format_supported(struct pipe_screen *pscreen,
954                          enum pipe_format format,
955                          enum pipe_texture_target target,
956                          unsigned sample_count,
957                          unsigned storage_sample_count,
958                          unsigned bind)
959 {
960    struct zink_screen *screen = zink_screen(pscreen);
961 
962    if (storage_sample_count && !screen->info.feats.features.shaderStorageImageMultisample && bind & PIPE_BIND_SHADER_IMAGE)
963       return false;
964 
965    if (format == PIPE_FORMAT_NONE)
966       return screen->info.props.limits.framebufferNoAttachmentsSampleCounts &
967              vk_sample_count_flags(sample_count);
968 
969    if (bind & PIPE_BIND_INDEX_BUFFER) {
970       if (format == PIPE_FORMAT_R8_UINT &&
971           !screen->info.have_EXT_index_type_uint8)
972          return false;
973       if (format != PIPE_FORMAT_R8_UINT &&
974           format != PIPE_FORMAT_R16_UINT &&
975           format != PIPE_FORMAT_R32_UINT)
976          return false;
977    }
978 
979    VkFormat vkformat = zink_get_format(screen, format);
980    if (vkformat == VK_FORMAT_UNDEFINED)
981       return false;
982 
983    if (sample_count >= 1) {
984       VkSampleCountFlagBits sample_mask = vk_sample_count_flags(sample_count);
985       if (!sample_mask)
986          return false;
987       const struct util_format_description *desc = util_format_description(format);
988       if (util_format_is_depth_or_stencil(format)) {
989          if (util_format_has_depth(desc)) {
990             if (bind & PIPE_BIND_DEPTH_STENCIL &&
991                 (screen->info.props.limits.framebufferDepthSampleCounts & sample_mask) != sample_mask)
992                return false;
993             if (bind & PIPE_BIND_SAMPLER_VIEW &&
994                 (screen->info.props.limits.sampledImageDepthSampleCounts & sample_mask) != sample_mask)
995                return false;
996          }
997          if (util_format_has_stencil(desc)) {
998             if (bind & PIPE_BIND_DEPTH_STENCIL &&
999                 (screen->info.props.limits.framebufferStencilSampleCounts & sample_mask) != sample_mask)
1000                return false;
1001             if (bind & PIPE_BIND_SAMPLER_VIEW &&
1002                 (screen->info.props.limits.sampledImageStencilSampleCounts & sample_mask) != sample_mask)
1003                return false;
1004          }
1005       } else if (util_format_is_pure_integer(format)) {
1006          if (bind & PIPE_BIND_RENDER_TARGET &&
1007              !(screen->info.props.limits.framebufferColorSampleCounts & sample_mask))
1008             return false;
1009          if (bind & PIPE_BIND_SAMPLER_VIEW &&
1010              !(screen->info.props.limits.sampledImageIntegerSampleCounts & sample_mask))
1011             return false;
1012       } else {
1013          if (bind & PIPE_BIND_RENDER_TARGET &&
1014              !(screen->info.props.limits.framebufferColorSampleCounts & sample_mask))
1015             return false;
1016          if (bind & PIPE_BIND_SAMPLER_VIEW &&
1017              !(screen->info.props.limits.sampledImageColorSampleCounts & sample_mask))
1018             return false;
1019       }
1020       if (bind & PIPE_BIND_SHADER_IMAGE) {
1021           if (!(screen->info.props.limits.storageImageSampleCounts & sample_mask))
1022              return false;
1023       }
1024    }
1025 
1026    VkFormatProperties props = screen->format_props[format];
1027 
1028    if (target == PIPE_BUFFER) {
1029       if (bind & PIPE_BIND_VERTEX_BUFFER) {
1030          if (!(props.bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)) {
1031             enum pipe_format new_format = zink_decompose_vertex_format(format);
1032             if (!new_format)
1033                return false;
1034             if (!(screen->format_props[new_format].bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))
1035                return false;
1036          }
1037       }
1038 
1039       if (bind & PIPE_BIND_SAMPLER_VIEW &&
1040          !(props.bufferFeatures & VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT))
1041             return false;
1042 
1043       if (bind & PIPE_BIND_SHADER_IMAGE &&
1044           !(props.bufferFeatures & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT))
1045          return false;
1046    } else {
1047       /* all other targets are texture-targets */
1048       if (bind & PIPE_BIND_RENDER_TARGET &&
1049           !(props.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
1050          return false;
1051 
1052       if (bind & PIPE_BIND_BLENDABLE &&
1053          !(props.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT))
1054         return false;
1055 
1056       if (bind & PIPE_BIND_SAMPLER_VIEW &&
1057          !(props.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT))
1058             return false;
1059 
1060       if (bind & PIPE_BIND_SAMPLER_REDUCTION_MINMAX &&
1061           !(props.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT))
1062          return false;
1063 
1064       if ((bind & PIPE_BIND_SAMPLER_VIEW) || (bind & PIPE_BIND_RENDER_TARGET)) {
1065          /* if this is a 3-component texture, force gallium to give us 4 components by rejecting this one */
1066          const struct util_format_description *desc = util_format_description(format);
1067          if (desc->nr_channels == 3 &&
1068              (desc->block.bits == 24 || desc->block.bits == 48 || desc->block.bits == 96))
1069             return false;
1070       }
1071 
1072       if (bind & PIPE_BIND_DEPTH_STENCIL &&
1073           !(props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
1074          return false;
1075 
1076       if (bind & PIPE_BIND_SHADER_IMAGE &&
1077           !(props.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT))
1078          return false;
1079    }
1080 
1081    if (util_format_is_compressed(format)) {
1082       const struct util_format_description *desc = util_format_description(format);
1083       if (desc->layout == UTIL_FORMAT_LAYOUT_BPTC &&
1084           !screen->info.feats.features.textureCompressionBC)
1085          return false;
1086    }
1087 
1088    return true;
1089 }
1090 
1091 static void
zink_destroy_screen(struct pipe_screen * pscreen)1092 zink_destroy_screen(struct pipe_screen *pscreen)
1093 {
1094    struct zink_screen *screen = zink_screen(pscreen);
1095 
1096    if (VK_NULL_HANDLE != screen->debugUtilsCallbackHandle) {
1097       VKSCR(DestroyDebugUtilsMessengerEXT)(screen->instance, screen->debugUtilsCallbackHandle, NULL);
1098    }
1099 
1100    if (!screen->info.have_KHR_imageless_framebuffer) {
1101       hash_table_foreach(&screen->framebuffer_cache, entry) {
1102          struct zink_framebuffer* fb = (struct zink_framebuffer*)entry->data;
1103          zink_destroy_framebuffer(screen, fb);
1104       }
1105       simple_mtx_destroy(&screen->framebuffer_mtx);
1106    }
1107 
1108    u_transfer_helper_destroy(pscreen->transfer_helper);
1109 #ifdef ENABLE_SHADER_CACHE
1110    if (screen->disk_cache) {
1111       util_queue_finish(&screen->cache_put_thread);
1112       util_queue_finish(&screen->cache_get_thread);
1113       disk_cache_wait_for_idle(screen->disk_cache);
1114       util_queue_destroy(&screen->cache_put_thread);
1115       util_queue_destroy(&screen->cache_get_thread);
1116    }
1117 #endif
1118    disk_cache_destroy(screen->disk_cache);
1119    zink_bo_deinit(screen);
1120    util_live_shader_cache_deinit(&screen->shaders);
1121 
1122    if (screen->sem)
1123       VKSCR(DestroySemaphore)(screen->dev, screen->sem, NULL);
1124    if (screen->prev_sem)
1125       VKSCR(DestroySemaphore)(screen->dev, screen->prev_sem, NULL);
1126 
1127    if (screen->threaded)
1128       util_queue_destroy(&screen->flush_queue);
1129 
1130    simple_mtx_destroy(&screen->queue_lock);
1131    VKSCR(DestroyDevice)(screen->dev, NULL);
1132    vkDestroyInstance(screen->instance, NULL);
1133    util_idalloc_mt_fini(&screen->buffer_ids);
1134 
1135    if (screen->drm_fd != -1)
1136       close(screen->drm_fd);
1137 
1138    slab_destroy_parent(&screen->transfer_pool);
1139    ralloc_free(screen);
1140 }
1141 
1142 static void
choose_pdev(struct zink_screen * screen)1143 choose_pdev(struct zink_screen *screen)
1144 {
1145    uint32_t i, pdev_count;
1146    VkPhysicalDevice *pdevs;
1147    VkResult result = vkEnumeratePhysicalDevices(screen->instance, &pdev_count, NULL);
1148    if (result != VK_SUCCESS)
1149       return;
1150 
1151    assert(pdev_count > 0);
1152 
1153    pdevs = malloc(sizeof(*pdevs) * pdev_count);
1154    result = vkEnumeratePhysicalDevices(screen->instance, &pdev_count, pdevs);
1155    assert(result == VK_SUCCESS);
1156    assert(pdev_count > 0);
1157 
1158    VkPhysicalDeviceProperties *props = &screen->info.props;
1159    for (i = 0; i < pdev_count; ++i) {
1160       vkGetPhysicalDeviceProperties(pdevs[i], props);
1161 
1162 #ifdef ZINK_WITH_SWRAST_VK
1163       char *use_lavapipe = getenv("ZINK_USE_LAVAPIPE");
1164       if (use_lavapipe) {
1165          if (props->deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU) {
1166             screen->pdev = pdevs[i];
1167             screen->info.device_version = props->apiVersion;
1168             break;
1169          }
1170          continue;
1171       }
1172 #endif
1173       if (props->deviceType != VK_PHYSICAL_DEVICE_TYPE_CPU) {
1174          screen->pdev = pdevs[i];
1175          screen->info.device_version = props->apiVersion;
1176          break;
1177       }
1178    }
1179    free(pdevs);
1180 
1181    /* runtime version is the lesser of the instance version and device version */
1182    screen->vk_version = MIN2(screen->info.device_version, screen->instance_info.loader_version);
1183 
1184    /* calculate SPIR-V version based on VK version */
1185    if (screen->vk_version >= VK_MAKE_VERSION(1, 2, 0))
1186       screen->spirv_version = SPIRV_VERSION(1, 5);
1187    else if (screen->vk_version >= VK_MAKE_VERSION(1, 1, 0))
1188       screen->spirv_version = SPIRV_VERSION(1, 3);
1189    else
1190       screen->spirv_version = SPIRV_VERSION(1, 0);
1191 }
1192 
1193 static void
update_queue_props(struct zink_screen * screen)1194 update_queue_props(struct zink_screen *screen)
1195 {
1196    uint32_t num_queues;
1197    vkGetPhysicalDeviceQueueFamilyProperties(screen->pdev, &num_queues, NULL);
1198    assert(num_queues > 0);
1199 
1200    VkQueueFamilyProperties *props = malloc(sizeof(*props) * num_queues);
1201    vkGetPhysicalDeviceQueueFamilyProperties(screen->pdev, &num_queues, props);
1202 
1203    for (uint32_t i = 0; i < num_queues; i++) {
1204       if (props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
1205          screen->gfx_queue = i;
1206          screen->max_queues = props[i].queueCount;
1207          screen->timestamp_valid_bits = props[i].timestampValidBits;
1208          break;
1209       }
1210    }
1211    free(props);
1212 }
1213 
1214 static void
init_queue(struct zink_screen * screen)1215 init_queue(struct zink_screen *screen)
1216 {
1217    simple_mtx_init(&screen->queue_lock, mtx_plain);
1218    vkGetDeviceQueue(screen->dev, screen->gfx_queue, 0, &screen->queue);
1219    if (screen->threaded && screen->max_queues > 1)
1220       vkGetDeviceQueue(screen->dev, screen->gfx_queue, 1, &screen->thread_queue);
1221    else
1222       screen->thread_queue = screen->queue;
1223 }
1224 
1225 static void
zink_flush_frontbuffer(struct pipe_screen * pscreen,struct pipe_context * pcontext,struct pipe_resource * pres,unsigned level,unsigned layer,void * winsys_drawable_handle,struct pipe_box * sub_box)1226 zink_flush_frontbuffer(struct pipe_screen *pscreen,
1227                        struct pipe_context *pcontext,
1228                        struct pipe_resource *pres,
1229                        unsigned level, unsigned layer,
1230                        void *winsys_drawable_handle,
1231                        struct pipe_box *sub_box)
1232 {
1233    struct zink_screen *screen = zink_screen(pscreen);
1234    struct sw_winsys *winsys = screen->winsys;
1235    struct zink_resource *res = zink_resource(pres);
1236 
1237    if (!winsys)
1238      return;
1239    void *map = winsys->displaytarget_map(winsys, res->dt, 0);
1240 
1241    if (map) {
1242       struct pipe_transfer *transfer = NULL;
1243       void *res_map = pipe_texture_map(pcontext, pres, level, layer, PIPE_MAP_READ, 0, 0,
1244                                         u_minify(pres->width0, level),
1245                                         u_minify(pres->height0, level),
1246                                         &transfer);
1247       if (res_map) {
1248          util_copy_rect((ubyte*)map, pres->format, res->dt_stride, 0, 0,
1249                         transfer->box.width, transfer->box.height,
1250                         (const ubyte*)res_map, transfer->stride, 0, 0);
1251          pipe_texture_unmap(pcontext, transfer);
1252       }
1253       winsys->displaytarget_unmap(winsys, res->dt);
1254    }
1255 
1256    winsys->displaytarget_display(winsys, res->dt, winsys_drawable_handle, sub_box);
1257 }
1258 
1259 bool
zink_is_depth_format_supported(struct zink_screen * screen,VkFormat format)1260 zink_is_depth_format_supported(struct zink_screen *screen, VkFormat format)
1261 {
1262    VkFormatProperties props;
1263    VKSCR(GetPhysicalDeviceFormatProperties)(screen->pdev, format, &props);
1264    return (props.linearTilingFeatures | props.optimalTilingFeatures) &
1265           VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT;
1266 }
1267 
1268 static enum pipe_format
emulate_x8(enum pipe_format format)1269 emulate_x8(enum pipe_format format)
1270 {
1271    /* convert missing X8 variants to A8 */
1272    switch (format) {
1273    case PIPE_FORMAT_B8G8R8X8_UNORM:
1274       return PIPE_FORMAT_B8G8R8A8_UNORM;
1275 
1276    case PIPE_FORMAT_B8G8R8X8_SRGB:
1277       return PIPE_FORMAT_B8G8R8A8_SRGB;
1278 
1279    case PIPE_FORMAT_R8G8B8X8_SINT:
1280       return PIPE_FORMAT_R8G8B8A8_SINT;
1281    case PIPE_FORMAT_R8G8B8X8_SNORM:
1282       return PIPE_FORMAT_R8G8B8A8_SNORM;
1283    case PIPE_FORMAT_R8G8B8X8_UNORM:
1284       return PIPE_FORMAT_R8G8B8A8_UNORM;
1285 
1286    case PIPE_FORMAT_R16G16B16X16_FLOAT:
1287       return PIPE_FORMAT_R16G16B16A16_FLOAT;
1288    case PIPE_FORMAT_R16G16B16X16_SINT:
1289       return PIPE_FORMAT_R16G16B16A16_SINT;
1290    case PIPE_FORMAT_R16G16B16X16_SNORM:
1291       return PIPE_FORMAT_R16G16B16A16_SNORM;
1292    case PIPE_FORMAT_R16G16B16X16_UNORM:
1293       return PIPE_FORMAT_R16G16B16A16_UNORM;
1294 
1295    default:
1296       return format;
1297    }
1298 }
1299 
1300 VkFormat
zink_get_format(struct zink_screen * screen,enum pipe_format format)1301 zink_get_format(struct zink_screen *screen, enum pipe_format format)
1302 {
1303    VkFormat ret = zink_pipe_format_to_vk_format(emulate_x8(format));
1304 
1305    if (format == PIPE_FORMAT_X32_S8X24_UINT)
1306       return VK_FORMAT_D32_SFLOAT_S8_UINT;
1307 
1308    if (format == PIPE_FORMAT_X24S8_UINT)
1309       /* valid when using aspects to extract stencil,
1310        * fails format test because it's emulated */
1311       ret = VK_FORMAT_D24_UNORM_S8_UINT;
1312 
1313    if (ret == VK_FORMAT_X8_D24_UNORM_PACK32 &&
1314        !screen->have_X8_D24_UNORM_PACK32) {
1315       assert(zink_is_depth_format_supported(screen, VK_FORMAT_D32_SFLOAT));
1316       return VK_FORMAT_D32_SFLOAT;
1317    }
1318 
1319    if (ret == VK_FORMAT_D24_UNORM_S8_UINT &&
1320        !screen->have_D24_UNORM_S8_UINT) {
1321       assert(zink_is_depth_format_supported(screen,
1322                                             VK_FORMAT_D32_SFLOAT_S8_UINT));
1323       return VK_FORMAT_D32_SFLOAT_S8_UINT;
1324    }
1325 
1326    if ((ret == VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT &&
1327         !screen->info.format_4444_feats.formatA4B4G4R4) ||
1328        (ret == VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT &&
1329         !screen->info.format_4444_feats.formatA4R4G4B4))
1330       return VK_FORMAT_UNDEFINED;
1331 
1332    return ret;
1333 }
1334 
1335 void
zink_screen_init_descriptor_funcs(struct zink_screen * screen,bool fallback)1336 zink_screen_init_descriptor_funcs(struct zink_screen *screen, bool fallback)
1337 {
1338    if (screen->info.have_KHR_descriptor_update_template &&
1339        !fallback &&
1340        screen->descriptor_mode == ZINK_DESCRIPTOR_MODE_LAZY) {
1341 #define LAZY(FUNC) screen->FUNC = zink_##FUNC##_lazy
1342       LAZY(descriptor_program_init);
1343       LAZY(descriptor_program_deinit);
1344       LAZY(context_invalidate_descriptor_state);
1345       LAZY(batch_descriptor_init);
1346       LAZY(batch_descriptor_reset);
1347       LAZY(batch_descriptor_deinit);
1348       LAZY(descriptors_init);
1349       LAZY(descriptors_deinit);
1350       LAZY(descriptors_update);
1351 #undef LAZY
1352    } else {
1353 #define DEFAULT(FUNC) screen->FUNC = zink_##FUNC
1354       DEFAULT(descriptor_program_init);
1355       DEFAULT(descriptor_program_deinit);
1356       DEFAULT(context_invalidate_descriptor_state);
1357       DEFAULT(batch_descriptor_init);
1358       DEFAULT(batch_descriptor_reset);
1359       DEFAULT(batch_descriptor_deinit);
1360       DEFAULT(descriptors_init);
1361       DEFAULT(descriptors_deinit);
1362       DEFAULT(descriptors_update);
1363 #undef DEFAULT
1364    }
1365 }
1366 
1367 static bool
check_have_device_time(struct zink_screen * screen)1368 check_have_device_time(struct zink_screen *screen)
1369 {
1370    uint32_t num_domains = 0;
1371    VkTimeDomainEXT domains[8]; //current max is 4
1372    VKSCR(GetPhysicalDeviceCalibrateableTimeDomainsEXT)(screen->pdev, &num_domains, NULL);
1373    assert(num_domains > 0);
1374    assert(num_domains < ARRAY_SIZE(domains));
1375 
1376    VKSCR(GetPhysicalDeviceCalibrateableTimeDomainsEXT)(screen->pdev, &num_domains, domains);
1377 
1378    /* VK_TIME_DOMAIN_DEVICE_EXT is used for the ctx->get_timestamp hook and is the only one we really need */
1379    for (unsigned i = 0; i < num_domains; i++) {
1380       if (domains[i] == VK_TIME_DOMAIN_DEVICE_EXT) {
1381          return true;
1382       }
1383    }
1384 
1385    return false;
1386 }
1387 
1388 static void
zink_error(const char * msg)1389 zink_error(const char *msg)
1390 {
1391 }
1392 
1393 static void
zink_warn(const char * msg)1394 zink_warn(const char *msg)
1395 {
1396 }
1397 
1398 static void
zink_info(const char * msg)1399 zink_info(const char *msg)
1400 {
1401 }
1402 
1403 static void
zink_msg(const char * msg)1404 zink_msg(const char *msg)
1405 {
1406 }
1407 
1408 static VKAPI_ATTR VkBool32 VKAPI_CALL
zink_debug_util_callback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,VkDebugUtilsMessageTypeFlagsEXT messageType,const VkDebugUtilsMessengerCallbackDataEXT * pCallbackData,void * pUserData)1409 zink_debug_util_callback(
1410     VkDebugUtilsMessageSeverityFlagBitsEXT           messageSeverity,
1411     VkDebugUtilsMessageTypeFlagsEXT                  messageType,
1412     const VkDebugUtilsMessengerCallbackDataEXT      *pCallbackData,
1413     void                                            *pUserData)
1414 {
1415    // Pick message prefix and color to use.
1416    // Only MacOS and Linux have been tested for color support
1417    if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) {
1418       zink_error(pCallbackData->pMessage);
1419    } else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) {
1420       zink_warn(pCallbackData->pMessage);
1421    } else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) {
1422       zink_info(pCallbackData->pMessage);
1423    } else
1424       zink_msg(pCallbackData->pMessage);
1425 
1426    return VK_FALSE;
1427 }
1428 
1429 static bool
create_debug(struct zink_screen * screen)1430 create_debug(struct zink_screen *screen)
1431 {
1432    VkDebugUtilsMessengerCreateInfoEXT vkDebugUtilsMessengerCreateInfoEXT = {
1433        VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
1434        NULL,
1435        0,  // flags
1436        VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
1437        VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT |
1438        VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
1439        VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,
1440        VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
1441        VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
1442        VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,
1443        zink_debug_util_callback,
1444        NULL
1445    };
1446 
1447    VkDebugUtilsMessengerEXT vkDebugUtilsCallbackEXT = VK_NULL_HANDLE;
1448 
1449    VKSCR(CreateDebugUtilsMessengerEXT)(
1450        screen->instance,
1451        &vkDebugUtilsMessengerCreateInfoEXT,
1452        NULL,
1453        &vkDebugUtilsCallbackEXT
1454    );
1455 
1456    screen->debugUtilsCallbackHandle = vkDebugUtilsCallbackEXT;
1457 
1458    return true;
1459 }
1460 
1461 static bool
zink_internal_setup_moltenvk(struct zink_screen * screen)1462 zink_internal_setup_moltenvk(struct zink_screen *screen)
1463 {
1464 #if defined(MVK_VERSION)
1465    if (!screen->instance_info.have_MVK_moltenvk)
1466       return true;
1467 
1468    GET_PROC_ADDR_INSTANCE_LOCAL(screen->instance, GetMoltenVKConfigurationMVK);
1469    GET_PROC_ADDR_INSTANCE_LOCAL(screen->instance, SetMoltenVKConfigurationMVK);
1470    GET_PROC_ADDR_INSTANCE_LOCAL(screen->instance, GetVersionStringsMVK);
1471 
1472    if (vk_GetVersionStringsMVK) {
1473       char molten_version[64] = {0};
1474       char vulkan_version[64] = {0};
1475 
1476       vk_GetVersionStringsMVK(molten_version, sizeof(molten_version) - 1, vulkan_version, sizeof(vulkan_version) - 1);
1477 
1478       printf("zink: MoltenVK %s Vulkan %s \n", molten_version, vulkan_version);
1479    }
1480 
1481    if (vk_GetMoltenVKConfigurationMVK && vk_SetMoltenVKConfigurationMVK) {
1482       MVKConfiguration molten_config = {0};
1483       size_t molten_config_size = sizeof(molten_config);
1484 
1485       VkResult res = vk_GetMoltenVKConfigurationMVK(screen->instance, &molten_config, &molten_config_size);
1486       if (res == VK_SUCCESS || res == VK_INCOMPLETE) {
1487          // Needed to allow MoltenVK to accept VkImageView swizzles.
1488          // Encountered when using VK_FORMAT_R8G8_UNORM
1489          molten_config.fullImageViewSwizzle = VK_TRUE;
1490          vk_SetMoltenVKConfigurationMVK(screen->instance, &molten_config, &molten_config_size);
1491       }
1492    }
1493 #endif // MVK_VERSION
1494 
1495    return true;
1496 }
1497 
1498 static void
check_device_needs_mesa_wsi(struct zink_screen * screen)1499 check_device_needs_mesa_wsi(struct zink_screen *screen)
1500 {
1501    if (
1502        /* Raspberry Pi 4 V3DV driver */
1503        (screen->info.props.vendorID == 0x14E4 &&
1504         screen->info.props.deviceID == 42) ||
1505        /* RADV */
1506        screen->info.driver_props.driverID == VK_DRIVER_ID_MESA_RADV_KHR
1507       ) {
1508       screen->needs_mesa_wsi = true;
1509    } else if (screen->info.driver_props.driverID == VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA_KHR)
1510       screen->needs_mesa_flush_wsi = true;
1511 
1512 }
1513 
1514 static void
populate_format_props(struct zink_screen * screen)1515 populate_format_props(struct zink_screen *screen)
1516 {
1517    for (unsigned i = 0; i < PIPE_FORMAT_COUNT; i++) {
1518       VkFormat format = zink_get_format(screen, i);
1519       if (!format)
1520          continue;
1521       if (VKSCR(GetPhysicalDeviceFormatProperties2)) {
1522          VkFormatProperties2 props = {0};
1523          props.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
1524 
1525          VkDrmFormatModifierPropertiesListEXT mod_props;
1526          VkDrmFormatModifierPropertiesEXT mods[128];
1527          if (screen->info.have_EXT_image_drm_format_modifier) {
1528             mod_props.sType = VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT;
1529             mod_props.pNext = NULL;
1530             mod_props.drmFormatModifierCount = ARRAY_SIZE(mods);
1531             mod_props.pDrmFormatModifierProperties = mods;
1532             props.pNext = &mod_props;
1533          }
1534          VKSCR(GetPhysicalDeviceFormatProperties2)(screen->pdev, format, &props);
1535          screen->format_props[i] = props.formatProperties;
1536          if (screen->info.have_EXT_image_drm_format_modifier && mod_props.drmFormatModifierCount) {
1537             screen->modifier_props[i].drmFormatModifierCount = mod_props.drmFormatModifierCount;
1538             screen->modifier_props[i].pDrmFormatModifierProperties = ralloc_array(screen, VkDrmFormatModifierPropertiesEXT, mod_props.drmFormatModifierCount);
1539             if (mod_props.pDrmFormatModifierProperties) {
1540                for (unsigned j = 0; j < mod_props.drmFormatModifierCount; j++)
1541                   screen->modifier_props[i].pDrmFormatModifierProperties[j] = mod_props.pDrmFormatModifierProperties[j];
1542             }
1543          }
1544       } else
1545          VKSCR(GetPhysicalDeviceFormatProperties)(screen->pdev, format, &screen->format_props[i]);
1546    }
1547 }
1548 
1549 bool
zink_screen_init_semaphore(struct zink_screen * screen)1550 zink_screen_init_semaphore(struct zink_screen *screen)
1551 {
1552    VkSemaphoreCreateInfo sci = {0};
1553    VkSemaphoreTypeCreateInfo tci = {0};
1554    VkSemaphore sem;
1555    sci.pNext = &tci;
1556    sci.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
1557    tci.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO;
1558    tci.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE;
1559 
1560    if (VKSCR(CreateSemaphore)(screen->dev, &sci, NULL, &sem) == VK_SUCCESS) {
1561       /* semaphore signal values can never decrease,
1562        * so we need a new semaphore anytime we overflow
1563        */
1564       if (screen->prev_sem)
1565          VKSCR(DestroySemaphore)(screen->dev, screen->prev_sem, NULL);
1566       screen->prev_sem = screen->sem;
1567       screen->sem = sem;
1568       return true;
1569    }
1570    screen->info.have_KHR_timeline_semaphore = false;
1571    return false;
1572 }
1573 
1574 bool
zink_screen_timeline_wait(struct zink_screen * screen,uint32_t batch_id,uint64_t timeout)1575 zink_screen_timeline_wait(struct zink_screen *screen, uint32_t batch_id, uint64_t timeout)
1576 {
1577    VkSemaphoreWaitInfo wi = {0};
1578 
1579    if (zink_screen_check_last_finished(screen, batch_id))
1580       return true;
1581 
1582    wi.sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO;
1583    wi.semaphoreCount = 1;
1584    /* handle batch_id overflow */
1585    wi.pSemaphores = batch_id > screen->curr_batch ? &screen->prev_sem : &screen->sem;
1586    uint64_t batch_id64 = batch_id;
1587    wi.pValues = &batch_id64;
1588    bool success = false;
1589    if (screen->device_lost)
1590       return true;
1591    VkResult ret = VKSCR(WaitSemaphores)(screen->dev, &wi, timeout);
1592    success = zink_screen_handle_vkresult(screen, ret);
1593 
1594    if (success)
1595       zink_screen_update_last_finished(screen, batch_id);
1596 
1597    return success;
1598 }
1599 
1600 struct noop_submit_info {
1601    struct zink_screen *screen;
1602    VkFence fence;
1603 };
1604 
1605 static void
noop_submit(void * data,void * gdata,int thread_index)1606 noop_submit(void *data, void *gdata, int thread_index)
1607 {
1608    struct noop_submit_info *n = data;
1609    VkSubmitInfo si = {0};
1610    si.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1611    simple_mtx_lock(&n->screen->queue_lock);
1612    if (n->VKSCR(QueueSubmit)(n->screen->threaded ? n->screen->thread_queue : n->screen->queue,
1613                      1, &si, n->fence) != VK_SUCCESS) {
1614       debug_printf("ZINK: vkQueueSubmit() failed\n");
1615       n->screen->device_lost = true;
1616    }
1617    simple_mtx_unlock(&n->screen->queue_lock);
1618 }
1619 
1620 bool
zink_screen_batch_id_wait(struct zink_screen * screen,uint32_t batch_id,uint64_t timeout)1621 zink_screen_batch_id_wait(struct zink_screen *screen, uint32_t batch_id, uint64_t timeout)
1622 {
1623    if (zink_screen_check_last_finished(screen, batch_id))
1624       return true;
1625 
1626    if (screen->info.have_KHR_timeline_semaphore)
1627       return zink_screen_timeline_wait(screen, batch_id, timeout);
1628 
1629    if (!timeout)
1630       return false;
1631 
1632    uint32_t new_id = 0;
1633    while (!new_id)
1634       new_id = p_atomic_inc_return(&screen->curr_batch);
1635    VkResult ret;
1636    struct noop_submit_info n;
1637    uint64_t abs_timeout = os_time_get_absolute_timeout(timeout);
1638    uint64_t remaining = PIPE_TIMEOUT_INFINITE;
1639    VkFenceCreateInfo fci = {0};
1640    struct util_queue_fence fence;
1641    util_queue_fence_init(&fence);
1642    fci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
1643 
1644    if (VKSCR(CreateFence)(screen->dev, &fci, NULL, &n.fence) != VK_SUCCESS)
1645       return false;
1646 
1647    n.screen = screen;
1648    if (screen->threaded) {
1649       /* must use thread dispatch for sanity */
1650       util_queue_add_job(&screen->flush_queue, &n, &fence, noop_submit, NULL, 0);
1651       util_queue_fence_wait(&fence);
1652    } else {
1653       noop_submit(&n, NULL, 0);
1654    }
1655    if (timeout != PIPE_TIMEOUT_INFINITE) {
1656       int64_t time_ns = os_time_get_nano();
1657       remaining = abs_timeout > time_ns ? abs_timeout - time_ns : 0;
1658    }
1659 
1660    if (remaining)
1661       ret = VKSCR(WaitForFences)(screen->dev, 1, &n.fence, VK_TRUE, remaining);
1662    else
1663       ret = VKSCR(GetFenceStatus)(screen->dev, n.fence);
1664    VKSCR(DestroyFence)(screen->dev, n.fence, NULL);
1665    bool success = zink_screen_handle_vkresult(screen, ret);
1666 
1667    if (success)
1668       zink_screen_update_last_finished(screen, new_id);
1669 
1670    return success;
1671 }
1672 
1673 static uint32_t
zink_get_loader_version(void)1674 zink_get_loader_version(void)
1675 {
1676 
1677    uint32_t loader_version = VK_API_VERSION_1_0;
1678 
1679    // Get the Loader version
1680    GET_PROC_ADDR_INSTANCE_LOCAL(NULL, EnumerateInstanceVersion);
1681    if (vk_EnumerateInstanceVersion) {
1682       uint32_t loader_version_temp = VK_API_VERSION_1_0;
1683       if (VK_SUCCESS == (*vk_EnumerateInstanceVersion)(&loader_version_temp)) {
1684          loader_version = loader_version_temp;
1685       }
1686    }
1687 
1688    return loader_version;
1689 }
1690 
1691 static void
zink_query_memory_info(struct pipe_screen * pscreen,struct pipe_memory_info * info)1692 zink_query_memory_info(struct pipe_screen *pscreen, struct pipe_memory_info *info)
1693 {
1694    struct zink_screen *screen = zink_screen(pscreen);
1695    memset(info, 0, sizeof(struct pipe_memory_info));
1696    if (screen->info.have_EXT_memory_budget && VKSCR(GetPhysicalDeviceMemoryProperties2)) {
1697       VkPhysicalDeviceMemoryProperties2 mem = {0};
1698       mem.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2;
1699 
1700       VkPhysicalDeviceMemoryBudgetPropertiesEXT budget = {0};
1701       budget.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT;
1702       mem.pNext = &budget;
1703       VKSCR(GetPhysicalDeviceMemoryProperties2)(screen->pdev, &mem);
1704 
1705       for (unsigned i = 0; i < mem.memoryProperties.memoryHeapCount; i++) {
1706          if (mem.memoryProperties.memoryHeaps[i].flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) {
1707             /* VRAM */
1708             info->total_device_memory += mem.memoryProperties.memoryHeaps[i].size / 1024;
1709             info->avail_device_memory += (mem.memoryProperties.memoryHeaps[i].size - budget.heapUsage[i]) / 1024;
1710          } else {
1711             /* GART */
1712             info->total_staging_memory += mem.memoryProperties.memoryHeaps[i].size / 1024;
1713             info->avail_staging_memory += (mem.memoryProperties.memoryHeaps[i].size - budget.heapUsage[i]) / 1024;
1714          }
1715       }
1716       /* evictions not yet supported in vulkan */
1717    } else {
1718       for (unsigned i = 0; i < screen->info.mem_props.memoryHeapCount; i++) {
1719          if (screen->info.mem_props.memoryHeaps[i].flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) {
1720             /* VRAM */
1721             info->total_device_memory += screen->info.mem_props.memoryHeaps[i].size / 1024;
1722             /* free real estate! */
1723             info->avail_device_memory += info->total_device_memory;
1724          } else {
1725             /* GART */
1726             info->total_staging_memory += screen->info.mem_props.memoryHeaps[i].size / 1024;
1727             /* free real estate! */
1728             info->avail_staging_memory += info->total_staging_memory;
1729          }
1730       }
1731    }
1732 }
1733 
1734 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)1735 zink_query_dmabuf_modifiers(struct pipe_screen *pscreen, enum pipe_format format, int max, uint64_t *modifiers, unsigned int *external_only, int *count)
1736 {
1737    struct zink_screen *screen = zink_screen(pscreen);
1738    *count = screen->modifier_props[format].drmFormatModifierCount;
1739    for (int i = 0; i < MIN2(max, *count); i++)
1740       modifiers[i] = screen->modifier_props[format].pDrmFormatModifierProperties[i].drmFormatModifier;
1741 }
1742 
1743 static bool
zink_is_dmabuf_modifier_supported(struct pipe_screen * pscreen,uint64_t modifier,enum pipe_format format,bool * external_only)1744 zink_is_dmabuf_modifier_supported(struct pipe_screen *pscreen, uint64_t modifier, enum pipe_format format, bool *external_only)
1745 {
1746    struct zink_screen *screen = zink_screen(pscreen);
1747    for (unsigned i = 0; i < screen->modifier_props[format].drmFormatModifierCount; i++)
1748       if (screen->modifier_props[format].pDrmFormatModifierProperties[i].drmFormatModifier == modifier)
1749          return true;
1750    return false;
1751 }
1752 
1753 static unsigned
zink_get_dmabuf_modifier_planes(struct pipe_screen * pscreen,uint64_t modifier,enum pipe_format format)1754 zink_get_dmabuf_modifier_planes(struct pipe_screen *pscreen, uint64_t modifier, enum pipe_format format)
1755 {
1756    struct zink_screen *screen = zink_screen(pscreen);
1757    for (unsigned i = 0; i < screen->modifier_props[format].drmFormatModifierCount; i++)
1758       if (screen->modifier_props[format].pDrmFormatModifierProperties[i].drmFormatModifier == modifier)
1759          return screen->modifier_props[format].pDrmFormatModifierProperties[i].drmFormatModifierPlaneCount;
1760    return 0;
1761 }
1762 
1763 static VkDevice
zink_create_logical_device(struct zink_screen * screen)1764 zink_create_logical_device(struct zink_screen *screen)
1765 {
1766    VkDevice dev = VK_NULL_HANDLE;
1767 
1768    VkDeviceQueueCreateInfo qci = {0};
1769    float dummy = 0.0f;
1770    qci.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
1771    qci.queueFamilyIndex = screen->gfx_queue;
1772    qci.queueCount = screen->threaded && screen->max_queues > 1 ? 2 : 1;
1773    qci.pQueuePriorities = &dummy;
1774 
1775    VkDeviceCreateInfo dci = {0};
1776    dci.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
1777    dci.queueCreateInfoCount = 1;
1778    dci.pQueueCreateInfos = &qci;
1779    /* extensions don't have bool members in pEnabledFeatures.
1780     * this requires us to pass the whole VkPhysicalDeviceFeatures2 struct
1781     */
1782    if (screen->info.feats.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2) {
1783       dci.pNext = &screen->info.feats;
1784    } else {
1785       dci.pEnabledFeatures = &screen->info.feats.features;
1786    }
1787 
1788    dci.ppEnabledExtensionNames = screen->info.extensions;
1789    dci.enabledExtensionCount = screen->info.num_extensions;
1790 
1791    vkCreateDevice(screen->pdev, &dci, NULL, &dev);
1792    return dev;
1793 }
1794 
1795 static void
pre_hash_descriptor_states(struct zink_screen * screen)1796 pre_hash_descriptor_states(struct zink_screen *screen)
1797 {
1798    VkImageViewCreateInfo null_info = {.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO};
1799    VkBufferViewCreateInfo null_binfo = {.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO};
1800    screen->null_descriptor_hashes.image_view = _mesa_hash_data(&null_info, sizeof(VkImageViewCreateInfo));
1801    screen->null_descriptor_hashes.buffer_view = _mesa_hash_data(&null_binfo, sizeof(VkBufferViewCreateInfo));
1802 }
1803 
1804 static void
check_base_requirements(struct zink_screen * screen)1805 check_base_requirements(struct zink_screen *screen)
1806 {
1807    if (!screen->info.feats.features.logicOp ||
1808        !screen->info.feats.features.fillModeNonSolid ||
1809        !screen->info.feats.features.wideLines ||
1810        !screen->info.feats.features.largePoints ||
1811        !screen->info.feats.features.shaderClipDistance ||
1812        !(screen->info.feats12.scalarBlockLayout ||
1813          screen->info.have_EXT_scalar_block_layout) ||
1814        !screen->info.have_KHR_maintenance1 ||
1815        !screen->info.have_EXT_custom_border_color ||
1816        !screen->info.have_EXT_line_rasterization) {
1817       fprintf(stderr, "WARNING: Some incorrect rendering "
1818               "might occur because the selected Vulkan device (%s) doesn't support "
1819               "base Zink requirements: ", screen->info.props.deviceName);
1820 #define CHECK_OR_PRINT(X) \
1821       if (!screen->info.X) \
1822          fprintf(stderr, "%s ", #X)
1823       CHECK_OR_PRINT(feats.features.logicOp);
1824       CHECK_OR_PRINT(feats.features.fillModeNonSolid);
1825       CHECK_OR_PRINT(feats.features.wideLines);
1826       CHECK_OR_PRINT(feats.features.largePoints);
1827       CHECK_OR_PRINT(feats.features.shaderClipDistance);
1828       if (!screen->info.feats12.scalarBlockLayout && !screen->info.have_EXT_scalar_block_layout)
1829          printf("scalarBlockLayout OR EXT_scalar_block_layout ");
1830       CHECK_OR_PRINT(have_KHR_maintenance1);
1831       CHECK_OR_PRINT(have_EXT_custom_border_color);
1832       CHECK_OR_PRINT(have_EXT_line_rasterization);
1833       fprintf(stderr, "\n");
1834    }
1835 }
1836 
1837 static void
zink_get_sample_pixel_grid(struct pipe_screen * pscreen,unsigned sample_count,unsigned * width,unsigned * height)1838 zink_get_sample_pixel_grid(struct pipe_screen *pscreen, unsigned sample_count,
1839                            unsigned *width, unsigned *height)
1840 {
1841    struct zink_screen *screen = zink_screen(pscreen);
1842    unsigned idx = util_logbase2_ceil(MAX2(sample_count, 1));
1843    assert(idx < ARRAY_SIZE(screen->maxSampleLocationGridSize));
1844    *width = screen->maxSampleLocationGridSize[idx].width;
1845    *height = screen->maxSampleLocationGridSize[idx].height;
1846 }
1847 
1848 static struct zink_screen *
zink_internal_create_screen(const struct pipe_screen_config * config)1849 zink_internal_create_screen(const struct pipe_screen_config *config)
1850 {
1851    struct zink_screen *screen = rzalloc(NULL, struct zink_screen);
1852    if (!screen)
1853       return NULL;
1854 
1855    util_cpu_detect();
1856    screen->threaded = util_get_cpu_caps()->nr_cpus > 1 && debug_get_bool_option("GALLIUM_THREAD", util_get_cpu_caps()->nr_cpus > 1);
1857    if (screen->threaded)
1858       util_queue_init(&screen->flush_queue, "zfq", 8, 1, UTIL_QUEUE_INIT_RESIZE_IF_FULL, NULL);
1859 
1860    zink_debug = debug_get_option_zink_debug();
1861    screen->descriptor_mode = debug_get_option_zink_descriptor_mode();
1862    if (screen->descriptor_mode > ZINK_DESCRIPTOR_MODE_NOTEMPLATES) {
1863       printf("Specify exactly one descriptor mode.\n");
1864       abort();
1865    }
1866 
1867    screen->instance_info.loader_version = zink_get_loader_version();
1868    screen->instance = zink_create_instance(&screen->instance_info);
1869 
1870    if (!screen->instance)
1871       goto fail;
1872 
1873    vk_instance_dispatch_table_load(&screen->vk.instance, &vkGetInstanceProcAddr, screen->instance);
1874    vk_physical_device_dispatch_table_load(&screen->vk.physical_device, &vkGetInstanceProcAddr, screen->instance);
1875 
1876    zink_verify_instance_extensions(screen);
1877 
1878    if (screen->instance_info.have_EXT_debug_utils &&
1879       (zink_debug & ZINK_DEBUG_VALIDATION) && !create_debug(screen))
1880       debug_printf("ZINK: failed to setup debug utils\n");
1881 
1882    choose_pdev(screen);
1883    if (screen->pdev == VK_NULL_HANDLE)
1884       goto fail;
1885 
1886    update_queue_props(screen);
1887 
1888    screen->have_X8_D24_UNORM_PACK32 = zink_is_depth_format_supported(screen,
1889                                               VK_FORMAT_X8_D24_UNORM_PACK32);
1890    screen->have_D24_UNORM_S8_UINT = zink_is_depth_format_supported(screen,
1891                                               VK_FORMAT_D24_UNORM_S8_UINT);
1892 
1893    if (!zink_get_physical_device_info(screen)) {
1894       debug_printf("ZINK: failed to detect features\n");
1895       goto fail;
1896    }
1897 
1898    /* Some Vulkan implementations have special requirements for WSI
1899     * allocations.
1900     */
1901    check_device_needs_mesa_wsi(screen);
1902 
1903    zink_internal_setup_moltenvk(screen);
1904 
1905    screen->dev = zink_create_logical_device(screen);
1906    if (!screen->dev)
1907       goto fail;
1908 
1909    init_queue(screen);
1910    if (screen->info.driver_props.driverID == VK_DRIVER_ID_MESA_RADV ||
1911        screen->info.driver_props.driverID == VK_DRIVER_ID_AMD_OPEN_SOURCE ||
1912        screen->info.driver_props.driverID == VK_DRIVER_ID_AMD_PROPRIETARY)
1913       /* this has bad perf on AMD */
1914       screen->info.have_KHR_push_descriptor = false;
1915 
1916    vk_device_dispatch_table_load(&screen->vk.device, &vkGetDeviceProcAddr, screen->dev);
1917 
1918    zink_verify_device_extensions(screen);
1919 
1920    if (screen->info.have_EXT_calibrated_timestamps && !check_have_device_time(screen))
1921       goto fail;
1922 
1923    screen->have_triangle_fans = true;
1924 #if defined(VK_EXTX_PORTABILITY_SUBSET_EXTENSION_NAME)
1925    if (screen->info.have_EXTX_portability_subset) {
1926       screen->have_triangle_fans = (VK_TRUE == screen->info.portability_subset_extx_feats.triangleFans);
1927    }
1928 #endif // VK_EXTX_PORTABILITY_SUBSET_EXTENSION_NAME
1929 
1930    check_base_requirements(screen);
1931    util_live_shader_cache_init(&screen->shaders, zink_create_gfx_shader_state, zink_delete_shader_state);
1932 
1933    screen->base.get_name = zink_get_name;
1934    screen->base.get_vendor = zink_get_vendor;
1935    screen->base.get_device_vendor = zink_get_device_vendor;
1936    screen->base.get_compute_param = zink_get_compute_param;
1937    screen->base.query_memory_info = zink_query_memory_info;
1938    screen->base.get_param = zink_get_param;
1939    screen->base.get_paramf = zink_get_paramf;
1940    screen->base.get_shader_param = zink_get_shader_param;
1941    screen->base.get_compiler_options = zink_get_compiler_options;
1942    screen->base.get_sample_pixel_grid = zink_get_sample_pixel_grid;
1943    screen->base.is_format_supported = zink_is_format_supported;
1944    screen->base.query_dmabuf_modifiers = zink_query_dmabuf_modifiers;
1945    screen->base.is_dmabuf_modifier_supported = zink_is_dmabuf_modifier_supported;
1946    screen->base.get_dmabuf_modifier_planes = zink_get_dmabuf_modifier_planes;
1947    screen->base.context_create = zink_context_create;
1948    screen->base.flush_frontbuffer = zink_flush_frontbuffer;
1949    screen->base.destroy = zink_destroy_screen;
1950    screen->base.finalize_nir = zink_shader_finalize;
1951 
1952    if (screen->info.have_EXT_sample_locations) {
1953       VkMultisamplePropertiesEXT prop;
1954       prop.sType = VK_STRUCTURE_TYPE_MULTISAMPLE_PROPERTIES_EXT;
1955       prop.pNext = NULL;
1956       for (unsigned i = 0; i < ARRAY_SIZE(screen->maxSampleLocationGridSize); i++) {
1957          if (screen->info.sample_locations_props.sampleLocationSampleCounts & (1 << i)) {
1958             VKSCR(GetPhysicalDeviceMultisamplePropertiesEXT)(screen->pdev, 1 << i, &prop);
1959             screen->maxSampleLocationGridSize[i] = prop.maxSampleLocationGridSize;
1960          }
1961       }
1962    }
1963 
1964    if (!zink_screen_resource_init(&screen->base))
1965       goto fail;
1966    zink_bo_init(screen);
1967    zink_screen_fence_init(&screen->base);
1968 
1969    zink_screen_init_compiler(screen);
1970    disk_cache_init(screen);
1971    populate_format_props(screen);
1972    pre_hash_descriptor_states(screen);
1973 
1974    slab_create_parent(&screen->transfer_pool, sizeof(struct zink_transfer), 16);
1975 
1976 #if WITH_XMLCONFIG
1977    if (config) {
1978       driParseConfigFiles(config->options, config->options_info, 0, "zink",
1979                           NULL, NULL, NULL, 0, NULL, 0);
1980       screen->driconf.dual_color_blend_by_location = driQueryOptionb(config->options, "dual_color_blend_by_location");
1981       //screen->driconf.inline_uniforms = driQueryOptionb(config->options, "radeonsi_inline_uniforms");
1982    }
1983 #endif
1984    screen->driconf.inline_uniforms = debug_get_bool_option("ZINK_INLINE_UNIFORMS", false);
1985 
1986    screen->total_video_mem = get_video_mem(screen);
1987    screen->clamp_video_mem = screen->total_video_mem * 0.8;
1988    if (!os_get_total_physical_memory(&screen->total_mem))
1989       goto fail;
1990 
1991    if (debug_get_bool_option("ZINK_NO_TIMELINES", false))
1992       screen->info.have_KHR_timeline_semaphore = false;
1993    if (screen->info.have_KHR_timeline_semaphore)
1994       zink_screen_init_semaphore(screen);
1995 
1996    memset(&screen->heap_map, UINT8_MAX, sizeof(screen->heap_map));
1997    for (enum zink_heap i = 0; i < ZINK_HEAP_MAX; i++) {
1998       for (unsigned j = 0; j < screen->info.mem_props.memoryTypeCount; j++) {
1999          VkMemoryPropertyFlags domains = vk_domain_from_heap(i);
2000          if ((screen->info.mem_props.memoryTypes[j].propertyFlags & domains) == domains) {
2001             assert(screen->heap_map[i] == UINT8_MAX);
2002             screen->heap_map[i] = j;
2003             break;
2004          }
2005       }
2006 
2007       /* not found: use compatible heap */
2008       if (screen->heap_map[i] == UINT8_MAX) {
2009          /* only cached mem has a failure case for now */
2010          assert(i == ZINK_HEAP_HOST_VISIBLE_CACHED || i == ZINK_HEAP_DEVICE_LOCAL_LAZY);
2011          if (i == ZINK_HEAP_HOST_VISIBLE_CACHED)
2012             screen->heap_map[i] = screen->heap_map[ZINK_HEAP_HOST_VISIBLE_COHERENT];
2013          else
2014             screen->heap_map[i] = screen->heap_map[ZINK_HEAP_DEVICE_LOCAL];
2015       }
2016    }
2017    {
2018       unsigned vis_vram = screen->heap_map[ZINK_HEAP_DEVICE_LOCAL_VISIBLE];
2019       unsigned vram = screen->heap_map[ZINK_HEAP_DEVICE_LOCAL];
2020       /* determine if vis vram is roughly equal to total vram */
2021       if (screen->info.mem_props.memoryHeaps[screen->info.mem_props.memoryTypes[vis_vram].heapIndex].size >
2022           screen->info.mem_props.memoryHeaps[screen->info.mem_props.memoryTypes[vram].heapIndex].size * 0.9)
2023          screen->resizable_bar = true;
2024    }
2025 
2026    if (!screen->info.have_KHR_imageless_framebuffer) {
2027       simple_mtx_init(&screen->framebuffer_mtx, mtx_plain);
2028       _mesa_hash_table_init(&screen->framebuffer_cache, screen, hash_framebuffer_state, equals_framebuffer_state);
2029    }
2030 
2031    zink_screen_init_descriptor_funcs(screen, false);
2032    util_idalloc_mt_init_tc(&screen->buffer_ids);
2033 
2034    return screen;
2035 
2036 fail:
2037    ralloc_free(screen);
2038    return NULL;
2039 }
2040 
2041 struct pipe_screen *
zink_create_screen(struct sw_winsys * winsys)2042 zink_create_screen(struct sw_winsys *winsys)
2043 {
2044    struct zink_screen *ret = zink_internal_create_screen(NULL);
2045    if (ret) {
2046       ret->winsys = winsys;
2047       ret->drm_fd = -1;
2048    }
2049 
2050    return &ret->base;
2051 }
2052 
2053 struct pipe_screen *
zink_drm_create_screen(int fd,const struct pipe_screen_config * config)2054 zink_drm_create_screen(int fd, const struct pipe_screen_config *config)
2055 {
2056    struct zink_screen *ret = zink_internal_create_screen(config);
2057 
2058    if (ret)
2059       ret->drm_fd = os_dupfd_cloexec(fd);
2060    if (ret && !ret->info.have_KHR_external_memory_fd) {
2061       debug_printf("ZINK: KHR_external_memory_fd required!\n");
2062       zink_destroy_screen(&ret->base);
2063       return NULL;
2064    }
2065 
2066    return &ret->base;
2067 }
2068 
zink_stub_function_not_loaded()2069 void zink_stub_function_not_loaded()
2070 {
2071    /* this will be used by the zink_verify_*_extensions() functions on a
2072     * release build
2073     */
2074    mesa_loge("ZINK: a Vulkan function was called without being loaded");
2075    abort();
2076 }
2077