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