1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2021 Intel Corporation 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 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * 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 NONINFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21bf215546Sopenharmony_ci * IN THE SOFTWARE. 22bf215546Sopenharmony_ci */ 23bf215546Sopenharmony_ci 24bf215546Sopenharmony_ci#include "vk_sync.h" 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_ci#include <assert.h> 27bf215546Sopenharmony_ci#include <string.h> 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_ci#include "util/debug.h" 30bf215546Sopenharmony_ci#include "util/macros.h" 31bf215546Sopenharmony_ci#include "util/os_time.h" 32bf215546Sopenharmony_ci 33bf215546Sopenharmony_ci#include "vk_alloc.h" 34bf215546Sopenharmony_ci#include "vk_device.h" 35bf215546Sopenharmony_ci#include "vk_log.h" 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_cistatic void 38bf215546Sopenharmony_civk_sync_type_validate(const struct vk_sync_type *type) 39bf215546Sopenharmony_ci{ 40bf215546Sopenharmony_ci assert(type->init); 41bf215546Sopenharmony_ci assert(type->finish); 42bf215546Sopenharmony_ci 43bf215546Sopenharmony_ci assert(type->features & (VK_SYNC_FEATURE_BINARY | 44bf215546Sopenharmony_ci VK_SYNC_FEATURE_TIMELINE)); 45bf215546Sopenharmony_ci 46bf215546Sopenharmony_ci if (type->features & VK_SYNC_FEATURE_TIMELINE) { 47bf215546Sopenharmony_ci assert(type->features & VK_SYNC_FEATURE_GPU_WAIT); 48bf215546Sopenharmony_ci assert(type->features & VK_SYNC_FEATURE_CPU_WAIT); 49bf215546Sopenharmony_ci assert(type->features & VK_SYNC_FEATURE_CPU_SIGNAL); 50bf215546Sopenharmony_ci assert(type->features & (VK_SYNC_FEATURE_WAIT_BEFORE_SIGNAL | 51bf215546Sopenharmony_ci VK_SYNC_FEATURE_WAIT_PENDING)); 52bf215546Sopenharmony_ci assert(type->signal); 53bf215546Sopenharmony_ci assert(type->get_value); 54bf215546Sopenharmony_ci } 55bf215546Sopenharmony_ci 56bf215546Sopenharmony_ci if (!(type->features & VK_SYNC_FEATURE_BINARY)) { 57bf215546Sopenharmony_ci assert(!(type->features & (VK_SYNC_FEATURE_GPU_MULTI_WAIT | 58bf215546Sopenharmony_ci VK_SYNC_FEATURE_CPU_RESET))); 59bf215546Sopenharmony_ci assert(!type->import_sync_file); 60bf215546Sopenharmony_ci assert(!type->export_sync_file); 61bf215546Sopenharmony_ci } 62bf215546Sopenharmony_ci 63bf215546Sopenharmony_ci if (type->features & VK_SYNC_FEATURE_CPU_WAIT) { 64bf215546Sopenharmony_ci assert(type->wait || type->wait_many); 65bf215546Sopenharmony_ci } else { 66bf215546Sopenharmony_ci assert(!(type->features & (VK_SYNC_FEATURE_WAIT_ANY | 67bf215546Sopenharmony_ci VK_SYNC_FEATURE_WAIT_PENDING))); 68bf215546Sopenharmony_ci } 69bf215546Sopenharmony_ci 70bf215546Sopenharmony_ci if (type->features & VK_SYNC_FEATURE_GPU_MULTI_WAIT) 71bf215546Sopenharmony_ci assert(type->features & VK_SYNC_FEATURE_GPU_WAIT); 72bf215546Sopenharmony_ci 73bf215546Sopenharmony_ci if (type->features & VK_SYNC_FEATURE_CPU_RESET) 74bf215546Sopenharmony_ci assert(type->reset); 75bf215546Sopenharmony_ci 76bf215546Sopenharmony_ci if (type->features & VK_SYNC_FEATURE_CPU_SIGNAL) 77bf215546Sopenharmony_ci assert(type->signal); 78bf215546Sopenharmony_ci} 79bf215546Sopenharmony_ci 80bf215546Sopenharmony_ciVkResult 81bf215546Sopenharmony_civk_sync_init(struct vk_device *device, 82bf215546Sopenharmony_ci struct vk_sync *sync, 83bf215546Sopenharmony_ci const struct vk_sync_type *type, 84bf215546Sopenharmony_ci enum vk_sync_flags flags, 85bf215546Sopenharmony_ci uint64_t initial_value) 86bf215546Sopenharmony_ci{ 87bf215546Sopenharmony_ci vk_sync_type_validate(type); 88bf215546Sopenharmony_ci 89bf215546Sopenharmony_ci if (flags & VK_SYNC_IS_TIMELINE) 90bf215546Sopenharmony_ci assert(type->features & VK_SYNC_FEATURE_TIMELINE); 91bf215546Sopenharmony_ci else 92bf215546Sopenharmony_ci assert(type->features & VK_SYNC_FEATURE_BINARY); 93bf215546Sopenharmony_ci 94bf215546Sopenharmony_ci assert(type->size >= sizeof(*sync)); 95bf215546Sopenharmony_ci memset(sync, 0, type->size); 96bf215546Sopenharmony_ci sync->type = type; 97bf215546Sopenharmony_ci sync->flags = flags; 98bf215546Sopenharmony_ci 99bf215546Sopenharmony_ci return type->init(device, sync, initial_value); 100bf215546Sopenharmony_ci} 101bf215546Sopenharmony_ci 102bf215546Sopenharmony_civoid 103bf215546Sopenharmony_civk_sync_finish(struct vk_device *device, 104bf215546Sopenharmony_ci struct vk_sync *sync) 105bf215546Sopenharmony_ci{ 106bf215546Sopenharmony_ci sync->type->finish(device, sync); 107bf215546Sopenharmony_ci} 108bf215546Sopenharmony_ci 109bf215546Sopenharmony_ciVkResult 110bf215546Sopenharmony_civk_sync_create(struct vk_device *device, 111bf215546Sopenharmony_ci const struct vk_sync_type *type, 112bf215546Sopenharmony_ci enum vk_sync_flags flags, 113bf215546Sopenharmony_ci uint64_t initial_value, 114bf215546Sopenharmony_ci struct vk_sync **sync_out) 115bf215546Sopenharmony_ci{ 116bf215546Sopenharmony_ci struct vk_sync *sync; 117bf215546Sopenharmony_ci 118bf215546Sopenharmony_ci sync = vk_alloc(&device->alloc, type->size, 8, 119bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_DEVICE); 120bf215546Sopenharmony_ci if (sync == NULL) 121bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 122bf215546Sopenharmony_ci 123bf215546Sopenharmony_ci VkResult result = vk_sync_init(device, sync, type, flags, initial_value); 124bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 125bf215546Sopenharmony_ci vk_free(&device->alloc, sync); 126bf215546Sopenharmony_ci return result; 127bf215546Sopenharmony_ci } 128bf215546Sopenharmony_ci 129bf215546Sopenharmony_ci *sync_out = sync; 130bf215546Sopenharmony_ci 131bf215546Sopenharmony_ci return VK_SUCCESS; 132bf215546Sopenharmony_ci} 133bf215546Sopenharmony_ci 134bf215546Sopenharmony_civoid 135bf215546Sopenharmony_civk_sync_destroy(struct vk_device *device, 136bf215546Sopenharmony_ci struct vk_sync *sync) 137bf215546Sopenharmony_ci{ 138bf215546Sopenharmony_ci vk_sync_finish(device, sync); 139bf215546Sopenharmony_ci vk_free(&device->alloc, sync); 140bf215546Sopenharmony_ci} 141bf215546Sopenharmony_ci 142bf215546Sopenharmony_ciVkResult 143bf215546Sopenharmony_civk_sync_signal(struct vk_device *device, 144bf215546Sopenharmony_ci struct vk_sync *sync, 145bf215546Sopenharmony_ci uint64_t value) 146bf215546Sopenharmony_ci{ 147bf215546Sopenharmony_ci assert(sync->type->features & VK_SYNC_FEATURE_CPU_SIGNAL); 148bf215546Sopenharmony_ci 149bf215546Sopenharmony_ci if (sync->flags & VK_SYNC_IS_TIMELINE) 150bf215546Sopenharmony_ci assert(value > 0); 151bf215546Sopenharmony_ci else 152bf215546Sopenharmony_ci assert(value == 0); 153bf215546Sopenharmony_ci 154bf215546Sopenharmony_ci return sync->type->signal(device, sync, value); 155bf215546Sopenharmony_ci} 156bf215546Sopenharmony_ci 157bf215546Sopenharmony_ciVkResult 158bf215546Sopenharmony_civk_sync_get_value(struct vk_device *device, 159bf215546Sopenharmony_ci struct vk_sync *sync, 160bf215546Sopenharmony_ci uint64_t *value) 161bf215546Sopenharmony_ci{ 162bf215546Sopenharmony_ci assert(sync->flags & VK_SYNC_IS_TIMELINE); 163bf215546Sopenharmony_ci return sync->type->get_value(device, sync, value); 164bf215546Sopenharmony_ci} 165bf215546Sopenharmony_ci 166bf215546Sopenharmony_ciVkResult 167bf215546Sopenharmony_civk_sync_reset(struct vk_device *device, 168bf215546Sopenharmony_ci struct vk_sync *sync) 169bf215546Sopenharmony_ci{ 170bf215546Sopenharmony_ci assert(sync->type->features & VK_SYNC_FEATURE_CPU_RESET); 171bf215546Sopenharmony_ci assert(!(sync->flags & VK_SYNC_IS_TIMELINE)); 172bf215546Sopenharmony_ci return sync->type->reset(device, sync); 173bf215546Sopenharmony_ci} 174bf215546Sopenharmony_ci 175bf215546Sopenharmony_ciVkResult vk_sync_move(struct vk_device *device, 176bf215546Sopenharmony_ci struct vk_sync *dst, 177bf215546Sopenharmony_ci struct vk_sync *src) 178bf215546Sopenharmony_ci{ 179bf215546Sopenharmony_ci assert(!(dst->flags & VK_SYNC_IS_TIMELINE)); 180bf215546Sopenharmony_ci assert(!(src->flags & VK_SYNC_IS_TIMELINE)); 181bf215546Sopenharmony_ci assert(dst->type == src->type); 182bf215546Sopenharmony_ci 183bf215546Sopenharmony_ci return src->type->move(device, dst, src); 184bf215546Sopenharmony_ci} 185bf215546Sopenharmony_ci 186bf215546Sopenharmony_cistatic void 187bf215546Sopenharmony_ciassert_valid_wait(struct vk_sync *sync, 188bf215546Sopenharmony_ci uint64_t wait_value, 189bf215546Sopenharmony_ci enum vk_sync_wait_flags wait_flags) 190bf215546Sopenharmony_ci{ 191bf215546Sopenharmony_ci assert(sync->type->features & VK_SYNC_FEATURE_CPU_WAIT); 192bf215546Sopenharmony_ci 193bf215546Sopenharmony_ci if (!(sync->flags & VK_SYNC_IS_TIMELINE)) 194bf215546Sopenharmony_ci assert(wait_value == 0); 195bf215546Sopenharmony_ci 196bf215546Sopenharmony_ci if (wait_flags & VK_SYNC_WAIT_PENDING) 197bf215546Sopenharmony_ci assert(sync->type->features & VK_SYNC_FEATURE_WAIT_PENDING); 198bf215546Sopenharmony_ci} 199bf215546Sopenharmony_ci 200bf215546Sopenharmony_cistatic uint64_t 201bf215546Sopenharmony_ciget_max_abs_timeout_ns(void) 202bf215546Sopenharmony_ci{ 203bf215546Sopenharmony_ci static int max_timeout_ms = -1; 204bf215546Sopenharmony_ci if (max_timeout_ms < 0) 205bf215546Sopenharmony_ci max_timeout_ms = env_var_as_unsigned("MESA_VK_MAX_TIMEOUT", 0); 206bf215546Sopenharmony_ci 207bf215546Sopenharmony_ci if (max_timeout_ms == 0) 208bf215546Sopenharmony_ci return UINT64_MAX; 209bf215546Sopenharmony_ci else 210bf215546Sopenharmony_ci return os_time_get_absolute_timeout(max_timeout_ms * 1000000ull); 211bf215546Sopenharmony_ci} 212bf215546Sopenharmony_ci 213bf215546Sopenharmony_cistatic VkResult 214bf215546Sopenharmony_ci__vk_sync_wait(struct vk_device *device, 215bf215546Sopenharmony_ci struct vk_sync *sync, 216bf215546Sopenharmony_ci uint64_t wait_value, 217bf215546Sopenharmony_ci enum vk_sync_wait_flags wait_flags, 218bf215546Sopenharmony_ci uint64_t abs_timeout_ns) 219bf215546Sopenharmony_ci{ 220bf215546Sopenharmony_ci assert_valid_wait(sync, wait_value, wait_flags); 221bf215546Sopenharmony_ci 222bf215546Sopenharmony_ci /* This doesn't make sense for a single wait */ 223bf215546Sopenharmony_ci assert(!(wait_flags & VK_SYNC_WAIT_ANY)); 224bf215546Sopenharmony_ci 225bf215546Sopenharmony_ci if (sync->type->wait) { 226bf215546Sopenharmony_ci return sync->type->wait(device, sync, wait_value, 227bf215546Sopenharmony_ci wait_flags, abs_timeout_ns); 228bf215546Sopenharmony_ci } else { 229bf215546Sopenharmony_ci struct vk_sync_wait wait = { 230bf215546Sopenharmony_ci .sync = sync, 231bf215546Sopenharmony_ci .stage_mask = ~(VkPipelineStageFlags2)0, 232bf215546Sopenharmony_ci .wait_value = wait_value, 233bf215546Sopenharmony_ci }; 234bf215546Sopenharmony_ci return sync->type->wait_many(device, 1, &wait, wait_flags, 235bf215546Sopenharmony_ci abs_timeout_ns); 236bf215546Sopenharmony_ci } 237bf215546Sopenharmony_ci} 238bf215546Sopenharmony_ci 239bf215546Sopenharmony_ciVkResult 240bf215546Sopenharmony_civk_sync_wait(struct vk_device *device, 241bf215546Sopenharmony_ci struct vk_sync *sync, 242bf215546Sopenharmony_ci uint64_t wait_value, 243bf215546Sopenharmony_ci enum vk_sync_wait_flags wait_flags, 244bf215546Sopenharmony_ci uint64_t abs_timeout_ns) 245bf215546Sopenharmony_ci{ 246bf215546Sopenharmony_ci uint64_t max_abs_timeout_ns = get_max_abs_timeout_ns(); 247bf215546Sopenharmony_ci if (abs_timeout_ns > max_abs_timeout_ns) { 248bf215546Sopenharmony_ci VkResult result = 249bf215546Sopenharmony_ci __vk_sync_wait(device, sync, wait_value, wait_flags, 250bf215546Sopenharmony_ci max_abs_timeout_ns); 251bf215546Sopenharmony_ci if (unlikely(result == VK_TIMEOUT)) 252bf215546Sopenharmony_ci return vk_device_set_lost(device, "Maximum timeout exceeded!"); 253bf215546Sopenharmony_ci return result; 254bf215546Sopenharmony_ci } else { 255bf215546Sopenharmony_ci return __vk_sync_wait(device, sync, wait_value, wait_flags, 256bf215546Sopenharmony_ci abs_timeout_ns); 257bf215546Sopenharmony_ci } 258bf215546Sopenharmony_ci} 259bf215546Sopenharmony_ci 260bf215546Sopenharmony_cistatic bool 261bf215546Sopenharmony_cican_wait_many(uint32_t wait_count, 262bf215546Sopenharmony_ci const struct vk_sync_wait *waits, 263bf215546Sopenharmony_ci enum vk_sync_wait_flags wait_flags) 264bf215546Sopenharmony_ci{ 265bf215546Sopenharmony_ci if (waits[0].sync->type->wait_many == NULL) 266bf215546Sopenharmony_ci return false; 267bf215546Sopenharmony_ci 268bf215546Sopenharmony_ci if ((wait_flags & VK_SYNC_WAIT_ANY) && 269bf215546Sopenharmony_ci !(waits[0].sync->type->features & VK_SYNC_FEATURE_WAIT_ANY)) 270bf215546Sopenharmony_ci return false; 271bf215546Sopenharmony_ci 272bf215546Sopenharmony_ci for (uint32_t i = 0; i < wait_count; i++) { 273bf215546Sopenharmony_ci assert_valid_wait(waits[i].sync, waits[i].wait_value, wait_flags); 274bf215546Sopenharmony_ci if (waits[i].sync->type != waits[0].sync->type) 275bf215546Sopenharmony_ci return false; 276bf215546Sopenharmony_ci } 277bf215546Sopenharmony_ci 278bf215546Sopenharmony_ci return true; 279bf215546Sopenharmony_ci} 280bf215546Sopenharmony_ci 281bf215546Sopenharmony_cistatic VkResult 282bf215546Sopenharmony_ci__vk_sync_wait_many(struct vk_device *device, 283bf215546Sopenharmony_ci uint32_t wait_count, 284bf215546Sopenharmony_ci const struct vk_sync_wait *waits, 285bf215546Sopenharmony_ci enum vk_sync_wait_flags wait_flags, 286bf215546Sopenharmony_ci uint64_t abs_timeout_ns) 287bf215546Sopenharmony_ci{ 288bf215546Sopenharmony_ci if (wait_count == 0) 289bf215546Sopenharmony_ci return VK_SUCCESS; 290bf215546Sopenharmony_ci 291bf215546Sopenharmony_ci if (wait_count == 1) { 292bf215546Sopenharmony_ci return __vk_sync_wait(device, waits[0].sync, waits[0].wait_value, 293bf215546Sopenharmony_ci wait_flags & ~VK_SYNC_WAIT_ANY, abs_timeout_ns); 294bf215546Sopenharmony_ci } 295bf215546Sopenharmony_ci 296bf215546Sopenharmony_ci if (can_wait_many(wait_count, waits, wait_flags)) { 297bf215546Sopenharmony_ci return waits[0].sync->type->wait_many(device, wait_count, waits, 298bf215546Sopenharmony_ci wait_flags, abs_timeout_ns); 299bf215546Sopenharmony_ci } else if (wait_flags & VK_SYNC_WAIT_ANY) { 300bf215546Sopenharmony_ci /* If we have multiple syncs and they don't support wait_any or they're 301bf215546Sopenharmony_ci * not all the same type, there's nothing better we can do than spin. 302bf215546Sopenharmony_ci */ 303bf215546Sopenharmony_ci do { 304bf215546Sopenharmony_ci for (uint32_t i = 0; i < wait_count; i++) { 305bf215546Sopenharmony_ci VkResult result = __vk_sync_wait(device, waits[i].sync, 306bf215546Sopenharmony_ci waits[i].wait_value, 307bf215546Sopenharmony_ci wait_flags & ~VK_SYNC_WAIT_ANY, 308bf215546Sopenharmony_ci 0 /* abs_timeout_ns */); 309bf215546Sopenharmony_ci if (result != VK_TIMEOUT) 310bf215546Sopenharmony_ci return result; 311bf215546Sopenharmony_ci } 312bf215546Sopenharmony_ci } while (os_time_get_nano() < abs_timeout_ns); 313bf215546Sopenharmony_ci 314bf215546Sopenharmony_ci return VK_TIMEOUT; 315bf215546Sopenharmony_ci } else { 316bf215546Sopenharmony_ci for (uint32_t i = 0; i < wait_count; i++) { 317bf215546Sopenharmony_ci VkResult result = __vk_sync_wait(device, waits[i].sync, 318bf215546Sopenharmony_ci waits[i].wait_value, 319bf215546Sopenharmony_ci wait_flags, abs_timeout_ns); 320bf215546Sopenharmony_ci if (result != VK_SUCCESS) 321bf215546Sopenharmony_ci return result; 322bf215546Sopenharmony_ci } 323bf215546Sopenharmony_ci return VK_SUCCESS; 324bf215546Sopenharmony_ci } 325bf215546Sopenharmony_ci} 326bf215546Sopenharmony_ci 327bf215546Sopenharmony_ciVkResult 328bf215546Sopenharmony_civk_sync_wait_many(struct vk_device *device, 329bf215546Sopenharmony_ci uint32_t wait_count, 330bf215546Sopenharmony_ci const struct vk_sync_wait *waits, 331bf215546Sopenharmony_ci enum vk_sync_wait_flags wait_flags, 332bf215546Sopenharmony_ci uint64_t abs_timeout_ns) 333bf215546Sopenharmony_ci{ 334bf215546Sopenharmony_ci uint64_t max_abs_timeout_ns = get_max_abs_timeout_ns(); 335bf215546Sopenharmony_ci if (abs_timeout_ns > max_abs_timeout_ns) { 336bf215546Sopenharmony_ci VkResult result = 337bf215546Sopenharmony_ci __vk_sync_wait_many(device, wait_count, waits, wait_flags, 338bf215546Sopenharmony_ci max_abs_timeout_ns); 339bf215546Sopenharmony_ci if (unlikely(result == VK_TIMEOUT)) 340bf215546Sopenharmony_ci return vk_device_set_lost(device, "Maximum timeout exceeded!"); 341bf215546Sopenharmony_ci return result; 342bf215546Sopenharmony_ci } else { 343bf215546Sopenharmony_ci return __vk_sync_wait_many(device, wait_count, waits, wait_flags, 344bf215546Sopenharmony_ci abs_timeout_ns); 345bf215546Sopenharmony_ci } 346bf215546Sopenharmony_ci} 347bf215546Sopenharmony_ci 348bf215546Sopenharmony_ciVkResult 349bf215546Sopenharmony_civk_sync_import_opaque_fd(struct vk_device *device, 350bf215546Sopenharmony_ci struct vk_sync *sync, 351bf215546Sopenharmony_ci int fd) 352bf215546Sopenharmony_ci{ 353bf215546Sopenharmony_ci VkResult result = sync->type->import_opaque_fd(device, sync, fd); 354bf215546Sopenharmony_ci if (unlikely(result != VK_SUCCESS)) 355bf215546Sopenharmony_ci return result; 356bf215546Sopenharmony_ci 357bf215546Sopenharmony_ci sync->flags |= VK_SYNC_IS_SHAREABLE | 358bf215546Sopenharmony_ci VK_SYNC_IS_SHARED; 359bf215546Sopenharmony_ci 360bf215546Sopenharmony_ci return VK_SUCCESS; 361bf215546Sopenharmony_ci} 362bf215546Sopenharmony_ci 363bf215546Sopenharmony_ciVkResult 364bf215546Sopenharmony_civk_sync_export_opaque_fd(struct vk_device *device, 365bf215546Sopenharmony_ci struct vk_sync *sync, 366bf215546Sopenharmony_ci int *fd) 367bf215546Sopenharmony_ci{ 368bf215546Sopenharmony_ci assert(sync->flags & VK_SYNC_IS_SHAREABLE); 369bf215546Sopenharmony_ci 370bf215546Sopenharmony_ci VkResult result = sync->type->export_opaque_fd(device, sync, fd); 371bf215546Sopenharmony_ci if (unlikely(result != VK_SUCCESS)) 372bf215546Sopenharmony_ci return result; 373bf215546Sopenharmony_ci 374bf215546Sopenharmony_ci sync->flags |= VK_SYNC_IS_SHARED; 375bf215546Sopenharmony_ci 376bf215546Sopenharmony_ci return VK_SUCCESS; 377bf215546Sopenharmony_ci} 378bf215546Sopenharmony_ci 379bf215546Sopenharmony_ciVkResult 380bf215546Sopenharmony_civk_sync_import_sync_file(struct vk_device *device, 381bf215546Sopenharmony_ci struct vk_sync *sync, 382bf215546Sopenharmony_ci int sync_file) 383bf215546Sopenharmony_ci{ 384bf215546Sopenharmony_ci assert(!(sync->flags & VK_SYNC_IS_TIMELINE)); 385bf215546Sopenharmony_ci 386bf215546Sopenharmony_ci /* Silently handle negative file descriptors in case the driver doesn't 387bf215546Sopenharmony_ci * want to bother. 388bf215546Sopenharmony_ci */ 389bf215546Sopenharmony_ci if (sync_file < 0 && sync->type->signal) 390bf215546Sopenharmony_ci return sync->type->signal(device, sync, 0); 391bf215546Sopenharmony_ci 392bf215546Sopenharmony_ci return sync->type->import_sync_file(device, sync, sync_file); 393bf215546Sopenharmony_ci} 394bf215546Sopenharmony_ci 395bf215546Sopenharmony_ciVkResult 396bf215546Sopenharmony_civk_sync_export_sync_file(struct vk_device *device, 397bf215546Sopenharmony_ci struct vk_sync *sync, 398bf215546Sopenharmony_ci int *sync_file) 399bf215546Sopenharmony_ci{ 400bf215546Sopenharmony_ci assert(!(sync->flags & VK_SYNC_IS_TIMELINE)); 401bf215546Sopenharmony_ci return sync->type->export_sync_file(device, sync, sync_file); 402bf215546Sopenharmony_ci} 403