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

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: Ensure vulkan handles all initialized to null, check destruction in destructor Created 4 years, 9 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
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_implementation.h"
8
9 namespace gfx {
10
11 VulkanSwapChain::VulkanSwapChain() {}
12
13 VulkanSwapChain::~VulkanSwapChain() {
14 DCHECK(buffers_.empty());
15 DCHECK_EQ(static_cast<VkSwapchainKHR>(VK_NULL_HANDLE), swap_chain_);
16 DCHECK_EQ(static_cast<VkRenderPass>(VK_NULL_HANDLE), render_pass_);
17 }
18
19 bool VulkanSwapChain::Initialize(VkCommandBuffer command_buffer,
20 VkSurfaceKHR surface,
21 const VkSurfaceCapabilitiesKHR& surface_caps,
22 const VkSurfaceFormatKHR& surface_format,
23 const VkComponentMapping& view_mapping) {
24 return InitializeSwapChain(surface, surface_caps, surface_format) &&
25 InitializeRenderPass(surface_format) &&
26 InitializeSwapBuffers(command_buffer, surface_caps, surface_format,
27 view_mapping);
28 }
29
30 void VulkanSwapChain::Destroy() {
31 VkDevice device = GetVulkanDevice();
32
33 for (const scoped_ptr<BufferData>& buffer_data : buffers_) {
34 if (buffer_data->command_buffer) {
35 buffer_data->command_buffer->Destroy();
36 buffer_data->command_buffer.reset();
37 }
38
39 vkDestroyFramebuffer(device, buffer_data->frame_buffer, nullptr);
40 buffer_data->frame_buffer = VK_NULL_HANDLE;
41
42 vkDestroyImageView(device, buffer_data->image_view, nullptr);
43 buffer_data->image_view = VK_NULL_HANDLE;
44 buffer_data->image = VK_NULL_HANDLE;
45 }
46 buffers_.clear();
47
48 if (render_pass_ != VK_NULL_HANDLE) {
49 vkDestroyRenderPass(device, render_pass_, nullptr);
50 render_pass_ = VK_NULL_HANDLE;
51 }
52
53 if (swap_chain_ != VK_NULL_HANDLE) {
54 vkDestroySwapchainKHR(device, swap_chain_, nullptr);
55 swap_chain_ = VK_NULL_HANDLE;
56 }
57 }
58
59 void VulkanSwapChain::SwapBuffers() {
60 current_buffer_ = (current_buffer_ + 1) % buffers_.size();
61 }
62
63 bool VulkanSwapChain::InitializeSwapChain(
64 VkSurfaceKHR surface,
65 const VkSurfaceCapabilitiesKHR& surface_caps,
66 const VkSurfaceFormatKHR& surface_format) {
67 VkDevice device = GetVulkanDevice();
68 VkResult result = VK_SUCCESS;
69
70 VkSwapchainCreateInfoKHR swap_chain_create_info = {};
71 swap_chain_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
72 swap_chain_create_info.surface = surface;
73 swap_chain_create_info.minImageCount =
74 std::max(surface_caps.minImageCount + 1, surface_caps.maxImageCount);
piman 2016/03/09 01:25:34 We shouldn't need +1, because we shouldn't be keep
David Yen 2016/03/10 01:39:49 Oops, I meant std::min here. I was assuming minIma
75 swap_chain_create_info.imageFormat = surface_format.format;
76 swap_chain_create_info.imageColorSpace = surface_format.colorSpace;
77 swap_chain_create_info.imageExtent = surface_caps.currentExtent;
78 swap_chain_create_info.imageArrayLayers = 1;
79 swap_chain_create_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
80 swap_chain_create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
81 swap_chain_create_info.preTransform = surface_caps.currentTransform;
82 swap_chain_create_info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
83 swap_chain_create_info.presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
piman 2016/03/09 01:25:35 VK_PRESENT_MODE_FIFO_KHR 1- that's the only one t
David Yen 2016/03/10 01:39:49 Done.
84 swap_chain_create_info.clipped = true;
85 swap_chain_create_info.oldSwapchain = swap_chain_;
86
87 VkSwapchainKHR new_swap_chain = VK_NULL_HANDLE;
88 result = vkCreateSwapchainKHR(device, &swap_chain_create_info, nullptr,
89 &new_swap_chain);
90 if (VK_SUCCESS != result) {
91 LOG(ERROR) << "vkCreateSwapchainKHR() failed: " << result;
piman 2016/03/09 01:25:34 nit: DLOG
David Yen 2016/03/10 01:39:49 Done.
92 return false;
93 }
94
95 // Destroy the old swap chain and buffers.
96 // TODO(dyen): Look into how to do this safely while commands in flight.
piman 2016/03/09 01:25:34 Right, at the very least we need to wait for previ
David Yen 2016/03/10 01:39:49 I will worry about this when I look into how to sa
97 Destroy();
98
99 swap_chain_ = new_swap_chain;
100 return true;
101 }
102
103 bool VulkanSwapChain::InitializeRenderPass(
piman 2016/03/09 01:25:35 I don't feel like this belongs to the SwapChain. E
David Yen 2016/03/10 01:39:49 Done.
104 const VkSurfaceFormatKHR& surface_format) {
105 VkAttachmentDescription attachment_description = {};
106 attachment_description.format = surface_format.format;
107 attachment_description.samples = VK_SAMPLE_COUNT_1_BIT;
108 attachment_description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
109 attachment_description.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
110 attachment_description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
111 attachment_description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
112 attachment_description.initialLayout =
113 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
114 attachment_description.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
piman 2016/03/09 01:25:34 It would be useful to do the transition to VK_IMAG
David Yen 2016/03/10 01:39:49 RenderPass no longer in this CL, I'll make a note
115
116 VkAttachmentReference color_attachment_reference = {};
117 color_attachment_reference.attachment = 0;
118 color_attachment_reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
119
120 VkSubpassDescription subpass_description = {};
121 subpass_description.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
122 subpass_description.colorAttachmentCount = 1;
123 subpass_description.pColorAttachments = &color_attachment_reference;
124
125 VkRenderPassCreateInfo render_pass_create_info = {};
126 render_pass_create_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
127 render_pass_create_info.attachmentCount = 1;
128 render_pass_create_info.pAttachments = &attachment_description;
129 render_pass_create_info.subpassCount = 1;
130 render_pass_create_info.pSubpasses = &subpass_description;
131
132 VkResult result = vkCreateRenderPass(
133 GetVulkanDevice(), &render_pass_create_info, nullptr, &render_pass_);
134 if (VK_SUCCESS != result) {
135 LOG(ERROR) << "vkCreateRenderPass() failed: " << result;
piman 2016/03/09 01:25:34 nit: DLOG
David Yen 2016/03/10 01:39:49 Done.
136 return false;
137 }
138
139 return true;
140 }
141
142 bool VulkanSwapChain::InitializeSwapBuffers(
143 VkCommandBuffer command_buffer,
144 const VkSurfaceCapabilitiesKHR& surface_caps,
145 const VkSurfaceFormatKHR& surface_format,
146 const VkComponentMapping& view_mapping) {
147 VkDevice device = GetVulkanDevice();
148 VkResult result = VK_SUCCESS;
149
150 uint32_t buffer_count = 0;
151 result = vkGetSwapchainImagesKHR(device, swap_chain_, &buffer_count, nullptr);
152 if (VK_SUCCESS != result) {
153 LOG(ERROR) << "vkGetSwapchainImagesKHR(NULL) failed: " << result;
piman 2016/03/09 01:25:34 nit: DLOG
David Yen 2016/03/10 01:39:49 Done.
154 return false;
155 }
156
157 std::vector<VkImage> images(buffer_count);
158 result = vkGetSwapchainImagesKHR(device, swap_chain_, &buffer_count,
159 images.data());
160 if (VK_SUCCESS != result) {
161 LOG(ERROR) << "vkGetSwapchainImagesKHR(images) failed: " << result;
piman 2016/03/09 01:25:34 nit: DLOG
David Yen 2016/03/10 01:39:49 Done.
162 return false;
163 }
164
165 // Default image subresource range.
166 VkImageSubresourceRange image_subresource_range = {};
167 image_subresource_range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
168 image_subresource_range.baseMipLevel = 0;
169 image_subresource_range.levelCount = 1;
170 image_subresource_range.baseArrayLayer = 0;
171 image_subresource_range.layerCount = 1;
172
173 // The image memory barrier is used to setup the image layout.
174 VkImageMemoryBarrier image_memory_barrier = {};
175 image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
176 image_memory_barrier.srcAccessMask =
177 VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT;
piman 2016/03/09 01:25:35 I don't think either of these flags is useful: - w
David Yen 2016/03/10 01:39:49 Done.
178 image_memory_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
179 image_memory_barrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
180 image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
181 image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
182 image_memory_barrier.subresourceRange = image_subresource_range;
183
184 // We must create an image view for each image.
185 VkImageViewCreateInfo image_view_create_info = {};
186 image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
187 image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
188 image_view_create_info.format = surface_format.format;
189 image_view_create_info.components = view_mapping;
piman 2016/03/09 01:25:34 For a render target view, the VkComponentMapping n
David Yen 2016/03/10 01:39:49 Done.
190 image_view_create_info.subresourceRange = image_subresource_range;
191
192 // Frame buffer creation info.
piman 2016/03/09 01:25:34 For the same reason as the RenderPass, I think we
David Yen 2016/03/10 01:39:49 Ok, I was originally thinking we could just have d
193 VkFramebufferCreateInfo frame_buffer_create_info = {};
194 frame_buffer_create_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
195 frame_buffer_create_info.renderPass = render_pass_;
196 frame_buffer_create_info.attachmentCount = 1;
197 frame_buffer_create_info.width = surface_caps.currentExtent.width;
198 frame_buffer_create_info.height = surface_caps.currentExtent.height;
199 frame_buffer_create_info.layers = 1;
200
201 buffers_.resize(buffer_count);
202 for (uint32_t i = 0; i < buffer_count; ++i) {
203 buffers_[i].reset(new BufferData);
204 buffers_[i]->image = images[i];
205
206 // Setup the Image Layout.
207 image_memory_barrier.image = images[i];
208 vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
209 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, 0,
piman 2016/03/09 01:25:34 If the intent is for this to happen before renderi
David Yen 2016/03/10 01:39:49 So I was envisioning every image to be in "PRESENT
210 nullptr, 1, &image_memory_barrier);
211
212 // Create the image view.
213 image_view_create_info.image = images[i];
214 result = vkCreateImageView(device, &image_view_create_info, nullptr,
215 &buffers_[i]->image_view);
216 if (VK_SUCCESS != result) {
217 LOG(ERROR) << "vkCreateImageView() failed: " << result;
piman 2016/03/09 01:25:35 nit: DLOG
David Yen 2016/03/10 01:39:49 Done.
218 return false;
219 }
220
221 // Create the frame buffer.
222 frame_buffer_create_info.pAttachments = &buffers_[i]->image_view;
223 result = vkCreateFramebuffer(device, &frame_buffer_create_info, nullptr,
224 &buffers_[i]->frame_buffer);
225 if (VK_SUCCESS != result) {
226 LOG(ERROR) << "vkCreateFramebuffer() failed: " << result;
piman 2016/03/09 01:25:35 nit: DLOG
David Yen 2016/03/10 01:39:49 Done.
227 return false;
228 }
229
230 // Initialize the command buffer for this buffer data.
231 buffers_[i]->command_buffer = CreatePrimaryCommandBuffer();
232 }
233
234 return true;
235 }
236
237 VulkanSwapChain::BufferData::BufferData() {}
238
239 VulkanSwapChain::BufferData::~BufferData() {}
240
241 } // namespace gfx
OLDNEW
« gpu/vulkan/vulkan_swap_chain.h ('K') | « gpu/vulkan/vulkan_swap_chain.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698