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