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->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 
693 static float
zink_get_paramf(struct pipe_screen * pscreen,enum pipe_capf param)694 zink_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 
729 static int
zink_get_shader_param(struct pipe_screen * pscreen,enum pipe_shader_type shader,enum pipe_shader_cap param)730 zink_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 
941 static VkSampleCountFlagBits
vk_sample_count_flags(uint32_t sample_count)942 vk_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 
957 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)958 zink_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 
1096 static void
zink_destroy_screen(struct pipe_screen * pscreen)1097 zink_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 
1147 static void
choose_pdev(struct zink_screen * screen)1148 choose_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 
1198 static void
update_queue_props(struct zink_screen * screen)1199 update_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 
1219 static void
init_queue(struct zink_screen * screen)1220 init_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 
1230 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)1231 zink_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 
1264 bool
zink_is_depth_format_supported(struct zink_screen * screen,VkFormat format)1265 zink_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 
1273 static enum pipe_format
emulate_x8(enum pipe_format format)1274 emulate_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 
1305 VkFormat
zink_get_format(struct zink_screen * screen,enum pipe_format format)1306 zink_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 
1340 void
zink_screen_init_descriptor_funcs(struct zink_screen * screen,bool fallback)1341 zink_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 
1372 static bool
check_have_device_time(struct zink_screen * screen)1373 check_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 
1393 static void
zink_error(const char * msg)1394 zink_error(const char *msg)
1395 {
1396 }
1397 
1398 static void
zink_warn(const char * msg)1399 zink_warn(const char *msg)
1400 {
1401 }
1402 
1403 static void
zink_info(const char * msg)1404 zink_info(const char *msg)
1405 {
1406 }
1407 
1408 static void
zink_msg(const char * msg)1409 zink_msg(const char *msg)
1410 {
1411 }
1412 
1413 static VKAPI_ATTR VkBool32 VKAPI_CALL
zink_debug_util_callback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,VkDebugUtilsMessageTypeFlagsEXT messageType,const VkDebugUtilsMessengerCallbackDataEXT * pCallbackData,void * pUserData)1414 zink_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 
1434 static bool
create_debug(struct zink_screen * screen)1435 create_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 
1466 static bool
zink_internal_setup_moltenvk(struct zink_screen * screen)1467 zink_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 
1503 static void
check_device_needs_mesa_wsi(struct zink_screen * screen)1504 check_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 
1519 static void
populate_format_props(struct zink_screen * screen)1520 populate_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 
1554 bool
zink_screen_init_semaphore(struct zink_screen * screen)1555 zink_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 
1579 bool
zink_screen_timeline_wait(struct zink_screen * screen,uint32_t batch_id,uint64_t timeout)1580 zink_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 
1605 struct noop_submit_info {
1606    struct zink_screen *screen;
1607    VkFence fence;
1608 };
1609 
1610 static void
noop_submit(void * data,void * gdata,int thread_index)1611 noop_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 
1625 bool
zink_screen_batch_id_wait(struct zink_screen * screen,uint32_t batch_id,uint64_t timeout)1626 zink_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 
1678 static uint32_t
zink_get_loader_version(void)1679 zink_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 
1696 static void
zink_query_memory_info(struct pipe_screen * pscreen,struct pipe_memory_info * info)1697 zink_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 
1739 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)1740 zink_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 
1748 static bool
zink_is_dmabuf_modifier_supported(struct pipe_screen * pscreen,uint64_t modifier,enum pipe_format format,bool * external_only)1749 zink_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 
1758 static unsigned
zink_get_dmabuf_modifier_planes(struct pipe_screen * pscreen,uint64_t modifier,enum pipe_format format)1759 zink_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 
1768 static VkDevice
zink_create_logical_device(struct zink_screen * screen)1769 zink_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 
1800 static void
pre_hash_descriptor_states(struct zink_screen * screen)1801 pre_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 
1809 static void
check_base_requirements(struct zink_screen * screen)1810 check_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 
1842 static void
zink_get_sample_pixel_grid(struct pipe_screen * pscreen,unsigned sample_count,unsigned * width,unsigned * height)1843 zink_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 
1853 static struct zink_screen *
zink_internal_create_screen(const struct pipe_screen_config * config)1854 zink_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 
2043 fail:
2044    ralloc_free(screen);
2045    return NULL;
2046 }
2047 
2048 struct pipe_screen *
zink_create_screen(struct sw_winsys * winsys)2049 zink_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 
2060 struct pipe_screen *
zink_drm_create_screen(int fd,const struct pipe_screen_config * config)2061 zink_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 
zink_stub_function_not_loaded()2076 void 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