Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(447)

Side by Side Diff: gpu/vulkan/vulkan_swap_chain.cc

Issue 1776453003: Added initial implementation of Vulkan Render Passes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@gn_vulkan
Patch Set: Adding logging/macros headers Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « gpu/vulkan/vulkan_swap_chain.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "gpu/vulkan/vulkan_swap_chain.h"
6
7 #include "gpu/vulkan/vulkan_command_buffer.h"
8 #include "gpu/vulkan/vulkan_command_pool.h"
9 #include "gpu/vulkan/vulkan_image_view.h"
10 #include "gpu/vulkan/vulkan_implementation.h"
11
12 namespace gpu {
13
14 VulkanSwapChain::VulkanSwapChain() {}
15
16 VulkanSwapChain::~VulkanSwapChain() {
17 DCHECK(images_.empty());
18 DCHECK_EQ(static_cast<VkSwapchainKHR>(VK_NULL_HANDLE), swap_chain_);
19 DCHECK_EQ(static_cast<VkSemaphore>(VK_NULL_HANDLE), next_present_semaphore_);
20 }
21
22 bool VulkanSwapChain::Initialize(VkSurfaceKHR surface,
23 const VkSurfaceCapabilitiesKHR& surface_caps,
24 const VkSurfaceFormatKHR& surface_format) {
25 return InitializeSwapChain(surface, surface_caps, surface_format) &&
26 InitializeSwapImages(surface_caps, surface_format);
27 }
28
29 void VulkanSwapChain::Destroy() {
30 DestroySwapImages();
31 DestroySwapChain();
32 }
33
34 gfx::SwapResult VulkanSwapChain::SwapBuffers() {
35 VkResult result = VK_SUCCESS;
36
37 VkDevice device = GetVulkanDevice();
38 VkQueue queue = GetVulkanQueue();
39
40 scoped_ptr<ImageData>& current_image_data = images_[current_image_];
41
42 // Default image subresource range.
43 VkImageSubresourceRange image_subresource_range = {};
44 image_subresource_range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
45 image_subresource_range.baseMipLevel = 0;
46 image_subresource_range.levelCount = 1;
47 image_subresource_range.baseArrayLayer = 0;
48 image_subresource_range.layerCount = 1;
49
50 // Submit our command buffer for the current buffer.
51 if (!current_image_data->command_buffer->Submit(
52 queue, 1, &current_image_data->present_semaphore, 1,
53 &current_image_data->render_semaphore)) {
54 return gfx::SwapResult::SWAP_FAILED;
55 }
56
57 // Queue the present.
58 VkPresentInfoKHR present_info = {};
59 present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
60 present_info.waitSemaphoreCount = 1;
61 present_info.pWaitSemaphores = &current_image_data->render_semaphore;
62 present_info.swapchainCount = 1;
63 present_info.pSwapchains = &swap_chain_;
64 present_info.pImageIndices = &current_image_;
65
66 result = vkQueuePresentKHR(queue, &present_info);
67 if (VK_SUCCESS != result) {
68 return gfx::SwapResult::SWAP_FAILED;
69 }
70
71 // Acquire then next image.
72 result = vkAcquireNextImageKHR(device, swap_chain_, UINT64_MAX,
73 next_present_semaphore_, VK_NULL_HANDLE,
74 &current_image_);
75 if (VK_SUCCESS != result) {
76 return gfx::SwapResult::SWAP_FAILED;
77 }
78
79 // Swap in the "next_present_semaphore" into the newly acquired image. The
80 // old "present_semaphore" for the image becomes the place holder for the next
81 // present semaphore for the next image.
82 std::swap(images_[current_image_]->present_semaphore,
83 next_present_semaphore_);
84
85 return gfx::SwapResult::SWAP_ACK;
86 }
87
88 bool VulkanSwapChain::InitializeSwapChain(
89 VkSurfaceKHR surface,
90 const VkSurfaceCapabilitiesKHR& surface_caps,
91 const VkSurfaceFormatKHR& surface_format) {
92 VkDevice device = GetVulkanDevice();
93 VkResult result = VK_SUCCESS;
94
95 VkSwapchainCreateInfoKHR swap_chain_create_info = {};
96 swap_chain_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
97 swap_chain_create_info.surface = surface;
98 swap_chain_create_info.minImageCount =
99 std::max(2u, surface_caps.minImageCount);
100 swap_chain_create_info.imageFormat = surface_format.format;
101 swap_chain_create_info.imageColorSpace = surface_format.colorSpace;
102 swap_chain_create_info.imageExtent = surface_caps.currentExtent;
103 swap_chain_create_info.imageArrayLayers = 1;
104 swap_chain_create_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
105 swap_chain_create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
106 swap_chain_create_info.preTransform = surface_caps.currentTransform;
107 swap_chain_create_info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
108 swap_chain_create_info.presentMode = VK_PRESENT_MODE_FIFO_KHR;
109 swap_chain_create_info.clipped = true;
110 swap_chain_create_info.oldSwapchain = swap_chain_;
111
112 VkSwapchainKHR new_swap_chain = VK_NULL_HANDLE;
113 result = vkCreateSwapchainKHR(device, &swap_chain_create_info, nullptr,
114 &new_swap_chain);
115 if (VK_SUCCESS != result) {
116 DLOG(ERROR) << "vkCreateSwapchainKHR() failed: " << result;
117 return false;
118 }
119
120 Destroy();
121
122 swap_chain_ = new_swap_chain;
123 size_ = gfx::Size(swap_chain_create_info.imageExtent.width,
124 swap_chain_create_info.imageExtent.height);
125
126 return true;
127 }
128
129 void VulkanSwapChain::DestroySwapChain() {
130 VkDevice device = GetVulkanDevice();
131
132 if (swap_chain_ != VK_NULL_HANDLE) {
133 vkDestroySwapchainKHR(device, swap_chain_, nullptr);
134 swap_chain_ = VK_NULL_HANDLE;
135 }
136 }
137
138 bool VulkanSwapChain::InitializeSwapImages(
139 const VkSurfaceCapabilitiesKHR& surface_caps,
140 const VkSurfaceFormatKHR& surface_format) {
141 VkDevice device = GetVulkanDevice();
142 VkResult result = VK_SUCCESS;
143
144 uint32_t image_count = 0;
145 result = vkGetSwapchainImagesKHR(device, swap_chain_, &image_count, nullptr);
146 if (VK_SUCCESS != result) {
147 DLOG(ERROR) << "vkGetSwapchainImagesKHR(NULL) failed: " << result;
148 return false;
149 }
150
151 std::vector<VkImage> images(image_count);
152 result =
153 vkGetSwapchainImagesKHR(device, swap_chain_, &image_count, images.data());
154 if (VK_SUCCESS != result) {
155 DLOG(ERROR) << "vkGetSwapchainImagesKHR(images) failed: " << result;
156 return false;
157 }
158
159 // Generic semaphore creation structure.
160 VkSemaphoreCreateInfo semaphore_create_info = {};
161 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
162
163 // Default image subresource range.
164 VkImageSubresourceRange image_subresource_range = {};
165 image_subresource_range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
166 image_subresource_range.baseMipLevel = 0;
167 image_subresource_range.levelCount = 1;
168 image_subresource_range.baseArrayLayer = 0;
169 image_subresource_range.layerCount = 1;
170
171 // The image memory barrier is used to setup the image layout.
172 VkImageMemoryBarrier image_memory_barrier = {};
173 image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
174 image_memory_barrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
175 image_memory_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
176 image_memory_barrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
177 image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
178 image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
179 image_memory_barrier.subresourceRange = image_subresource_range;
180
181 command_pool_ = CreateCommandPool();
182 if (!command_pool_)
183 return false;
184
185 images_.resize(image_count);
186 for (uint32_t i = 0; i < image_count; ++i) {
187 images_[i].reset(new ImageData);
188 scoped_ptr<ImageData>& image_data = images_[i];
189 image_data->image = images[i];
190
191 // Setup semaphores.
192 result = vkCreateSemaphore(device, &semaphore_create_info, nullptr,
193 &image_data->render_semaphore);
194 if (VK_SUCCESS != result) {
195 DLOG(ERROR) << "vkCreateSemaphore(render) failed: " << result;
196 return false;
197 }
198
199 result = vkCreateSemaphore(device, &semaphore_create_info, nullptr,
200 &image_data->present_semaphore);
201 if (VK_SUCCESS != result) {
202 DLOG(ERROR) << "vkCreateSemaphore(present) failed: " << result;
203 return false;
204 }
205
206 // Initialize the command buffer for this buffer data.
207 image_data->command_buffer = command_pool_->CreatePrimaryCommandBuffer();
208
209 // Setup the Image Layout as the first command that gets issued in each
210 // command buffer.
211 ScopedSingleUseCommandBufferRecorder recorder(*image_data->command_buffer);
212 image_memory_barrier.image = images[i];
213 vkCmdPipelineBarrier(recorder.handle(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
214 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, 0,
215 nullptr, 1, &image_memory_barrier);
216
217 // Create the image view.
218 image_data->image_view.reset(new VulkanImageView);
219 if (!image_data->image_view->Initialize(
220 images[i], VK_IMAGE_VIEW_TYPE_2D, VulkanImageView::IMAGE_TYPE_COLOR,
221 surface_format.format, size_.width(), size_.height(), 0, 1, 0, 1)) {
222 return false;
223 }
224 }
225
226 result = vkCreateSemaphore(device, &semaphore_create_info, nullptr,
227 &next_present_semaphore_);
228 if (VK_SUCCESS != result) {
229 DLOG(ERROR) << "vkCreateSemaphore(next_present) failed: " << result;
230 return false;
231 }
232
233 // Acquire the initial buffer.
234 result = vkAcquireNextImageKHR(GetVulkanDevice(), swap_chain_, UINT64_MAX,
235 next_present_semaphore_, VK_NULL_HANDLE,
236 &current_image_);
237 if (VK_SUCCESS != result) {
238 DLOG(ERROR) << "vkAcquireNextImageKHR() failed: " << result;
239 return false;
240 }
241
242 std::swap(images_[current_image_]->present_semaphore,
243 next_present_semaphore_);
244
245 return true;
246 }
247
248 void VulkanSwapChain::DestroySwapImages() {
249 VkDevice device = GetVulkanDevice();
250
251 if (VK_NULL_HANDLE != next_present_semaphore_) {
252 vkDestroySemaphore(device, next_present_semaphore_, nullptr);
253 next_present_semaphore_ = VK_NULL_HANDLE;
254 }
255
256 for (const scoped_ptr<ImageData>& image_data : images_) {
257 if (image_data->command_buffer) {
258 // Make sure command buffer is done processing.
259 image_data->command_buffer->Wait(UINT64_MAX);
260
261 image_data->command_buffer->Destroy();
262 image_data->command_buffer.reset();
263 }
264
265 // Destroy Image View.
266 if (image_data->image_view) {
267 image_data->image_view->Destroy();
268 image_data->image_view.reset();
269 }
270
271 // Destroy Semaphores.
272 if (VK_NULL_HANDLE != image_data->present_semaphore) {
273 vkDestroySemaphore(device, image_data->present_semaphore, nullptr);
274 image_data->present_semaphore = VK_NULL_HANDLE;
275 }
276
277 if (VK_NULL_HANDLE != image_data->render_semaphore) {
278 vkDestroySemaphore(device, image_data->render_semaphore, nullptr);
279 image_data->render_semaphore = VK_NULL_HANDLE;
280 }
281
282 image_data->image = VK_NULL_HANDLE;
283 }
284 images_.clear();
285
286 if (command_pool_) {
287 command_pool_->Destroy();
288 command_pool_.reset();
289 }
290 }
291
292 VulkanSwapChain::ImageData::ImageData() {}
293
294 VulkanSwapChain::ImageData::~ImageData() {}
295
296 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/vulkan/vulkan_swap_chain.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698