1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright 2018 Collabora Ltd. 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * on the rights to use, copy, modify, merge, publish, distribute, sub 8bf215546Sopenharmony_ci * license, and/or sell copies of the Software, and to permit persons to whom 9bf215546Sopenharmony_ci * the Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 19bf215546Sopenharmony_ci * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20bf215546Sopenharmony_ci * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21bf215546Sopenharmony_ci * USE OR OTHER DEALINGS IN THE SOFTWARE. 22bf215546Sopenharmony_ci */ 23bf215546Sopenharmony_ci 24bf215546Sopenharmony_ci#include "zink_screen.h" 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_ci#include "zink_kopper.h" 27bf215546Sopenharmony_ci#include "zink_compiler.h" 28bf215546Sopenharmony_ci#include "zink_context.h" 29bf215546Sopenharmony_ci#include "zink_device_info.h" 30bf215546Sopenharmony_ci#include "zink_descriptors.h" 31bf215546Sopenharmony_ci#include "zink_fence.h" 32bf215546Sopenharmony_ci#include "zink_format.h" 33bf215546Sopenharmony_ci#include "zink_framebuffer.h" 34bf215546Sopenharmony_ci#include "zink_instance.h" 35bf215546Sopenharmony_ci#include "zink_program.h" 36bf215546Sopenharmony_ci#include "zink_public.h" 37bf215546Sopenharmony_ci#include "zink_query.h" 38bf215546Sopenharmony_ci#include "zink_resource.h" 39bf215546Sopenharmony_ci#include "nir_to_spirv/nir_to_spirv.h" // for SPIRV_VERSION 40bf215546Sopenharmony_ci 41bf215546Sopenharmony_ci#include "os/os_process.h" 42bf215546Sopenharmony_ci#include "util/u_debug.h" 43bf215546Sopenharmony_ci#include "util/u_dl.h" 44bf215546Sopenharmony_ci#include "util/format/u_format.h" 45bf215546Sopenharmony_ci#include "util/hash_table.h" 46bf215546Sopenharmony_ci#include "util/os_file.h" 47bf215546Sopenharmony_ci#include "util/u_math.h" 48bf215546Sopenharmony_ci#include "util/u_memory.h" 49bf215546Sopenharmony_ci#include "util/u_screen.h" 50bf215546Sopenharmony_ci#include "util/u_string.h" 51bf215546Sopenharmony_ci#include "util/u_transfer_helper.h" 52bf215546Sopenharmony_ci#include "util/xmlconfig.h" 53bf215546Sopenharmony_ci 54bf215546Sopenharmony_ci#include "util/u_cpu_detect.h" 55bf215546Sopenharmony_ci 56bf215546Sopenharmony_ci#if DETECT_OS_WINDOWS 57bf215546Sopenharmony_ci#include <io.h> 58bf215546Sopenharmony_ci#define VK_LIBNAME "vulkan-1.dll" 59bf215546Sopenharmony_ci#else 60bf215546Sopenharmony_ci#include <unistd.h> 61bf215546Sopenharmony_ci#if DETECT_OS_APPLE 62bf215546Sopenharmony_ci#define VK_LIBNAME "libvulkan.1.dylib" 63bf215546Sopenharmony_ci#else 64bf215546Sopenharmony_ci#define VK_LIBNAME "libvulkan.so.1" 65bf215546Sopenharmony_ci#endif 66bf215546Sopenharmony_ci#endif 67bf215546Sopenharmony_ci 68bf215546Sopenharmony_ci#if defined(__APPLE__) 69bf215546Sopenharmony_ci// Source of MVK_VERSION 70bf215546Sopenharmony_ci#include "MoltenVK/vk_mvk_moltenvk.h" 71bf215546Sopenharmony_ci#endif 72bf215546Sopenharmony_ci 73bf215546Sopenharmony_cistatic const struct debug_named_value 74bf215546Sopenharmony_cizink_debug_options[] = { 75bf215546Sopenharmony_ci { "nir", ZINK_DEBUG_NIR, "Dump NIR during program compile" }, 76bf215546Sopenharmony_ci { "spirv", ZINK_DEBUG_SPIRV, "Dump SPIR-V during program compile" }, 77bf215546Sopenharmony_ci { "tgsi", ZINK_DEBUG_TGSI, "Dump TGSI during program compile" }, 78bf215546Sopenharmony_ci { "validation", ZINK_DEBUG_VALIDATION, "Dump Validation layer output" }, 79bf215546Sopenharmony_ci { "sync", ZINK_DEBUG_SYNC, "Force synchronization before draws/dispatches" }, 80bf215546Sopenharmony_ci { "compact", ZINK_DEBUG_COMPACT, "Use only 4 descriptor sets" }, 81bf215546Sopenharmony_ci { "noreorder", ZINK_DEBUG_NOREORDER, "Do not reorder command streams" }, 82bf215546Sopenharmony_ci DEBUG_NAMED_VALUE_END 83bf215546Sopenharmony_ci}; 84bf215546Sopenharmony_ci 85bf215546Sopenharmony_ciDEBUG_GET_ONCE_FLAGS_OPTION(zink_debug, "ZINK_DEBUG", zink_debug_options, 0) 86bf215546Sopenharmony_ci 87bf215546Sopenharmony_ciuint32_t 88bf215546Sopenharmony_cizink_debug; 89bf215546Sopenharmony_ci 90bf215546Sopenharmony_ci 91bf215546Sopenharmony_cistatic const struct debug_named_value 92bf215546Sopenharmony_cizink_descriptor_options[] = { 93bf215546Sopenharmony_ci { "auto", ZINK_DESCRIPTOR_MODE_AUTO, "Automatically detect best mode" }, 94bf215546Sopenharmony_ci { "lazy", ZINK_DESCRIPTOR_MODE_LAZY, "Don't cache, do least amount of updates" }, 95bf215546Sopenharmony_ci { "cached", ZINK_DESCRIPTOR_MODE_CACHED, "Cache, reuse sets" }, 96bf215546Sopenharmony_ci { "notemplates", ZINK_DESCRIPTOR_MODE_NOTEMPLATES, "Cache, but disable templated updates" }, 97bf215546Sopenharmony_ci DEBUG_NAMED_VALUE_END 98bf215546Sopenharmony_ci}; 99bf215546Sopenharmony_ci 100bf215546Sopenharmony_ciDEBUG_GET_ONCE_FLAGS_OPTION(zink_descriptor_mode, "ZINK_DESCRIPTORS", zink_descriptor_options, ZINK_DESCRIPTOR_MODE_AUTO) 101bf215546Sopenharmony_ci 102bf215546Sopenharmony_cienum zink_descriptor_mode zink_descriptor_mode; 103bf215546Sopenharmony_ci 104bf215546Sopenharmony_cistatic const char * 105bf215546Sopenharmony_cizink_get_vendor(struct pipe_screen *pscreen) 106bf215546Sopenharmony_ci{ 107bf215546Sopenharmony_ci return "Collabora Ltd"; 108bf215546Sopenharmony_ci} 109bf215546Sopenharmony_ci 110bf215546Sopenharmony_cistatic const char * 111bf215546Sopenharmony_cizink_get_device_vendor(struct pipe_screen *pscreen) 112bf215546Sopenharmony_ci{ 113bf215546Sopenharmony_ci struct zink_screen *screen = zink_screen(pscreen); 114bf215546Sopenharmony_ci static char buf[1000]; 115bf215546Sopenharmony_ci snprintf(buf, sizeof(buf), "Unknown (vendor-id: 0x%04x)", screen->info.props.vendorID); 116bf215546Sopenharmony_ci return buf; 117bf215546Sopenharmony_ci} 118bf215546Sopenharmony_ci 119bf215546Sopenharmony_cistatic const char * 120bf215546Sopenharmony_cizink_get_name(struct pipe_screen *pscreen) 121bf215546Sopenharmony_ci{ 122bf215546Sopenharmony_ci struct zink_screen *screen = zink_screen(pscreen); 123bf215546Sopenharmony_ci static char buf[1000]; 124bf215546Sopenharmony_ci snprintf(buf, sizeof(buf), "zink (%s)", screen->info.props.deviceName); 125bf215546Sopenharmony_ci return buf; 126bf215546Sopenharmony_ci} 127bf215546Sopenharmony_ci 128bf215546Sopenharmony_cistatic void 129bf215546Sopenharmony_cizink_get_driver_uuid(struct pipe_screen *pscreen, char *uuid) 130bf215546Sopenharmony_ci{ 131bf215546Sopenharmony_ci struct zink_screen *screen = zink_screen(pscreen); 132bf215546Sopenharmony_ci if (screen->vk_version >= VK_MAKE_VERSION(1,2,0)) { 133bf215546Sopenharmony_ci memcpy(uuid, screen->info.props11.driverUUID, VK_UUID_SIZE); 134bf215546Sopenharmony_ci } else { 135bf215546Sopenharmony_ci memcpy(uuid, screen->info.deviceid_props.driverUUID, VK_UUID_SIZE); 136bf215546Sopenharmony_ci } 137bf215546Sopenharmony_ci} 138bf215546Sopenharmony_ci 139bf215546Sopenharmony_cistatic void 140bf215546Sopenharmony_cizink_get_device_uuid(struct pipe_screen *pscreen, char *uuid) 141bf215546Sopenharmony_ci{ 142bf215546Sopenharmony_ci struct zink_screen *screen = zink_screen(pscreen); 143bf215546Sopenharmony_ci if (screen->vk_version >= VK_MAKE_VERSION(1,2,0)) { 144bf215546Sopenharmony_ci memcpy(uuid, screen->info.props11.deviceUUID, VK_UUID_SIZE); 145bf215546Sopenharmony_ci } else { 146bf215546Sopenharmony_ci memcpy(uuid, screen->info.deviceid_props.deviceUUID, VK_UUID_SIZE); 147bf215546Sopenharmony_ci } 148bf215546Sopenharmony_ci} 149bf215546Sopenharmony_ci 150bf215546Sopenharmony_cistatic void 151bf215546Sopenharmony_cizink_get_device_luid(struct pipe_screen *pscreen, char *luid) 152bf215546Sopenharmony_ci{ 153bf215546Sopenharmony_ci struct zink_screen *screen = zink_screen(pscreen); 154bf215546Sopenharmony_ci if (screen->info.have_vulkan12) { 155bf215546Sopenharmony_ci memcpy(luid, screen->info.props11.deviceLUID, VK_LUID_SIZE); 156bf215546Sopenharmony_ci } else { 157bf215546Sopenharmony_ci memcpy(luid, screen->info.deviceid_props.deviceLUID, VK_LUID_SIZE); 158bf215546Sopenharmony_ci } 159bf215546Sopenharmony_ci} 160bf215546Sopenharmony_ci 161bf215546Sopenharmony_cistatic uint32_t 162bf215546Sopenharmony_cizink_get_device_node_mask(struct pipe_screen *pscreen) 163bf215546Sopenharmony_ci{ 164bf215546Sopenharmony_ci struct zink_screen *screen = zink_screen(pscreen); 165bf215546Sopenharmony_ci if (screen->info.have_vulkan12) { 166bf215546Sopenharmony_ci return screen->info.props11.deviceNodeMask; 167bf215546Sopenharmony_ci } else { 168bf215546Sopenharmony_ci return screen->info.deviceid_props.deviceNodeMask; 169bf215546Sopenharmony_ci } 170bf215546Sopenharmony_ci} 171bf215546Sopenharmony_ci 172bf215546Sopenharmony_cistatic VkDeviceSize 173bf215546Sopenharmony_ciget_video_mem(struct zink_screen *screen) 174bf215546Sopenharmony_ci{ 175bf215546Sopenharmony_ci VkDeviceSize size = 0; 176bf215546Sopenharmony_ci for (uint32_t i = 0; i < screen->info.mem_props.memoryHeapCount; ++i) { 177bf215546Sopenharmony_ci if (screen->info.mem_props.memoryHeaps[i].flags & 178bf215546Sopenharmony_ci VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) 179bf215546Sopenharmony_ci size += screen->info.mem_props.memoryHeaps[i].size; 180bf215546Sopenharmony_ci } 181bf215546Sopenharmony_ci return size; 182bf215546Sopenharmony_ci} 183bf215546Sopenharmony_ci 184bf215546Sopenharmony_cistatic bool 185bf215546Sopenharmony_cidisk_cache_init(struct zink_screen *screen) 186bf215546Sopenharmony_ci{ 187bf215546Sopenharmony_ci#ifdef ENABLE_SHADER_CACHE 188bf215546Sopenharmony_ci static char buf[1000]; 189bf215546Sopenharmony_ci snprintf(buf, sizeof(buf), "zink_%x04x", screen->info.props.vendorID); 190bf215546Sopenharmony_ci 191bf215546Sopenharmony_ci screen->disk_cache = disk_cache_create(buf, screen->info.props.deviceName, 0); 192bf215546Sopenharmony_ci if (!screen->disk_cache) 193bf215546Sopenharmony_ci return true; 194bf215546Sopenharmony_ci 195bf215546Sopenharmony_ci if (!util_queue_init(&screen->cache_put_thread, "zcq", 8, 1, UTIL_QUEUE_INIT_RESIZE_IF_FULL, screen) || 196bf215546Sopenharmony_ci !util_queue_init(&screen->cache_get_thread, "zcfq", 8, 4, 197bf215546Sopenharmony_ci UTIL_QUEUE_INIT_RESIZE_IF_FULL | UTIL_QUEUE_INIT_SCALE_THREADS, screen)) { 198bf215546Sopenharmony_ci mesa_loge("zink: Failed to create disk cache queue\n"); 199bf215546Sopenharmony_ci 200bf215546Sopenharmony_ci disk_cache_destroy(screen->disk_cache); 201bf215546Sopenharmony_ci screen->disk_cache = NULL; 202bf215546Sopenharmony_ci 203bf215546Sopenharmony_ci util_queue_destroy(&screen->cache_put_thread); 204bf215546Sopenharmony_ci util_queue_destroy(&screen->cache_get_thread); 205bf215546Sopenharmony_ci 206bf215546Sopenharmony_ci return false; 207bf215546Sopenharmony_ci } 208bf215546Sopenharmony_ci#endif 209bf215546Sopenharmony_ci 210bf215546Sopenharmony_ci return true; 211bf215546Sopenharmony_ci} 212bf215546Sopenharmony_ci 213bf215546Sopenharmony_ci 214bf215546Sopenharmony_cistatic void 215bf215546Sopenharmony_cicache_put_job(void *data, void *gdata, int thread_index) 216bf215546Sopenharmony_ci{ 217bf215546Sopenharmony_ci struct zink_program *pg = data; 218bf215546Sopenharmony_ci struct zink_screen *screen = gdata; 219bf215546Sopenharmony_ci size_t size = 0; 220bf215546Sopenharmony_ci VkResult result = VKSCR(GetPipelineCacheData)(screen->dev, pg->pipeline_cache, &size, NULL); 221bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 222bf215546Sopenharmony_ci mesa_loge("ZINK: vkGetPipelineCacheData failed (%s)", vk_Result_to_str(result)); 223bf215546Sopenharmony_ci return; 224bf215546Sopenharmony_ci } 225bf215546Sopenharmony_ci if (pg->pipeline_cache_size == size) 226bf215546Sopenharmony_ci return; 227bf215546Sopenharmony_ci void *pipeline_data = malloc(size); 228bf215546Sopenharmony_ci if (!pipeline_data) 229bf215546Sopenharmony_ci return; 230bf215546Sopenharmony_ci result = VKSCR(GetPipelineCacheData)(screen->dev, pg->pipeline_cache, &size, pipeline_data); 231bf215546Sopenharmony_ci if (result == VK_SUCCESS) { 232bf215546Sopenharmony_ci pg->pipeline_cache_size = size; 233bf215546Sopenharmony_ci 234bf215546Sopenharmony_ci cache_key key; 235bf215546Sopenharmony_ci disk_cache_compute_key(screen->disk_cache, pg->sha1, sizeof(pg->sha1), key); 236bf215546Sopenharmony_ci disk_cache_put_nocopy(screen->disk_cache, key, pipeline_data, size, NULL); 237bf215546Sopenharmony_ci } else { 238bf215546Sopenharmony_ci mesa_loge("ZINK: vkGetPipelineCacheData failed (%s)", vk_Result_to_str(result)); 239bf215546Sopenharmony_ci } 240bf215546Sopenharmony_ci} 241bf215546Sopenharmony_ci 242bf215546Sopenharmony_civoid 243bf215546Sopenharmony_cizink_screen_update_pipeline_cache(struct zink_screen *screen, struct zink_program *pg) 244bf215546Sopenharmony_ci{ 245bf215546Sopenharmony_ci if (!screen->disk_cache) 246bf215546Sopenharmony_ci return; 247bf215546Sopenharmony_ci 248bf215546Sopenharmony_ci util_queue_add_job(&screen->cache_put_thread, pg, &pg->cache_fence, cache_put_job, NULL, 0); 249bf215546Sopenharmony_ci} 250bf215546Sopenharmony_ci 251bf215546Sopenharmony_cistatic void 252bf215546Sopenharmony_cicache_get_job(void *data, void *gdata, int thread_index) 253bf215546Sopenharmony_ci{ 254bf215546Sopenharmony_ci struct zink_program *pg = data; 255bf215546Sopenharmony_ci struct zink_screen *screen = gdata; 256bf215546Sopenharmony_ci 257bf215546Sopenharmony_ci VkPipelineCacheCreateInfo pcci; 258bf215546Sopenharmony_ci pcci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; 259bf215546Sopenharmony_ci pcci.pNext = NULL; 260bf215546Sopenharmony_ci pcci.flags = screen->info.have_EXT_pipeline_creation_cache_control ? VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT : 0; 261bf215546Sopenharmony_ci pcci.initialDataSize = 0; 262bf215546Sopenharmony_ci pcci.pInitialData = NULL; 263bf215546Sopenharmony_ci 264bf215546Sopenharmony_ci cache_key key; 265bf215546Sopenharmony_ci disk_cache_compute_key(screen->disk_cache, pg->sha1, sizeof(pg->sha1), key); 266bf215546Sopenharmony_ci pcci.pInitialData = disk_cache_get(screen->disk_cache, key, &pg->pipeline_cache_size); 267bf215546Sopenharmony_ci pcci.initialDataSize = pg->pipeline_cache_size; 268bf215546Sopenharmony_ci 269bf215546Sopenharmony_ci VkResult res = VKSCR(CreatePipelineCache)(screen->dev, &pcci, NULL, &pg->pipeline_cache); 270bf215546Sopenharmony_ci if (res != VK_SUCCESS) { 271bf215546Sopenharmony_ci mesa_loge("ZINK: vkCreatePipelineCache failed (%s)", vk_Result_to_str(res)); 272bf215546Sopenharmony_ci } 273bf215546Sopenharmony_ci free((void*)pcci.pInitialData); 274bf215546Sopenharmony_ci} 275bf215546Sopenharmony_ci 276bf215546Sopenharmony_civoid 277bf215546Sopenharmony_cizink_screen_get_pipeline_cache(struct zink_screen *screen, struct zink_program *pg) 278bf215546Sopenharmony_ci{ 279bf215546Sopenharmony_ci if (!screen->disk_cache) 280bf215546Sopenharmony_ci return; 281bf215546Sopenharmony_ci 282bf215546Sopenharmony_ci util_queue_add_job(&screen->cache_get_thread, pg, &pg->cache_fence, cache_get_job, NULL, 0); 283bf215546Sopenharmony_ci} 284bf215546Sopenharmony_ci 285bf215546Sopenharmony_cistatic int 286bf215546Sopenharmony_cizink_get_compute_param(struct pipe_screen *pscreen, enum pipe_shader_ir ir_type, 287bf215546Sopenharmony_ci enum pipe_compute_cap param, void *ret) 288bf215546Sopenharmony_ci{ 289bf215546Sopenharmony_ci struct zink_screen *screen = zink_screen(pscreen); 290bf215546Sopenharmony_ci#define RET(x) do { \ 291bf215546Sopenharmony_ci if (ret) \ 292bf215546Sopenharmony_ci memcpy(ret, x, sizeof(x)); \ 293bf215546Sopenharmony_ci return sizeof(x); \ 294bf215546Sopenharmony_ci} while (0) 295bf215546Sopenharmony_ci 296bf215546Sopenharmony_ci switch (param) { 297bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_ADDRESS_BITS: 298bf215546Sopenharmony_ci RET((uint32_t []){ 32 }); 299bf215546Sopenharmony_ci 300bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_IR_TARGET: 301bf215546Sopenharmony_ci if (ret) 302bf215546Sopenharmony_ci strcpy(ret, "nir"); 303bf215546Sopenharmony_ci return 4; 304bf215546Sopenharmony_ci 305bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_GRID_DIMENSION: 306bf215546Sopenharmony_ci RET((uint64_t []) { 3 }); 307bf215546Sopenharmony_ci 308bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_GRID_SIZE: 309bf215546Sopenharmony_ci RET(((uint64_t []) { screen->info.props.limits.maxComputeWorkGroupCount[0], 310bf215546Sopenharmony_ci screen->info.props.limits.maxComputeWorkGroupCount[1], 311bf215546Sopenharmony_ci screen->info.props.limits.maxComputeWorkGroupCount[2] })); 312bf215546Sopenharmony_ci 313bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE: 314bf215546Sopenharmony_ci /* MaxComputeWorkGroupSize[0..2] */ 315bf215546Sopenharmony_ci RET(((uint64_t []) {screen->info.props.limits.maxComputeWorkGroupSize[0], 316bf215546Sopenharmony_ci screen->info.props.limits.maxComputeWorkGroupSize[1], 317bf215546Sopenharmony_ci screen->info.props.limits.maxComputeWorkGroupSize[2]})); 318bf215546Sopenharmony_ci 319bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK: 320bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_VARIABLE_THREADS_PER_BLOCK: 321bf215546Sopenharmony_ci RET((uint64_t []) { screen->info.props.limits.maxComputeWorkGroupInvocations }); 322bf215546Sopenharmony_ci 323bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_LOCAL_SIZE: 324bf215546Sopenharmony_ci RET((uint64_t []) { screen->info.props.limits.maxComputeSharedMemorySize }); 325bf215546Sopenharmony_ci 326bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_IMAGES_SUPPORTED: 327bf215546Sopenharmony_ci RET((uint32_t []) { 1 }); 328bf215546Sopenharmony_ci 329bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_SUBGROUP_SIZE: 330bf215546Sopenharmony_ci RET((uint32_t []) { screen->info.props11.subgroupSize }); 331bf215546Sopenharmony_ci 332bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_MEM_ALLOC_SIZE: 333bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_CLOCK_FREQUENCY: 334bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_COMPUTE_UNITS: 335bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_GLOBAL_SIZE: 336bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_PRIVATE_SIZE: 337bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_INPUT_SIZE: 338bf215546Sopenharmony_ci // XXX: I think these are for Clover... 339bf215546Sopenharmony_ci return 0; 340bf215546Sopenharmony_ci 341bf215546Sopenharmony_ci default: 342bf215546Sopenharmony_ci unreachable("unknown compute param"); 343bf215546Sopenharmony_ci } 344bf215546Sopenharmony_ci} 345bf215546Sopenharmony_ci 346bf215546Sopenharmony_cistatic uint32_t 347bf215546Sopenharmony_ciget_smallest_buffer_heap(struct zink_screen *screen) 348bf215546Sopenharmony_ci{ 349bf215546Sopenharmony_ci enum zink_heap heaps[] = { 350bf215546Sopenharmony_ci ZINK_HEAP_DEVICE_LOCAL, 351bf215546Sopenharmony_ci ZINK_HEAP_DEVICE_LOCAL_VISIBLE, 352bf215546Sopenharmony_ci ZINK_HEAP_HOST_VISIBLE_COHERENT, 353bf215546Sopenharmony_ci ZINK_HEAP_HOST_VISIBLE_COHERENT 354bf215546Sopenharmony_ci }; 355bf215546Sopenharmony_ci unsigned size = UINT32_MAX; 356bf215546Sopenharmony_ci for (unsigned i = 0; i < ARRAY_SIZE(heaps); i++) { 357bf215546Sopenharmony_ci unsigned heap_idx = screen->info.mem_props.memoryTypes[screen->heap_map[i]].heapIndex; 358bf215546Sopenharmony_ci size = MIN2(screen->info.mem_props.memoryHeaps[heap_idx].size, size); 359bf215546Sopenharmony_ci } 360bf215546Sopenharmony_ci return size; 361bf215546Sopenharmony_ci} 362bf215546Sopenharmony_ci 363bf215546Sopenharmony_cistatic int 364bf215546Sopenharmony_cizink_get_param(struct pipe_screen *pscreen, enum pipe_cap param) 365bf215546Sopenharmony_ci{ 366bf215546Sopenharmony_ci struct zink_screen *screen = zink_screen(pscreen); 367bf215546Sopenharmony_ci 368bf215546Sopenharmony_ci switch (param) { 369bf215546Sopenharmony_ci case PIPE_CAP_TEXRECT: 370bf215546Sopenharmony_ci case PIPE_CAP_MULTI_DRAW_INDIRECT_PARTIAL_STRIDE: 371bf215546Sopenharmony_ci return 0; 372bf215546Sopenharmony_ci case PIPE_CAP_ANISOTROPIC_FILTER: 373bf215546Sopenharmony_ci return screen->info.feats.features.samplerAnisotropy; 374bf215546Sopenharmony_ci case PIPE_CAP_EMULATE_NONFIXED_PRIMITIVE_RESTART: 375bf215546Sopenharmony_ci return 1; 376bf215546Sopenharmony_ci case PIPE_CAP_SUPPORTED_PRIM_MODES_WITH_RESTART: { 377bf215546Sopenharmony_ci uint32_t modes = BITFIELD_BIT(PIPE_PRIM_LINE_STRIP) | 378bf215546Sopenharmony_ci BITFIELD_BIT(PIPE_PRIM_TRIANGLE_STRIP) | 379bf215546Sopenharmony_ci BITFIELD_BIT(PIPE_PRIM_LINE_STRIP_ADJACENCY) | 380bf215546Sopenharmony_ci BITFIELD_BIT(PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY); 381bf215546Sopenharmony_ci if (screen->have_triangle_fans) 382bf215546Sopenharmony_ci modes |= BITFIELD_BIT(PIPE_PRIM_TRIANGLE_FAN); 383bf215546Sopenharmony_ci if (screen->info.have_EXT_primitive_topology_list_restart) { 384bf215546Sopenharmony_ci modes |= BITFIELD_BIT(PIPE_PRIM_POINTS) | 385bf215546Sopenharmony_ci BITFIELD_BIT(PIPE_PRIM_LINES) | 386bf215546Sopenharmony_ci BITFIELD_BIT(PIPE_PRIM_LINES_ADJACENCY) | 387bf215546Sopenharmony_ci BITFIELD_BIT(PIPE_PRIM_TRIANGLES) | 388bf215546Sopenharmony_ci BITFIELD_BIT(PIPE_PRIM_TRIANGLES_ADJACENCY); 389bf215546Sopenharmony_ci if (screen->info.list_restart_feats.primitiveTopologyPatchListRestart) 390bf215546Sopenharmony_ci modes |= BITFIELD_BIT(PIPE_PRIM_PATCHES); 391bf215546Sopenharmony_ci } 392bf215546Sopenharmony_ci return modes; 393bf215546Sopenharmony_ci } 394bf215546Sopenharmony_ci case PIPE_CAP_SUPPORTED_PRIM_MODES: { 395bf215546Sopenharmony_ci uint32_t modes = BITFIELD_MASK(PIPE_PRIM_MAX); 396bf215546Sopenharmony_ci modes &= ~BITFIELD_BIT(PIPE_PRIM_QUADS); 397bf215546Sopenharmony_ci modes &= ~BITFIELD_BIT(PIPE_PRIM_QUAD_STRIP); 398bf215546Sopenharmony_ci modes &= ~BITFIELD_BIT(PIPE_PRIM_POLYGON); 399bf215546Sopenharmony_ci modes &= ~BITFIELD_BIT(PIPE_PRIM_LINE_LOOP); 400bf215546Sopenharmony_ci if (!screen->have_triangle_fans) 401bf215546Sopenharmony_ci modes &= ~BITFIELD_BIT(PIPE_PRIM_TRIANGLE_FAN); 402bf215546Sopenharmony_ci return modes; 403bf215546Sopenharmony_ci } 404bf215546Sopenharmony_ci 405bf215546Sopenharmony_ci case PIPE_CAP_FBFETCH: 406bf215546Sopenharmony_ci return 1; 407bf215546Sopenharmony_ci 408bf215546Sopenharmony_ci case PIPE_CAP_MEMOBJ: 409bf215546Sopenharmony_ci return screen->instance_info.have_KHR_external_memory_capabilities && (screen->info.have_KHR_external_memory_fd || screen->info.have_KHR_external_memory_win32); 410bf215546Sopenharmony_ci case PIPE_CAP_FENCE_SIGNAL: 411bf215546Sopenharmony_ci return screen->info.have_KHR_external_semaphore_fd || screen->info.have_KHR_external_semaphore_win32; 412bf215546Sopenharmony_ci 413bf215546Sopenharmony_ci case PIPE_CAP_DEVICE_RESET_STATUS_QUERY: 414bf215546Sopenharmony_ci case PIPE_CAP_QUERY_MEMORY_INFO: 415bf215546Sopenharmony_ci case PIPE_CAP_NPOT_TEXTURES: 416bf215546Sopenharmony_ci case PIPE_CAP_TGSI_TEXCOORD: 417bf215546Sopenharmony_ci case PIPE_CAP_DRAW_INDIRECT: 418bf215546Sopenharmony_ci case PIPE_CAP_TEXTURE_QUERY_LOD: 419bf215546Sopenharmony_ci case PIPE_CAP_GLSL_TESS_LEVELS_AS_INPUTS: 420bf215546Sopenharmony_ci case PIPE_CAP_CLEAR_TEXTURE: 421bf215546Sopenharmony_ci case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS: 422bf215546Sopenharmony_ci case PIPE_CAP_FORCE_PERSAMPLE_INTERP: 423bf215546Sopenharmony_ci case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT: 424bf215546Sopenharmony_ci case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT: 425bf215546Sopenharmony_ci case PIPE_CAP_SHADER_ARRAY_COMPONENTS: 426bf215546Sopenharmony_ci case PIPE_CAP_QUERY_BUFFER_OBJECT: 427bf215546Sopenharmony_ci case PIPE_CAP_CONDITIONAL_RENDER_INVERTED: 428bf215546Sopenharmony_ci case PIPE_CAP_CLIP_HALFZ: 429bf215546Sopenharmony_ci case PIPE_CAP_TEXTURE_QUERY_SAMPLES: 430bf215546Sopenharmony_ci case PIPE_CAP_TEXTURE_BARRIER: 431bf215546Sopenharmony_ci case PIPE_CAP_QUERY_SO_OVERFLOW: 432bf215546Sopenharmony_ci case PIPE_CAP_GL_SPIRV: 433bf215546Sopenharmony_ci case PIPE_CAP_CLEAR_SCISSORED: 434bf215546Sopenharmony_ci case PIPE_CAP_INVALIDATE_BUFFER: 435bf215546Sopenharmony_ci case PIPE_CAP_PREFER_REAL_BUFFER_IN_CONSTBUF0: 436bf215546Sopenharmony_ci case PIPE_CAP_PACKED_UNIFORMS: 437bf215546Sopenharmony_ci case PIPE_CAP_SHADER_PACK_HALF_FLOAT: 438bf215546Sopenharmony_ci case PIPE_CAP_CULL_DISTANCE_NOCOMBINE: 439bf215546Sopenharmony_ci case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: 440bf215546Sopenharmony_ci case PIPE_CAP_LOAD_CONSTBUF: 441bf215546Sopenharmony_ci return 1; 442bf215546Sopenharmony_ci 443bf215546Sopenharmony_ci case PIPE_CAP_DRAW_VERTEX_STATE: 444bf215546Sopenharmony_ci return screen->info.have_EXT_vertex_input_dynamic_state; 445bf215546Sopenharmony_ci 446bf215546Sopenharmony_ci case PIPE_CAP_SURFACE_SAMPLE_COUNT: 447bf215546Sopenharmony_ci return screen->vk_version >= VK_MAKE_VERSION(1,2,0); 448bf215546Sopenharmony_ci 449bf215546Sopenharmony_ci case PIPE_CAP_DRAW_PARAMETERS: 450bf215546Sopenharmony_ci return screen->info.feats11.shaderDrawParameters || screen->info.have_KHR_shader_draw_parameters; 451bf215546Sopenharmony_ci 452bf215546Sopenharmony_ci case PIPE_CAP_SHADER_GROUP_VOTE: 453bf215546Sopenharmony_ci if (screen->info.have_vulkan11 && 454bf215546Sopenharmony_ci (screen->info.subgroup.supportedOperations & VK_SUBGROUP_FEATURE_VOTE_BIT) && 455bf215546Sopenharmony_ci (screen->info.subgroup.supportedStages & VK_SHADER_STAGE_COMPUTE_BIT)) 456bf215546Sopenharmony_ci return true; 457bf215546Sopenharmony_ci if (screen->info.have_EXT_shader_subgroup_vote) 458bf215546Sopenharmony_ci return true; 459bf215546Sopenharmony_ci return false; 460bf215546Sopenharmony_ci case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION: 461bf215546Sopenharmony_ci return screen->info.have_EXT_provoking_vertex; 462bf215546Sopenharmony_ci 463bf215546Sopenharmony_ci case PIPE_CAP_TEXTURE_MIRROR_CLAMP_TO_EDGE: 464bf215546Sopenharmony_ci return screen->info.have_KHR_sampler_mirror_clamp_to_edge; 465bf215546Sopenharmony_ci 466bf215546Sopenharmony_ci case PIPE_CAP_POLYGON_OFFSET_UNITS_UNSCALED: 467bf215546Sopenharmony_ci return 1; 468bf215546Sopenharmony_ci 469bf215546Sopenharmony_ci case PIPE_CAP_POLYGON_OFFSET_CLAMP: 470bf215546Sopenharmony_ci return screen->info.feats.features.depthBiasClamp; 471bf215546Sopenharmony_ci 472bf215546Sopenharmony_ci case PIPE_CAP_QUERY_PIPELINE_STATISTICS_SINGLE: 473bf215546Sopenharmony_ci return screen->info.feats.features.pipelineStatisticsQuery; 474bf215546Sopenharmony_ci 475bf215546Sopenharmony_ci case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR: 476bf215546Sopenharmony_ci return screen->info.feats.features.robustBufferAccess; 477bf215546Sopenharmony_ci 478bf215546Sopenharmony_ci case PIPE_CAP_MULTI_DRAW_INDIRECT: 479bf215546Sopenharmony_ci return screen->info.feats.features.multiDrawIndirect; 480bf215546Sopenharmony_ci 481bf215546Sopenharmony_ci case PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS: 482bf215546Sopenharmony_ci return screen->info.have_KHR_draw_indirect_count; 483bf215546Sopenharmony_ci 484bf215546Sopenharmony_ci case PIPE_CAP_START_INSTANCE: 485bf215546Sopenharmony_ci return (screen->info.have_vulkan12 && screen->info.feats11.shaderDrawParameters) || 486bf215546Sopenharmony_ci screen->info.have_KHR_shader_draw_parameters; 487bf215546Sopenharmony_ci 488bf215546Sopenharmony_ci case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: 489bf215546Sopenharmony_ci return screen->info.have_EXT_vertex_attribute_divisor; 490bf215546Sopenharmony_ci 491bf215546Sopenharmony_ci case PIPE_CAP_MAX_VERTEX_STREAMS: 492bf215546Sopenharmony_ci return screen->info.tf_props.maxTransformFeedbackStreams; 493bf215546Sopenharmony_ci 494bf215546Sopenharmony_ci case PIPE_CAP_INT64: 495bf215546Sopenharmony_ci case PIPE_CAP_INT64_DIVMOD: 496bf215546Sopenharmony_ci case PIPE_CAP_DOUBLES: 497bf215546Sopenharmony_ci return 1; 498bf215546Sopenharmony_ci 499bf215546Sopenharmony_ci case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS: 500bf215546Sopenharmony_ci if (!screen->info.feats.features.dualSrcBlend) 501bf215546Sopenharmony_ci return 0; 502bf215546Sopenharmony_ci return screen->info.props.limits.maxFragmentDualSrcAttachments; 503bf215546Sopenharmony_ci 504bf215546Sopenharmony_ci case PIPE_CAP_MAX_RENDER_TARGETS: 505bf215546Sopenharmony_ci return screen->info.props.limits.maxColorAttachments; 506bf215546Sopenharmony_ci 507bf215546Sopenharmony_ci case PIPE_CAP_OCCLUSION_QUERY: 508bf215546Sopenharmony_ci return screen->info.feats.features.occlusionQueryPrecise; 509bf215546Sopenharmony_ci 510bf215546Sopenharmony_ci case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS: 511bf215546Sopenharmony_ci return screen->info.have_EXT_sample_locations && screen->info.have_EXT_extended_dynamic_state; 512bf215546Sopenharmony_ci 513bf215546Sopenharmony_ci case PIPE_CAP_QUERY_TIME_ELAPSED: 514bf215546Sopenharmony_ci return screen->timestamp_valid_bits > 0; 515bf215546Sopenharmony_ci 516bf215546Sopenharmony_ci case PIPE_CAP_TEXTURE_MULTISAMPLE: 517bf215546Sopenharmony_ci return 1; 518bf215546Sopenharmony_ci 519bf215546Sopenharmony_ci case PIPE_CAP_FRAGMENT_SHADER_INTERLOCK: 520bf215546Sopenharmony_ci return screen->info.have_EXT_fragment_shader_interlock; 521bf215546Sopenharmony_ci 522bf215546Sopenharmony_ci case PIPE_CAP_SHADER_CLOCK: 523bf215546Sopenharmony_ci return screen->info.have_KHR_shader_clock; 524bf215546Sopenharmony_ci 525bf215546Sopenharmony_ci case PIPE_CAP_POINT_SPRITE: 526bf215546Sopenharmony_ci return 1; 527bf215546Sopenharmony_ci 528bf215546Sopenharmony_ci case PIPE_CAP_SHADER_BALLOT: 529bf215546Sopenharmony_ci if (screen->info.props11.subgroupSize > 64) 530bf215546Sopenharmony_ci return false; 531bf215546Sopenharmony_ci if (screen->info.have_vulkan11 && 532bf215546Sopenharmony_ci screen->info.subgroup.supportedOperations & VK_SUBGROUP_FEATURE_BALLOT_BIT) 533bf215546Sopenharmony_ci return true; 534bf215546Sopenharmony_ci if (screen->info.have_EXT_shader_subgroup_ballot) 535bf215546Sopenharmony_ci return true; 536bf215546Sopenharmony_ci return false; 537bf215546Sopenharmony_ci case PIPE_CAP_SAMPLE_SHADING: 538bf215546Sopenharmony_ci return screen->info.feats.features.sampleRateShading; 539bf215546Sopenharmony_ci 540bf215546Sopenharmony_ci case PIPE_CAP_TEXTURE_SWIZZLE: 541bf215546Sopenharmony_ci return 1; 542bf215546Sopenharmony_ci 543bf215546Sopenharmony_ci case PIPE_CAP_VERTEX_ATTRIB_ELEMENT_ALIGNED_ONLY: 544bf215546Sopenharmony_ci return 1; 545bf215546Sopenharmony_ci 546bf215546Sopenharmony_ci case PIPE_CAP_GL_CLAMP: 547bf215546Sopenharmony_ci return 0; 548bf215546Sopenharmony_ci 549bf215546Sopenharmony_ci case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK: 550bf215546Sopenharmony_ci if (!screen->info.border_color_feats.customBorderColorWithoutFormat) 551bf215546Sopenharmony_ci return PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_FREEDRENO; 552bf215546Sopenharmony_ci /* assume that if drivers don't implement this extension they either: 553bf215546Sopenharmony_ci * - don't support custom border colors 554bf215546Sopenharmony_ci * - handle things correctly 555bf215546Sopenharmony_ci * - hate border color accuracy 556bf215546Sopenharmony_ci */ 557bf215546Sopenharmony_ci if (screen->info.have_EXT_border_color_swizzle && 558bf215546Sopenharmony_ci !screen->info.border_swizzle_feats.borderColorSwizzleFromImage) 559bf215546Sopenharmony_ci return PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50; 560bf215546Sopenharmony_ci return 0; 561bf215546Sopenharmony_ci 562bf215546Sopenharmony_ci case PIPE_CAP_MAX_TEXTURE_2D_SIZE: 563bf215546Sopenharmony_ci return screen->info.props.limits.maxImageDimension2D; 564bf215546Sopenharmony_ci case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: 565bf215546Sopenharmony_ci return 1 + util_logbase2(screen->info.props.limits.maxImageDimension3D); 566bf215546Sopenharmony_ci case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: 567bf215546Sopenharmony_ci return 1 + util_logbase2(screen->info.props.limits.maxImageDimensionCube); 568bf215546Sopenharmony_ci 569bf215546Sopenharmony_ci case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD: 570bf215546Sopenharmony_ci case PIPE_CAP_FRAGMENT_SHADER_DERIVATIVES: 571bf215546Sopenharmony_ci return 1; 572bf215546Sopenharmony_ci 573bf215546Sopenharmony_ci case PIPE_CAP_BLEND_EQUATION_SEPARATE: 574bf215546Sopenharmony_ci case PIPE_CAP_INDEP_BLEND_ENABLE: 575bf215546Sopenharmony_ci case PIPE_CAP_INDEP_BLEND_FUNC: 576bf215546Sopenharmony_ci return screen->info.feats.features.independentBlend; 577bf215546Sopenharmony_ci 578bf215546Sopenharmony_ci case PIPE_CAP_DITHERING: 579bf215546Sopenharmony_ci return 0; 580bf215546Sopenharmony_ci 581bf215546Sopenharmony_ci case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS: 582bf215546Sopenharmony_ci return screen->info.have_EXT_transform_feedback ? screen->info.tf_props.maxTransformFeedbackBuffers : 0; 583bf215546Sopenharmony_ci case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME: 584bf215546Sopenharmony_ci case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS: 585bf215546Sopenharmony_ci return screen->info.have_EXT_transform_feedback; 586bf215546Sopenharmony_ci 587bf215546Sopenharmony_ci case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS: 588bf215546Sopenharmony_ci return screen->info.props.limits.maxImageArrayLayers; 589bf215546Sopenharmony_ci 590bf215546Sopenharmony_ci case PIPE_CAP_DEPTH_CLIP_DISABLE: 591bf215546Sopenharmony_ci return !screen->driver_workarounds.depth_clip_control_missing; 592bf215546Sopenharmony_ci 593bf215546Sopenharmony_ci case PIPE_CAP_SHADER_STENCIL_EXPORT: 594bf215546Sopenharmony_ci return screen->info.have_EXT_shader_stencil_export; 595bf215546Sopenharmony_ci 596bf215546Sopenharmony_ci case PIPE_CAP_VS_INSTANCEID: 597bf215546Sopenharmony_ci case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: 598bf215546Sopenharmony_ci case PIPE_CAP_SEAMLESS_CUBE_MAP: 599bf215546Sopenharmony_ci return 1; 600bf215546Sopenharmony_ci 601bf215546Sopenharmony_ci case PIPE_CAP_MIN_TEXEL_OFFSET: 602bf215546Sopenharmony_ci return screen->info.props.limits.minTexelOffset; 603bf215546Sopenharmony_ci case PIPE_CAP_MAX_TEXEL_OFFSET: 604bf215546Sopenharmony_ci return screen->info.props.limits.maxTexelOffset; 605bf215546Sopenharmony_ci 606bf215546Sopenharmony_ci case PIPE_CAP_VERTEX_COLOR_UNCLAMPED: 607bf215546Sopenharmony_ci return 1; 608bf215546Sopenharmony_ci 609bf215546Sopenharmony_ci case PIPE_CAP_CONDITIONAL_RENDER: 610bf215546Sopenharmony_ci return 1; 611bf215546Sopenharmony_ci 612bf215546Sopenharmony_ci case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY: 613bf215546Sopenharmony_ci case PIPE_CAP_GLSL_FEATURE_LEVEL: 614bf215546Sopenharmony_ci return 460; 615bf215546Sopenharmony_ci 616bf215546Sopenharmony_ci case PIPE_CAP_COMPUTE: 617bf215546Sopenharmony_ci return 1; 618bf215546Sopenharmony_ci 619bf215546Sopenharmony_ci case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: 620bf215546Sopenharmony_ci return screen->info.props.limits.minUniformBufferOffsetAlignment; 621bf215546Sopenharmony_ci 622bf215546Sopenharmony_ci case PIPE_CAP_QUERY_TIMESTAMP: 623bf215546Sopenharmony_ci return screen->timestamp_valid_bits > 0; 624bf215546Sopenharmony_ci 625bf215546Sopenharmony_ci case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT: 626bf215546Sopenharmony_ci return 1 << MIN_SLAB_ORDER; 627bf215546Sopenharmony_ci 628bf215546Sopenharmony_ci case PIPE_CAP_CUBE_MAP_ARRAY: 629bf215546Sopenharmony_ci return screen->info.feats.features.imageCubeArray; 630bf215546Sopenharmony_ci 631bf215546Sopenharmony_ci case PIPE_CAP_TEXTURE_BUFFER_OBJECTS: 632bf215546Sopenharmony_ci case PIPE_CAP_PRIMITIVE_RESTART: 633bf215546Sopenharmony_ci return 1; 634bf215546Sopenharmony_ci 635bf215546Sopenharmony_ci case PIPE_CAP_BINDLESS_TEXTURE: 636bf215546Sopenharmony_ci return screen->info.have_EXT_descriptor_indexing; 637bf215546Sopenharmony_ci 638bf215546Sopenharmony_ci case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT: 639bf215546Sopenharmony_ci return screen->info.props.limits.minTexelBufferOffsetAlignment; 640bf215546Sopenharmony_ci 641bf215546Sopenharmony_ci case PIPE_CAP_TEXTURE_TRANSFER_MODES: { 642bf215546Sopenharmony_ci enum pipe_texture_transfer_mode mode = PIPE_TEXTURE_TRANSFER_BLIT; 643bf215546Sopenharmony_ci if (!screen->is_cpu && 644bf215546Sopenharmony_ci /* this needs substantial perf tuning */ 645bf215546Sopenharmony_ci screen->info.driver_props.driverID != VK_DRIVER_ID_MESA_TURNIP && 646bf215546Sopenharmony_ci screen->info.have_KHR_8bit_storage && 647bf215546Sopenharmony_ci screen->info.have_KHR_16bit_storage && 648bf215546Sopenharmony_ci screen->info.have_KHR_shader_float16_int8) 649bf215546Sopenharmony_ci mode |= PIPE_TEXTURE_TRANSFER_COMPUTE; 650bf215546Sopenharmony_ci return mode; 651bf215546Sopenharmony_ci } 652bf215546Sopenharmony_ci 653bf215546Sopenharmony_ci case PIPE_CAP_MAX_TEXEL_BUFFER_ELEMENTS_UINT: 654bf215546Sopenharmony_ci return MIN2(get_smallest_buffer_heap(screen), 655bf215546Sopenharmony_ci screen->info.props.limits.maxTexelBufferElements); 656bf215546Sopenharmony_ci 657bf215546Sopenharmony_ci case PIPE_CAP_ENDIANNESS: 658bf215546Sopenharmony_ci return PIPE_ENDIAN_NATIVE; /* unsure */ 659bf215546Sopenharmony_ci 660bf215546Sopenharmony_ci case PIPE_CAP_MAX_VIEWPORTS: 661bf215546Sopenharmony_ci return MIN2(screen->info.props.limits.maxViewports, PIPE_MAX_VIEWPORTS); 662bf215546Sopenharmony_ci 663bf215546Sopenharmony_ci case PIPE_CAP_IMAGE_LOAD_FORMATTED: 664bf215546Sopenharmony_ci return screen->info.feats.features.shaderStorageImageReadWithoutFormat; 665bf215546Sopenharmony_ci 666bf215546Sopenharmony_ci case PIPE_CAP_IMAGE_STORE_FORMATTED: 667bf215546Sopenharmony_ci return screen->info.feats.features.shaderStorageImageWriteWithoutFormat; 668bf215546Sopenharmony_ci 669bf215546Sopenharmony_ci case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES: 670bf215546Sopenharmony_ci return 1; 671bf215546Sopenharmony_ci 672bf215546Sopenharmony_ci case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES: 673bf215546Sopenharmony_ci return screen->info.props.limits.maxGeometryOutputVertices; 674bf215546Sopenharmony_ci case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS: 675bf215546Sopenharmony_ci return screen->info.props.limits.maxGeometryTotalOutputComponents; 676bf215546Sopenharmony_ci 677bf215546Sopenharmony_ci case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS: 678bf215546Sopenharmony_ci return 4; 679bf215546Sopenharmony_ci 680bf215546Sopenharmony_ci case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET: 681bf215546Sopenharmony_ci return screen->info.props.limits.minTexelGatherOffset; 682bf215546Sopenharmony_ci case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET: 683bf215546Sopenharmony_ci return screen->info.props.limits.maxTexelGatherOffset; 684bf215546Sopenharmony_ci 685bf215546Sopenharmony_ci case PIPE_CAP_SAMPLER_REDUCTION_MINMAX_ARB: 686bf215546Sopenharmony_ci return screen->info.feats12.samplerFilterMinmax || screen->info.have_EXT_sampler_filter_minmax; 687bf215546Sopenharmony_ci 688bf215546Sopenharmony_ci case PIPE_CAP_FS_FINE_DERIVATIVE: 689bf215546Sopenharmony_ci return 1; 690bf215546Sopenharmony_ci 691bf215546Sopenharmony_ci case PIPE_CAP_VENDOR_ID: 692bf215546Sopenharmony_ci return screen->info.props.vendorID; 693bf215546Sopenharmony_ci case PIPE_CAP_DEVICE_ID: 694bf215546Sopenharmony_ci return screen->info.props.deviceID; 695bf215546Sopenharmony_ci 696bf215546Sopenharmony_ci case PIPE_CAP_ACCELERATED: 697bf215546Sopenharmony_ci return !screen->is_cpu; 698bf215546Sopenharmony_ci case PIPE_CAP_VIDEO_MEMORY: 699bf215546Sopenharmony_ci return get_video_mem(screen) >> 20; 700bf215546Sopenharmony_ci case PIPE_CAP_UMA: 701bf215546Sopenharmony_ci return screen->info.props.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU; 702bf215546Sopenharmony_ci 703bf215546Sopenharmony_ci case PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE: 704bf215546Sopenharmony_ci return screen->info.props.limits.maxVertexInputBindingStride; 705bf215546Sopenharmony_ci 706bf215546Sopenharmony_ci case PIPE_CAP_SAMPLER_VIEW_TARGET: 707bf215546Sopenharmony_ci return 1; 708bf215546Sopenharmony_ci 709bf215546Sopenharmony_ci case PIPE_CAP_VS_LAYER_VIEWPORT: 710bf215546Sopenharmony_ci case PIPE_CAP_TES_LAYER_VIEWPORT: 711bf215546Sopenharmony_ci return screen->info.have_EXT_shader_viewport_index_layer || 712bf215546Sopenharmony_ci (screen->spirv_version >= SPIRV_VERSION(1, 5) && 713bf215546Sopenharmony_ci screen->info.feats12.shaderOutputLayer && 714bf215546Sopenharmony_ci screen->info.feats12.shaderOutputViewportIndex); 715bf215546Sopenharmony_ci 716bf215546Sopenharmony_ci case PIPE_CAP_TEXTURE_FLOAT_LINEAR: 717bf215546Sopenharmony_ci case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR: 718bf215546Sopenharmony_ci return 1; 719bf215546Sopenharmony_ci 720bf215546Sopenharmony_ci case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT: 721bf215546Sopenharmony_ci return screen->info.props.limits.minStorageBufferOffsetAlignment; 722bf215546Sopenharmony_ci 723bf215546Sopenharmony_ci case PIPE_CAP_PCI_GROUP: 724bf215546Sopenharmony_ci case PIPE_CAP_PCI_BUS: 725bf215546Sopenharmony_ci case PIPE_CAP_PCI_DEVICE: 726bf215546Sopenharmony_ci case PIPE_CAP_PCI_FUNCTION: 727bf215546Sopenharmony_ci return 0; /* TODO: figure these out */ 728bf215546Sopenharmony_ci 729bf215546Sopenharmony_ci case PIPE_CAP_CULL_DISTANCE: 730bf215546Sopenharmony_ci return screen->info.feats.features.shaderCullDistance; 731bf215546Sopenharmony_ci 732bf215546Sopenharmony_ci case PIPE_CAP_SPARSE_BUFFER_PAGE_SIZE: 733bf215546Sopenharmony_ci return screen->info.feats.features.sparseBinding ? ZINK_SPARSE_BUFFER_PAGE_SIZE : 0; 734bf215546Sopenharmony_ci 735bf215546Sopenharmony_ci /* Sparse texture */ 736bf215546Sopenharmony_ci case PIPE_CAP_MAX_SPARSE_TEXTURE_SIZE: 737bf215546Sopenharmony_ci return screen->info.feats.features.sparseResidencyImage2D ? 738bf215546Sopenharmony_ci zink_get_param(pscreen, PIPE_CAP_MAX_TEXTURE_2D_SIZE) : 0; 739bf215546Sopenharmony_ci case PIPE_CAP_MAX_SPARSE_3D_TEXTURE_SIZE: 740bf215546Sopenharmony_ci return screen->info.feats.features.sparseResidencyImage3D ? 741bf215546Sopenharmony_ci (1 << (zink_get_param(pscreen, PIPE_CAP_MAX_TEXTURE_3D_LEVELS) - 1)) : 0; 742bf215546Sopenharmony_ci case PIPE_CAP_MAX_SPARSE_ARRAY_TEXTURE_LAYERS: 743bf215546Sopenharmony_ci return screen->info.feats.features.sparseResidencyImage2D ? 744bf215546Sopenharmony_ci zink_get_param(pscreen, PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS) : 0; 745bf215546Sopenharmony_ci case PIPE_CAP_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS: 746bf215546Sopenharmony_ci return screen->info.feats.features.sparseResidencyImage2D ? 1 : 0; 747bf215546Sopenharmony_ci case PIPE_CAP_QUERY_SPARSE_TEXTURE_RESIDENCY: 748bf215546Sopenharmony_ci case PIPE_CAP_CLAMP_SPARSE_TEXTURE_LOD: 749bf215546Sopenharmony_ci return screen->info.feats.features.sparseResidency2Samples ? 1 : 0; 750bf215546Sopenharmony_ci 751bf215546Sopenharmony_ci case PIPE_CAP_VIEWPORT_SUBPIXEL_BITS: 752bf215546Sopenharmony_ci return screen->info.props.limits.viewportSubPixelBits; 753bf215546Sopenharmony_ci 754bf215546Sopenharmony_ci case PIPE_CAP_MAX_GS_INVOCATIONS: 755bf215546Sopenharmony_ci return screen->info.props.limits.maxGeometryShaderInvocations; 756bf215546Sopenharmony_ci 757bf215546Sopenharmony_ci case PIPE_CAP_MAX_COMBINED_SHADER_BUFFERS: 758bf215546Sopenharmony_ci /* gallium handles this automatically */ 759bf215546Sopenharmony_ci return 0; 760bf215546Sopenharmony_ci 761bf215546Sopenharmony_ci case PIPE_CAP_MAX_SHADER_BUFFER_SIZE_UINT: 762bf215546Sopenharmony_ci /* 1<<27 is required by VK spec */ 763bf215546Sopenharmony_ci assert(screen->info.props.limits.maxStorageBufferRange >= 1 << 27); 764bf215546Sopenharmony_ci /* clamp to VK spec minimum */ 765bf215546Sopenharmony_ci return MIN2(get_smallest_buffer_heap(screen), screen->info.props.limits.maxStorageBufferRange); 766bf215546Sopenharmony_ci 767bf215546Sopenharmony_ci case PIPE_CAP_FS_COORD_ORIGIN_UPPER_LEFT: 768bf215546Sopenharmony_ci case PIPE_CAP_FS_COORD_PIXEL_CENTER_HALF_INTEGER: 769bf215546Sopenharmony_ci return 1; 770bf215546Sopenharmony_ci 771bf215546Sopenharmony_ci case PIPE_CAP_FS_COORD_ORIGIN_LOWER_LEFT: 772bf215546Sopenharmony_ci case PIPE_CAP_FS_COORD_PIXEL_CENTER_INTEGER: 773bf215546Sopenharmony_ci return 0; 774bf215546Sopenharmony_ci 775bf215546Sopenharmony_ci case PIPE_CAP_NIR_COMPACT_ARRAYS: 776bf215546Sopenharmony_ci return 1; 777bf215546Sopenharmony_ci 778bf215546Sopenharmony_ci case PIPE_CAP_FS_FACE_IS_INTEGER_SYSVAL: 779bf215546Sopenharmony_ci return 1; 780bf215546Sopenharmony_ci 781bf215546Sopenharmony_ci case PIPE_CAP_VIEWPORT_TRANSFORM_LOWERED: 782bf215546Sopenharmony_ci return 1; 783bf215546Sopenharmony_ci 784bf215546Sopenharmony_ci case PIPE_CAP_FLATSHADE: 785bf215546Sopenharmony_ci case PIPE_CAP_ALPHA_TEST: 786bf215546Sopenharmony_ci case PIPE_CAP_CLIP_PLANES: 787bf215546Sopenharmony_ci case PIPE_CAP_POINT_SIZE_FIXED: 788bf215546Sopenharmony_ci case PIPE_CAP_TWO_SIDED_COLOR: 789bf215546Sopenharmony_ci return 0; 790bf215546Sopenharmony_ci 791bf215546Sopenharmony_ci case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS: 792bf215546Sopenharmony_ci return screen->info.props.limits.maxTessellationControlPerVertexOutputComponents / 4; 793bf215546Sopenharmony_ci case PIPE_CAP_MAX_VARYINGS: 794bf215546Sopenharmony_ci /* need to reserve up to 60 of our varying components and 16 slots for streamout */ 795bf215546Sopenharmony_ci return MIN2(screen->info.props.limits.maxVertexOutputComponents / 4 / 2, 16); 796bf215546Sopenharmony_ci 797bf215546Sopenharmony_ci case PIPE_CAP_DMABUF: 798bf215546Sopenharmony_ci return screen->info.have_KHR_external_memory_fd && 799bf215546Sopenharmony_ci screen->info.have_EXT_external_memory_dma_buf && 800bf215546Sopenharmony_ci screen->info.have_EXT_queue_family_foreign; 801bf215546Sopenharmony_ci 802bf215546Sopenharmony_ci case PIPE_CAP_DEPTH_BOUNDS_TEST: 803bf215546Sopenharmony_ci return screen->info.feats.features.depthBounds; 804bf215546Sopenharmony_ci 805bf215546Sopenharmony_ci case PIPE_CAP_POST_DEPTH_COVERAGE: 806bf215546Sopenharmony_ci return screen->info.have_EXT_post_depth_coverage; 807bf215546Sopenharmony_ci 808bf215546Sopenharmony_ci case PIPE_CAP_STRING_MARKER: 809bf215546Sopenharmony_ci return screen->instance_info.have_EXT_debug_utils; 810bf215546Sopenharmony_ci 811bf215546Sopenharmony_ci default: 812bf215546Sopenharmony_ci return u_pipe_screen_get_param_defaults(pscreen, param); 813bf215546Sopenharmony_ci } 814bf215546Sopenharmony_ci} 815bf215546Sopenharmony_ci 816bf215546Sopenharmony_cistatic float 817bf215546Sopenharmony_cizink_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param) 818bf215546Sopenharmony_ci{ 819bf215546Sopenharmony_ci struct zink_screen *screen = zink_screen(pscreen); 820bf215546Sopenharmony_ci 821bf215546Sopenharmony_ci switch (param) { 822bf215546Sopenharmony_ci case PIPE_CAPF_MIN_LINE_WIDTH: 823bf215546Sopenharmony_ci case PIPE_CAPF_MIN_LINE_WIDTH_AA: 824bf215546Sopenharmony_ci if (!screen->info.feats.features.wideLines) 825bf215546Sopenharmony_ci return 1.0f; 826bf215546Sopenharmony_ci return MAX2(screen->info.props.limits.lineWidthRange[0], 0.01); 827bf215546Sopenharmony_ci 828bf215546Sopenharmony_ci case PIPE_CAPF_MIN_POINT_SIZE: 829bf215546Sopenharmony_ci case PIPE_CAPF_MIN_POINT_SIZE_AA: 830bf215546Sopenharmony_ci if (!screen->info.feats.features.largePoints) 831bf215546Sopenharmony_ci return 1.0f; 832bf215546Sopenharmony_ci return MAX2(screen->info.props.limits.pointSizeRange[0], 0.01); 833bf215546Sopenharmony_ci 834bf215546Sopenharmony_ci 835bf215546Sopenharmony_ci case PIPE_CAPF_LINE_WIDTH_GRANULARITY: 836bf215546Sopenharmony_ci if (!screen->info.feats.features.wideLines) 837bf215546Sopenharmony_ci return 0.1f; 838bf215546Sopenharmony_ci return screen->info.props.limits.lineWidthGranularity; 839bf215546Sopenharmony_ci 840bf215546Sopenharmony_ci case PIPE_CAPF_POINT_SIZE_GRANULARITY: 841bf215546Sopenharmony_ci if (!screen->info.feats.features.largePoints) 842bf215546Sopenharmony_ci return 0.1f; 843bf215546Sopenharmony_ci return screen->info.props.limits.pointSizeGranularity; 844bf215546Sopenharmony_ci 845bf215546Sopenharmony_ci 846bf215546Sopenharmony_ci case PIPE_CAPF_MAX_LINE_WIDTH: 847bf215546Sopenharmony_ci case PIPE_CAPF_MAX_LINE_WIDTH_AA: 848bf215546Sopenharmony_ci if (!screen->info.feats.features.wideLines) 849bf215546Sopenharmony_ci return 1.0f; 850bf215546Sopenharmony_ci return screen->info.props.limits.lineWidthRange[1]; 851bf215546Sopenharmony_ci 852bf215546Sopenharmony_ci case PIPE_CAPF_MAX_POINT_SIZE: 853bf215546Sopenharmony_ci case PIPE_CAPF_MAX_POINT_SIZE_AA: 854bf215546Sopenharmony_ci if (!screen->info.feats.features.largePoints) 855bf215546Sopenharmony_ci return 1.0f; 856bf215546Sopenharmony_ci return screen->info.props.limits.pointSizeRange[1]; 857bf215546Sopenharmony_ci 858bf215546Sopenharmony_ci case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY: 859bf215546Sopenharmony_ci if (!screen->info.feats.features.samplerAnisotropy) 860bf215546Sopenharmony_ci return 1.0f; 861bf215546Sopenharmony_ci return screen->info.props.limits.maxSamplerAnisotropy; 862bf215546Sopenharmony_ci 863bf215546Sopenharmony_ci case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS: 864bf215546Sopenharmony_ci return screen->info.props.limits.maxSamplerLodBias; 865bf215546Sopenharmony_ci 866bf215546Sopenharmony_ci case PIPE_CAPF_MIN_CONSERVATIVE_RASTER_DILATE: 867bf215546Sopenharmony_ci case PIPE_CAPF_MAX_CONSERVATIVE_RASTER_DILATE: 868bf215546Sopenharmony_ci case PIPE_CAPF_CONSERVATIVE_RASTER_DILATE_GRANULARITY: 869bf215546Sopenharmony_ci return 0.0f; /* not implemented */ 870bf215546Sopenharmony_ci } 871bf215546Sopenharmony_ci 872bf215546Sopenharmony_ci /* should only get here on unhandled cases */ 873bf215546Sopenharmony_ci return 0.0f; 874bf215546Sopenharmony_ci} 875bf215546Sopenharmony_ci 876bf215546Sopenharmony_cistatic int 877bf215546Sopenharmony_cizink_get_shader_param(struct pipe_screen *pscreen, 878bf215546Sopenharmony_ci enum pipe_shader_type shader, 879bf215546Sopenharmony_ci enum pipe_shader_cap param) 880bf215546Sopenharmony_ci{ 881bf215546Sopenharmony_ci struct zink_screen *screen = zink_screen(pscreen); 882bf215546Sopenharmony_ci 883bf215546Sopenharmony_ci switch (param) { 884bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: 885bf215546Sopenharmony_ci switch (shader) { 886bf215546Sopenharmony_ci case PIPE_SHADER_FRAGMENT: 887bf215546Sopenharmony_ci case PIPE_SHADER_VERTEX: 888bf215546Sopenharmony_ci return INT_MAX; 889bf215546Sopenharmony_ci case PIPE_SHADER_TESS_CTRL: 890bf215546Sopenharmony_ci case PIPE_SHADER_TESS_EVAL: 891bf215546Sopenharmony_ci if (screen->info.feats.features.tessellationShader && 892bf215546Sopenharmony_ci screen->info.have_KHR_maintenance2) 893bf215546Sopenharmony_ci return INT_MAX; 894bf215546Sopenharmony_ci break; 895bf215546Sopenharmony_ci 896bf215546Sopenharmony_ci case PIPE_SHADER_GEOMETRY: 897bf215546Sopenharmony_ci if (screen->info.feats.features.geometryShader) 898bf215546Sopenharmony_ci return INT_MAX; 899bf215546Sopenharmony_ci break; 900bf215546Sopenharmony_ci 901bf215546Sopenharmony_ci case PIPE_SHADER_COMPUTE: 902bf215546Sopenharmony_ci return INT_MAX; 903bf215546Sopenharmony_ci default: 904bf215546Sopenharmony_ci break; 905bf215546Sopenharmony_ci } 906bf215546Sopenharmony_ci return 0; 907bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: 908bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: 909bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: 910bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: 911bf215546Sopenharmony_ci return INT_MAX; 912bf215546Sopenharmony_ci 913bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_INPUTS: { 914bf215546Sopenharmony_ci uint32_t max = 0; 915bf215546Sopenharmony_ci switch (shader) { 916bf215546Sopenharmony_ci case PIPE_SHADER_VERTEX: 917bf215546Sopenharmony_ci max = MIN2(screen->info.props.limits.maxVertexInputAttributes, PIPE_MAX_ATTRIBS); 918bf215546Sopenharmony_ci break; 919bf215546Sopenharmony_ci case PIPE_SHADER_TESS_CTRL: 920bf215546Sopenharmony_ci max = screen->info.props.limits.maxTessellationControlPerVertexInputComponents / 4; 921bf215546Sopenharmony_ci break; 922bf215546Sopenharmony_ci case PIPE_SHADER_TESS_EVAL: 923bf215546Sopenharmony_ci max = screen->info.props.limits.maxTessellationEvaluationInputComponents / 4; 924bf215546Sopenharmony_ci break; 925bf215546Sopenharmony_ci case PIPE_SHADER_GEOMETRY: 926bf215546Sopenharmony_ci max = screen->info.props.limits.maxGeometryInputComponents / 4; 927bf215546Sopenharmony_ci break; 928bf215546Sopenharmony_ci case PIPE_SHADER_FRAGMENT: 929bf215546Sopenharmony_ci /* intel drivers report fewer components, but it's a value that's compatible 930bf215546Sopenharmony_ci * with what we need for GL, so we can still force a conformant value here 931bf215546Sopenharmony_ci */ 932bf215546Sopenharmony_ci if (screen->info.driver_props.driverID == VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA || 933bf215546Sopenharmony_ci screen->info.driver_props.driverID == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS) 934bf215546Sopenharmony_ci return 32; 935bf215546Sopenharmony_ci max = screen->info.props.limits.maxFragmentInputComponents / 4; 936bf215546Sopenharmony_ci break; 937bf215546Sopenharmony_ci default: 938bf215546Sopenharmony_ci return 0; /* unsupported stage */ 939bf215546Sopenharmony_ci } 940bf215546Sopenharmony_ci switch (shader) { 941bf215546Sopenharmony_ci case PIPE_SHADER_VERTEX: 942bf215546Sopenharmony_ci case PIPE_SHADER_TESS_EVAL: 943bf215546Sopenharmony_ci case PIPE_SHADER_GEOMETRY: 944bf215546Sopenharmony_ci /* last vertex stage must support streamout, and this is capped in glsl compiler */ 945bf215546Sopenharmony_ci return MIN2(max, MAX_VARYING); 946bf215546Sopenharmony_ci default: break; 947bf215546Sopenharmony_ci } 948bf215546Sopenharmony_ci return MIN2(max, 64); // prevent overflowing struct shader_info::inputs_read 949bf215546Sopenharmony_ci } 950bf215546Sopenharmony_ci 951bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_OUTPUTS: { 952bf215546Sopenharmony_ci uint32_t max = 0; 953bf215546Sopenharmony_ci switch (shader) { 954bf215546Sopenharmony_ci case PIPE_SHADER_VERTEX: 955bf215546Sopenharmony_ci max = screen->info.props.limits.maxVertexOutputComponents / 4; 956bf215546Sopenharmony_ci break; 957bf215546Sopenharmony_ci case PIPE_SHADER_TESS_CTRL: 958bf215546Sopenharmony_ci max = screen->info.props.limits.maxTessellationControlPerVertexOutputComponents / 4; 959bf215546Sopenharmony_ci break; 960bf215546Sopenharmony_ci case PIPE_SHADER_TESS_EVAL: 961bf215546Sopenharmony_ci max = screen->info.props.limits.maxTessellationEvaluationOutputComponents / 4; 962bf215546Sopenharmony_ci break; 963bf215546Sopenharmony_ci case PIPE_SHADER_GEOMETRY: 964bf215546Sopenharmony_ci max = screen->info.props.limits.maxGeometryOutputComponents / 4; 965bf215546Sopenharmony_ci break; 966bf215546Sopenharmony_ci case PIPE_SHADER_FRAGMENT: 967bf215546Sopenharmony_ci max = screen->info.props.limits.maxColorAttachments; 968bf215546Sopenharmony_ci break; 969bf215546Sopenharmony_ci default: 970bf215546Sopenharmony_ci return 0; /* unsupported stage */ 971bf215546Sopenharmony_ci } 972bf215546Sopenharmony_ci return MIN2(max, 64); // prevent overflowing struct shader_info::outputs_read/written 973bf215546Sopenharmony_ci } 974bf215546Sopenharmony_ci 975bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_CONST_BUFFER0_SIZE: 976bf215546Sopenharmony_ci /* At least 16384 is guaranteed by VK spec */ 977bf215546Sopenharmony_ci assert(screen->info.props.limits.maxUniformBufferRange >= 16384); 978bf215546Sopenharmony_ci /* but Gallium can't handle values that are too big */ 979bf215546Sopenharmony_ci return MIN3(get_smallest_buffer_heap(screen), 980bf215546Sopenharmony_ci screen->info.props.limits.maxUniformBufferRange, BITFIELD_BIT(31)); 981bf215546Sopenharmony_ci 982bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: 983bf215546Sopenharmony_ci return MIN2(screen->info.props.limits.maxPerStageDescriptorUniformBuffers, 984bf215546Sopenharmony_ci PIPE_MAX_CONSTANT_BUFFERS); 985bf215546Sopenharmony_ci 986bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_TEMPS: 987bf215546Sopenharmony_ci return INT_MAX; 988bf215546Sopenharmony_ci 989bf215546Sopenharmony_ci case PIPE_SHADER_CAP_INTEGERS: 990bf215546Sopenharmony_ci return 1; 991bf215546Sopenharmony_ci 992bf215546Sopenharmony_ci case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: 993bf215546Sopenharmony_ci case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: 994bf215546Sopenharmony_ci case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: 995bf215546Sopenharmony_ci case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: 996bf215546Sopenharmony_ci return 1; 997bf215546Sopenharmony_ci 998bf215546Sopenharmony_ci case PIPE_SHADER_CAP_SUBROUTINES: 999bf215546Sopenharmony_ci case PIPE_SHADER_CAP_INT64_ATOMICS: 1000bf215546Sopenharmony_ci case PIPE_SHADER_CAP_GLSL_16BIT_CONSTS: 1001bf215546Sopenharmony_ci return 0; /* not implemented */ 1002bf215546Sopenharmony_ci 1003bf215546Sopenharmony_ci case PIPE_SHADER_CAP_FP16_CONST_BUFFERS: 1004bf215546Sopenharmony_ci //enabling this breaks GTF-GL46.gtf21.GL2Tests.glGetUniform.glGetUniform 1005bf215546Sopenharmony_ci //return screen->info.feats11.uniformAndStorageBuffer16BitAccess || 1006bf215546Sopenharmony_ci //(screen->info.have_KHR_16bit_storage && screen->info.storage_16bit_feats.uniformAndStorageBuffer16BitAccess); 1007bf215546Sopenharmony_ci return 0; 1008bf215546Sopenharmony_ci case PIPE_SHADER_CAP_FP16_DERIVATIVES: 1009bf215546Sopenharmony_ci return 0; //spirv requires 32bit derivative srcs and dests 1010bf215546Sopenharmony_ci case PIPE_SHADER_CAP_FP16: 1011bf215546Sopenharmony_ci return screen->info.feats12.shaderFloat16 || 1012bf215546Sopenharmony_ci (screen->info.have_KHR_shader_float16_int8 && 1013bf215546Sopenharmony_ci screen->info.shader_float16_int8_feats.shaderFloat16); 1014bf215546Sopenharmony_ci 1015bf215546Sopenharmony_ci case PIPE_SHADER_CAP_INT16: 1016bf215546Sopenharmony_ci return screen->info.feats.features.shaderInt16; 1017bf215546Sopenharmony_ci 1018bf215546Sopenharmony_ci case PIPE_SHADER_CAP_PREFERRED_IR: 1019bf215546Sopenharmony_ci return PIPE_SHADER_IR_NIR; 1020bf215546Sopenharmony_ci 1021bf215546Sopenharmony_ci case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED: 1022bf215546Sopenharmony_ci return 0; /* not implemented */ 1023bf215546Sopenharmony_ci 1024bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: 1025bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS: 1026bf215546Sopenharmony_ci return MIN2(MIN2(screen->info.props.limits.maxPerStageDescriptorSamplers, 1027bf215546Sopenharmony_ci screen->info.props.limits.maxPerStageDescriptorSampledImages), 1028bf215546Sopenharmony_ci PIPE_MAX_SAMPLERS); 1029bf215546Sopenharmony_ci 1030bf215546Sopenharmony_ci case PIPE_SHADER_CAP_DROUND_SUPPORTED: 1031bf215546Sopenharmony_ci case PIPE_SHADER_CAP_DFRACEXP_DLDEXP_SUPPORTED: 1032bf215546Sopenharmony_ci return 0; /* not implemented */ 1033bf215546Sopenharmony_ci 1034bf215546Sopenharmony_ci case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE: 1035bf215546Sopenharmony_ci return 0; /* no idea */ 1036bf215546Sopenharmony_ci 1037bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS: 1038bf215546Sopenharmony_ci switch (shader) { 1039bf215546Sopenharmony_ci case PIPE_SHADER_VERTEX: 1040bf215546Sopenharmony_ci case PIPE_SHADER_TESS_CTRL: 1041bf215546Sopenharmony_ci case PIPE_SHADER_TESS_EVAL: 1042bf215546Sopenharmony_ci case PIPE_SHADER_GEOMETRY: 1043bf215546Sopenharmony_ci if (!screen->info.feats.features.vertexPipelineStoresAndAtomics) 1044bf215546Sopenharmony_ci return 0; 1045bf215546Sopenharmony_ci break; 1046bf215546Sopenharmony_ci 1047bf215546Sopenharmony_ci case PIPE_SHADER_FRAGMENT: 1048bf215546Sopenharmony_ci if (!screen->info.feats.features.fragmentStoresAndAtomics) 1049bf215546Sopenharmony_ci return 0; 1050bf215546Sopenharmony_ci break; 1051bf215546Sopenharmony_ci 1052bf215546Sopenharmony_ci default: 1053bf215546Sopenharmony_ci break; 1054bf215546Sopenharmony_ci } 1055bf215546Sopenharmony_ci 1056bf215546Sopenharmony_ci /* TODO: this limitation is dumb, and will need some fixes in mesa */ 1057bf215546Sopenharmony_ci return MIN2(screen->info.props.limits.maxPerStageDescriptorStorageBuffers, PIPE_MAX_SHADER_BUFFERS); 1058bf215546Sopenharmony_ci 1059bf215546Sopenharmony_ci case PIPE_SHADER_CAP_SUPPORTED_IRS: 1060bf215546Sopenharmony_ci return (1 << PIPE_SHADER_IR_NIR) | (1 << PIPE_SHADER_IR_TGSI); 1061bf215546Sopenharmony_ci 1062bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_SHADER_IMAGES: 1063bf215546Sopenharmony_ci if (screen->info.feats.features.shaderStorageImageExtendedFormats && 1064bf215546Sopenharmony_ci screen->info.feats.features.shaderStorageImageWriteWithoutFormat) 1065bf215546Sopenharmony_ci return MIN2(screen->info.props.limits.maxPerStageDescriptorStorageImages, 1066bf215546Sopenharmony_ci ZINK_MAX_SHADER_IMAGES); 1067bf215546Sopenharmony_ci return 0; 1068bf215546Sopenharmony_ci 1069bf215546Sopenharmony_ci case PIPE_SHADER_CAP_LDEXP_SUPPORTED: 1070bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS: 1071bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS: 1072bf215546Sopenharmony_ci return 0; /* not implemented */ 1073bf215546Sopenharmony_ci case PIPE_SHADER_CAP_CONT_SUPPORTED: 1074bf215546Sopenharmony_ci return 1; 1075bf215546Sopenharmony_ci } 1076bf215546Sopenharmony_ci 1077bf215546Sopenharmony_ci /* should only get here on unhandled cases */ 1078bf215546Sopenharmony_ci return 0; 1079bf215546Sopenharmony_ci} 1080bf215546Sopenharmony_ci 1081bf215546Sopenharmony_cistatic VkSampleCountFlagBits 1082bf215546Sopenharmony_civk_sample_count_flags(uint32_t sample_count) 1083bf215546Sopenharmony_ci{ 1084bf215546Sopenharmony_ci switch (sample_count) { 1085bf215546Sopenharmony_ci case 1: return VK_SAMPLE_COUNT_1_BIT; 1086bf215546Sopenharmony_ci case 2: return VK_SAMPLE_COUNT_2_BIT; 1087bf215546Sopenharmony_ci case 4: return VK_SAMPLE_COUNT_4_BIT; 1088bf215546Sopenharmony_ci case 8: return VK_SAMPLE_COUNT_8_BIT; 1089bf215546Sopenharmony_ci case 16: return VK_SAMPLE_COUNT_16_BIT; 1090bf215546Sopenharmony_ci case 32: return VK_SAMPLE_COUNT_32_BIT; 1091bf215546Sopenharmony_ci case 64: return VK_SAMPLE_COUNT_64_BIT; 1092bf215546Sopenharmony_ci default: 1093bf215546Sopenharmony_ci return 0; 1094bf215546Sopenharmony_ci } 1095bf215546Sopenharmony_ci} 1096bf215546Sopenharmony_ci 1097bf215546Sopenharmony_cistatic bool 1098bf215546Sopenharmony_cizink_is_compute_copy_faster(struct pipe_screen *pscreen, 1099bf215546Sopenharmony_ci enum pipe_format src_format, 1100bf215546Sopenharmony_ci enum pipe_format dst_format, 1101bf215546Sopenharmony_ci unsigned width, 1102bf215546Sopenharmony_ci unsigned height, 1103bf215546Sopenharmony_ci unsigned depth, 1104bf215546Sopenharmony_ci bool cpu) 1105bf215546Sopenharmony_ci{ 1106bf215546Sopenharmony_ci if (cpu) 1107bf215546Sopenharmony_ci /* very basic for now, probably even worse for some cases, 1108bf215546Sopenharmony_ci * but fixes lots of others 1109bf215546Sopenharmony_ci */ 1110bf215546Sopenharmony_ci return width * height * depth > 64 * 64; 1111bf215546Sopenharmony_ci return false; 1112bf215546Sopenharmony_ci} 1113bf215546Sopenharmony_ci 1114bf215546Sopenharmony_cistatic bool 1115bf215546Sopenharmony_cizink_is_format_supported(struct pipe_screen *pscreen, 1116bf215546Sopenharmony_ci enum pipe_format format, 1117bf215546Sopenharmony_ci enum pipe_texture_target target, 1118bf215546Sopenharmony_ci unsigned sample_count, 1119bf215546Sopenharmony_ci unsigned storage_sample_count, 1120bf215546Sopenharmony_ci unsigned bind) 1121bf215546Sopenharmony_ci{ 1122bf215546Sopenharmony_ci struct zink_screen *screen = zink_screen(pscreen); 1123bf215546Sopenharmony_ci 1124bf215546Sopenharmony_ci if (storage_sample_count && !screen->info.feats.features.shaderStorageImageMultisample && bind & PIPE_BIND_SHADER_IMAGE) 1125bf215546Sopenharmony_ci return false; 1126bf215546Sopenharmony_ci 1127bf215546Sopenharmony_ci if (format == PIPE_FORMAT_NONE) 1128bf215546Sopenharmony_ci return screen->info.props.limits.framebufferNoAttachmentsSampleCounts & 1129bf215546Sopenharmony_ci vk_sample_count_flags(sample_count); 1130bf215546Sopenharmony_ci 1131bf215546Sopenharmony_ci if (bind & PIPE_BIND_INDEX_BUFFER) { 1132bf215546Sopenharmony_ci if (format == PIPE_FORMAT_R8_UINT && 1133bf215546Sopenharmony_ci !screen->info.have_EXT_index_type_uint8) 1134bf215546Sopenharmony_ci return false; 1135bf215546Sopenharmony_ci if (format != PIPE_FORMAT_R8_UINT && 1136bf215546Sopenharmony_ci format != PIPE_FORMAT_R16_UINT && 1137bf215546Sopenharmony_ci format != PIPE_FORMAT_R32_UINT) 1138bf215546Sopenharmony_ci return false; 1139bf215546Sopenharmony_ci } 1140bf215546Sopenharmony_ci 1141bf215546Sopenharmony_ci VkFormat vkformat = zink_get_format(screen, format); 1142bf215546Sopenharmony_ci if (vkformat == VK_FORMAT_UNDEFINED) 1143bf215546Sopenharmony_ci return false; 1144bf215546Sopenharmony_ci 1145bf215546Sopenharmony_ci if (sample_count >= 1) { 1146bf215546Sopenharmony_ci VkSampleCountFlagBits sample_mask = vk_sample_count_flags(sample_count); 1147bf215546Sopenharmony_ci if (!sample_mask) 1148bf215546Sopenharmony_ci return false; 1149bf215546Sopenharmony_ci const struct util_format_description *desc = util_format_description(format); 1150bf215546Sopenharmony_ci if (util_format_is_depth_or_stencil(format)) { 1151bf215546Sopenharmony_ci if (util_format_has_depth(desc)) { 1152bf215546Sopenharmony_ci if (bind & PIPE_BIND_DEPTH_STENCIL && 1153bf215546Sopenharmony_ci (screen->info.props.limits.framebufferDepthSampleCounts & sample_mask) != sample_mask) 1154bf215546Sopenharmony_ci return false; 1155bf215546Sopenharmony_ci if (bind & PIPE_BIND_SAMPLER_VIEW && 1156bf215546Sopenharmony_ci (screen->info.props.limits.sampledImageDepthSampleCounts & sample_mask) != sample_mask) 1157bf215546Sopenharmony_ci return false; 1158bf215546Sopenharmony_ci } 1159bf215546Sopenharmony_ci if (util_format_has_stencil(desc)) { 1160bf215546Sopenharmony_ci if (bind & PIPE_BIND_DEPTH_STENCIL && 1161bf215546Sopenharmony_ci (screen->info.props.limits.framebufferStencilSampleCounts & sample_mask) != sample_mask) 1162bf215546Sopenharmony_ci return false; 1163bf215546Sopenharmony_ci if (bind & PIPE_BIND_SAMPLER_VIEW && 1164bf215546Sopenharmony_ci (screen->info.props.limits.sampledImageStencilSampleCounts & sample_mask) != sample_mask) 1165bf215546Sopenharmony_ci return false; 1166bf215546Sopenharmony_ci } 1167bf215546Sopenharmony_ci } else if (util_format_is_pure_integer(format)) { 1168bf215546Sopenharmony_ci if (bind & PIPE_BIND_RENDER_TARGET && 1169bf215546Sopenharmony_ci !(screen->info.props.limits.framebufferColorSampleCounts & sample_mask)) 1170bf215546Sopenharmony_ci return false; 1171bf215546Sopenharmony_ci if (bind & PIPE_BIND_SAMPLER_VIEW && 1172bf215546Sopenharmony_ci !(screen->info.props.limits.sampledImageIntegerSampleCounts & sample_mask)) 1173bf215546Sopenharmony_ci return false; 1174bf215546Sopenharmony_ci } else { 1175bf215546Sopenharmony_ci if (bind & PIPE_BIND_RENDER_TARGET && 1176bf215546Sopenharmony_ci !(screen->info.props.limits.framebufferColorSampleCounts & sample_mask)) 1177bf215546Sopenharmony_ci return false; 1178bf215546Sopenharmony_ci if (bind & PIPE_BIND_SAMPLER_VIEW && 1179bf215546Sopenharmony_ci !(screen->info.props.limits.sampledImageColorSampleCounts & sample_mask)) 1180bf215546Sopenharmony_ci return false; 1181bf215546Sopenharmony_ci } 1182bf215546Sopenharmony_ci if (bind & PIPE_BIND_SHADER_IMAGE) { 1183bf215546Sopenharmony_ci if (!(screen->info.props.limits.storageImageSampleCounts & sample_mask)) 1184bf215546Sopenharmony_ci return false; 1185bf215546Sopenharmony_ci } 1186bf215546Sopenharmony_ci } 1187bf215546Sopenharmony_ci 1188bf215546Sopenharmony_ci VkFormatProperties props = screen->format_props[format]; 1189bf215546Sopenharmony_ci 1190bf215546Sopenharmony_ci if (target == PIPE_BUFFER) { 1191bf215546Sopenharmony_ci if (bind & PIPE_BIND_VERTEX_BUFFER) { 1192bf215546Sopenharmony_ci if (!(props.bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)) { 1193bf215546Sopenharmony_ci enum pipe_format new_format = zink_decompose_vertex_format(format); 1194bf215546Sopenharmony_ci if (!new_format) 1195bf215546Sopenharmony_ci return false; 1196bf215546Sopenharmony_ci if (!(screen->format_props[new_format].bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)) 1197bf215546Sopenharmony_ci return false; 1198bf215546Sopenharmony_ci } 1199bf215546Sopenharmony_ci } 1200bf215546Sopenharmony_ci 1201bf215546Sopenharmony_ci if (bind & PIPE_BIND_SAMPLER_VIEW && 1202bf215546Sopenharmony_ci !(props.bufferFeatures & VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT)) 1203bf215546Sopenharmony_ci return false; 1204bf215546Sopenharmony_ci 1205bf215546Sopenharmony_ci if (bind & PIPE_BIND_SHADER_IMAGE && 1206bf215546Sopenharmony_ci !(props.bufferFeatures & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT)) 1207bf215546Sopenharmony_ci return false; 1208bf215546Sopenharmony_ci } else { 1209bf215546Sopenharmony_ci /* all other targets are texture-targets */ 1210bf215546Sopenharmony_ci if (bind & PIPE_BIND_RENDER_TARGET && 1211bf215546Sopenharmony_ci !(props.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) 1212bf215546Sopenharmony_ci return false; 1213bf215546Sopenharmony_ci 1214bf215546Sopenharmony_ci if (bind & PIPE_BIND_BLENDABLE && 1215bf215546Sopenharmony_ci !(props.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT)) 1216bf215546Sopenharmony_ci return false; 1217bf215546Sopenharmony_ci 1218bf215546Sopenharmony_ci if (bind & PIPE_BIND_SAMPLER_VIEW && 1219bf215546Sopenharmony_ci !(props.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) 1220bf215546Sopenharmony_ci return false; 1221bf215546Sopenharmony_ci 1222bf215546Sopenharmony_ci if (bind & PIPE_BIND_SAMPLER_REDUCTION_MINMAX && 1223bf215546Sopenharmony_ci !(props.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT)) 1224bf215546Sopenharmony_ci return false; 1225bf215546Sopenharmony_ci 1226bf215546Sopenharmony_ci if ((bind & PIPE_BIND_SAMPLER_VIEW) || (bind & PIPE_BIND_RENDER_TARGET)) { 1227bf215546Sopenharmony_ci /* if this is a 3-component texture, force gallium to give us 4 components by rejecting this one */ 1228bf215546Sopenharmony_ci const struct util_format_description *desc = util_format_description(format); 1229bf215546Sopenharmony_ci if (desc->nr_channels == 3 && 1230bf215546Sopenharmony_ci (desc->block.bits == 24 || desc->block.bits == 48 || desc->block.bits == 96)) 1231bf215546Sopenharmony_ci return false; 1232bf215546Sopenharmony_ci } 1233bf215546Sopenharmony_ci 1234bf215546Sopenharmony_ci if (bind & PIPE_BIND_DEPTH_STENCIL && 1235bf215546Sopenharmony_ci !(props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) 1236bf215546Sopenharmony_ci return false; 1237bf215546Sopenharmony_ci 1238bf215546Sopenharmony_ci if (bind & PIPE_BIND_SHADER_IMAGE && 1239bf215546Sopenharmony_ci !(props.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) 1240bf215546Sopenharmony_ci return false; 1241bf215546Sopenharmony_ci } 1242bf215546Sopenharmony_ci 1243bf215546Sopenharmony_ci if (util_format_is_compressed(format)) { 1244bf215546Sopenharmony_ci const struct util_format_description *desc = util_format_description(format); 1245bf215546Sopenharmony_ci if (desc->layout == UTIL_FORMAT_LAYOUT_BPTC && 1246bf215546Sopenharmony_ci !screen->info.feats.features.textureCompressionBC) 1247bf215546Sopenharmony_ci return false; 1248bf215546Sopenharmony_ci } 1249bf215546Sopenharmony_ci 1250bf215546Sopenharmony_ci return true; 1251bf215546Sopenharmony_ci} 1252bf215546Sopenharmony_ci 1253bf215546Sopenharmony_cistatic void 1254bf215546Sopenharmony_cizink_destroy_screen(struct pipe_screen *pscreen) 1255bf215546Sopenharmony_ci{ 1256bf215546Sopenharmony_ci struct zink_screen *screen = zink_screen(pscreen); 1257bf215546Sopenharmony_ci 1258bf215546Sopenharmony_ci hash_table_foreach(&screen->dts, entry) 1259bf215546Sopenharmony_ci zink_kopper_deinit_displaytarget(screen, entry->data); 1260bf215546Sopenharmony_ci simple_mtx_destroy(&screen->dt_lock); 1261bf215546Sopenharmony_ci 1262bf215546Sopenharmony_ci if (screen->copy_context) 1263bf215546Sopenharmony_ci screen->copy_context->base.destroy(&screen->copy_context->base); 1264bf215546Sopenharmony_ci 1265bf215546Sopenharmony_ci if (VK_NULL_HANDLE != screen->debugUtilsCallbackHandle) { 1266bf215546Sopenharmony_ci VKSCR(DestroyDebugUtilsMessengerEXT)(screen->instance, screen->debugUtilsCallbackHandle, NULL); 1267bf215546Sopenharmony_ci } 1268bf215546Sopenharmony_ci 1269bf215546Sopenharmony_ci util_vertex_state_cache_deinit(&screen->vertex_state_cache); 1270bf215546Sopenharmony_ci 1271bf215546Sopenharmony_ci u_transfer_helper_destroy(pscreen->transfer_helper); 1272bf215546Sopenharmony_ci#ifdef ENABLE_SHADER_CACHE 1273bf215546Sopenharmony_ci if (screen->disk_cache) { 1274bf215546Sopenharmony_ci util_queue_finish(&screen->cache_put_thread); 1275bf215546Sopenharmony_ci util_queue_finish(&screen->cache_get_thread); 1276bf215546Sopenharmony_ci disk_cache_wait_for_idle(screen->disk_cache); 1277bf215546Sopenharmony_ci util_queue_destroy(&screen->cache_put_thread); 1278bf215546Sopenharmony_ci util_queue_destroy(&screen->cache_get_thread); 1279bf215546Sopenharmony_ci } 1280bf215546Sopenharmony_ci#endif 1281bf215546Sopenharmony_ci disk_cache_destroy(screen->disk_cache); 1282bf215546Sopenharmony_ci zink_bo_deinit(screen); 1283bf215546Sopenharmony_ci util_live_shader_cache_deinit(&screen->shaders); 1284bf215546Sopenharmony_ci 1285bf215546Sopenharmony_ci if (screen->sem) 1286bf215546Sopenharmony_ci VKSCR(DestroySemaphore)(screen->dev, screen->sem, NULL); 1287bf215546Sopenharmony_ci 1288bf215546Sopenharmony_ci if (screen->fence) 1289bf215546Sopenharmony_ci VKSCR(DestroyFence)(screen->dev, screen->fence, NULL); 1290bf215546Sopenharmony_ci 1291bf215546Sopenharmony_ci if (screen->threaded) 1292bf215546Sopenharmony_ci util_queue_destroy(&screen->flush_queue); 1293bf215546Sopenharmony_ci 1294bf215546Sopenharmony_ci simple_mtx_destroy(&screen->queue_lock); 1295bf215546Sopenharmony_ci VKSCR(DestroyDevice)(screen->dev, NULL); 1296bf215546Sopenharmony_ci VKSCR(DestroyInstance)(screen->instance, NULL); 1297bf215546Sopenharmony_ci util_idalloc_mt_fini(&screen->buffer_ids); 1298bf215546Sopenharmony_ci 1299bf215546Sopenharmony_ci util_dl_close(screen->loader_lib); 1300bf215546Sopenharmony_ci if (screen->drm_fd != -1) 1301bf215546Sopenharmony_ci close(screen->drm_fd); 1302bf215546Sopenharmony_ci 1303bf215546Sopenharmony_ci slab_destroy_parent(&screen->transfer_pool); 1304bf215546Sopenharmony_ci ralloc_free(screen); 1305bf215546Sopenharmony_ci glsl_type_singleton_decref(); 1306bf215546Sopenharmony_ci} 1307bf215546Sopenharmony_ci 1308bf215546Sopenharmony_cistatic bool 1309bf215546Sopenharmony_cichoose_pdev(struct zink_screen *screen) 1310bf215546Sopenharmony_ci{ 1311bf215546Sopenharmony_ci uint32_t i, pdev_count; 1312bf215546Sopenharmony_ci VkPhysicalDevice *pdevs; 1313bf215546Sopenharmony_ci bool is_cpu = false; 1314bf215546Sopenharmony_ci VkResult result = VKSCR(EnumeratePhysicalDevices)(screen->instance, &pdev_count, NULL); 1315bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 1316bf215546Sopenharmony_ci mesa_loge("ZINK: vkEnumeratePhysicalDevices failed (%s)", vk_Result_to_str(result)); 1317bf215546Sopenharmony_ci return is_cpu; 1318bf215546Sopenharmony_ci } 1319bf215546Sopenharmony_ci 1320bf215546Sopenharmony_ci assert(pdev_count > 0); 1321bf215546Sopenharmony_ci 1322bf215546Sopenharmony_ci pdevs = malloc(sizeof(*pdevs) * pdev_count); 1323bf215546Sopenharmony_ci result = VKSCR(EnumeratePhysicalDevices)(screen->instance, &pdev_count, pdevs); 1324bf215546Sopenharmony_ci assert(result == VK_SUCCESS); 1325bf215546Sopenharmony_ci assert(pdev_count > 0); 1326bf215546Sopenharmony_ci 1327bf215546Sopenharmony_ci VkPhysicalDeviceProperties props; 1328bf215546Sopenharmony_ci bool cpu = debug_get_bool_option("LIBGL_ALWAYS_SOFTWARE", false); 1329bf215546Sopenharmony_ci /* priority when multiple drivers are available (highest to lowest): 1330bf215546Sopenharmony_ci VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU 1331bf215546Sopenharmony_ci VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU 1332bf215546Sopenharmony_ci VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU 1333bf215546Sopenharmony_ci VK_PHYSICAL_DEVICE_TYPE_CPU 1334bf215546Sopenharmony_ci VK_PHYSICAL_DEVICE_TYPE_OTHER 1335bf215546Sopenharmony_ci 1336bf215546Sopenharmony_ci * users should specify VK_ICD_FILENAMES since this is a standardized variable 1337bf215546Sopenharmony_ci * used by all vulkan applications 1338bf215546Sopenharmony_ci */ 1339bf215546Sopenharmony_ci unsigned prio_map[] = { 1340bf215546Sopenharmony_ci [VK_PHYSICAL_DEVICE_TYPE_OTHER] = 0, 1341bf215546Sopenharmony_ci [VK_PHYSICAL_DEVICE_TYPE_CPU] = 1, 1342bf215546Sopenharmony_ci [VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU] = 2, 1343bf215546Sopenharmony_ci [VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU] = 3, 1344bf215546Sopenharmony_ci [VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU] = 4, 1345bf215546Sopenharmony_ci }; 1346bf215546Sopenharmony_ci unsigned idx = 0; 1347bf215546Sopenharmony_ci int cur_prio = 0; 1348bf215546Sopenharmony_ci for (i = 0; i < pdev_count; ++i) { 1349bf215546Sopenharmony_ci VKSCR(GetPhysicalDeviceProperties)(pdevs[i], &props); 1350bf215546Sopenharmony_ci 1351bf215546Sopenharmony_ci if (cpu) { 1352bf215546Sopenharmony_ci /* if user wants cpu, only give them cpu */ 1353bf215546Sopenharmony_ci if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU) { 1354bf215546Sopenharmony_ci idx = i; 1355bf215546Sopenharmony_ci cur_prio = prio_map[props.deviceType]; 1356bf215546Sopenharmony_ci break; 1357bf215546Sopenharmony_ci } 1358bf215546Sopenharmony_ci } else { 1359bf215546Sopenharmony_ci assert(props.deviceType <= VK_PHYSICAL_DEVICE_TYPE_CPU); 1360bf215546Sopenharmony_ci if (prio_map[props.deviceType] > cur_prio) { 1361bf215546Sopenharmony_ci idx = i; 1362bf215546Sopenharmony_ci cur_prio = prio_map[props.deviceType]; 1363bf215546Sopenharmony_ci } 1364bf215546Sopenharmony_ci } 1365bf215546Sopenharmony_ci } 1366bf215546Sopenharmony_ci is_cpu = cur_prio == prio_map[VK_PHYSICAL_DEVICE_TYPE_CPU]; 1367bf215546Sopenharmony_ci if (cpu != is_cpu) 1368bf215546Sopenharmony_ci goto out; 1369bf215546Sopenharmony_ci 1370bf215546Sopenharmony_ci screen->pdev = pdevs[idx]; 1371bf215546Sopenharmony_ci VKSCR(GetPhysicalDeviceProperties)(screen->pdev, &screen->info.props); 1372bf215546Sopenharmony_ci screen->info.device_version = screen->info.props.apiVersion; 1373bf215546Sopenharmony_ci 1374bf215546Sopenharmony_ci /* runtime version is the lesser of the instance version and device version */ 1375bf215546Sopenharmony_ci screen->vk_version = MIN2(screen->info.device_version, screen->instance_info.loader_version); 1376bf215546Sopenharmony_ci 1377bf215546Sopenharmony_ci /* calculate SPIR-V version based on VK version */ 1378bf215546Sopenharmony_ci if (screen->vk_version >= VK_MAKE_VERSION(1, 2, 0)) 1379bf215546Sopenharmony_ci screen->spirv_version = SPIRV_VERSION(1, 5); 1380bf215546Sopenharmony_ci else if (screen->vk_version >= VK_MAKE_VERSION(1, 1, 0)) 1381bf215546Sopenharmony_ci screen->spirv_version = SPIRV_VERSION(1, 3); 1382bf215546Sopenharmony_ci else 1383bf215546Sopenharmony_ci screen->spirv_version = SPIRV_VERSION(1, 0); 1384bf215546Sopenharmony_ciout: 1385bf215546Sopenharmony_ci free(pdevs); 1386bf215546Sopenharmony_ci return is_cpu; 1387bf215546Sopenharmony_ci} 1388bf215546Sopenharmony_ci 1389bf215546Sopenharmony_cistatic void 1390bf215546Sopenharmony_ciupdate_queue_props(struct zink_screen *screen) 1391bf215546Sopenharmony_ci{ 1392bf215546Sopenharmony_ci uint32_t num_queues; 1393bf215546Sopenharmony_ci VKSCR(GetPhysicalDeviceQueueFamilyProperties)(screen->pdev, &num_queues, NULL); 1394bf215546Sopenharmony_ci assert(num_queues > 0); 1395bf215546Sopenharmony_ci 1396bf215546Sopenharmony_ci VkQueueFamilyProperties *props = malloc(sizeof(*props) * num_queues); 1397bf215546Sopenharmony_ci VKSCR(GetPhysicalDeviceQueueFamilyProperties)(screen->pdev, &num_queues, props); 1398bf215546Sopenharmony_ci 1399bf215546Sopenharmony_ci bool found_gfx = false; 1400bf215546Sopenharmony_ci uint32_t sparse_only = UINT32_MAX; 1401bf215546Sopenharmony_ci screen->sparse_queue = UINT32_MAX; 1402bf215546Sopenharmony_ci for (uint32_t i = 0; i < num_queues; i++) { 1403bf215546Sopenharmony_ci if (!found_gfx && (props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)) { 1404bf215546Sopenharmony_ci screen->gfx_queue = i; 1405bf215546Sopenharmony_ci screen->max_queues = props[i].queueCount; 1406bf215546Sopenharmony_ci screen->timestamp_valid_bits = props[i].timestampValidBits; 1407bf215546Sopenharmony_ci found_gfx = true; 1408bf215546Sopenharmony_ci if (props[i].queueFlags & VK_QUEUE_SPARSE_BINDING_BIT) 1409bf215546Sopenharmony_ci screen->sparse_queue = i; 1410bf215546Sopenharmony_ci } else if (props[i].queueFlags & VK_QUEUE_SPARSE_BINDING_BIT) 1411bf215546Sopenharmony_ci sparse_only = i; 1412bf215546Sopenharmony_ci } 1413bf215546Sopenharmony_ci if (screen->sparse_queue == UINT32_MAX) 1414bf215546Sopenharmony_ci screen->sparse_queue = sparse_only; 1415bf215546Sopenharmony_ci free(props); 1416bf215546Sopenharmony_ci} 1417bf215546Sopenharmony_ci 1418bf215546Sopenharmony_cistatic void 1419bf215546Sopenharmony_ciinit_queue(struct zink_screen *screen) 1420bf215546Sopenharmony_ci{ 1421bf215546Sopenharmony_ci simple_mtx_init(&screen->queue_lock, mtx_plain); 1422bf215546Sopenharmony_ci VKSCR(GetDeviceQueue)(screen->dev, screen->gfx_queue, 0, &screen->queue); 1423bf215546Sopenharmony_ci if (screen->sparse_queue != UINT32_MAX) { 1424bf215546Sopenharmony_ci if (screen->sparse_queue != screen->gfx_queue) 1425bf215546Sopenharmony_ci VKSCR(GetDeviceQueue)(screen->dev, screen->sparse_queue, 0, &screen->queue_sparse); 1426bf215546Sopenharmony_ci else 1427bf215546Sopenharmony_ci screen->queue_sparse = screen->queue; 1428bf215546Sopenharmony_ci } 1429bf215546Sopenharmony_ci} 1430bf215546Sopenharmony_ci 1431bf215546Sopenharmony_cistatic void 1432bf215546Sopenharmony_cizink_flush_frontbuffer(struct pipe_screen *pscreen, 1433bf215546Sopenharmony_ci struct pipe_context *pctx, 1434bf215546Sopenharmony_ci struct pipe_resource *pres, 1435bf215546Sopenharmony_ci unsigned level, unsigned layer, 1436bf215546Sopenharmony_ci void *winsys_drawable_handle, 1437bf215546Sopenharmony_ci struct pipe_box *sub_box) 1438bf215546Sopenharmony_ci{ 1439bf215546Sopenharmony_ci struct zink_screen *screen = zink_screen(pscreen); 1440bf215546Sopenharmony_ci struct zink_resource *res = zink_resource(pres); 1441bf215546Sopenharmony_ci struct zink_context *ctx = zink_context(pctx); 1442bf215546Sopenharmony_ci 1443bf215546Sopenharmony_ci /* if the surface has never been acquired, there's nothing to present, 1444bf215546Sopenharmony_ci * so this is a no-op */ 1445bf215546Sopenharmony_ci if (!zink_is_swapchain(res) || (!zink_kopper_acquired(res->obj->dt, res->obj->dt_idx) && res->obj->last_dt_idx == UINT32_MAX)) 1446bf215546Sopenharmony_ci return; 1447bf215546Sopenharmony_ci 1448bf215546Sopenharmony_ci ctx = zink_tc_context_unwrap(pctx); 1449bf215546Sopenharmony_ci if (ctx->batch.swapchain || ctx->needs_present) { 1450bf215546Sopenharmony_ci ctx->batch.has_work = true; 1451bf215546Sopenharmony_ci pctx->flush(pctx, NULL, PIPE_FLUSH_END_OF_FRAME); 1452bf215546Sopenharmony_ci if (ctx->last_fence && screen->threaded) { 1453bf215546Sopenharmony_ci struct zink_batch_state *bs = zink_batch_state(ctx->last_fence); 1454bf215546Sopenharmony_ci util_queue_fence_wait(&bs->flush_completed); 1455bf215546Sopenharmony_ci } 1456bf215546Sopenharmony_ci } 1457bf215546Sopenharmony_ci 1458bf215546Sopenharmony_ci if (zink_kopper_acquired(res->obj->dt, res->obj->dt_idx)) 1459bf215546Sopenharmony_ci zink_kopper_present_queue(screen, res); 1460bf215546Sopenharmony_ci else { 1461bf215546Sopenharmony_ci assert(res->obj->last_dt_idx != UINT32_MAX); 1462bf215546Sopenharmony_ci if (!zink_kopper_last_present_eq(res->obj->dt, res->obj->last_dt_idx)) { 1463bf215546Sopenharmony_ci zink_kopper_acquire_readback(ctx, res); 1464bf215546Sopenharmony_ci zink_kopper_present_readback(ctx, res); 1465bf215546Sopenharmony_ci } 1466bf215546Sopenharmony_ci } 1467bf215546Sopenharmony_ci} 1468bf215546Sopenharmony_ci 1469bf215546Sopenharmony_cibool 1470bf215546Sopenharmony_cizink_is_depth_format_supported(struct zink_screen *screen, VkFormat format) 1471bf215546Sopenharmony_ci{ 1472bf215546Sopenharmony_ci VkFormatProperties props; 1473bf215546Sopenharmony_ci VKSCR(GetPhysicalDeviceFormatProperties)(screen->pdev, format, &props); 1474bf215546Sopenharmony_ci return (props.linearTilingFeatures | props.optimalTilingFeatures) & 1475bf215546Sopenharmony_ci VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT; 1476bf215546Sopenharmony_ci} 1477bf215546Sopenharmony_ci 1478bf215546Sopenharmony_cistatic enum pipe_format 1479bf215546Sopenharmony_ciemulate_x8(enum pipe_format format) 1480bf215546Sopenharmony_ci{ 1481bf215546Sopenharmony_ci /* convert missing X8 variants to A8 */ 1482bf215546Sopenharmony_ci switch (format) { 1483bf215546Sopenharmony_ci case PIPE_FORMAT_B8G8R8X8_UNORM: 1484bf215546Sopenharmony_ci return PIPE_FORMAT_B8G8R8A8_UNORM; 1485bf215546Sopenharmony_ci 1486bf215546Sopenharmony_ci case PIPE_FORMAT_B8G8R8X8_SRGB: 1487bf215546Sopenharmony_ci return PIPE_FORMAT_B8G8R8A8_SRGB; 1488bf215546Sopenharmony_ci case PIPE_FORMAT_R8G8B8X8_SRGB: 1489bf215546Sopenharmony_ci return PIPE_FORMAT_R8G8B8A8_SRGB; 1490bf215546Sopenharmony_ci 1491bf215546Sopenharmony_ci case PIPE_FORMAT_R8G8B8X8_SINT: 1492bf215546Sopenharmony_ci return PIPE_FORMAT_R8G8B8A8_SINT; 1493bf215546Sopenharmony_ci case PIPE_FORMAT_R8G8B8X8_SNORM: 1494bf215546Sopenharmony_ci return PIPE_FORMAT_R8G8B8A8_SNORM; 1495bf215546Sopenharmony_ci case PIPE_FORMAT_R8G8B8X8_UNORM: 1496bf215546Sopenharmony_ci return PIPE_FORMAT_R8G8B8A8_UNORM; 1497bf215546Sopenharmony_ci 1498bf215546Sopenharmony_ci case PIPE_FORMAT_R16G16B16X16_FLOAT: 1499bf215546Sopenharmony_ci return PIPE_FORMAT_R16G16B16A16_FLOAT; 1500bf215546Sopenharmony_ci case PIPE_FORMAT_R16G16B16X16_SINT: 1501bf215546Sopenharmony_ci return PIPE_FORMAT_R16G16B16A16_SINT; 1502bf215546Sopenharmony_ci case PIPE_FORMAT_R16G16B16X16_SNORM: 1503bf215546Sopenharmony_ci return PIPE_FORMAT_R16G16B16A16_SNORM; 1504bf215546Sopenharmony_ci case PIPE_FORMAT_R16G16B16X16_UNORM: 1505bf215546Sopenharmony_ci return PIPE_FORMAT_R16G16B16A16_UNORM; 1506bf215546Sopenharmony_ci 1507bf215546Sopenharmony_ci default: 1508bf215546Sopenharmony_ci return format; 1509bf215546Sopenharmony_ci } 1510bf215546Sopenharmony_ci} 1511bf215546Sopenharmony_ci 1512bf215546Sopenharmony_ciVkFormat 1513bf215546Sopenharmony_cizink_get_format(struct zink_screen *screen, enum pipe_format format) 1514bf215546Sopenharmony_ci{ 1515bf215546Sopenharmony_ci VkFormat ret = zink_pipe_format_to_vk_format(emulate_x8(format)); 1516bf215546Sopenharmony_ci 1517bf215546Sopenharmony_ci if (format == PIPE_FORMAT_X32_S8X24_UINT && 1518bf215546Sopenharmony_ci screen->have_D32_SFLOAT_S8_UINT) 1519bf215546Sopenharmony_ci return VK_FORMAT_D32_SFLOAT_S8_UINT; 1520bf215546Sopenharmony_ci 1521bf215546Sopenharmony_ci if (format == PIPE_FORMAT_X24S8_UINT) 1522bf215546Sopenharmony_ci /* valid when using aspects to extract stencil, 1523bf215546Sopenharmony_ci * fails format test because it's emulated */ 1524bf215546Sopenharmony_ci ret = VK_FORMAT_D24_UNORM_S8_UINT; 1525bf215546Sopenharmony_ci 1526bf215546Sopenharmony_ci if (ret == VK_FORMAT_X8_D24_UNORM_PACK32 && 1527bf215546Sopenharmony_ci !screen->have_X8_D24_UNORM_PACK32) { 1528bf215546Sopenharmony_ci assert(zink_is_depth_format_supported(screen, VK_FORMAT_D32_SFLOAT)); 1529bf215546Sopenharmony_ci return VK_FORMAT_D32_SFLOAT; 1530bf215546Sopenharmony_ci } 1531bf215546Sopenharmony_ci 1532bf215546Sopenharmony_ci if (ret == VK_FORMAT_D24_UNORM_S8_UINT && 1533bf215546Sopenharmony_ci !screen->have_D24_UNORM_S8_UINT) { 1534bf215546Sopenharmony_ci assert(screen->have_D32_SFLOAT_S8_UINT); 1535bf215546Sopenharmony_ci return VK_FORMAT_D32_SFLOAT_S8_UINT; 1536bf215546Sopenharmony_ci } 1537bf215546Sopenharmony_ci 1538bf215546Sopenharmony_ci if ((ret == VK_FORMAT_A4B4G4R4_UNORM_PACK16 && 1539bf215546Sopenharmony_ci !screen->info.format_4444_feats.formatA4B4G4R4) || 1540bf215546Sopenharmony_ci (ret == VK_FORMAT_A4R4G4B4_UNORM_PACK16 && 1541bf215546Sopenharmony_ci !screen->info.format_4444_feats.formatA4R4G4B4)) 1542bf215546Sopenharmony_ci return VK_FORMAT_UNDEFINED; 1543bf215546Sopenharmony_ci 1544bf215546Sopenharmony_ci return ret; 1545bf215546Sopenharmony_ci} 1546bf215546Sopenharmony_ci 1547bf215546Sopenharmony_civoid 1548bf215546Sopenharmony_cizink_screen_init_descriptor_funcs(struct zink_screen *screen, bool fallback) 1549bf215546Sopenharmony_ci{ 1550bf215546Sopenharmony_ci if (!fallback && 1551bf215546Sopenharmony_ci zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_LAZY) { 1552bf215546Sopenharmony_ci#define LAZY(FUNC) screen->FUNC = zink_##FUNC##_lazy 1553bf215546Sopenharmony_ci LAZY(descriptor_program_init); 1554bf215546Sopenharmony_ci LAZY(descriptor_program_deinit); 1555bf215546Sopenharmony_ci LAZY(context_invalidate_descriptor_state); 1556bf215546Sopenharmony_ci LAZY(batch_descriptor_init); 1557bf215546Sopenharmony_ci LAZY(batch_descriptor_reset); 1558bf215546Sopenharmony_ci LAZY(batch_descriptor_deinit); 1559bf215546Sopenharmony_ci LAZY(descriptors_init); 1560bf215546Sopenharmony_ci LAZY(descriptors_deinit); 1561bf215546Sopenharmony_ci LAZY(descriptors_update); 1562bf215546Sopenharmony_ci#undef LAZY 1563bf215546Sopenharmony_ci } else { 1564bf215546Sopenharmony_ci#define DEFAULT(FUNC) screen->FUNC = zink_##FUNC 1565bf215546Sopenharmony_ci DEFAULT(descriptor_program_init); 1566bf215546Sopenharmony_ci DEFAULT(descriptor_program_deinit); 1567bf215546Sopenharmony_ci DEFAULT(context_invalidate_descriptor_state); 1568bf215546Sopenharmony_ci DEFAULT(batch_descriptor_init); 1569bf215546Sopenharmony_ci DEFAULT(batch_descriptor_reset); 1570bf215546Sopenharmony_ci DEFAULT(batch_descriptor_deinit); 1571bf215546Sopenharmony_ci DEFAULT(descriptors_init); 1572bf215546Sopenharmony_ci DEFAULT(descriptors_deinit); 1573bf215546Sopenharmony_ci DEFAULT(descriptors_update); 1574bf215546Sopenharmony_ci#undef DEFAULT 1575bf215546Sopenharmony_ci } 1576bf215546Sopenharmony_ci} 1577bf215546Sopenharmony_ci 1578bf215546Sopenharmony_cistatic bool 1579bf215546Sopenharmony_cicheck_have_device_time(struct zink_screen *screen) 1580bf215546Sopenharmony_ci{ 1581bf215546Sopenharmony_ci uint32_t num_domains = 0; 1582bf215546Sopenharmony_ci VkTimeDomainEXT domains[8]; //current max is 4 1583bf215546Sopenharmony_ci VkResult result = VKSCR(GetPhysicalDeviceCalibrateableTimeDomainsEXT)(screen->pdev, &num_domains, NULL); 1584bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 1585bf215546Sopenharmony_ci mesa_loge("ZINK: vkGetPhysicalDeviceCalibrateableTimeDomainsEXT failed (%s)", vk_Result_to_str(result)); 1586bf215546Sopenharmony_ci } 1587bf215546Sopenharmony_ci assert(num_domains > 0); 1588bf215546Sopenharmony_ci assert(num_domains < ARRAY_SIZE(domains)); 1589bf215546Sopenharmony_ci 1590bf215546Sopenharmony_ci result = VKSCR(GetPhysicalDeviceCalibrateableTimeDomainsEXT)(screen->pdev, &num_domains, domains); 1591bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 1592bf215546Sopenharmony_ci mesa_loge("ZINK: vkGetPhysicalDeviceCalibrateableTimeDomainsEXT failed (%s)", vk_Result_to_str(result)); 1593bf215546Sopenharmony_ci } 1594bf215546Sopenharmony_ci 1595bf215546Sopenharmony_ci /* VK_TIME_DOMAIN_DEVICE_EXT is used for the ctx->get_timestamp hook and is the only one we really need */ 1596bf215546Sopenharmony_ci for (unsigned i = 0; i < num_domains; i++) { 1597bf215546Sopenharmony_ci if (domains[i] == VK_TIME_DOMAIN_DEVICE_EXT) { 1598bf215546Sopenharmony_ci return true; 1599bf215546Sopenharmony_ci } 1600bf215546Sopenharmony_ci } 1601bf215546Sopenharmony_ci 1602bf215546Sopenharmony_ci return false; 1603bf215546Sopenharmony_ci} 1604bf215546Sopenharmony_ci 1605bf215546Sopenharmony_cistatic void 1606bf215546Sopenharmony_cizink_error(const char *msg) 1607bf215546Sopenharmony_ci{ 1608bf215546Sopenharmony_ci} 1609bf215546Sopenharmony_ci 1610bf215546Sopenharmony_cistatic void 1611bf215546Sopenharmony_cizink_warn(const char *msg) 1612bf215546Sopenharmony_ci{ 1613bf215546Sopenharmony_ci} 1614bf215546Sopenharmony_ci 1615bf215546Sopenharmony_cistatic void 1616bf215546Sopenharmony_cizink_info(const char *msg) 1617bf215546Sopenharmony_ci{ 1618bf215546Sopenharmony_ci} 1619bf215546Sopenharmony_ci 1620bf215546Sopenharmony_cistatic void 1621bf215546Sopenharmony_cizink_msg(const char *msg) 1622bf215546Sopenharmony_ci{ 1623bf215546Sopenharmony_ci} 1624bf215546Sopenharmony_ci 1625bf215546Sopenharmony_cistatic VKAPI_ATTR VkBool32 VKAPI_CALL 1626bf215546Sopenharmony_cizink_debug_util_callback( 1627bf215546Sopenharmony_ci VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, 1628bf215546Sopenharmony_ci VkDebugUtilsMessageTypeFlagsEXT messageType, 1629bf215546Sopenharmony_ci const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData, 1630bf215546Sopenharmony_ci void *pUserData) 1631bf215546Sopenharmony_ci{ 1632bf215546Sopenharmony_ci // Pick message prefix and color to use. 1633bf215546Sopenharmony_ci // Only MacOS and Linux have been tested for color support 1634bf215546Sopenharmony_ci if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) { 1635bf215546Sopenharmony_ci zink_error(pCallbackData->pMessage); 1636bf215546Sopenharmony_ci } else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) { 1637bf215546Sopenharmony_ci zink_warn(pCallbackData->pMessage); 1638bf215546Sopenharmony_ci } else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) { 1639bf215546Sopenharmony_ci zink_info(pCallbackData->pMessage); 1640bf215546Sopenharmony_ci } else 1641bf215546Sopenharmony_ci zink_msg(pCallbackData->pMessage); 1642bf215546Sopenharmony_ci 1643bf215546Sopenharmony_ci return VK_FALSE; 1644bf215546Sopenharmony_ci} 1645bf215546Sopenharmony_ci 1646bf215546Sopenharmony_cistatic bool 1647bf215546Sopenharmony_cicreate_debug(struct zink_screen *screen) 1648bf215546Sopenharmony_ci{ 1649bf215546Sopenharmony_ci VkDebugUtilsMessengerCreateInfoEXT vkDebugUtilsMessengerCreateInfoEXT = { 1650bf215546Sopenharmony_ci VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT, 1651bf215546Sopenharmony_ci NULL, 1652bf215546Sopenharmony_ci 0, // flags 1653bf215546Sopenharmony_ci VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | 1654bf215546Sopenharmony_ci VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT | 1655bf215546Sopenharmony_ci VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | 1656bf215546Sopenharmony_ci VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, 1657bf215546Sopenharmony_ci VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | 1658bf215546Sopenharmony_ci VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | 1659bf215546Sopenharmony_ci VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, 1660bf215546Sopenharmony_ci zink_debug_util_callback, 1661bf215546Sopenharmony_ci NULL 1662bf215546Sopenharmony_ci }; 1663bf215546Sopenharmony_ci 1664bf215546Sopenharmony_ci VkDebugUtilsMessengerEXT vkDebugUtilsCallbackEXT = VK_NULL_HANDLE; 1665bf215546Sopenharmony_ci 1666bf215546Sopenharmony_ci VkResult result = VKSCR(CreateDebugUtilsMessengerEXT)( 1667bf215546Sopenharmony_ci screen->instance, 1668bf215546Sopenharmony_ci &vkDebugUtilsMessengerCreateInfoEXT, 1669bf215546Sopenharmony_ci NULL, 1670bf215546Sopenharmony_ci &vkDebugUtilsCallbackEXT); 1671bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 1672bf215546Sopenharmony_ci mesa_loge("ZINK: vkCreateDebugUtilsMessengerEXT failed (%s)", vk_Result_to_str(result)); 1673bf215546Sopenharmony_ci } 1674bf215546Sopenharmony_ci 1675bf215546Sopenharmony_ci screen->debugUtilsCallbackHandle = vkDebugUtilsCallbackEXT; 1676bf215546Sopenharmony_ci 1677bf215546Sopenharmony_ci return true; 1678bf215546Sopenharmony_ci} 1679bf215546Sopenharmony_ci 1680bf215546Sopenharmony_cistatic bool 1681bf215546Sopenharmony_cizink_internal_setup_moltenvk(struct zink_screen *screen) 1682bf215546Sopenharmony_ci{ 1683bf215546Sopenharmony_ci#if defined(MVK_VERSION) 1684bf215546Sopenharmony_ci if (!screen->instance_info.have_MVK_moltenvk) 1685bf215546Sopenharmony_ci return true; 1686bf215546Sopenharmony_ci 1687bf215546Sopenharmony_ci GET_PROC_ADDR_INSTANCE_LOCAL(screen, screen->instance, GetMoltenVKConfigurationMVK); 1688bf215546Sopenharmony_ci GET_PROC_ADDR_INSTANCE_LOCAL(screen, screen->instance, SetMoltenVKConfigurationMVK); 1689bf215546Sopenharmony_ci GET_PROC_ADDR_INSTANCE_LOCAL(screen, screen->instance, GetVersionStringsMVK); 1690bf215546Sopenharmony_ci 1691bf215546Sopenharmony_ci if (vk_GetVersionStringsMVK) { 1692bf215546Sopenharmony_ci char molten_version[64] = {0}; 1693bf215546Sopenharmony_ci char vulkan_version[64] = {0}; 1694bf215546Sopenharmony_ci 1695bf215546Sopenharmony_ci vk_GetVersionStringsMVK(molten_version, sizeof(molten_version) - 1, vulkan_version, sizeof(vulkan_version) - 1); 1696bf215546Sopenharmony_ci 1697bf215546Sopenharmony_ci printf("zink: MoltenVK %s Vulkan %s \n", molten_version, vulkan_version); 1698bf215546Sopenharmony_ci } 1699bf215546Sopenharmony_ci 1700bf215546Sopenharmony_ci if (vk_GetMoltenVKConfigurationMVK && vk_SetMoltenVKConfigurationMVK) { 1701bf215546Sopenharmony_ci MVKConfiguration molten_config = {0}; 1702bf215546Sopenharmony_ci size_t molten_config_size = sizeof(molten_config); 1703bf215546Sopenharmony_ci 1704bf215546Sopenharmony_ci VkResult res = vk_GetMoltenVKConfigurationMVK(screen->instance, &molten_config, &molten_config_size); 1705bf215546Sopenharmony_ci if (res == VK_SUCCESS || res == VK_INCOMPLETE) { 1706bf215546Sopenharmony_ci // Needed to allow MoltenVK to accept VkImageView swizzles. 1707bf215546Sopenharmony_ci // Encountered when using VK_FORMAT_R8G8_UNORM 1708bf215546Sopenharmony_ci molten_config.fullImageViewSwizzle = VK_TRUE; 1709bf215546Sopenharmony_ci vk_SetMoltenVKConfigurationMVK(screen->instance, &molten_config, &molten_config_size); 1710bf215546Sopenharmony_ci } 1711bf215546Sopenharmony_ci } 1712bf215546Sopenharmony_ci#endif // MVK_VERSION 1713bf215546Sopenharmony_ci 1714bf215546Sopenharmony_ci return true; 1715bf215546Sopenharmony_ci} 1716bf215546Sopenharmony_ci 1717bf215546Sopenharmony_cistatic void 1718bf215546Sopenharmony_cipopulate_format_props(struct zink_screen *screen) 1719bf215546Sopenharmony_ci{ 1720bf215546Sopenharmony_ci for (unsigned i = 0; i < PIPE_FORMAT_COUNT; i++) { 1721bf215546Sopenharmony_ci VkFormat format = zink_get_format(screen, i); 1722bf215546Sopenharmony_ci if (!format) 1723bf215546Sopenharmony_ci continue; 1724bf215546Sopenharmony_ci if (VKSCR(GetPhysicalDeviceFormatProperties2)) { 1725bf215546Sopenharmony_ci VkFormatProperties2 props = {0}; 1726bf215546Sopenharmony_ci props.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2; 1727bf215546Sopenharmony_ci 1728bf215546Sopenharmony_ci VkDrmFormatModifierPropertiesListEXT mod_props; 1729bf215546Sopenharmony_ci VkDrmFormatModifierPropertiesEXT mods[128]; 1730bf215546Sopenharmony_ci if (screen->info.have_EXT_image_drm_format_modifier) { 1731bf215546Sopenharmony_ci mod_props.sType = VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT; 1732bf215546Sopenharmony_ci mod_props.pNext = NULL; 1733bf215546Sopenharmony_ci mod_props.drmFormatModifierCount = ARRAY_SIZE(mods); 1734bf215546Sopenharmony_ci mod_props.pDrmFormatModifierProperties = mods; 1735bf215546Sopenharmony_ci props.pNext = &mod_props; 1736bf215546Sopenharmony_ci } 1737bf215546Sopenharmony_ci VkFormatProperties3 props3 = {0}; 1738bf215546Sopenharmony_ci props3.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3; 1739bf215546Sopenharmony_ci props3.pNext = props.pNext; 1740bf215546Sopenharmony_ci props.pNext = &props3; 1741bf215546Sopenharmony_ci VKSCR(GetPhysicalDeviceFormatProperties2)(screen->pdev, format, &props); 1742bf215546Sopenharmony_ci screen->format_props[i] = props.formatProperties; 1743bf215546Sopenharmony_ci if (props3.linearTilingFeatures & VK_FORMAT_FEATURE_2_LINEAR_COLOR_ATTACHMENT_BIT_NV) 1744bf215546Sopenharmony_ci screen->format_props[i].linearTilingFeatures |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT; 1745bf215546Sopenharmony_ci if (screen->info.have_EXT_image_drm_format_modifier && mod_props.drmFormatModifierCount) { 1746bf215546Sopenharmony_ci screen->modifier_props[i].drmFormatModifierCount = mod_props.drmFormatModifierCount; 1747bf215546Sopenharmony_ci screen->modifier_props[i].pDrmFormatModifierProperties = ralloc_array(screen, VkDrmFormatModifierPropertiesEXT, mod_props.drmFormatModifierCount); 1748bf215546Sopenharmony_ci if (mod_props.pDrmFormatModifierProperties) { 1749bf215546Sopenharmony_ci for (unsigned j = 0; j < mod_props.drmFormatModifierCount; j++) 1750bf215546Sopenharmony_ci screen->modifier_props[i].pDrmFormatModifierProperties[j] = mod_props.pDrmFormatModifierProperties[j]; 1751bf215546Sopenharmony_ci } 1752bf215546Sopenharmony_ci } 1753bf215546Sopenharmony_ci } else 1754bf215546Sopenharmony_ci VKSCR(GetPhysicalDeviceFormatProperties)(screen->pdev, format, &screen->format_props[i]); 1755bf215546Sopenharmony_ci } 1756bf215546Sopenharmony_ci VkImageFormatProperties image_props; 1757bf215546Sopenharmony_ci VkResult ret = VKSCR(GetPhysicalDeviceImageFormatProperties)(screen->pdev, VK_FORMAT_D32_SFLOAT, 1758bf215546Sopenharmony_ci VK_IMAGE_TYPE_1D, 1759bf215546Sopenharmony_ci VK_IMAGE_TILING_OPTIMAL, 1760bf215546Sopenharmony_ci VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, 1761bf215546Sopenharmony_ci 0, &image_props); 1762bf215546Sopenharmony_ci if (ret != VK_SUCCESS && ret != VK_ERROR_FORMAT_NOT_SUPPORTED) { 1763bf215546Sopenharmony_ci mesa_loge("ZINK: vkGetPhysicalDeviceImageFormatProperties failed (%s)", vk_Result_to_str(ret)); 1764bf215546Sopenharmony_ci } 1765bf215546Sopenharmony_ci screen->need_2D_zs = ret != VK_SUCCESS; 1766bf215546Sopenharmony_ci 1767bf215546Sopenharmony_ci if (screen->info.feats.features.sparseResidencyImage2D) 1768bf215546Sopenharmony_ci screen->need_2D_sparse = !screen->base.get_sparse_texture_virtual_page_size(&screen->base, PIPE_TEXTURE_1D, false, PIPE_FORMAT_R32_FLOAT, 0, 16, NULL, NULL, NULL); 1769bf215546Sopenharmony_ci} 1770bf215546Sopenharmony_ci 1771bf215546Sopenharmony_cibool 1772bf215546Sopenharmony_cizink_screen_init_semaphore(struct zink_screen *screen) 1773bf215546Sopenharmony_ci{ 1774bf215546Sopenharmony_ci VkSemaphoreCreateInfo sci = {0}; 1775bf215546Sopenharmony_ci VkSemaphoreTypeCreateInfo tci = {0}; 1776bf215546Sopenharmony_ci sci.pNext = &tci; 1777bf215546Sopenharmony_ci sci.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; 1778bf215546Sopenharmony_ci tci.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO; 1779bf215546Sopenharmony_ci tci.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE; 1780bf215546Sopenharmony_ci 1781bf215546Sopenharmony_ci return VKSCR(CreateSemaphore)(screen->dev, &sci, NULL, &screen->sem) == VK_SUCCESS; 1782bf215546Sopenharmony_ci} 1783bf215546Sopenharmony_ci 1784bf215546Sopenharmony_cibool 1785bf215546Sopenharmony_cizink_screen_timeline_wait(struct zink_screen *screen, uint64_t batch_id, uint64_t timeout) 1786bf215546Sopenharmony_ci{ 1787bf215546Sopenharmony_ci VkSemaphoreWaitInfo wi = {0}; 1788bf215546Sopenharmony_ci 1789bf215546Sopenharmony_ci if (zink_screen_check_last_finished(screen, batch_id)) 1790bf215546Sopenharmony_ci return true; 1791bf215546Sopenharmony_ci 1792bf215546Sopenharmony_ci wi.sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO; 1793bf215546Sopenharmony_ci wi.semaphoreCount = 1; 1794bf215546Sopenharmony_ci wi.pSemaphores = &screen->sem; 1795bf215546Sopenharmony_ci wi.pValues = &batch_id; 1796bf215546Sopenharmony_ci bool success = false; 1797bf215546Sopenharmony_ci if (screen->device_lost) 1798bf215546Sopenharmony_ci return true; 1799bf215546Sopenharmony_ci VkResult ret = VKSCR(WaitSemaphores)(screen->dev, &wi, timeout); 1800bf215546Sopenharmony_ci success = zink_screen_handle_vkresult(screen, ret); 1801bf215546Sopenharmony_ci 1802bf215546Sopenharmony_ci if (success) 1803bf215546Sopenharmony_ci zink_screen_update_last_finished(screen, batch_id); 1804bf215546Sopenharmony_ci 1805bf215546Sopenharmony_ci return success; 1806bf215546Sopenharmony_ci} 1807bf215546Sopenharmony_ci 1808bf215546Sopenharmony_cistatic uint32_t 1809bf215546Sopenharmony_cizink_get_loader_version(struct zink_screen *screen) 1810bf215546Sopenharmony_ci{ 1811bf215546Sopenharmony_ci 1812bf215546Sopenharmony_ci uint32_t loader_version = VK_API_VERSION_1_0; 1813bf215546Sopenharmony_ci 1814bf215546Sopenharmony_ci // Get the Loader version 1815bf215546Sopenharmony_ci GET_PROC_ADDR_INSTANCE_LOCAL(screen, NULL, EnumerateInstanceVersion); 1816bf215546Sopenharmony_ci if (vk_EnumerateInstanceVersion) { 1817bf215546Sopenharmony_ci uint32_t loader_version_temp = VK_API_VERSION_1_0; 1818bf215546Sopenharmony_ci VkResult result = (*vk_EnumerateInstanceVersion)(&loader_version_temp); 1819bf215546Sopenharmony_ci if (VK_SUCCESS == result) { 1820bf215546Sopenharmony_ci loader_version = loader_version_temp; 1821bf215546Sopenharmony_ci } else { 1822bf215546Sopenharmony_ci mesa_loge("ZINK: vkEnumerateInstanceVersion failed (%s)", vk_Result_to_str(result)); 1823bf215546Sopenharmony_ci } 1824bf215546Sopenharmony_ci } 1825bf215546Sopenharmony_ci 1826bf215546Sopenharmony_ci return loader_version; 1827bf215546Sopenharmony_ci} 1828bf215546Sopenharmony_ci 1829bf215546Sopenharmony_cistatic void 1830bf215546Sopenharmony_cizink_query_memory_info(struct pipe_screen *pscreen, struct pipe_memory_info *info) 1831bf215546Sopenharmony_ci{ 1832bf215546Sopenharmony_ci struct zink_screen *screen = zink_screen(pscreen); 1833bf215546Sopenharmony_ci memset(info, 0, sizeof(struct pipe_memory_info)); 1834bf215546Sopenharmony_ci if (screen->info.have_EXT_memory_budget && VKSCR(GetPhysicalDeviceMemoryProperties2)) { 1835bf215546Sopenharmony_ci VkPhysicalDeviceMemoryProperties2 mem = {0}; 1836bf215546Sopenharmony_ci mem.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2; 1837bf215546Sopenharmony_ci 1838bf215546Sopenharmony_ci VkPhysicalDeviceMemoryBudgetPropertiesEXT budget = {0}; 1839bf215546Sopenharmony_ci budget.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT; 1840bf215546Sopenharmony_ci mem.pNext = &budget; 1841bf215546Sopenharmony_ci VKSCR(GetPhysicalDeviceMemoryProperties2)(screen->pdev, &mem); 1842bf215546Sopenharmony_ci 1843bf215546Sopenharmony_ci for (unsigned i = 0; i < mem.memoryProperties.memoryHeapCount; i++) { 1844bf215546Sopenharmony_ci if (mem.memoryProperties.memoryHeaps[i].flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) { 1845bf215546Sopenharmony_ci /* VRAM */ 1846bf215546Sopenharmony_ci info->total_device_memory += mem.memoryProperties.memoryHeaps[i].size / 1024; 1847bf215546Sopenharmony_ci info->avail_device_memory += (mem.memoryProperties.memoryHeaps[i].size - budget.heapUsage[i]) / 1024; 1848bf215546Sopenharmony_ci } else { 1849bf215546Sopenharmony_ci /* GART */ 1850bf215546Sopenharmony_ci info->total_staging_memory += mem.memoryProperties.memoryHeaps[i].size / 1024; 1851bf215546Sopenharmony_ci info->avail_staging_memory += (mem.memoryProperties.memoryHeaps[i].size - budget.heapUsage[i]) / 1024; 1852bf215546Sopenharmony_ci } 1853bf215546Sopenharmony_ci } 1854bf215546Sopenharmony_ci /* evictions not yet supported in vulkan */ 1855bf215546Sopenharmony_ci } else { 1856bf215546Sopenharmony_ci for (unsigned i = 0; i < screen->info.mem_props.memoryHeapCount; i++) { 1857bf215546Sopenharmony_ci if (screen->info.mem_props.memoryHeaps[i].flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) { 1858bf215546Sopenharmony_ci /* VRAM */ 1859bf215546Sopenharmony_ci info->total_device_memory += screen->info.mem_props.memoryHeaps[i].size / 1024; 1860bf215546Sopenharmony_ci /* free real estate! */ 1861bf215546Sopenharmony_ci info->avail_device_memory += info->total_device_memory; 1862bf215546Sopenharmony_ci } else { 1863bf215546Sopenharmony_ci /* GART */ 1864bf215546Sopenharmony_ci info->total_staging_memory += screen->info.mem_props.memoryHeaps[i].size / 1024; 1865bf215546Sopenharmony_ci /* free real estate! */ 1866bf215546Sopenharmony_ci info->avail_staging_memory += info->total_staging_memory; 1867bf215546Sopenharmony_ci } 1868bf215546Sopenharmony_ci } 1869bf215546Sopenharmony_ci } 1870bf215546Sopenharmony_ci} 1871bf215546Sopenharmony_ci 1872bf215546Sopenharmony_cistatic void 1873bf215546Sopenharmony_cizink_query_dmabuf_modifiers(struct pipe_screen *pscreen, enum pipe_format format, int max, uint64_t *modifiers, unsigned int *external_only, int *count) 1874bf215546Sopenharmony_ci{ 1875bf215546Sopenharmony_ci struct zink_screen *screen = zink_screen(pscreen); 1876bf215546Sopenharmony_ci *count = screen->modifier_props[format].drmFormatModifierCount; 1877bf215546Sopenharmony_ci for (int i = 0; i < MIN2(max, *count); i++) 1878bf215546Sopenharmony_ci modifiers[i] = screen->modifier_props[format].pDrmFormatModifierProperties[i].drmFormatModifier; 1879bf215546Sopenharmony_ci} 1880bf215546Sopenharmony_ci 1881bf215546Sopenharmony_cistatic bool 1882bf215546Sopenharmony_cizink_is_dmabuf_modifier_supported(struct pipe_screen *pscreen, uint64_t modifier, enum pipe_format format, bool *external_only) 1883bf215546Sopenharmony_ci{ 1884bf215546Sopenharmony_ci struct zink_screen *screen = zink_screen(pscreen); 1885bf215546Sopenharmony_ci for (unsigned i = 0; i < screen->modifier_props[format].drmFormatModifierCount; i++) 1886bf215546Sopenharmony_ci if (screen->modifier_props[format].pDrmFormatModifierProperties[i].drmFormatModifier == modifier) 1887bf215546Sopenharmony_ci return true; 1888bf215546Sopenharmony_ci return false; 1889bf215546Sopenharmony_ci} 1890bf215546Sopenharmony_ci 1891bf215546Sopenharmony_cistatic unsigned 1892bf215546Sopenharmony_cizink_get_dmabuf_modifier_planes(struct pipe_screen *pscreen, uint64_t modifier, enum pipe_format format) 1893bf215546Sopenharmony_ci{ 1894bf215546Sopenharmony_ci struct zink_screen *screen = zink_screen(pscreen); 1895bf215546Sopenharmony_ci for (unsigned i = 0; i < screen->modifier_props[format].drmFormatModifierCount; i++) 1896bf215546Sopenharmony_ci if (screen->modifier_props[format].pDrmFormatModifierProperties[i].drmFormatModifier == modifier) 1897bf215546Sopenharmony_ci return screen->modifier_props[format].pDrmFormatModifierProperties[i].drmFormatModifierPlaneCount; 1898bf215546Sopenharmony_ci return 0; 1899bf215546Sopenharmony_ci} 1900bf215546Sopenharmony_ci 1901bf215546Sopenharmony_cistatic int 1902bf215546Sopenharmony_cizink_get_sparse_texture_virtual_page_size(struct pipe_screen *pscreen, 1903bf215546Sopenharmony_ci enum pipe_texture_target target, 1904bf215546Sopenharmony_ci bool multi_sample, 1905bf215546Sopenharmony_ci enum pipe_format pformat, 1906bf215546Sopenharmony_ci unsigned offset, unsigned size, 1907bf215546Sopenharmony_ci int *x, int *y, int *z) 1908bf215546Sopenharmony_ci{ 1909bf215546Sopenharmony_ci struct zink_screen *screen = zink_screen(pscreen); 1910bf215546Sopenharmony_ci static const int page_size_2d[][3] = { 1911bf215546Sopenharmony_ci { 256, 256, 1 }, /* 8bpp */ 1912bf215546Sopenharmony_ci { 256, 128, 1 }, /* 16bpp */ 1913bf215546Sopenharmony_ci { 128, 128, 1 }, /* 32bpp */ 1914bf215546Sopenharmony_ci { 128, 64, 1 }, /* 64bpp */ 1915bf215546Sopenharmony_ci { 64, 64, 1 }, /* 128bpp */ 1916bf215546Sopenharmony_ci }; 1917bf215546Sopenharmony_ci static const int page_size_3d[][3] = { 1918bf215546Sopenharmony_ci { 64, 32, 32 }, /* 8bpp */ 1919bf215546Sopenharmony_ci { 32, 32, 32 }, /* 16bpp */ 1920bf215546Sopenharmony_ci { 32, 32, 16 }, /* 32bpp */ 1921bf215546Sopenharmony_ci { 32, 16, 16 }, /* 64bpp */ 1922bf215546Sopenharmony_ci { 16, 16, 16 }, /* 128bpp */ 1923bf215546Sopenharmony_ci }; 1924bf215546Sopenharmony_ci /* Only support one type of page size. */ 1925bf215546Sopenharmony_ci if (offset != 0) 1926bf215546Sopenharmony_ci return 0; 1927bf215546Sopenharmony_ci 1928bf215546Sopenharmony_ci /* reject multisample if 2x isn't supported; assume none are */ 1929bf215546Sopenharmony_ci if (multi_sample && !screen->info.feats.features.sparseResidency2Samples) 1930bf215546Sopenharmony_ci return 0; 1931bf215546Sopenharmony_ci 1932bf215546Sopenharmony_ci VkFormat format = zink_get_format(screen, pformat); 1933bf215546Sopenharmony_ci bool is_zs = util_format_is_depth_or_stencil(pformat); 1934bf215546Sopenharmony_ci VkImageType type; 1935bf215546Sopenharmony_ci switch (target) { 1936bf215546Sopenharmony_ci case PIPE_TEXTURE_1D: 1937bf215546Sopenharmony_ci case PIPE_TEXTURE_1D_ARRAY: 1938bf215546Sopenharmony_ci type = (screen->need_2D_sparse || (screen->need_2D_zs && is_zs)) ? VK_IMAGE_TYPE_2D : VK_IMAGE_TYPE_1D; 1939bf215546Sopenharmony_ci break; 1940bf215546Sopenharmony_ci 1941bf215546Sopenharmony_ci case PIPE_TEXTURE_2D: 1942bf215546Sopenharmony_ci case PIPE_TEXTURE_CUBE: 1943bf215546Sopenharmony_ci case PIPE_TEXTURE_RECT: 1944bf215546Sopenharmony_ci case PIPE_TEXTURE_2D_ARRAY: 1945bf215546Sopenharmony_ci case PIPE_TEXTURE_CUBE_ARRAY: 1946bf215546Sopenharmony_ci type = VK_IMAGE_TYPE_2D; 1947bf215546Sopenharmony_ci break; 1948bf215546Sopenharmony_ci 1949bf215546Sopenharmony_ci case PIPE_TEXTURE_3D: 1950bf215546Sopenharmony_ci type = VK_IMAGE_TYPE_3D; 1951bf215546Sopenharmony_ci break; 1952bf215546Sopenharmony_ci 1953bf215546Sopenharmony_ci case PIPE_BUFFER: 1954bf215546Sopenharmony_ci goto hack_it_up; 1955bf215546Sopenharmony_ci 1956bf215546Sopenharmony_ci default: 1957bf215546Sopenharmony_ci return 0; 1958bf215546Sopenharmony_ci } 1959bf215546Sopenharmony_ci VkImageUsageFlags flags = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | 1960bf215546Sopenharmony_ci VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 1961bf215546Sopenharmony_ci flags |= is_zs ? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT : VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 1962bf215546Sopenharmony_ci VkSparseImageFormatProperties props[4]; //planar? 1963bf215546Sopenharmony_ci unsigned prop_count = ARRAY_SIZE(props); 1964bf215546Sopenharmony_ci VKSCR(GetPhysicalDeviceSparseImageFormatProperties)(screen->pdev, format, type, 1965bf215546Sopenharmony_ci multi_sample ? VK_SAMPLE_COUNT_2_BIT : VK_SAMPLE_COUNT_1_BIT, 1966bf215546Sopenharmony_ci flags, 1967bf215546Sopenharmony_ci VK_IMAGE_TILING_OPTIMAL, 1968bf215546Sopenharmony_ci &prop_count, props); 1969bf215546Sopenharmony_ci if (!prop_count) { 1970bf215546Sopenharmony_ci if (pformat == PIPE_FORMAT_R9G9B9E5_FLOAT) { 1971bf215546Sopenharmony_ci screen->faked_e5sparse = true; 1972bf215546Sopenharmony_ci goto hack_it_up; 1973bf215546Sopenharmony_ci } 1974bf215546Sopenharmony_ci return 0; 1975bf215546Sopenharmony_ci } 1976bf215546Sopenharmony_ci 1977bf215546Sopenharmony_ci if (size) { 1978bf215546Sopenharmony_ci if (x) 1979bf215546Sopenharmony_ci *x = props[0].imageGranularity.width; 1980bf215546Sopenharmony_ci if (y) 1981bf215546Sopenharmony_ci *y = props[0].imageGranularity.height; 1982bf215546Sopenharmony_ci if (z) 1983bf215546Sopenharmony_ci *z = props[0].imageGranularity.depth; 1984bf215546Sopenharmony_ci } 1985bf215546Sopenharmony_ci 1986bf215546Sopenharmony_ci return 1; 1987bf215546Sopenharmony_cihack_it_up: 1988bf215546Sopenharmony_ci { 1989bf215546Sopenharmony_ci const int (*page_sizes)[3] = target == PIPE_TEXTURE_3D ? page_size_3d : page_size_2d; 1990bf215546Sopenharmony_ci int blk_size = util_format_get_blocksize(pformat); 1991bf215546Sopenharmony_ci 1992bf215546Sopenharmony_ci if (size) { 1993bf215546Sopenharmony_ci unsigned index = util_logbase2(blk_size); 1994bf215546Sopenharmony_ci if (x) *x = page_sizes[index][0]; 1995bf215546Sopenharmony_ci if (y) *y = page_sizes[index][1]; 1996bf215546Sopenharmony_ci if (z) *z = page_sizes[index][2]; 1997bf215546Sopenharmony_ci } 1998bf215546Sopenharmony_ci } 1999bf215546Sopenharmony_ci return 1; 2000bf215546Sopenharmony_ci} 2001bf215546Sopenharmony_ci 2002bf215546Sopenharmony_cistatic VkDevice 2003bf215546Sopenharmony_cizink_create_logical_device(struct zink_screen *screen) 2004bf215546Sopenharmony_ci{ 2005bf215546Sopenharmony_ci VkDevice dev = VK_NULL_HANDLE; 2006bf215546Sopenharmony_ci 2007bf215546Sopenharmony_ci VkDeviceQueueCreateInfo qci = {0}; 2008bf215546Sopenharmony_ci float dummy = 0.0f; 2009bf215546Sopenharmony_ci qci.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; 2010bf215546Sopenharmony_ci qci.queueFamilyIndex = screen->gfx_queue; 2011bf215546Sopenharmony_ci qci.queueCount = screen->threaded && screen->max_queues > 1 ? 2 : 1; 2012bf215546Sopenharmony_ci qci.pQueuePriorities = &dummy; 2013bf215546Sopenharmony_ci 2014bf215546Sopenharmony_ci VkDeviceCreateInfo dci = {0}; 2015bf215546Sopenharmony_ci dci.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; 2016bf215546Sopenharmony_ci dci.queueCreateInfoCount = 1; 2017bf215546Sopenharmony_ci dci.pQueueCreateInfos = &qci; 2018bf215546Sopenharmony_ci /* extensions don't have bool members in pEnabledFeatures. 2019bf215546Sopenharmony_ci * this requires us to pass the whole VkPhysicalDeviceFeatures2 struct 2020bf215546Sopenharmony_ci */ 2021bf215546Sopenharmony_ci if (screen->info.feats.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2) { 2022bf215546Sopenharmony_ci dci.pNext = &screen->info.feats; 2023bf215546Sopenharmony_ci } else { 2024bf215546Sopenharmony_ci dci.pEnabledFeatures = &screen->info.feats.features; 2025bf215546Sopenharmony_ci } 2026bf215546Sopenharmony_ci 2027bf215546Sopenharmony_ci dci.ppEnabledExtensionNames = screen->info.extensions; 2028bf215546Sopenharmony_ci dci.enabledExtensionCount = screen->info.num_extensions; 2029bf215546Sopenharmony_ci 2030bf215546Sopenharmony_ci VkResult result = VKSCR(CreateDevice)(screen->pdev, &dci, NULL, &dev); 2031bf215546Sopenharmony_ci if (result != VK_SUCCESS) 2032bf215546Sopenharmony_ci mesa_loge("ZINK: vkCreateDevice failed (%s)", vk_Result_to_str(result)); 2033bf215546Sopenharmony_ci 2034bf215546Sopenharmony_ci return dev; 2035bf215546Sopenharmony_ci} 2036bf215546Sopenharmony_ci 2037bf215546Sopenharmony_cistatic void 2038bf215546Sopenharmony_cipre_hash_descriptor_states(struct zink_screen *screen) 2039bf215546Sopenharmony_ci{ 2040bf215546Sopenharmony_ci VkImageViewCreateInfo null_info = {.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO}; 2041bf215546Sopenharmony_ci VkBufferViewCreateInfo null_binfo = {.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO}; 2042bf215546Sopenharmony_ci screen->null_descriptor_hashes.image_view = _mesa_hash_data(&null_info, sizeof(VkImageViewCreateInfo)); 2043bf215546Sopenharmony_ci screen->null_descriptor_hashes.buffer_view = _mesa_hash_data(&null_binfo, sizeof(VkBufferViewCreateInfo)); 2044bf215546Sopenharmony_ci} 2045bf215546Sopenharmony_ci 2046bf215546Sopenharmony_cistatic void 2047bf215546Sopenharmony_cicheck_base_requirements(struct zink_screen *screen) 2048bf215546Sopenharmony_ci{ 2049bf215546Sopenharmony_ci if (!screen->info.feats.features.logicOp || 2050bf215546Sopenharmony_ci !screen->info.feats.features.fillModeNonSolid || 2051bf215546Sopenharmony_ci !screen->info.feats.features.shaderClipDistance || 2052bf215546Sopenharmony_ci !(screen->info.feats12.scalarBlockLayout || 2053bf215546Sopenharmony_ci screen->info.have_EXT_scalar_block_layout) || 2054bf215546Sopenharmony_ci !screen->info.have_KHR_maintenance1 || 2055bf215546Sopenharmony_ci !screen->info.have_EXT_custom_border_color || 2056bf215546Sopenharmony_ci !screen->info.have_EXT_line_rasterization) { 2057bf215546Sopenharmony_ci fprintf(stderr, "WARNING: Some incorrect rendering " 2058bf215546Sopenharmony_ci "might occur because the selected Vulkan device (%s) doesn't support " 2059bf215546Sopenharmony_ci "base Zink requirements: ", screen->info.props.deviceName); 2060bf215546Sopenharmony_ci#define CHECK_OR_PRINT(X) \ 2061bf215546Sopenharmony_ci if (!screen->info.X) \ 2062bf215546Sopenharmony_ci fprintf(stderr, "%s ", #X) 2063bf215546Sopenharmony_ci CHECK_OR_PRINT(feats.features.logicOp); 2064bf215546Sopenharmony_ci CHECK_OR_PRINT(feats.features.fillModeNonSolid); 2065bf215546Sopenharmony_ci CHECK_OR_PRINT(feats.features.shaderClipDistance); 2066bf215546Sopenharmony_ci if (!screen->info.feats12.scalarBlockLayout && !screen->info.have_EXT_scalar_block_layout) 2067bf215546Sopenharmony_ci printf("scalarBlockLayout OR EXT_scalar_block_layout "); 2068bf215546Sopenharmony_ci CHECK_OR_PRINT(have_KHR_maintenance1); 2069bf215546Sopenharmony_ci CHECK_OR_PRINT(have_EXT_custom_border_color); 2070bf215546Sopenharmony_ci CHECK_OR_PRINT(have_EXT_line_rasterization); 2071bf215546Sopenharmony_ci fprintf(stderr, "\n"); 2072bf215546Sopenharmony_ci } 2073bf215546Sopenharmony_ci} 2074bf215546Sopenharmony_ci 2075bf215546Sopenharmony_cistatic void 2076bf215546Sopenharmony_cizink_get_sample_pixel_grid(struct pipe_screen *pscreen, unsigned sample_count, 2077bf215546Sopenharmony_ci unsigned *width, unsigned *height) 2078bf215546Sopenharmony_ci{ 2079bf215546Sopenharmony_ci struct zink_screen *screen = zink_screen(pscreen); 2080bf215546Sopenharmony_ci unsigned idx = util_logbase2_ceil(MAX2(sample_count, 1)); 2081bf215546Sopenharmony_ci assert(idx < ARRAY_SIZE(screen->maxSampleLocationGridSize)); 2082bf215546Sopenharmony_ci *width = screen->maxSampleLocationGridSize[idx].width; 2083bf215546Sopenharmony_ci *height = screen->maxSampleLocationGridSize[idx].height; 2084bf215546Sopenharmony_ci} 2085bf215546Sopenharmony_ci 2086bf215546Sopenharmony_cistatic void 2087bf215546Sopenharmony_ciinit_driver_workarounds(struct zink_screen *screen) 2088bf215546Sopenharmony_ci{ 2089bf215546Sopenharmony_ci /* enable implicit sync for all non-mesa drivers */ 2090bf215546Sopenharmony_ci screen->driver_workarounds.implicit_sync = true; 2091bf215546Sopenharmony_ci switch (screen->info.driver_props.driverID) { 2092bf215546Sopenharmony_ci case VK_DRIVER_ID_MESA_RADV: 2093bf215546Sopenharmony_ci case VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA: 2094bf215546Sopenharmony_ci case VK_DRIVER_ID_MESA_LLVMPIPE: 2095bf215546Sopenharmony_ci case VK_DRIVER_ID_MESA_TURNIP: 2096bf215546Sopenharmony_ci case VK_DRIVER_ID_MESA_V3DV: 2097bf215546Sopenharmony_ci case VK_DRIVER_ID_MESA_PANVK: 2098bf215546Sopenharmony_ci case VK_DRIVER_ID_MESA_VENUS: 2099bf215546Sopenharmony_ci screen->driver_workarounds.implicit_sync = false; 2100bf215546Sopenharmony_ci break; 2101bf215546Sopenharmony_ci default: 2102bf215546Sopenharmony_ci break; 2103bf215546Sopenharmony_ci } 2104bf215546Sopenharmony_ci 2105bf215546Sopenharmony_ci screen->driver_workarounds.color_write_missing = 2106bf215546Sopenharmony_ci !screen->info.have_EXT_color_write_enable || 2107bf215546Sopenharmony_ci !screen->info.cwrite_feats.colorWriteEnable; 2108bf215546Sopenharmony_ci 2109bf215546Sopenharmony_ci screen->driver_workarounds.depth_clip_control_missing = !screen->info.have_EXT_depth_clip_control; 2110bf215546Sopenharmony_ci if (screen->info.driver_props.driverID == VK_DRIVER_ID_AMD_PROPRIETARY) 2111bf215546Sopenharmony_ci /* this completely breaks xfb somehow */ 2112bf215546Sopenharmony_ci screen->info.have_EXT_extended_dynamic_state2 = false; 2113bf215546Sopenharmony_ci if (screen->info.driver_props.driverID == VK_DRIVER_ID_MESA_TURNIP) { 2114bf215546Sopenharmony_ci /* performance */ 2115bf215546Sopenharmony_ci screen->info.border_color_feats.customBorderColorWithoutFormat = VK_FALSE; 2116bf215546Sopenharmony_ci } 2117bf215546Sopenharmony_ci if (screen->info.driver_props.driverID == VK_DRIVER_ID_AMD_OPEN_SOURCE || 2118bf215546Sopenharmony_ci screen->info.driver_props.driverID == VK_DRIVER_ID_AMD_PROPRIETARY || 2119bf215546Sopenharmony_ci screen->info.driver_props.driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY || 2120bf215546Sopenharmony_ci screen->info.driver_props.driverID == VK_DRIVER_ID_MESA_RADV) 2121bf215546Sopenharmony_ci screen->driver_workarounds.z24_unscaled_bias = 1<<23; 2122bf215546Sopenharmony_ci else 2123bf215546Sopenharmony_ci screen->driver_workarounds.z24_unscaled_bias = 1<<24; 2124bf215546Sopenharmony_ci if (screen->info.driver_props.driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY) 2125bf215546Sopenharmony_ci screen->driver_workarounds.z16_unscaled_bias = 1<<15; 2126bf215546Sopenharmony_ci else 2127bf215546Sopenharmony_ci screen->driver_workarounds.z16_unscaled_bias = 1<<16; 2128bf215546Sopenharmony_ci} 2129bf215546Sopenharmony_ci 2130bf215546Sopenharmony_cistatic struct zink_screen * 2131bf215546Sopenharmony_cizink_internal_create_screen(const struct pipe_screen_config *config) 2132bf215546Sopenharmony_ci{ 2133bf215546Sopenharmony_ci if (getenv("ZINK_USE_LAVAPIPE")) { 2134bf215546Sopenharmony_ci mesa_loge("ZINK_USE_LAVAPIPE is obsolete. Use LIBGL_ALWAYS_SOFTWARE\n"); 2135bf215546Sopenharmony_ci return NULL; 2136bf215546Sopenharmony_ci } 2137bf215546Sopenharmony_ci 2138bf215546Sopenharmony_ci struct zink_screen *screen = rzalloc(NULL, struct zink_screen); 2139bf215546Sopenharmony_ci if (!screen) 2140bf215546Sopenharmony_ci return NULL; 2141bf215546Sopenharmony_ci 2142bf215546Sopenharmony_ci screen->threaded = util_get_cpu_caps()->nr_cpus > 1 && debug_get_bool_option("GALLIUM_THREAD", util_get_cpu_caps()->nr_cpus > 1); 2143bf215546Sopenharmony_ci screen->abort_on_hang = debug_get_bool_option("ZINK_HANG_ABORT", false); 2144bf215546Sopenharmony_ci 2145bf215546Sopenharmony_ci zink_debug = debug_get_option_zink_debug(); 2146bf215546Sopenharmony_ci zink_descriptor_mode = debug_get_option_zink_descriptor_mode(); 2147bf215546Sopenharmony_ci if (zink_descriptor_mode > ZINK_DESCRIPTOR_MODE_NOTEMPLATES) { 2148bf215546Sopenharmony_ci printf("Specify exactly one descriptor mode.\n"); 2149bf215546Sopenharmony_ci abort(); 2150bf215546Sopenharmony_ci } 2151bf215546Sopenharmony_ci 2152bf215546Sopenharmony_ci screen->loader_lib = util_dl_open(VK_LIBNAME); 2153bf215546Sopenharmony_ci if (!screen->loader_lib) 2154bf215546Sopenharmony_ci goto fail; 2155bf215546Sopenharmony_ci 2156bf215546Sopenharmony_ci screen->vk_GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)util_dl_get_proc_address(screen->loader_lib, "vkGetInstanceProcAddr"); 2157bf215546Sopenharmony_ci screen->vk_GetDeviceProcAddr = (PFN_vkGetDeviceProcAddr)util_dl_get_proc_address(screen->loader_lib, "vkGetDeviceProcAddr"); 2158bf215546Sopenharmony_ci if (!screen->vk_GetInstanceProcAddr || 2159bf215546Sopenharmony_ci !screen->vk_GetDeviceProcAddr) 2160bf215546Sopenharmony_ci goto fail; 2161bf215546Sopenharmony_ci 2162bf215546Sopenharmony_ci screen->instance_info.loader_version = zink_get_loader_version(screen); 2163bf215546Sopenharmony_ci#if WITH_XMLCONFIG 2164bf215546Sopenharmony_ci if (config) { 2165bf215546Sopenharmony_ci driParseConfigFiles(config->options, config->options_info, 0, "zink", 2166bf215546Sopenharmony_ci NULL, NULL, NULL, 0, NULL, 0); 2167bf215546Sopenharmony_ci screen->driconf.dual_color_blend_by_location = driQueryOptionb(config->options, "dual_color_blend_by_location"); 2168bf215546Sopenharmony_ci //screen->driconf.inline_uniforms = driQueryOptionb(config->options, "radeonsi_inline_uniforms"); 2169bf215546Sopenharmony_ci screen->instance_info.disable_xcb_surface = driQueryOptionb(config->options, "disable_xcb_surface"); 2170bf215546Sopenharmony_ci } 2171bf215546Sopenharmony_ci#endif 2172bf215546Sopenharmony_ci 2173bf215546Sopenharmony_ci if (!zink_create_instance(screen)) 2174bf215546Sopenharmony_ci goto fail; 2175bf215546Sopenharmony_ci 2176bf215546Sopenharmony_ci vk_instance_dispatch_table_load(&screen->vk.instance, 2177bf215546Sopenharmony_ci screen->vk_GetInstanceProcAddr, 2178bf215546Sopenharmony_ci screen->instance); 2179bf215546Sopenharmony_ci vk_physical_device_dispatch_table_load(&screen->vk.physical_device, 2180bf215546Sopenharmony_ci screen->vk_GetInstanceProcAddr, 2181bf215546Sopenharmony_ci screen->instance); 2182bf215546Sopenharmony_ci 2183bf215546Sopenharmony_ci zink_verify_instance_extensions(screen); 2184bf215546Sopenharmony_ci 2185bf215546Sopenharmony_ci if (screen->instance_info.have_EXT_debug_utils && 2186bf215546Sopenharmony_ci (zink_debug & ZINK_DEBUG_VALIDATION) && !create_debug(screen)) 2187bf215546Sopenharmony_ci debug_printf("ZINK: failed to setup debug utils\n"); 2188bf215546Sopenharmony_ci 2189bf215546Sopenharmony_ci screen->is_cpu = choose_pdev(screen); 2190bf215546Sopenharmony_ci if (screen->pdev == VK_NULL_HANDLE) 2191bf215546Sopenharmony_ci goto fail; 2192bf215546Sopenharmony_ci 2193bf215546Sopenharmony_ci update_queue_props(screen); 2194bf215546Sopenharmony_ci 2195bf215546Sopenharmony_ci screen->have_X8_D24_UNORM_PACK32 = zink_is_depth_format_supported(screen, 2196bf215546Sopenharmony_ci VK_FORMAT_X8_D24_UNORM_PACK32); 2197bf215546Sopenharmony_ci screen->have_D24_UNORM_S8_UINT = zink_is_depth_format_supported(screen, 2198bf215546Sopenharmony_ci VK_FORMAT_D24_UNORM_S8_UINT); 2199bf215546Sopenharmony_ci screen->have_D32_SFLOAT_S8_UINT = zink_is_depth_format_supported(screen, 2200bf215546Sopenharmony_ci VK_FORMAT_D32_SFLOAT_S8_UINT); 2201bf215546Sopenharmony_ci 2202bf215546Sopenharmony_ci if (!zink_get_physical_device_info(screen)) { 2203bf215546Sopenharmony_ci debug_printf("ZINK: failed to detect features\n"); 2204bf215546Sopenharmony_ci goto fail; 2205bf215546Sopenharmony_ci } 2206bf215546Sopenharmony_ci 2207bf215546Sopenharmony_ci if (screen->threaded && !util_queue_init(&screen->flush_queue, "zfq", 8, 1, UTIL_QUEUE_INIT_RESIZE_IF_FULL, screen)) { 2208bf215546Sopenharmony_ci mesa_loge("zink: Failed to create flush queue.\n"); 2209bf215546Sopenharmony_ci goto fail; 2210bf215546Sopenharmony_ci } 2211bf215546Sopenharmony_ci 2212bf215546Sopenharmony_ci zink_internal_setup_moltenvk(screen); 2213bf215546Sopenharmony_ci if (!screen->info.have_KHR_timeline_semaphore) { 2214bf215546Sopenharmony_ci mesa_loge("zink: KHR_timeline_semaphore is required"); 2215bf215546Sopenharmony_ci goto fail; 2216bf215546Sopenharmony_ci } 2217bf215546Sopenharmony_ci 2218bf215546Sopenharmony_ci init_driver_workarounds(screen); 2219bf215546Sopenharmony_ci 2220bf215546Sopenharmony_ci screen->dev = zink_create_logical_device(screen); 2221bf215546Sopenharmony_ci if (!screen->dev) 2222bf215546Sopenharmony_ci goto fail; 2223bf215546Sopenharmony_ci 2224bf215546Sopenharmony_ci vk_device_dispatch_table_load(&screen->vk.device, 2225bf215546Sopenharmony_ci screen->vk_GetDeviceProcAddr, 2226bf215546Sopenharmony_ci screen->dev); 2227bf215546Sopenharmony_ci 2228bf215546Sopenharmony_ci init_queue(screen); 2229bf215546Sopenharmony_ci if (screen->info.driver_props.driverID == VK_DRIVER_ID_MESA_RADV || 2230bf215546Sopenharmony_ci screen->info.driver_props.driverID == VK_DRIVER_ID_AMD_OPEN_SOURCE || 2231bf215546Sopenharmony_ci screen->info.driver_props.driverID == VK_DRIVER_ID_AMD_PROPRIETARY) 2232bf215546Sopenharmony_ci /* this has bad perf on AMD */ 2233bf215546Sopenharmony_ci screen->info.have_KHR_push_descriptor = false; 2234bf215546Sopenharmony_ci 2235bf215546Sopenharmony_ci zink_verify_device_extensions(screen); 2236bf215546Sopenharmony_ci 2237bf215546Sopenharmony_ci if ((zink_debug & ZINK_DEBUG_COMPACT) || 2238bf215546Sopenharmony_ci screen->info.props.limits.maxBoundDescriptorSets < ZINK_MAX_DESCRIPTOR_SETS) { 2239bf215546Sopenharmony_ci screen->desc_set_id[ZINK_DESCRIPTOR_TYPES] = 0; 2240bf215546Sopenharmony_ci screen->desc_set_id[ZINK_DESCRIPTOR_TYPE_UBO] = 1; 2241bf215546Sopenharmony_ci screen->desc_set_id[ZINK_DESCRIPTOR_TYPE_SSBO] = 1; 2242bf215546Sopenharmony_ci screen->desc_set_id[ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW] = 2; 2243bf215546Sopenharmony_ci screen->desc_set_id[ZINK_DESCRIPTOR_TYPE_IMAGE] = 2; 2244bf215546Sopenharmony_ci screen->desc_set_id[ZINK_DESCRIPTOR_BINDLESS] = 3; 2245bf215546Sopenharmony_ci screen->compact_descriptors = true; 2246bf215546Sopenharmony_ci } else { 2247bf215546Sopenharmony_ci screen->desc_set_id[ZINK_DESCRIPTOR_TYPES] = 0; 2248bf215546Sopenharmony_ci screen->desc_set_id[ZINK_DESCRIPTOR_TYPE_UBO] = 1; 2249bf215546Sopenharmony_ci screen->desc_set_id[ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW] = 2; 2250bf215546Sopenharmony_ci screen->desc_set_id[ZINK_DESCRIPTOR_TYPE_SSBO] = 3; 2251bf215546Sopenharmony_ci screen->desc_set_id[ZINK_DESCRIPTOR_TYPE_IMAGE] = 4; 2252bf215546Sopenharmony_ci screen->desc_set_id[ZINK_DESCRIPTOR_BINDLESS] = 5; 2253bf215546Sopenharmony_ci } 2254bf215546Sopenharmony_ci if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_AUTO) { 2255bf215546Sopenharmony_ci if (screen->info.have_KHR_descriptor_update_template) 2256bf215546Sopenharmony_ci zink_descriptor_mode = ZINK_DESCRIPTOR_MODE_LAZY; 2257bf215546Sopenharmony_ci else 2258bf215546Sopenharmony_ci zink_descriptor_mode = ZINK_DESCRIPTOR_MODE_CACHED; 2259bf215546Sopenharmony_ci } 2260bf215546Sopenharmony_ci 2261bf215546Sopenharmony_ci if (screen->info.have_EXT_calibrated_timestamps && !check_have_device_time(screen)) 2262bf215546Sopenharmony_ci goto fail; 2263bf215546Sopenharmony_ci 2264bf215546Sopenharmony_ci screen->have_triangle_fans = true; 2265bf215546Sopenharmony_ci#if defined(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME) 2266bf215546Sopenharmony_ci if (screen->info.have_KHR_portability_subset) { 2267bf215546Sopenharmony_ci screen->have_triangle_fans = (VK_TRUE == screen->info.portability_subset_feats.triangleFans); 2268bf215546Sopenharmony_ci } 2269bf215546Sopenharmony_ci#endif // VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME 2270bf215546Sopenharmony_ci 2271bf215546Sopenharmony_ci check_base_requirements(screen); 2272bf215546Sopenharmony_ci util_live_shader_cache_init(&screen->shaders, zink_create_gfx_shader_state, zink_delete_shader_state); 2273bf215546Sopenharmony_ci 2274bf215546Sopenharmony_ci screen->base.get_name = zink_get_name; 2275bf215546Sopenharmony_ci if (screen->instance_info.have_KHR_external_memory_capabilities) { 2276bf215546Sopenharmony_ci screen->base.get_device_uuid = zink_get_device_uuid; 2277bf215546Sopenharmony_ci screen->base.get_driver_uuid = zink_get_driver_uuid; 2278bf215546Sopenharmony_ci } 2279bf215546Sopenharmony_ci if (screen->info.have_KHR_external_memory_win32) { 2280bf215546Sopenharmony_ci screen->base.get_device_luid = zink_get_device_luid; 2281bf215546Sopenharmony_ci screen->base.get_device_node_mask = zink_get_device_node_mask; 2282bf215546Sopenharmony_ci } 2283bf215546Sopenharmony_ci screen->base.get_vendor = zink_get_vendor; 2284bf215546Sopenharmony_ci screen->base.get_device_vendor = zink_get_device_vendor; 2285bf215546Sopenharmony_ci screen->base.get_compute_param = zink_get_compute_param; 2286bf215546Sopenharmony_ci screen->base.get_timestamp = zink_get_timestamp; 2287bf215546Sopenharmony_ci screen->base.query_memory_info = zink_query_memory_info; 2288bf215546Sopenharmony_ci screen->base.get_param = zink_get_param; 2289bf215546Sopenharmony_ci screen->base.get_paramf = zink_get_paramf; 2290bf215546Sopenharmony_ci screen->base.get_shader_param = zink_get_shader_param; 2291bf215546Sopenharmony_ci screen->base.get_compiler_options = zink_get_compiler_options; 2292bf215546Sopenharmony_ci screen->base.get_sample_pixel_grid = zink_get_sample_pixel_grid; 2293bf215546Sopenharmony_ci screen->base.is_compute_copy_faster = zink_is_compute_copy_faster; 2294bf215546Sopenharmony_ci screen->base.is_format_supported = zink_is_format_supported; 2295bf215546Sopenharmony_ci if (screen->info.have_EXT_image_drm_format_modifier && screen->info.have_EXT_external_memory_dma_buf) { 2296bf215546Sopenharmony_ci screen->base.query_dmabuf_modifiers = zink_query_dmabuf_modifiers; 2297bf215546Sopenharmony_ci screen->base.is_dmabuf_modifier_supported = zink_is_dmabuf_modifier_supported; 2298bf215546Sopenharmony_ci screen->base.get_dmabuf_modifier_planes = zink_get_dmabuf_modifier_planes; 2299bf215546Sopenharmony_ci } 2300bf215546Sopenharmony_ci#if defined(_WIN32) 2301bf215546Sopenharmony_ci if (screen->info.have_KHR_external_memory_win32) 2302bf215546Sopenharmony_ci screen->base.create_fence_win32 = zink_create_fence_win32; 2303bf215546Sopenharmony_ci#endif 2304bf215546Sopenharmony_ci screen->base.context_create = zink_context_create; 2305bf215546Sopenharmony_ci screen->base.flush_frontbuffer = zink_flush_frontbuffer; 2306bf215546Sopenharmony_ci screen->base.destroy = zink_destroy_screen; 2307bf215546Sopenharmony_ci screen->base.finalize_nir = zink_shader_finalize; 2308bf215546Sopenharmony_ci screen->base.get_sparse_texture_virtual_page_size = zink_get_sparse_texture_virtual_page_size; 2309bf215546Sopenharmony_ci 2310bf215546Sopenharmony_ci if (screen->info.have_EXT_sample_locations) { 2311bf215546Sopenharmony_ci VkMultisamplePropertiesEXT prop; 2312bf215546Sopenharmony_ci prop.sType = VK_STRUCTURE_TYPE_MULTISAMPLE_PROPERTIES_EXT; 2313bf215546Sopenharmony_ci prop.pNext = NULL; 2314bf215546Sopenharmony_ci for (unsigned i = 0; i < ARRAY_SIZE(screen->maxSampleLocationGridSize); i++) { 2315bf215546Sopenharmony_ci if (screen->info.sample_locations_props.sampleLocationSampleCounts & (1 << i)) { 2316bf215546Sopenharmony_ci VKSCR(GetPhysicalDeviceMultisamplePropertiesEXT)(screen->pdev, 1 << i, &prop); 2317bf215546Sopenharmony_ci screen->maxSampleLocationGridSize[i] = prop.maxSampleLocationGridSize; 2318bf215546Sopenharmony_ci } 2319bf215546Sopenharmony_ci } 2320bf215546Sopenharmony_ci } 2321bf215546Sopenharmony_ci 2322bf215546Sopenharmony_ci if (!zink_screen_resource_init(&screen->base)) 2323bf215546Sopenharmony_ci goto fail; 2324bf215546Sopenharmony_ci zink_bo_init(screen); 2325bf215546Sopenharmony_ci zink_screen_fence_init(&screen->base); 2326bf215546Sopenharmony_ci 2327bf215546Sopenharmony_ci zink_screen_init_compiler(screen); 2328bf215546Sopenharmony_ci if (!disk_cache_init(screen)) 2329bf215546Sopenharmony_ci goto fail; 2330bf215546Sopenharmony_ci populate_format_props(screen); 2331bf215546Sopenharmony_ci pre_hash_descriptor_states(screen); 2332bf215546Sopenharmony_ci 2333bf215546Sopenharmony_ci slab_create_parent(&screen->transfer_pool, sizeof(struct zink_transfer), 16); 2334bf215546Sopenharmony_ci 2335bf215546Sopenharmony_ci screen->driconf.inline_uniforms = debug_get_bool_option("ZINK_INLINE_UNIFORMS", screen->is_cpu); 2336bf215546Sopenharmony_ci 2337bf215546Sopenharmony_ci screen->total_video_mem = get_video_mem(screen); 2338bf215546Sopenharmony_ci screen->clamp_video_mem = screen->total_video_mem * 0.8; 2339bf215546Sopenharmony_ci if (!os_get_total_physical_memory(&screen->total_mem)) 2340bf215546Sopenharmony_ci goto fail; 2341bf215546Sopenharmony_ci 2342bf215546Sopenharmony_ci if (!zink_screen_init_semaphore(screen)) { 2343bf215546Sopenharmony_ci mesa_loge("zink: failed to create timeline semaphore"); 2344bf215546Sopenharmony_ci goto fail; 2345bf215546Sopenharmony_ci } 2346bf215546Sopenharmony_ci 2347bf215546Sopenharmony_ci memset(&screen->heap_map, UINT8_MAX, sizeof(screen->heap_map)); 2348bf215546Sopenharmony_ci for (enum zink_heap i = 0; i < ZINK_HEAP_MAX; i++) { 2349bf215546Sopenharmony_ci for (unsigned j = 0; j < screen->info.mem_props.memoryTypeCount; j++) { 2350bf215546Sopenharmony_ci VkMemoryPropertyFlags domains = vk_domain_from_heap(i); 2351bf215546Sopenharmony_ci if ((screen->info.mem_props.memoryTypes[j].propertyFlags & domains) == domains) { 2352bf215546Sopenharmony_ci assert(screen->heap_map[i] == UINT8_MAX); 2353bf215546Sopenharmony_ci screen->heap_map[i] = j; 2354bf215546Sopenharmony_ci break; 2355bf215546Sopenharmony_ci } 2356bf215546Sopenharmony_ci } 2357bf215546Sopenharmony_ci 2358bf215546Sopenharmony_ci /* not found: use compatible heap */ 2359bf215546Sopenharmony_ci if (screen->heap_map[i] == UINT8_MAX) { 2360bf215546Sopenharmony_ci /* only cached mem has a failure case for now */ 2361bf215546Sopenharmony_ci assert(i == ZINK_HEAP_HOST_VISIBLE_CACHED || i == ZINK_HEAP_DEVICE_LOCAL_LAZY || 2362bf215546Sopenharmony_ci i == ZINK_HEAP_DEVICE_LOCAL_VISIBLE); 2363bf215546Sopenharmony_ci if (i == ZINK_HEAP_HOST_VISIBLE_CACHED) 2364bf215546Sopenharmony_ci screen->heap_map[i] = screen->heap_map[ZINK_HEAP_HOST_VISIBLE_COHERENT]; 2365bf215546Sopenharmony_ci else 2366bf215546Sopenharmony_ci screen->heap_map[i] = screen->heap_map[ZINK_HEAP_DEVICE_LOCAL]; 2367bf215546Sopenharmony_ci } 2368bf215546Sopenharmony_ci screen->heap_flags[i] = screen->info.mem_props.memoryTypes[screen->heap_map[i]].propertyFlags; 2369bf215546Sopenharmony_ci } 2370bf215546Sopenharmony_ci { 2371bf215546Sopenharmony_ci unsigned vis_vram = screen->heap_map[ZINK_HEAP_DEVICE_LOCAL_VISIBLE]; 2372bf215546Sopenharmony_ci unsigned vram = screen->heap_map[ZINK_HEAP_DEVICE_LOCAL]; 2373bf215546Sopenharmony_ci /* determine if vis vram is roughly equal to total vram */ 2374bf215546Sopenharmony_ci if (screen->info.mem_props.memoryHeaps[screen->info.mem_props.memoryTypes[vis_vram].heapIndex].size > 2375bf215546Sopenharmony_ci screen->info.mem_props.memoryHeaps[screen->info.mem_props.memoryTypes[vram].heapIndex].size * 0.9) 2376bf215546Sopenharmony_ci screen->resizable_bar = true; 2377bf215546Sopenharmony_ci } 2378bf215546Sopenharmony_ci 2379bf215546Sopenharmony_ci simple_mtx_init(&screen->dt_lock, mtx_plain); 2380bf215546Sopenharmony_ci 2381bf215546Sopenharmony_ci zink_screen_init_descriptor_funcs(screen, false); 2382bf215546Sopenharmony_ci util_idalloc_mt_init_tc(&screen->buffer_ids); 2383bf215546Sopenharmony_ci 2384bf215546Sopenharmony_ci util_vertex_state_cache_init(&screen->vertex_state_cache, 2385bf215546Sopenharmony_ci zink_create_vertex_state, zink_vertex_state_destroy); 2386bf215546Sopenharmony_ci screen->base.create_vertex_state = zink_cache_create_vertex_state; 2387bf215546Sopenharmony_ci screen->base.vertex_state_destroy = zink_cache_vertex_state_destroy; 2388bf215546Sopenharmony_ci glsl_type_singleton_init_or_ref(); 2389bf215546Sopenharmony_ci 2390bf215546Sopenharmony_ci screen->copy_context = zink_context(screen->base.context_create(&screen->base, NULL, ZINK_CONTEXT_COPY_ONLY)); 2391bf215546Sopenharmony_ci if (!screen->copy_context) { 2392bf215546Sopenharmony_ci mesa_loge("zink: failed to create copy context"); 2393bf215546Sopenharmony_ci goto fail; 2394bf215546Sopenharmony_ci } 2395bf215546Sopenharmony_ci 2396bf215546Sopenharmony_ci return screen; 2397bf215546Sopenharmony_ci 2398bf215546Sopenharmony_cifail: 2399bf215546Sopenharmony_ci if (screen->loader_lib) 2400bf215546Sopenharmony_ci util_dl_close(screen->loader_lib); 2401bf215546Sopenharmony_ci if (screen->threaded) 2402bf215546Sopenharmony_ci util_queue_destroy(&screen->flush_queue); 2403bf215546Sopenharmony_ci 2404bf215546Sopenharmony_ci ralloc_free(screen); 2405bf215546Sopenharmony_ci return NULL; 2406bf215546Sopenharmony_ci} 2407bf215546Sopenharmony_ci 2408bf215546Sopenharmony_cistruct pipe_screen * 2409bf215546Sopenharmony_cizink_create_screen(struct sw_winsys *winsys, const struct pipe_screen_config *config) 2410bf215546Sopenharmony_ci{ 2411bf215546Sopenharmony_ci struct zink_screen *ret = zink_internal_create_screen(config); 2412bf215546Sopenharmony_ci if (ret) { 2413bf215546Sopenharmony_ci ret->drm_fd = -1; 2414bf215546Sopenharmony_ci } 2415bf215546Sopenharmony_ci 2416bf215546Sopenharmony_ci return &ret->base; 2417bf215546Sopenharmony_ci} 2418bf215546Sopenharmony_ci 2419bf215546Sopenharmony_cistruct pipe_screen * 2420bf215546Sopenharmony_cizink_drm_create_screen(int fd, const struct pipe_screen_config *config) 2421bf215546Sopenharmony_ci{ 2422bf215546Sopenharmony_ci struct zink_screen *ret = zink_internal_create_screen(config); 2423bf215546Sopenharmony_ci 2424bf215546Sopenharmony_ci if (ret) 2425bf215546Sopenharmony_ci ret->drm_fd = os_dupfd_cloexec(fd); 2426bf215546Sopenharmony_ci if (ret && !ret->info.have_KHR_external_memory_fd) { 2427bf215546Sopenharmony_ci debug_printf("ZINK: KHR_external_memory_fd required!\n"); 2428bf215546Sopenharmony_ci zink_destroy_screen(&ret->base); 2429bf215546Sopenharmony_ci return NULL; 2430bf215546Sopenharmony_ci } 2431bf215546Sopenharmony_ci 2432bf215546Sopenharmony_ci return &ret->base; 2433bf215546Sopenharmony_ci} 2434bf215546Sopenharmony_ci 2435bf215546Sopenharmony_civoid zink_stub_function_not_loaded() 2436bf215546Sopenharmony_ci{ 2437bf215546Sopenharmony_ci /* this will be used by the zink_verify_*_extensions() functions on a 2438bf215546Sopenharmony_ci * release build 2439bf215546Sopenharmony_ci */ 2440bf215546Sopenharmony_ci mesa_loge("ZINK: a Vulkan function was called without being loaded"); 2441bf215546Sopenharmony_ci abort(); 2442bf215546Sopenharmony_ci} 2443