1 /* Copyright (c) 2015-2021 The Khronos Group Inc. 2 * Copyright (c) 2015-2021 Valve Corporation 3 * Copyright (c) 2015-2021 LunarG, Inc. 4 * Copyright (C) 2015-2021 Google Inc. 5 * Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 * Author: Courtney Goeltzenleuchter <courtneygo@google.com> 20 * Author: Tobin Ehlis <tobine@google.com> 21 * Author: Chris Forbes <chrisf@ijw.co.nz> 22 * Author: Mark Lobodzinski <mark@lunarg.com> 23 * Author: Dave Houlton <daveh@lunarg.com> 24 * Author: John Zulauf <jzulauf@lunarg.com> 25 * Author: Tobias Hector <tobias.hector@amd.com> 26 */ 27 #pragma once 28 #include "base_node.h" 29 #include <vector> 30 #include <deque> 31 32 class CMD_BUFFER_STATE; 33 class QUEUE_STATE; 34 35 enum SyncScope { 36 kSyncScopeInternal, 37 kSyncScopeExternalTemporary, 38 kSyncScopeExternalPermanent, 39 }; 40 41 enum FENCE_STATUS { FENCE_UNSIGNALED, FENCE_INFLIGHT, FENCE_RETIRED }; 42 43 struct QUEUE_SIGNALER { 44 QUEUE_STATE *queue{nullptr}; 45 uint64_t seq{0}; 46 }; 47 48 class FENCE_STATE : public REFCOUNTED_NODE { 49 public: 50 const VkFenceCreateInfo createInfo; 51 QUEUE_SIGNALER signaler; 52 FENCE_STATUS state; 53 SyncScope scope{kSyncScopeInternal}; 54 55 // Default constructor FENCE_STATE(VkFence f,const VkFenceCreateInfo * pCreateInfo)56 FENCE_STATE(VkFence f, const VkFenceCreateInfo *pCreateInfo) 57 : REFCOUNTED_NODE(f, kVulkanObjectTypeFence), 58 createInfo(*pCreateInfo), 59 state((pCreateInfo->flags & VK_FENCE_CREATE_SIGNALED_BIT) ? FENCE_RETIRED : FENCE_UNSIGNALED), 60 scope(kSyncScopeInternal) {} 61 fence()62 VkFence fence() const { return handle_.Cast<VkFence>(); } 63 64 void Retire(); 65 }; 66 67 class SEMAPHORE_STATE : public REFCOUNTED_NODE { 68 public: 69 QUEUE_SIGNALER signaler; 70 bool signaled{false}; 71 SyncScope scope{kSyncScopeInternal}; 72 const VkSemaphoreType type; 73 uint64_t payload; 74 SEMAPHORE_STATE(VkSemaphore sem,const VkSemaphoreTypeCreateInfo * type_create_info)75 SEMAPHORE_STATE(VkSemaphore sem, const VkSemaphoreTypeCreateInfo *type_create_info) 76 : REFCOUNTED_NODE(sem, kVulkanObjectTypeSemaphore), 77 type(type_create_info ? type_create_info->semaphoreType : VK_SEMAPHORE_TYPE_BINARY), 78 payload(type_create_info ? type_create_info->initialValue : 0) {} 79 semaphore()80 VkSemaphore semaphore() const { return handle_.Cast<VkSemaphore>(); } 81 82 void Retire(uint64_t next_seq); 83 }; 84 85 struct SEMAPHORE_WAIT { 86 std::shared_ptr<SEMAPHORE_STATE> semaphore; 87 uint64_t payload{0}; 88 uint64_t seq{0}; 89 }; 90 91 struct SEMAPHORE_SIGNAL { 92 std::shared_ptr<SEMAPHORE_STATE> semaphore; 93 uint64_t payload{0}; 94 uint64_t seq{0}; 95 }; 96 97 struct CB_SUBMISSION { 98 std::vector<std::shared_ptr<CMD_BUFFER_STATE>> cbs; 99 std::vector<SEMAPHORE_WAIT> wait_semaphores; 100 std::vector<SEMAPHORE_SIGNAL> signal_semaphores; 101 std::shared_ptr<FENCE_STATE> fence; 102 uint32_t perf_submit_pass{0}; 103 AddCommandBufferCB_SUBMISSION104 void AddCommandBuffer(std::shared_ptr<CMD_BUFFER_STATE> &&cb_node) { cbs.emplace_back(std::move(cb_node)); } 105 AddSignalSemaphoreCB_SUBMISSION106 void AddSignalSemaphore(std::shared_ptr<SEMAPHORE_STATE> &&semaphore_state, uint64_t value) { 107 SEMAPHORE_SIGNAL signal; 108 signal.semaphore = std::move(semaphore_state); 109 signal.payload = value; 110 signal.seq = 0; 111 signal_semaphores.emplace_back(std::move(signal)); 112 } 113 AddWaitSemaphoreCB_SUBMISSION114 void AddWaitSemaphore(std::shared_ptr<SEMAPHORE_STATE> &&semaphore_state, uint64_t value) { 115 SEMAPHORE_WAIT wait; 116 wait.semaphore = std::move(semaphore_state); 117 wait.payload = value; 118 wait_semaphores.emplace_back(std::move(wait)); 119 } 120 AddFenceCB_SUBMISSION121 void AddFence(std::shared_ptr<FENCE_STATE> &&fence_state) { fence = std::move(fence_state); } 122 }; 123 124 class QUEUE_STATE : public BASE_NODE { 125 public: 126 const uint32_t queueFamilyIndex; 127 const VkDeviceQueueCreateFlags flags; 128 129 uint64_t seq; 130 std::deque<CB_SUBMISSION> submissions; 131 QUEUE_STATE(VkQueue q,uint32_t index,VkDeviceQueueCreateFlags flags)132 QUEUE_STATE(VkQueue q, uint32_t index, VkDeviceQueueCreateFlags flags) 133 : BASE_NODE(q, kVulkanObjectTypeQueue), queueFamilyIndex(index), flags(flags), seq(0) {} 134 Queue()135 VkQueue Queue() const { return handle_.Cast<VkQueue>(); } 136 137 uint64_t Submit(CB_SUBMISSION &&submission); 138 139 void Retire(uint64_t next_seq); Retire()140 void Retire() { Retire(seq + submissions.size()); } 141 }; 142