| Index: gpu/vulkan/vulkan_surface.cc
|
| diff --git a/gpu/vulkan/vulkan_surface.cc b/gpu/vulkan/vulkan_surface.cc
|
| index 158ab4a3a49aaff156443f1ed112edd5668804d4..344045af90cdd14152e79ae1c74fc13587031306 100644
|
| --- a/gpu/vulkan/vulkan_surface.cc
|
| +++ b/gpu/vulkan/vulkan_surface.cc
|
| @@ -4,11 +4,130 @@
|
|
|
| #include "gpu/vulkan/vulkan_surface.h"
|
|
|
| +#include <vulkan/vulkan.h>
|
| +
|
| +#include "base/macros.h"
|
| +#include "gpu/vulkan/vulkan_command_buffer.h"
|
| #include "gpu/vulkan/vulkan_implementation.h"
|
| +#include "gpu/vulkan/vulkan_platform.h"
|
| +#include "gpu/vulkan/vulkan_swap_chain.h"
|
| +
|
| +#if defined(USE_X11)
|
| +#include "ui/gfx/x/x11_types.h"
|
| +#endif // defined(USE_X11)
|
|
|
| namespace gpu {
|
|
|
| -VulkanSurface::VulkanSurface() {}
|
| +namespace {
|
| +const VkFormat kNativeVkFormat[] = {
|
| + VK_FORMAT_B8G8R8A8_UNORM, // FORMAT_BGRA8888,
|
| + VK_FORMAT_R5G6B5_UNORM_PACK16, // FORMAT_RGB565,
|
| +};
|
| +static_assert(arraysize(kNativeVkFormat) == VulkanSurface::NUM_SURFACE_FORMATS,
|
| + "Array size for kNativeVkFormat must match surface formats.");
|
| +
|
| +} // namespace
|
| +
|
| +class VulkanWSISurface : public VulkanSurface {
|
| + public:
|
| + explicit VulkanWSISurface(gfx::AcceleratedWidget window) : window_(window) {}
|
| +
|
| + ~VulkanWSISurface() override {
|
| + DCHECK_EQ(static_cast<VkSurfaceKHR>(VK_NULL_HANDLE), surface_);
|
| + }
|
| +
|
| + bool Initialize(VulkanSurface::Format format) override {
|
| + DCHECK(format >= 0 && format < NUM_SURFACE_FORMATS);
|
| +#if defined(VK_USE_PLATFORM_XLIB_KHR)
|
| + VkXlibSurfaceCreateInfoKHR surface_create_info = {};
|
| + surface_create_info.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
|
| + surface_create_info.dpy = gfx::GetXDisplay();
|
| + surface_create_info.window = window_;
|
| + vkCreateXlibSurfaceKHR(GetVulkanInstance(), &surface_create_info, nullptr,
|
| + &surface_);
|
| +#else
|
| +#error Unsupported Vulkan Platform.
|
| +#endif
|
| +
|
| + // Get list of supported formats.
|
| + uint32_t format_count = 0;
|
| + VkResult result = vkGetPhysicalDeviceSurfaceFormatsKHR(
|
| + GetVulkanPhysicalDevice(), surface_, &format_count, nullptr);
|
| + if (VK_SUCCESS != result) {
|
| + DLOG(ERROR) << "vkGetPhysicalDeviceSurfaceFormatsKHR() failed: "
|
| + << result;
|
| + return false;
|
| + }
|
| +
|
| + std::vector<VkSurfaceFormatKHR> formats(format_count);
|
| + result = vkGetPhysicalDeviceSurfaceFormatsKHR(
|
| + GetVulkanPhysicalDevice(), surface_, &format_count, formats.data());
|
| + if (VK_SUCCESS != result) {
|
| + DLOG(ERROR) << "vkGetPhysicalDeviceSurfaceFormatsKHR() failed: "
|
| + << result;
|
| + return false;
|
| + }
|
| +
|
| + const VkFormat preferred_format = kNativeVkFormat[format];
|
| + if (formats.size() == 1 && VK_FORMAT_UNDEFINED == formats[0].format) {
|
| + surface_format_.format = preferred_format;
|
| + surface_format_.colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
|
| + } else {
|
| + bool format_set = false;
|
| + for (VkSurfaceFormatKHR supported_format : formats) {
|
| + if (supported_format.format == preferred_format) {
|
| + surface_format_ = supported_format;
|
| + surface_format_.colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
|
| + format_set = true;
|
| + break;
|
| + }
|
| + }
|
| + if (!format_set) {
|
| + DLOG(ERROR) << "Format not supported.";
|
| + return false;
|
| + }
|
| + }
|
| +
|
| + // Get Surface Information.
|
| + VkSurfaceCapabilitiesKHR surface_caps;
|
| + result = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(
|
| + GetVulkanPhysicalDevice(), surface_, &surface_caps);
|
| + if (VK_SUCCESS != result) {
|
| + DLOG(ERROR) << "vkGetPhysicalDeviceSurfaceCapabilitiesKHR() failed: "
|
| + << result;
|
| + return false;
|
| + }
|
| +
|
| + // These are actual surfaces so the current extent should be defined.
|
| + DCHECK_NE(UINT_MAX, surface_caps.currentExtent.width);
|
| + DCHECK_NE(UINT_MAX, surface_caps.currentExtent.height);
|
| + size_ = gfx::Size(surface_caps.currentExtent.width,
|
| + surface_caps.currentExtent.height);
|
| +
|
| + // Create Swapchain.
|
| + if (!swap_chain_.Initialize(surface_, surface_caps, surface_format_))
|
| + return false;
|
| +
|
| + return true;
|
| + }
|
| +
|
| + void Destroy() override {
|
| + swap_chain_.Destroy();
|
| + vkDestroySurfaceKHR(GetVulkanInstance(), surface_, nullptr);
|
| + surface_ = VK_NULL_HANDLE;
|
| + }
|
| +
|
| + gfx::SwapResult SwapBuffers() override { return swap_chain_.SwapBuffers(); }
|
| + VulkanSwapChain* GetSwapChain() override { return &swap_chain_; }
|
| + void Finish() override { vkQueueWaitIdle(GetVulkanQueue()); }
|
| +
|
| + protected:
|
| + gfx::AcceleratedWidget window_;
|
| + gfx::Size size_;
|
| + VkSurfaceKHR surface_ = VK_NULL_HANDLE;
|
| + VkSurfaceFormatKHR surface_format_ = {};
|
| + VulkanSwapChain swap_chain_;
|
| +};
|
|
|
| // static
|
| bool VulkanSurface::InitializeOneOff() {
|
| @@ -20,4 +139,12 @@ bool VulkanSurface::InitializeOneOff() {
|
|
|
| VulkanSurface::~VulkanSurface() {}
|
|
|
| +// static
|
| +scoped_ptr<VulkanSurface> VulkanSurface::CreateViewSurface(
|
| + gfx::AcceleratedWidget window) {
|
| + return scoped_ptr<VulkanSurface>(new VulkanWSISurface(window));
|
| +}
|
| +
|
| +VulkanSurface::VulkanSurface() {}
|
| +
|
| } // namespace gpu
|
|
|