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_surface.h" | 5 #include "gpu/vulkan/vulkan_surface.h" |
6 | 6 |
7 #include <vulkan/vulkan.h> | 7 #include <vulkan/vulkan.h> |
8 | 8 |
9 #include "base/macros.h" | 9 #include "base/macros.h" |
10 #include "gpu/vulkan/vulkan_command_buffer.h" | 10 #include "gpu/vulkan/vulkan_command_buffer.h" |
| 11 #include "gpu/vulkan/vulkan_device_queue.h" |
11 #include "gpu/vulkan/vulkan_implementation.h" | 12 #include "gpu/vulkan/vulkan_implementation.h" |
12 #include "gpu/vulkan/vulkan_platform.h" | 13 #include "gpu/vulkan/vulkan_platform.h" |
13 #include "gpu/vulkan/vulkan_swap_chain.h" | 14 #include "gpu/vulkan/vulkan_swap_chain.h" |
14 | 15 |
15 #if defined(USE_X11) | 16 #if defined(USE_X11) |
16 #include "ui/gfx/x/x11_types.h" | 17 #include "ui/gfx/x/x11_types.h" |
17 #endif // defined(USE_X11) | 18 #endif // defined(USE_X11) |
18 | 19 |
19 namespace gpu { | 20 namespace gpu { |
20 | 21 |
21 namespace { | 22 namespace { |
22 const VkFormat kNativeVkFormat[] = { | 23 const VkFormat kNativeVkFormat[] = { |
23 VK_FORMAT_B8G8R8A8_UNORM, // FORMAT_BGRA8888, | 24 VK_FORMAT_B8G8R8A8_UNORM, // FORMAT_BGRA8888, |
24 VK_FORMAT_R5G6B5_UNORM_PACK16, // FORMAT_RGB565, | 25 VK_FORMAT_R5G6B5_UNORM_PACK16, // FORMAT_RGB565, |
25 }; | 26 }; |
26 static_assert(arraysize(kNativeVkFormat) == VulkanSurface::NUM_SURFACE_FORMATS, | 27 static_assert(arraysize(kNativeVkFormat) == VulkanSurface::NUM_SURFACE_FORMATS, |
27 "Array size for kNativeVkFormat must match surface formats."); | 28 "Array size for kNativeVkFormat must match surface formats."); |
28 | 29 |
29 } // namespace | 30 } // namespace |
30 | 31 |
31 class VulkanWSISurface : public VulkanSurface { | 32 class VulkanWSISurface : public VulkanSurface { |
32 public: | 33 public: |
33 explicit VulkanWSISurface(gfx::AcceleratedWidget window) : window_(window) {} | 34 explicit VulkanWSISurface(gfx::AcceleratedWidget window) : window_(window) {} |
34 | 35 |
35 ~VulkanWSISurface() override { | 36 ~VulkanWSISurface() override { |
36 DCHECK_EQ(static_cast<VkSurfaceKHR>(VK_NULL_HANDLE), surface_); | 37 DCHECK_EQ(static_cast<VkSurfaceKHR>(VK_NULL_HANDLE), surface_); |
37 } | 38 } |
38 | 39 |
39 bool Initialize(VulkanSurface::Format format) override { | 40 bool Initialize(VulkanDeviceQueue* device_queue, |
| 41 VulkanSurface::Format format) override { |
40 DCHECK(format >= 0 && format < NUM_SURFACE_FORMATS); | 42 DCHECK(format >= 0 && format < NUM_SURFACE_FORMATS); |
| 43 DCHECK_EQ(static_cast<VkSurfaceKHR>(VK_NULL_HANDLE), surface_); |
| 44 VkResult result = VK_SUCCESS; |
| 45 |
41 #if defined(VK_USE_PLATFORM_XLIB_KHR) | 46 #if defined(VK_USE_PLATFORM_XLIB_KHR) |
42 VkXlibSurfaceCreateInfoKHR surface_create_info = {}; | 47 VkXlibSurfaceCreateInfoKHR surface_create_info = {}; |
43 surface_create_info.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR; | 48 surface_create_info.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR; |
44 surface_create_info.dpy = gfx::GetXDisplay(); | 49 surface_create_info.dpy = gfx::GetXDisplay(); |
45 surface_create_info.window = window_; | 50 surface_create_info.window = window_; |
46 vkCreateXlibSurfaceKHR(GetVulkanInstance(), &surface_create_info, nullptr, | 51 result = vkCreateXlibSurfaceKHR(GetVulkanInstance(), &surface_create_info, |
47 &surface_); | 52 nullptr, &surface_); |
| 53 if (VK_SUCCESS != result) { |
| 54 DLOG(ERROR) << "vkCreateXlibSurfaceKHR() failed: " << result; |
| 55 return false; |
| 56 } |
48 #else | 57 #else |
49 #error Unsupported Vulkan Platform. | 58 #error Unsupported Vulkan Platform. |
50 #endif | 59 #endif |
51 | 60 |
| 61 DCHECK_NE(static_cast<VkSurfaceKHR>(VK_NULL_HANDLE), surface_); |
| 62 DCHECK(device_queue); |
| 63 device_queue_ = device_queue; |
| 64 |
52 // Get list of supported formats. | 65 // Get list of supported formats. |
53 uint32_t format_count = 0; | 66 uint32_t format_count = 0; |
54 VkResult result = vkGetPhysicalDeviceSurfaceFormatsKHR( | 67 result = vkGetPhysicalDeviceSurfaceFormatsKHR( |
55 GetVulkanPhysicalDevice(), surface_, &format_count, nullptr); | 68 device_queue_->GetVulkanPhysicalDevice(), surface_, &format_count, |
| 69 nullptr); |
56 if (VK_SUCCESS != result) { | 70 if (VK_SUCCESS != result) { |
57 DLOG(ERROR) << "vkGetPhysicalDeviceSurfaceFormatsKHR() failed: " | 71 DLOG(ERROR) << "vkGetPhysicalDeviceSurfaceFormatsKHR() failed: " |
58 << result; | 72 << result; |
59 return false; | 73 return false; |
60 } | 74 } |
61 | 75 |
62 std::vector<VkSurfaceFormatKHR> formats(format_count); | 76 std::vector<VkSurfaceFormatKHR> formats(format_count); |
63 result = vkGetPhysicalDeviceSurfaceFormatsKHR( | 77 result = vkGetPhysicalDeviceSurfaceFormatsKHR( |
64 GetVulkanPhysicalDevice(), surface_, &format_count, formats.data()); | 78 device_queue_->GetVulkanPhysicalDevice(), surface_, &format_count, |
| 79 formats.data()); |
65 if (VK_SUCCESS != result) { | 80 if (VK_SUCCESS != result) { |
66 DLOG(ERROR) << "vkGetPhysicalDeviceSurfaceFormatsKHR() failed: " | 81 DLOG(ERROR) << "vkGetPhysicalDeviceSurfaceFormatsKHR() failed: " |
67 << result; | 82 << result; |
68 return false; | 83 return false; |
69 } | 84 } |
70 | 85 |
71 const VkFormat preferred_format = kNativeVkFormat[format]; | 86 const VkFormat preferred_format = kNativeVkFormat[format]; |
72 if (formats.size() == 1 && VK_FORMAT_UNDEFINED == formats[0].format) { | 87 if (formats.size() == 1 && VK_FORMAT_UNDEFINED == formats[0].format) { |
73 surface_format_.format = preferred_format; | 88 surface_format_.format = preferred_format; |
74 surface_format_.colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; | 89 surface_format_.colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; |
75 } else { | 90 } else { |
76 bool format_set = false; | 91 bool format_set = false; |
77 for (VkSurfaceFormatKHR supported_format : formats) { | 92 for (VkSurfaceFormatKHR supported_format : formats) { |
78 if (supported_format.format == preferred_format) { | 93 if (supported_format.format == preferred_format) { |
79 surface_format_ = supported_format; | 94 surface_format_ = supported_format; |
80 surface_format_.colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; | 95 surface_format_.colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; |
81 format_set = true; | 96 format_set = true; |
82 break; | 97 break; |
83 } | 98 } |
84 } | 99 } |
85 if (!format_set) { | 100 if (!format_set) { |
86 DLOG(ERROR) << "Format not supported."; | 101 DLOG(ERROR) << "Format not supported."; |
87 return false; | 102 return false; |
88 } | 103 } |
89 } | 104 } |
90 | 105 |
91 // Get Surface Information. | 106 // Get Surface Information. |
92 VkSurfaceCapabilitiesKHR surface_caps; | 107 VkSurfaceCapabilitiesKHR surface_caps; |
93 result = vkGetPhysicalDeviceSurfaceCapabilitiesKHR( | 108 result = vkGetPhysicalDeviceSurfaceCapabilitiesKHR( |
94 GetVulkanPhysicalDevice(), surface_, &surface_caps); | 109 device_queue_->GetVulkanPhysicalDevice(), surface_, &surface_caps); |
95 if (VK_SUCCESS != result) { | 110 if (VK_SUCCESS != result) { |
96 DLOG(ERROR) << "vkGetPhysicalDeviceSurfaceCapabilitiesKHR() failed: " | 111 DLOG(ERROR) << "vkGetPhysicalDeviceSurfaceCapabilitiesKHR() failed: " |
97 << result; | 112 << result; |
98 return false; | 113 return false; |
99 } | 114 } |
100 | 115 |
101 // These are actual surfaces so the current extent should be defined. | 116 // These are actual surfaces so the current extent should be defined. |
102 DCHECK_NE(UINT_MAX, surface_caps.currentExtent.width); | 117 DCHECK_NE(UINT_MAX, surface_caps.currentExtent.width); |
103 DCHECK_NE(UINT_MAX, surface_caps.currentExtent.height); | 118 DCHECK_NE(UINT_MAX, surface_caps.currentExtent.height); |
104 size_ = gfx::Size(surface_caps.currentExtent.width, | 119 size_ = gfx::Size(surface_caps.currentExtent.width, |
105 surface_caps.currentExtent.height); | 120 surface_caps.currentExtent.height); |
106 | 121 |
107 // Create Swapchain. | 122 // Create Swapchain. |
108 if (!swap_chain_.Initialize(surface_, surface_caps, surface_format_)) | 123 if (!swap_chain_.Initialize(device_queue_, surface_, surface_caps, |
| 124 surface_format_)) { |
109 return false; | 125 return false; |
| 126 } |
110 | 127 |
111 return true; | 128 return true; |
112 } | 129 } |
113 | 130 |
114 void Destroy() override { | 131 void Destroy() override { |
115 swap_chain_.Destroy(); | 132 swap_chain_.Destroy(); |
116 vkDestroySurfaceKHR(GetVulkanInstance(), surface_, nullptr); | 133 vkDestroySurfaceKHR(GetVulkanInstance(), surface_, nullptr); |
117 surface_ = VK_NULL_HANDLE; | 134 surface_ = VK_NULL_HANDLE; |
118 } | 135 } |
119 | 136 |
120 gfx::SwapResult SwapBuffers() override { return swap_chain_.SwapBuffers(); } | 137 gfx::SwapResult SwapBuffers() override { return swap_chain_.SwapBuffers(); } |
121 VulkanSwapChain* GetSwapChain() override { return &swap_chain_; } | 138 VulkanSwapChain* GetSwapChain() override { return &swap_chain_; } |
122 void Finish() override { vkQueueWaitIdle(GetVulkanQueue()); } | 139 void Finish() override { vkQueueWaitIdle(device_queue_->GetVulkanQueue()); } |
123 | 140 |
124 protected: | 141 protected: |
125 gfx::AcceleratedWidget window_; | 142 gfx::AcceleratedWidget window_; |
126 gfx::Size size_; | 143 gfx::Size size_; |
127 VkSurfaceKHR surface_ = VK_NULL_HANDLE; | 144 VkSurfaceKHR surface_ = VK_NULL_HANDLE; |
128 VkSurfaceFormatKHR surface_format_ = {}; | 145 VkSurfaceFormatKHR surface_format_ = {}; |
| 146 VulkanDeviceQueue* device_queue_ = nullptr; |
129 VulkanSwapChain swap_chain_; | 147 VulkanSwapChain swap_chain_; |
130 }; | 148 }; |
131 | 149 |
132 // static | 150 // static |
133 bool VulkanSurface::InitializeOneOff() { | 151 bool VulkanSurface::InitializeOneOff() { |
134 if (!InitializeVulkan()) | 152 if (!InitializeVulkan()) |
135 return false; | 153 return false; |
136 | 154 |
137 return true; | 155 return true; |
138 } | 156 } |
139 | 157 |
140 VulkanSurface::~VulkanSurface() {} | 158 VulkanSurface::~VulkanSurface() {} |
141 | 159 |
142 // static | 160 // static |
143 scoped_ptr<VulkanSurface> VulkanSurface::CreateViewSurface( | 161 scoped_ptr<VulkanSurface> VulkanSurface::CreateViewSurface( |
144 gfx::AcceleratedWidget window) { | 162 gfx::AcceleratedWidget window) { |
145 return scoped_ptr<VulkanSurface>(new VulkanWSISurface(window)); | 163 return scoped_ptr<VulkanSurface>(new VulkanWSISurface(window)); |
146 } | 164 } |
147 | 165 |
148 VulkanSurface::VulkanSurface() {} | 166 VulkanSurface::VulkanSurface() {} |
149 | 167 |
150 } // namespace gpu | 168 } // namespace gpu |
OLD | NEW |