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