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

Unified Diff: gpu/vulkan/vulkan_implementation.cc

Issue 1726303002: Added initial Vulkan build files as well as a basic implementation file. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added queue and global accessors Created 4 years, 10 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 side-by-side diff with in-line comments
Download patch
Index: gpu/vulkan/vulkan_implementation.cc
diff --git a/gpu/vulkan/vulkan_implementation.cc b/gpu/vulkan/vulkan_implementation.cc
new file mode 100644
index 0000000000000000000000000000000000000000..60b67df76417716e6b007e5fafaad72db7c5352f
--- /dev/null
+++ b/gpu/vulkan/vulkan_implementation.cc
@@ -0,0 +1,220 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "gpu/vulkan/vulkan_implementation.h"
+
+#include <string>
+#include <vector>
+#include <vulkan/vulkan.h>
+
+#include "base/macros.h"
+
+#if defined(VK_USE_PLATFORM_XLIB_KHR)
+#include "ui/gfx/x/x11_types.h"
+#endif // defined(VK_USE_PLATFORM_XLIB_KHR)
+
+// The following code is not going to be necessary once the loader handles
+// the VK_KHR_XLIB_SURFACE_EXTENSION_NAME extension.
+#if defined(VK_USE_PLATFORM_XLIB_KHR)
+struct VulkanProcs {
+ PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR
+ vkGetPhysicalDeviceXlibPresentationSupportKHRFn = nullptr;
+
+ PFN_vkCreateXlibSurfaceKHR vkCreateXlibSurfaceKHRFn = nullptr;
+
+ bool InitializeFunctions(VkInstance vk_instance) {
+ vkGetPhysicalDeviceXlibPresentationSupportKHRFn =
+ reinterpret_cast<PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR>(
+ vkGetInstanceProcAddr(
+ vk_instance, "vkGetPhysicalDeviceXlibPresentationSupportKHR"));
+
+ vkCreateXlibSurfaceKHRFn = reinterpret_cast<PFN_vkCreateXlibSurfaceKHR>(
+ vkGetInstanceProcAddr(vk_instance, "vkCreateXlibSurfaceKHR"));
+
+ return true;
+ }
+};
+
+static VulkanProcs vulkan_procs;
piman 2016/03/04 21:07:09 non-POD globals are not allowed (causes global ini
David Yen 2016/03/04 22:12:28 I thought I would be able to get around the loader
piman 2016/03/05 00:11:25 vkGetInstanceProcAddr /could/ give you a more spe
David Yen 2016/03/07 23:33:31 So after building the loader locally, there are 2
+
+VKAPI_ATTR VkResult VKAPI_CALL
+vkCreateXlibSurfaceKHR(VkInstance instance,
+ const VkXlibSurfaceCreateInfoKHR* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSurfaceKHR* pSurface) {
+ return vulkan_procs.vkCreateXlibSurfaceKHRFn(instance, pCreateInfo,
+ pAllocator, pSurface);
+}
+
+VKAPI_ATTR VkBool32 VKAPI_CALL
+vkGetPhysicalDeviceXlibPresentationSupportKHR(VkPhysicalDevice physicalDevice,
+ uint32_t queueFamilyIndex,
+ Display* dpy,
+ VisualID visualID) {
+ // TODO(dyen): Re-enable this function once drivers properly support this.
+ return true;
+ return vulkan_procs.vkGetPhysicalDeviceXlibPresentationSupportKHRFn(
+ physicalDevice, queueFamilyIndex, dpy, visualID);
+}
+
+#endif // defined(VK_USE_PLATFORM_XLIB_KHR)
+// End of temporary VK_KHR_XLIB_SURFACE_EXTENSION_NAME loader code.
+
+namespace gfx {
+
+struct VulkanInstance {
+ VulkanInstance() : valid(false) {}
+
+ void Initialize() {
+ valid = InitializeVulkanInstance() && InitializeVulkanDevice();
+ }
+
+ bool InitializeVulkanInstance() {
+ VkResult status = VK_SUCCESS;
+
+ VkApplicationInfo app_info = {};
+ app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
+ app_info.pApplicationName = "Chromium";
+ app_info.apiVersion = VK_MAKE_VERSION(1, 0, 2);
+
+ const char* instance_extensions[] = {
+ VK_KHR_SURFACE_EXTENSION_NAME,
+
+#if defined(VK_USE_PLATFORM_XLIB_KHR)
+ VK_KHR_XLIB_SURFACE_EXTENSION_NAME,
+#endif // defined(VK_USE_PLATFORM_XLIB_KHR)
+ };
+
+ VkInstanceCreateInfo instance_create_info = {};
+ instance_create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
+ instance_create_info.pApplicationInfo = &app_info;
+ instance_create_info.ppEnabledExtensionNames = instance_extensions;
+ instance_create_info.enabledExtensionCount = arraysize(instance_extensions);
+
+ status = vkCreateInstance(&instance_create_info, nullptr, &vk_instance);
+ DCHECK_EQ(VK_SUCCESS, status);
+ if (VK_SUCCESS != status)
+ return false;
+
+ // TODO(dyen): Remove once loader properly supports xlib functions.
+ if (!vulkan_procs.InitializeFunctions(vk_instance))
+ return false;
+
+ return true;
+ }
+
+ bool InitializeVulkanDevice() {
+ VkResult status = VK_SUCCESS;
+
+ uint32_t device_count = 0;
+ status = vkEnumeratePhysicalDevices(vk_instance, &device_count, nullptr);
+ if (VK_SUCCESS != status || device_count == 0)
+ return false;
+
+ std::vector<VkPhysicalDevice> devices(device_count);
+ status =
+ vkEnumeratePhysicalDevices(vk_instance, &device_count, devices.data());
+ if (VK_SUCCESS != status) {
+ LOG(ERROR) << "vkEnumeratePhysicalDevices failed: " << status;
+ return false;
+ }
+
+#if defined(VK_USE_PLATFORM_XLIB_KHR)
+ Display* xdisplay = gfx::GetXDisplay();
+ VisualID visual_id =
+ XVisualIDFromVisual(DefaultVisual(xdisplay, DefaultScreen(xdisplay)));
+#endif // defined(VK_USE_PLATFORM_XLIB_KHR)
+
+ int device_index = -1;
+ int queue_index = -1;
+ for (size_t i = 0; i < devices.size(); ++i) {
+ const VkPhysicalDevice& device = devices[i];
+ uint32_t queue_count = 0;
+ vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_count, nullptr);
+ if (queue_count) {
+ std::vector<VkQueueFamilyProperties> queue_properties(queue_count);
+ vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_count,
+ queue_properties.data());
+ for (size_t n = 0; n < queue_properties.size(); ++n) {
+ if ((queue_properties[n].queueFlags & VK_QUEUE_GRAPHICS_BIT) == 0)
+ continue;
+
+#if defined(VK_USE_PLATFORM_XLIB_KHR)
+ if (!vkGetPhysicalDeviceXlibPresentationSupportKHR(
+ device, n, xdisplay, visual_id)) {
+ continue;
+ }
+#else
+#error Non-Supported Vulkan implementation.
+#endif
+
+ queue_index = static_cast<int>(n);
+ break;
+ }
+
+ if (-1 != queue_index) {
+ device_index = static_cast<int>(i);
+ break;
+ }
+ }
+ }
+
+ if (queue_index == -1)
+ return false;
+
+ float queue_priority = 0.0f;
+ VkDeviceQueueCreateInfo queue_create_info = {};
+ queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
+ queue_create_info.queueFamilyIndex = queue_index;
+ queue_create_info.queueCount = 1;
+ queue_create_info.pQueuePriorities = &queue_priority;
+
+ const char* device_extensions[] = {VK_KHR_SWAPCHAIN_EXTENSION_NAME};
+
+ VkDeviceCreateInfo device_create_info = {};
+ device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
+ device_create_info.queueCreateInfoCount = 1;
+ device_create_info.pQueueCreateInfos = &queue_create_info;
+ device_create_info.enabledExtensionCount = arraysize(device_extensions);
+ device_create_info.ppEnabledExtensionNames = device_extensions;
+
+ status = vkCreateDevice(devices[device_index], &device_create_info, nullptr,
+ &vk_device);
+ if (VK_SUCCESS != status)
+ return false;
+
+ vkGetDeviceQueue(vk_device, queue_index, 0, &vk_queue);
+
+ return true;
+ }
+
+ bool valid;
+ VkInstance vk_instance;
+ VkDevice vk_device;
+ VkQueue vk_queue;
+};
+
+static VulkanInstance vulkan_instance;
piman 2016/03/04 21:07:09 Same here wrt non-POD globals. LazyInstance seems
David Yen 2016/03/04 22:12:28 Done.
+
+bool InitializeVulkan() {
+ vulkan_instance.Initialize();
+ return vulkan_instance.valid;
+}
+
+VkInstance GetVulkanInstance() {
+ DCHECK(vulkan_instance.valid);
+ return vulkan_instance.vk_instance;
+}
+
+VkDevice GetVulkanDevice() {
+ DCHECK(vulkan_instance.valid);
+ return vulkan_instance.vk_device;
+}
+
+VkQueue GetVulkanQueue() {
+ DCHECK(vulkan_instance.valid);
+ return vulkan_instance.vk_queue;
+}
+
+} // namespace gfx

Powered by Google App Engine
This is Rietveld 408576698