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