1/* 2 * Copyright © 2021 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 */ 23 24#include "vk_sync_binary.h" 25 26#include "vk_util.h" 27 28static struct vk_sync_binary * 29to_vk_sync_binary(struct vk_sync *sync) 30{ 31 assert(sync->type->init == vk_sync_binary_init); 32 33 return container_of(sync, struct vk_sync_binary, sync); 34} 35 36VkResult 37vk_sync_binary_init(struct vk_device *device, 38 struct vk_sync *sync, 39 uint64_t initial_value) 40{ 41 struct vk_sync_binary *binary = to_vk_sync_binary(sync); 42 43 const struct vk_sync_binary_type *btype = 44 container_of(binary->sync.type, struct vk_sync_binary_type, sync); 45 46 assert(!(sync->flags & VK_SYNC_IS_TIMELINE)); 47 assert(!(sync->flags & VK_SYNC_IS_SHAREABLE)); 48 49 binary->next_point = (initial_value == 0); 50 51 return vk_sync_init(device, &binary->timeline, btype->timeline_type, 52 VK_SYNC_IS_TIMELINE, 0 /* initial_value */); 53} 54 55static void 56vk_sync_binary_finish(struct vk_device *device, 57 struct vk_sync *sync) 58{ 59 struct vk_sync_binary *binary = to_vk_sync_binary(sync); 60 61 vk_sync_finish(device, &binary->timeline); 62} 63 64static VkResult 65vk_sync_binary_reset(struct vk_device *device, 66 struct vk_sync *sync) 67{ 68 struct vk_sync_binary *binary = to_vk_sync_binary(sync); 69 70 binary->next_point++; 71 72 return VK_SUCCESS; 73} 74 75static VkResult 76vk_sync_binary_signal(struct vk_device *device, 77 struct vk_sync *sync, 78 uint64_t value) 79{ 80 struct vk_sync_binary *binary = to_vk_sync_binary(sync); 81 82 assert(value == 0); 83 84 return vk_sync_signal(device, &binary->timeline, binary->next_point); 85} 86 87static VkResult 88vk_sync_binary_wait_many(struct vk_device *device, 89 uint32_t wait_count, 90 const struct vk_sync_wait *waits, 91 enum vk_sync_wait_flags wait_flags, 92 uint64_t abs_timeout_ns) 93{ 94 STACK_ARRAY(struct vk_sync_wait, timeline_waits, wait_count); 95 96 for (uint32_t i = 0; i < wait_count; i++) { 97 struct vk_sync_binary *binary = to_vk_sync_binary(waits[i].sync); 98 99 timeline_waits[i] = (struct vk_sync_wait) { 100 .sync = &binary->timeline, 101 .stage_mask = waits[i].stage_mask, 102 .wait_value = binary->next_point, 103 }; 104 } 105 106 VkResult result = vk_sync_wait_many(device, wait_count, timeline_waits, 107 wait_flags, abs_timeout_ns); 108 109 STACK_ARRAY_FINISH(timeline_waits); 110 111 return result; 112} 113 114struct vk_sync_binary_type 115vk_sync_binary_get_type(const struct vk_sync_type *timeline_type) 116{ 117 assert(timeline_type->features & VK_SYNC_FEATURE_TIMELINE); 118 119 return (struct vk_sync_binary_type) { 120 .sync = { 121 .size = offsetof(struct vk_sync_binary, timeline) + 122 timeline_type->size, 123 .features = VK_SYNC_FEATURE_BINARY | 124 VK_SYNC_FEATURE_GPU_WAIT | 125 VK_SYNC_FEATURE_CPU_WAIT | 126 VK_SYNC_FEATURE_CPU_RESET | 127 VK_SYNC_FEATURE_CPU_SIGNAL | 128 VK_SYNC_FEATURE_WAIT_ANY | 129 VK_SYNC_FEATURE_WAIT_PENDING, 130 .init = vk_sync_binary_init, 131 .finish = vk_sync_binary_finish, 132 .reset = vk_sync_binary_reset, 133 .signal = vk_sync_binary_signal, 134 .wait_many = vk_sync_binary_wait_many, 135 }, 136 .timeline_type = timeline_type, 137 }; 138} 139