OLD | NEW |
1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "gpu/vulkan/vulkan_command_buffer.h" | 5 #include "gpu/vulkan/vulkan_command_buffer.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "gpu/vulkan/vulkan_command_pool.h" | 8 #include "gpu/vulkan/vulkan_command_pool.h" |
| 9 #include "gpu/vulkan/vulkan_device_queue.h" |
9 #include "gpu/vulkan/vulkan_implementation.h" | 10 #include "gpu/vulkan/vulkan_implementation.h" |
10 | 11 |
11 namespace gpu { | 12 namespace gpu { |
12 | 13 |
13 VulkanCommandBuffer::VulkanCommandBuffer(VulkanCommandPool* command_pool, | 14 VulkanCommandBuffer::VulkanCommandBuffer(VulkanDeviceQueue* device_queue, |
| 15 VulkanCommandPool* command_pool, |
14 bool primary) | 16 bool primary) |
15 : primary_(primary), command_pool_(command_pool) { | 17 : primary_(primary), |
| 18 device_queue_(device_queue), |
| 19 command_pool_(command_pool) { |
16 command_pool_->IncrementCommandBufferCount(); | 20 command_pool_->IncrementCommandBufferCount(); |
17 } | 21 } |
18 | 22 |
19 VulkanCommandBuffer::~VulkanCommandBuffer() { | 23 VulkanCommandBuffer::~VulkanCommandBuffer() { |
20 DCHECK_EQ(static_cast<VkCommandBuffer>(VK_NULL_HANDLE), command_buffer_); | 24 DCHECK_EQ(static_cast<VkCommandBuffer>(VK_NULL_HANDLE), command_buffer_); |
21 DCHECK_EQ(static_cast<VkFence>(VK_NULL_HANDLE), submission_fence_); | 25 DCHECK_EQ(static_cast<VkFence>(VK_NULL_HANDLE), submission_fence_); |
22 DCHECK(!recording_); | 26 DCHECK(!recording_); |
23 command_pool_->DecrementCommandBufferCount(); | 27 command_pool_->DecrementCommandBufferCount(); |
24 } | 28 } |
25 | 29 |
26 bool VulkanCommandBuffer::Initialize() { | 30 bool VulkanCommandBuffer::Initialize() { |
27 VkResult result = VK_SUCCESS; | 31 VkResult result = VK_SUCCESS; |
28 VkDevice device = GetVulkanDevice(); | 32 VkDevice device = device_queue_->GetVulkanDevice(); |
29 | 33 |
30 VkCommandBufferAllocateInfo command_buffer_info = {}; | 34 VkCommandBufferAllocateInfo command_buffer_info = {}; |
31 command_buffer_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; | 35 command_buffer_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; |
32 command_buffer_info.commandPool = command_pool_->handle(); | 36 command_buffer_info.commandPool = command_pool_->handle(); |
33 command_buffer_info.level = primary_ ? VK_COMMAND_BUFFER_LEVEL_PRIMARY | 37 command_buffer_info.level = primary_ ? VK_COMMAND_BUFFER_LEVEL_PRIMARY |
34 : VK_COMMAND_BUFFER_LEVEL_SECONDARY; | 38 : VK_COMMAND_BUFFER_LEVEL_SECONDARY; |
35 command_buffer_info.commandBufferCount = 1; | 39 command_buffer_info.commandBufferCount = 1; |
36 | 40 |
37 result = | 41 result = |
38 vkAllocateCommandBuffers(device, &command_buffer_info, &command_buffer_); | 42 vkAllocateCommandBuffers(device, &command_buffer_info, &command_buffer_); |
(...skipping 11 matching lines...) Expand all Loading... |
50 if (VK_SUCCESS != result) { | 54 if (VK_SUCCESS != result) { |
51 DLOG(ERROR) << "vkCreateFence(submission) failed: " << result; | 55 DLOG(ERROR) << "vkCreateFence(submission) failed: " << result; |
52 return false; | 56 return false; |
53 } | 57 } |
54 | 58 |
55 record_type_ = RECORD_TYPE_EMPTY; | 59 record_type_ = RECORD_TYPE_EMPTY; |
56 return true; | 60 return true; |
57 } | 61 } |
58 | 62 |
59 void VulkanCommandBuffer::Destroy() { | 63 void VulkanCommandBuffer::Destroy() { |
60 VkDevice device = GetVulkanDevice(); | 64 VkDevice device = device_queue_->GetVulkanDevice(); |
61 if (VK_NULL_HANDLE != submission_fence_) { | 65 if (VK_NULL_HANDLE != submission_fence_) { |
62 DCHECK(SubmissionFinished()); | 66 DCHECK(SubmissionFinished()); |
63 vkDestroyFence(device, submission_fence_, nullptr); | 67 vkDestroyFence(device, submission_fence_, nullptr); |
64 submission_fence_ = VK_NULL_HANDLE; | 68 submission_fence_ = VK_NULL_HANDLE; |
65 } | 69 } |
66 | 70 |
67 if (VK_NULL_HANDLE != command_buffer_) { | 71 if (VK_NULL_HANDLE != command_buffer_) { |
68 vkFreeCommandBuffers(device, command_pool_->handle(), 1, &command_buffer_); | 72 vkFreeCommandBuffers(device, command_pool_->handle(), 1, &command_buffer_); |
69 command_buffer_ = VK_NULL_HANDLE; | 73 command_buffer_ = VK_NULL_HANDLE; |
70 } | 74 } |
71 } | 75 } |
72 | 76 |
73 bool VulkanCommandBuffer::Submit(VkQueue queue, | 77 bool VulkanCommandBuffer::Submit(uint32_t num_wait_semaphores, |
74 uint32_t num_wait_semaphores, | |
75 VkSemaphore* wait_semaphores, | 78 VkSemaphore* wait_semaphores, |
76 uint32_t num_signal_semaphores, | 79 uint32_t num_signal_semaphores, |
77 VkSemaphore* signal_semaphores) { | 80 VkSemaphore* signal_semaphores) { |
78 DCHECK(primary_); | 81 DCHECK(primary_); |
79 VkSubmitInfo submit_info = {}; | 82 VkSubmitInfo submit_info = {}; |
80 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; | 83 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; |
81 submit_info.commandBufferCount = 1; | 84 submit_info.commandBufferCount = 1; |
82 submit_info.pCommandBuffers = &command_buffer_; | 85 submit_info.pCommandBuffers = &command_buffer_; |
83 submit_info.waitSemaphoreCount = num_wait_semaphores; | 86 submit_info.waitSemaphoreCount = num_wait_semaphores; |
84 submit_info.pWaitSemaphores = wait_semaphores; | 87 submit_info.pWaitSemaphores = wait_semaphores; |
85 submit_info.signalSemaphoreCount = num_signal_semaphores; | 88 submit_info.signalSemaphoreCount = num_signal_semaphores; |
86 submit_info.pSignalSemaphores = signal_semaphores; | 89 submit_info.pSignalSemaphores = signal_semaphores; |
87 | 90 |
88 vkResetFences(GetVulkanDevice(), 1, &submission_fence_); | 91 VkResult result = VK_SUCCESS; |
89 VkResult result = vkQueueSubmit(queue, 1, &submit_info, submission_fence_); | 92 |
| 93 result = |
| 94 vkResetFences(device_queue_->GetVulkanDevice(), 1, &submission_fence_); |
| 95 if (VK_SUCCESS != result) { |
| 96 DLOG(ERROR) << "vkResetFences() failed: " << result; |
| 97 return false; |
| 98 } |
| 99 |
| 100 result = vkQueueSubmit(device_queue_->GetVulkanQueue(), 1, &submit_info, |
| 101 submission_fence_); |
| 102 |
90 PostExecution(); | 103 PostExecution(); |
91 if (VK_SUCCESS != result) { | 104 if (VK_SUCCESS != result) { |
92 DLOG(ERROR) << "vkQueueSubmit() failed: " << result; | 105 DLOG(ERROR) << "vkQueueSubmit() failed: " << result; |
93 return false; | 106 return false; |
94 } | 107 } |
95 | 108 |
96 return true; | 109 return true; |
97 } | 110 } |
98 | 111 |
99 void VulkanCommandBuffer::Enqueue(VkCommandBuffer primary_command_buffer) { | 112 void VulkanCommandBuffer::Enqueue(VkCommandBuffer primary_command_buffer) { |
100 DCHECK(!primary_); | 113 DCHECK(!primary_); |
101 vkCmdExecuteCommands(primary_command_buffer, 1, &command_buffer_); | 114 vkCmdExecuteCommands(primary_command_buffer, 1, &command_buffer_); |
102 PostExecution(); | 115 PostExecution(); |
103 } | 116 } |
104 | 117 |
105 void VulkanCommandBuffer::Clear() { | 118 void VulkanCommandBuffer::Clear() { |
106 // Mark to reset upon next use. | 119 // Mark to reset upon next use. |
107 if (record_type_ != RECORD_TYPE_EMPTY) | 120 if (record_type_ != RECORD_TYPE_EMPTY) |
108 record_type_ = RECORD_TYPE_DIRTY; | 121 record_type_ = RECORD_TYPE_DIRTY; |
109 } | 122 } |
110 | 123 |
111 void VulkanCommandBuffer::Wait(uint64_t timeout) { | 124 void VulkanCommandBuffer::Wait(uint64_t timeout) { |
112 vkWaitForFences(GetVulkanDevice(), 1, &submission_fence_, true, timeout); | 125 VkDevice device = device_queue_->GetVulkanDevice(); |
| 126 vkWaitForFences(device, 1, &submission_fence_, true, timeout); |
113 } | 127 } |
114 | 128 |
115 bool VulkanCommandBuffer::SubmissionFinished() { | 129 bool VulkanCommandBuffer::SubmissionFinished() { |
116 return VK_SUCCESS == vkGetFenceStatus(GetVulkanDevice(), submission_fence_); | 130 VkDevice device = device_queue_->GetVulkanDevice(); |
| 131 return VK_SUCCESS == vkGetFenceStatus(device, submission_fence_); |
117 } | 132 } |
118 | 133 |
119 void VulkanCommandBuffer::PostExecution() { | 134 void VulkanCommandBuffer::PostExecution() { |
120 if (record_type_ == RECORD_TYPE_SINGLE_USE) { | 135 if (record_type_ == RECORD_TYPE_SINGLE_USE) { |
121 // Clear upon next use. | 136 // Clear upon next use. |
122 record_type_ = RECORD_TYPE_DIRTY; | 137 record_type_ = RECORD_TYPE_DIRTY; |
123 } else if (record_type_ == RECORD_TYPE_MULTI_USE) { | 138 } else if (record_type_ == RECORD_TYPE_MULTI_USE) { |
124 // Can no longer record new items unless marked as clear. | 139 // Can no longer record new items unless marked as clear. |
125 record_type_ = RECORD_TYPE_RECORDED; | 140 record_type_ = RECORD_TYPE_RECORDED; |
126 } | 141 } |
127 } | 142 } |
128 | 143 |
129 void VulkanCommandBuffer::ResetIfDirty() { | 144 void VulkanCommandBuffer::ResetIfDirty() { |
130 DCHECK(!recording_); | 145 DCHECK(!recording_); |
131 if (record_type_ == RECORD_TYPE_DIRTY) { | 146 if (record_type_ == RECORD_TYPE_DIRTY) { |
132 // Block if command buffer is still in use. This can be externally avoided | 147 // Block if command buffer is still in use. This can be externally avoided |
133 // using the asynchronous SubmissionFinished() function. | 148 // using the asynchronous SubmissionFinished() function. |
134 vkWaitForFences(GetVulkanDevice(), 1, &submission_fence_, true, UINT64_MAX); | 149 VkDevice device = device_queue_->GetVulkanDevice(); |
| 150 vkWaitForFences(device, 1, &submission_fence_, true, UINT64_MAX); |
135 | 151 |
136 vkResetCommandBuffer(command_buffer_, 0); | 152 vkResetCommandBuffer(command_buffer_, 0); |
137 record_type_ = RECORD_TYPE_EMPTY; | 153 record_type_ = RECORD_TYPE_EMPTY; |
138 } | 154 } |
139 } | 155 } |
140 | 156 |
141 CommandBufferRecorderBase::~CommandBufferRecorderBase() { | 157 CommandBufferRecorderBase::~CommandBufferRecorderBase() { |
142 vkEndCommandBuffer(handle_); | 158 vkEndCommandBuffer(handle_); |
143 }; | 159 }; |
144 | 160 |
(...skipping 10 matching lines...) Expand all Loading... |
155 VulkanCommandBuffer& command_buffer) | 171 VulkanCommandBuffer& command_buffer) |
156 : CommandBufferRecorderBase(command_buffer) { | 172 : CommandBufferRecorderBase(command_buffer) { |
157 ValidateSingleUse(command_buffer); | 173 ValidateSingleUse(command_buffer); |
158 VkCommandBufferBeginInfo begin_info = {}; | 174 VkCommandBufferBeginInfo begin_info = {}; |
159 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; | 175 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; |
160 begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; | 176 begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; |
161 vkBeginCommandBuffer(handle_, &begin_info); | 177 vkBeginCommandBuffer(handle_, &begin_info); |
162 } | 178 } |
163 | 179 |
164 } // namespace gpu | 180 } // namespace gpu |
OLD | NEW |