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

Side by Side Diff: gpu/vulkan/vulkan_surface.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
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_surface.h" 5 #include "gpu/vulkan/vulkan_surface.h"
6 6
7 #include <vulkan/vulkan.h>
8
9 #include "base/macros.h"
10 #include "gpu/vulkan/vulkan_command_buffer.h"
7 #include "gpu/vulkan/vulkan_implementation.h" 11 #include "gpu/vulkan/vulkan_implementation.h"
12 #include "gpu/vulkan/vulkan_swap_chain.h"
13
14 #if defined(VK_USE_PLATFORM_XLIB_KHR)
15 #include "ui/gfx/x/x11_types.h"
16 #endif // defined(VK_USE_PLATFORM_XLIB_KHR)
8 17
9 namespace gfx { 18 namespace gfx {
10 19
11 VulkanSurface::VulkanSurface() {} 20 namespace {
21 const VkDeviceSize kFormatSize[] = {
22 4, // SURFACE_ARGB8888,
23 2, // SURFACE_RGB565,
24 4, // SURFACE_OSMESA_BGRA,
25 4, // SURFACE_OSMESA_RGBA,
26 };
27 static_assert(arraysize(kFormatSize) == VulkanSurface::NUM_SURFACE_FORMATS,
28 "Array size for kFormatSize must match surface formats.");
29
30 const VkFormat kNativeVkFormat[] = {
31 VK_FORMAT_B8G8R8A8_UNORM, // SURFACE_ARGB8888,
32 VK_FORMAT_R5G6B5_UNORM_PACK16, // SURFACE_RGB565,
33 VK_FORMAT_B8G8R8A8_UNORM, // SURFACE_OSMESA_BGRA,
34 VK_FORMAT_B8G8R8A8_UNORM, // SURFACE_OSMESA_RGBA,
35 };
36 static_assert(arraysize(kNativeVkFormat) == VulkanSurface::NUM_SURFACE_FORMATS,
37 "Array size for kNativeVkFormat must match surface formats.");
38
39 const VkComponentMapping kFormatMapping[] = {
40 // SURFACE_ARGB8888,
41 {VK_COMPONENT_SWIZZLE_A, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
42 VK_COMPONENT_SWIZZLE_B},
43
44 // SURFACE_RGB565,
45 {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B,
46 VK_COMPONENT_SWIZZLE_ONE},
47
48 // SURFACE_OSMESA_BGRA,
49 {VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R,
50 VK_COMPONENT_SWIZZLE_A},
51
52 // SURFACE_OSMESA_RGBA,
53 {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B,
54 VK_COMPONENT_SWIZZLE_A},
55 };
56 static_assert(arraysize(kFormatMapping) == VulkanSurface::NUM_SURFACE_FORMATS,
57 "Array size for kFormatMapping must match surface formats.");
58
59 } // namespace
60
61 class VulkanWSISurface : public VulkanSurface {
62 public:
63 VulkanWSISurface(gfx::AcceleratedWidget window) : window_(window) {}
piman 2016/03/09 01:25:34 nit: explicit
David Yen 2016/03/10 01:39:49 Done.
64
65 ~VulkanWSISurface() override {
66 DCHECK_EQ(static_cast<VkSurfaceKHR>(VK_NULL_HANDLE), surface_);
67 }
68
69 bool Initialize(VulkanSurface::Format format) override {
70 DCHECK(format >= 0 && format < NUM_SURFACE_FORMATS);
71 #if defined(VK_USE_PLATFORM_XLIB_KHR)
72 VkXlibSurfaceCreateInfoKHR surface_create_info = {};
73 surface_create_info.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
74 surface_create_info.dpy = gfx::GetXDisplay();
75 surface_create_info.window = window_;
76 vkCreateXlibSurfaceKHR(GetVulkanInstance(), &surface_create_info, nullptr,
77 &surface_);
78 #else
79 #error Unsupported Vulkan Platform.
80 #endif
81
82 // Get list of supported formats.
83 uint32_t format_count = 0;
84 VkResult result = vkGetPhysicalDeviceSurfaceFormatsKHR(
85 GetVulkanPhysicalDevice(), surface_, &format_count, nullptr);
86 if (VK_SUCCESS != result) {
87 LOG(ERROR) << "vkGetPhysicalDeviceSurfaceFormatsKHR() failed: " << result;
piman 2016/03/09 01:25:34 nit: DLOG
David Yen 2016/03/10 01:39:48 Done.
88 return false;
89 }
90
91 std::vector<VkSurfaceFormatKHR> formats(format_count);
92 result = vkGetPhysicalDeviceSurfaceFormatsKHR(
93 GetVulkanPhysicalDevice(), surface_, &format_count, formats.data());
94 if (VK_SUCCESS != result) {
95 LOG(ERROR) << "vkGetPhysicalDeviceSurfaceFormatsKHR() failed: " << result;
96 return false;
97 }
98
99 const VkFormat preferred_format = kNativeVkFormat[format];
100 if (formats.size() == 1 && VK_FORMAT_UNDEFINED == formats[0].format) {
101 surface_format_.format = preferred_format;
102 surface_format_.colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
103 } else {
104 bool format_set = false;
105 for (VkSurfaceFormatKHR supported_format : formats) {
106 if (supported_format.format == preferred_format) {
107 surface_format_ = supported_format;
108 format_set = true;
109 break;
110 }
111 }
112 if (!format_set) {
113 surface_format_.format = VK_FORMAT_B8G8R8A8_UNORM;
piman 2016/03/09 01:25:34 There's no guarantee that this is supported. If we
David Yen 2016/03/10 01:39:49 Done.
114 surface_format_.colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
115 }
116 }
117
118 // Get Surface Information.
119 VkSurfaceCapabilitiesKHR surface_caps;
120 result = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(
121 GetVulkanPhysicalDevice(), surface_, &surface_caps);
122 if (VK_SUCCESS != result) {
123 LOG(ERROR) << "vkGetPhysicalDeviceSurfaceCapabilitiesKHR() failed: "
piman 2016/03/09 01:25:34 nit: DLOG
David Yen 2016/03/10 01:39:49 Done.
124 << result;
125 return false;
126 }
127
128 // These are actual surfaces so the current extent should be defined.
129 DCHECK_NE(UINT_MAX, surface_caps.currentExtent.width);
130 DCHECK_NE(UINT_MAX, surface_caps.currentExtent.height);
131 size_ = gfx::Size(surface_caps.currentExtent.width,
132 surface_caps.currentExtent.height);
133
134 // The next part of the setup process needs to submit commands, we create
135 // a temporary command buffer to do these submissions.
136 scoped_ptr<VulkanCommandBuffer> command_buffer =
137 CreatePrimaryCommandBuffer();
138
139 bool success = false;
140 do {
141 {
142 ScopedSingleUseCommandBufferRecorder recorder(*command_buffer);
143
144 // Create Swapchain.
145 if (!swap_chain_.Initialize(recorder.handle(), surface_, surface_caps,
146 surface_format_, kFormatMapping[format])) {
147 break;
148 }
149 }
150
151 if (!command_buffer->Submit()) {
152 LOG(ERROR) << "Failed to submit command buffer commands.";
piman 2016/03/09 01:25:34 nit: DLOG
David Yen 2016/03/10 01:39:49 Done.
153 break;
154 }
155
156 // TODO(dyen): Look into if it's worth inserting a fence or event here
157 // and keeping around the command buffer until it's done.
piman 2016/03/09 01:25:34 We'll definitely want some facility to do that - d
David Yen 2016/03/10 01:39:48 After thinking through this more, I now have this
158 result = vkQueueWaitIdle(GetVulkanQueue());
159 if (VK_SUCCESS != result) {
160 LOG(ERROR) << "vkQueueWaitIdle() failed: " << result;
piman 2016/03/09 01:25:34 nit: DLOG
David Yen 2016/03/10 01:39:49 Done.
161 break;
162 }
163
164 success = true;
165 } while (false);
166
167 command_buffer->Destroy();
168 return success;
169 }
170
171 void Destroy() override {
172 swap_chain_.Destroy();
173 vkDestroySurfaceKHR(GetVulkanInstance(), surface_, nullptr);
174 surface_ = VK_NULL_HANDLE;
175 }
176
177 protected:
178 gfx::AcceleratedWidget window_;
179 gfx::Size size_;
180 VkSurfaceKHR surface_ = VK_NULL_HANDLE;
181 VkSurfaceFormatKHR surface_format_ = {};
182 VulkanSwapChain swap_chain_;
183 };
184
185 class VulkanBufferSurface : public VulkanSurface {
piman 2016/03/09 01:25:34 I don't think this is useful - you can't use a VkB
David Yen 2016/03/10 01:39:48 Deleted.
186 public:
187 VulkanBufferSurface(const gfx::Size& size) : size_(size) {}
188
189 ~VulkanBufferSurface() override {
190 DCHECK_EQ(static_cast<VkBuffer>(VK_NULL_HANDLE), buffer_);
191 }
192
193 bool Initialize(VulkanSurface::Format format) override {
194 VkBufferCreateInfo buffer_create_info = {};
195 buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
196 buffer_create_info.size = kFormatSize[format] * size_.GetArea();
197 buffer_create_info.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT |
198 VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
199 buffer_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
200
201 VkResult result = vkCreateBuffer(GetVulkanDevice(), &buffer_create_info,
202 nullptr, &buffer_);
203 if (VK_SUCCESS != result) {
204 LOG(ERROR) << "Could not create VkBuffer (" << size_.width() << "x"
205 << size_.height() << "x" << kFormatSize[format]
206 << "): " << result;
207 return false;
208 }
209 return true;
210 }
211
212 void Destroy() override {
213 vkDestroyBuffer(GetVulkanDevice(), buffer_, nullptr);
214 buffer_ = VK_NULL_HANDLE;
215 }
216
217 protected:
218 gfx::Size size_;
219 VkBuffer buffer_ = VK_NULL_HANDLE;
220 };
12 221
13 // static 222 // static
14 bool VulkanSurface::InitializeOneOff() { 223 bool VulkanSurface::InitializeOneOff() {
15 if (!InitializeVulkan()) 224 if (!InitializeVulkan())
16 return false; 225 return false;
17 226
18 return true; 227 return true;
19 } 228 }
20 229
21 VulkanSurface::~VulkanSurface() {} 230 VulkanSurface::~VulkanSurface() {}
22 231
232 // static
233 scoped_ptr<gfx::VulkanSurface> VulkanSurface::CreateViewSurface(
234 gfx::AcceleratedWidget window) {
235 return scoped_ptr<gfx::VulkanSurface>(new VulkanWSISurface(window));
236 }
237
238 // static
239 scoped_ptr<gfx::VulkanSurface> VulkanSurface::CreateOffscreenSurface(
240 const gfx::Size& size) {
241 return scoped_ptr<gfx::VulkanSurface>(new VulkanBufferSurface(size));
242 }
243
244 VulkanSurface::VulkanSurface() {}
245
23 } // namespace gfx 246 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698