1 | // Copyright 2013 The Flutter Authors. All rights reserved. |
2 | // Use of this source code is governed by a BSD-style license that can be |
3 | // found in the LICENSE file. |
4 | |
5 | #include "vulkan_backbuffer.h" |
6 | |
7 | #include <limits> |
8 | |
9 | #include "third_party/skia/include/gpu/vk/GrVkTypes.h" |
10 | #include "vulkan/vulkan.h" |
11 | #include "vulkan_proc_table.h" |
12 | |
13 | namespace vulkan { |
14 | |
15 | VulkanBackbuffer::VulkanBackbuffer(const VulkanProcTable& p_vk, |
16 | const VulkanHandle<VkDevice>& device, |
17 | const VulkanHandle<VkCommandPool>& pool) |
18 | : vk(p_vk), |
19 | device_(device), |
20 | usage_command_buffer_(p_vk, device, pool), |
21 | render_command_buffer_(p_vk, device, pool), |
22 | valid_(false) { |
23 | if (!usage_command_buffer_.IsValid() || !render_command_buffer_.IsValid()) { |
24 | FML_DLOG(INFO) << "Command buffers were not valid." ; |
25 | return; |
26 | } |
27 | |
28 | if (!CreateSemaphores()) { |
29 | FML_DLOG(INFO) << "Could not create semaphores." ; |
30 | return; |
31 | } |
32 | |
33 | if (!CreateFences()) { |
34 | FML_DLOG(INFO) << "Could not create fences." ; |
35 | return; |
36 | } |
37 | |
38 | valid_ = true; |
39 | } |
40 | |
41 | VulkanBackbuffer::~VulkanBackbuffer() { |
42 | FML_ALLOW_UNUSED_LOCAL(WaitFences()); |
43 | } |
44 | |
45 | bool VulkanBackbuffer::IsValid() const { |
46 | return valid_; |
47 | } |
48 | |
49 | bool VulkanBackbuffer::CreateSemaphores() { |
50 | const VkSemaphoreCreateInfo create_info = { |
51 | .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, |
52 | .pNext = nullptr, |
53 | .flags = 0, |
54 | }; |
55 | |
56 | auto semaphore_collect = [this](VkSemaphore semaphore) { |
57 | vk.DestroySemaphore(device_, semaphore, nullptr); |
58 | }; |
59 | |
60 | for (size_t i = 0; i < semaphores_.size(); i++) { |
61 | VkSemaphore semaphore = VK_NULL_HANDLE; |
62 | |
63 | if (VK_CALL_LOG_ERROR(vk.CreateSemaphore(device_, &create_info, nullptr, |
64 | &semaphore)) != VK_SUCCESS) { |
65 | return false; |
66 | } |
67 | |
68 | semaphores_[i] = {semaphore, semaphore_collect}; |
69 | } |
70 | |
71 | return true; |
72 | } |
73 | |
74 | bool VulkanBackbuffer::CreateFences() { |
75 | const VkFenceCreateInfo create_info = { |
76 | .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, |
77 | .pNext = nullptr, |
78 | .flags = VK_FENCE_CREATE_SIGNALED_BIT, |
79 | }; |
80 | |
81 | auto fence_collect = [this](VkFence fence) { |
82 | vk.DestroyFence(device_, fence, nullptr); |
83 | }; |
84 | |
85 | for (size_t i = 0; i < use_fences_.size(); i++) { |
86 | VkFence fence = VK_NULL_HANDLE; |
87 | |
88 | if (VK_CALL_LOG_ERROR(vk.CreateFence(device_, &create_info, nullptr, |
89 | &fence)) != VK_SUCCESS) { |
90 | return false; |
91 | } |
92 | |
93 | use_fences_[i] = {fence, fence_collect}; |
94 | } |
95 | |
96 | return true; |
97 | } |
98 | |
99 | bool VulkanBackbuffer::WaitFences() { |
100 | VkFence fences[use_fences_.size()]; |
101 | |
102 | for (size_t i = 0; i < use_fences_.size(); i++) { |
103 | fences[i] = use_fences_[i]; |
104 | } |
105 | |
106 | return VK_CALL_LOG_ERROR(vk.WaitForFences( |
107 | device_, static_cast<uint32_t>(use_fences_.size()), fences, true, |
108 | std::numeric_limits<uint64_t>::max())) == VK_SUCCESS; |
109 | } |
110 | |
111 | bool VulkanBackbuffer::ResetFences() { |
112 | VkFence fences[use_fences_.size()]; |
113 | |
114 | for (size_t i = 0; i < use_fences_.size(); i++) { |
115 | fences[i] = use_fences_[i]; |
116 | } |
117 | |
118 | return VK_CALL_LOG_ERROR(vk.ResetFences( |
119 | device_, static_cast<uint32_t>(use_fences_.size()), fences)) == |
120 | VK_SUCCESS; |
121 | } |
122 | |
123 | const VulkanHandle<VkFence>& VulkanBackbuffer::GetUsageFence() const { |
124 | return use_fences_[0]; |
125 | } |
126 | |
127 | const VulkanHandle<VkFence>& VulkanBackbuffer::GetRenderFence() const { |
128 | return use_fences_[1]; |
129 | } |
130 | |
131 | const VulkanHandle<VkSemaphore>& VulkanBackbuffer::GetUsageSemaphore() const { |
132 | return semaphores_[0]; |
133 | } |
134 | |
135 | const VulkanHandle<VkSemaphore>& VulkanBackbuffer::GetRenderSemaphore() const { |
136 | return semaphores_[1]; |
137 | } |
138 | |
139 | VulkanCommandBuffer& VulkanBackbuffer::GetUsageCommandBuffer() { |
140 | return usage_command_buffer_; |
141 | } |
142 | |
143 | VulkanCommandBuffer& VulkanBackbuffer::GetRenderCommandBuffer() { |
144 | return render_command_buffer_; |
145 | } |
146 | |
147 | } // namespace vulkan |
148 | |